From 5d2b8ecef953fc1e324f0993c31faa30af5ce1c0 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Mon, 5 Sep 2022 12:35:37 -0500 Subject: [PATCH] Basic multiplayer stuff --- .gitmodules | 3 + package-lock.json | 371 +++++++++++++++++++++++++++------------ package.json | 4 + src/components/Nav.vue | 20 ++- src/data/Room.vue | 154 ++++++++++++++++ src/data/RoomsDialog.vue | 234 ++++++++++++++++++++++++ src/data/projEntry.tsx | 68 +------ src/data/projInfo.json | 12 +- src/data/socket.tsx | 190 ++++++++++++++++++++ src/util/save.ts | 5 +- 10 files changed, 876 insertions(+), 185 deletions(-) create mode 100644 .gitmodules create mode 100644 src/data/Room.vue create mode 100644 src/data/RoomsDialog.vue create mode 100644 src/data/socket.tsx diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7f909d5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "alkatest-common"] + path = src/alkatest-common + url = https://github.com/thepaperpilot/alkatest-common diff --git a/package-lock.json b/package-lock.json index 491a72f..7c26609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,9 @@ "is-plain-object": "^5.0.0", "lz-string": "^1.4.4", "nanoevents": "^6.0.2", + "semver": "^7.3.7", + "socket.io-client": "^4.5.2", + "unique-names-generator": "^4.7.1", "vite": "^2.9.12", "vite-plugin-pwa": "^0.12.0", "vite-tsconfig-paths": "^3.5.0", @@ -34,6 +37,7 @@ "@ivanv/vue-collapse-transition": "^1.0.2", "@rushstack/eslint-patch": "^1.1.0", "@types/lz-string": "^1.3.34", + "@types/semver": "^7.3.12", "@vue/eslint-config-prettier": "^7.0.0", "@vue/eslint-config-typescript": "^10.0.0", "eslint": "^8.6.0", @@ -107,6 +111,14 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { "version": "7.18.12", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", @@ -173,6 +185,14 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz", @@ -224,6 +244,14 @@ "@babel/core": "^7.4.0-0" } }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", @@ -1525,6 +1553,14 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/preset-modules": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", @@ -2058,6 +2094,11 @@ "integrity": "sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==", "dev": true }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -2134,6 +2175,12 @@ "@types/node": "*" } }, + "node_modules/@types/semver": { + "version": "7.3.12", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", + "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "dev": true + }, "node_modules/@types/trusted-types": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", @@ -2172,21 +2219,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { "version": "5.33.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.1.tgz", @@ -2297,21 +2329,6 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { "version": "5.33.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.1.tgz", @@ -2754,6 +2771,14 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz", @@ -3240,6 +3265,46 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz", "integrity": "sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw==" }, + "node_modules/engine.io-client": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.2.tgz", + "integrity": "sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/entities": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", @@ -3847,22 +3912,6 @@ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/eslint-plugin-vue/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5261,7 +5310,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -5967,11 +6015,17 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/serialize-javascript": { @@ -6024,6 +6078,32 @@ "node": ">=8" } }, + "node_modules/socket.io-client": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.2.tgz", + "integrity": "sha512-naqYfFu7CLDiQ1B7AlLhRXKX3gdeaIMfgigwavDzgJoIUYulc1qHH5+2XflTsXTPY7BlPH5rppJyUjhjrKQKLg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/sortablejs": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", @@ -6428,6 +6508,14 @@ "node": ">=4" } }, + "node_modules/unique-names-generator": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz", + "integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==", + "engines": { + "node": ">=8" + } + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -6698,21 +6786,6 @@ "node": ">=4.0" } }, - "node_modules/vue-eslint-parser/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/vue-next-select": { "version": "2.10.4", "resolved": "https://registry.npmjs.org/vue-next-select/-/vue-next-select-2.10.4.tgz", @@ -7211,11 +7284,18 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yocto-queue": { "version": "0.1.0", @@ -7273,6 +7353,13 @@ "gensync": "^1.0.0-beta.2", "json5": "^2.2.1", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "@babel/generator": { @@ -7323,6 +7410,13 @@ "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.20.2", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "@babel/helper-create-class-features-plugin": { @@ -7359,6 +7453,13 @@ "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "@babel/helper-environment-visitor": { @@ -8213,6 +8314,13 @@ "babel-plugin-polyfill-regenerator": "^0.4.0", "core-js-compat": "^3.22.1", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "@babel/preset-modules": { @@ -8609,6 +8717,11 @@ "integrity": "sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==", "dev": true }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -8682,6 +8795,12 @@ "@types/node": "*" } }, + "@types/semver": { + "version": "7.3.12", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", + "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "dev": true + }, "@types/trusted-types": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", @@ -8702,17 +8821,6 @@ "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/parser": { @@ -8767,17 +8875,6 @@ "is-glob": "^4.0.3", "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/utils": { @@ -9140,6 +9237,13 @@ "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.2", "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "babel-plugin-polyfill-corejs3": { @@ -9499,6 +9603,31 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz", "integrity": "sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw==" }, + "engine.io-client": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.2.tgz", + "integrity": "sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0" + }, + "dependencies": { + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} + } + } + }, + "engine.io-parser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" + }, "entities": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", @@ -9927,18 +10056,6 @@ "postcss-selector-parser": "^6.0.9", "semver": "^7.3.5", "vue-eslint-parser": "^8.0.1" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "eslint-scope": { @@ -10866,7 +10983,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -11357,9 +11473,12 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } }, "serialize-javascript": { "version": "4.0.0", @@ -11399,6 +11518,26 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "socket.io-client": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.2.tgz", + "integrity": "sha512-naqYfFu7CLDiQ1B7AlLhRXKX3gdeaIMfgigwavDzgJoIUYulc1qHH5+2XflTsXTPY7BlPH5rppJyUjhjrKQKLg==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" + } + }, + "socket.io-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, "sortablejs": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", @@ -11685,6 +11824,11 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==" }, + "unique-names-generator": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz", + "integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==" + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -11847,15 +11991,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, @@ -12279,11 +12414,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index 24a31af..e45232c 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,9 @@ "is-plain-object": "^5.0.0", "lz-string": "^1.4.4", "nanoevents": "^6.0.2", + "semver": "^7.3.7", + "socket.io-client": "^4.5.2", + "unique-names-generator": "^4.7.1", "vite": "^2.9.12", "vite-plugin-pwa": "^0.12.0", "vite-tsconfig-paths": "^3.5.0", @@ -38,6 +41,7 @@ "@ivanv/vue-collapse-transition": "^1.0.2", "@rushstack/eslint-patch": "^1.1.0", "@types/lz-string": "^1.3.34", + "@types/semver": "^7.3.12", "@vue/eslint-config-prettier": "^7.0.0", "@vue/eslint-config-typescript": "^10.0.0", "eslint": "^8.6.0", diff --git a/src/components/Nav.vue b/src/components/Nav.vue index d2017a8..eefc1b0 100644 --- a/src/components/Nav.vue +++ b/src/components/Nav.vue @@ -41,6 +41,11 @@ library_books +
+ + group + +
settings @@ -58,6 +63,11 @@ library_books
+
+ + group + +
settings @@ -96,12 +106,15 @@ + + + + + diff --git a/src/data/RoomsDialog.vue b/src/data/RoomsDialog.vue new file mode 100644 index 0000000..a0c2de1 --- /dev/null +++ b/src/data/RoomsDialog.vue @@ -0,0 +1,234 @@ + + + + + diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index 8ee2c7b..4b535dd 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -1,75 +1,25 @@ -import Spacer from "components/layout/Spacer.vue"; import { jsx } from "features/feature"; -import { createResource, trackBest, trackOOMPS, trackTotal } from "features/resources/resource"; -import type { GenericTree } from "features/trees/tree"; -import { branchedResetPropagation, createTree } from "features/trees/tree"; -import { globalBus } from "game/events"; import type { BaseLayer, GenericLayer } from "game/layers"; import { createLayer } from "game/layers"; +import { persistent } from "game/persistence"; import type { PlayerData } from "game/player"; -import player from "game/player"; -import type { DecimalSource } from "util/bignum"; -import Decimal, { format, formatTime } from "util/bignum"; -import { render } from "util/vue"; -import { computed, toRaw } from "vue"; -import prestige from "./layers/prestige"; +import { computed } from "vue"; /** * @hidden */ export const main = createLayer("main", function (this: BaseLayer) { - const points = createResource(10); - const best = trackBest(points); - const total = trackTotal(points); - - const pointGain = computed(() => { - // eslint-disable-next-line prefer-const - let gain = new Decimal(1); - return gain; - }); - globalBus.on("update", diff => { - points.value = Decimal.add(points.value, Decimal.times(pointGain.value, diff)); - }); - const oomps = trackOOMPS(points, pointGain); - - const tree = createTree(() => ({ - nodes: [[prestige.treeNode]], - branches: [], - onReset() { - points.value = toRaw(this.resettingNode.value) === toRaw(prestige.treeNode) ? 0 : 10; - best.value = points.value; - total.value = points.value; - }, - resetPropagation: branchedResetPropagation - })) as GenericTree; + const contentPacks = persistent<(ContentPack | string)[]>(["core"]); return { - name: "Tree", - links: tree.links, + name: "Main", + minimizable: false, + contentPacks, display: jsx(() => ( <> - {player.devSpeed === 0 ?
Game Paused
: null} - {player.devSpeed && player.devSpeed !== 1 ? ( -
Dev Speed: {format(player.devSpeed)}x
- ) : null} - {player.offlineTime ? ( -
Offline Time: {formatTime(player.offlineTime)}
- ) : null} -
- {Decimal.lt(points.value, "1e1000") ? You have : null} -

{format(points.value)}

- {Decimal.lt(points.value, "1e1e6") ? points : null} -
- {Decimal.gt(pointGain.value, 0) ?
({oomps.value})
: null} - - {render(tree)} +
placeholder
- )), - points, - best, - total, - oomps, - tree + )) }; }); @@ -80,7 +30,7 @@ export const main = createLayer("main", function (this: BaseLayer) { export const getInitialLayers = ( /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ player: Partial -): Array => [main, prestige]; +): Array => [main]; /** * A computed ref whose value is true whenever the game is over. diff --git a/src/data/projInfo.json b/src/data/projInfo.json index 1504cba..9bf6603 100644 --- a/src/data/projInfo.json +++ b/src/data/projInfo.json @@ -1,15 +1,15 @@ { - "title": "Profectus", - "description": "A project made in Profectus", - "id": "", - "author": "", + "title": "Alkatest", + "description": "A test", + "id": "alkatest", + "author": "thepaperpilot", "discordName": "", "discordLink": "", - "versionNumber": "0.0", + "versionNumber": "0.0.0", "versionTitle": "Initial Commit", - "allowGoBack": true, + "allowGoBack": false, "defaultShowSmall": false, "defaultDecimalsShown": 2, "useHeader": true, diff --git a/src/data/socket.tsx b/src/data/socket.tsx new file mode 100644 index 0000000..7f1c2ed --- /dev/null +++ b/src/data/socket.tsx @@ -0,0 +1,190 @@ +import Text from "components/fields/Text.vue"; +import { jsx, setDefault } from "features/feature"; +import { globalBus } from "game/events"; +import settings, { registerSettingField } from "game/settings"; +import { io, Socket } from "socket.io-client"; +import { load } from "util/save"; +import { ref, watch } from "vue"; +import { uniqueNamesGenerator, adjectives, colors, animals } from "unique-names-generator"; +import player from "game/player"; +import { useToast } from "vue-toastification"; +import { ProxyState } from "util/proxies"; +import satisfies from "semver/functions/satisfies"; +import projInfo from "data/projInfo.json"; + +export const connected = ref(false); +export const room = ref(null); +export const isHosting = ref(false); +export const nicknames = ref>({}); + +const toast = useToast(); + +const socket = ref | null>(); +const connectionError = ref(""); + +export function emit( + event: T, + ...args: Parameters +): void { + if (!connected.value) { + return; + } + socket.value?.emit(event, ...args); +} + +export function getGameState(): GameState { + return player.layers.main[ProxyState] as unknown as GameState; +} + +globalBus.on("loadSettings", settings => { + setDefault(settings, "server", window.location.origin); + setDefault(settings, "nickname", randomName()); + + watch( + () => settings.server, + server => { + if (socket.value) { + socket.value.close(); + } + + socket.value = io(server); + setupSocket(socket.value); + + connected.value = false; + connectionError.value = ""; + socket.value.connect(); + }, + { immediate: true } + ); + + watch( + () => settings.nickname, + nickname => { + if (room.value) { + emit("set nickname", nickname); + } + } + ); + + registerSettingField( + jsx(() => ( + <> + (settings.server = value)} + modelValue={settings.server} + /> +
+ {connected.value ? ( + Connected! + ) : connectionError.value ? ( + {connectionError.value} + ) : ( + Connecting... + )} +
+ + )) + ); + registerSettingField( + jsx(() => ( + <> + ( + + Nickname + + + ))} + onUpdate:modelValue={value => (settings.nickname = value)} + modelValue={settings.nickname} + /> + + )) + ); +}); + +function setupSocket(socket: Socket) { + socket.on("connect", () => { + connectionError.value = ""; + connected.value = true; + }); + socket.on("connect_error", error => { + connectionError.value = `${error.name}: ${error.message}`; + }); + socket.on("disconnect", (reason, details) => { + connectionError.value = + details instanceof Error + ? `${details.name}: ${details.message}` + : details?.description ?? reason; + connected.value = false; + }); + socket.on("server version", semver => { + if (!satisfies(projInfo.versionNumber, semver)) { + toast.info("Server only accepts game versions in range: " + semver); + socket.disconnect(); + } + }); + + socket.on("info", message => { + toast.info(message); + globalBus.emit("serverSentInfo"); + }); + socket.on("set rooms", rooms => { + globalBus.emit("setRooms", rooms); + }); + socket.on("joined room", (r, hosting) => { + room.value = r; + isHosting.value = hosting; + }); + socket.on("left room", () => { + room.value = null; + }); + socket.on("set nicknames", n => { + nicknames.value = n; + }); +} + +function randomName(): string { + return uniqueNamesGenerator({ + dictionaries: [adjectives, colors, animals], + length: 3, + separator: " ", + style: "capital" + }); +} + +watch(connected, connected => { + if (!connected && room.value) { + stopMultiplayer(); + } +}); + +function stopMultiplayer() { + if (!isHosting.value) { + load(); + } + room.value = null; + isHosting.value = false; +} + +declare module "game/settings" { + interface Settings { + server: string; + nickname: string; + } +} + +declare module "game/events" { + interface GlobalEvents { + openMultiplayer: VoidFunction; + setRooms: (rooms: ClientRoomData[]) => void; + serverSentInfo: VoidFunction; + } +} diff --git a/src/util/save.ts b/src/util/save.ts index 4138e17..b26013e 100644 --- a/src/util/save.ts +++ b/src/util/save.ts @@ -1,4 +1,5 @@ import projInfo from "data/projInfo.json"; +import { isHosting, room } from "data/socket"; import { globalBus } from "game/events"; import type { Player, PlayerData } from "game/player"; import player, { stringifySave } from "game/player"; @@ -118,12 +119,12 @@ export async function loadSave(playerObj: Partial): Promise { } setInterval(() => { - if (player.autosave) { + if (player.autosave && (!room.value || isHosting.value)) { save(); } }, 1000); window.onbeforeunload = () => { - if (player.autosave) { + if (player.autosave && (!room.value || isHosting.value)) { save(); } };