1
0

Implement automatic cards exchange

This commit is contained in:
Anton Vakhrushev 2023-10-20 15:11:42 +03:00
parent 1ef176f3f7
commit bfec3048d3
Signed by: av
GPG Key ID: 581F7473F7A21FA2
6 changed files with 898 additions and 11 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/vendor/
.env
.php-cs-fixer.cache

View File

@ -4,23 +4,26 @@ version: '3'
env: {}
dotenv:
- '.env'
vars:
DOCKER_IMAGE: 'the-tale-ca-php'
DOCKER_RUN: 'docker run -it --rm -u 1000:1000 -v ${PWD}:/app -w /app {{.DOCKER_IMAGE}}'
tasks:
default:
cmds:
- echo "{{.GREETING}}"
silent: true
build-docker-image:
cmds:
- docker build -t "{{.DOCKER_IMAGE}}" .
run-shell:
cmds:
- docker run -it --rm -u 1000:1000 -v ${PWD}:/app -w /app {{.DOCKER_IMAGE}} bash
- '{{.DOCKER_RUN}} bash'
format:
cmds:
- docker run -it --rm -u 1000:1000 -v ${PWD}:/app -w /app {{.DOCKER_IMAGE}} php-cs-fixer fix
- '{{.DOCKER_RUN}} php-cs-fixer fix'
exchange:
cmds:
- '{{.DOCKER_RUN}} php console.php cards:exchange'

View File

@ -4,7 +4,12 @@
"require": {
"php": "^8.2",
"guzzlehttp/guzzle": "^7.8",
"symfony/console": "^6.3"
"symfony/console": "^6.3",
"symfony/var-dumper": "^6.3",
"zakirullin/mess": "^0.8.4",
"webmozart/assert": "^1.11",
"lstrojny/functional-php": "^1.17",
"vlucas/phpdotenv": "^5.5"
},
"require-dev": {
"roave/security-advisories": "dev-latest"

662
composer.lock generated
View File

@ -4,8 +4,70 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9f83c44ba9881f7ae4f216d730b5731e",
"content-hash": "ab3e79c130e558d40e02b1d848a78b7e",
"packages": [
{
"name": "graham-campbell/result-type",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
"reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
"reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.1"
},
"require-dev": {
"phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
},
"type": "library",
"autoload": {
"psr-4": {
"GrahamCampbell\\ResultType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "An Implementation Of The Result Type",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
"Result Type",
"Result-Type",
"result"
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
"type": "tidelift"
}
],
"time": "2023-02-25T20:23:15+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "7.8.0",
@ -331,6 +393,235 @@
],
"time": "2023-08-27T10:13:57+00:00"
},
{
"name": "lstrojny/functional-php",
"version": "1.17.0",
"source": {
"type": "git",
"url": "https://github.com/lstrojny/functional-php.git",
"reference": "e459d5cb307bc6e10e9e992c4e96bb71a0262506"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lstrojny/functional-php/zipball/e459d5cb307bc6e10e9e992c4e96bb71a0262506",
"reference": "e459d5cb307bc6e10e9e992c4e96bb71a0262506",
"shasum": ""
},
"require": {
"php": "^7.1|~8"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.17",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.5",
"squizlabs/php_codesniffer": "~3.0"
},
"type": "library",
"autoload": {
"files": [
"src/Functional/Ary.php",
"src/Functional/Average.php",
"src/Functional/ButLast.php",
"src/Functional/Capture.php",
"src/Functional/ConstFunction.php",
"src/Functional/CompareOn.php",
"src/Functional/CompareObjectHashOn.php",
"src/Functional/Compose.php",
"src/Functional/Concat.php",
"src/Functional/Contains.php",
"src/Functional/Converge.php",
"src/Functional/Curry.php",
"src/Functional/CurryN.php",
"src/Functional/Difference.php",
"src/Functional/DropFirst.php",
"src/Functional/DropLast.php",
"src/Functional/Each.php",
"src/Functional/Equal.php",
"src/Functional/ErrorToException.php",
"src/Functional/Every.php",
"src/Functional/False.php",
"src/Functional/Falsy.php",
"src/Functional/Filter.php",
"src/Functional/First.php",
"src/Functional/FirstIndexOf.php",
"src/Functional/FlatMap.php",
"src/Functional/Flatten.php",
"src/Functional/Flip.php",
"src/Functional/GreaterThan.php",
"src/Functional/GreaterThanOrEqual.php",
"src/Functional/Group.php",
"src/Functional/Head.php",
"src/Functional/Id.php",
"src/Functional/IfElse.php",
"src/Functional/Identical.php",
"src/Functional/IndexesOf.php",
"src/Functional/Intersperse.php",
"src/Functional/Invoke.php",
"src/Functional/InvokeFirst.php",
"src/Functional/InvokeIf.php",
"src/Functional/InvokeLast.php",
"src/Functional/Invoker.php",
"src/Functional/Last.php",
"src/Functional/LastIndexOf.php",
"src/Functional/LessThan.php",
"src/Functional/LessThanOrEqual.php",
"src/Functional/LexicographicCompare.php",
"src/Functional/Map.php",
"src/Functional/Matching.php",
"src/Functional/Maximum.php",
"src/Functional/Memoize.php",
"src/Functional/Minimum.php",
"src/Functional/None.php",
"src/Functional/Noop.php",
"src/Functional/Not.php",
"src/Functional/OmitKeys.php",
"src/Functional/PartialAny.php",
"src/Functional/PartialLeft.php",
"src/Functional/PartialMethod.php",
"src/Functional/PartialRight.php",
"src/Functional/Partition.php",
"src/Functional/Pick.php",
"src/Functional/Pluck.php",
"src/Functional/Poll.php",
"src/Functional/Product.php",
"src/Functional/Ratio.php",
"src/Functional/ReduceLeft.php",
"src/Functional/ReduceRight.php",
"src/Functional/Reindex.php",
"src/Functional/Reject.php",
"src/Functional/Repeat.php",
"src/Functional/Retry.php",
"src/Functional/Select.php",
"src/Functional/SelectKeys.php",
"src/Functional/SequenceConstant.php",
"src/Functional/SequenceExponential.php",
"src/Functional/SequenceLinear.php",
"src/Functional/Some.php",
"src/Functional/Sort.php",
"src/Functional/Sum.php",
"src/Functional/SuppressError.php",
"src/Functional/Tap.php",
"src/Functional/Tail.php",
"src/Functional/TailRecursion.php",
"src/Functional/TakeLeft.php",
"src/Functional/TakeRight.php",
"src/Functional/True.php",
"src/Functional/Truthy.php",
"src/Functional/Unique.php",
"src/Functional/ValueToKey.php",
"src/Functional/With.php",
"src/Functional/Zip.php",
"src/Functional/ZipAll.php"
],
"psr-4": {
"Functional\\": "src/Functional"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lars Strojny",
"email": "lstrojny@php.net",
"homepage": "https://usrportage.de"
},
{
"name": "Max Beutel",
"email": "nash12@gmail.com"
}
],
"description": "Functional primitives for PHP",
"keywords": [
"functional"
],
"support": {
"issues": "https://github.com/lstrojny/functional-php/issues",
"source": "https://github.com/lstrojny/functional-php/tree/1.17.0"
},
"funding": [
{
"url": "https://github.com/lstrojny",
"type": "github"
}
],
"time": "2021-03-07T00:25:34+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
"reference": "dd3a383e599f49777d8b628dadbb90cae435b87e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e",
"reference": "dd3a383e599f49777d8b628dadbb90cae435b87e",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": true
},
"branch-alias": {
"dev-master": "1.9-dev"
}
},
"autoload": {
"psr-4": {
"PhpOption\\": "src/PhpOption/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh"
},
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "Option Type for PHP",
"keywords": [
"language",
"option",
"php",
"type"
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
"source": "https://github.com/schmittjoh/php-option/tree/1.9.1"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
"type": "tidelift"
}
],
"time": "2023-02-25T19:38:58+00:00"
},
{
"name": "psr/container",
"version": "2.0.2",
@ -1075,6 +1366,89 @@
],
"time": "2023-07-28T09:04:16+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.28.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v3.3.0",
@ -1242,6 +1616,292 @@
}
],
"time": "2023-09-18T10:38:32+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v6.3.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "3d9999376be5fea8de47752837a3e1d1c5f69ef5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/3d9999376be5fea8de47752837a3e1d1c5f69ef5",
"reference": "3d9999376be5fea8de47752837a3e1d1c5f69ef5",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/console": "<5.4"
},
"require-dev": {
"ext-iconv": "*",
"symfony/console": "^5.4|^6.0",
"symfony/http-kernel": "^5.4|^6.0",
"symfony/process": "^5.4|^6.0",
"symfony/uid": "^5.4|^6.0",
"twig/twig": "^2.13|^3.0.4"
},
"bin": [
"Resources/bin/var-dump-server"
],
"type": "library",
"autoload": {
"files": [
"Resources/functions/dump.php"
],
"psr-4": {
"Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides mechanisms for walking through any arbitrary PHP variable",
"homepage": "https://symfony.com",
"keywords": [
"debug",
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v6.3.5"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-09-12T10:11:35+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v5.5.0",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
"reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
"shasum": ""
},
"require": {
"ext-pcre": "*",
"graham-campbell/result-type": "^1.0.2",
"php": "^7.1.3 || ^8.0",
"phpoption/phpoption": "^1.8",
"symfony/polyfill-ctype": "^1.23",
"symfony/polyfill-mbstring": "^1.23.1",
"symfony/polyfill-php80": "^1.23.1"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"ext-filter": "*",
"phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25"
},
"suggest": {
"ext-filter": "Required to use the boolean validator."
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": true
},
"branch-alias": {
"dev-master": "5.5-dev"
}
},
"autoload": {
"psr-4": {
"Dotenv\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Vance Lucas",
"email": "vance@vancelucas.com",
"homepage": "https://github.com/vlucas"
}
],
"description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
"keywords": [
"dotenv",
"env",
"environment"
],
"support": {
"issues": "https://github.com/vlucas/phpdotenv/issues",
"source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
"type": "tidelift"
}
],
"time": "2022-10-16T01:01:54+00:00"
},
{
"name": "webmozart/assert",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"php": "^7.2 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<0.12.20",
"vimeo/psalm": "<4.6.1 || 4.6.2"
},
"require-dev": {
"phpunit/phpunit": "^8.5.13"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.10-dev"
}
},
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
}
],
"description": "Assertions to validate method input/output with nice error messages.",
"keywords": [
"assert",
"check",
"validate"
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
},
"time": "2022-06-03T18:03:27+00:00"
},
{
"name": "zakirullin/mess",
"version": "0.8.4",
"source": {
"type": "git",
"url": "https://github.com/zakirullin/mess.git",
"reference": "71c66962b96b31071d8c05dee073d4bf6d38f6d1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zakirullin/mess/zipball/71c66962b96b31071d8c05dee073d4bf6d38f6d1",
"reference": "71c66962b96b31071d8c05dee073d4bf6d38f6d1",
"shasum": ""
},
"require": {
"php": "^7.2|^8.0"
},
"require-dev": {
"infection/infection": "^0.15|^0.20",
"phpunit/phpunit": "^8.0",
"vimeo/psalm": "4.16.1"
},
"type": "library",
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"Zakirullin\\Mess\\": "src/",
"Zakirullin\\TypedAccessor\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Artem Zakirullin",
"email": "artemzr@gmail.com"
}
],
"description": "Convenient array-related routine & better type casting",
"homepage": "https://github.com/zakirullin/mess",
"keywords": [
"array",
"assert",
"cast",
"json",
"language",
"mess",
"php",
"type"
],
"support": {
"issues": "https://github.com/zakirullin/mess/issues",
"source": "https://github.com/zakirullin/mess/tree/0.8.4"
},
"time": "2022-04-05T14:52:52+00:00"
}
],
"packages-dev": [

31
src/Card.php Normal file
View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace App;
use Zakirullin\Mess\Mess;
final readonly class Card
{
public function __construct(
public string $name,
public int $type,
public string $fullType,
public int $rarity,
public string $uid,
) {}
public static function fromArray(array $data): self
{
$mess = new Mess($data);
return new self(
name: $mess['name']->getString(),
type: $mess['type']->getInt(),
fullType: $mess['full_type']->getString(),
rarity: $mess['rarity']->getInt(),
uid: $mess['uid']->getString(),
);
}
}

View File

@ -4,10 +4,18 @@ declare(strict_types=1);
namespace App;
use Dotenv\Dotenv;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Cookie\SetCookie;
use GuzzleHttp\RequestOptions;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Webmozart\Assert\Assert;
use function Functional\map;
use function Functional\partition;
#[AsCommand(
name: 'cards:exchange',
@ -15,8 +23,187 @@ use Symfony\Component\Console\Output\OutputInterface;
)]
class ExchangeCardsCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output)
{
private const CARDS = [
144, // Удачный поворот: +4 карты
145, // Колесо Фортуны: +12 карт
146, // Белая полоса: +42 карты
147, // Прядь Кайроса: +150 карт
];
private readonly string $csrfToken;
private readonly CookieJar $cookies;
private readonly Client $client;
public function __construct(string $name = null)
{
parent::__construct($name);
$dotenv = Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();
$this->csrfToken = bin2hex(random_bytes(32));
$this->cookies = new CookieJar();
$this->cookies->setCookie(new SetCookie([
'Name' => 'csrftoken',
'Value' => $this->csrfToken,
'Domain' => 'the-tale.org',
]));
$this->client = new Client();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->login();
$output->writeln('Receive new cards');
$this->receiveNewCards();
do {
$output->writeln('Fetch cards');
$cards = $this->getCards();
$output->writeln('Find special cards');
$specialCards = array_filter($cards, static fn (Card $c) => in_array($c->type, self::CARDS));
if (count($specialCards) > 0) {
foreach ($specialCards as $card) {
$output->writeln('Use card ' . $card->name);
$this->useCard($card->uid);
}
}
$output->writeln('Wait for cards applies');
sleep(3);
$output->writeln('Receive new cards');
$this->receiveNewCards();
$cards = $this->getCards();
$output->writeln('Combine cards');
$combined = 0;
foreach ([0, 1, 2, 3] as $rarity) {
$selectedCards = array_filter($cards, static fn (Card $c) => $c->rarity === $rarity && !in_array($c->type, self::CARDS));
while (true) {
[$next, $rest] = partition(array_values($selectedCards), fn ($_, $index) => $index < 3);
if (count($next) < 3) {
break;
}
$this->combileCards(map($next, fn (Card $c) => $c->uid));
$selectedCards = $rest;
$combined++;
}
}
$output->writeln('Combined cards: ' . $combined);
} while ($combined !== 0);
return self::SUCCESS;
}
private function login()
{
$response = $this->client->request('POST', 'https://the-tale.org/accounts/auth/api/login', [
RequestOptions::HEADERS => [
'Referer' => 'https://the-tale.org/',
'X-CSRFToken' => $this->csrfToken,
],
RequestOptions::QUERY => [
'api_version' => '1.0',
'api_client' => 'anwinged-1',
],
RequestOptions::FORM_PARAMS => [
'email' => (string) $_ENV['TALE_EMAIL'],
'password' => (string) $_ENV['TALE_PASS'],
],
RequestOptions::COOKIES => $this->cookies,
]);
Assert::eq($response->getStatusCode(), 200);
}
/**
* @return Card[]
* @throws \GuzzleHttp\Exception\GuzzleException
*/
private function getCards(): array
{
$response = $this->client->request('GET', 'https://the-tale.org/game/cards/api/get-cards', [
RequestOptions::HEADERS => [
'Referer' => 'https://the-tale.org/',
],
RequestOptions::QUERY => [
'api_version' => '2.0',
'api_client' => 'anwinged-1',
],
RequestOptions::COOKIES => $this->cookies,
]);
Assert::eq($response->getStatusCode(), 200);
$data = json_decode((string) $response->getBody(), associative: true);
$cardsArray = $data['data']['cards'];
Assert::isArray($cardsArray);
return array_map(Card::fromArray(...), $cardsArray);
}
private function receiveNewCards()
{
$response = $this->client->request('POST', 'https://the-tale.org/game/cards/api/receive', [
RequestOptions::HEADERS => [
'Referer' => 'https://the-tale.org/',
'X-CSRFToken' => $this->cookies->getCookieByName('csrftoken')?->getValue(),
],
RequestOptions::QUERY => [
'api_version' => '1.0',
'api_client' => 'anwinged-1',
],
RequestOptions::COOKIES => $this->cookies,
]);
Assert::eq($response->getStatusCode(), 200);
}
private function useCard(string $uid)
{
$response = $this->client->request('POST', 'https://the-tale.org/game/cards/api/use', [
RequestOptions::HEADERS => [
'Referer' => 'https://the-tale.org/',
'X-CSRFToken' => $this->cookies->getCookieByName('csrftoken')?->getValue(),
],
RequestOptions::QUERY => [
'api_version' => '2.0',
'api_client' => 'anwinged-1',
'card' => $uid,
],
RequestOptions::COOKIES => $this->cookies,
]);
Assert::eq($response->getStatusCode(), 200);
dump((string) $response->getBody());
}
private function combileCards(array $uids)
{
$cardsData = implode('&', map($uids, fn ($uid) => 'card=' . $uid));
$response = $this->client->request('POST', 'https://the-tale.org/game/cards/api/combine', [
RequestOptions::HEADERS => [
'Referer' => 'https://the-tale.org/',
'X-CSRFToken' => $this->cookies->getCookieByName('csrftoken')?->getValue(),
'Content-Type' => 'application/x-www-form-urlencoded',
],
RequestOptions::QUERY => [
'api_version' => '3.0',
'api_client' => 'anwinged-1',
],
RequestOptions::BODY => $cardsData,
RequestOptions::COOKIES => $this->cookies,
]);
Assert::eq($response->getStatusCode(), 200);
dump((string) $response->getBody());
}
}