From 2f6f98ff30cff51ba06eac63397ffebcceb07ecc Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Mon, 20 Mar 2023 13:46:22 +0100 Subject: [PATCH] better --- package-lock.json | 439 +++++++++++++++++++++++++++++ package.json | 19 +- src/client.ts | 1 - src/definitions/settings.d.ts | 99 +++++-- src/game_standard.ts | 1 - src/games/chainreact.ts | 104 +++++++ src/games/game_standard.ts | 37 +++ src/games/global_draw.ts | 149 ++++++++++ src/games/memory.ts | 14 + src/games/pong.ts | 10 + src/index.ts | 12 +- src/manager.ts | 1 - src/room.ts | 1 - src/start.ts | 16 +- ssl_certificate/make_selfsigned.sh | 1 - tsconfig.json | 20 +- 16 files changed, 852 insertions(+), 72 deletions(-) create mode 100644 package-lock.json create mode 100644 src/games/chainreact.ts create mode 100644 src/games/game_standard.ts create mode 100644 src/games/global_draw.ts create mode 100644 src/games/memory.ts create mode 100644 src/games/pong.ts delete mode 100644 ssl_certificate/make_selfsigned.sh diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d090b32 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,439 @@ +{ + "name": "chainreact-server", + "version": "2.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "chainreact-server", + "version": "2.0", + "dependencies": { + "dotenv": "^16.0.3", + "https": "^1.0.0", + "socket.io": "^4.4.1", + "typescript": "^5.0.2" + }, + "devDependencies": { + "@types/node": "^18.15.3" + } + }, + "base": { + "name": "game-server", + "version": "2.0", + "extraneous": true, + "dependencies": { + "dotenv": "^16.0.3", + "https": "^1.0.0", + "ini": "^2.0.0", + "socket.io": "^4.4.1" + }, + "devDependencies": { + "@types/node": "^17.0.18", + "typescript": "^4.8.4" + } + }, + "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/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "node_modules/@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz", + "integrity": "sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/engine.io": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", + "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/socket.io": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", + "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "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 + } + } + } + }, + "dependencies": { + "@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==" + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz", + "integrity": "sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "engine.io": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", + "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0" + } + }, + "engine.io-parser": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==" + }, + "https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "socket.io": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" + } + }, + "socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "requires": { + "ws": "~8.11.0" + } + }, + "socket.io-parser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", + "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, + "typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "requires": {} + } + } +} diff --git a/package.json b/package.json index cf1776c..e4f5b4a 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,18 @@ { - "name": "game-server", + "name": "chainreact-server", "version": "2.0", "private": true, - "type": "commonjs", - "main": "out/index.js", - "types": "out/index.d.ts", + "scripts": { + "start": "node out/index.js", + "tsc": "npx tsc" + }, "dependencies": { "dotenv": "^16.0.3", "https": "^1.0.0", - "ini": "^2.0.0", - "socket.io": "^4.4.1" + "socket.io": "^4.4.1", + "typescript": "^5.0.2" }, "devDependencies": { - "@types/node": "^17.0.18", - "typescript": "^4.8.4" - }, - "scripts": { - "start": "node out/index.js" + "@types/node": "^18.15.3" } } diff --git a/src/client.ts b/src/client.ts index 9494723..873e6a2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2,7 +2,6 @@ import {Room} from "./room.js" import {ConnectionManager, serializeObject} from "./manager.js" import {log} from "./logger.js"; import * as SocketIO from "socket.io"; -import { Settings } from "./definitions/settings"; export class Client { diff --git a/src/definitions/settings.d.ts b/src/definitions/settings.d.ts index d269460..0d73fef 100644 --- a/src/definitions/settings.d.ts +++ b/src/definitions/settings.d.ts @@ -1,29 +1,74 @@ -import {ServerGame} from "../game_standard.js"; - declare module Settings { - interface Global { - project: Project - frameWork: FrameWork - game: any - always: boolean - spectators: boolean - } - - interface Project { - name: string - author: string - playerCounts: number[] - } - - interface FrameWork { - frameRate: number - updateRate: number - width: number - height: number - } - - interface Server { - useP2P: boolean - gameClass: typeof ServerGame - } + interface Global { + project: Project + frameWork: FrameWork + game: any + always: boolean + spectators: boolean + } + + interface Project { + name: string + author: string + playerCounts: number[] + } + + interface FrameWork { + frameRate: number + updateRate: number + width: number + height: number + } + + interface Game { + ball: Ball + player: Player + cw: number + ch: number + } + + interface Ball { + radius: number + velocity: number + acceleration: number + runUp: Ball.RunUp + color: Color + cw: number + ch: number + } + + interface Player { + width: number + height: number + margin: number + points: number + normal: State + weakened: State + enhanced: State + cw: number + ch: number + } + + interface Color { + stroke: string + fill: string + } + + interface State { + vel: Vector + color: Color + moveMargin: number + } + + interface Vector { + x: number + y: number + } + + module Ball { + interface RunUp { + min: number + max: number + } + } } \ No newline at end of file diff --git a/src/game_standard.ts b/src/game_standard.ts index defdf2d..33b4ca8 100644 --- a/src/game_standard.ts +++ b/src/game_standard.ts @@ -1,6 +1,5 @@ import {Room} from "./room.js" import {Client} from "./client.js" -import { Settings } from "./definitions/settings.js"; export class ServerGame { diff --git a/src/games/chainreact.ts b/src/games/chainreact.ts new file mode 100644 index 0000000..809db6c --- /dev/null +++ b/src/games/chainreact.ts @@ -0,0 +1,104 @@ +import {Room} from "../room" +import {ServerGame} from "./game_standard" +import {Client} from "../client" + +export class Chainreact extends ServerGame { + + readyForTurn: Client[]; + currentTurnIndex: number; + currentGameData: any; + colorHues: { [id: string]: number }; + + constructor(room: Room, settings: Settings.Global) { + super(room, settings); + this.readyForTurn = [] + } + + setEvents(client: Client) { + let socket = client.socket; + socket.on('ready-for-turn', isDead => { + if (isDead) { + client.isPlayer = false; + client.isSpectator = true; + this.room.toAll('client-list', this.room.clients) + } else { + this.readyForTurn.push(client) + } + + let allReady = true; + this.room.players.forEach(c => { + if (this.readyForTurn.find(r => r.id === c.id) == null) { + allReady = false + } + }); + if (allReady) { + this.nextTurn(); + this.readyForTurn = [] + } + }); + socket.on('set-slot', (fieldsIndex: number, slotsIndex: number) => { + this.room.toAll('set-slot', fieldsIndex, slotsIndex, socket.id) + }); + socket.on('game-data', data => this.currentGameData = data) + } + + addClient(client: Client): void { + super.addClient(client); + if (client.isSpectator) { + let room = this.room; + let data = this.currentGameData; + let hues = this.colorHues; + let turnId = ''; + if (this.room.players[this.currentTurnIndex]) + turnId = this.room.players[this.currentTurnIndex].id; + client.send('start-spectate', room, data, hues, turnId) + } + } + + removeClient(client: Client): void { + super.removeClient(client); + if (this.room.players.indexOf(client) === this.currentTurnIndex) + this.nextTurn(true); + + let s = client.socket; + s.removeAllListeners('set-slot'); + s.removeAllListeners('ready-for-turn'); + s.removeAllListeners('game-data') + } + + nextTurn(skip?: boolean) { + if (this.currentTurnIndex != null && !skip) { + this.currentTurnIndex++; + if (this.currentTurnIndex >= this.room.players.length) { + this.currentTurnIndex = 0 + } + } else if (!skip) { + this.setTurnAndColors() + } + let index = this.currentTurnIndex; + if (skip) { + index = this.currentTurnIndex + 1; + if (index >= this.room.players.length) { + index = 0; + this.currentTurnIndex = 0 + } + } + if (this.room.players.length) { + this.room.toAll('current-turn', this.room.players[index].id) + } + } + + setTurnAndColors() { + this.currentTurnIndex = Math.floor(Math.random() * this.room.players.length); + let colorHues = [0, 60, 120, 240]; + this.colorHues = {}; + for (let c of this.room.players) { + let index = Math.floor(Math.random() * colorHues.length); + let hue = colorHues[index]; + colorHues.splice(index, 1); + this.colorHues[c.id] = hue + } + this.room.toAll('player-colors', this.colorHues) + } + +} \ No newline at end of file diff --git a/src/games/game_standard.ts b/src/games/game_standard.ts new file mode 100644 index 0000000..4b726f8 --- /dev/null +++ b/src/games/game_standard.ts @@ -0,0 +1,37 @@ +import {Room} from "../room" +import {Client} from "../client" + +export class ServerGame { + + room: Room; + settings: Settings.Global; + game: any; + + constructor(room: Room, settings: Settings.Global) { + this.settings = settings; + this.room = room; + this.room.clients.forEach(c => this.addClient(c)) + } + + addClient(client: Client): void { + this.setEvents(client) + } + + removeClient(client: Client): void { + this.removeEvents(client) + } + + gameAction(action: string, ...args: any[]): void { + } + + setEvents(client: Client): void { + let socket = client.socket; + socket.on('game-action', (action, ...args) => this.gameAction(action, ...args)) + } + + removeEvents(client: Client): void { + let socket = client.socket; + socket.removeAllListeners('game-action') + } + +} \ No newline at end of file diff --git a/src/games/global_draw.ts b/src/games/global_draw.ts new file mode 100644 index 0000000..2c206e1 --- /dev/null +++ b/src/games/global_draw.ts @@ -0,0 +1,149 @@ +import {ServerGame} from "./game_standard" +import {Room} from "../room" +import {Client} from "../client" +import {log} from "../logger"; + +import fs = require("fs"); + +export class GlobalDraw extends ServerGame { + + lines: any[]; + pixels: any[][]; + + linesPath = "json_data/global_draw/lines.json"; + pixelsPath = "json_data/global_draw/pixels.json"; + + pixelCount = 1000; + + constructor(lobby: Room, settings: Settings.Global) { + super(lobby, settings); + + this.lines = []; + this.pixels = []; + + for (let x = 0; x < this.pixelCount; x++) { + let column = []; + for (let y = 0; y < this.pixelCount; y++) { + column.push({x: x, y: y, c: "#ffffff"}); + } + this.pixels.push(column); + } + + let linesLoaded = false; + let pixelsLoaded = false; + + this.loadDrawingsFromFile(this.linesPath, (data: any[]) => { + this.lines = data; + }, () => { + linesLoaded = true; + if (pixelsLoaded) { + this.startSaveInterval(); + } + }); + this.loadDrawingsFromFile(this.pixelsPath, (data: any[]) => { + for (let x = 0; x < this.pixelCount; x++) { + for (let y = 0; y < this.pixelCount; y++) { + if (data[x]) + if (data[x][y]) + this.pixels[x][y].c = data[x][y].c + } + } + }, () => { + pixelsLoaded = true; + if (linesLoaded) { + this.startSaveInterval(); + } + }); + } + + startSaveInterval() { + this.saveAllDrawingsToFile(); + + //Saves once every day + setInterval(() => this.saveAllDrawingsToFile(), 1000 * 60 * 60 * 24); + } + + addLine(line: any) { + this.lines.push(line); + this.room.toAll('add-line', line) + } + + fillPixel(pixel: any) { + this.pixels[pixel.x][pixel.y].c = pixel.c; + this.room.toAll('fill-pixel', pixel) + } + + loadDrawingsFromFile(drawingsPath: string, successs: (data: any[]) => void, done: () => void) { + fs.readFile(drawingsPath, 'utf8', (err, data) => { + if (err) + log('load-error', null, this.room, err.message); + else { + try { + let parsed = JSON.parse(data); + log('load-success', null, this.room); + successs(parsed); + } catch (e) { + log('parse-error', null, this.room, e.message); + } + } + done(); + }); + } + + saveDrawingsToFile(drawings: any[], drawingsPath: string, callback: (err: any) => void) { + let splits = drawingsPath.split('/'); + let path = splits.slice(0, splits.length - 1).reduce((prev, curr) => prev + '/' + curr); + let name = splits[splits.length - 1]; + if (!fs.existsSync(path)) { + fs.mkdirSync(path, {recursive: true}); + } + fs.writeFile(drawingsPath, JSON.stringify(drawings), callback); + } + + saveAllDrawingsToFile() { + let linesSaved = false; + let pixelsSaved = false; + + this.saveDrawingsToFile(this.lines, this.linesPath, (err) => { + if (err) + log('save-error', null, this.room, err.message); + else { + linesSaved = true; + if (pixelsSaved) { + this.room.toAll('all-saved'); + linesSaved = false; + pixelsSaved = false + } + log('save-success', null, this.room, 'Successfully saved lines to file') + } + }); + this.saveDrawingsToFile(this.pixels, this.pixelsPath, (err) => { + if (err) + log('save-error', null, this.room, err.message); + else { + pixelsSaved = true; + if (linesSaved) { + this.room.toAll('all-saved'); + pixelsSaved = false; + linesSaved = false + } + log('save-success', null, this.room, 'Successfully saved pixels to file') + } + }); + } + + addClient(client: Client): void { + this.setEvents(client); + } + + setEvents(client: Client): void { + super.setEvents(client); + let socket = client.socket; + socket.on('add-line', (line) => this.addLine(line)); + socket.on('fill-pixel', (pixel) => this.fillPixel(pixel)); + socket.on('request-all-lines', () => socket.emit('add-all', this.lines)); + socket.on('request-all-pixels', () => socket.emit('fill-all', this.pixels)); + socket.on('save-all', () => this.saveAllDrawingsToFile()); + } + +} \ No newline at end of file diff --git a/src/games/memory.ts b/src/games/memory.ts new file mode 100644 index 0000000..4b503a0 --- /dev/null +++ b/src/games/memory.ts @@ -0,0 +1,14 @@ +import {Room} from "../room" +import {ServerGame} from "./game_standard" + +export class Memory extends ServerGame { + + constructor(room: Room, settings: Settings.Global) { + super(room, settings); + } + + gameAction(action: string, ...args: any[]) { + this.room.toAll('game-action', action, ...args); + } + +} \ No newline at end of file diff --git a/src/games/pong.ts b/src/games/pong.ts new file mode 100644 index 0000000..02b1804 --- /dev/null +++ b/src/games/pong.ts @@ -0,0 +1,10 @@ +import {ServerGame} from "./game_standard" +import {Room} from "../room"; + +export class Pong extends ServerGame { + + constructor(lobby: Room, settings: Settings.Global) { + super(lobby, settings) + } + +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 7fea5c2..8288048 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -'use strict'; +import {Chainreact} from "./chainreact"; +import {StartServer} from "./start"; -export {StartServer} from "./start.js" -export {Room} from "./room.js" -export {log} from "./logger.js" -export {Client} from "./client.js" -export {ServerGame} from "./game_standard.js" +StartServer({ + useP2P: false, + gameClass: Chainreact +}); \ No newline at end of file diff --git a/src/manager.ts b/src/manager.ts index 59c65d0..a15fabf 100644 --- a/src/manager.ts +++ b/src/manager.ts @@ -3,7 +3,6 @@ import {Client} from "./client.js" import {log} from "./logger.js" import * as fs from "fs"; import * as SocketIO from "socket.io" -import { Settings } from "./definitions/settings"; export class ConnectionManager { diff --git a/src/room.ts b/src/room.ts index b6d3036..8510b03 100644 --- a/src/room.ts +++ b/src/room.ts @@ -2,7 +2,6 @@ import {Client} from "./client.js" import {ServerGame} from "./game_standard.js" import {serializeObject} from "./manager.js"; import {Server} from "socket.io"; -import { Settings } from "./definitions/settings.js"; export class Room { diff --git a/src/start.ts b/src/start.ts index 575fa0f..82293ed 100644 --- a/src/start.ts +++ b/src/start.ts @@ -1,26 +1,24 @@ import {ConnectionManager} from "./manager.js"; import {log} from "./logger.js"; -import https from 'https'; import {Server} from 'socket.io'; -import fs from 'fs'; -import { Settings } from "./definitions/settings"; import {Room} from "./room.js"; +import * as https from "https"; +import * as fs from "fs"; -export function StartServer(settings: Settings.Server){ - let rootDir = __dirname + '/..'; +export function StartServer(settings: any){ require("dotenv").config(); - const httpsPort = parseInt(process.env["HTTPS_PORT"]); + const httpsPort = parseInt(process.env.HTTPS_PORT); - let cert = fs.readFileSync(rootDir + '/ssl_certificate/cert.pem'); - let key = fs.readFileSync(rootDir + '/ssl_certificate/key.pem'); + let cert = fs.readFileSync(`${process.env.SSL_PATH}/cert.pem`); + let key = fs.readFileSync(`${process.env.SSL_PATH}/key.pem`); let httpsServer = https.createServer({key: key, cert: cert}); let sIO = new Server(httpsServer, { cors: { - origin: ["https://play.benjamin-kraft.local", "https://dev.play.benjamin-kraft.eu", "https://play.benjamin-kraft.eu"] + origin: ["https://play.benjamin-kraft.local", "https://play.benjamin-kraft.eu"] } }); if (settings.useP2P){ diff --git a/ssl_certificate/make_selfsigned.sh b/ssl_certificate/make_selfsigned.sh deleted file mode 100644 index eb26ebf..0000000 --- a/ssl_certificate/make_selfsigned.sh +++ /dev/null @@ -1 +0,0 @@ -openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index e8e5bb6..3be4fdb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,11 @@ { "compilerOptions": { - "target": "ES2022", - "module": "Node16", - "moduleResolution": "Node", - "esModuleInterop": true, - - "alwaysStrict": true, - "removeComments": true, - - "declaration": true, - "declarationMap": true, + "module": "CommonJS", + "outDir": "./out", "sourceMap": true, - "outDir": "./out" + "alwaysStrict": true }, - "include": [ - "src/**/*.ts" - ] + "include": [ + "./src" + ] } \ No newline at end of file