diff --git a/package-lock.json b/package-lock.json index 505bd9c..143f957 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,25 +63,25 @@ "@types/yargs": "^17.0.35", "@typescript-eslint/eslint-plugin": "^8.57.1", "@typescript-eslint/parser": "^8.57.1", - "ag-psd": "^6.2.0", - "ag-sockets": "^4.7.0", + "ag-psd": "^30.1.0", + "ag-sockets": "^14.0.2", "angular2-template-loader": "^0.6.2", "babel-loader": "^10.1.1", "base64-js": "^1.3.1", "bluebird": "^3.5.5", - "body-parser": "^1.19.0", + "body-parser": "^2.2.2", "bootstrap": "^4.6.2", "canvas": "^3.2.1", "canvas-toBlob": "^1.0.0", - "chai": "^4.2.0", - "chai-as-promised": "^7.1.1", - "chalk": "^2.4.2", - "color-convert": "^2.0.1", + "chai": "^6.2.2", + "chai-as-promised": "^8.0.2", + "chalk": "^5.6.2", + "color-convert": "^3.1.3", "connect-mongo": "^6.0.0", "cookie-parser": "^1.4.4", "core-js": "^3.2.1", "del": "^8.0.1", - "delta-e": "0.0.7", + "delta-e": "^0.0.8", "errorhandler": "^1.5.1", "eslint": "^5.16.0", "eslint-config-google": "^0.14.0", @@ -1236,6 +1236,18 @@ "node": ">=12" } }, + "node_modules/@angular/compiler-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/@angular/compiler-cli/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -5550,15 +5562,6 @@ "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", "license": "MIT" }, - "node_modules/@types/ws": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", - "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/yargs": { "version": "17.0.35", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", @@ -6088,23 +6091,20 @@ } }, "node_modules/ag-psd": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ag-psd/-/ag-psd-6.3.0.tgz", - "integrity": "sha512-OTYnugsjq8DlPcrXafzC9CJFRU7yyHKgPVATU4CoSKz9V3wtfVJ7qehi2luJoUR4NkjwTeUGeel7gAJOgJU2zQ==", + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/ag-psd/-/ag-psd-30.1.0.tgz", + "integrity": "sha512-1ce6o84aC+oVyl83A35HHUniGjwA3piHmGem3J2odBOFRq5p7i4htaco94vePLfOcingZu4fsyospJLwPagkhg==", "license": "MIT", "dependencies": { - "@types/base64-js": "^1.2.5", - "base64-js": "^1.3.1" + "base64-js": "1.5.1", + "pako": "2.1.0" } }, "node_modules/ag-sockets": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/ag-sockets/-/ag-sockets-4.7.0.tgz", - "integrity": "sha512-qM8qqyBN4X010bj/8G5/CesdGFyEgOFR1uT6WSkubP76lFYh3qFa4jm2GqHuCOAKE0MkOJkk3Mf9snBYPCI+kg==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/ag-sockets/-/ag-sockets-14.0.2.tgz", + "integrity": "sha512-5IxzfyBkfp5z80hnJajwWqNADFbE8554ppUgp0EvPWY2j3UjtjXrHhnfasXb1YWHs6qEWG3lv7TrJ/9aOirhKg==", "license": "MIT", - "dependencies": { - "@types/ws": "^6.0.1" - }, "peerDependencies": { "ws": "*" } @@ -7714,43 +7714,83 @@ } }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.14.0", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" + "node_modules/body-parser/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } }, "node_modules/body/node_modules/bytes": { "version": "1.0.0", @@ -7841,6 +7881,20 @@ "node": ">=4" } }, + "node_modules/boxen/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/boxen/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -8376,56 +8430,36 @@ } }, "node_modules/chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "license": "MIT", - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.1.0" - }, "engines": { - "node": ">=4" + "node": ">=18" } }, "node_modules/chai-as-promised": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", - "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", - "license": "WTFPL", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.2.tgz", + "integrity": "sha512-1GadL+sEJVLzDjcawPM4kjfnL+p/9vrxiEUonowKOAzvVg0PixJUdtuDzdkDeQhK3zfOE76GqGkZIQ7/Adcrqw==", + "license": "MIT", "dependencies": { - "check-error": "^1.0.2" + "check-error": "^2.1.1" }, "peerDependencies": { - "chai": ">= 2.1.2 < 6" - } - }, - "node_modules/chai/node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "license": "MIT", - "engines": { - "node": "*" + "chai": ">= 2.1.2 < 7" } }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, "engines": { - "node": ">=4" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/change-file-extension": { @@ -8456,15 +8490,12 @@ "license": "MIT" }, "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.2" - }, "engines": { - "node": "*" + "node": ">= 16" } }, "node_modules/chokidar": { @@ -8929,15 +8960,24 @@ } }, "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", + "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "color-name": "^2.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=14.6" + } + }, + "node_modules/color-convert/node_modules/color-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", + "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", + "license": "MIT", + "engines": { + "node": ">=12.20" } }, "node_modules/color-name": { @@ -9542,6 +9582,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/critters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/critters/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -10289,18 +10341,6 @@ "node": ">=0.10.0" } }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -10463,9 +10503,9 @@ } }, "node_modules/delta-e": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/delta-e/-/delta-e-0.0.7.tgz", - "integrity": "sha512-0OuNvCL0r4y4e5H/56PMhALSyE/ykDdLD6VW66SvymNSAdcpZDzceYsqjRrovealTH1IEqZHgDUu5e2dIFHfxQ==" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/delta-e/-/delta-e-0.0.8.tgz", + "integrity": "sha512-xIggbz7AoZLjwyV+BatfsKhWB1ejeh6vabM4KTJ2e7/d+TS0f7s87aUfkJ7B+MfniM6DD5VOWWlqcKXksp5mIg==" }, "node_modules/depd": { "version": "2.0.0", @@ -11904,6 +11944,20 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", @@ -12492,6 +12546,30 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -12507,6 +12585,21 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -13546,15 +13639,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -14345,6 +14429,18 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/gulp-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/gulp-cli/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -14467,18 +14563,6 @@ } } }, - "node_modules/gulp-imagemin/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/gulp-live-server": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/gulp-live-server/-/gulp-live-server-0.0.31.tgz", @@ -14620,18 +14704,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gulp-plugin-extras/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/gulp-plumber": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/gulp-plumber/-/gulp-plumber-1.2.1.tgz", @@ -14908,6 +14980,18 @@ "node": ">=8" } }, + "node_modules/gulp-shell/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/gulp-shell/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -16233,6 +16317,20 @@ "node": ">=6" } }, + "node_modules/inquirer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/inquirer/node_modules/cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", @@ -18220,6 +18318,20 @@ "node": ">=4" } }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -18441,15 +18553,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } - }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -20441,6 +20544,18 @@ "node": ">=8" } }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/ora/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -20831,6 +20946,12 @@ "semver": "bin/semver" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -21275,15 +21396,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/pause": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", @@ -25074,18 +25186,34 @@ } }, "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", + "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.10" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/raw-loader": { @@ -29150,6 +29278,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/ts-loader/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/ts-loader/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -29299,6 +29439,20 @@ "node": ">=0.10.0" } }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/tslint/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -29428,15 +29582,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -29949,6 +30094,20 @@ "node": ">=4" } }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/update-notifier/node_modules/import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -31804,6 +31963,20 @@ "node": ">=0.10.0" } }, + "node_modules/workbox-cli/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/workbox-cli/node_modules/chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -32251,6 +32424,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/wrapper-webpack-plugin": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/wrapper-webpack-plugin/-/wrapper-webpack-plugin-2.2.2.tgz", diff --git a/package.json b/package.json index a57e138..4e41b89 100644 --- a/package.json +++ b/package.json @@ -105,25 +105,25 @@ "@types/yargs": "^17.0.35", "@typescript-eslint/eslint-plugin": "^8.57.1", "@typescript-eslint/parser": "^8.57.1", - "ag-psd": "^6.2.0", - "ag-sockets": "^4.7.0", + "ag-psd": "^30.1.0", + "ag-sockets": "^14.0.2", "angular2-template-loader": "^0.6.2", "babel-loader": "^10.1.1", "base64-js": "^1.3.1", "bluebird": "^3.5.5", - "body-parser": "^1.19.0", + "body-parser": "^2.2.2", "bootstrap": "^4.6.2", "canvas": "^3.2.1", "canvas-toBlob": "^1.0.0", - "chai": "^4.2.0", - "chai-as-promised": "^7.1.1", - "chalk": "^2.4.2", - "color-convert": "^2.0.1", + "chai": "^6.2.2", + "chai-as-promised": "^8.0.2", + "chalk": "^5.6.2", + "color-convert": "^3.1.3", "connect-mongo": "^6.0.0", "cookie-parser": "^1.4.4", "core-js": "^3.2.1", "del": "^8.0.1", - "delta-e": "0.0.7", + "delta-e": "^0.0.8", "errorhandler": "^1.5.1", "eslint": "^5.16.0", "eslint-config-google": "^0.14.0", diff --git a/src/ts/client/handlers.ts b/src/ts/client/handlers.ts index 2a03c06..a3f1c9d 100644 --- a/src/ts/client/handlers.ts +++ b/src/ts/client/handlers.ts @@ -1,6 +1,5 @@ import { compact, escapeRegExp, repeat } from 'lodash'; import { createBinaryReader, readUint8, readUint32, readUint16 } from 'ag-sockets/dist/browser'; -import { decodeString } from 'ag-sockets/dist/utf8'; import { Entity, Region, Pony, EntityState, PonyOptions, MessageType, isNonIgnorableMessage, EntityPlayerState, EntityOrPonyOptions, isPublicMessage, FakeEntity, Action, WorldMap, DoAction, UpdateType, DecodedUpdate, @@ -36,6 +35,7 @@ import { compareFriends } from '../components/services/model'; import { canCollideWith } from '../common/collision'; import { hasDrawLight, hasLightSprite } from './draw'; import { setTile } from '../common/tileUtils'; +import { decodeStringFromUint8Array } from '../common/binaryUtils'; function log(message: string) { if (DEVELOPMENT && !TESTS) { @@ -180,7 +180,7 @@ export function handleUpdateEntity(game: PonyTownGame, update: DecodedUpdate) { export function handleUpdatePonies(game: PonyTownGame, ponies: PonyData[]) { for (const [id, options = {}, name, info, playerState, nameBad] of ponies) { - const decodedName = name && decodeString(name) || undefined; + const decodedName = name && decodeStringFromUint8Array(name) || undefined; const filteredName = filterEntityName(game, decodedName, nameBad); const decodedInfo = info ? bitmask(info, PONY_INFO_KEY) : ''; const pony = createPonyEntity(game, id, options, filteredName, decodedInfo, EntityState.None); diff --git a/src/ts/common/binaryUtils.ts b/src/ts/common/binaryUtils.ts index 116ab2d..11fcf12 100644 --- a/src/ts/common/binaryUtils.ts +++ b/src/ts/common/binaryUtils.ts @@ -1,5 +1,7 @@ -import { BinaryWriter, getWriterBuffer, createBinaryWriter, resizeWriter } from 'ag-sockets/dist/browser'; +import { BinaryWriter, getWriterBuffer, createBinaryWriter, resizeWriter, readUint8Array, BinaryReader } from 'ag-sockets/dist/browser'; import { isDataViewError } from './utils'; +import { encodeStringTo } from 'ag-sockets/dist/utf8'; +import { getLength } from 'ag-sockets/dist/utils'; export function writeBinary(write: (writer: BinaryWriter) => void): Uint8Array { const writer = createBinaryWriter(); @@ -19,3 +21,153 @@ export function writeBinary(write: (writer: BinaryWriter) => void): Uint8Array { return getWriterBuffer(writer); } + +export function decodeString(value: DataView | null, offset: number, length: number): string | null { + if (value == null) return null; + + let result = ''; + const end = offset + length; + + for (let i = offset; i < end;) { + const byte1 = value.getUint8(i++); + let code: number; + + if ((byte1 & 0x80) === 0) { + code = byte1; + } else if ((byte1 & 0xe0) === 0xc0) { + const byte2 = continuationByte(value, i++, end); + code = ((byte1 & 0x1f) << 6) | byte2; + + if (code < 0x80) { + throw Error('Invalid continuation byte'); + } + } else if ((byte1 & 0xf0) === 0xe0) { + const byte2 = continuationByte(value, i++, end); + const byte3 = continuationByte(value, i++, end); + code = ((byte1 & 0x0f) << 12) | (byte2 << 6) | byte3; + + if (code < 0x0800) { + throw Error('Invalid continuation byte'); + } + + if (code >= 0xd800 && code <= 0xdfff) { + throw Error(`Lone surrogate U+${code.toString(16).toUpperCase()} is not a scalar value`); + } + } else if ((byte1 & 0xf8) === 0xf0) { + const byte2 = continuationByte(value, i++, end); + const byte3 = continuationByte(value, i++, end); + const byte4 = continuationByte(value, i++, end); + code = ((byte1 & 0x0f) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4; + + if (code < 0x010000 || code > 0x10ffff) { + throw Error('Invalid continuation byte'); + } + } else { + throw Error('Invalid UTF-8 detected'); + } + + if (code > 0xffff) { + code -= 0x10000; + result += String.fromCharCode(code >>> 10 & 0x3ff | 0xd800); + code = 0xdc00 | code & 0x3ff; + } + + result += String.fromCharCode(code); + } + + return result; +} + +function continuationByte(buffer: DataView, index: number, end: number): number { + if (index >= end) throw Error('Invalid byte index'); + + const continuationByte = buffer.getUint8(index); + + if ((continuationByte & 0xC0) === 0x80) { + return continuationByte & 0x3F; + } else { + throw Error('Invalid continuation byte'); + } +} + +export function encodeString(string?: string | null) { + const writer = createBinaryWriter(getStringLengthWithLength(string)); + if (string != null) { + writeStringValue(writer, string); + } + return getWriterBuffer(writer); +} + +export function getStringLengthWithLength(value?: string | null) { + if (value == null) + return 1; + const len = stringLengthInBytes(value); + return getLength(len) + len; +} + +export function writeStringValue(writer: BinaryWriter, value: string) { + writer.offset = encodeStringTo(writer.view, writer.offset, value); + + if (writer.offset > writer.view.byteLength) { + throw new Error('Exceeded DataView size'); + } +} + +function stringLengthInBytes(value: string): number { + let result = 0; + forEachCharacter(value, code => result += charLengthInBytes(code)); + return result; +} + +function forEachCharacter(value: string, callback: (code: number) => void) { + for (let i = 0; i < value.length; i++) { + const code = value.charCodeAt(i); + + // high surrogate + if (code >= 0xd800 && code <= 0xdbff) { + if ((i + 1) < value.length) { + const extra = value.charCodeAt(i + 1); + + // low surrogate + if ((extra & 0xfc00) === 0xdc00) { + i++; + callback(((code & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000); + } + } + } else { + callback(code); + } + } +} + +function charLengthInBytes(code: number): number { + if ((code & 0xffffff80) === 0) { + return 1; + } else if ((code & 0xfffff800) === 0) { + return 2; + } else if ((code & 0xffff0000) === 0) { + return 3; + } else { + return 4; + } +} + +export function resizeWriterWithData(writer: BinaryWriter) { + const size = writer.view.byteLength; + const originalBuffer = new Uint8Array(writer.view.buffer); + const resizedBuffer = new Uint8Array(size * 2); + for (let i = 0; i < originalBuffer.byteLength; i++) { + resizedBuffer[i] = originalBuffer[i]; + } + const resizedDataView = new DataView(resizedBuffer.buffer); + writer.view = resizedDataView; +} + +export function decodeStringFromBuffer(reader: BinaryReader) { + return decodeStringFromUint8Array(readUint8Array(reader)); +} + +export function decodeStringFromUint8Array(value: Uint8Array | null) { + const view = value ? new DataView(value.buffer, value.byteOffset, value.byteLength) : null; + return decodeString(view, 0, view ? view.byteLength : 0); +} diff --git a/src/ts/common/encoders/updateDecoder.ts b/src/ts/common/encoders/updateDecoder.ts index 961ddef..99f82e0 100644 --- a/src/ts/common/encoders/updateDecoder.ts +++ b/src/ts/common/encoders/updateDecoder.ts @@ -2,9 +2,9 @@ import { BinaryWriter, BinaryReader, writeInt16, readInt16, createBinaryReader, readUint16, readLength, readUint32, readUint8, readObject, readUint8Array } from 'ag-sockets/dist/browser'; -import { decodeString } from 'ag-sockets/dist/utf8'; import { DecodedUpdate, DecodedRegionUpdate, TileUpdate, UpdateFlags } from '../interfaces'; import { tileWidth, tileHeight, MAX_VELOCITY } from '../constants'; +import { decodeStringFromUint8Array } from '../binaryUtils'; export function writeVelocity(writer: BinaryWriter, value: number) { if (value >= MAX_VELOCITY || value <= -MAX_VELOCITY) { @@ -140,7 +140,7 @@ export function readOneUpdate(reader: BinaryReader): DecodedUpdate | undefined { } if ((flags & UpdateFlags.Name) !== 0) { - update.name = decodeString(readUint8Array(reader)) || undefined; + update.name = decodeStringFromUint8Array(readUint8Array(reader)) || undefined; update.filterName = (flags & UpdateFlags.NameBad) !== 0; } diff --git a/src/ts/components/tools/sheetExport.ts b/src/ts/components/tools/sheetExport.ts index 9e6588a..1182003 100644 --- a/src/ts/components/tools/sheetExport.ts +++ b/src/ts/components/tools/sheetExport.ts @@ -1,6 +1,6 @@ import { max, compact } from 'lodash'; import { saveAs } from 'file-saver'; -import { Psd, writePsd, Layer } from 'ag-psd'; +import { Psd, writePsd, Layer, BlendMode } from 'ag-psd'; import { SpriteSet, PonyInfoNumber, PaletteSpriteSet, NoDraw } from '../../common/interfaces'; import { times, cloneDeep, setFlag, includes, toInt } from '../../common/utils'; import { createDefaultPony, syncLockedPonyInfoNumber, toPaletteNumber, mockPaletteManager } from '../../common/ponyInfo'; @@ -237,7 +237,7 @@ function createPsdPatternLayers(sheet: Sheet, rows: number, cols: number, layer: canvas: drawPsdLayer(sheet, rows, cols, layer, i), hidden: true, clipping: true, - blendMode: 'multiply', + blendMode: 'multiply' as BlendMode, })), ]); } diff --git a/src/ts/server/characterUtils.ts b/src/ts/server/characterUtils.ts index e3f859d..4b5284f 100644 --- a/src/ts/server/characterUtils.ts +++ b/src/ts/server/characterUtils.ts @@ -1,6 +1,5 @@ import { repeat } from 'lodash'; import { toByteArray } from 'base64-js'; -import { encodeString } from 'ag-sockets/dist/utf8'; import { PonyOptions, EntityState, UpdateFlags } from '../common/interfaces'; import { ICharacter, IAccount, Character, queryCharacter } from './db'; import { isForbiddenName } from '../common/security'; @@ -23,6 +22,7 @@ import { isPonyFlying } from '../common/entityUtils'; import { createCharacterState, updateClientCharacter } from './playerUtils'; import { encodeExpression } from '../common/encoders/expressionEncoder'; import { QueryFilter } from 'mongoose'; +import { encodeString } from '../common/binaryUtils'; export const defaultCharacterState: CharacterState = { x: 0, y: 0 }; diff --git a/src/ts/server/entityUtils.ts b/src/ts/server/entityUtils.ts index 800fd09..893e2e5 100644 --- a/src/ts/server/entityUtils.ts +++ b/src/ts/server/entityUtils.ts @@ -1,5 +1,4 @@ -import { resizeWriter, writeUint8, BinaryWriter, writeUint32, writeUint16 } from 'ag-sockets'; -import { encodeString } from 'ag-sockets/dist/utf8'; +import { writeUint8, BinaryWriter, writeUint32, writeUint16 } from 'ag-sockets'; import { Entity, Rect, EntityState, UpdateFlags, Action, EntityOrPonyOptions, UpdateType, TileType, canWalk, setAnimationToEntityState } from '../common/interfaces'; @@ -16,6 +15,7 @@ import { PONY_TYPE } from '../common/constants'; import { grapesPurple, grapesGreen } from '../common/entities'; import { getTile } from '../common/tileUtils'; import { getRegion, getRegionGlobal } from '../common/region'; +import { encodeString, resizeWriterWithData } from '../common/binaryUtils'; export function isEntityShadowed(entity: ServerEntity): entity is ServerEntityWithClient { return entity.client !== undefined && entity.client.shadowed; @@ -163,18 +163,17 @@ export function pushUpdateEntity(update: EntityUpdateBase) { } } -function resizePreserveWriter(error: unknown, writer: BinaryWriter, offset: number) { +function resizePreserveWriter(error: Error, writer: BinaryWriter, offset: number) { if (isOverflowError(error)) { - const bytes = writer.bytes; - resizeWriter(writer); - writer.bytes.set(bytes); + resizeWriterWithData(writer); writer.offset = offset; - // DEVELOPMENT && logger.debug(`resize writer to ${writer.bytes.byteLength} (${error.message})`); + // DEVELOPMENT && console.log(`resize writer to ${writer.view.byteLength} (${error.message})`); } else { throw error; } } + export function pushAddEntityToClient(client: IClient, entity: ServerEntity) { const writer = client.updateQueue; const offset = writer.offset; @@ -185,7 +184,7 @@ export function pushAddEntityToClient(client: IClient, entity: ServerEntity) { writeOneEntity(writer, entity, client); break; } catch (e) { - resizePreserveWriter(e, writer, offset); + resizePreserveWriter(e as Error, writer, offset); } } } @@ -201,7 +200,7 @@ export function pushUpdateEntityToClient(client: IClient, update: EntityUpdateBa writeOneUpdate(writer, entity, flags, x, y, vx, vy, options, action, playerState); break; } catch (e) { - resizePreserveWriter(e, writer, offset); + resizePreserveWriter(e as Error, writer, offset); } } } @@ -216,7 +215,7 @@ export function pushRemoveEntityToClient(client: IClient, entity: ServerEntity) writeUint32(writer, entity.id); break; } catch (e) { - resizePreserveWriter(e, writer, offset); + resizePreserveWriter(e as Error, writer, offset); } } } @@ -233,7 +232,7 @@ export function pushUpdateTileToClient(client: IClient, x: number, y: number, ty writeUint8(writer, type); break; } catch (e) { - resizePreserveWriter(e, writer, offset); + resizePreserveWriter(e as Error, writer, offset); } } } diff --git a/src/ts/server/server.ts b/src/ts/server/server.ts index 57bdc18..9c1d40e 100644 --- a/src/ts/server/server.ts +++ b/src/ts/server/server.ts @@ -14,7 +14,7 @@ import * as express from 'express'; import { WebSocketServer } from '@encharm/cws'; import { compact, once } from 'lodash'; import { copySync, removeSync, ensureDirSync } from 'fs-extra'; -import { createServerHost, createClientOptions, ServerOptions, ClientExtensions, Packet } from 'ag-sockets'; +import { createServerHost, createClientOptions, ServerOptions, ClientExtensions } from 'ag-sockets'; import { config, port, server, args, version } from './config'; import { YEAR, WEEK } from '../common/constants'; import { rollbarCheckIgnore } from '../common/rollbar'; @@ -210,7 +210,7 @@ const sessionMiddlewares = once(() => [createSession(), passport.initialize(), p const adminMiddlewares = once(() => [...sessionMiddlewares(), isAdmin(server)]); const socketOptionsBase: ServerOptions = { ws: { Server: WebSocketServer }, - hash: STAMP, + hash: STAMP.toString(), }; initLogRequest(stats.logRequest); @@ -246,15 +246,15 @@ if (args.game) { ...socketOptionsBase, verifyClient: () => !getSettings().isServerOffline && !liveSettings.shutdown, forceBinary: true, - onSend: (packet: Packet) => { - sent += packet.binary ? packet.binary.byteLength : (packet.json ? packet.json.length : 0); + onSend: (id: number, name: string, packetSize: number, binary: boolean) => { + sent += packetSize; sentPackets++; - stats.logSendStats(packet); + stats.logSendStats(id, name, binary, packetSize); }, - onRecv: (packet: Packet) => { - received += packet.binary ? packet.binary.byteLength : (packet.json ? packet.json.length : 0); + onRecv: (id: number, name: string, packetSize: number, binary: boolean) => { + received += packetSize; receivedPackets++; - stats.logRecvStats(packet); + stats.logRecvStats(id, name, binary, packetSize); }, }; diff --git a/src/ts/server/services/friends.ts b/src/ts/server/services/friends.ts index 8cdf865..30ce0dd 100644 --- a/src/ts/server/services/friends.ts +++ b/src/ts/server/services/friends.ts @@ -53,7 +53,7 @@ export function toFriendRemove(client: IClient): FriendStatusData { } export function toFriend(client: IClient): FriendStatusData { - if (client.isConnected) { + if (client.isConnected()) { return toFriendOnline(client); } else { return toFriendOffline(client); diff --git a/src/ts/server/stats.ts b/src/ts/server/stats.ts index f1bbb26..6deee76 100644 --- a/src/ts/server/stats.ts +++ b/src/ts/server/stats.ts @@ -3,7 +3,6 @@ import * as path from 'path'; import * as moment from 'moment'; import { compact } from 'lodash'; import { Request } from 'express'; -import { Packet } from 'ag-sockets'; import { RequestStats, ServerStats } from '../common/adminInterfaces'; import { HOUR } from '../common/constants'; import { ByteSize } from './utils/byteSize'; @@ -92,13 +91,13 @@ export class StatsTracker { logSpamming = () => { this.dailySpamming++; } - logRecvStats = (packet: Packet) => { - this.logSocketStats(this.recvStats, packet); + logRecvStats = (id: number, name: string, binary: boolean, size: number) => { + this.logSocketStats(this.recvStats, id, name, binary, size); } - logSendStats = (packet: Packet) => { - this.logSocketStats(this.sendStats, packet); + logSendStats = (id: number, name: string, binary: boolean, size: number) => { + this.logSocketStats(this.sendStats, id, name, binary, size); } - private logSocketStats(stats: (SocketStats | undefined)[], { id, name, binary, json }: Packet) { + private logSocketStats(stats: (SocketStats | undefined)[], id: number, name: string, binary: boolean, size: number) { const entry = stats[id] || (stats[id] = { id, name, @@ -119,7 +118,7 @@ export class StatsTracker { entry.countStr++; } - entry.size.addBytes(binary ? (binary.length || binary.byteLength) : (json ? json.length : 0)); + entry.size.addBytes(size); } getStats(): RequestStats[] { const result: RequestStats[] = []; diff --git a/src/ts/server/world.ts b/src/ts/server/world.ts index d5ff476..4a2e953 100644 --- a/src/ts/server/world.ts +++ b/src/ts/server/world.ts @@ -95,7 +95,7 @@ export class World { // this.mapPools.set('house', createPool(10, () => createHouseMap(this, true), resetHouseMap)); partyService.partyChanged.subscribe(client => { - if (client.isConnected && client.map.usage === MapUsage.Party) { + if (client.isConnected() && client.map.usage === MapUsage.Party) { if ( client.party && client.party.leader === client && client.map.instance === client.accountId && !this.maps.some(m => m.id === client.map.id && m.instance === client.party!.id) @@ -785,7 +785,7 @@ export class World { client.disconnect(true); } else { setTimeout(() => { - if (client.isConnected) { + if (client.isConnected()) { client.disconnect(true); } }, 200); diff --git a/src/ts/tests/client/clientActions.spec.ts b/src/ts/tests/client/clientActions.spec.ts index f8ce6dc..e00a935 100644 --- a/src/ts/tests/client/clientActions.spec.ts +++ b/src/ts/tests/client/clientActions.spec.ts @@ -1,6 +1,5 @@ import { stubClass, resetStubMethods } from '../lib'; import { NgZone } from '@angular/core'; -import { encodeString } from 'ag-sockets/dist/utf8'; import { Subject } from 'rxjs'; import { expect } from 'chai'; import { stub, assert, SinonStub } from 'sinon'; @@ -25,6 +24,7 @@ import { createServerRegion } from '../../server/serverRegion'; import { ServerRegion } from '../../server/serverInterfaces'; import { getTile } from '../../common/tileUtils'; import { Weather } from '../../common/commonInterfaces'; +import { encodeString } from '../../common/binaryUtils'; describe('ClientActions', () => { let zone: NgZone; diff --git a/src/ts/tests/common/encoders/updateEncoder.spec.ts b/src/ts/tests/common/encoders/updateEncoder.spec.ts index 6ea26d6..f7f1def 100644 --- a/src/ts/tests/common/encoders/updateEncoder.spec.ts +++ b/src/ts/tests/common/encoders/updateEncoder.spec.ts @@ -3,13 +3,13 @@ import { expect } from 'chai'; import { encodeUpdateSimple, encodeRegionSimple } from '../../../common/encoders/updateEncoder'; import { EntityState, DecodedRegionUpdate, UpdateFlags, TileType } from '../../../common/interfaces'; import { entity, mockClient, serverEntity } from '../../mocks'; -import { encodeString } from 'ag-sockets/dist/utf8'; import { emptyUpdate, decodeUpdate } from '../../../common/encoders/updateDecoder'; import { createServerRegion } from '../../../server/serverRegion'; import { IClient, ServerRegion } from '../../../server/serverInterfaces'; import { setEntityName } from '../../../server/entityUtils'; import { compressTiles } from '../../../common/compress'; import { REGION_SIZE } from '../../../common/constants'; +import { encodeString } from '../../../common/binaryUtils'; describe('updateEncoder', () => { describe('encodeUpdate() + decodeUpdate()', () => { diff --git a/src/ts/tests/server/characterUtils.spec.ts b/src/ts/tests/server/characterUtils.spec.ts index 2df3247..7269fa5 100644 --- a/src/ts/tests/server/characterUtils.spec.ts +++ b/src/ts/tests/server/characterUtils.spec.ts @@ -1,6 +1,5 @@ import '../lib'; import { expect } from 'chai'; -import { encodeString } from 'ag-sockets/dist/utf8'; import { createExtraOptions, updatePony, encryptInfo, createPony, getAndFixCharacterState } from '../../server/characterUtils'; import { account, character, serverEntity, entity, genObjectId } from '../mocks'; import { CharacterFlags, CharacterState, SupporterFlags, CharacterStateFlags } from '../../common/adminInterfaces'; @@ -13,6 +12,7 @@ import { CounterService } from '../../server/services/counter'; import { createCharacterState } from '../../server/playerUtils'; import { hasFlag } from '../../common/utils'; import { Types } from 'mongoose'; +import { encodeString } from '../../common/binaryUtils'; describe('characterUtils', () => { describe('createPony()', () => { diff --git a/src/ts/tests/server/serverActions.spec.ts b/src/ts/tests/server/serverActions.spec.ts index 99a9e89..a11233d 100644 --- a/src/ts/tests/server/serverActions.spec.ts +++ b/src/ts/tests/server/serverActions.spec.ts @@ -3,7 +3,6 @@ import { expect } from 'chai'; import { stub, assert, spy, SinonSpy, SinonFakeTimers, useFakeTimers, SinonStub } from 'sinon'; import { range } from 'lodash'; import { getWriterBuffer } from 'ag-sockets'; -import { encodeString } from 'ag-sockets/dist/utf8'; import { ChatType, TileType, Action, PlayerAction, ModAction, Eye, Muzzle, SelectFlags, InfoFlags } from '../../common/interfaces'; @@ -24,6 +23,7 @@ import { SupporterInvitesService } from '../../server/services/supporterInvites' import { createCamera } from '../../common/camera'; import { FriendsService } from '../../server/services/friends'; import * as playerUtils from '../../server/playerUtils'; +import { encodeString } from '../../common/binaryUtils'; describe('ServerActions', () => { let accountService = stubFromInstance({