From e387c6e4edfcd0f1bb01ca98bcf2701d0e63160e Mon Sep 17 00:00:00 2001 From: paring Date: Wed, 10 May 2023 15:42:54 +0900 Subject: [PATCH] hi crack --- .vscode/settings.json | 3 + package.json | 11 +- pnpm-lock.yaml | 600 ++++++++++++++++++++++++++++--- src/index.ts | 177 +++++++++ src/types/events.ts | 567 +++++++++++++++++++++++++++++ src/types/index.ts | 3 + src/types/level.ts | 78 ++++ src/types/types.ts | 287 +++++++++++++++ parser.js => src/utils/parser.ts | 8 +- tsconfig.json | 109 ++++++ wowsans.js | 72 ---- 11 files changed, 1788 insertions(+), 127 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/index.ts create mode 100644 src/types/events.ts create mode 100644 src/types/index.ts create mode 100644 src/types/level.ts create mode 100644 src/types/types.ts rename parser.js => src/utils/parser.ts (78%) create mode 100644 tsconfig.json delete mode 100644 wowsans.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cccb509 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.preferences.importModuleSpecifierEnding": "js" +} diff --git a/package.json b/package.json index 1a25fc4..9e0d00f 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,21 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "start": "tsx src" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { + "inquirer": "^9.2.2", "json5": "^2.2.3", - "sharp": "^0.32.1", - "yargs": "^17.7.2" + "sharp": "^0.32.1" }, "devDependencies": { - "@types/node": "^20.1.1" + "@types/inquirer": "^9.0.3", + "@types/node": "^20.1.1", + "tsx": "^3.12.7", + "typescript": "^5.0.4" }, "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98ee636..839f07f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,32 +1,285 @@ lockfileVersion: '6.0' dependencies: + inquirer: + specifier: ^9.2.2 + version: 9.2.2 json5: specifier: ^2.2.3 version: 2.2.3 sharp: specifier: ^0.32.1 version: 0.32.1 - yargs: - specifier: ^17.7.2 - version: 17.7.2 devDependencies: + '@types/inquirer': + specifier: ^9.0.3 + version: 9.0.3 '@types/node': specifier: ^20.1.1 version: 20.1.1 + tsx: + specifier: ^3.12.7 + version: 3.12.7 + typescript: + specifier: ^5.0.4 + version: 5.0.4 packages: + /@esbuild-kit/cjs-loader@2.4.2: + resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==} + dependencies: + '@esbuild-kit/core-utils': 3.1.0 + get-tsconfig: 4.5.0 + dev: true + + /@esbuild-kit/core-utils@3.1.0: + resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} + dependencies: + esbuild: 0.17.18 + source-map-support: 0.5.21 + dev: true + + /@esbuild-kit/esm-loader@2.5.5: + resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==} + dependencies: + '@esbuild-kit/core-utils': 3.1.0 + get-tsconfig: 4.5.0 + dev: true + + /@esbuild/android-arm64@0.17.18: + resolution: {integrity: sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.18: + resolution: {integrity: sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.18: + resolution: {integrity: sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.17.18: + resolution: {integrity: sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.17.18: + resolution: {integrity: sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.17.18: + resolution: {integrity: sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.17.18: + resolution: {integrity: sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.17.18: + resolution: {integrity: sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.17.18: + resolution: {integrity: sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.18: + resolution: {integrity: sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.17.18: + resolution: {integrity: sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.17.18: + resolution: {integrity: sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.17.18: + resolution: {integrity: sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.17.18: + resolution: {integrity: sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.17.18: + resolution: {integrity: sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.17.18: + resolution: {integrity: sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.17.18: + resolution: {integrity: sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.17.18: + resolution: {integrity: sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.17.18: + resolution: {integrity: sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.17.18: + resolution: {integrity: sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.17.18: + resolution: {integrity: sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.17.18: + resolution: {integrity: sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@types/inquirer@9.0.3: + resolution: {integrity: sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==} + dependencies: + '@types/through': 0.0.30 + rxjs: 7.8.1 + dev: true + /@types/node@20.1.1: resolution: {integrity: sha512-uKBEevTNb+l6/aCQaKVnUModfEMjAl98lw2Si9P5y4hLu9tm6AlX2ZIoXZX6Wh9lJueYPrGPKk5WMCNHg/u6/A==} dev: true + /@types/through@0.0.30: + resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} + dependencies: + '@types/node': 20.1.1 + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: false + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: false + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: false + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -46,6 +299,10 @@ packages: readable-stream: 3.6.2 dev: false + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: @@ -53,17 +310,47 @@ packages: ieee754: 1.2.1 dev: false + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /chalk@5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: false + /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: false - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + restore-cursor: 3.1.0 + dev: false + + /cli-spinners@2.9.0: + resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==} + engines: {node: '>=6'} + dev: false + + /cli-width@4.0.0: + resolution: {integrity: sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==} + engines: {node: '>= 12'} + dev: false + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} dev: false /color-convert@2.0.1: @@ -104,6 +391,12 @@ packages: engines: {node: '>=4.0.0'} dev: false + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: false + /detect-libc@2.0.1: resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} engines: {node: '>=8'} @@ -119,9 +412,39 @@ packages: once: 1.4.0 dev: false - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} + /esbuild@0.17.18: + resolution: {integrity: sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.18 + '@esbuild/android-arm64': 0.17.18 + '@esbuild/android-x64': 0.17.18 + '@esbuild/darwin-arm64': 0.17.18 + '@esbuild/darwin-x64': 0.17.18 + '@esbuild/freebsd-arm64': 0.17.18 + '@esbuild/freebsd-x64': 0.17.18 + '@esbuild/linux-arm': 0.17.18 + '@esbuild/linux-arm64': 0.17.18 + '@esbuild/linux-ia32': 0.17.18 + '@esbuild/linux-loong64': 0.17.18 + '@esbuild/linux-mips64el': 0.17.18 + '@esbuild/linux-ppc64': 0.17.18 + '@esbuild/linux-riscv64': 0.17.18 + '@esbuild/linux-s390x': 0.17.18 + '@esbuild/linux-x64': 0.17.18 + '@esbuild/netbsd-x64': 0.17.18 + '@esbuild/openbsd-x64': 0.17.18 + '@esbuild/sunos-x64': 0.17.18 + '@esbuild/win32-arm64': 0.17.18 + '@esbuild/win32-ia32': 0.17.18 + '@esbuild/win32-x64': 0.17.18 + dev: true + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} dev: false /expand-template@2.0.3: @@ -129,19 +452,55 @@ packages: engines: {node: '>=6'} dev: false + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: false + + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: false + /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: false - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: false + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /get-tsconfig@4.5.0: + resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==} + dev: true /github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} dev: false + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -154,6 +513,27 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: false + /inquirer@9.2.2: + resolution: {integrity: sha512-VV2ZOZe4ilLlOgEo7drIdzbi+EYJcNty0leF2vJq49zOW8+IoK1miJ+V5FjZY/X21Io29j66T/AiqHvS4tPIrw==} + engines: {node: '>=14.18.0'} + dependencies: + ansi-escapes: 4.3.2 + chalk: 5.2.0 + cli-cursor: 3.1.0 + cli-width: 4.0.0 + external-editor: 3.1.0 + figures: 5.0.0 + lodash: 4.17.21 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 7.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + dev: false + /is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} dev: false @@ -163,12 +543,39 @@ packages: engines: {node: '>=8'} dev: false + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: false + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: false + + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: false + /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true dev: false + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: false + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -176,6 +583,11 @@ packages: yallist: 4.0.0 dev: false + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: false + /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -189,6 +601,11 @@ packages: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: false + /mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: false + /napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} dev: false @@ -210,6 +627,33 @@ packages: wrappy: 1.0.2 dev: false + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: false + + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.0 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: false + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: false + /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -255,15 +699,32 @@ packages: util-deprecate: 1.0.2 dev: false - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 dev: false + /run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: false + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.5.0 + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + /semver@7.5.0: resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==} engines: {node: '>=10'} @@ -287,6 +748,10 @@ packages: tunnel-agent: 0.6.0 dev: false + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false + /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} dev: false @@ -305,6 +770,18 @@ packages: is-arrayish: 0.3.2 dev: false + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -327,11 +804,25 @@ packages: ansi-regex: 5.0.1 dev: false + /strip-ansi@7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: false + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} dev: false + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: false + /tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} dependencies: @@ -352,19 +843,61 @@ packages: readable-stream: 3.6.2 dev: false + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: false + + /tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + + /tsx@3.12.7: + resolution: {integrity: sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==} + hasBin: true + dependencies: + '@esbuild-kit/cjs-loader': 2.4.2 + '@esbuild-kit/core-utils': 3.1.0 + '@esbuild-kit/esm-loader': 2.5.5 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 dev: false + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: false + + /typescript@5.0.4: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} + engines: {node: '>=12.20'} + hasBin: true + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: false - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: false + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 @@ -375,29 +908,6 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: false - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: false - /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: false - - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: false - - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: false diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..72c34f7 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,177 @@ +import { copyFile, readFile } from 'fs/promises' +import inquirer from 'inquirer' +import { parseADOFAILevel } from './utils/parser.js' +import { + ActionType, + DecorationEvent, + LevelEvent, + MoveDecorations, +} from './types/events.js' +import { join } from 'path' +import { dirname } from 'path' +import sharp from 'sharp' +import { Level } from './types/level.js' + +const { filePath } = await inquirer.prompt([ + { + message: 'wow give me level file path', + name: 'filePath', + }, +]) +const levelDir = dirname(filePath) + +const distPath = join(process.cwd(), 'dist') + +console.log(filePath) + +// todo functions +// .filter(x=>x.tag.split(' ').includes(tag)) +// function findAndFilterDecorationEventWithTagReference(levelEvents: LevelEvent[], tag: string): LevelEvent[] + +// occupiedTags: string[] +// let newTag = createUniqueTag(tag) +// findAndFilterDecorationEventWithTagReference(levelEvents, tag).forEachasfhgjksguhds +// function createTagAndCopyUsageReference(levelEvents: LevelEvent[], tag: string): LevelEvent[] + +// function splitTagByCondition(levelEvents: LevelEvent[], tag: string, condition: (levelEvent: LevelEvent) => boolean): LevelEvent[] + +// function minimizeEvent(levelEvents: LevelEvent[]): LevelEvent[] + +class EventSans { + origEvents: MoveDecorations[] = [] + events: MoveDecorations[] = [] + + // decorationsByTag: Map = new Map() + + get decorations() { + return this._level.decorations as Decoration[] + } + + constructor(private _level: Level) { + this.filterEvents() + } + + filterEvents() { + const actions = this._level.actions + + for (let index = actions.length - 1; index >= 0; index--) { + const event = actions[index] + + if (event.eventType === ActionType.MoveDecorations) { + actions.splice(index, 1) + for (const tag of event.tag.split(' ')) { + if (!tag) { + this.origEvents.push({ ...event }) + continue + } + this.origEvents.push({ ...event, tag }) + } + } + } + } + + /** + * wow + */ + tagDecorations() { + // ? 뭐해야하지 + // of -> array의 엘리먼트 / 오브젝트의 value 부분 + // in -> array의 index를 string으로 만들어버린거 / 오브젝트의 key 부분 + + let decorationsByTag: Map = new Map() + + const setOrPush = (tag: string, deco: Decoration) => { + if (decorationsByTag.has(tag)) { + let arr = decorationsByTag.get(tag)!.slice() + arr.push(deco) + + decorationsByTag.set(tag, arr) + } else decorationsByTag.set(tag, [deco]) + } + + // 이거 끝난거 아닌가(????) -> 원래 태그는 근데 가지고 있어야 나중에 육안으로 잘 됐는지 구분 가능할듯 + for (const deco of this.decorations) { + const tag = `${deco.tag}-${deco.id}` + + for (const ev of this.origEvents) { + if (ev.tag.split(' ').includes(deco.tag)) { + // 이벤트에는 태그 여러개들어감..................... 스페이스로 구분해서............ + this.events.push({ ...ev, tag }) + } + } + + deco.tag = tag + } + } +} + +type Decoration = DecorationEvent & { id: number } +type ImageSize = { width: number; height: number } + +// Read file +const content: string = await readFile(filePath, 'utf-8') + +// Objectify content JSON.parse (or similar method) +const level = parseADOFAILevel(content) + +const decorations: Decoration[] = [] +const imagePaths: Map = new Map() + +let lastId = 0 + +const registerDecorationImage = async (decorationImage: string) => { + if (!decorationImage || imagePaths.has(decorationImage)) return + + const imagePath = join(levelDir, decorationImage) + + const meta = await sharp(imagePath).metadata() + + imagePaths.set(decorationImage, { + width: meta.width!, + height: meta.height!, + }) +} + +for (const event of [...level.actions, ...level.decorations]) { + // Read through decorations, apply id to each decoration + if ( + event.eventType === ActionType.AddDecoration || + event.eventType === ActionType.AddText + ) { + const decoration: Decoration = event as Decoration + decoration.id = lastId++ + decorations.push(decoration) + + // Record file path in decorationImage property then acquire image resolution, match these + if (decoration.eventType != ActionType.AddDecoration) continue + + await registerDecorationImage(decoration.decorationImage) + } + + // Record file path in decorationImage property then acquire image resolution, match these + if (event.eventType === ActionType.MoveDecorations) + await registerDecorationImage(event.decorationImage) +} + +// Create a new directory, then copy over all files to new directory +for (const [imagePath, image] of imagePaths) { + let newPath = join(distPath, imagePath) + + // Apply resolution changes to image files + + await sharp(join(levelDir, imagePath)) + .resize({ width: image.width, height: image.height }) + .toFile(newPath) + + // 충격: 아직 파일별로 ratio로 나누는거 구현안함 + // wow +} + +// Iterate through decorations: +// 1) record which tags are used in each decoration +// 2) split image decoration(AddDecoration eventType) and text decoration(AddText eventType) tag references +// 3) make changes to pivotOffset and scale properties depending on which image path is stored in decorationImage +//!4) ensure one to one relation to image files and image decoration tag by duplicating tag and its usage. duplicate the event if needed +// Iterate through actions +// 1) make changes to pivotOffset and scale properties corresponding to tag +// Save file to new directory diff --git a/src/types/events.ts b/src/types/events.ts new file mode 100644 index 0000000..82686ce --- /dev/null +++ b/src/types/events.ts @@ -0,0 +1,567 @@ +import { + SpeedType, + BgDisplayMode, + ToggleBool, + TrackColorType, + TrackColorPulse, + TrackStyle, + TrackAnimationType, + TrackAnimationType2, + DecPlacementType, + DecorationBlendMode, + MaskingType, + Hitbox, + FlashPlane, + Ease, + RandomMode, + CamMovementType, + GameSound, + HitSound, + Filter, + EasePartBehavior, + HoldStartSound, + HoldLoopSound, + HoldEndSound, + HoldMidSound, + HoldMidSoundType, + HoldMidSoundTimingRelativeTo, + PlanetCount, + FontName, + TargetPlanet, +} from './types' + +export enum ActionType { + SetSpeed = 'SetSpeed', + Twirl = 'Twirl', + Multitap = 'Multitap', + Checkpoint = 'Checkpoint', + CustomBackground = 'CustomBackground', + ChangeTrack = 'ChangeTrack', + ColorTrack = 'ColorTrack', + AnimateTrack = 'AnimateTrack', + AddDecoration = 'AddDecoration', + Flash = 'Flash', + MoveCamera = 'MoveCamera', + SetHitsound = 'SetHitsound', + SetGameSound = 'SetGameSound', + PlaySound = 'PlaySound', + RecolorTrack = 'RecolorTrack', + MoveTrack = 'MoveTrack', + SetFilter = 'SetFilter', + HallOfMirrors = 'HallOfMirrors', + ShakeScreen = 'ShakeScreen', + SetPlanetRotation = 'SetPlanetRotation', + KillPlayer = 'KillPlayer', + MoveDecorations = 'MoveDecorations', + PositionTrack = 'PositionTrack', + Hold = 'Hold', + SetHoldSound = 'SetHoldSound', + TileDimensions = 'TileDimensions', + RepeatEvents = 'RepeatEvents', + Bloom = 'Bloom', + SetConditionalEvents = 'SetConditionalEvents', + MultiPlanet = 'MultiPlanet', + FreeRoam = 'FreeRoam', + FreeRoamTwirl = 'FreeRoamTwirl', + FreeRoamRemove = 'FreeRoamRemove', + FreeRoamWarning = 'FreeRoamWarning', + Pause = 'Pause', + AutoPlayTiles = 'AutoPlayTiles', + Hide = 'Hide', + ScaleMargin = 'ScaleMargin', + ScaleRadius = 'ScaleRadius', + ScreenTile = 'ScreenTile', + ScreenScroll = 'ScreenScroll', + AddText = 'AddText', + SetText = 'SetText', + EditorComment = 'EditorComment', + Bookmark = 'Bookmark', + CallMethod = 'CallMethod', + AddComponent = 'AddComponent', + ScalePlanets = 'ScalePlanets', +} + +export interface Action { + floor: number + eventType: T +} + +export type Tile = [number, TileType] + +export enum TileType { + ThisTile = 'ThisTile', + FirstTile = 'FirstTile', + LastTile = 'LastTile', +} + +export type Color = `#${string}` + +export type Vector2 = [number, number] + +export interface SetSpeed extends Action { + speedType: SpeedType + beatsPerMinute: number + bpmMultiplier: number +} + +export interface Twirl extends Action {} + +export interface Multitap extends Action { + taps: number +} + +export interface Checkpoint extends Action { + tileOffset: number +} + +export interface CustomBackground extends Action { + color: Color + bgImage: string + imageColor: Color + parallax: Vector2 + bgDisplayMode: BgDisplayMode + lockRot: ToggleBool + loopBG: ToggleBool + unscaledSize: number + angleOffset: number + eventTag: string +} + +export interface ChangeTrack extends Action { + trackColorType: TrackColorType + trackColor: Color + secondaryTrackColor: Color + trackColorAnimDuration: number + trackColorPulse: TrackColorPulse + trackPulseLength: number + trackStyle: TrackStyle + trackAnimation: TrackAnimationType + beatsAhead: number + trackDisappearAnimation: TrackAnimationType2 + beatsBehind: number +} + +export interface ColorTrack extends Action { + trackColorType: TrackColorType + trackColor: Color + secondaryTrackColor: Color + trackColorAnimDuration: number + trackColorPulse: TrackColorPulse + trackPulseLength: number + trackStyle: TrackStyle + trackTexture: string + trackTextureScale: number + trackGlowIntensity: number +} + +export interface AnimateTrack extends Action { + trackAnimation: TrackAnimationType + beatsAhead: number + trackDisappearAnimation: TrackAnimationType2 + beatsBehind: number +} + +export interface AddDecoration extends Action { + decorationImage: string + position: Vector2 + relativeTo: DecPlacementType + pivotOffset: Vector2 + rotation: number + lockRotation: ToggleBool + scale: Vector2 + lockScale: ToggleBool + tile: Vector2 + color: Color + opacity: number + depth: number + parallax: Vector2 + parallaxOffset: Vector2 + tag: string + imageSmoothing: ToggleBool + blendMode: DecorationBlendMode + maskingType: MaskingType + useMaskingDepth: ToggleBool + maskingFrontDepth: number + maskingBackDepth: number + failHitbox: ToggleBool + failHitboxType: Hitbox + failHitboxScale: Vector2 + failHitboxOffset: Vector2 + failHitboxRotation: number + components: string +} + +export interface Flash extends Action { + duration: number + plane: FlashPlane + startColor: Color + startOpacity: number + endColor: Color + endOpacity: number + angleOffset: number + ease: Ease + eventTag: string +} + +export interface MoveCamera extends Action { + duration: number + durationRandomMode: RandomMode + durationRandomValue: number + relativeTo: CamMovementType + position: Vector2 + positionRandomMode: RandomMode + positionRandomValue: Vector2 + rotation: number + rotationRandomMode: RandomMode + rotationRandomValue: number + zoom: number + zoomRandomMode: RandomMode + zoomRandomValue: number + angleOffset: number + ease: Ease + dontDisable: ToggleBool + minVfxOnly: ToggleBool + eventTag: string +} + +export interface SetHitsound extends Action { + gameSound: GameSound + hitsound: HitSound + hitsoundVolume: number +} + +export interface SetGameSound extends Action { + gameSound: GameSound + hitsound: HitSound + volume: number +} + +export interface PlaySound extends Action { + hitsound: HitSound + hitsoundVolume: number + angleOffset: number + eventTag: string +} + +export interface RecolorTrack extends Action { + startTile: Tile + endTile: Tile + gapLength: number + trackColorType: TrackColorType + trackColor: Color + secondaryTrackColor: Color + trackColorAnimDuration: number + trackColorPulse: TrackColorPulse + trackPulseLength: number + trackStyle: TrackStyle + trackGlowIntensity: number + angleOffset: number + eventTag: string +} + +export interface MoveTrack extends Action { + startTile: Tile + endTile: Tile + gapLength: number + duration: number + positionOffset: Vector2 + rotationOffset: number + scale: Vector2 + opacity: number + angleOffset: number + ease: Ease + maxVfxOnly: ToggleBool + eventTag: string +} + +export interface SetFilter extends Action { + filter: Filter + enabled: ToggleBool + intensity: number + duration: number + ease: Ease + disableOthers: ToggleBool + angleOffset: number + eventTag: string +} + +export interface HallOfMirrors extends Action { + enabled: ToggleBool + angleOffset: number + eventTag: string +} + +export interface ShakeScreen extends Action { + duration: number + strength: number + intensity: number + fadeOut: ToggleBool + angleOffset: number + eventTag: string +} + +export interface SetPlanetRotation + extends Action { + ease: Ease + easeParts: number + easePartBehavior: EasePartBehavior +} + +export interface KillPlayer extends Action { + playAnimation: ToggleBool + failMessage: string + eventTag: string +} + +export interface MoveDecorations extends Action { + duration: number + tag: string + decorationImage: string + positionOffset: Vector2 + pivotOffset: Vector2 + rotationOffset: number + scale: Vector2 + color: Color + opacity: number + depth: number + parallax: Vector2 + parallaxOffset: Vector2 + angleOffset: number + ease: Ease + eventTag: string + maskingType: MaskingType + useMaskingDepth: ToggleBool + maskingFrontDepth: number + maskingBackDepth: number +} + +export interface PositionTrack extends Action { + positionOffset: Vector2 + relativeTo: Tile + rotation: number + scale: number + opacity: number + justThisTile: ToggleBool + editorOnly: ToggleBool + stickToFloors: ToggleBool +} + +export interface Hold extends Action { + duration: number + distanceMultiplier: number + landingAnimation: ToggleBool +} + +export interface SetHoldSound extends Action { + holdStartSound: HoldStartSound + holdLoopSound: HoldLoopSound + holdEndSound: HoldEndSound + holdMidSound: HoldMidSound + holdMidSoundType: HoldMidSoundType + holdMidSoundDelay: number + holdMidSoundTimingRelativeTo: HoldMidSoundTimingRelativeTo + holdSoundVolume: number +} + +export interface TileDimensions extends Action { + width: number + length: number +} + +export interface RepeatEvents extends Action { + repetitions: number + interval: number + tag: string +} + +export interface Bloom extends Action { + enabled: ToggleBool + threshold: number + intensity: number + color: Color + duration: number + ease: Ease + angleOffset: number + eventTag: string +} + +export interface SetConditionalEvents + extends Action { + perfectTag: string + hitTag: string + earlyPerfectTag: string + latePerfectTag: string + barelyTag: string + veryEarlyTag: string + veryLateTag: string + missTag: string + tooEarlyTag: string + tooLateTag: string + lossTag: string +} + +export interface MultiPlanet extends Action { + planets: PlanetCount +} + +export interface FreeRoam extends Action { + duration: number + size: Vector2 + positionOffset: Vector2 + outTime: number + outEase: Ease + hitsoundOnBeats: HitSound + hitsoundOffBeats: HitSound + countdownTicks: number + angleCorrectionDir: number +} + +export interface FreeRoamTwirl extends Action { + position: Vector2 +} + +export interface FreeRoamRemove extends Action { + position: Vector2 + size: Vector2 +} + +export interface FreeRoamWarning extends Action { + position: Vector2 +} + +export interface Pause extends Action { + duration: number + countdownTicks: number + angleCorrectionDir: number +} + +export interface AutoPlayTiles extends Action { + enabled: ToggleBool + safetyTiles: ToggleBool +} + +export interface Hide extends Action { + hideJudgment: ToggleBool + hideTileIcon: ToggleBool +} + +export interface ScaleMargin extends Action { + scale: number +} + +export interface ScaleRadius extends Action { + scale: number +} + +export interface ScreenTile extends Action { + tile: Vector2 + angleOffset: number + eventTag: string +} + +export interface ScreenScroll extends Action { + scroll: Vector2 + angleOffset: number + eventTag: string +} + +export interface AddText extends Action { + decText: string + font: FontName + position: Vector2 + relativeTo: DecPlacementType + pivotOffset: Vector2 + rotation: number + lockRotation: ToggleBool + scale: Vector2 + lockScale: ToggleBool + color: Color + opacity: number + depth: number + parallax: Vector2 + tag: string +} + +export interface SetText extends Action { + decText: string + tag: string + angleOffset: number + eventTag: string +} + +export interface EditorComment extends Action { + comment: string +} + +export interface Bookmark extends Action {} + +export interface CallMethod extends Action { + method: string + angleOffset: number +} + +export interface AddComponent extends Action { + component: string + properties: string + duration: number + angleOffset: number +} + +export interface ScalePlanets extends Action { + duration: number + targetPlanet: TargetPlanet + scale: number + angleOffset: number + ease: Ease + eventTag: string +} + +export type LevelEvent = + | SetSpeed + | Twirl + | Multitap + | Checkpoint + | CustomBackground + | ChangeTrack + | ColorTrack + | AnimateTrack + | Flash + | MoveCamera + | SetHitsound + | SetGameSound + | PlaySound + | RecolorTrack + | MoveTrack + | SetFilter + | HallOfMirrors + | ShakeScreen + | SetPlanetRotation + | KillPlayer + | MoveDecorations + | PositionTrack + | Hold + | SetHoldSound + | TileDimensions + | RepeatEvents + | Bloom + | SetConditionalEvents + | MultiPlanet + | FreeRoam + | FreeRoamTwirl + | FreeRoamRemove + | FreeRoamWarning + | Pause + | AutoPlayTiles + | Hide + | ScaleMargin + | ScaleRadius + | ScreenTile + | ScreenScroll + | SetText + | EditorComment + | Bookmark + | CallMethod + | AddComponent + | ScalePlanets + +export type DecorationEvent = AddDecoration | AddText diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..38d80c4 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,3 @@ +export * from './events.js' +export * from './types.js' +export * from './level.js' diff --git a/src/types/level.ts b/src/types/level.ts new file mode 100644 index 0000000..278d939 --- /dev/null +++ b/src/types/level.ts @@ -0,0 +1,78 @@ +import { DecorationEvent, LevelEvent } from './events.js' + +type AngleData = number[] + +export interface Level { + angleData: AngleData + settings: LevelSettings + actions: LevelEvent[] + decorations: DecorationEvent[] +} + +export interface LevelSettings { + version: 12 + artist: '' + specialArtistType: 'None' + artistPermission: '' + song: '' + author: '' + separateCountdownTime: 'Enabled' + previewImage: '' + previewIcon: '' + previewIconColor: '003f52' + previewSongStart: 0 + previewSongDuration: 10 + seizureWarning: 'Disabled' + levelDesc: '' + levelTags: '' + artistLinks: '' + difficulty: 1 + requiredMods: [] + songFilename: 'L_X.wav' + bpm: 107.5 + volume: 100 + offset: 502 + pitch: 100 + hitsound: 'Sizzle' + hitsoundVolume: 100 + countdownTicks: 4 + trackColorType: 'Single' + trackColor: 'ffffffaa' + secondaryTrackColor: 'ffffff' + trackColorAnimDuration: 2 + trackColorPulse: 'None' + trackPulseLength: 10 + trackStyle: 'Minimal' + trackGlowIntensity: 50 + trackAnimation: 'Fade' + beatsAhead: 6 + trackDisappearAnimation: 'Fade' + beatsBehind: 0 + backgroundColor: '000000' + showDefaultBGIfNoImage: 'Disabled' + bgImage: '' + bgImageColor: 'ffffff' + parallax: [100, 100] + bgDisplayMode: 'Unscaled' + lockRot: 'Disabled' + loopBG: 'Disabled' + unscaledSize: 100 + relativeTo: 'Player' + position: [0, 0] + rotation: 0 + zoom: 175 + pulseOnFloor: 'Enabled' + startCamLowVFX: 'Disabled' + bgVideo: '' + loopVideo: 'Disabled' + vidOffset: 0 + floorIconOutlines: 'Disabled' + stickToFloors: 'Enabled' + planetEase: 'Linear' + planetEaseParts: 1 + planetEasePartBehavior: 'Mirror' + customClass: '' + legacyFlash: false + legacyCamRelativeTo: false + legacySpriteTiles: false +} diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..c8b3ef2 --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,287 @@ +export enum SpeedType { + Bpm = 'Bpm', + Multiplier = 'Multiplier', +} + +export enum BgDisplayMode { + FitToScreen = 'FitToScreen', + Unscaled = 'Unscaled', + Tiled = 'Tiled', +} + +export enum ToggleBool { + Enabled = 'Enabled', + Disabled = 'Disabled', +} + +export enum TrackColorType { + Single = 'Single', + Stripes = 'Stripes', + Glow = 'Glow', + Blink = 'Blink', + Switch = 'Switch', + Rainbow = 'Rainbow', + Volume = 'Volume', +} + +export enum TrackColorPulse { + None = 'None', + Forward = 'Forward', + Backward = 'Backward', +} + +export enum TrackStyle { + Standard = 'Standard', + Neon = 'Neon', + NeonLight = 'NeonLight', + Basic = 'Basic', + Gems = 'Gems', + Minimal = 'Minimal', +} + +export enum TrackAnimationType { + None = 'None', + Assemble = 'Assemble', + Assemble_Far = 'Assemble_Far', + Extend = 'Extend', + Grow = 'Grow', + Grow_Spin = 'Grow_Spin', + Fade = 'Fade', + Drop = 'Drop', + Rise = 'Rise', +} + +export enum TrackAnimationType2 { + None = 'None', + Scatter = 'Scatter', + Scatter_Far = 'Scatter_Far', + Retract = 'Retract', + Shrink = 'Shrink', + Shrink_Spin = 'Shrink_Spin', + Fade = 'Fade', +} + +export enum DecPlacementType { + Tile = 'Tile', + Global = 'Global', + RedPlanet = 'RedPlanet', + BluePlanet = 'BluePlanet', + Camera = 'Camera', + CameraAspect = 'CameraAspect', +} + +export enum DecorationBlendMode { + None = 'None', + Screen = 'Screen', + LinearDodge = 'LinearDodge', + Overlay = 'Overlay', + SoftLight = 'SoftLight', + Difference = 'Difference', +} + +export enum MaskingType { + None = 'None', + Mask = 'Mask', + VisibleInsideMask = 'VisibleInsideMask', + VisibleOutsideMask = 'VisibleOutsideMask', +} + +export enum Hitbox { + Box = 'Box', + Circle = 'Circle', + Capsule = 'Capsule', +} + +export enum FlashPlane { + Foreground = 'Foreground', + Background = 'Background', +} + +export enum Ease { + Linear = 'Linear', + InSine = 'InSine', + OutSine = 'OutSine', + InOutSine = 'InOutSine', + InQuad = 'InQuad', + OutQuad = 'OutQuad', + InOutQuad = 'InOutQuad', + InCubic = 'InCubic', + OutCubic = 'OutCubic', + InOutCubic = 'InOutCubic', + InQuart = 'InQuart', + OutQuart = 'OutQuart', + InOutQuart = 'InOutQuart', + InQuint = 'InQuint', + OutQuint = 'OutQuint', + InOutQuint = 'InOutQuint', + InExpo = 'InExpo', + OutExpo = 'OutExpo', + InOutExpo = 'InOutExpo', + InCirc = 'InCirc', + OutCirc = 'OutCirc', + InOutCirc = 'InOutCirc', + InElastic = 'InElastic', + OutElastic = 'OutElastic', + InOutElastic = 'InOutElastic', + InBack = 'InBack', + OutBack = 'OutBack', + InOutBack = 'InOutBack', + InBounce = 'InBounce', + OutBounce = 'OutBounce', + InOutBounce = 'InOutBounce', + Flash = 'Flash', + InFlash = 'InFlash', + OutFlash = 'OutFlash', + InOutFlash = 'InOutFlash', +} + +export enum RandomMode { + None = 'None', + Between = 'Between', + OneOrOther = 'OneOrOther', +} + +export enum CamMovementType { + Player = 'Player', + Tile = 'Tile', + Global = 'Global', + LastPosition = 'LastPosition', + LastPositionNoRotation = 'LastPositionNoRotation', +} + +export enum GameSound { + Hitsound = 'Hitsound', + Midspin = 'Midspin', +} + +export enum HitSound { + Hat = 'Hat', + Kick = 'Kick', + Shaker = 'Shaker', + Sizzle = 'Sizzle', + Chuck = 'Chuck', + ShakerLoud = 'ShakerLoud', + None = 'None', + Hammer = 'Hammer', + KickChroma = 'KickChroma', + SnareAcoustic2 = 'SnareAcoustic2', + Sidestick = 'Sidestick', + Stick = 'Stick', + ReverbClack = 'ReverbClack', + Squareshot = 'Squareshot', + PowerDown = 'PowerDown', + PowerUp = 'PowerUp', + KickHouse = 'KickHouse', + KickRupture = 'KickRupture', + HatHouse = 'HatHouse', + SnareHouse = 'SnareHouse', + SnareVapor = 'SnareVapor', + ClapHit = 'ClapHit', + ClapHitEcho = 'ClapHitEcho', + ReverbClap = 'ReverbClap', + FireTile = 'FireTile', + IceTile = 'IceTile', + VehiclePositive = 'VehiclePositive', + VehicleNegative = 'VehicleNegative', +} + +export enum Filter { + Grayscale = 'Grayscale', + Sepia = 'Sepia', + Invert = 'Invert', + VHS = 'VHS', + EightiesTV = 'EightiesTV', + FiftiesTV = 'FiftiesTV', + Arcade = 'Arcade', + LED = 'LED', + Rain = 'Rain', + Blizzard = 'Blizzard', + PixelSnow = 'PixelSnow', + Compression = 'Compression', + Glitch = 'Glitch', + Pixelate = 'Pixelate', + Waves = 'Waves', + Static = 'Static', + Grain = 'Grain', + MotionBlur = 'MotionBlur', + Fisheye = 'Fisheye', + Aberration = 'Aberration', + Drawing = 'Drawing', + Neon = 'Neon', + Handheld = 'Handheld', + NightVision = 'NightVision', + Funk = 'Funk', + Tunnel = 'Tunnel', + Weird3D = 'Weird3D', + Blur = 'Blur', + BlurFocus = 'BlurFocus', + GaussianBlur = 'GaussianBlur', + HexagonBlack = 'HexagonBlack', + Posterize = 'Posterize', + Sharpen = 'Sharpen', + Contrast = 'Contrast', + EdgeBlackLine = 'EdgeBlackLine', + OilPaint = 'OilPaint', + SuperDot = 'SuperDot', + WaterDrop = 'WaterDrop', + LightWater = 'LightWater', + Petals = 'Petals', + PetalsInstant = 'PetalsInstant', +} + +export enum EasePartBehavior { + Mirror = 'Mirror', + Repeat = 'Repeat', +} + +export enum HoldStartSound { + Fuse = 'Fuse', + None = 'None', +} + +export enum HoldLoopSound { + Fuse = 'Fuse', + None = 'None', +} + +export enum HoldEndSound { + Fuse = 'Fuse', + None = 'None', +} + +export enum HoldMidSound { + Fuse = 'Fuse', + SingSing = 'SingSing', + None = 'None', +} + +export enum HoldMidSoundType { + Once = 'Once', + Repeat = 'Repeat', +} + +export enum HoldMidSoundTimingRelativeTo { + Start = 'Start', + End = 'End', +} + +export enum PlanetCount { + TwoPlanets = 'TwoPlanets', + ThreePlanets = 'ThreePlanets', +} + +export enum FontName { + Default = 'Default', + Arial = 'Arial', + ComicSansMS = 'ComicSansMS', + CourierNew = 'CourierNew', + Georgia = 'Georgia', + Impact = 'Impact', + TimesNewRoman = 'TimesNewRoman', +} + +export enum TargetPlanet { + FirePlanet = 'FirePlanet', + IcePlanet = 'IcePlanet', + Both = 'Both', +} diff --git a/parser.js b/src/utils/parser.ts similarity index 78% rename from parser.js rename to src/utils/parser.ts index e16c099..b17fdc8 100644 --- a/parser.js +++ b/src/utils/parser.ts @@ -1,10 +1,7 @@ import JSON5 from 'json5' +import { Level } from '../types' -/** - * @param {string} level - * @returns {any} level json - */ -export const parseADOFAILevel = (level) => { +export const parseADOFAILevel = (level: string): Level => { try { return JSON5.parse(level) } catch (e) { @@ -24,7 +21,6 @@ export const parseADOFAILevel = (level) => { .replaceAll(']\t"decorations', '],\t"decorations') .replaceAll('\r', '') - // require('fs').writeFileSync('./debug.adofai', formattedLevel); return JSON5.parse(formattedLevel) } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3a0c480 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "ESNext" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/wowsans.js b/wowsans.js deleted file mode 100644 index ccb2fe5..0000000 --- a/wowsans.js +++ /dev/null @@ -1,72 +0,0 @@ -import { copyFile, mkdir, readFile, readdir, rm, writeFile } from 'fs/promises' -import yargs from 'yargs' -import { parseADOFAILevel } from './parser.js' -import { basename, dirname, join } from 'path' -import { existsSync } from 'fs' -import sharp from 'sharp' - -const args = yargs(process.argv) - -const path = args.argv._[2] -const ratio = Number(args.argv._[3]) - -if (isNaN(ratio)) throw new Error('ratio is not number') - -console.log(path) - -const file = await readFile(path) - -const level = parseADOFAILevel(file) - -const workDir = join(process.cwd(), 'work') - -if (existsSync(workDir)) await rm(workDir, { recursive: true, force: true }) - -await mkdir(workDir) - -const origLevelDir = dirname(path) - -for (const item of await readdir(origLevelDir)) { - await copyFile(join(origLevelDir, item), join(workDir, item)) -} - -const decoFiles = new Set() -const textTags = new Set() - -for (const deco of level.decorations) { - if (deco.eventType === 'AddDecoration') { - deco.scale = deco.scale.map((x) => x / ratio) - decoFiles.add(deco.decorationImage) - } else if (deco.eventType === 'AddText') { - textTags.add(deco.tag) - } -} - -for (const action of level.actions) { - if (action.eventType === 'MoveDecorations') { - if (textTags.has(action.tag)) continue - - if (action.scale) action.scale = action.scale.map((x) => x / ratio) - - if (action.decorationImage) decoFiles.add(action.decorationImage) - } -} - -for (const f of decoFiles) { - try { - const orig = join(origLevelDir, f) - const dest = join(workDir, f) - - const meta = await sharp(orig).metadata() - - await sharp(orig) - .resize(Math.round(meta.width * ratio), Math.round(meta.height * ratio)) - .toFile(dest) - - console.log(f) - } catch (e) { - console.error(e) - } -} - -await writeFile(join(workDir, basename(path)), JSON.stringify(level))