mirror of
https://github.com/laochan-eacnet/backend.git
synced 2026-10-02 11:37:58 +03:00
Merge pull request 'add sound voltex support' (#1) from sdvx into eacnet
Reviewed-on: https://git.girlsband.party/laochan/laochan-eacnet/pulls/1
This commit is contained in:
@@ -29,3 +29,8 @@ build/
|
||||
.DS_Store
|
||||
|
||||
.env
|
||||
|
||||
input.xml
|
||||
output.json
|
||||
dump.xml
|
||||
pdata.json
|
||||
|
||||
Generated
+465
-11
@@ -17,6 +17,7 @@
|
||||
"dedent-js": "^1.0.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"fast-xml-parser": "^4.3.2",
|
||||
"highwayhash": "^3.1.1",
|
||||
"koa": "^2.15.0",
|
||||
"koa-bodyparser": "^4.4.1",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -2522,7 +2523,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -2555,6 +2555,11 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"node_modules/arc4": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/arc4/-/arc4-2.1.4.tgz",
|
||||
@@ -2563,6 +2568,15 @@
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/are-we-there-yet": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
|
||||
"integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
|
||||
"dependencies": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz",
|
||||
@@ -2729,6 +2743,34 @@
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bl/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@@ -2812,6 +2854,15 @@
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
@@ -2924,6 +2975,11 @@
|
||||
"is-regex": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
|
||||
},
|
||||
"node_modules/ci-info": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
|
||||
@@ -2979,6 +3035,14 @@
|
||||
"type-is": "^1.6.16"
|
||||
}
|
||||
},
|
||||
"node_modules/code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/collect-v8-coverage": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
|
||||
@@ -3009,6 +3073,11 @@
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
|
||||
},
|
||||
"node_modules/constantinople": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/constantinople/-/constantinople-4.0.1.tgz",
|
||||
@@ -3069,6 +3138,11 @@
|
||||
"cosmokit": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
||||
},
|
||||
"node_modules/cosmokit": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/cosmokit/-/cosmokit-1.5.2.tgz",
|
||||
@@ -3133,6 +3207,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||
"dependencies": {
|
||||
"mimic-response": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/dedent": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz",
|
||||
@@ -3157,6 +3242,14 @@
|
||||
"resolved": "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw=="
|
||||
},
|
||||
"node_modules/deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
@@ -3207,6 +3300,17 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
|
||||
"bin": {
|
||||
"detect-libc": "bin/detect-libc.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-newline": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
|
||||
@@ -3305,8 +3409,7 @@
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
@@ -3316,6 +3419,14 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
@@ -3754,6 +3865,14 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/expect": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
|
||||
@@ -3956,6 +4075,11 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
@@ -3984,6 +4108,64 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmmirror.com/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==",
|
||||
"dependencies": {
|
||||
"aproba": "^1.0.3",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
|
||||
"dependencies": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
|
||||
"dependencies": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge/node_modules/strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@@ -4047,6 +4229,11 @@
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
@@ -4177,6 +4364,11 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
|
||||
@@ -4188,6 +4380,19 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/highwayhash": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/highwayhash/-/highwayhash-3.1.1.tgz",
|
||||
"integrity": "sha512-FjsF/X47Q9+y7TJ+xjZxcNaOGhrGJTg5AFedEpNYate5GB5ezXeG3tqMjsuZ99R2If9xDdQQRCrka6hRC7J82g==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^3.1.0",
|
||||
"prebuild-install": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/html-escaper": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||
@@ -4249,6 +4454,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
|
||||
@@ -4325,6 +4535,11 @@
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/ini": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
@@ -4375,7 +4590,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -4459,6 +4673,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -5452,6 +5671,14 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@@ -5464,6 +5691,11 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
|
||||
@@ -5473,6 +5705,11 @@
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
||||
},
|
||||
"node_modules/mongodb": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/mongodb/-/mongodb-6.4.0.tgz",
|
||||
@@ -5532,6 +5769,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/napi-build-utils": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
|
||||
},
|
||||
"node_modules/natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
@@ -5546,6 +5788,27 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://registry.npmmirror.com/node-abi/-/node-abi-2.30.1.tgz",
|
||||
"integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==",
|
||||
"dependencies": {
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-3.2.1.tgz",
|
||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A=="
|
||||
},
|
||||
"node_modules/node-int64": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||
@@ -5579,6 +5842,25 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"dependencies": {
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
"console-control-strings": "~1.1.0",
|
||||
"gauge": "~2.7.3",
|
||||
"set-blocking": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -5607,7 +5889,6 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -5888,6 +6169,32 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-6.1.4.tgz",
|
||||
"integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==",
|
||||
"dependencies": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"napi-build-utils": "^1.0.1",
|
||||
"node-abi": "^2.21.0",
|
||||
"npmlog": "^4.0.1",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^3.0.3",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"prebuild-install": "bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@@ -5938,6 +6245,11 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"node_modules/promise": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/promise/-/promise-7.3.1.tgz",
|
||||
@@ -6071,6 +6383,15 @@
|
||||
"resolved": "https://registry.npmmirror.com/pug-walk/-/pug-walk-2.0.0.tgz",
|
||||
"integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ=="
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
@@ -6163,12 +6484,53 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"dependencies": {
|
||||
"deep-extend": "^0.6.0",
|
||||
"ini": "~1.3.0",
|
||||
"minimist": "^1.2.0",
|
||||
"strip-json-comments": "~2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"rc": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/rc/node_modules/strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/reflect-metadata": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.2.1.tgz",
|
||||
@@ -6405,6 +6767,11 @@
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
@@ -6464,8 +6831,22 @@
|
||||
"node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"node_modules/simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
|
||||
},
|
||||
"node_modules/simple-get": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz",
|
||||
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
|
||||
"dependencies": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sisteransi": {
|
||||
"version": "1.0.5",
|
||||
@@ -6544,6 +6925,19 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/string-length": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
|
||||
@@ -6561,7 +6955,6 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -6590,7 +6983,6 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@@ -6669,6 +7061,45 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"dependencies": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-stream/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
|
||||
@@ -6908,6 +7339,17 @@
|
||||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@@ -7019,6 +7461,11 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/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.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
@@ -7101,6 +7548,14 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz",
|
||||
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||
"dependencies": {
|
||||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"node_modules/with": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/with/-/with-7.0.2.tgz",
|
||||
@@ -7153,8 +7608,7 @@
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/write-file-atomic": {
|
||||
"version": "4.0.2",
|
||||
|
||||
+3
-1
@@ -40,7 +40,8 @@
|
||||
"lint:fix": "eslint . --ext .ts --ext .mts --fix",
|
||||
"test": "jest --coverage",
|
||||
"prettier": "prettier --config .prettierrc --write .",
|
||||
"test:watch": "jest --watch"
|
||||
"test:watch": "jest --watch",
|
||||
"xmltojson": "tsx src/tool/xml-to-json.ts"
|
||||
},
|
||||
"author": "GEEKiDoS",
|
||||
"license": "MIT",
|
||||
@@ -53,6 +54,7 @@
|
||||
"dedent-js": "^1.0.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"fast-xml-parser": "^4.3.2",
|
||||
"highwayhash": "^3.1.1",
|
||||
"koa": "^2.15.0",
|
||||
"koa-bodyparser": "^4.4.1",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Logger } from "@cordisjs/logger";
|
||||
import Router from "@koa/router";
|
||||
import { Context } from "../index.js";
|
||||
import { UserService } from "../../services/p2d/user.js";
|
||||
import { PlayerCustomizeSetting, PlayerRivalData } from "../../types/index.js";
|
||||
import { RivalPatch, RivalPostOrDelete } from "../../types/api.js";
|
||||
import { PlayerCustomizeSetting, PlayerRivalData } from "../../types/p2d/index.js";
|
||||
import { RivalPatch, RivalPostOrDelete } from "../../types/p2d/api.js";
|
||||
|
||||
const logger = new Logger('p2d-api');
|
||||
const router = new Router({
|
||||
|
||||
+38
-12
@@ -1,22 +1,48 @@
|
||||
import { Context } from '../types.js';
|
||||
import { eacnet } from '../decorators/eacnet.js';
|
||||
import { p2d, sdvx } from '../decorators/eacnet.js';
|
||||
import { v } from '../utils/kxml-value.js';
|
||||
import { singleton } from 'tsyringe';
|
||||
|
||||
@singleton()
|
||||
export class DefaultService {
|
||||
async default(ctx: Context) {
|
||||
const descriptor = {
|
||||
value: () => ({
|
||||
status: v.s32(0),
|
||||
error: v.s32(0),
|
||||
result: {
|
||||
dummy: v.u8(0),
|
||||
}
|
||||
})
|
||||
};
|
||||
if (ctx.service.name === 'p2d') {
|
||||
const descriptor = {
|
||||
value: () => ({
|
||||
status: v.s32(0),
|
||||
error: v.s32(0),
|
||||
result: {},
|
||||
})
|
||||
};
|
||||
|
||||
eacnet(ctx.service.name)(undefined, undefined, descriptor);
|
||||
return descriptor.value();
|
||||
p2d()(undefined, undefined, descriptor);
|
||||
return descriptor.value();
|
||||
} else if (ctx.service.name === 'sdvx') {
|
||||
const result = {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {},
|
||||
};
|
||||
|
||||
// handle ac relay
|
||||
if (ctx.eacnetRequest) {
|
||||
result['xrpc_status_code'] = v.s32(0);
|
||||
result['xrpc_fault_code'] = v.s32(0);
|
||||
result['response'] = {
|
||||
[ctx.eacnetRequest.module]: {
|
||||
$status: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const descriptor = {
|
||||
value: () => result,
|
||||
};
|
||||
|
||||
sdvx()(undefined, undefined, descriptor);
|
||||
return descriptor.value();
|
||||
}
|
||||
|
||||
throw new Error(`unsupported game ${ctx.service.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
import { eacnet } from "../../decorators/eacnet.js";
|
||||
import { p2d } from "../../decorators/eacnet.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
|
||||
export class Game {
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getChampionshipInfo() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -15,7 +15,7 @@ export class Game {
|
||||
entry_begin_clock: v.u64(0),
|
||||
championship_begin_clock: v.u64(0),
|
||||
championship_end_clock: v.u64(0),
|
||||
is_possible_play: v.bool(0),
|
||||
is_possible_play: v.bool(false),
|
||||
repertoire_list: {
|
||||
repertoire_num: v.s32(0),
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export class Game {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServerValues() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -41,7 +41,7 @@ export class Game {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async checkGameVersion() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -52,7 +52,7 @@ export class Game {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getClearRate(ctx: Context) {
|
||||
const { play_style } = ctx.body as { play_style: number };
|
||||
return {
|
||||
@@ -63,7 +63,7 @@ export class Game {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getGoodsList() {
|
||||
const goods = [{
|
||||
goods_id: v.str('G1000000'),
|
||||
|
||||
@@ -2,32 +2,11 @@ import { v } from "../../utils/kxml-value.js";
|
||||
import { Game } from "./game.js";
|
||||
import { Service } from "./service.js";
|
||||
import { User } from "./user.js";
|
||||
import data from './data.json' with { type: "json" };
|
||||
import { inject, singleton } from "tsyringe";
|
||||
import { UserService } from "../../services/p2d/user.js";
|
||||
import { Music } from "./music.js";
|
||||
|
||||
function Combine(...modules: ({ new(): any })[]) {
|
||||
class Modules {
|
||||
constructor() {
|
||||
modules.forEach(v => Object.assign(this, new v()));
|
||||
}
|
||||
}
|
||||
|
||||
modules.forEach(v => {
|
||||
const descriptors = Object.getOwnPropertyDescriptors(v.prototype);
|
||||
|
||||
for (const name in descriptors) {
|
||||
if (name === 'constructor')
|
||||
continue;
|
||||
|
||||
const descriptor = descriptors[name];
|
||||
Object.defineProperty(Modules.prototype, name, descriptor);
|
||||
}
|
||||
});
|
||||
|
||||
return Modules;
|
||||
}
|
||||
import { Combine } from "../../utils/combine.js";
|
||||
import * as data from '../../datas/p2d.js'
|
||||
|
||||
@singleton()
|
||||
export default class extends Combine(Service, User, Game, Music) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { PlayerPlayLog } from "../../types/index.js";
|
||||
import { eacnet } from "../../decorators/eacnet.js";
|
||||
import { PlayerPlayLog } from "../../types/p2d/index.js";
|
||||
import { p2d } from "../../decorators/eacnet.js";
|
||||
import { UserService } from "../../services/p2d/user.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import { MUSIC_LIST } from "./index.js";
|
||||
import { Binary } from "mongodb";
|
||||
import data from './data.json' with { type: "json" };
|
||||
import * as data from '../../datas/p2d.js'
|
||||
|
||||
// user only needs to unlock omni music, which is temporary
|
||||
const userUnlockMusic = new Map<string, number>();
|
||||
@@ -13,7 +13,7 @@ const userUnlockMusic = new Map<string, number>();
|
||||
export class Music {
|
||||
userService: UserService;
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getMusicGhost(ctx: Context) {
|
||||
// playstyle is actually chart diff, game is sending wrong request
|
||||
// TODO: check game code and maybe patch it later
|
||||
@@ -62,7 +62,7 @@ export class Music {
|
||||
ghost_data: v.bin(Buffer.from(playlog.ghost.buffer)),
|
||||
dj_name: v.str(djname),
|
||||
best_option: {
|
||||
valid: v.bool(1),
|
||||
valid: v.bool(true),
|
||||
arrange_0: v.s32(playlog.arrange_0),
|
||||
arrange_1: v.s32(playlog.arrange_1),
|
||||
assist: v.s32(playlog.assist),
|
||||
@@ -85,7 +85,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async reportMusicResult(ctx: Context) {
|
||||
const result = ctx.body as PlayerPlayLog;
|
||||
result.player = ctx.token;
|
||||
@@ -131,7 +131,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async unlockMusic(ctx: Context) {
|
||||
const { music: { music_id } } = ctx.body as { music: { music_id: number } };
|
||||
userUnlockMusic.set(ctx.token, music_id);
|
||||
@@ -144,7 +144,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getMusicList(ctx: Context) {
|
||||
let music = [...MUSIC_LIST];
|
||||
|
||||
@@ -177,7 +177,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getMusicData(ctx: Context) {
|
||||
const { play_style } = ctx.body as { play_style: number };
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { eacnet } from '../../decorators/eacnet.js';
|
||||
import { p2d } from '../../decorators/eacnet.js';
|
||||
import { Context } from '../../types.js';
|
||||
import config from '../../utils/config.js';
|
||||
import { v } from '../../utils/kxml-value.js';
|
||||
|
||||
export class Service {
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async sendLog() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -12,7 +12,7 @@ export class Service {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServerState() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -25,7 +25,7 @@ export class Service {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServerClock() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -36,7 +36,7 @@ export class Service {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async heartbeat(ctx: Context) {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -51,7 +51,7 @@ export class Service {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async checkSendLogAvailable() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -63,7 +63,7 @@ export class Service {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServices() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
|
||||
+20
-20
@@ -1,7 +1,7 @@
|
||||
import { eacnet } from "../../decorators/eacnet.js";
|
||||
import { p2d } from "../../decorators/eacnet.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import { fromToken } from "../../utils/laochan-id.js";
|
||||
import { tokenToInfinitasId } from "../../utils/laochan-id.js";
|
||||
import { UserService } from "../../services/p2d/user.js";
|
||||
import { sha256 } from "../../utils/sha256.js";
|
||||
import { toKBinXml } from "../../utils/kbinxml.js";
|
||||
@@ -10,7 +10,7 @@ import { ITEM_LIST } from "./index.js";
|
||||
export class User {
|
||||
userService: UserService;
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async addPoint() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -18,7 +18,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async reserveChangePoint() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -26,7 +26,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async sendGradeCertificationLog(ctx: Context) {
|
||||
await this.userService.addCourseLog({
|
||||
player: ctx.token,
|
||||
@@ -39,7 +39,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async consumeItem(ctx: Context) {
|
||||
const { item_id } = ctx.body;
|
||||
const { items_count } = await this.userService.getCustomizeSetting(ctx.token);
|
||||
@@ -75,7 +75,7 @@ export class User {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async reserveConsumeItem() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -83,7 +83,7 @@ export class User {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getCustomizeSetting(ctx: Context) {
|
||||
const { customize, other_customize } = await this.userService.getCustomizeSetting(ctx.token);
|
||||
|
||||
@@ -103,7 +103,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async gameEnd() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -111,7 +111,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPointList(ctx: Context) {
|
||||
const customize = await this.userService.getCustomizeSetting(ctx.token);
|
||||
|
||||
@@ -128,7 +128,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPrivilegeClient() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -139,7 +139,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPrivilegeServer() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -150,7 +150,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async savePlayData(ctx: Context) {
|
||||
const { pdata, check_sum } = ctx.body as { pdata: Buffer, check_sum: string };
|
||||
const localChecksum = sha256(pdata);
|
||||
@@ -167,7 +167,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPlayData(ctx: Context) {
|
||||
const result = await this.userService.getPDataBinary(ctx.token);
|
||||
|
||||
@@ -190,7 +190,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async registPlayer(ctx: Context) {
|
||||
const { pdata, check_sum } = ctx.body as { pdata: Buffer, check_sum: string };
|
||||
const localChecksum = sha256(pdata);
|
||||
@@ -207,12 +207,12 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async checkPlayData(ctx: Context) {
|
||||
const { check_sum } = ctx.body as { check_sum: string };
|
||||
|
||||
const checksum = await this.userService.getPDataChecksum(ctx.token);
|
||||
const id = fromToken(ctx.token);
|
||||
const id = tokenToInfinitasId(ctx.token);
|
||||
|
||||
if (!checksum) {
|
||||
return {
|
||||
@@ -249,7 +249,7 @@ export class User {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getRivalInfo(ctx: Context) {
|
||||
const rivalData = await this.userService.getPlayerRivalData(ctx.token);
|
||||
if (!rivalData.enabled) {
|
||||
@@ -320,7 +320,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getCompeScoreData() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -329,7 +329,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getItemList(ctx: Context) {
|
||||
const { items_count } = await this.userService.getCustomizeSetting(ctx.token);
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import { sdvx } from "../../decorators/eacnet.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { Serializable, v } from "../../utils/kxml-value.js";
|
||||
import * as data from '../../datas/sdvx.js';
|
||||
|
||||
export class AcRelay {
|
||||
@sdvx()
|
||||
async sv6_play_e(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_play_s(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
play_id: v.u32(Math.floor(new Date().valueOf() / 6e4)),
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_hiscore() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
sc: {},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_log(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_common(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
music: {},
|
||||
event: {
|
||||
info: data.eventList.map(id => ({
|
||||
event_id: v.str(id),
|
||||
}))
|
||||
},
|
||||
extend: {
|
||||
info: data.extendInfos,
|
||||
},
|
||||
music_limited: {
|
||||
info: data.musicInfos,
|
||||
},
|
||||
skill_course: {
|
||||
info: data.skillCourses,
|
||||
},
|
||||
appealcard: {},
|
||||
valgene: {},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_music_url(ctx: Context): Promise<Serializable> {
|
||||
let { music_id } = ctx.body as { music_id: number | number[] };
|
||||
if (typeof music_id === 'number') {
|
||||
music_id = [music_id];
|
||||
}
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
music: music_id.map(id => {
|
||||
const music = data.musicDownloadLinks[id];
|
||||
|
||||
if (!music) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
music_id: v.s32(id),
|
||||
url: v.str(music.url),
|
||||
hash: v.str(music.hash),
|
||||
size: v.s32(music.size),
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import { sdvx } from "../../decorators/eacnet.js";
|
||||
import { Combine } from "../../utils/combine.js";
|
||||
import config from "../../utils/config.js";
|
||||
import { Serializable, v } from "../../utils/kxml-value.js";
|
||||
import { AcRelay } from "./ac-relay.js";
|
||||
import { UserService } from "../../services/sdvx/user.js";
|
||||
import { inject, singleton } from "tsyringe";
|
||||
import { User } from "./user.js";
|
||||
import { Music } from "./music.js";
|
||||
|
||||
@singleton()
|
||||
export default class extends Combine(AcRelay, User, Music) {
|
||||
constructor(
|
||||
@inject(UserService) private readonly userService: UserService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.userService;
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async heartbeat(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
state: v.s32(1),
|
||||
next_clock: v.u64(new Date().valueOf() + 36e5),
|
||||
server_state: v.s32(1),
|
||||
mainte_start_clock: v.u64(0),
|
||||
mainte_end_clock: v.u64(0),
|
||||
usta_boot_status: v.s32(1),
|
||||
usta_time_remain: v.s32(0),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async checkVersion(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
permission: v.s32(1),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getServerClock(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
server_clock: v.u64(new Date().valueOf()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getServerState(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
server_state: v.s32(1),
|
||||
mainte_start_clock: v.u64(0),
|
||||
mainte_end_clock: v.u64(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@sdvx('SHIFT_JIS')
|
||||
async getServices(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
service_num: v.s32(18),
|
||||
service: [
|
||||
{
|
||||
service_name: v.str('acRelay'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/AcRelay`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('cancelReserveConsumeItem'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/CancelReserveConsumeItem`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('checkGameStart'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/CheckGameStart`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('checkVersion'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/CheckVersion`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('consumeItem'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/ConsumeItem`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getGoodsList'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetGoodsList`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getHash'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetHash`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getItemList'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/GetItemList`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getLauncherData'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetLauncherData`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getResourceInfo'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetResourceInfo`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getServerClock'),
|
||||
url: v.str(`${config.selfUrl}/pre_process/GetServerClock`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getServerState'),
|
||||
url: v.str(`${config.selfUrl}/pre_process/GetServerStatus`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getServices'),
|
||||
url: v.str(`${config.selfUrl}/pre_process/GetServices`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getSubscriptionStatus'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/GetSubscriptionStatus`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getUserIDs'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/GetUserId`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('heartbeat'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/Heartbeat`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('reserveConsumeItem'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/ReserveConsumeItem`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('uploadFile'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/UploadFile`),
|
||||
},
|
||||
|
||||
],
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import { sdvx } from "../../decorators/eacnet.js";
|
||||
import { UserService } from "../../services/sdvx/user.js";
|
||||
import { Serializable, v } from "../../utils/kxml-value.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { PlayerMusicData, PlayerPlayLog } from "../../types/sdvx/index.js";
|
||||
|
||||
export class Music {
|
||||
userService: UserService;
|
||||
|
||||
@sdvx()
|
||||
async sv6_save_m(ctx: Context): Promise<Serializable> {
|
||||
const { track } = ctx.body as { track: PlayerPlayLog };
|
||||
|
||||
track.player = ctx.token;
|
||||
track.play_time = new Date();
|
||||
|
||||
const mdata = (await this.userService.getPlayerMusicData(ctx.token, track.music_id, track.music_type)) ?? {
|
||||
player: ctx.token,
|
||||
music_id: track.music_id,
|
||||
music_type: track.music_type,
|
||||
score: 0, exscore: 0, clear_type: 0, score_grade: 0,
|
||||
max_chain: 0, play_count: 0,
|
||||
btn_rate: 0, long_rate: 0, vol_rate: 0,
|
||||
best_play_time: track.play_time,
|
||||
} as PlayerMusicData;
|
||||
|
||||
if (track.score > mdata.score) {
|
||||
mdata.score = track.score;
|
||||
mdata.score_grade = track.score_grade;
|
||||
|
||||
mdata.best_play_time = track.play_time;
|
||||
mdata.btn_rate = track.btn_rate;
|
||||
mdata.long_rate = track.long_rate;
|
||||
mdata.vol_rate = track.vol_rate;
|
||||
}
|
||||
|
||||
if (track.exscore > mdata.score) {
|
||||
mdata.exscore = track.exscore;
|
||||
|
||||
// if score is same, use exscore to compare
|
||||
if (track.score == mdata.score) {
|
||||
mdata.best_play_time = track.play_time;
|
||||
mdata.btn_rate = track.btn_rate;
|
||||
mdata.long_rate = track.long_rate;
|
||||
mdata.vol_rate = track.vol_rate;
|
||||
}
|
||||
}
|
||||
|
||||
if (track.clear_type > mdata.clear_type) {
|
||||
mdata.clear_type = track.clear_type;
|
||||
}
|
||||
|
||||
if (track.max_chain > mdata.max_chain) {
|
||||
mdata.max_chain = track.max_chain;
|
||||
}
|
||||
|
||||
mdata.play_count++;
|
||||
|
||||
await Promise.all([
|
||||
this.userService.insertPlayLog(track),
|
||||
this.userService.upsertMusicData(mdata),
|
||||
]);
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_load_r(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* music_id diff
|
||||
* score exscore clear_type score_grade max_chain play_count btn_rate long_rate vol_rate
|
||||
* 0 0 0 0 0 timestamp_s 0 0 0 0 0 0
|
||||
*/
|
||||
@sdvx()
|
||||
async sv6_load_m(ctx: Context): Promise<Serializable> {
|
||||
const mdata = await this.userService.getPlayerMusicDatas(ctx.token);
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
music: {
|
||||
info: mdata.map(d => ({
|
||||
date: d.best_play_time,
|
||||
param: v.u32([
|
||||
d.music_id, d.music_type,
|
||||
d.score, d.exscore, d.clear_type, d.score_grade, d.max_chain,
|
||||
d.play_count, d.btn_rate, d.long_rate, d.vol_rate,
|
||||
0, 0, 0, 0, 0,
|
||||
Math.floor(d.best_play_time.valueOf() / 1000),
|
||||
0, 0, 0, 0, 0, 0,
|
||||
])
|
||||
}))
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
import * as data from '../../datas/sdvx.js';
|
||||
import { tokenToCardNumber, tokenToHash, tokenToSnsId } from "../../utils/laochan-id.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { sdvx } from '../../decorators/eacnet.js';
|
||||
import { KValueG, Serializable, ValueTypes, v } from '../../utils/kxml-value.js';
|
||||
import { UserService } from '../../services/sdvx/user.js';
|
||||
import { Item, Param } from '../../types/sdvx/savedata.js';
|
||||
import { dateToString } from '../../utils/time.js';
|
||||
|
||||
function trySet<T>(kvalue: KValueG<ValueTypes, T>, value: T) {
|
||||
if (value === undefined || value === null)
|
||||
return;
|
||||
|
||||
kvalue.__value = value;
|
||||
}
|
||||
|
||||
function tryAdd(kvalue: KValueG<ValueTypes, number>, value: number) {
|
||||
if (value === undefined || value === null)
|
||||
return;
|
||||
|
||||
if (kvalue.__value instanceof Array)
|
||||
return;
|
||||
|
||||
kvalue.__value += value;
|
||||
}
|
||||
|
||||
export function tryMergeItem(params: Item[], newParams: object[]) {
|
||||
if (!params) {
|
||||
params = [];
|
||||
}
|
||||
|
||||
if (!newParams) {
|
||||
return params;
|
||||
}
|
||||
|
||||
if (!(newParams instanceof Array)) {
|
||||
newParams = [newParams];
|
||||
}
|
||||
|
||||
for (const np of newParams) {
|
||||
const target = params.find(p => p.id.__value === np['id'] && p.type.__value === np['type']);
|
||||
|
||||
if (target) {
|
||||
target.type = v.u8(np['type']);
|
||||
target.param = v.u32(np['param']);
|
||||
continue;
|
||||
}
|
||||
|
||||
params.push({
|
||||
type: v.u8(np['type']),
|
||||
id: v.u32(np['id']),
|
||||
param: v.u32(np['param']),
|
||||
})
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
export function tryMergeParam(params: Param[], newParams: object[]) {
|
||||
if (!params) {
|
||||
params = [];
|
||||
}
|
||||
|
||||
if (!newParams) {
|
||||
return params;
|
||||
}
|
||||
|
||||
if (!(newParams instanceof Array)) {
|
||||
newParams = [newParams];
|
||||
}
|
||||
|
||||
for (const np of newParams) {
|
||||
const target = params.find(p => p.id.__value === np['id'] && p.type.__value === np['type']);
|
||||
|
||||
if (target) {
|
||||
target.param = v.s32(np['param']);
|
||||
continue;
|
||||
}
|
||||
|
||||
params.push({
|
||||
type: v.s32(np['type']),
|
||||
id: v.s32(np['id']),
|
||||
param: v.s32(np['param']),
|
||||
})
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
export class User {
|
||||
userService: UserService;
|
||||
|
||||
@sdvx()
|
||||
async sv6_save_c(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
play_id: v.u32(Math.floor(new Date().valueOf() / 6e4)),
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_save(ctx: Context): Promise<Serializable> {
|
||||
const playData = await this.userService.getPlayerData(ctx.token);
|
||||
if (!playData) {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(1),
|
||||
xrpc_fault_code: v.s32(404),
|
||||
};
|
||||
}
|
||||
|
||||
const newData = ctx.body;
|
||||
|
||||
trySet(playData.appeal_id, newData.appeal_id);
|
||||
|
||||
trySet(playData.skill_level, newData.skill_level);
|
||||
trySet(playData.skill_base_id, newData.skill_base_id);
|
||||
trySet(playData.skill_name_id, newData.skill_name_id);
|
||||
|
||||
tryAdd(playData.blaster_energy, newData.earned_blaster_energy);
|
||||
tryAdd(playData.gamecoin_packet, newData.earned_gamecoin_packet);
|
||||
tryAdd(playData.gamecoin_block, newData.earned_gamecoin_block);
|
||||
|
||||
tryAdd(playData.play_count, 1);
|
||||
|
||||
trySet(playData.hispeed, newData.hispeed);
|
||||
trySet(playData.lanespeed, newData.lanespeed);
|
||||
trySet(playData.gauge_option, newData.gauge_option);
|
||||
trySet(playData.ars_option, newData.ars_option);
|
||||
trySet(playData.notes_option, newData.notes_option);
|
||||
trySet(playData.early_late_disp, newData.early_late_disp);
|
||||
trySet(playData.draw_adjust, newData.draw_adjust);
|
||||
trySet(playData.eff_c_left, newData.eff_c_left);
|
||||
trySet(playData.eff_c_right, newData.eff_c_right);
|
||||
trySet(playData.last_music_id, newData.music_id);
|
||||
trySet(playData.last_music_type, newData.music_type);
|
||||
trySet(playData.sort_type, newData.sort_type);
|
||||
trySet(playData.narrow_down, newData.narrow_down);
|
||||
trySet(playData.headphone, newData.headphone);
|
||||
|
||||
playData.item.info = tryMergeItem(playData.item.info, newData.item?.info);
|
||||
playData.item_infinite.info = tryMergeItem(playData.item_infinite.info, newData.item_infinite?.info);
|
||||
playData.param.info = tryMergeParam(playData.param.info, newData.param?.info);
|
||||
|
||||
playData.last_date = v.str(dateToString(new Date()));
|
||||
|
||||
if (!await this.userService.savePlayerData(ctx.token, playData)) {
|
||||
ctx.logger.error('play data save failed');
|
||||
}
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: { $status: 0 },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_new(ctx: Context): Promise<Serializable> {
|
||||
await this.userService.createEmptyPlayerData(ctx.token, ctx.body.name);
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async sv6_load(ctx: Context): Promise<Serializable> {
|
||||
const playData = await this.userService.getPlayerData(ctx.token);
|
||||
|
||||
if (!playData) {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
result: v.u8(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// blaster pass
|
||||
playData.ea_shop.blaster_pass_enable = v.bool(true);
|
||||
playData.ea_shop.blaster_pass_limit_date = v.u64(new Date().valueOf() + (30 * 60 * 60 * 1000));
|
||||
|
||||
// unlock all navigaters
|
||||
playData.item.info = tryMergeItem(playData.item.info, data.charaItems);
|
||||
playData.start_date = v.str(dateToString(new Date()));
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
result: v.u8(0),
|
||||
...playData,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getItemList(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
item_num: v.s32(data.itemList.length),
|
||||
item: data.itemList.map(id => ({
|
||||
item_id: v.str(id),
|
||||
not_free_count: v.s32(1),
|
||||
free_count: v.s32(0),
|
||||
})),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getGoodsList(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
goods_num: v.s32(0),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getUserIDs(ctx: Context): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
card_num: v.str(tokenToCardNumber(ctx.token)),
|
||||
ref_id: v.str(tokenToHash(ctx.token)),
|
||||
data_id: v.str(tokenToHash(ctx.token)),
|
||||
sns_id: v.str(tokenToSnsId(ctx.token)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getSubscriptionStatus(): Promise<Serializable> {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
subscription: {
|
||||
name: v.str('eac_sdvx_basic'),
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+26
-2
@@ -1,9 +1,9 @@
|
||||
import { Logger } from "@cordisjs/logger";
|
||||
import { MongoClient } from "mongodb";
|
||||
import config from "./utils/config.js";
|
||||
import { PlayerPlayData } from "./types/index.js";
|
||||
import { PlayerPlayData } from "./types/p2d/index.js";
|
||||
import { fromKBinXml } from "./utils/kbinxml.js";
|
||||
import { Pdata } from "./types/pdata.js";
|
||||
import { Pdata } from "./types/p2d/pdata.js";
|
||||
|
||||
interface DatabaseMeta {
|
||||
version: number;
|
||||
@@ -43,6 +43,30 @@ export async function initMongoDb() {
|
||||
meta.version = 1;
|
||||
}
|
||||
|
||||
if (meta.version < 2) {
|
||||
const collections = await db.listCollections().toArray();
|
||||
const tryRenameCollection = async (src: string, dest: string) => {
|
||||
if (!collections.some(v => v.name === src)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const col = db.collection(src);
|
||||
await col.rename(dest);
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
tryRenameCollection('player_play_data', 'p2d_play_data'),
|
||||
tryRenameCollection('player_music_data', 'p2d_music_data'),
|
||||
tryRenameCollection('player_play_log', 'p2d_play_log'),
|
||||
tryRenameCollection('player_course_log', 'p2d_course_log'),
|
||||
tryRenameCollection('player_customize_setting', 'p2d_customize_setting'),
|
||||
tryRenameCollection('player_rival_data', 'p2d_rival_data'),
|
||||
])
|
||||
|
||||
logger.info('upgraded database to ver 2, renamed prefix player to p2d.');
|
||||
meta.version = 2;
|
||||
}
|
||||
|
||||
await metaCol.updateOne({}, { $set: meta }, { upsert: true });
|
||||
return db;
|
||||
}
|
||||
|
||||
+7712
File diff suppressed because it is too large
Load Diff
+10587
File diff suppressed because it is too large
Load Diff
+17
-12
@@ -1,19 +1,24 @@
|
||||
import { LZ77 } from '../utils/lz77.js';
|
||||
import { toKBinXml } from '../utils/kbinxml.js';
|
||||
|
||||
export function eacnet(topName: string, encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8'): MethodDecorator {
|
||||
return function (_target, _propertyKey, descriptor) {
|
||||
const orig = descriptor.value as Function;
|
||||
descriptor.value = async function (...args: any[]) {
|
||||
const obj = await orig.apply(this, args);
|
||||
const kxml = toKBinXml(topName, obj, encoding);
|
||||
const compressed = LZ77.compress(kxml.data);
|
||||
const result = Buffer.allocUnsafe(compressed.length + 0x2E);
|
||||
export function eacnet(protocol_name: string, topName: string, dataOffset: number) {
|
||||
return (encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8') => {
|
||||
return function (_target, _propertyKey, descriptor) {
|
||||
const orig = descriptor.value as Function;
|
||||
descriptor.value = async function (...args: any[]) {
|
||||
const obj = await orig.apply(this, args);
|
||||
const kxml = toKBinXml(topName, obj, encoding);
|
||||
const compressed = LZ77.compress(kxml.data);
|
||||
const result = Buffer.allocUnsafe(compressed.length + dataOffset);
|
||||
|
||||
result.write('P2D:2015091800', 0, 'ascii');
|
||||
result.set(compressed, 0x2E);
|
||||
result.write(protocol_name, 0, 'ascii');
|
||||
result.set(compressed, dataOffset);
|
||||
|
||||
return result;
|
||||
} as unknown as any;
|
||||
return result;
|
||||
} as unknown as any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const p2d = eacnet('P2D:2015091800', 'p2d', 0x2E);
|
||||
export const sdvx = eacnet('2020090800', 'eacnet', 0x2A);
|
||||
|
||||
@@ -114,6 +114,10 @@ async function main(): Promise<void> {
|
||||
JSON.stringify(ctx.body, (key, value) => {
|
||||
if (key === 'pdata') {
|
||||
return '<PDATA>';
|
||||
} else if (key == 'item') {
|
||||
return '<ITEM>';
|
||||
} else if (key == 'param') {
|
||||
return '<PARAM>';
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@@ -6,16 +6,16 @@ import { fromKBinXml } from '../utils/kbinxml.js';
|
||||
export async function eacnet(ctx: Context, next: Next): Promise<any> {
|
||||
const body = ctx.request.body as {
|
||||
request: string;
|
||||
p2d_token: string;
|
||||
p2d_token?: string;
|
||||
} | undefined;
|
||||
|
||||
if (!body || !body.request) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const { request, p2d_token: token } = body;
|
||||
const { request } = body;
|
||||
|
||||
if (!request || !token) {
|
||||
if (!request) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -29,12 +29,28 @@ export async function eacnet(ctx: Context, next: Next): Promise<any> {
|
||||
const decoded = LZ77.decompress(buffer);
|
||||
const result = fromKBinXml(decoded);
|
||||
|
||||
const game = Object.keys(result)[0];
|
||||
if (result['eacnet']) {
|
||||
const info = result['eacnet'].info;
|
||||
ctx.token = info.token;
|
||||
|
||||
if (!(game in result)) {
|
||||
const request = result['eacnet'].request;
|
||||
if (!request) {
|
||||
return next();
|
||||
}
|
||||
|
||||
ctx.service = {
|
||||
name: info.game_id,
|
||||
method: request.method,
|
||||
};
|
||||
|
||||
ctx.body = request.data ?? {};
|
||||
ctx.eacnetRequest = request;
|
||||
return next();
|
||||
}
|
||||
|
||||
// for p2d
|
||||
const game = Object.keys(result)[0];
|
||||
|
||||
if (result[game].params) {
|
||||
ctx.body = result.p2d.params;
|
||||
} else {
|
||||
@@ -46,6 +62,6 @@ export async function eacnet(ctx: Context, next: Next): Promise<any> {
|
||||
method: result[game].method,
|
||||
}
|
||||
|
||||
ctx.token = token;
|
||||
ctx.token = body.p2d_token;
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -1,41 +1,38 @@
|
||||
import { Binary, Db } from "mongodb";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { PlayerPlayData, PlayerMusicData, PlayerPlayLog, PlayerCourseLog, PlayerCustomizeSetting, PlayerRivalData } from "../../types/index.js";
|
||||
import { Pdata } from "../../types/pdata.js";
|
||||
import { PlayerPlayData, PlayerMusicData, PlayerPlayLog, PlayerCourseLog, PlayerCustomizeSetting, PlayerRivalData } from "../../types/p2d/index.js";
|
||||
import { Pdata } from "../../types/p2d/pdata.js";
|
||||
import { fromKBinXml } from "../../utils/kbinxml.js";
|
||||
|
||||
@injectable()
|
||||
export class UserService {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(
|
||||
@inject(Db)
|
||||
private readonly db: Db,
|
||||
) { }
|
||||
|
||||
get playDataCol() {
|
||||
return this.db.collection<PlayerPlayData>('player_play_data');
|
||||
return this.db.collection<PlayerPlayData>('p2d_play_data');
|
||||
}
|
||||
|
||||
get musicDataCol() {
|
||||
return this.db.collection<PlayerMusicData>('player_music_data');
|
||||
return this.db.collection<PlayerMusicData>('p2d_music_data');
|
||||
}
|
||||
|
||||
get playLogCol() {
|
||||
return this.db.collection<PlayerPlayLog>('player_play_log');
|
||||
return this.db.collection<PlayerPlayLog>('p2d_play_log');
|
||||
}
|
||||
|
||||
get courseLogCol() {
|
||||
return this.db.collection<PlayerCourseLog>('player_course_log');
|
||||
return this.db.collection<PlayerCourseLog>('p2d_course_log');
|
||||
}
|
||||
|
||||
get customizeSettingCol() {
|
||||
return this.db.collection<PlayerCustomizeSetting>('player_customize_setting');
|
||||
return this.db.collection<PlayerCustomizeSetting>('p2d_customize_setting');
|
||||
}
|
||||
|
||||
get rivalDataCol() {
|
||||
return this.db.collection<PlayerRivalData>('player_rival_data');
|
||||
return this.db.collection<PlayerRivalData>('p2d_rival_data');
|
||||
}
|
||||
|
||||
addCourseLog(coruseLog: PlayerCourseLog) {
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
import { Db, FindOptions } from "mongodb";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { PlayerMusicData, PlayerPlayData, PlayerPlayLog } from "../../types/sdvx/index.js";
|
||||
import { tokenToCode, tokenToSdvxId } from "../../utils/laochan-id.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import { dateToString } from "../../utils/time.js";
|
||||
import { SaveData } from "../../types/sdvx/savedata.js";
|
||||
|
||||
@injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@inject(Db)
|
||||
private readonly db: Db,
|
||||
) { }
|
||||
|
||||
get playDataCol() {
|
||||
return this.db.collection<PlayerPlayData>('sdvx_player_data');
|
||||
}
|
||||
|
||||
get musicDataCol() {
|
||||
return this.db.collection<PlayerMusicData>('sdvx_music_data');
|
||||
}
|
||||
|
||||
get playLogCol() {
|
||||
return this.db.collection<PlayerPlayLog>('sdvx_play_log');
|
||||
}
|
||||
|
||||
getPlayerMusicData(token: string, music_id: number, music_type: number) {
|
||||
return this.musicDataCol.findOne({ player: token, music_id, music_type });
|
||||
}
|
||||
|
||||
getPlayerMusicDatas(token: string) {
|
||||
return this.musicDataCol.find({ player: token }).toArray();
|
||||
}
|
||||
|
||||
async upsertMusicData(musicData: PlayerMusicData) {
|
||||
return await this.musicDataCol.updateOne({
|
||||
player: musicData.player,
|
||||
music_id: musicData.music_id,
|
||||
music_type: musicData.music_type,
|
||||
}, {
|
||||
$set: musicData
|
||||
}, {
|
||||
upsert: true
|
||||
});
|
||||
};
|
||||
|
||||
async insertPlayLog(playlog: PlayerPlayLog) {
|
||||
return this.playLogCol.insertOne(playlog);
|
||||
}
|
||||
|
||||
async hasPlayerData(token: string) {
|
||||
return !!await this.playDataCol.countDocuments({ _id: token });
|
||||
}
|
||||
|
||||
async savePlayerData(token: string, data: SaveData, name?: string): Promise<boolean> {
|
||||
const $set = {
|
||||
save_data: data,
|
||||
};
|
||||
|
||||
if (name) {
|
||||
$set['name'] = name;
|
||||
}
|
||||
|
||||
const result = await this.playDataCol.updateOne({ _id: token }, { $set }, { upsert: true })
|
||||
return !!(result.modifiedCount ? result.modifiedCount : result.upsertedCount);
|
||||
}
|
||||
|
||||
async getPlayerData(token: string, options?: FindOptions): Promise<SaveData | undefined> {
|
||||
const result = await this.playDataCol.findOne({ _id: token }, options);
|
||||
if (!result)
|
||||
return undefined;
|
||||
|
||||
return result.save_data;
|
||||
}
|
||||
|
||||
async createEmptyPlayerData(token: string, name: string) {
|
||||
const save_data = {
|
||||
code: v.str(tokenToCode(token)),
|
||||
name: v.str(name),
|
||||
sdvx_id: v.str(tokenToSdvxId(token)),
|
||||
creator_id: v.u32(0),
|
||||
gamecoin_block: v.u32(0),
|
||||
gamecoin_packet: v.u32(0),
|
||||
blaster_energy: v.u32(0),
|
||||
blaster_count: v.u32(0),
|
||||
appeal_id: v.u16(0),
|
||||
skill_level: v.s16(0),
|
||||
skill_base_id: v.s16(0),
|
||||
skill_name_id: v.s16(0),
|
||||
|
||||
hispeed: v.s32(0),
|
||||
lanespeed: v.u32(0),
|
||||
gauge_option: v.u8(0),
|
||||
ars_option: v.u8(0),
|
||||
notes_option: v.u8(0),
|
||||
early_late_disp: v.u8(0),
|
||||
draw_adjust: v.s32(0),
|
||||
eff_c_left: v.u8(0),
|
||||
eff_c_right: v.u8(1),
|
||||
last_music_id: v.s32(0),
|
||||
last_music_type: v.u8(0),
|
||||
sort_type: v.u8(0),
|
||||
narrow_down: v.u8(0),
|
||||
headphone: v.u8(0),
|
||||
|
||||
play_count: v.u32(0),
|
||||
day_count: v.u32(0),
|
||||
today_count: v.u32(0),
|
||||
play_chain: v.u32(0),
|
||||
max_play_chain: v.u32(0),
|
||||
week_count: v.u32(0),
|
||||
week_play_count: v.u32(0),
|
||||
week_chain: v.u32(0),
|
||||
max_week_chain: v.u32(0),
|
||||
|
||||
last_date: v.str(dateToString(new Date())),
|
||||
start_date: v.str(dateToString(new Date())),
|
||||
|
||||
item: {},
|
||||
item_cloud: {},
|
||||
item_infinite: {},
|
||||
skill: {},
|
||||
param: {},
|
||||
present: {},
|
||||
cloud: {
|
||||
relation: v.s8(1),
|
||||
},
|
||||
ea_shop: {
|
||||
shop_item: {},
|
||||
},
|
||||
} as SaveData;
|
||||
|
||||
return this.savePlayerData(token, save_data, name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { toObject, parser } from "../utils/kbinxml.js";
|
||||
|
||||
const xml = readFileSync('input.xml', 'utf-8');
|
||||
|
||||
const parsedXml = parser.parse(xml);
|
||||
const obj = toObject(parsedXml);
|
||||
|
||||
writeFileSync('output.json', JSON.stringify(obj, undefined, 2));
|
||||
@@ -10,6 +10,13 @@ export interface ILaochanContext {
|
||||
method: string,
|
||||
};
|
||||
|
||||
eacnetRequest?: {
|
||||
service: string;
|
||||
module: string;
|
||||
method: string;
|
||||
data: unknown;
|
||||
};
|
||||
|
||||
logger: Logger;
|
||||
body?: unknown;
|
||||
resolve: <T>(resolveToken: InjectionToken<T>) => T;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { ObjectId } from "mongodb";
|
||||
import { SaveData } from "./savedata.js";
|
||||
|
||||
export interface PlayerPlayData {
|
||||
_id: string;
|
||||
name: string;
|
||||
save_data: SaveData;
|
||||
}
|
||||
|
||||
export interface PlayerMusicData {
|
||||
_id: ObjectId;
|
||||
player: string;
|
||||
|
||||
music_id: number;
|
||||
music_type: number;
|
||||
|
||||
score: number;
|
||||
exscore: number;
|
||||
clear_type: number;
|
||||
score_grade: number;
|
||||
max_chain: number;
|
||||
play_count: number;
|
||||
btn_rate: number;
|
||||
long_rate: number;
|
||||
vol_rate: number;
|
||||
|
||||
best_play_time: Date;
|
||||
}
|
||||
|
||||
export interface PlayerPlayLog {
|
||||
_id: ObjectId;
|
||||
player: string;
|
||||
play_time: Date;
|
||||
play_id: number;
|
||||
track_no: number;
|
||||
music_id: number;
|
||||
music_type: number;
|
||||
score: number;
|
||||
exscore: number;
|
||||
clear_type: number;
|
||||
score_grade: number;
|
||||
max_chain: number;
|
||||
just: number;
|
||||
critical: number;
|
||||
near: number;
|
||||
error: number;
|
||||
effective_rate: number;
|
||||
btn_rate: number;
|
||||
long_rate: number;
|
||||
vol_rate: number;
|
||||
mode: number;
|
||||
gauge_type: number;
|
||||
notes_option: number;
|
||||
online_num: number;
|
||||
local_num: number;
|
||||
challenge_type: number;
|
||||
retry_cnt: number;
|
||||
pad_type: number;
|
||||
judge: number[];
|
||||
drop_frame: number;
|
||||
drop_frame_max: number;
|
||||
drop_count: number;
|
||||
etc: string;
|
||||
mix_id: number;
|
||||
mix_like: boolean;
|
||||
matching: {
|
||||
score: number;
|
||||
}[];
|
||||
is_blaster: boolean;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import { KBoolean, KS16, KS32, KS8, KString, KU16, KU32, KU64, KU8 } from "../../utils/kxml-value.js";
|
||||
|
||||
export interface SaveData {
|
||||
code: KString;
|
||||
name: KString;
|
||||
sdvx_id: KString;
|
||||
|
||||
creator_id: KU32;
|
||||
|
||||
gamecoin_packet: KU32;
|
||||
gamecoin_block: KU32;
|
||||
|
||||
blaster_energy: KU32;
|
||||
blaster_count: KU32;
|
||||
|
||||
appeal_id: KU16;
|
||||
|
||||
skill_level: KS16;
|
||||
skill_base_id: KS16;
|
||||
skill_name_id: KS16;
|
||||
|
||||
hispeed: KS32;
|
||||
lanespeed: KU32;
|
||||
gauge_option: KU8;
|
||||
ars_option: KU8;
|
||||
notes_option: KU8;
|
||||
early_late_disp: KU8;
|
||||
draw_adjust: KS32;
|
||||
eff_c_left: KU8;
|
||||
eff_c_right: KU8;
|
||||
last_music_id: KS32;
|
||||
last_music_type: KU8;
|
||||
sort_type: KU8;
|
||||
narrow_down: KU8;
|
||||
headphone: KU8;
|
||||
|
||||
play_count: KU32;
|
||||
day_count: KU32;
|
||||
today_count: KU32;
|
||||
play_chain: KU32;
|
||||
max_play_chain: KU32;
|
||||
week_count: KU32;
|
||||
week_play_count: KU32;
|
||||
week_chain: KU32;
|
||||
max_week_chain: KU32;
|
||||
last_date: KString;
|
||||
start_date: KString;
|
||||
|
||||
item: { info?: Item[] };
|
||||
item_cloud: { info?: Item[] };
|
||||
item_infinite: { info?: Item[] };
|
||||
|
||||
skill: { course?: Course[] };
|
||||
|
||||
param: { info?: Param[] };
|
||||
|
||||
present: { info?: Item[] };
|
||||
cloud: { relation: KS8 };
|
||||
ea_shop: EaShop;
|
||||
}
|
||||
|
||||
export interface Course {
|
||||
ssnid: KS16;
|
||||
crsid: KS16;
|
||||
st: KS16;
|
||||
sc: KS32;
|
||||
ex: KS32;
|
||||
ct: KS16;
|
||||
gr: KS16;
|
||||
ar: KS16;
|
||||
cnt: KS16;
|
||||
}
|
||||
|
||||
export interface EaShop {
|
||||
blaster_pass_enable: KBoolean;
|
||||
blaster_pass_limit_date: KU64;
|
||||
shop_item: {
|
||||
item?: Item[];
|
||||
}
|
||||
}
|
||||
|
||||
export interface Item {
|
||||
type: KU8;
|
||||
id: KU32;
|
||||
param: KU32;
|
||||
}
|
||||
|
||||
export interface Param {
|
||||
type: KS32;
|
||||
id: KS32;
|
||||
param: KS32;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
export function Combine(...modules: ({ new(): any })[]) {
|
||||
class Modules {
|
||||
constructor() {
|
||||
modules.forEach(v => Object.assign(this, new v()));
|
||||
}
|
||||
}
|
||||
|
||||
modules.forEach(v => {
|
||||
const descriptors = Object.getOwnPropertyDescriptors(v.prototype);
|
||||
|
||||
for (const name in descriptors) {
|
||||
if (name === 'constructor')
|
||||
continue;
|
||||
|
||||
const descriptor = descriptors[name];
|
||||
Object.defineProperty(Modules.prototype, name, descriptor);
|
||||
}
|
||||
});
|
||||
|
||||
return Modules;
|
||||
}
|
||||
+14
-4
@@ -1,8 +1,10 @@
|
||||
import { to_bin, to_xml } from "@kamyu/kbinxml";
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import _ from "lodash";
|
||||
import { Serializable } from "./kxml-value.js";
|
||||
import { writeFileSync } from "fs";
|
||||
|
||||
const parser = new XMLParser({
|
||||
export const parser = new XMLParser({
|
||||
ignoreAttributes: false,
|
||||
parseAttributeValue: false,
|
||||
attributeNamePrefix: '$',
|
||||
@@ -67,7 +69,7 @@ function parseValue(node: { $__type: string; $__count?: unknown }): any {
|
||||
};
|
||||
}
|
||||
|
||||
function toObject(node: Record<string, unknown> | unknown[] | string): any {
|
||||
export function toObject(node: Record<string, unknown> | unknown[] | string): any {
|
||||
if (node instanceof Array) {
|
||||
return node.map((v) => toObject(v as Record<string, unknown>));
|
||||
}
|
||||
@@ -152,7 +154,7 @@ function serializeValue(value: any, type: string): string {
|
||||
throw new Error(`unsupported type ${type}`);
|
||||
}
|
||||
|
||||
function serializeObject(obj: Object, name: string, linePrefix: string = '') {
|
||||
function serializeObject(obj: Serializable, name: string, linePrefix: string = '') {
|
||||
let output = `${linePrefix}<${name}`;
|
||||
|
||||
const entries = Object.entries(obj);
|
||||
@@ -175,12 +177,19 @@ function serializeObject(obj: Object, name: string, linePrefix: string = '') {
|
||||
attrs.sort((a, b) => a[0] < b[0] ? 1 : (a[0] > b[0] ? -1 : 0));
|
||||
|
||||
for (const attr of attrs) {
|
||||
if (attr[1] === undefined)
|
||||
continue;
|
||||
|
||||
output += ` ${attr[0]}="${_.escape(attr[1])}"`;
|
||||
}
|
||||
|
||||
output += '>';
|
||||
|
||||
if (value) {
|
||||
if (value[1] === undefined) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const type = attrs.find(v => v[0] == '__type');
|
||||
|
||||
if (!type) {
|
||||
@@ -217,7 +226,8 @@ function serializeObject(obj: Object, name: string, linePrefix: string = '') {
|
||||
return output + `</${name}>\n`;
|
||||
}
|
||||
|
||||
export function toKBinXml(topName: string, obj: unknown, encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8') {
|
||||
export function toKBinXml(topName: string, obj: Serializable, encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8') {
|
||||
const xml = `<?xml version="1.0" encoding="${encoding}"?>` + serializeObject(obj, topName);
|
||||
writeFileSync('dump.xml', xml);
|
||||
return to_bin(xml);
|
||||
}
|
||||
|
||||
+55
-21
@@ -14,8 +14,42 @@ export type ValueTypes = 's8' |
|
||||
'str' | 'string' |
|
||||
'time';
|
||||
|
||||
function vg(type: ValueTypes) {
|
||||
return (value: unknown, attrs?: object) => {
|
||||
type AttributeProperty<T> = {
|
||||
[K in keyof T as K extends string ? `$${K}` : never]: T[K]
|
||||
}
|
||||
|
||||
export type KValueG<T extends ValueTypes, VT = unknown> = {
|
||||
$__type: T;
|
||||
__value: VT | VT[];
|
||||
} & AttributeProperty<{
|
||||
[key: string]: string | number;
|
||||
}>;
|
||||
|
||||
export type KS8 = KValueG<'s8', number>;
|
||||
export type KU8 = KValueG<'u8', number>;
|
||||
export type KS16 = KValueG<'s16', number>;
|
||||
export type KU16 = KValueG<'u16', number>;
|
||||
export type KS32 = KValueG<'s32', number>;
|
||||
export type KU32 = KValueG<'u32', number>;
|
||||
export type KS64 = KValueG<'s64', number>;
|
||||
export type KU64 = KValueG<'u64', number>;
|
||||
export type KFloat = KValueG<'float', number>;
|
||||
export type KDouble = KValueG<'double', number>;
|
||||
export type KBoolean = KValueG<'bool', boolean> | KValueG<'b', boolean>;
|
||||
export type KBinary = KValueG<'bin', Buffer> | KValueG<'binary', Buffer>;
|
||||
export type KString = KValueG<'str', string> | KValueG<'string', string>;
|
||||
export type KIPv4 = KValueG<'ip4', string>;
|
||||
export type KTime = KValueG<'time', Date | number>;
|
||||
export type KValue = KS8 | KU8 | KS16 | KU16 | KS32 | KS64 | KU64 | KFloat | KDouble | KBoolean | KBinary | KString | KIPv4 | KTime;
|
||||
|
||||
export type Serializable = {
|
||||
[key: string]: KValue | Serializable | Serializable[]
|
||||
} | AttributeProperty<{
|
||||
[key: string]: string | number;
|
||||
}>;
|
||||
|
||||
function vg<T extends ValueTypes, VT>(type: T) {
|
||||
return (value: VT | VT[], attrs?: object): KValueG<T, VT> => {
|
||||
const result = {
|
||||
$__type: type,
|
||||
__value: value,
|
||||
@@ -31,23 +65,23 @@ function vg(type: ValueTypes) {
|
||||
};
|
||||
}
|
||||
|
||||
export const v: Record<ValueTypes, (value: unknown, attrs?: object) => object> = {
|
||||
s8: vg('s8'),
|
||||
u8: vg('u8'),
|
||||
s16: vg('s16'),
|
||||
u16: vg('u16'),
|
||||
s32: vg('s32'),
|
||||
u32: vg('u32'),
|
||||
s64: vg('s64'),
|
||||
u64: vg('u64'),
|
||||
float: vg('float'),
|
||||
double: vg('double'),
|
||||
b: vg('b'),
|
||||
bool: vg('bool'),
|
||||
bin: vg('bin'),
|
||||
binary: vg('binary'),
|
||||
ip4: vg('ip4'),
|
||||
str: vg('str'),
|
||||
string: vg('string'),
|
||||
time: vg('time'),
|
||||
export const v = {
|
||||
s8: vg<'s8', number>('s8'),
|
||||
u8: vg<'u8', number>('u8'),
|
||||
s16: vg<'s16', number>('s16'),
|
||||
u16: vg<'u16', number>('u16'),
|
||||
s32: vg<'s32', number>('s32'),
|
||||
u32: vg<'u32', number>('u32'),
|
||||
s64: vg<'s64', number>('s64'),
|
||||
u64: vg<'u64', number>('u64'),
|
||||
float: vg<'float', number>('float'),
|
||||
double: vg<'double', number>('double'),
|
||||
b: vg<'b', boolean>('b'),
|
||||
bool: vg<'bool', boolean>('bool'),
|
||||
bin: vg<'bin', Buffer>('bin'),
|
||||
binary: vg<'binary', Buffer>('binary'),
|
||||
ip4: vg<'ip4', string>('ip4'),
|
||||
str: vg<'str', string>('str'),
|
||||
string: vg<'string', string>('string'),
|
||||
time: vg<'time', Date | number>('time'),
|
||||
}
|
||||
|
||||
+29
-1
@@ -1,9 +1,37 @@
|
||||
import { createHash } from 'crypto';
|
||||
import highwayHash from 'highwayhash';
|
||||
|
||||
export function fromToken(token: string) {
|
||||
export function tokenToInfinitasId(token: string) {
|
||||
const key = createHash('md5')
|
||||
.update(token, 'utf-8')
|
||||
.digest('hex');
|
||||
|
||||
return ('LCHAN' + key).slice(0, 13);
|
||||
}
|
||||
|
||||
const HIGHWAY_KEY = Buffer.from('LAOCHANID_HIGHWAY_KEY_NOTSECURE!');
|
||||
|
||||
export function tokenToHash(token: string) {
|
||||
const key = highwayHash.asHexString(HIGHWAY_KEY, Buffer.from(token));
|
||||
return key.toUpperCase();
|
||||
}
|
||||
|
||||
export function tokenToCardNumber(token: string) {
|
||||
const hash = tokenToHash(token);
|
||||
return ('LCHAN' + hash.toUpperCase()).slice(0, 16);
|
||||
}
|
||||
|
||||
export function tokenToCode(token: string) {
|
||||
const key = highwayHash.asUInt32Low(HIGHWAY_KEY, Buffer.from(token));
|
||||
return 'MOAI' + key.toString().padStart(9, '0').slice(0, 9);
|
||||
}
|
||||
|
||||
export function tokenToSnsId(token: string) {
|
||||
const key = highwayHash.asUInt32Low(HIGHWAY_KEY, Buffer.from(token));
|
||||
return key.toString().padStart(8, '0');
|
||||
}
|
||||
|
||||
export function tokenToSdvxId(token: string) {
|
||||
const snsId = tokenToSnsId(token);
|
||||
return 'SV-' + snsId.slice(0, 4) + '-' + snsId.slice(4, 8);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export function dateToString(date: Date) {
|
||||
const isoStr = date.toISOString();
|
||||
const d = isoStr.split('T')[0]
|
||||
const t = isoStr.split('T')[1].split('.')[0];
|
||||
|
||||
return `${d} ${t}`;
|
||||
}
|
||||
Reference in New Issue
Block a user