From a5ba03a22d4988354f4ad4eda60c1a716b5c430d Mon Sep 17 00:00:00 2001 From: Jacob Medina Date: Thu, 3 Aug 2023 03:07:05 -0400 Subject: [PATCH 1/8] made socket.io connection, began creating race menu --- package-lock.json | 496 +++++++++++++++++++++++++++++++++- package.json | 4 +- public/assets/modules/race.js | 5 + public/index.html | 36 +++ public/main.js | 11 + server.js | 14 +- 6 files changed, 563 insertions(+), 3 deletions(-) create mode 100644 public/assets/modules/race.js diff --git a/package-lock.json b/package-lock.json index 3ca3f6a..52577f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,37 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "express": "^4.18.2" + "express": "^4.18.2", + "socket.io": "^4.7.2", + "socket.io-client": "^4.7.2" }, "devDependencies": { "nodemon": "^3.0.1" } }, + "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": "20.4.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.6.tgz", + "integrity": "sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==" + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -57,6 +82,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -196,6 +229,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "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": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -234,6 +279,96 @@ "node": ">= 0.8" } }, + "node_modules/engine.io": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.2.tgz", + "integrity": "sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==", + "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.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz", + "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/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/engine.io-client/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/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/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/engine.io/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/engine.io/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/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -662,6 +797,14 @@ "node": ">=0.10.0" } }, + "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/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -883,6 +1026,120 @@ "node": ">=10" } }, + "node_modules/socket.io": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", + "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.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-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-client/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/socket.io-client/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/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/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/socket.io-parser/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/socket.io/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/socket.io/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/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -977,6 +1234,34 @@ "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 + } + } + }, + "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", @@ -985,6 +1270,29 @@ } }, "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": "20.4.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.6.tgz", + "integrity": "sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1021,6 +1329,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1124,6 +1437,15 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "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": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1152,6 +1474,75 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, + "engine.io": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.2.tgz", + "integrity": "sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==", + "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.2.1", + "ws": "~8.11.0" + }, + "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "engine.io-client": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz", + "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1466,6 +1857,11 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "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==" + }, "object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -1624,6 +2020,93 @@ "semver": "^7.5.3" } }, + "socket.io": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", + "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "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-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1691,6 +2174,17 @@ "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": {} + }, + "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", diff --git a/package.json b/package.json index 29e89f5..f1daf71 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ }, "homepage": "https://github.com/jacob-medina/totk-bingo#readme", "dependencies": { - "express": "^4.18.2" + "express": "^4.18.2", + "socket.io": "^4.7.2", + "socket.io-client": "^4.7.2" }, "devDependencies": { "nodemon": "^3.0.1" diff --git a/public/assets/modules/race.js b/public/assets/modules/race.js new file mode 100644 index 0000000..0ccfb6c --- /dev/null +++ b/public/assets/modules/race.js @@ -0,0 +1,5 @@ +function startRace(socket) { + socket.emit('new-race', {seed: '123456'}); +} + +export { startRace }; \ No newline at end of file diff --git a/public/index.html b/public/index.html index 57f8903..981ba40 100644 --- a/public/index.html +++ b/public/index.html @@ -38,6 +38,11 @@

Bingo

share + + @@ -141,6 +146,37 @@

Share

+ +
+ +
+

Race

+ +
+ +
+

Join a room:

+
+ + +
+
+ +

Create a room:

+
+ + +
+
+
diff --git a/public/main.js b/public/main.js index 9e5009c..0f7f239 100644 --- a/public/main.js +++ b/public/main.js @@ -9,10 +9,18 @@ import { handleRandomSeedBtn, newBoard, handleOptionsFormSubmit, setBoardSizeVal import { isBetween, clamp, hideElement, showElement } from "./assets/modules/helper.js"; import { updateShareURL, copyShareURL } from "./assets/modules/share.js"; +import { io } from "https://cdn.socket.io/4.3.2/socket.io.esm.min.js"; +import { startRace } from './assets/modules/race.js'; + let rand; let url; let searchParams; +const socket = io(location.origin); + +socket.on('connect', () => { + console.log(`You connected with ID: ${socket.id}`); +}); function init() { url = new URL(location.href); @@ -49,6 +57,9 @@ function init() { // share $('.copy-link-btn').on('click', copyShareURL); + //race + $('.race-btn').on('click', () => startRace(socket)); + // debug $('.show-stats-btn').on('click', showBoardStats); $('.hide-stats-btn').on('click', hideBoardStats); diff --git a/server.js b/server.js index d6e70aa..45fbf24 100644 --- a/server.js +++ b/server.js @@ -4,8 +4,20 @@ const path = require('path'); const entries = require('./lib/entries'); const app = express(); +const server = require('http').createServer(app); +const io = require('socket.io')(server); + const PORT = process.env.PORT || 3000; +const rooms = []; + +io.on('connection', socket => { + console.log(socket.id); + socket.on('new-race', (data) => { + console.log(data); + }) +}) + // static public folder app.use(express.static('public')); @@ -14,6 +26,6 @@ app.get('/api/entries', (req, res) => { res.json(entries); }); -app.listen(PORT, () => { +server.listen(PORT, () => { console.log(`Serving static assets on http://localhost:${PORT}`); }); \ No newline at end of file From 93829d64e828c15a5eeb8f3b46f548feb28fe8ed Mon Sep 17 00:00:00 2001 From: Jacob Medina Date: Thu, 3 Aug 2023 19:06:33 -0400 Subject: [PATCH 2/8] basic lockout race implementation --- public/assets/css/style.css | 21 ++++++++++--- public/assets/modules/race.js | 37 +++++++++++++++++++++-- public/index.html | 2 +- public/main.js | 33 +++++++++++++++----- server.js | 57 +++++++++++++++++++++++++++++++++-- 5 files changed, 132 insertions(+), 18 deletions(-) diff --git a/public/assets/css/style.css b/public/assets/css/style.css index c6e69a6..c937b0c 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -32,6 +32,9 @@ --green-dark: rgba(42, 138, 92, 0.5); --green-light: rgba(35, 205, 123, 0.3); + --orange-dark: rgba(138, 98, 42, 0.5); + --orange-light: rgba(205, 151, 35, 0.3); + --bg-img-dark: url("../images/background-dark.png") repeat; --bg-img-light: url("../images/background-light.png") repeat center/70%; @@ -92,6 +95,7 @@ body { --highlight: var(--highlight-light); --bg-highlight: var(--bg-highlight-light); --green: var(--green-dark); + --orange: var(--orange-dark); --bg-img: var(--bg-img-dark); background: var(--bg-img); @@ -106,6 +110,7 @@ body[data-color-mode="light"] { --highlight: var(--highlight-dark); --bg-highlight: var(--bg-highlight-dark); --green: var(--green-light); + --orange: var(--orange-light); --bg-img: var(--bg-img-light); } @@ -435,16 +440,24 @@ h1 { color: var(--highlight); } -.board-item:hover:not(.done) { +.board-item:hover:not(:is(.done-1, .done-2)) { background-color: var(--bg-highlight); } -.done, -.board-item:active:not(.done) { - background-color: var(--green); +.done-1, +.done-2 { backdrop-filter: blur(3px); } +.done-1 { +/* .board-item:active:not(.done) { */ + background-color: var(--green); +} + +.done-2 { + background-color: var(--orange); +} + .board-item p { margin: 0; } diff --git a/public/assets/modules/race.js b/public/assets/modules/race.js index 0ccfb6c..e6f534b 100644 --- a/public/assets/modules/race.js +++ b/public/assets/modules/race.js @@ -1,5 +1,36 @@ -function startRace(socket) { - socket.emit('new-race', {seed: '123456'}); +let clientNum = 1; +let room = null; + +function createRoom(socket) { + const roomName = $('#create-room-name').val(); + socket.emit('create-room', roomName); + + socket.on('create-room-response', ({res, error}) => { + if (error) { + console.warn(error); + return; + } + + room = roomName; + clientNum = 1; + console.log(res); + }); +} + +function joinRoom(socket) { + const roomName = $('#join-room-name').val(); + socket.emit('join-room', roomName); + + socket.on('join-room-response', ({res, error}) => { + if (error) { + console.warn(error); + return; + } + + room = roomName; + clientNum = 2; + console.log(res); + }); } -export { startRace }; \ No newline at end of file +export { createRoom, joinRoom, room, clientNum }; \ No newline at end of file diff --git a/public/index.html b/public/index.html index 981ba40..81bbed4 100644 --- a/public/index.html +++ b/public/index.html @@ -169,7 +169,7 @@

Race

Create a room:

- + +
+
diff --git a/public/main.js b/public/main.js index b3a76b0..69dff5b 100644 --- a/public/main.js +++ b/public/main.js @@ -7,7 +7,7 @@ import { updateShareURL, copyShareURL } from "./assets/modules/share.js"; import { fetchAndGenerateBoard } from "./assets/modules/board.js"; import { io } from "https://cdn.socket.io/4.3.2/socket.io.esm.min.js"; -import { createRoom, joinRoom, room, clientNum } from './assets/modules/race.js'; +import { createRoom, joinRoom, room, clientNum, handleReadyBtn, generatePlayerMenu, onConnect } from './assets/modules/race.js'; let rand; let url; @@ -15,20 +15,7 @@ let searchParams; const socket = io(location.origin); -socket.on('connect', () => { - console.log(`You connected with ID: ${socket.id}`); - - socket.on('receive-board-click', ({boardItem, clientNum, active}) => { - boardItem = $('#' + boardItem); - - if (active === true) { - boardItem.addClass(`done-${clientNum}`); - return; - } - - boardItem.removeClass(`done-${clientNum}`); - }) -}); +onConnect(socket); function init() { url = new URL(location.href); @@ -62,10 +49,13 @@ function init() { // share $('.copy-link-btn').on('click', copyShareURL); - //race - console.log(searchParams.toString()); + // race $('.create-room-btn').on('click', () => createRoom(socket, searchParams)); $('.join-room-btn').on('click', () => joinRoom(socket, searchParams)); + $('.ready-btn').on('click', () => handleReadyBtn(socket)); + + // misc + // window.addEventListener("beforeunload", (e) => beforeClose(e, socket)); // debug $('.show-stats-btn').on('click', showBoardStats); diff --git a/server.js b/server.js index c1cf6cc..e131da6 100644 --- a/server.js +++ b/server.js @@ -2,6 +2,7 @@ const express = require('express'); const path = require('path'); const entries = require('./lib/entries'); +// const { clientNum } = require('./public/assets/modules/race'); const app = express(); const server = require('http').createServer(app); @@ -11,25 +12,56 @@ const PORT = process.env.PORT || 3000; const rooms = []; +// returns the room object with a given name +function getRoom(roomName) { + return rooms.find(room => room.name === roomName); +} + +// returns the number of clients connected to a room +function getAmountClients(room) { + amountConnected = room.clients.reduce((sum, client) => { + return client.connected ? sum + 1: sum; }, + 0); + return amountConnected; +} + +// returns the number of clients who are ready in the waiting room +function getAmountReadyClients(room) { + amountReady = room.clients.reduce((sum, client) => { + return client.ready ? sum + 1: sum; }, + 0); + return amountReady; +} + +class Client { + constructor(id, num, connected=true) { + this.id = id; + this.num = num; + this.connected = connected; + this.timeout = null; + this.ready = false; + } +} + + io.on('connection', socket => { - console.log(socket.id); + console.info(`${socket.id} joined.`); // Create room socket.on('create-room', ({room, params}) => { - if (rooms.find(rm => rm.name === room)) { + if (getRoom(room)) { socket.emit('create-room-response', { error: `Room name ${room} already in use!` }); return; } - console.log(params); - rooms.push({ name: room, params: params, - clients: 1 + clients: [new Client(socket.id, 1)] }); + console.info(`Room "${room}" created by ${socket.id}`); socket.join(room); @@ -38,9 +70,10 @@ io.on('connection', socket => { }); }); + // Join room socket.on('join-room', (roomName) => { - const room = rooms.find(rm => rm.name === roomName); + const room = getRoom(roomName); if (room == null) { socket.emit('join-room-response', { @@ -49,17 +82,30 @@ io.on('connection', socket => { return; } - if (room.clients >= 2) { + if (getAmountClients(room) >= 2) { socket.emit('join-room-response', { - error: `Room already filled with ${room.clients} clients!` + error: `Room already filled with ${getAmountClients(room)} clients!` }); return; } - room.clients++; + let clientNum; + const unconnectedClient = room.clients.find(client => !client.connected); + + if (unconnectedClient) { + unconnectedClient = new Client(socket.id, unconnectedClient.num); + clientNum = unconnectedClient.num; + } + + else { + room.clients.push(new Client(socket.id, room.clients.length + 1)); + clientNum = room.clients.length; + } socket.join(roomName); + socket.to(roomName).emit('client-joined-room', clientNum); + socket.emit('join-room-response', { res: { message: `Joined room ${roomName}`, @@ -70,11 +116,67 @@ io.on('connection', socket => { console.info(rooms); }); + + socket.on('ready', (roomName, id) => { + const room = getRoom(roomName); + const client = room.clients.find(c => c.id === id); + + client.ready = true; + + const allReady = getAmountReadyClients(room) >= getAmountClients(room); + + io.in(roomName).emit('ready', client.num, allReady); + }); + + socket.on('request-ready-status', (roomName, cb) => { + const room = getRoom(roomName); + + const clients = []; + + for (const client of room.clients) { + clients.push({ + clientNum: client.num, + ready: client.ready + }); + } + + cb(clients); + }) + + + socket.on('disconnecting', reason => { + for (const roomName of socket.rooms) { + if (roomName === socket.id) continue; // pass over default room + + const room = getRoom(roomName); + const client = room.clients.find(c => c.id === socket.id); + + client.connected = false; + socket.to(roomName).emit('client-left-room', { + id: socket.id + }); + } + console.log(`Client ${socket.id} disconnected.`); + }); + + socket.on('board-click', (room, obj) => { socket.to(room).emit('receive-board-click', obj); - }) + }); }); +// continually delete rooms that have no connections +setInterval(() => { + for (room of rooms) { + // cancel if there are still connected clients in room + if (getAmountClients(room) > 0) continue; + + // remove room + rooms.splice(rooms.findIndex(rm => rm.name === room.name), 1); + console.info(`Room "${room.name}" deleted. No more clients connected.`); + } +}, 5000); + // static public folder app.use(express.static('public')); From 8a8f752681f8cfc89e30f665cef604df78adeb8a Mon Sep 17 00:00:00 2001 From: Jacob Medina Date: Sat, 5 Aug 2023 22:22:39 -0400 Subject: [PATCH 5/8] options sliders adjust to query parameters on load --- public/assets/modules/options.js | 18 ++++++------------ public/index.html | 23 ++++++++++++----------- public/main.js | 7 +++++-- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/public/assets/modules/options.js b/public/assets/modules/options.js index 61dbfdf..a997024 100644 --- a/public/assets/modules/options.js +++ b/public/assets/modules/options.js @@ -70,31 +70,25 @@ function resetOptions() { function setBoardSize(val) { - boardSize = val; + boardSize = Math.floor(Number(val)); } function setDifficulty(val) { - diffMultiplier = val; + diffMultiplier = parseFloat(val).toFixed(1); } function setBoardSizeValue(val) { - if (val && val.type !== 'input') { - setBoardSize(val); - $('#board-size-range').val(boardSize); - } - else setBoardSize($('#board-size-range').val()); + setBoardSize(val); + $('#board-size-range').val(boardSize); const text = boardSize + 'x' + boardSize; $('.board-size').text(text); } function setDifficultyValue(val) { - if (val && val.type !== 'input') { - setDifficulty(val); - $('#difficulty-range').val(diffMultiplier); - } - else setDifficulty( parseFloat($('#difficulty-range').val()).toFixed(1) ); + setDifficulty(val); + $('#difficulty-range').val(val); $('.difficulty').text(diffMultiplier); } diff --git a/public/index.html b/public/index.html index 09c3936..b717d45 100644 --- a/public/index.html +++ b/public/index.html @@ -157,24 +157,25 @@

Race

-

Join a room:

-
- - -
-
-

Create a room:

- +
+ +
+ +

Join a room:

+
+ + +
diff --git a/public/main.js b/public/main.js index 69dff5b..19925b4 100644 --- a/public/main.js +++ b/public/main.js @@ -30,6 +30,9 @@ function init() { rand = new SeededRandom(seed); $('#seed-input').val(seed); + + setBoardSizeValue(searchParams.get('boardSize') ?? defaultBoardSize); + setDifficultyValue(searchParams.get('difficulty') ?? defaultDiffMultiplier) updateShareURL(); setColorMode(getColorMode()); @@ -41,8 +44,8 @@ function init() { $('.options-form').on('submit', handleOptionsFormSubmit); $('.reroll-btn').on('click', () => handleRandomSeedBtn()); $('.random-seed-btn').on('click', () => handleRandomSeedBtn(false)); - $('#board-size-range').on('input', setBoardSizeValue); - $('#difficulty-range').on('input', setDifficultyValue); + $('#board-size-range').on('input', () => setBoardSizeValue($('#board-size-range').val())); + $('#difficulty-range').on('input', () => setDifficultyValue($('#difficulty-range').val())); $('.build-btn').on('click', handleOptionsFormSubmit); $('.reset-btn').on('click', resetOptions); From d8b2ec63746c701609e5c5d38343f8d88edc4ccc Mon Sep 17 00:00:00 2001 From: Jacob Medina Date: Sun, 6 Aug 2023 00:00:52 -0400 Subject: [PATCH 6/8] waiting room updates to players leaving and joining --- public/assets/css/style.css | 12 ++++++++++-- public/assets/modules/race.js | 33 +++++++++++++++++++++++++++++++-- public/index.html | 20 ++++++++++++++++---- public/main.js | 3 ++- server.js | 27 +++++++++++++++------------ 5 files changed, 74 insertions(+), 21 deletions(-) diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 82b7942..690b305 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -226,8 +226,13 @@ input[type="text"]:is(:focus, :hover) ::placeholder { padding: 0.5rem; } -.text-icon-btn:hover, -.icon-btn:hover, +.text-icon-btn[disabled], +.icon-btn[disabled] { + opacity: 60%; +} + +.text-icon-btn:hover:not([disabled]), +.icon-btn:hover:not([disabled]), div:has( > input[type="checkbox"]:hover) label { color: var(--highlight); border-color: var(--highlight); @@ -537,6 +542,9 @@ footer { /* RACE */ +.race-menu :is(h2, h3) { + font-family: "Hylia Serif"; +} .player-container { gap: 2rem; diff --git a/public/assets/modules/race.js b/public/assets/modules/race.js index 8255a74..5b64178 100644 --- a/public/assets/modules/race.js +++ b/public/assets/modules/race.js @@ -1,6 +1,7 @@ import { fetchAndGenerateBoard } from "./board.js"; import { SeededRandom } from "./SeededRandom.js"; import { updateShareURL } from "./share.js"; +import { hideElement } from "./helper.js"; let clientNum = 1; let room = null; @@ -10,10 +11,12 @@ function onConnect(socket) { console.log(`You connected with ID: ${socket.id}`); socket.on('client-joined-room', clientNum => { + $('.ready-btn').prop('disabled', false); generatePlayerMenu(clientNum); }); - socket.on('client-left-room', ({ id }) => { + socket.on('client-left-room', ({ id, clientNum }) => { + $(`.player-${clientNum}`).remove(); console.warn(`Client ${id} left the room!`); }); @@ -60,11 +63,16 @@ function createRoom(socket, urlSearchParams) { room = roomName; clientNum = 1; + + $('#room-name-title').text(room); + $('.ready-btn').prop('disabled', true); + clearUI(); generatePlayerMenu(clientNum); generateRaceMenu(); }); } + function joinRoom(socket, urlSearchParams) { const roomName = $('#join-room-name').val(); socket.emit('join-room', roomName); @@ -77,6 +85,7 @@ function joinRoom(socket, urlSearchParams) { room = roomName; clientNum = 2; + $('#room-name-title').text(room); socket.emit('request-ready-status', roomName, (clients) => { for (const client of clients) { @@ -90,6 +99,7 @@ function joinRoom(socket, urlSearchParams) { const seed = urlSearchParams.get("seed"); const rand = new SeededRandom(seed); + clearUI(); $('#seed-input').val(seed); updateShareURL(); fetchAndGenerateBoard(urlSearchParams, rand); @@ -97,6 +107,25 @@ function joinRoom(socket, urlSearchParams) { }); } + +function leaveRoom() { + location.reload(); +} + + +function clearUI() { + // hide menu buttons + hideElement('.reroll-btn'); + hideElement('button[data-bs-target="#options-sidebar"]'); + hideElement('button[data-bs-target="#share-sidebar"]'); + hideElement('button[data-bs-target="#race-sidebar"]'); + + // close sidebar + const raceSidebar = bootstrap.Offcanvas.getInstance('#race-sidebar'); + raceSidebar.hide(); +} + + function generatePlayerMenu(clientNum, ready=false) { const readyIcon = ready ? 'check_circle' : 'radio_button_unchecked'; @@ -133,4 +162,4 @@ function beginRace() { $('.bingo-board').removeClass('hide'); } -export { onConnect, createRoom, joinRoom, room, clientNum, handleReadyBtn, generatePlayerMenu }; \ No newline at end of file +export { onConnect, createRoom, joinRoom, room, clientNum, handleReadyBtn, generatePlayerMenu, leaveRoom }; \ No newline at end of file diff --git a/public/index.html b/public/index.html index b717d45..9d261df 100644 --- a/public/index.html +++ b/public/index.html @@ -157,8 +157,8 @@

Race

-

Create a room:

-
+

Create a room:

+
+

-

Join a room:

-
+

Join a room:

+
+ + +
diff --git a/public/main.js b/public/main.js index 19925b4..6a4b2d4 100644 --- a/public/main.js +++ b/public/main.js @@ -7,7 +7,7 @@ import { updateShareURL, copyShareURL } from "./assets/modules/share.js"; import { fetchAndGenerateBoard } from "./assets/modules/board.js"; import { io } from "https://cdn.socket.io/4.3.2/socket.io.esm.min.js"; -import { createRoom, joinRoom, room, clientNum, handleReadyBtn, generatePlayerMenu, onConnect } from './assets/modules/race.js'; +import { createRoom, joinRoom, room, clientNum, handleReadyBtn, generatePlayerMenu, onConnect, leaveRoom } from './assets/modules/race.js'; let rand; let url; @@ -56,6 +56,7 @@ function init() { $('.create-room-btn').on('click', () => createRoom(socket, searchParams)); $('.join-room-btn').on('click', () => joinRoom(socket, searchParams)); $('.ready-btn').on('click', () => handleReadyBtn(socket)); + $('.exit-room-btn').on('click', leaveRoom); // misc // window.addEventListener("beforeunload", (e) => beforeClose(e, socket)); diff --git a/server.js b/server.js index e131da6..a0e7a1c 100644 --- a/server.js +++ b/server.js @@ -89,18 +89,17 @@ io.on('connection', socket => { return; } - let clientNum; - const unconnectedClient = room.clients.find(client => !client.connected); + // let clientNum; + // let unconnectedClient = room.clients.find(client => !client.connected); - if (unconnectedClient) { - unconnectedClient = new Client(socket.id, unconnectedClient.num); - clientNum = unconnectedClient.num; - } + // if (unconnectedClient) { + // unconnectedClient = new Client(socket.id, unconnectedClient.num); + // clientNum = unconnectedClient.num; + // } - else { - room.clients.push(new Client(socket.id, room.clients.length + 1)); - clientNum = room.clients.length; - } + // else { + room.clients.push(new Client(socket.id, room.clients.length + 1)); + let clientNum = room.clients.length; socket.join(roomName); @@ -149,11 +148,15 @@ io.on('connection', socket => { if (roomName === socket.id) continue; // pass over default room const room = getRoom(roomName); - const client = room.clients.find(c => c.id === socket.id); + const clientIndex = room.clients.findIndex(c => c.id === socket.id); + const client = room.clients[clientIndex]; client.connected = false; + room.clients.splice(clientIndex, 1); + socket.to(roomName).emit('client-left-room', { - id: socket.id + id: socket.id, + clientNum: client.num }); } console.log(`Client ${socket.id} disconnected.`); From 6ce6a0df1306183a8a5864ff31659da057476f14 Mon Sep 17 00:00:00 2001 From: Jacob Medina Date: Sun, 6 Aug 2023 15:57:47 -0400 Subject: [PATCH 7/8] fixed waiting room player display bug --- public/assets/css/style.css | 44 ++++++++++++----- public/assets/modules/race.js | 91 +++++++++++++++++++++++------------ public/index.html | 39 ++++++++------- public/main.js | 9 ++-- server.js | 31 +++++++++--- 5 files changed, 144 insertions(+), 70 deletions(-) diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 690b305..3bf049a 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -29,11 +29,11 @@ --bg-highlight-light: rgba(255,255,255,0.15); --bg-highlight-dark: rgba(223, 209, 186, 0.241); - --green-dark: rgba(42, 138, 92, 0.5); - --green-light: rgba(35, 205, 123, 0.3); + --green-dark: #39a372; + --green-light: #23cd7b; - --orange-dark: rgba(138, 98, 42, 0.5); - --orange-light: rgba(205, 151, 35, 0.3); + --orange-dark: #a6691f; + --orange-light: #d9901a; --bg-img-dark: url("../images/background-dark.png") repeat; --bg-img-light: url("../images/background-light.png") repeat center/70%; @@ -449,17 +449,29 @@ h1 { background-color: var(--bg-highlight); } -.done-1, -.done-2 { +:is(.done-1, .done-2) { backdrop-filter: blur(3px); + position: relative; + isolation: isolate; +} + +:is(.done-1, .done-2)::before { + content: ""; + + position: absolute; + width: 100%; + height: 100%; + + z-index: -1; + opacity: 80%; } -.done-1 { +.done-1::before { /* .board-item:active:not(.done) { */ background-color: var(--green); } -.done-2 { +.done-2::before { background-color: var(--orange); } @@ -565,14 +577,22 @@ footer { font-size: 2rem; } -.player-container .ready-icon[data-ready=false] { - opacity: 80%; -} +/* .player-container .ready-icon[data-ready=true] { + color: var(--green); +} */ -.player-container .ready-icon[data-ready=true] { +.player-1 { color: var(--green); } +.player-2 { + color: var(--orange); +} + +.player-container .ready-icon { + color: var(--text-color); + /* opacity: 80%; */ +} /* MEDIA QUERIES */ diff --git a/public/assets/modules/race.js b/public/assets/modules/race.js index 5b64178..3b152bb 100644 --- a/public/assets/modules/race.js +++ b/public/assets/modules/race.js @@ -1,7 +1,8 @@ import { fetchAndGenerateBoard } from "./board.js"; import { SeededRandom } from "./SeededRandom.js"; import { updateShareURL } from "./share.js"; -import { hideElement } from "./helper.js"; +import { hideElement, showElement } from "./helper.js"; +import { titleCase } from "./formatName.js"; let clientNum = 1; let room = null; @@ -11,13 +12,22 @@ function onConnect(socket) { console.log(`You connected with ID: ${socket.id}`); socket.on('client-joined-room', clientNum => { - $('.ready-btn').prop('disabled', false); - generatePlayerMenu(clientNum); + // $('.ready-btn').prop('disabled', false); + generateReadyStatus(socket); }); socket.on('client-left-room', ({ id, clientNum }) => { $(`.player-${clientNum}`).remove(); - console.warn(`Client ${id} left the room!`); + + // if host leaves, exit room + if (clientNum === 1) { + leaveRoom(); + return; + } + + // $('.ready-btn').prop('disabled', false); + generateReadyStatus(socket); + // console.warn(`Client ${id} left the room!`); }); socket.on('ready', (clientNum, allReady) => { @@ -29,11 +39,11 @@ function onConnect(socket) { } else { - generatePlayerMenu(clientNum, true); + generateReadyStatus(socket); } if (allReady) beginRace(); - }) + }); socket.on('receive-board-click', ({boardItem, clientNum, active}) => { boardItem = $('#' + boardItem); @@ -48,7 +58,9 @@ function onConnect(socket) { }); } -function createRoom(socket, urlSearchParams) { +function createRoom(event, socket, urlSearchParams) { + event.preventDefault(); + const roomName = $('#create-room-name').val(); socket.emit('create-room', { room: roomName, @@ -57,17 +69,23 @@ function createRoom(socket, urlSearchParams) { socket.on('create-room-response', ({res, error}) => { if (error) { - console.warn(error); + const errorEl = $('.create-room-options .error'); + errorEl.text(error); + showElement(errorEl); + // console.warn(error); return; } - room = roomName; + room = roomName.toLowerCase(); clientNum = 1; - $('#room-name-title').text(room); - $('.ready-btn').prop('disabled', true); + $('#room-name-title').text(titleCase(room)); + // $('.ready-btn').prop('disabled', true); clearUI(); - generatePlayerMenu(clientNum); + generatePlayerMenu([{ + clientNum: clientNum, + ready: false + }]); generateRaceMenu(); }); } @@ -79,19 +97,20 @@ function joinRoom(socket, urlSearchParams) { socket.on('join-room-response', ({res, error}) => { if (error) { - console.warn(error); + const errorEl = $('.join-room-options .error'); + errorEl.text(error); + showElement(errorEl); + // console.warn(error); return; } room = roomName; clientNum = 2; - $('#room-name-title').text(room); + $('#room-name-title').text(titleCase(room)); - socket.emit('request-ready-status', roomName, (clients) => { - for (const client of clients) { - generatePlayerMenu(client.clientNum, client.ready); - } - }); + socket.emit('request-ready-status', roomName, (clients) => + generatePlayerMenu(clients) + ); console.log(res.message); @@ -107,6 +126,12 @@ function joinRoom(socket, urlSearchParams) { }); } +function generateReadyStatus(socket) { + socket.emit('request-ready-status', room, (clients) => + generatePlayerMenu(clients) + ); +} + function leaveRoom() { location.reload(); @@ -126,18 +151,24 @@ function clearUI() { } -function generatePlayerMenu(clientNum, ready=false) { - const readyIcon = ready ? 'check_circle' : 'radio_button_unchecked'; +function generatePlayerMenu(clients) { + $('.players').text(''); // clear players - $('.players').append( -`
-
- person -

Player ${clientNum}

-
- ${readyIcon} -
` - ) + for (const { clientNum, ready } of clients) { + const readyIcon = ready ? 'check_circle' : 'radio_button_unchecked'; + const host = (clientNum === 1) ? '(host)' : '(host)'; + + $('.players').append( + `
+
+ person +

Player ${clientNum}

+ ${host} +
+ ${readyIcon} +
` + ) + } } function generateRaceMenu() { diff --git a/public/index.html b/public/index.html index 9d261df..5e0c25b 100644 --- a/public/index.html +++ b/public/index.html @@ -65,7 +65,7 @@

Options

Seed
- +