Implement automatic cards exchange
This commit is contained in:
parent
1ef176f3f7
commit
bfec3048d3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/vendor/
|
||||
.env
|
||||
.php-cs-fixer.cache
|
17
Taskfile.yml
17
Taskfile.yml
@ -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'
|
@ -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
662
composer.lock
generated
@ -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
31
src/Card.php
Normal 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(),
|
||||
);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user