no, šachy, no

This commit is contained in:
Histmy 2023-02-20 21:21:55 +01:00
parent 83e344487f
commit bec2cb7016
9 changed files with 1253 additions and 11 deletions

375
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "denim_3001",
"version": "3001.45.1",
"version": "3001.46.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "denim_3001",
"version": "3001.45.1",
"version": "3001.46.0",
"license": "ISC",
"dependencies": {
"@discordjs/voice": "^0.14.0",
@ -15,13 +15,16 @@
"node-fetch": "^2.6.1",
"opusscript": "^0.0.8",
"play-dl": "^1.9.6",
"tiny-typed-emitter": "^2.1.0",
"tweetnacl": "^1.0.3"
},
"devDependencies": {
"@types/jest": "^29.2.4",
"@types/js-levenshtein": "^1.1.1",
"@types/node-fetch": "^2.6.2",
"jest": "^29.3.1"
"jest": "^29.3.1",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.1.2"
}
},
"node_modules/@ampproject/remapping": {
@ -608,6 +611,28 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@discordjs/builders": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.4.0.tgz",
@ -1083,6 +1108,30 @@
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
"dev": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"dev": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"dev": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
},
"node_modules/@types/babel__core": {
"version": "7.1.20",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
@ -1237,6 +1286,27 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
"node_modules/acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true,
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@ -1289,6 +1359,12 @@
"node": ">= 8"
}
},
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true
},
"node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@ -1620,6 +1696,12 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -1684,6 +1766,15 @@
"node": ">=8"
}
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/diff-sequences": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
@ -2839,9 +2930,9 @@
"dev": true
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
@ -2923,6 +3014,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"node_modules/makeerror": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@ -2993,6 +3090,15 @@
"node": "*"
}
},
"node_modules/minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -3655,6 +3761,11 @@
"node": ">=8"
}
},
"node_modules/tiny-typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="
},
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@ -3708,6 +3819,72 @@
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.2.tgz",
"integrity": "sha512-zvHx3VM83m2WYCE8XL99uaM7mFwYSkjR2OZti98fabHrwkjsCvgwChda5xctein3xGOyaQhtTeDq/1H/GNvF3A=="
},
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dev": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/tsconfig-paths": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz",
"integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==",
"dev": true,
"dependencies": {
"json5": "^2.2.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/tsconfig-paths/node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/tslib": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
@ -3739,6 +3916,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"dev": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/undici": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.14.0.tgz",
@ -3781,6 +3972,12 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true
},
"node_modules/v8-to-istanbul": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
@ -3937,6 +4134,15 @@
"node": ">=12"
}
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@ -4393,6 +4599,27 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
"@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
"requires": {
"@jridgewell/trace-mapping": "0.3.9"
},
"dependencies": {
"@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
}
}
},
"@discordjs/builders": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.4.0.tgz",
@ -4768,6 +4995,30 @@
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
"dev": true
},
"@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"dev": true
},
"@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"dev": true
},
"@tsconfig/node16": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
},
"@types/babel__core": {
"version": "7.1.20",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
@ -4921,6 +5172,18 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
"acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"dev": true
},
"acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true
},
"ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@ -4955,6 +5218,12 @@
"picomatch": "^2.0.4"
}
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@ -5205,6 +5474,12 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -5249,6 +5524,12 @@
"integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
"dev": true
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
},
"diff-sequences": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
@ -6111,9 +6392,9 @@
"dev": true
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"kleur": {
@ -6171,6 +6452,12 @@
"semver": "^6.0.0"
}
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"makeerror": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@ -6226,6 +6513,12 @@
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"dev": true
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -6680,6 +6973,11 @@
"minimatch": "^3.0.4"
}
},
"tiny-typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="
},
"tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@ -6720,6 +7018,46 @@
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.2.tgz",
"integrity": "sha512-zvHx3VM83m2WYCE8XL99uaM7mFwYSkjR2OZti98fabHrwkjsCvgwChda5xctein3xGOyaQhtTeDq/1H/GNvF3A=="
},
"ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dev": true,
"requires": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
}
},
"tsconfig-paths": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz",
"integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==",
"dev": true,
"requires": {
"json5": "^2.2.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
},
"dependencies": {
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true
}
}
},
"tslib": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
@ -6742,6 +7080,13 @@
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true
},
"typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"dev": true,
"peer": true
},
"undici": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.14.0.tgz",
@ -6765,6 +7110,12 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true
},
"v8-to-istanbul": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
@ -6882,6 +7233,12 @@
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "denim_3001",
"version": "3001.45.1",
"version": "3001.46.0",
"description": "Toto je velmi kvalitní bot.",
"repository": {
"url": "https://github.com/Histmy/Denim-Bot/"
@ -20,12 +20,15 @@
"node-fetch": "^2.6.1",
"opusscript": "^0.0.8",
"play-dl": "^1.9.6",
"tiny-typed-emitter": "^2.1.0",
"tweetnacl": "^1.0.3"
},
"devDependencies": {
"@types/jest": "^29.2.4",
"@types/js-levenshtein": "^1.1.1",
"@types/node-fetch": "^2.6.2",
"jest": "^29.3.1"
"jest": "^29.3.1",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.1.2"
}
}

15
res/sachy/error.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chyba - šach.ml</title>
</head>
<body>
$error
</body>
</html>

32
res/sachy/index.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Šach.ml</title>
</head>
<body>
<h1>Šach.ml</h1>
<p>Vytajte na úvodní stránce DENIM3001 šachů!</p>
<p id="sem"></p>
<script>
// Jo, použivám JS na render :fujjjj:
// Prasárna, jsem si vědom, ale je to nejjednoduší :ksd:
const pecko = document.querySelector("#sem");
if ($logged) {
pecko.innerHTML = "Jsi přihlášen jako $jmeno. Pro odhlášení pokračuj <a href='logout'>sem</a>.";
} else {
pecko.innerHTML = "Pro přihlášení pokračujte <a href='login'>sem</a>.";
}
</script>
</body>
</html>

24
res/sachy/promotion.html Normal file
View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Proměna</title>
</head>
<body>
<h1>Gratuluju! Provádíš speciální tah "proměna"!</h1>
<p>Aby ale tento tah mohl být dokončen, vyber, prosím, na co se má tvůj pěšec proměnit:</p>
<div>
<a href="?q">Královna</a>
<a href="?n">Jezdec</a>
<a href="?r">Věž</a>
<a href="?b">Střelec</a>
</div>
</body>
</html>

19
res/sachy/tah.html Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Šach.ml - $title</title>
</head>
<body>
$content
<script>
if ($podminka)
addEventListener("load", close);
</script>
</body>
</html>

522
src/modules/sachy.ts Normal file
View File

@ -0,0 +1,522 @@
// Jo, šachec, :sjetec:
import { APIEmbed, Message } from "discord.js";
import { Modul, SRecord } from "../utils/types";
import { fokinLookupTable, klikance, pocetKeStrane } from "../utils/sachyEtc";
import { emiter } from "../utils/sachyServer";
const hry: SRecord<Hra> = {};
const hraci: SRecord<string> = {};
const smery = [-8, 1, 8, -1, -7, 9, 7, -9];
const mkPis = (barva: Figurka["barva"], typ: Figurka["typ"]) => ({ barva, typ, netahnuta: true, enPassantovatelna: false });
function createGame(kanel: string, bilej: string, cernej: string, mes: Message) {
const deska: Deska = [...new Array(64)];
for (let i = 0; i < 8; i++) {
deska[i + 8] = mkPis("cerna", "pawn");
deska[i + 48] = mkPis("bila", "pawn");
}
deska[0] = mkPis("cerna", "rook");
deska[7] = mkPis("cerna", "rook");
deska[56] = mkPis("bila", "rook");
deska[63] = mkPis("bila", "rook");
deska[1] = mkPis("cerna", "knight");
deska[6] = mkPis("cerna", "knight");
deska[57] = mkPis("bila", "knight");
deska[62] = mkPis("bila", "knight");
deska[2] = mkPis("cerna", "bishop");
deska[5] = mkPis("cerna", "bishop");
deska[58] = mkPis("bila", "bishop");
deska[61] = mkPis("bila", "bishop");
deska[4] = mkPis("cerna", "king");
deska[60] = mkPis("bila", "king");
deska[3] = mkPis("cerna", "queen");
deska[59] = mkPis("bila", "queen");
const hra: Hra = {
bila: bilej,
cerna: cernej,
deska,
hraje: "bila",
tahy: [],
message: mes
};
hry[kanel] = hra;
return hra;
}
function jeCheck(barva: Hra["hraje"], deska: Deska) {
let check = false;
const index = deska.findIndex(pis => pis?.typ == "king" && pis.barva == barva);
// Od tahačů
for (let smer = 0; smer < 8; smer++) {
for (let n = 1; n <= pocetKeStrane[index][smer]; n++) {
const target = index + smery[smer] * n;
const pisNaTargetu = deska[target];
if (pisNaTargetu?.barva != barva && [(smer < 4 ? "rook" : "bishop"), "queen"].includes(pisNaTargetu?.typ || "")) return true;
if (pisNaTargetu) break;
}
}
// Od koliků
[[-1, 2], [1, 2], [-2, 1], [2, 1], [-2, -1], [2, -1], [-1, -2], [1, -2]].forEach(smery => {
const x = smery[0] > 0 ? 1 : 3;
const y = smery[1] > 0 ? 2 : 0;
// Estli je mimo board
if (pocetKeStrane[index][x] < Math.abs(smery[0]) || pocetKeStrane[index][y] < Math.abs(smery[1])) return;
const target = index + (8 * smery[1] + smery[0]);
const pis = deska[target];
// Estli už tam felí náš
if (pis?.barva == barva) return;
if (pis?.typ == "knight") check = true;
});
// od pawnů
[7, 9].forEach(i => {
let pis = deska[index - i];
if (pis?.typ == "pawn" && pis.barva != barva) check = true;
});
// od králika
for (let smer = 0; smer < 8; smer++) {
if (pocetKeStrane[index][smer] == 0) continue;
if (deska[index + smery[smer]]?.typ == "king") return true;
}
return check;
}
function tahyProJezdiciPisi(index: number, pis: "queen" | "bishop" | "rook", deska: Deska) {
const tahy: number[] = [];
const barva = deska[index]!.barva;
const startSmer = pis == "bishop" ? 4 : 0;
const endSmer = pis == "rook" ? 4 : 8;
for (let smer = startSmer; smer < endSmer; smer++) {
for (let n = 1; n <= pocetKeStrane[index][smer]; n++) {
const target = index + smery[smer] * n;
const pisNaTargetu = deska[target];
if (pisNaTargetu?.barva == barva) break;
tahy.push(target);
if (pisNaTargetu && pisNaTargetu.barva != barva) break;
}
}
return tahy;
}
function tahyProKoniky(index: number, deska: Deska) {
const tahy: number[] = [];
const barva = deska[index]!.barva;
[[-1, 2], [1, 2], [-2, 1], [2, 1], [-2, -1], [2, -1], [-1, -2], [1, -2]].forEach(smery => {
const x = smery[0] > 0 ? 1 : 3;
const y = smery[1] > 0 ? 2 : 0;
// Estli je mimo board
if (pocetKeStrane[index][x] < Math.abs(smery[0]) || pocetKeStrane[index][y] < Math.abs(smery[1])) return;
const target = index + (8 * smery[1] + smery[0]);
const pis = deska[target];
// Estli už tam felí náš
if (pis?.barva == barva) return;
tahy.push(target);
});
return tahy;
}
function tahyProPawny(index: number, deska: Deska) {
const tahy: number[] = [];
const barva = deska[index]!.barva;
// Takey
if (index % 8 != 0 && deska[index - 9] && deska[index - 9]!.barva != barva)
tahy.push(index - 9);
if (index % 8 != 7 && deska[index - 7] && deska[index - 7]!.barva != barva)
tahy.push(index - 7);
// Blokáda
if (deska[index - 8])
return tahy;
tahy.push(index - 8);
// Double-advance
if (deska[index]?.netahnuta && !deska[index - 16])
tahy.push(index - 16);
// en croassant
if (deska[index - 1]?.enPassantovatelna)
tahy.push(index - 9);
if (deska[index + 1]?.enPassantovatelna)
tahy.push(index - 7);
return tahy;
}
function tahyProKrale(index: number, deska: Deska) {
const tahy: number[] = [];
const barva = deska[index]!.barva;
for (let smer = 0; smer < 8; smer++) {
const target = index + smery[smer];
if (pocetKeStrane[index][smer] != 0 && deska[target]?.barva != barva) tahy.push(target);
}
// Castling
if (jeCheck(barva, deska)) return tahy;
for (let strana = 0; strana < 2; strana++) {
const offset = (barva == "bila" ? (strana ? 3 : -4) : (strana ? 4 : -3));
const rook = deska[index + offset];
if (deska[index]!.netahnuta && rook?.typ == "rook" && rook.netahnuta) {
let muze = true;
for (let i = (strana > 0 ? 1 : -1); (strana > 0 ? i < offset : i > offset); strana > 0 ? i++ : i--) {
if (deska[index + i]) {
muze = false;
break;
}
const novaDeska = [...deska];
novaDeska[index + i] = deska[index];
novaDeska[index] = undefined;
if (jeCheck(barva, novaDeska))
muze = false;
}
if (muze) tahy.push(index + (2 * (offset > 0 ? 1 : -1)));
}
}
return tahy;
}
function legalniTahy(index: number, deska: Deska) {
let tahy: number[];
const pis = deska[index]!;
if (pis.typ == "queen" || pis.typ == "bishop" || pis.typ == "rook")
tahy = tahyProJezdiciPisi(index, pis.typ, deska);
else if (pis.typ == "knight")
tahy = tahyProKoniky(index, deska);
else if (pis.typ == "pawn")
tahy = tahyProPawny(index, deska);
else
tahy = tahyProKrale(index, deska);
// Otestovat jestli jsou fakt legální
for (let i = 0; i < tahy.length; i++) {
const tah = tahy[i];
if (jeCheck(pis.barva, udelejTah(index, tah, deska))) {
tahy.splice(i, 1);
i--;
}
};
return tahy;
}
function udelejTah(z: number, kam: number, deska: Deska, fakt?: true) {
const mojeDeska = [...deska];
const pis = mojeDeska[z]!;
if (fakt) pis.netahnuta = false;
mojeDeska[kam] = pis;
mojeDeska[z] = undefined;
// croassant
if (pis.typ == "pawn" && mojeDeska[kam + 8]?.enPassantovatelna)
mojeDeska[kam + 8] = undefined;
if (fakt)
mojeDeska.forEach(pole => {
if (!pole) return;
pole.enPassantovatelna = false;
});
if (fakt && pis.typ == "pawn" && z - kam == 16) pis.enPassantovatelna = true;
// Castling
const rozdil = z - kam;
if (pis.typ == "king" && Math.abs(rozdil) == 2) {
const i = (rozdil > 0 ? 56 : 63);
mojeDeska[(rozdil > 0 ? kam + 1 : kam - 1)] = mojeDeska[i];
mojeDeska[i] = undefined;
}
return mojeDeska;
}
function renderHra(hra: Hra, konec?: true) {
const deska = [...hra.deska];
const vybranejPis = hra.vybranejPis;
const embed: APIEmbed = {
fields: [
{
name: "Sachy sou",
value: "",
inline: true
},
{
name: "gamesa vole",
value: "",
inline: true
}
]
};
hra.tahy = [];
if (typeof vybranejPis == "number") hra.tahy = legalniTahy(vybranejPis, deska);
for (let i = 0; i < 64; i++) {
const figurka = deska[i];
const klikanec = klikance[i];
const prvniDuhy = (i % 8) < 4 ? 0 : 1;
const field = embed.fields![prvniDuhy];
const cernyPozadi = (Math.floor(i / 8) + (i % 8)) % 2;
if (!figurka) {
field.value += hra.tahy.includes(i)
? (cernyPozadi ? `[<:h:1066376051422404628>](http://šach.ml/${klikanec})` : `[<:h:1066376343807336488>](http://šach.ml/${klikanec})`)
: (cernyPozadi ? "🟩" : "⬜");
} else {
let klic = (cernyPozadi ? "g" : "w") + (figurka.barva == "bila" ? "w" : "b") + figurka.typ;
if (hra.tahy.includes(i)) klic += "t";
if (figurka.typ == "king" && figurka.barva == hra.hraje && jeCheck(figurka.barva, deska)) klic += "c";
const emout = fokinLookupTable[klic];
const figurkaStr = `<:h:${emout}>`;
if (!konec && figurka.barva == hra.hraje || hra.tahy.includes(i)) {
field.value += `[${figurkaStr}](http://šach.ml/${klikanec})`;
} else {
field.value += figurkaStr;
}
}
if (i % 8 == 3 || i % 8 == 7) field.value += "\n";
}
return embed;
}
function konec(mes: Message, hra: Hra, duvod: string) {
mes.edit({ content: `hra zkoncila ${duvod}`, embeds: [renderHra(hra, true)] });
delete hraci[hra.bila];
delete hraci[hra.cerna];
delete hry[mes.channelId];
}
function prekreslitHru(hra: Hra) {
const mes = hra.message;
// Checkmate
if (jeCheck(hra.hraje, hra.deska)) {
let mat = true;
hra.deska.forEach((pole, i) => {
if (!pole || pole.barva != hra.hraje) return;
if (legalniTahy(i, hra.deska).length != 0) mat = false;
});
if (mat)
return konec(mes, hra, `${hra.hraje} je zasachmatovana`);
}
// Stalemate
let pat = true;
hra.deska.forEach((pole, i) => {
if (!pole || pole.barva != hra.hraje) return;
if (legalniTahy(i, hra.deska).length != 0) pat = false;
});
if (pat)
return konec(mes, hra, `achylova sytuace`);
mes.edit({ content: "", embeds: [renderHra(hra)] });
}
emiter.on("tah", (hrac, policko, respond, promo) => {
const channelId = hraci[hrac];
if (!channelId) return respond("Však vůbec nehraješ ty magore");
const hra = hry[channelId];
const barva = hra.bila == hrac ? "bila" : "cerna";
if (hra.hraje != barva) return respond("Teď nehraješ ty ty magore");
const index = klikance.findIndex(e => e == policko);
if (typeof index != "number") return respond("Co to meleš za hovna?");
// Kliknul na stejnej pis
if (hra.vybranejPis == index) {
hra.vybranejPis = undefined;
prekreslitHru(hra);
return respond();
}
// Kliknul nějakej pis
const pis = hra.deska[index];
if (pis && pis.barva == barva) {
hra.vybranejPis = index;
prekreslitHru(hra);
return respond();
}
// Táhnul
if (typeof hra.vybranejPis == "number" && hra.tahy.includes(index)) {
// Promotuje
if (hra.deska[hra.vybranejPis!]?.typ == "pawn" && index < 8) {
if (!promo) return respond("--promote--");
const promoNa = promo == "q" ? "queen" :
promo == "r" ? "rook" :
promo == "n" ? "knight" :
promo == "b" ? "bishop" : undefined;
if (!promoNa) return respond("Co to meleš za hovna?");
hra.deska[hra.vybranejPis] = mkPis(barva, promoNa);
}
hra.deska = udelejTah(hra.vybranejPis, index, hra.deska, true);
hra.vybranejPis = undefined;
hra.hraje = barva == "bila" ? "cerna" : "bila";
hra.deska = hra.deska.reduce<Deska>((acc, item) => [item].concat(acc), []);
prekreslitHru(hra);
return respond();
}
respond("cos to tam zandal");
});
const exp: Modul = {
more_komandy: {
sachy: {
DMUnsafe: true,
run: async mes => {
if (hry[mes.channelId]) return "nejze tady se us hraej";
const druhej = mes.mentions.members?.first()?.id;
if (!druhej) return "no sam asi hrat nebudez vet";
for (const player of [mes.author.id, druhej]) {
if (hraci[player]) return "zakaz symultanki";
};
const message = await mes.channel.send("hraj zopiciva");
const hra = createGame(mes.channelId, mes.author.id, druhej, message);
hraci[mes.author.id] = mes.channelId;
hraci[druhej] = mes.channelId;
message.edit({ content: "", embeds: [renderHra(hra)] });
}
},
jasevzdavam: mes => {
if (!hraci[mes.author.id]) return "vsak nehrajes magore";
const hra = hry[mes.channelId];
if (!hra) return "tadi nehrajes";
konec(hra.message, hra, `${mes.author} je pusi`);
}
}
};
module.exports = exp;
type Hra = {
bila: string;
cerna: string;
deska: Deska;
hraje: "bila" | "cerna";
tahy: number[];
vybranejPis?: number;
message: Message;
};
type Deska = (Figurka | undefined)[];
type Figurka = {
barva: "bila" | "cerna";
typ: "pawn" | "rook" | "knight" | "bishop" | "queen" | "king";
netahnuta: boolean;
enPassantovatelna: boolean;
};

93
src/utils/sachyEtc.ts Normal file
View File

@ -0,0 +1,93 @@
import { Message } from "discord.js";
import { SRecord } from "./types";
export const fokinLookupTable: SRecord<string> = {
wwking: "1045048659508727961",
gwking: "1045048657826824243",
wbking: "1039994234553507860",
gbking: "1039994216673185843",
wwrook: "1039994248273072228",
gwrook: "1039994231395192903",
wbrook: "1039994241100820500",
gbrook: "1039994225380573194",
wwknight: "1039994245412565012",
gwknight: "1039994228559843328",
wbknight: "1039994236348661820",
gbknight: "1039994219110088726",
wwbishop: "1039994244158459924",
gwbishop: "1039994226844373023",
wbbishop: "1039994232842240162",
gbbishop: "1039994215217778738",
wwqueen: "1039990754434625656",
gwqueen: "1039991198309425172",
wbqueen: "1039994239729287230",
gbqueen: "1039994224025817138",
wwpawn: "1039994246888964106",
gwpawn: "1039994230027858030",
wbpawn: "1039994237887975494",
gbpawn: "1039994222306152498",
wwrookt: "1066376081478778930",
gwrookt: "1066376061392261121",
wbrookt: "1066376070586179724",
gbrookt: "1066376049732091955",
wwknightt: "1066376345598316655",
gwknightt: "1066376055646060585",
wbknightt: "1066376065422991470",
gbknightt: "1066376042425622650",
wwbishopt: "1066376074033897522",
gwbishopt: "1066376054169669672",
wbbishopt: "1066376063862718464",
gbbishopt: "1066371034795753522",
wwqueent: "1066376348609818624",
gwqueent: "1066376059546775612",
wbqueent: "1066376340770652232",
gbqueent: "1066376047194550402",
wwpawnt: "1066376078119141456",
gwpawnt: "1066376057009217586",
wbpawnt: "1066376067956363294",
gbpawnt: "1066376044975751268",
wwkingc: "1068186011311542343",
gwkingc: "1068186006869778533",
wbkingc: "1068186008824320134",
gbkingc: "1068186004386758706"
};
export const klikance = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "-", "_"
];
export const pocetKeStrane: number[][] = [];
for (let sloupec = 0; sloupec < 8; sloupec++) {
for (let radek = 0; radek < 8; radek++) {
const nahoru = radek;
const dolu = 7 - radek;
const vlevo = sloupec;
const vpravo = 7 - sloupec;
const index = 8 * radek + sloupec;
pocetKeStrane[index] = [
nahoru,
vpravo,
dolu,
vlevo,
Math.min(nahoru, vpravo),
Math.min(vpravo, dolu),
Math.min(dolu, vlevo),
Math.min(vlevo, nahoru)
];
}
}

177
src/utils/sachyServer.ts Normal file
View File

@ -0,0 +1,177 @@
import { createServer, IncomingMessage, ServerResponse } from "http";
import { SRecord } from "./types";
import { join } from "path";
import { readFileSync } from "fs";
import fetch from "node-fetch";
import { TypedEmitter } from "tiny-typed-emitter";
import { log, rand } from "./utils";
const basePath = join(__dirname, "../../res/sachy");
const sessions: SRecord<Session> = {};
const indexStranka = readFileSync(`${basePath}/index.html`).toString();
const tahStranka = readFileSync(`${basePath}/tah.html`).toString();
const promoStranka = readFileSync(`${basePath}/promotion.html`).toString();
const chybaStranka = readFileSync(`${basePath}/error.html`).toString();
interface Eventy {
tah: (playerId: string, square: string, verify: (err?: string) => void, promotionType?: string) => void;
}
export const emiter = new TypedEmitter<Eventy>();
function parseCookies(cookies?: string) {
const list: SRecord<string> = {};
if (!cookies) return list;
cookies.split(`;`).forEach(function (cookie) {
let [name, ...rest] = cookie.split(`=`);
name = name?.trim();
if (!name) return;
const value = rest.join(`=`).trim();
if (!value) return;
list[name] = decodeURIComponent(value);
});
return list;
}
function generateId() {
while (true) {
const id = Math.round(Math.random() * 3554597877099506 + 101560562963469).toString(36);
if (!Object.keys(sessions).includes(id)) return id;
}
}
function startSession(req: IncomingMessage, res: ServerResponse): Session {
const cookies = parseCookies(req.headers.cookie);
const sessionId = cookies.sachySession;
// Jestli on něco pošle a my to máme taky, akorát updateneme dýlku uložení
if (sessionId && sessions[sessionId]) {
sessions[sessionId].lastInteractedAt = Date.now();
res.setHeader("Set-Cookie", `sachySession=${sessionId}; Max-Age=3600`);
return sessions[sessionId];
}
const randomId = generateId();
sessions[randomId] = { logedIn: false, lastInteractedAt: Date.now() };
res.setHeader("Set-Cookie", `sachySession=${randomId}; Max-Age=3600`);
return sessions[randomId];
}
// Session garbage-collection
setInterval(() => {
for (const key in sessions) {
if ((sessions[key].lastInteractedAt + 36e5) > Date.now()) return;
delete sessions[key];
}
}, 3e5);
function redirect(res: ServerResponse, path: string) {
res.statusCode = 302;
res.setHeader("Location", path);
res.end("302 gone");
}
function login(session: Session, res: ServerResponse) {
if (session.logedIn) return "uzjsi prihlasenej";
redirect(res, "https://discord.com/api/oauth2/authorize?client_id=1064269692165963826&redirect_uri=http%3A%2F%2F%C5%A1ach.ml%2Foauth&response_type=code&scope=identify");
}
function logout(session: Session, res: ServerResponse) {
session.logedIn = false;
redirect(res, "/");
}
function loginErr(res: ServerResponse) {
res.end(chybaStranka.replaceAll("$error", "Prihlaseni se nezdarilo, zkus to znovu a jestli to nefunguje furt, tak si holt stezuj no"));
}
async function overeni(url: string, session: Session, res: ServerResponse) {
const code = (new URL(url, "h:/")).searchParams.get("code");
const data = await fetch("https://discord.com/api/v10/oauth2/token", { method: "post", body: `client_id=1064269692165963826&client_secret=8HHKODmb1HTLWoJGVyoinSU_9323dEla&grant_type=authorization_code&code=${code}&redirect_uri=http%3A%2F%2F%C5%A1ach.ml%2Foauth`, headers: { "Content-type": "application/x-www-form-urlencoded" } })
.then(r => r.json())
.catch(err => log("sachy jednotka:", err));
if (!data?.access_token) return loginErr(res);
const uzivatel = await fetch("https://discord.com/api/v10/users/@me", { headers: { authorization: `Bearer ${data.access_token}` } })
.then(r => r.json())
.catch(err => log("sachy dva:", err));
if (!uzivatel) return loginErr(res);
session.logedIn = true;
session.discordId = uzivatel.id;
session.discordName = `${uzivatel.username}#${uzivatel.discriminator}`;
redirect(res, session.redirect || "/");
}
function validateMove(res: ServerResponse, session: Session, url: string) {
if (!session.logedIn) return redirect(res, `/login?redirect=${url}`);
const pismenko = url[1];
const promoNa: string | undefined = url[3];
function overeni(err?: string) {
if (err == "--promote--")
return res.end(promoStranka);
const response = tahStranka.replace("$title", err ? "Neplatej tah" : "Úspšný tah")
.replace("$content", err ?? "Kvalitní tah!")
.replace("$podminka", err ? "0" : "1");
res.end(response);
}
emiter.emit("tah", session.discordId!, pismenko, overeni, promoNa);
}
const server = createServer((req, res) => {
const session = startSession(req, res);
// TODO: Natipovaný, protože vscode jebe (možná někdy přestane, v tom případě odebrat pls)
const url: URL = new URL(req.url!, "http://šach.ml");
if (url.pathname.length == 2 || url.pathname.length == 4) return validateMove(res, session, req.url!);
if (req.url?.startsWith("/oauth")) return overeni(req.url, session, res);
switch (url.pathname) {
case "/":
const response = indexStranka.replace("$logged", session.logedIn ? "1" : "0")
.replace("$jmeno", session.discordName ?? "");
return res.end(response);
case "/login":
const path = url.searchParams.get("redirect");
session.redirect = path || "";
return login(session, res);
case "/logout":
return logout(session, res);
default:
redirect(res, "/");
}
});
server.listen(50236);
type Session = {
logedIn: boolean;
discordId?: string;
discordName?: string;
lastInteractedAt: number;
redirect?: string;
};