diff --git a/data/games/cah/cards.json b/data/games/cah/cards.json new file mode 100644 index 0000000000000000000000000000000000000000..a034777317940394db9bac0fff4c7ee5baeb45a2 --- /dev/null +++ b/data/games/cah/cards.json @@ -0,0 +1,486 @@ +[{ + "name": "Cards against humanity", + "cards": [{ + "bw": false, + "text": "Silence.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The illusion of shoice in a late-stage capitalist society.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Many bats.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Famine.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Flesh-eating bacteria.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Flying sex snakes.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Not giving a shit about the Third World.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Magnets.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Shapeshifters.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Seeing what happens when you lock people in a room with hungry seagulls.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A crucifixion.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Jennifer Lawrence.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "72 virgins.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A live studio audience.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A time travel paradox.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Authentic Mexican cuisine.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Doing crimes.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Synergistic management solutions.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Crippling debt.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Daddy issues.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Used panties.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A fart so powerful that it wakes the giants from their thousand-year slumber.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Former President George W. Bush.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Full frontal nudity.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Covering myself with Parmesan cheese and chili flakes becauseI am pizza.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Laying an egg.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Getting naked and watching Nickelodeon.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Pretendingto care.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Having big dreams but no realistic way to achieve them.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Seeing Grandma naked.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Boogers.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The inevitable heat death ofthe universe.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The miracleof childbirth.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The Rapture.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Whipping it out.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "White privilege.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Emerging from the sea and rampaging through Tokyo.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The Hamburglar.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "AXE Body Spray.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The Blood of Christ.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Soft, kissy missionary sex.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "BATMAN!", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Agriculture.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Barely making $25,000 a year.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Natural selection.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Coat hanger abortions.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Sex withPatrick Stewart.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "My abusive boyfriend who really isn’t so bad once you get to know him.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Prescription pain killers.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Swooping.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Mansplaining.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A homoerotic volleyball montage.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Alexandria Ocasio-Cortez.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Putting things where they go.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Fragile masculinity.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "All-you-can-eat shrimp for $8.99.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "An old guy who’s almost dead.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Kanye West.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Kanye West.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Raptor attacks.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Seven dead and three in critical condition.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Smegma.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Alcoholism.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A middle-aged man on roller skates.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Looking in the mirror, applying lipstick, and whispering “tonight, you will have sex with Tom Cruise.”", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Bingeing and purging.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "An oversized lollipop.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Self-loathing.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Hey Reddit! I’m __________________. Ask me anything.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Introducing X-treme Baseball! It’s like baseball, but with __________!", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "What is Batman’s guilty pleasure.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "TSA guidelinesnow prohibit __________________ on airplanes", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Next from J.K. Rowling: Harry Potter and the Chamber of __________________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "That’s right, I killed _________________. How, you ask? _________________.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "I’m sorry, Professor, but I couldn’t complete my homework because of __________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "And the Academy Award for __________________ goes to __________.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "Dude, do not go in that bathroom. There’s __________ in there.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "How did I losemy virginity?", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "It’s a pity that kids these days are all getting involved with _____________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Step 1: __________. Step 2: __________. Step 3: Profit.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "_________________. Betcha can’t have just one!", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Kids, I don’t need drugs to get high. I’m high on __________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "For my next trick, I will pull __________ out of ___________.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "While the United States raced the Soviet Union to the moon, the Mexican government funneled millions of pesos into research on _____________________", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "In the Disney Channel Original Movie, Hannah Montana struggles with _____________ for the first time.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "What’s mysecret power?", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "I’m going on a cleanse this week. Nothing but kale juice and __________________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "________ + ________ = ________________.", + "pack_name": "Cards against humanity", + "extra": { + "draw": 2, + "pick": 3 + } + } + + ] + }, + { + "name": "Covid-19 Pack", + "cards": [{ + "bw": false, + "text": "Coronavirus.", + "pack_name": "Covid-19 Pack" + }, + { + "bw": false, + "text": "Boris Johnson in an ICU.", + "pack_name": "Covid-19 Pack" + }, + { + "bw": false, + "text": "A man ate a bat.", + "pack_name": "Covid-19 Pack" + } + ] + } +] \ No newline at end of file diff --git a/package.json b/package.json index a8c60b428252b15bc002ec69c9c157dd44cd5a72..a31cf460b24a3a09d6c5cc941cf03157e1af9ef9 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,29 @@ { - "name": "web-games", - "version": "1.0.0", - "description": "node-based backend and frontend for web-games", - "main": "server.js", - "scripts": { - "run": "export PORT=80; node server.js", - "test": "export PORT=8080; export DEBUG=1; node server.js" - }, - "author": "Alex Mansfield", - "license": "ISC", - "dependencies": { - "@types/express": "^4.17.3", - "@types/multer": "^1.4.2", - "@types/mysql": "^2.15.9", - "@types/node": "^13.9.8", - "@types/socket.io": "^2.1.4", - "body-parser": "^1.19.0", - "express": "^4.17.1", - "multer": "^1.4.2", - "mysql": "^2.18.1", - "path": "^0.12.7", - "socket.io": "^2.3.0", - "ts": "^0.2.2" - }, - "devDependencies": { - "typescript": "^3.8.3" - } -} + "name": "web-games", + "version": "1.0.0", + "description": "node-based backend and frontend for web-games", + "main": "server.js", + "scripts": { + "run": "export PORT=80; node server.js", + "test": "export PORT=8080; export DEBUG=1; node server.js" + }, + "author": "Alex Mansfield", + "license": "ISC", + "dependencies": { + "@types/express": "^4.17.3", + "@types/multer": "^1.4.2", + "@types/mysql": "^2.15.9", + "@types/node": "^13.9.8", + "@types/socket.io": "^2.1.4", + "body-parser": "^1.19.0", + "express": "^4.17.1", + "multer": "^1.4.2", + "mysql": "^2.18.1", + "path": "^0.12.7", + "socket.io": "^2.3.0", + "ts": "^0.2.2" + }, + "devDependencies": { + "typescript": "^3.8.3" + } +} \ No newline at end of file diff --git a/public/css/main.css b/public/css/main.css new file mode 100644 index 0000000000000000000000000000000000000000..aa7cdec09b1daefc06d800045db3cfdbfcb7fa2b --- /dev/null +++ b/public/css/main.css @@ -0,0 +1,67 @@ +html { + background-color: #303030; + color: white; +} + +body { + margin: 0; + /* border: 0; + padding: 0; */ + /* position: absolute; */ + /* top: 0; */ +} + +#header { + + margin: 0; + border: 0; + padding: 20px; + width: calc(100vw - 40px); + background-color: #181818; + font-size: 24px; + +} + +#subheader { + margin: 0; + border: 0; + padding: 10px; + padding-left: 30px; + background-color: #202020; + +} + +h1 { + margin: 0; +} + +#footer { + + margin: 0; + width: 100vw; +} + +#container { + margin: 20px; +} + +#home { + color: white; + text-decoration: none; +} + +a { + color: white; +} + +button { + margin: 10px; + padding: 10px; + border-color: whitesmoke; + border-style: solid; + border: 10px; + border-radius: 5px; + font-size: 20px; + color: white; + background-color: #101010; +} \ No newline at end of file diff --git a/public/errors/404.html b/public/errors/404.html index b15639f701e101e58b2c22bf96d363be548c229d..061915fad571fbe749e7017f37dcbe2b54326848 100644 --- a/public/errors/404.html +++ b/public/errors/404.html @@ -1,17 +1,43 @@ <!DOCTYPE html> <html> - <head> - - </head> - <body> - <h1> - Error 404 - </h1><br> - <p> - oops - </p><br> - <h3> - Page not found! - </h3><br> - </body> + +<head> + <link rel="stylesheet" href="/css/main.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Error + </h1> + + </div> + <div id="container" style="text-align: center;"> + + <h1> + 404 + </h1> + + <p> + Oops + </p> + + <h3> + Page Not Found! + </h3> + + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/games/backgammon/game.html b/public/games/backgammon/game.html new file mode 100644 index 0000000000000000000000000000000000000000..4b2c30709e676da16aa4b1c8bde3f6b7796309ca --- /dev/null +++ b/public/games/backgammon/game.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + +<head> + <title>Cards against Humanity</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="/js/p5/p5.js"></script> + <script src="./game.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="./cah.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Backgammon game + </h1> + + <a href="../">Games/</a><a href="./">Backgammon/</a> + </div> + <div id="container"> + <div id="game"> + + </div> + </div> + <div id="footer"> + + </div> +</body> + +</html> \ No newline at end of file diff --git a/public/games/backgammon/game.js b/public/games/backgammon/game.js new file mode 100644 index 0000000000000000000000000000000000000000..a97d83dcbead2161662fa648fe5f7f99a2faf0bb --- /dev/null +++ b/public/games/backgammon/game.js @@ -0,0 +1,36 @@ +/// <reference path="../../../p5.global-mode.d.ts" /> +/// <reference path="../../../socket.io.d.ts" /> +const cookies = document.cookie + .split(';') + .reduce((res, c) => { + const [key, val] = c.trim().split('=').map(decodeURIComponent); + try { + return Object.assign(res, { + [key]: JSON.parse(val) + }); + } + catch (e) { + return Object.assign(res, { + [key]: val + }); + } +}, {}); +const params = new window.URLSearchParams(window.location.search); +//@ts-ignore +let _socket = io(); +_socket.on("connect", () => { + _socket.emit("join", { + gameId: params.get("id"), + userName: cookies["username"], + }); + _socket.removeAllListeners(); + _socket.on("welcome", data => { + new backgammon(_socket); + }); +}); +class backgammon extends p5 { + constructor(socket) { + super(() => { }, document.getElementById("game"), false); + } +} +// new backgammon(_socket); diff --git a/public/games/backgammon/game.ts b/public/games/backgammon/game.ts new file mode 100644 index 0000000000000000000000000000000000000000..664de1f16b85bbead63b1e47f51e154e30de05f7 --- /dev/null +++ b/public/games/backgammon/game.ts @@ -0,0 +1,61 @@ +/// <reference path="../../../p5.global-mode.d.ts" /> +/// <reference path="../../../socket.io.d.ts" /> + + +interface GameDataPacket { + gameId: number, + gameType: number, + gameToken: string, + packetType: string, + userName ? : string, + userToken ? : string, + data ? : any +} + +interface Game { + gameId: number, + gameType: number, + gameName: string, + gameToken: string, +} + +const cookies: any = document.cookie + .split(';') + .reduce((res, c) => { + const [key, val] = c.trim().split('=').map(decodeURIComponent) + try { + return Object.assign(res, { + [key]: JSON.parse(val) + }) + } catch (e) { + return Object.assign(res, { + [key]: val + }) + } + }, {}); +const params: any = new window.URLSearchParams(window.location.search); + +//@ts-ignore +let _socket = io(); + + +_socket.on("connect", () => { + _socket.emit("join", { + gameId: params.get("id"), + userName: cookies["username"], + }); + _socket.removeAllListeners(); + _socket.on("welcome", data => { + new backgammon(_socket); + }) +}) + +class backgammon extends p5 { + + constructor(socket: SocketIO.Socket) { + super(() => {}, document.getElementById("game"), false); + } + +} + +// new backgammon(_socket); \ No newline at end of file diff --git a/public/games/backgammon/index.html b/public/games/backgammon/index.html new file mode 100644 index 0000000000000000000000000000000000000000..17f13ec090a7b713ea9c0fb7a68f1f0fdd76a867 --- /dev/null +++ b/public/games/backgammon/index.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> + +<head> + <title>Battleships</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> + <script src="../game_loader.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="../loader.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Backgammon games. + </h1> + + <a href="../">Games/</a> + </div> + <div id="container"> + + </div> + <div id="footer"> + + </div> +</body> + +</html> \ No newline at end of file diff --git a/public/games/backgammon/tsconfig.json b/public/games/backgammon/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..a19a54328f993ca26d564eecdbc93cecbbf93b43 --- /dev/null +++ b/public/games/backgammon/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "target": "ES2020" + + } +} \ No newline at end of file diff --git a/public/games/battleships/game.html b/public/games/battleships/game.html index 2dac2386b369cfb90276d9a24c83702c44f477e5..92316e60b573c220e418231f27401ba190fc82dc 100644 --- a/public/games/battleships/game.html +++ b/public/games/battleships/game.html @@ -1,22 +1,45 @@ <!DOCTYPE html> <html> - <head> - <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> - <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> - <script src="./game.js"></script> - </head> - <body> - <a href="./index.html"><_Back to games</a><br> - <div id="game"> - <div id="me" style="float: left; padding: 10px;"> - - </div> - - <div id="opponent" style="float: left;padding: 10px"> - - </div> - - </div> - - </body> + +<head> + <title>Battleships</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> + <script src="./game.js"></script> + <link rel="stylesheet" href="/css/main.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Battleships game + </h1> + + <a href="../">Games/</a><a href="./">Battleships/</a> + </div> + <div id="container"> + <div id="game"> + <div id="me" style="float: left; padding: 10px;"> + + </div> + + <div id="opponent" style="float: left;padding: 10px"> + + </div> + + </div> + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/games/battleships/game.js b/public/games/battleships/game.js index d7d0f610460d920b08370e3107691f82047f71d6..39e5c3f47549163403c9feaa250b0e52fb32da37 100644 --- a/public/games/battleships/game.js +++ b/public/games/battleships/game.js @@ -113,11 +113,10 @@ function _setup() { } else { gameID = params.id; } - let join_data = { - username: username, - password: game_password, - id: gameID, + gameId: gameID, + userName: username, + gamePassword: game_password, } socket.on("disconnect", console.log); socket.emit("join", join_data); diff --git a/public/games/battleships/index.html b/public/games/battleships/index.html index 2c907ae5b1cf489f44d2845dfb71f74588a508cd..3752123a0621a246fab3940c3ac54588ecdd629b 100644 --- a/public/games/battleships/index.html +++ b/public/games/battleships/index.html @@ -1,17 +1,37 @@ <!DOCTYPE html> <html> - <head> - <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> - <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> - <script src="../game_loader.js"></script> - </head> - <body> - <h1> - Battleships game - </h1> - <a href="../"><- Back to Games!</a><br><br> - <!-- <p> - Current running games: <br> - </!--> - </body> + +<head> + <title>Battleships</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> + <script src="../game_loader.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="../loader.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Battleships games + </h1> + + <a href="../">Games/</a> + </div> + <div id="container"> + + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/games/battleships_v2/game.html b/public/games/battleships_v2/game.html index ea1429777edf9737325690a750e04463f55bac4a..587d50a40bf91dddd7bb6686a5588c7c9ea842b9 100644 --- a/public/games/battleships_v2/game.html +++ b/public/games/battleships_v2/game.html @@ -2,26 +2,47 @@ <html> <head> + <title>Battleships-V2.0</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> <script src="/js/p5/p5.js"></script> - <!-- <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.js"></script> --> - <script src="/js/p5_build.js"></script> <script src="./game.js"></script> + <link rel="stylesheet" href="/css/main.css"> </head> <body> - <a href="./index.html"><_Back to games</a><br> - <div id="game"> - <div id="defend" style="float: left; padding: 10px;"> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> - </div> + <h1> + Battleships-V2.0 game + </h1> - <div id="attack" style="float: left;padding: 10px"> + <a href="../">Games/</a><a href="./">Battleships-V2/</a> + </div> + <div id="container"> + <div id="game"> + <span style="display: inline-block;"> + <div id="defend" style="padding: 10px;"> - </div> + </div> + </span> + <span style="display: inline-block;"> + <div id="attack" style="padding: 10px"> + </div> + </span> + + </div> </div> + <div id="footer"> + </div> </body> </html> \ No newline at end of file diff --git a/public/games/battleships_v2/game.js b/public/games/battleships_v2/game.js index c1e919117d0b234480d892779bb0f3e105dc2cbf..f6843911538226a09e5a66e9cd28c23c2d3e8ad0 100644 --- a/public/games/battleships_v2/game.js +++ b/public/games/battleships_v2/game.js @@ -18,11 +18,12 @@ const cookies = document.cookie const URLParams = new window.URLSearchParams(window.location.search); //@ts-ignore const _socket = io(); -_socket.emit("join", { - username: cookies.username, - password: cookies.game_password, - id: URLParams.get("id"), -}); +let joinParams = { + gameId: URLParams.get("id"), + userName: cookies.username, + gamePassword: cookies.game_password, +}; +_socket.emit("join", joinParams); _socket.on("kick", (reason) => { console.log(reason); window.location.href = "./"; @@ -294,7 +295,7 @@ class attack extends base { this.createCanvas(500, 500); this.createElement("br"); this.fireButton = this.createButton("Fire!"); - this.fireButton.size(100, 30); + // this.fireButton.size(100, 30); this.fireButton.mouseClicked(() => { // this.shots.push(this.firing); this.socket.emit("fire", this.firing); diff --git a/public/games/battleships_v2/game.ts b/public/games/battleships_v2/game.ts index 15227a93a75c41667d73839715a025b0fcc6343c..d8851a8718e523850959d2b61c7ab7ecf559827e 100644 --- a/public/games/battleships_v2/game.ts +++ b/public/games/battleships_v2/game.ts @@ -18,11 +18,12 @@ const URLParams: any = new window.URLSearchParams(window.location.search); //@ts-ignore const _socket = io(); -_socket.emit("join", { - username: cookies.username, - password: cookies.game_password, - id: URLParams.get("id"), -}); +let joinParams: GameJoinParams = { + gameId: URLParams.get("id"), + userName: cookies.username, + gamePassword: cookies.game_password, +} +_socket.emit("join", joinParams); _socket.on("kick", (reason) => { console.log(reason) window.location.href = "./" @@ -53,6 +54,11 @@ interface shot { y: number, hit: boolean, } +interface GameJoinParams { + gameId: number, + userName: string, + gamePassword: string, +} class base extends p5 { placing: ship; @@ -367,7 +373,7 @@ class attack extends base { this.createCanvas(500, 500); this.createElement("br"); this.fireButton = this.createButton("Fire!"); - this.fireButton.size(100, 30); + // this.fireButton.size(100, 30); this.fireButton.mouseClicked(() => { // this.shots.push(this.firing); this.socket.emit("fire", this.firing); diff --git a/public/games/battleships_v2/index.html b/public/games/battleships_v2/index.html index d99bf12b1af524a6bb5f8e68af2b6b1b1a69a73f..0763f123c0e33c0252fd6aa8a86c1684e22beb04 100644 --- a/public/games/battleships_v2/index.html +++ b/public/games/battleships_v2/index.html @@ -1,17 +1,37 @@ <!DOCTYPE html> <html> - <head> - <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> - <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> - <script src="../game_loader.js"></script> - </head> - <body> - <h1> - Battleships 2.0 game - </h1> - <a href="../"><- Back to Games!</a><br><br> - <!-- <p> - Current running games: <br> - </!--> - </body> + +<head> + <title>Battleships</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> + <script src="../game_loader.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="../loader.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Battleships-V2 games + </h1> + + <a href="../">Games/</a> + </div> + <div id="container"> + + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/games/cah/cah.css b/public/games/cah/cah.css new file mode 100644 index 0000000000000000000000000000000000000000..e9c4eb3cb7b7eb97ef2ae0b7df45a7da5107b39c --- /dev/null +++ b/public/games/cah/cah.css @@ -0,0 +1,34 @@ +.card { + background-color: white; + color: black; + font-size: 22px; + padding: 10px; + position: relative; + border-width: 2px; + border-style: solid; + border-color: black; + border-radius: 15px; + margin: 5px; + cursor: pointer; + width: 240px; + height: 300px; + scale: 1; + display: inline-block; +} + +.card p { + position: absolute; +} + +.card div p { + margin-top: 10px; + margin-bottom: 10px; + left: 50px; + bottom: 0; + width: max-content; +} + +.card img { + position: absolute; + bottom: 0; +} \ No newline at end of file diff --git a/public/games/cah/game.html b/public/games/cah/game.html new file mode 100644 index 0000000000000000000000000000000000000000..8222ebb39c6b19ee38acbcafdb5b464526c1e64f --- /dev/null +++ b/public/games/cah/game.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + +<head> + <title>Cards against Humanity</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="/js/p5/p5.js"></script> + <script src="./game.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="./cah.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Cards against Humanity game + </h1> + + <a href="../">Games/</a><a href="./">Cards against Humanity/</a> + </div> + <div id="container"> + <div id="game"> + + </div> + </div> + <div id="footer"> + + </div> +</body> + +</html> \ No newline at end of file diff --git a/public/games/cah/game.js b/public/games/cah/game.js new file mode 100644 index 0000000000000000000000000000000000000000..fd9c3eb3b5cd18563111f7bad3527926a52e26cf --- /dev/null +++ b/public/games/cah/game.js @@ -0,0 +1,143 @@ +/// <reference path="../../../p5.global-mode.d.ts" /> +const cookies = document.cookie + .split(';') + .reduce((res, c) => { + const [key, val] = c.trim().split('=').map(decodeURIComponent); + try { + return Object.assign(res, { + [key]: JSON.parse(val) + }); + } + catch (e) { + return Object.assign(res, { + [key]: val + }); + } +}, {}); +const params = new window.URLSearchParams(window.location.search); +const icon = "data:image/svg+xml;base64,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"; +// @ts-ignore +let _socket = io(); +_socket.on("connect", () => { + _socket.emit("join", { + gameId: params.get("id"), + userName: cookies["username"], + }); + _socket.removeAllListeners(); + _socket.on("welcome", data => { + new cah(_socket); + }); +}); +class cah extends p5 { + constructor(socket) { + super(() => { }, document.getElementById("game"), false); + this.socket = socket; + this.socket.on("game_data", this.onData.bind(this)); + } + onData(data) { + // console.log(data); + switch (data.packetType) { + case "black": + this.black = data.data; + break; + case "hand": + this.hand = data.data; + break; + default: + console.log(`Unknown data packet of type : ${data.packetType}`); + console.log(data.data); + break; + } + this.updateCards(); + } + setup() { + // console.log(this.socket); + this.noCanvas(); + this.game = { + gameId: parseInt(params.get("id")), + gameName: "", + gameType: 2, + gameToken: "", + }; + //@ts-ignore + let b = this.createButton("rand"); + b.mousePressed(() => { + this.socket.emit("game_data", { + gameId: this.game.gameId, + gameToken: this.game.gameToken, + packetType: "rand", + gameType: this.game.gameType, + }); + }); + this.createElement("br"); + //@ts-ignore + this.createDiv().id("black"); + //@ts-ignore + this.createDiv().id("hand"); + } + updateCards() { + let cards = document.getElementsByClassName("card"); + while (cards.length) + cards[0].remove(); + // for (let card of cards) { + // card.remove(); + // } + if (this.black) + this.drawCard(this.black, "black"); + if (this.hand) + for (let card of this.hand) { + this.drawCard(card, "hand"); + } + } + drawCard(c, node) { + // @ts-ignore + // let d: p5.Element = this.createSpan(); + // if (node) d.parent(node); + // d.style("display", "inline-block") + let d; + //@ts-ignore + // d = this.createDiv().parent(d); + //@ts-ignore + d = this.createDiv().parent(node); + d.addClass("card"); + if (c.bw) + d.addClass("black"); + //@ts-ignore + let t = this.createP(); + t.parent(d); + t.html(c.text); + t.style("margin", "0"); + d.style("background-color", c.bw ? "black" : "white"); + d.style("color", c.bw ? "white" : "black"); + d.size(240, 300); + //@ts-ignore + let foot = this.createDiv(); + foot.style("position", "absolute"); + foot.style("bottom", "0"); + foot.parent(d); + //@ts-ignore + let simg = this.createSpan(); + simg.parent(foot); + simg.style("display", "inline-block"); + //@ts-ignore + let img = this.createImg(icon, "cah icon"); + img.parent(simg); + img.size(50, 50); + // img.style("position", "absolute"); + // img.style("bottom", "0"); + //@ts-ignore + let sp = this.createSpan(); + sp.parent(foot); + sp.style("display", "inline-block"); + // @ts-ignore + let p = this.createP(); + p.parent(sp); + p.html(c.pack_name); + // p.style("position", "absolute"); + // p.style("bottom", "0"); + p.style("left", "60px"); + p.style("font-size", "14px"); + // if (node) d.parent(node); + } +} +// new cah(_socket) diff --git a/public/games/cah/game.ts b/public/games/cah/game.ts new file mode 100644 index 0000000000000000000000000000000000000000..cdc5099f6ed4b9f8e407ea23facf4db07e2f3552 --- /dev/null +++ b/public/games/cah/game.ts @@ -0,0 +1,196 @@ +/// <reference path="../../../p5.global-mode.d.ts" /> + +interface GameDataPacket { + gameId: number, + gameType: number, + gameToken: string, + packetType: string, + userName ? : string, + userToken ? : string, + data ? : any +} + +interface Game { + gameId: number, + gameType: number, + gameName: string, + gameToken: string, +} + +interface card { + bw: boolean, + text: string, + pack_name: string, + extra ? : { + draw ? : number, + pick ? : number + } +} + +const cookies: any = document.cookie + .split(';') + .reduce((res, c) => { + const [key, val] = c.trim().split('=').map(decodeURIComponent) + try { + return Object.assign(res, { + [key]: JSON.parse(val) + }) + } catch (e) { + return Object.assign(res, { + [key]: val + }) + } + }, {}); +const params: any = new window.URLSearchParams(window.location.search); + +const icon = "data:image/svg+xml;base64,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" + + +// @ts-ignore +let _socket = io(); +_socket.on("connect", () => { + _socket.emit("join", { + gameId: params.get("id"), + userName: cookies["username"], + }); + _socket.removeAllListeners(); + _socket.on("welcome", data => { + new cah(_socket); + }) +}) + +class cah extends p5 { + socket; + + black: card; + hand: card[]; + game: Game; + + constructor(socket) { + super(() => {}, document.getElementById("game"), false); + this.socket = socket; + this.socket.on("game_data", this.onData.bind(this)); + } + + onData(data: GameDataPacket) { + // console.log(data); + switch (data.packetType) { + case "black": + this.black = data.data; + break; + case "hand": + this.hand = data.data; + break; + default: + console.log(`Unknown data packet of type : ${data.packetType}`); + console.log(data.data); + break; + } + this.updateCards(); + } + + setup() { + // console.log(this.socket); + this.noCanvas(); + + this.game = { + gameId: parseInt(params.get("id")), + gameName: "", + gameType: 2, + gameToken: "", + } + //@ts-ignore + let b: p5.Element = this.createButton("rand"); + b.mousePressed(() => { + this.socket.emit("game_data", { + gameId: this.game.gameId, + gameToken: this.game.gameToken, + packetType: "rand", + gameType: this.game.gameType, + }); + }); + this.createElement("br"); + //@ts-ignore + this.createDiv().id("black"); + //@ts-ignore + this.createDiv().id("hand"); + } + + updateCards() { + let cards = document.getElementsByClassName("card"); + while (cards.length) cards[0].remove(); + // for (let card of cards) { + // card.remove(); + // } + if (this.black) + this.drawCard(this.black, "black"); + if (this.hand) + for (let card of this.hand) { + this.drawCard(card, "hand"); + } + } + + drawCard(c: card, node ? : string | HTMLElement | p5.Element) { + // @ts-ignore + // let d: p5.Element = this.createSpan(); + // if (node) d.parent(node); + // d.style("display", "inline-block") + let d: p5.Element; + //@ts-ignore + // d = this.createDiv().parent(d); + //@ts-ignore + d = this.createDiv().parent(node); + d.addClass("card"); + if (c.bw) d.addClass("black"); + //@ts-ignore + let t: p5.Element = this.createP(); + t.parent(d); + t.html(c.text); + t.style("margin", "0"); + d.style("background-color", c.bw ? "black" : "white"); + d.style("color", c.bw ? "white" : "black"); + d.size(240, 300); + + + //@ts-ignore + let foot: p5.Element = this.createDiv(); + foot.style("position", "absolute"); + foot.style("bottom", "0"); + foot.parent(d); + + + //@ts-ignore + let simg: p5.Element = this.createSpan(); + simg.parent(foot); + simg.style("display", "inline-block"); + + //@ts-ignore + let img: p5.Element = this.createImg(icon, "cah icon"); + img.parent(simg); + img.size(50, 50); + // img.style("position", "absolute"); + // img.style("bottom", "0"); + + //@ts-ignore + let sp: p5.Element = this.createSpan(); + sp.parent(foot); + sp.style("display", "inline-block"); + + // @ts-ignore + let p: p5.Element = this.createP(); + p.parent(sp); + p.html(c.pack_name); + // p.style("position", "absolute"); + // p.style("bottom", "0"); + p.style("left", "60px"); + p.style("font-size", "14px"); + + + + // if (node) d.parent(node); + } + + +} + +// new cah(_socket) \ No newline at end of file diff --git a/public/games/cah/index.html b/public/games/cah/index.html index acecd4ff8fbdce830934331ee96175d26116f859..572563cb014379c54db8c543155ef2b5b15caacf 100644 --- a/public/games/cah/index.html +++ b/public/games/cah/index.html @@ -1,17 +1,39 @@ <!DOCTYPE html> <html> - <head> - <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> - <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> - <script src="../game_loader.js"></script> - </head> - <body> - <h1> - Cards against humanity Game! - </h1> - <a href="../"><- Back to Games!</a><br><br> - <!-- <p> - Current running games: <br> - </!--> - </body> + +<head> + <title>Battleships</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> + <script src="../game_loader.js"></script> + <script src="./loader.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="../loader.css"> + <link rel="stylesheet" href="./loader.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Cards Against Humanity. + </h1> + + <a href="../">Games/</a> + </div> + <div id="container"> + + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/games/cah/loader.css b/public/games/cah/loader.css new file mode 100644 index 0000000000000000000000000000000000000000..b7ffd888dc96de96f8777db7f964cb3412b962d9 --- /dev/null +++ b/public/games/cah/loader.css @@ -0,0 +1,34 @@ +.spanPack { + display: inline-block; + margin-right: 20px; +} + +#packs { + height: auto; +} + +#wCreate { + + position: absolute; + bottom: 0; + left: 0; + width: calc(100vw - 20px); + padding: 10px; + background-color: cyan; + height: max-content; +} + +/* +#wButtons { + position: absolute; + bottom: 0; +} */ + +#dButtons { + position: absolute; + bottom: 0; +} + +.wB { + margin: 5px; +} \ No newline at end of file diff --git a/public/games/cah/loader.js b/public/games/cah/loader.js new file mode 100644 index 0000000000000000000000000000000000000000..7a1adf0957d68ef9a269c1d6a0ece0b58a102579 --- /dev/null +++ b/public/games/cah/loader.js @@ -0,0 +1,132 @@ +const c_styles = {}; +async function customCreate() { + let w = document.getElementById("wCreate"); + if (w) + w.remove(); + let d = document.createElement("div"); + d.id = "wCreate"; + document.getElementById("container").appendChild(d); + let tName = document.createElement("input"); + tName.setAttribute("type", "text"); + tName.value = "name"; + tName.id = "tName"; + d.appendChild(tName); + tName.focus(); + d.appendChild(document.createElement("br")); + let _packs = document.createElement("p"); + _packs.innerText = "Packs: "; + d.appendChild(_packs); + //@ts-ignore + let add_packs = document.createElement("div"); + add_packs.id = "packs"; + d.appendChild(add_packs); + getPacks() + .then(packs => { + for (let pack of packs) { + let s = document.createElement("span"); + s.className = "spanPack"; + add_packs.appendChild(s); + //@ts-ignore + let p = document.createElement("input"); + p.innerText = pack; + p.setAttribute("type", "checkbox"); + s.appendChild(p); + let p_id = crypto.getRandomValues(new Uint32Array(1)).toString(); + p.id = p_id; + let l = document.createElement("label"); + l.setAttribute("for", p_id); + l.innerText = pack; + s.appendChild(l); + p.className = "checkPack"; + if (pack == "Cards against humanity") { + p.setAttribute("disabled", "disabled"); + p.setAttribute("checked", "checked"); + } + } + }); + d.appendChild(document.createElement("br")); + let pwd = document.createElement("div"); + d.appendChild(pwd); + let p = document.createElement("input"); + p.setAttribute("type", "text"); + p.id = "tPass"; + pwd.appendChild(p); + p.setAttribute("placeholder", "password"); + let c = document.createElement("input"); + c.id = "cPass"; + c.setAttribute("type", "checkbox"); + pwd.appendChild(c); + c.onmouseup = () => { + setInterval(() => { + //@ts-ignore + if (c.checked) + p.setAttribute("type", "text"); + else + p.setAttribute("type", "password"); + }, 0); + }; + let cpL = document.createElement("label"); + cpL.setAttribute("for", "cPass"); + cpL.innerText = "Show password?"; + pwd.appendChild(cpL); + let b = document.createElement("div"); + d.appendChild(b); + let s1 = document.createElement("span"); + b.appendChild(s1); + let bCreate = document.createElement("button"); + s1.appendChild(bCreate); + bCreate.id = "bCreate"; + bCreate.className = "wB"; + bCreate.innerText = "Create."; + let s2 = document.createElement("span"); + b.appendChild(s2); + let bCancel = document.createElement("button"); + s2.appendChild(bCancel); + bCancel.id = "bCancel"; + bCancel.innerText = "Cancel."; + return new Promise((resolve, reject) => { + bCreate.onmouseup = () => { + //resolve + // console.log(add_packs.child()); + let packs = []; + let ePacks = document.getElementById("packs"); + // packs.forEach(console.log); + for (let p of ePacks.children) { + let label = p.getElementsByTagName("label").item(0).innerText; + let checked = p.getElementsByTagName("input").item(0).checked; + console.log({ + label, + checked + }); + if (checked) { + packs.push(label); + } + } + let createData = { + //@ts-ignore + name: document.getElementById("tName").value, + packs: packs, + //@ts-ignore + password: document.getElementById("tPass").value, + }; + d.remove(); + resolve(createData); + }; + bCancel.onmouseup = () => { + //resolve + d.remove(); + resolve(null); + }; + }); +} +async function getPacks() { + let res = await fetch("/games/api/cah/packs", { + method: "GET", + }); + if (res.status == 200) { + return res.json(); + } + else { + return null; + } +} diff --git a/public/games/cah/loader.ts b/public/games/cah/loader.ts new file mode 100644 index 0000000000000000000000000000000000000000..29feaa2e4efe67bbc30db5941fc8b7e9d7c3af02 --- /dev/null +++ b/public/games/cah/loader.ts @@ -0,0 +1,171 @@ +interface cahCreateData { + name: string, + packs: string[], + + max_players ? : number, + timeout ? : number, + password ? : string, +} + +const c_styles = {} + +async function customCreate(): Promise < cahCreateData > { + + let w = document.getElementById("wCreate"); + if (w) w.remove(); + let d = document.createElement("div"); + d.id = "wCreate"; + document.getElementById("container").appendChild(d); + + + let tName = document.createElement("input"); + tName.setAttribute("type", "text"); + tName.value = "name"; + tName.id = "tName"; + d.appendChild(tName); + tName.focus(); + + d.appendChild(document.createElement("br")); + let _packs = document.createElement("p"); + _packs.innerText = "Packs: "; + d.appendChild(_packs); + + //@ts-ignore + let add_packs = document.createElement("div"); + add_packs.id = "packs"; + d.appendChild(add_packs); + getPacks() + .then(packs => { + for (let pack of packs) { + let s = document.createElement("span"); + s.className = "spanPack"; + add_packs.appendChild(s); + //@ts-ignore + let p = document.createElement("input"); + p.innerText = pack; + p.setAttribute("type", "checkbox"); + s.appendChild(p); + + let p_id = crypto.getRandomValues(new Uint32Array(1)).toString(); + p.id = p_id; + + let l = document.createElement("label"); + l.setAttribute("for", p_id); + l.innerText = pack; + s.appendChild(l); + p.className = "checkPack"; + if (pack == "Cards against humanity") { + p.setAttribute("disabled", "disabled"); + p.setAttribute("checked", "checked"); + } + } + }); + + + d.appendChild(document.createElement("br")); + + let pwd = document.createElement("div"); + d.appendChild(pwd); + + let p = document.createElement("input"); + p.setAttribute("type", "text"); + p.id = "tPass"; + pwd.appendChild(p); + p.setAttribute("placeholder", "password"); + + let c = document.createElement("input"); + c.id = "cPass"; + c.setAttribute("type", "checkbox"); + pwd.appendChild(c); + c.onmouseup = () => { + setInterval(() => { + //@ts-ignore + if (c.checked) + p.setAttribute("type", "text"); + else + p.setAttribute("type", "password"); + + }, 0) + }; + + let cpL = document.createElement("label"); + cpL.setAttribute("for", "cPass"); + cpL.innerText = "Show password?"; + pwd.appendChild(cpL); + + let b = document.createElement("div"); + d.appendChild(b); + + + let s1 = document.createElement("span"); + b.appendChild(s1); + + let bCreate = document.createElement("button"); + s1.appendChild(bCreate); + bCreate.id = "bCreate"; + bCreate.className = "wB"; + bCreate.innerText = "Create."; + + let s2 = document.createElement("span"); + b.appendChild(s2); + + let bCancel = document.createElement("button"); + s2.appendChild(bCancel); + bCancel.id = "bCancel"; + bCancel.innerText = "Cancel."; + return new Promise < cahCreateData > ((resolve, reject) => { + bCreate.onmouseup = () => { + + //resolve + + // console.log(add_packs.child()); + + let packs = []; + + let ePacks = document.getElementById("packs"); + // packs.forEach(console.log); + for (let p of ePacks.children) { + let label = p.getElementsByTagName("label").item(0).innerText; + let checked = p.getElementsByTagName("input").item(0).checked; + console.log({ + label, + checked + }); + if (checked) { + packs.push(label); + } + } + + let createData: cahCreateData = { + //@ts-ignore + name: document.getElementById("tName").value, + packs: packs, + //@ts-ignore + password: document.getElementById("tPass").value, + } + d.remove(); + + resolve(createData); + }; + bCancel.onmouseup = () => { + //resolve + + d.remove(); + resolve(null); + }; + + }) +} + +async function getPacks(): Promise < string[] > { + let res = await fetch("/games/api/cah/packs", { + method: "GET", + }); + + if (res.status == 200) { + return res.json(); + } else { + return null; + } + +} \ No newline at end of file diff --git a/public/games/cah/tsconfig.json b/public/games/cah/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..a19a54328f993ca26d564eecdbc93cecbbf93b43 --- /dev/null +++ b/public/games/cah/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "target": "ES2020" + + } +} \ No newline at end of file diff --git a/public/games/game_loader.js b/public/games/game_loader.js index 05937dfa8569e8e957f8b3b06686d5e2b8d0c4fc..e6a253f062c67ae379258150539784232ead588e 100644 --- a/public/games/game_loader.js +++ b/public/games/game_loader.js @@ -43,17 +43,13 @@ function refreshList() { while (children.length > 0) children[0].remove(); for (let _game of json) { + let s = createElement("span"); + s.parent(GamesList); + s.addClass("game"); let child = createElement("div"); - child.parent(GamesList); + child.parent(s); child.html(`Join game:<br/>${_game.name}<br/>Players:${_game.players}`); - // let join_button = createButton("Join"); - // join_button.parent(child); child.mouseClicked(joinGame.bind(_game)); - child.style("text-align", "center") - child.style("float", "left") - child.style("padding", "7px") - child.style("background-color", "lightblue") - child.style("margin", "2px") // child.html(`<a href='/games/${game}/game.html?id=${_game.id}'>Join</a>`, true); // createElement("li", `${JSON.stringify(game)}`).parent(GamesList); @@ -81,15 +77,28 @@ function joinGame() { } -function createGame() { +async function createGame() { + let data = {}; + if (window.customCreate) { + let custom_data = window.customCreate(); + if (custom_data instanceof Promise) { + data = await custom_data; + } + if (data == null) return; + } else { + let name = prompt("Please enter game name", "name"); + if (name == null) return; + let password = prompt("Enter password, \nor leave blank for open game."); + // let data = { + // name: name, + // password: password, + // }; + + data.name = name; + data.password = password; + + } - let name = prompt("Please enter game name", "name"); - if (name == null) return; - let password = prompt("Enter password, \nor leave blank for open game."); - let data = { - name: name, - password: password, - }; fetch(`/games/api/create/${game}`, { method: "POST", @@ -104,4 +113,6 @@ function createGame() { function draw() { -} \ No newline at end of file +} + +new p5(null, "container"); \ No newline at end of file diff --git a/public/games/index.html b/public/games/index.html index a5aa81d3778e13d8e351de6d8fecdca7573d45f1..d8f422a530a85c1aeda5d1713a715d86c642d234 100644 --- a/public/games/index.html +++ b/public/games/index.html @@ -1,32 +1,57 @@ <!DOCTYPE html> <html> - <head> - - </head> - <body> - <h1> - Game listing - </h1> - - <p> - <li> - <a href="./cah/"> - Cards against humanity - </a> - </li> - <li> - <a href="./battleships/"> - Battleships - </a> - </li> - <li> - <a href="./battleships_v2/"> - Battleships v2 - </a> - </li> - - </p> - - - </body> + +<head> + <link rel="stylesheet" href="/css/main.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Game listing + </h1> + + </div> + <div id="container"> + + <ul> + <li> + <a href="./battleships/"> + Battleships + </a> + </li> + <li> + <a href="./battleships_v2/"> + Battleships v2 + </a> + </li> + <li> + <a href="./cah/"> + Cards against humanity + </a> + (WIP) + </li> + <li> + <a href="./backgammon/"> + Backgammon + </a> + (WIP) + </li> + + </ul> + + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/games/loader.css b/public/games/loader.css new file mode 100644 index 0000000000000000000000000000000000000000..491befe647444de251b4dfd6d47ad2d7f990a196 --- /dev/null +++ b/public/games/loader.css @@ -0,0 +1,18 @@ +.game { + text-align: center; + /* float: left; */ + padding: 7px; + background-color: darkblue; + margin: 2px; + scale: 1.5; + margin: 20px; + border: 5px; + border-style: solid; + border-radius: 5px; + margin-right: 50px; + border-color: #101010; +} + +span { + display: inline-block; +} \ No newline at end of file diff --git a/public/games/template/index.html b/public/games/template/index.html index ec95983991c2d1d940b26add6773cd70fef8f9ca..e755b3abdda7e400f1c71ef1aa6c42f0bb475f82 100644 --- a/public/games/template/index.html +++ b/public/games/template/index.html @@ -1,17 +1,37 @@ <!DOCTYPE html> <html> - <head> - <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> - <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> - <script src="../game_loader.js"></script> - </head> - <body> - <h1> - #{TEMPLATE} Game! - </h1> - <a href="../"><- Back to Games!</a><br><br> - <!-- <p> - Current running games: <br> - </!--> - </body> + +<head> + <title>Battleships</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script> + <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script> + <script src="../game_loader.js"></script> + <link rel="stylesheet" href="/css/main.css"> + <link rel="stylesheet" href="../loader.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="subheader"> + + <h1> + Game Loader Template! + </h1> + + <a href="../">Games/</a> + </div> + <div id="container"> + + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/index.html b/public/index.html index 805522aa32fe15f0134dcde2a1c6000b6dae0316..ac9dca2e104e0185ff5377caa8d1f73d6e8d1f48 100644 --- a/public/index.html +++ b/public/index.html @@ -1,16 +1,29 @@ <!DOCTYPE html> <html> - <head> - </head> - <body> - <h1> - Test web-server - </h1> - <p> - <li> - <a href="games/">Games</a> - </li> - </p> - </body> +<head> + <title>AM Web!</title> + <link rel="stylesheet" href="/css/main.css"> +</head> + +<body> + <div id="header"> + <h1> + <a href="/" id="home"> + Alex Mansfield's web server! + </a> + </h1> + </div> + <div id="container"> + <ul> + <li> + <a href="games/">Games</a> + </li> + </ul> + </div> + <div id="footer"> + + </div> +</body> + </html> \ No newline at end of file diff --git a/public/js/p5/p5.js b/public/js/p5/p5.js index 10e98d7954883a47330e69b363b6d1f7a404a9ba..1da9b6bc38a991dd6c837148f55fe5549611ff10 100644 --- a/public/js/p5/p5.js +++ b/public/js/p5/p5.js @@ -69872,8 +69872,8 @@ } var context = this._isGlobal ? window : this; - var userSetup = context.setup.bind(this); - var userDraw = context.draw.bind(this); + var userSetup = context.setup; //.bind(this); + var userDraw = context.draw; //.bind(this); if (typeof userDraw === 'function') { if (typeof userSetup === 'undefined') { context.scale(context._pixelDensity, context._pixelDensity); @@ -69890,7 +69890,7 @@ context._registeredMethods.pre.forEach(callMethod); this._inUserDraw = true; try { - userDraw(); + userDraw.call(this); } finally { this._inUserDraw = false; } diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000000000000000000000000000000000000..ceb9ba7c0857102b75d5c7e71bc8d67c013433f2 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +#google +User-agent: Googlebot +Allow: / \ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000000000000000000000000000000000000..c5fa78456dbde5c0ffa05377925131501c0c794d --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1 @@ +< \ No newline at end of file diff --git a/src/gamedb.ts b/src/gamedb.ts index 69053e3b161b0dc9495028616fb46bad60705233..e3b88e1baae687558dc1daf86c73013de7d0d472 100644 --- a/src/gamedb.ts +++ b/src/gamedb.ts @@ -26,6 +26,10 @@ export interface QueryResults { fields ? : mysql.FieldInfo[]; } +export interface GameType { + name: string, + id: number, +} export class GameDB { pool: mysql.Pool; @@ -83,13 +87,13 @@ export class GameDB { } async getGameData(gameId: number, key ? : number): Promise < game > { - let query: string = "SELECT game_id,active_game_type_id,data_key,data_value FROM game_data, active_games WHERE game_id=active_game_id AND game_id=?"; + let query: string = "SELECT game_id,active_game_type_id,data_key,data_value FROM game_data, active_games WHERE game_id=active_game_id AND game_id=? AND (data_key = 0 OR "; let args: any[] = [gameId]; if (key) { - query += " AND data_key=?;"; + query += " data_key=?);"; args.push(key); } else { - query += ";"; + query += " 1 );"; } let results = await this.query(query, args); let json = {}; @@ -98,11 +102,69 @@ export class GameDB { json[row.data_key] = JSON.parse(row.data_value); } let game: game = { - id: results.results.reduce((acc: any, cur: any) => cur.data_key == 0 ? cur : acc, null).game_id, + id: results.results[0].game_id, type_id: results.results[0].active_game_type_id, data: JSON.parse(results.results.reduce((acc: any, cur: any) => cur.data_key == 0 ? cur : acc, null).data_value), json: json } return game; } + + async getConnection(): Promise < mysql.PoolConnection > { + return new Promise((resolve, reject) => { + this.pool.getConnection((err, conn) => { + if (err) reject(err); + else resolve(conn); + }) + }) + } + + async setGameData(gameId: number, json: any, key: number | Array < number > ) { + if (key instanceof Array && json instanceof Array) { + let conn = await this.getConnection(); + for (let _k in key) { + let k = key[_k]; + try { + await new Promise((resolve, reject) => { + conn.query("UPDATE game_data SET data_value=? WHERE game_id=? AND data_key=?;", [json[_k], gameId, k], (err, res, fields) => { + console.log(res); + if (err) reject(err); + else resolve(res); + }) + }); + } catch (err) { + console.log(err); + //insert instead of update + }; + } + conn.release(); + } else { + try { + this.query("UPDATE game_data SET data_value=? WHERE game_id=? AND data_key=?;", [json, gameId, key]); + } catch (err) { + + //insert instead of update + } + } + } + + async getGameType(game: string | number): Promise < GameType > { + let query: string; + if (typeof(game) == "string") { + query = "SELECT * FROM games WHERE game_name=?"; + } else { + query = "SELECT * FROM games WHERE game_id=?"; + } + let { + results + } = await this.query(query, game); + if (results[0]) { + return { + id: results[0].game_id, + name: results[0].game_name, + } + } else { + throw null as GameType; + } + } } \ No newline at end of file diff --git a/src/games.ts b/src/games.ts index 64395f2859bbfcd5f0cf36461bcce6c2f18bb785..ee96b1a83f6c85ebd7b8258ed68802bb26563257 100644 --- a/src/games.ts +++ b/src/games.ts @@ -9,7 +9,9 @@ import { } from "./debug"; import { Game, - GameConstructor + GameConstructor, + GameDataPacket, + GameJoinParams } from "./games/game"; import { resolve @@ -21,6 +23,7 @@ import { readFileSync } from "fs"; + const DB = { active_games: { table: "active_games", @@ -72,13 +75,17 @@ const Games: GameDB = new GameDB(MYSQL_CONFIG); let socket; -function joinGame(socket: io.Socket, args: any) { +function joinGame(socket: io.Socket, args: GameJoinParams) { console.log(`Join game request : `); console.log(args); + if (!args) { + socket.emit("kick", "no data"); + return; + } //check game id exists - Games.query(`SELECT active_games.active_game_id, active_games.active_game_type_id, active_games.active_game_idle, game_data.data_value FROM active_games, game_data WHERE active_game_id = ? AND game_data.data_key = 0;`, [args.id]) + Games.query(`SELECT active_games.active_game_id, active_games.active_game_type_id, active_games.active_game_idle, game_data.data_value FROM active_games, game_data WHERE active_game_id = ? AND game_data.data_key = 0;`, [args.gameId]) .then(res => { if (res.err) { console.log(res.err); @@ -125,10 +132,14 @@ async function API(req: express.Request, res: express.Response, next: express.Ne return; break; default: + let g = await getGame(paths[0]); + console.log(paths); + if (g) g.apiHandler(req, res, next); + else next(404); break; } - next(); + // next(); } function game_api(app: Server) { @@ -138,12 +149,19 @@ function game_api(app: Server) { socket = io(app); socket.sockets.on("connection", (socket: io.Socket) => { console.log(`New connection : ${socket.id}`); - socket.on("join", (data: any) => joinGame(socket, data)); + socket.on("join", (data: GameJoinParams) => joinGame(socket, data)); socket.on("disconnect", (args) => { console.log(`Socket disconnected : ${socket.id}`); }); - + socket.on("game_data", async (data: GameDataPacket) => { + // console.log(data); + let game = await getGame(data.gameType); + if (game) + game.data(socket, data); + else + console.log("Unable to find game"); + }); }); return { @@ -180,8 +198,6 @@ function listGames(game: string, response: express.Response, next: express.NextF .catch(console.log) .catch(next) return; - - } let loadedGames: Game[] = []; @@ -195,7 +211,7 @@ function createGame(game: string, req: express.Request, res: express.Response, n return getGame(game).then((game: Game) => { debug(`Creating game by Alex. CHANGE`); console.log(req.body); - game.create(req.body.name, req.body.password).then(active_game_id => { + game.create(req.body).then(active_game_id => { res.send(`Created new ${game.name} game by ${"Alex"} with id ${active_game_id}`); res.end(); }); @@ -209,10 +225,12 @@ function getGame(game: string | number): Promise < Game > { } else { query = `SELECT ${DB.games.game_id.column}, ${DB.games.game_name.column} FROM ${DB.games.table} WHERE ${DB.games.game_name.column} = ${mysql.escape(game)};`; } - + // console.log(query) return Games.query(query) .then(results => { + // console.log(results); + if (!results.results[0]) return null; // console.log(query); // console.log(results); let game_id: number = results.results[0].game_id; diff --git a/src/games/backgammon.ts b/src/games/backgammon.ts new file mode 100644 index 0000000000000000000000000000000000000000..8eb525676d5b5c746d352c0fd439f0a98767c7db --- /dev/null +++ b/src/games/backgammon.ts @@ -0,0 +1,31 @@ +import { + Game, + GameJoinParams, + GameDataPacket +} from "./game"; +import { + GameDB +} from "../gamedb"; +import * as io from "socket.io" + + +class backgammon extends Game { + constructor(db: GameDB) { + super("backgammon", db); + } + + async join(socket: io.Socket, d: GameJoinParams): Promise < boolean > { + + return true; + } + + async data(socket: io.Socket, d: GameDataPacket) { + + } + + +} + +export { + backgammon as game +}; \ No newline at end of file diff --git a/src/games/battleships.ts b/src/games/battleships.ts index b486c83a44276296858d4e454a79f43a8240447a..12b8c2005c83e2894ffa4d2fb8cad82cfffa1191 100644 --- a/src/games/battleships.ts +++ b/src/games/battleships.ts @@ -4,7 +4,10 @@ import { GameInitFunction, GameCreateFunction, GameDestroyFunction, - GameConstructor + GameConstructor, + GameDataPacket, + GameJoinParams, + GameCreateData } from "./game"; import { debug @@ -42,33 +45,30 @@ interface shot { hit: boolean, } -const battleships: GameConstructor = class battleships implements Game { - - public readonly id: number = 1; - public readonly name: string = "battleships"; - - protected db: GameDB; +const battleships: GameConstructor = class battleships extends Game { protected players: player[] = []; constructor(db_server: GameDB) { + super("battleships", db_server) this.db = db_server; + } + async data(socket: io.Socket, game_data: GameDataPacket) { + } // init(){} - async create(creator: string, password ? : string): Promise < number > { - debug(`Battleships creating game by ${creator}`); + async create(d: GameCreateData): Promise < number > { + + return super.create(d); return new Promise < number > ((resolve, reject) => { this.db.query(`INSERT INTO active_games(active_game_type_id, active_game_idle) VALUES (${this.id}, now());`) // .then(results => { // console.log(results.results); resolve(results.results.insertId || -1); let json_data: any = { - name: creator, + name: d.name, players: [], - password: password + password: d.password }; - if (password) { - json_data.password = password; - } return this.db.query(`INSERT INTO game_data(game_id, data_key, data_value) VALUES (${results.results.insertId}, 0, ?);`, JSON.stringify(json_data)); }) .then(results => { @@ -85,7 +85,7 @@ const battleships: GameConstructor = class battleships implements Game { } - async join(socket: io.Socket, args: any): Promise < boolean > { + async join(socket: io.Socket, args: GameJoinParams): Promise < boolean > { console.log(`Joining battleships game`); console.log(args); @@ -94,13 +94,13 @@ const battleships: GameConstructor = class battleships implements Game { //query to check if password correct etc, max number of players not reached etc - return this.db.query(`SELECT data_key, data_value FROM game_data WHERE game_id = ${args.id} AND data_key = 0;`) + return this.db.query(`SELECT data_key, data_value FROM game_data WHERE game_id = ${args.gameId} AND data_key = 0;`) .then(results => { let row = results.results[0]; // console.log(row.data_value); let json = JSON.parse(row.data_value); // console.log(json); - if (json.password !== args.password) { + if (json.password !== args.gamePassword) { socket.emit("disconnect", "Incorrect password"); socket.disconnect(true); return false; @@ -112,18 +112,18 @@ const battleships: GameConstructor = class battleships implements Game { } // socket.emit("welcome", "Successfully joined game!"); console.log("Successfully joined game!"); - json.players.push(args.username); + json.players.push(args.userName); // console.log(json); console.trace("JOINING USERS"); - this.db.query(`UPDATE game_data SET data_value = ${escape(JSON.stringify(json))} WHERE game_id = ${args.id} AND data_key = 0;`) + this.db.query(`UPDATE game_data SET data_value = ${escape(JSON.stringify(json))} WHERE game_id = ${args.gameId} AND data_key = 0;`) .then(() => { - return this.db.query(`SELECT data_key, data_value FROM game_data WHERE game_id = ${args.id};`) + return this.db.query(`SELECT data_key, data_value FROM game_data WHERE game_id = ${args.gameId};`) }) .then(results => { //player number console.log(results.results); let json = JSON.parse(results.results.reduce((acc: any, cur: any) => cur.data_key == 0 ? cur : acc, null).data_value); - let player_number = json.players.indexOf(args.username); + let player_number = json.players.indexOf(args.userName); debug(player_number) let player_data = results.results.reduce((acc: any, cur: any) => cur.data_key == player_number + 1 ? cur : acc, null); if (player_data) { @@ -147,8 +147,8 @@ const battleships: GameConstructor = class battleships implements Game { let player: player = { socket: socket, - game_id: args.id, - username: args.username, + game_id: args.gameId, + username: args.userName, } this.players.push(player); diff --git a/src/games/battleships_v2.ts b/src/games/battleships_v2.ts index 452d792884bd10364842d8ee6267adefef8069b9..74037f9adde3728921a51c894a9e016c6e8b14be 100644 --- a/src/games/battleships_v2.ts +++ b/src/games/battleships_v2.ts @@ -6,7 +6,10 @@ import { } from "../gamedb"; import { Game, - GameConstructor + GameConstructor, + GameDataPacket, + GameCreateData, + GameJoinParams } from "./game" interface player { @@ -36,10 +39,7 @@ interface shot { hit: boolean, } -const battleships_v2: GameConstructor = class battleships_v2 implements Game { - db: GameDB; - public readonly name: string = "battleships_v2"; - public readonly id: number = 3; +const battleships_v2: GameConstructor = class battleships_v2 extends Game { players: player[] = []; ships: ship[] = [{ size: 5, @@ -77,39 +77,37 @@ const battleships_v2: GameConstructor = class battleships_v2 implements Game { y: number = 10; constructor(db_server: GameDB) { - this.db = db_server; - // this.db.query("") + super("battleships_v2", db_server); } - async create(creator: string, password ? : string): Promise < number > { - let game_data: game = { - id: -1, - type_id: this.id, - data: { - name: creator, - players: [], - password: password - } - } + async data(socket: io.Socket, game_data: GameDataPacket) { + + } + + async create(d: GameCreateData): Promise < number > { + await this.ready; + + let id: number; try { - game_data = await this.db.createGame(game_data); + id = await super.create(d); this.db.query("INSERT INTO game_data (game_id, data_key, data_value) VALUES\ (?, 1, '[]'),(?, 2, '[]');", - [game_data.id, game_data.id]) + [id, id]); } catch (e) { console.log("ERROR: creating game"); console.log(e); } - return game_data.id; + return id; } async destroy() {} - async join(socket: io.Socket, args: any): Promise < boolean > { + async join(socket: io.Socket, args: GameJoinParams): Promise < boolean > { + await this.ready; let p: player = { - game_id: args.id, - username: args.username, + game_id: args.gameId, + username: args.userName, socket: socket, player_no: -1, } @@ -118,7 +116,7 @@ const battleships_v2: GameConstructor = class battleships_v2 implements Game { let game_data: game_data = JSON.parse(game.results[0].data_value); console.log(game_data); if (game_data.password) { - if (args.password != game_data.password) { + if (args.gamePassword != game_data.password) { return false; } } @@ -132,10 +130,11 @@ const battleships_v2: GameConstructor = class battleships_v2 implements Game { if (p.player_no >= 2) return false; game_data.players[p.player_no] = p.username; - this.db.query(`UPDATE game_data SET data_value=? WHERE game_id=? AND data_key=0;`, [JSON.stringify(game_data), p.game_id]); + await this.db.query(`UPDATE game_data SET data_value=? WHERE game_id=? AND data_key=0;`, [JSON.stringify(game_data), p.game_id]); let player_data = await this.db.getGameData(p.game_id); let ships: ship[] = player_data.json[p.player_no + 1]; //JSON.parse(player_data.results.reduce((acc: any, row: any) => row.data_key == p.player_no + 1 ? row : acc, null).data_value) + // if (ships) { setTimeout(() => { socket.emit("placed", ships); socket.emit("place", this.ships[ships.length]); @@ -157,6 +156,7 @@ const battleships_v2: GameConstructor = class battleships_v2 implements Game { console.log("sent placed ships"); console.log(ships); console.log(this.ships[ships.length]); + // } socket.on("place", (ship: ship) => this.place(p, ship)); diff --git a/src/games/cah.ts b/src/games/cah.ts new file mode 100644 index 0000000000000000000000000000000000000000..ea8eebc08107aa1be03646f41c3be75b368e12ff --- /dev/null +++ b/src/games/cah.ts @@ -0,0 +1,210 @@ +import { + GameConstructor, + Game, + GameDataPacket, + GameJoinParams, + GameCreateData +} from "./game"; +import { + GameDB, + game, + GameType +} from "../gamedb"; +import * as io from "socket.io" +import { + readFileSync, + readFile +} from "fs"; +import { + threadId +} from "worker_threads"; +import { + Socket +} from "dgram"; +import { + NextFunction, + Response, + Request +} from "express"; +import { + randomBytes +} from "crypto"; + +interface CahCreateData extends GameCreateData { + + packs: string[], + + max_players ? : number, + timeout ? : number, +} + +interface player { + userName: string, + gameId: number, + gameToken: string, + lastSocket: io.Socket, +} + +interface card { + bw: boolean, + text: string, + pack_name: string, + extra ? : { + draw ? : number, + pick ? : number + } +} + +interface pack { + name: string, + cards: card[], +} + +const cah: GameConstructor = class cah extends Game { + + packs: pack[]; + cards_ready: Promise < void > ; + constructor(db_server: GameDB) { + super("cah", db_server); + let self = this; + this.cards_ready = new Promise < void > ((resolve, reject) => { + readFile("./data/games/cah/cards.json", (err, data) => { + if (err) { + reject(err); + return; + } + // console.log(data.toString()); + self.packs = JSON.parse(data.toString()); + for (let pack of this.packs) { + console.log(pack.name + ":"); + for (let card of pack.cards) { + console.log(" " + card.text.substr(0, 40)); + } + } + resolve(); + }) + }) + } + + async data(socket: io.Socket, data: GameDataPacket) { + await this.ready; + console.log(data); + switch (data.packetType) { + case "rand": + this.randCard(socket, data); + break; + case "hand": + this.sendHand(socket, data); + break; + } + } + + async create(d: CahCreateData): Promise < number > { + await this.ready; + let id: number; + try { + id = await super.create(d); + await this.db.query("INSERT INTO game_data (game_id, data_key, data_value) VALUES (?, 1, ?);", [id, JSON.stringify(d.packs)]); + } catch (e) { + console.log(e); + } + return id; + } + + async join(socket: io.Socket, args: GameJoinParams): Promise < boolean > { + await this.ready; + await this.cards_ready; + + let p: player = { + gameId: args.gameId, + gameToken: randomBytes(16).toString("base64"), + userName: args.userName, + lastSocket: socket + } + console.log(p); + + return true; + } + + async randCard(socket: io.Socket, args: any) { + await this.cards_ready; + + let cards = this.packs.reduce((arr: card[], cur) => { + return arr.concat(cur.cards) + }, []); + let d: GameDataPacket = { + gameId: -1, + gameToken: "", + // userName: "", + // userToken: "", + packetType: "black", + gameType: this.id, + data: cards[Math.floor(Math.random() * cards.length)], + } + + if (!d.data) debugger; + + + socket.emit("game_data", d); + + } + + async sendHand(socket: io.Socket, data: GameDataPacket) { + await this.cards_ready + let packs = await this.db.getGameData(data.gameId, 1); + + let game_cards = this.packs.reduce( + (arr, cur) => packs.json[1].indexOf(cur.name) != -1 ? arr.concat(cur.cards.reduce( + (_arr, _cur) => _cur.bw ? _arr : _arr.concat(_cur), [])) : arr, []); + // []) + console.log(game_cards); + console.trace("WIP"); + let hand: card[] = []; + while (hand.length < 7) { + hand.push(game_cards[Math.floor(Math.random() * game_cards.length)]); + } + let d: GameDataPacket = { + gameId: data.gameId, + gameToken: data.gameToken, + gameType: data.gameType, + packetType: "hand", + data: hand, + } + socket.emit("game_data", d); + } + + async getPacks(req: Request, res: Response, next: NextFunction) { + await this.cards_ready; + let packs: string[] = this.packs.reduce((p, c) => { + p.push(c.name); + return p; + }, []); + res.type("json"); + res.send(packs); + res.end(); + + } + + async apiHandler(req: Request, res: Response, next: NextFunction) { + if (req.method == "GET") { + let action = req.path.split("/"); + action = action.slice(action.lastIndexOf("api") + 2); + switch (action[0]) { + case "packs": + this.getPacks(req, res, next); + break; + default: + next(404); + } + } else if (req.method == "POST") { + next(404); + } + } + + + +} + +export { + cah as game +}; \ No newline at end of file diff --git a/src/games/cah_cards.json b/src/games/cah_cards.json new file mode 100644 index 0000000000000000000000000000000000000000..e825b944017e9efe47f0474b96e6ed9b49246ffe --- /dev/null +++ b/src/games/cah_cards.json @@ -0,0 +1,316 @@ +[{ + "name": "Cards against humanity", + "cards": [{ + "bw": false, + "text": "Silence.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "The illusion of shoice in a late-stage capitalist society.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Many bats.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Famine.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Flesh-eating bacteria.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Flying sex snakes.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Not giving a shit about the Third World.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Magnets.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Shapeshifters.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Seeing what happens when you lock people in a room with hungry seagulls.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A crucifixion.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Jennifer Lawrence.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "72 virgins.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A live studio audience.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "A time travel paradox.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Authentic Mexican cuisine.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Doing crimes.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Synergistic management solutions.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Crippling debt.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "Daddy issues.", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": false, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Hey Reddit! I’m __________________. Ask me anything.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Introducing X-treme Baseball! It’s like baseball, but with __________!", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "What is Batman’s guilty pleasure.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "TSA guidelinesnow prohibit __________________ on airplanes", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Next from J.K. Rowling: Harry Potter and the Chamber of __________________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "That’s right, I killed _________________. How, you ask? _________________.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "I’m sorry, Professor, but I couldn’t complete my homework because of __________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "And the Academy Award for __________________ goes to __________.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "Dude, do not go in that bathroom. There’s __________ in there.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "How did I losemy virginity?", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "It’s a pity that kids these days are all getting involved with _____________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Step 1: __________. Step 2: __________. Step 3: Profit.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "_________________. Betcha can’t have just one!", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "Kids, I don’t need drugs to get high. I’m high on __________.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "For my next trick, I will pull __________ out of ___________.", + "pack_name": "Cards against humanity", + "extra": { + "pick": 2 + } + }, + { + "bw": true, + "text": "While the United States raced the Soviet Union to the moon, the Mexican government funneled millions of pesos into research on _____________________", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "In the Disney Channel Original Movie, Hannah Montana struggles with _____________ for the first time.", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "What’s mysecret power?", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "", + "pack_name": "Cards against humanity" + }, + { + "bw": true, + "text": "", + "pack_name": "Cards against humanity" + } + ] + }, + { + "name": "Covid-19 Pack", + "cards": [{ + "bw": false, + "text": "Coronavirus.", + "pack_name": "Covid-19 Pack" + }, + { + "bw": false, + "text": "Boris Johnson in an ICU.", + "pack_name": "Covid-19 Pack" + } + ] + } +] \ No newline at end of file diff --git a/src/games/game.ts b/src/games/game.ts index 902a89649e099bf37dc618c17b075475ed38e49e..40bdd982bc542d3662ec038a2d9ed77bd2e26c79 100644 --- a/src/games/game.ts +++ b/src/games/game.ts @@ -1,23 +1,107 @@ import * as mysql from "mysql" import { - GameDB + GameDB, + GameType, + game } from "../gamedb"; import * as io from "socket.io" +import { + Request, + Response, + NextFunction +} from "express"; export type GameInitFunction = (db_server: GameDB) => void; -export type GameCreateFunction = (creator: string, password ? : string) => Promise < number > ; +export type GameCreateFunction = (d: GameCreateData) => Promise < number > ; export type GameDestroyFunction = (game_id: number) => void; export type GameJoinFunction = (socket: io.Socket, args: any) => Promise < boolean > ; export interface GameConstructor { new(db_server: GameDB): Game; } +export type GameDataFunction = (socket: io.Socket, game_data: GameDataPacket) => void; +export interface GameCreateData { + name: string, + password ? : string, +} -export interface Game { +export interface GameDataPacket { + gameId: number, + gameType: number, + gameToken: string, + packetType: string, + data ? : any, + userName ? : string, + userToken ? : string, +} + +export interface GameJoinParams { + gameId: number, + userName: string, + gamePassword: string, +} + +export type GameAPIHandlerFunction = (req: Request, res: Response, next: NextFunction) => void; + +interface _Game { create: GameCreateFunction; + data: GameDataFunction; destroy: GameDestroyFunction; join: GameJoinFunction; + apiHandler: GameAPIHandlerFunction; name: string; id: number; [key: string]: any; +} + +let getGameType: Function = async function(name: string, db: GameDB): Promise < GameType > { + return db.getGameType(name) + .catch(() => { + return db.query("INSERT INTO games (game_name) VALUES (?);", name) + .then(getGameType(name, db)); + }) + +}; + +export abstract class Game implements _Game { + public name: string; + public id: number; + protected db: GameDB; + protected ready: Promise < void > ; + constructor(name: string, db: GameDB) { + this.name = name; + this.db = db; + this.ready = getGameType(this.name, this.db) + .then((g: GameType) => { + this.id = g.id; + }); + } + abstract async data(socket: io.Socket, data: GameDataPacket): Promise < void > ; + + async create(d: GameCreateData): Promise < number > { + await this.ready; + let game: game = { + id: -1, + type_id: this.id, + data: { + name: d.name, + players: [], + password: d.password, + }, + } + game = await this.db.createGame(game); + + return game.id; + } + + async destroy() { + + } + + abstract async join(socket: io.Socket, args: GameJoinParams): Promise < boolean > ; + + apiHandler(req: Request, res: Response, next: NextFunction) { + next(404); + } + } \ No newline at end of file diff --git a/src/sendFile.ts b/src/sendFile.ts index 023bbd0f105bbf43f63456330b3305488f5a203d..700ff6753fe5481a0808f0de36f2829a73847cca 100644 --- a/src/sendFile.ts +++ b/src/sendFile.ts @@ -1,29 +1,40 @@ import * as express from "express"; import * as fs from "fs"; -function staticServe(root : string){ - return function (req : express.Request, res : express.Response, next : express.NextFunction){ - let fullpath = root+req.path; - sendFile(fullpath, req, res, next); - } +function staticServe(root: string) { + return function(req: express.Request, res: express.Response, next: express.NextFunction) { + let fullpath = root + req.path; + sendFile(fullpath, req, res, next); + } } -function sendFile(path : string, req : express.Request, res : express.Response, next : express.NextFunction){ - fs.exists(path, (exists : boolean) => { - if(!exists){ - next(404); - return; - } - let rs = fs.createReadStream(path); - res.type(path.substr(path.lastIndexOf("."))); - rs.on("data", (data : Buffer) => { - res.write(data); - }); - rs.on("end", () => { - res.end(); - rs.close(); - }); - }) +function sendFile(path: string, req: express.Request, res: express.Response, next: express.NextFunction) { + fs.exists(path, (exists: boolean) => { + if (!exists) { + next(404); + return; + } + fs.stat(path, (err, stat) => { + if (stat.isDirectory()) { + res.redirect(req.path + "/"); + res.end(); + } else { + let rs = fs.createReadStream(path); + res.type(path.substr(path.lastIndexOf("."))); + rs.on("data", (data: Buffer) => { + res.write(data); + }); + rs.on("end", () => { + res.end(); + rs.close(); + }); + } + + }) + }) } -export {sendFile, staticServe}; \ No newline at end of file +export { + sendFile, + staticServe +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index e74bbca1a14ba0c74fe6e34f782b4e4b710be4c0..a8a22c014106b522d560a647785fdcb0b2ce71bc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,16 @@ { - "compilerOptions": { - "module": "CommonJS", - "target": "ES2020", - "sourceMap": true, - "removeComments": false, - "outDir": "dst/", - "noImplicitAny": true, - - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules" - ] + "compilerOptions": { + "module": "CommonJS", + "target": "ES2020", + "sourceMap": true, + "removeComments": false, + "outDir": "dst/", + "noImplicitAny": true, + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules" + ] } \ No newline at end of file