Now to iron out a million type erros (:

This commit is contained in:
Alexander Bass 2022-06-24 09:37:03 -04:00
parent 4d5577b1f2
commit c2d02655cd
39 changed files with 1401 additions and 23 deletions

1
dist/env.js vendored Normal file
View file

@ -0,0 +1 @@
export const port = 8082;

38
dist/game.js vendored Normal file
View file

@ -0,0 +1,38 @@
import { Player } from "./player.js";
import { roomManager } from "./roomManager.js";
import { World } from "./world/world.js";
export class Game {
constructor(id, options) {
this.id = id;
this.players = [];
this.oldWorld = [];
this.world = new World(options);
}
addPlayer(id, name, color) {
if (this.getAllNames().includes(name))
return false;
const player = new Player(id, name, color);
this.players.push(player);
return player;
}
removePlayerByID(id) {
this.players = this.players.filter(obj => obj.id != id);
if (this.players.length < 1) {
roomManager.removeGameByID(this.id);
}
}
getAllIDs() {
let ids = [];
for (let i = 0; i < this.players.length; i++) {
ids.push(this.players[i].id);
}
return ids;
}
getAllNames() {
let names = [];
for (let i = 0; i < this.players.length; i++) {
names.push(this.players[i].name);
}
return names;
}
}

115
dist/log.js vendored Normal file
View file

@ -0,0 +1,115 @@
import * as os from "os";
var mode = 0;
var logs = [];
var rightView = [0, 1, 2, 3, 4, 5, 6];
var info = [[], []];
export function setMode(type) {
mode = type;
}
export function updateLog() {
if (mode)
return;
let templogs = logs;
console.clear();
const columns = process.stdout.columns;
const rows = process.stdout.rows;
const vertSplit = Math.round(rows / 4);
for (var i = 0; i < vertSplit; i++) {
process.stdout.cursorTo(Math.round(columns / 2), i);
process.stdout.clearLine();
process.stdout.write(`|`);
}
for (var i = 0; i < columns; i++) {
process.stdout.cursorTo(i + 1, vertSplit);
process.stdout.write(`=`);
}
process.stdout.cursorTo(0, 0);
process.stdout.write("Players:");
const games = info[0];
var pointer = 0;
for (i = 0; i < games.length; i++) {
process.stdout.cursorTo(0, pointer + 1);
process.stdout.write(`\x1b[46mGameName: \x1b[1m${games[i].name}\x1b[0m`);
const players = games[i].players;
for (var j = 0; j < players.length; j++) {
process.stdout.cursorTo(0, pointer + 2);
process.stdout.write(`--Name: \x1b[1m${players[j].name}\x1b[0m -\x1b[1m ID:${players[j].id}\x1b[0m`);
pointer++;
}
pointer++;
}
if (templogs.length > Math.round(3 * rows / 4) - 3) {
templogs.splice(0, logs.length - Math.round(3 * rows / 4) + 2);
}
for (var i = 0; i < templogs.length; i++) {
process.stdout.cursorTo(0, vertSplit + 1 + i);
process.stdout.write(`${templogs[i]}${os.EOL}`);
}
}
export function log(string, color) {
if (mode)
return console.log(string);
if (string == undefined)
return;
var prefix = '';
switch (color) {
case "reset":
prefix = "\x1b[0m";
break;
case "bright":
prefix = "\x1b[1m";
break;
case "dim":
prefix = "\x1b[2m";
break;
case "underscore":
prefix = "\x1b[4m";
break;
case "reverse":
prefix = "\x1b[7m";
break;
case "FgBlack":
prefix = "\x1b[30m";
break;
case "FgRed":
prefix = "\x1b[31m";
break;
case "FgGreen":
prefix = "\x1b[32m";
break;
case "FgYellow":
prefix = "\x1b[33m";
break;
case "FgBlue":
prefix = "\x1b[34m";
break;
case "FgMagenta":
prefix = "\x1b[35m";
break;
case "FgCyan":
prefix = "\x1b[36m";
break;
case "FgWhite":
prefix = "\x1b[37m";
break;
}
// BgBlack = "\x1b[40m"
// BgRed = "\x1b[41m"
// BgGreen = "\x1b[42m"
// BgYellow = "\x1b[43m"
// BgBlue = "\x1b[44m"
// BgMagenta = "\x1b[45m"
// BgCyan = "\x1b[46m"
// BgWhite = "\x1b[47m"
const newString = prefix + string + "\x1b[0m";
logs.push(newString);
updateLog();
}
export function setInfo(players) {
if (mode)
return false;
if (players != undefined) {
info[0] = players;
updateLog();
}
}

6
dist/main.js vendored Normal file
View file

@ -0,0 +1,6 @@
import "./roomManager.js";
import "./server/netcode.js";
setInterval(function () { updateInfo(); }, 5000);
function updateInfo() {
console.log("running...");
}

7
dist/player.js vendored Normal file
View file

@ -0,0 +1,7 @@
export class Player {
constructor(id, name, color) {
this.id = id;
this.name = name;
this.color = color;
}
}

67
dist/roomManager.js vendored Normal file
View file

@ -0,0 +1,67 @@
import { Game } from "./game.js";
import * as util from "./util.js";
import { IllegalAction } from "./server/illegalAction.js";
class RoomManager {
constructor() {
this.games = [];
}
getGameByID(id) {
const game = this.games.filter(obj => obj.id == id)[0];
if (game === undefined) {
return false;
}
return game;
}
addGame(id, options) {
const game = new Game(id, options);
this.games.push(game);
return game;
}
removeGameByID(id) {
this.games = this.games.filter(obj => obj.id != id);
}
getAllPlayerIDs() {
let ids = [];
for (let i = 0; i < this.games.length; i++) {
for (let j = 0; j < this.games[i].players.length; j++) {
ids.push(this.games[i].players[j].id);
}
}
return ids;
}
getAllGameIDs() {
let ids = [];
for (let i = 0; i < this.games.length; i++) {
ids.push(this.games[i].id);
}
return ids;
}
playerJoinGame(roomCode, playerName, playerID) {
// See if the client is already in a game
if (this.getAllPlayerIDs().includes(playerID)) {
return new IllegalAction(id, 22);
}
if (!this.getAllGameIDs().includes(roomCode)) {
return new IllegalAction(id, 30);
}
const game = this.getGameByID(roomCode);
const player = game.addPlayer(playerID, playerName);
// See if player name is taken already
if (player === false) {
this.removeGame(game);
return new IllegalAction(id, 20);
}
return [game, player];
}
playerCreateGame(options, playerName, playerColor, playerID) {
if (this.getAllPlayerIDs().includes(playerID)) {
return new IllegalAction(id, 22);
}
console.log(options);
const id = util.createCode();
const game = this.addGame(id, options);
const player = game.addPlayer(playerID, playerName, playerColor);
return [game, player];
}
}
export var roomManager = new RoomManager();

11
dist/server/illegalAction.js vendored Normal file
View file

@ -0,0 +1,11 @@
import { io } from "./io.js";
export class IllegalAction {
constructor(id, action) {
this.action = action;
this.id = id;
this.sendIllegalAction();
}
sendIllegalAction() {
io.to(this.id).emit('illegalAction', this.action);
}
}

3
dist/server/io.js vendored Normal file
View file

@ -0,0 +1,3 @@
import { webServer } from "./server.js";
import { Server } from "socket.io";
export const io = new Server(webServer, {});

55
dist/server/netcode.js vendored Normal file
View file

@ -0,0 +1,55 @@
import { IllegalAction } from "./illegalAction.js";
import { roomManager } from "../roomManager.js";
import { io } from "./io.js";
io.on('connection', function (client) {
connected(client);
});
function connected(client) {
client.sync = function () {
const tempWorld = client.game.world.obfuscate();
io.to(client.game.id).emit('sync', { world: tempWorld });
};
client.sendMeta = function () {
const roomID = client.game.id;
const roomPlayers = client.game.players; // Dont send client id's to everyone, TODO
const metadata = { players: roomPlayers, roomID: roomID };
io.to(client.game.id).emit('metadata', metadata);
const id = client.game.id;
client.emit('message', id);
};
client.game = "";
client.player = "";
client.on('disconnect', function () {
if (!roomManager.getAllPlayerIDs().includes(client.id))
return new IllegalAction(client.id, 22);
client.game.removePlayerByID(client.id);
client.sendMeta();
});
client.on('joinGame', function (data) {
const info = roomManager.playerJoinGame(data.room, data.name, client.id);
client.join(info[0].id);
client.game = info[0];
client.player = info[1];
client.sync();
client.emit('inGame', true);
client.sendMeta();
});
client.on('createGame', function (data) {
const info = roomManager.playerCreateGame(data.options, data.name, data.color, client.id);
client.join(info[0].id);
client.game = info[0];
client.player = info[1];
client.emit('inGame', true);
client.sync();
client.sendMeta();
});
client.on('leaveGame', function (data) {
client.game.removePlayerByID(client.id);
});
client.on('clickCanvas', function (data) {
if (!roomManager.getAllPlayerIDs().includes(client.id))
return new IllegalAction(client.id, 1);
client.game.world.click(data.tilePosition[0], data.tilePosition[1], data.mode, client.player);
client.sync();
});
}

9
dist/server/server.js vendored Normal file
View file

@ -0,0 +1,9 @@
import path from 'path';
import express from "express";
import { port } from "../env.js";
var app = express();
const __dirname = path.resolve(path.dirname(''));
app.use(express.static(__dirname + '/www/'));
export var webServer = app.listen(port, function () {
var port = webServer.address().port;
});

11
dist/util.js vendored Normal file
View file

@ -0,0 +1,11 @@
import crypto from "crypto";
export function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
export function clamp(number, min, max) {
return Math.max(min, Math.min(number, max));
}
export function createCode() {
const randomString = crypto.randomBytes(3).toString("hex").toUpperCase();
return randomString;
}

20
dist/world/flagger.js vendored Normal file
View file

@ -0,0 +1,20 @@
export function flag(x, y, data, player) {
let tile = data[x][y];
if (!tile.mask || tile.color === 0)
return data;
const color = player.color * 1;
console.log(player);
switch (tile.flag) {
case (0):
tile.flag = color;
break;
case (color):
tile.flag = color + 16;
break;
default:
tile.flag = 0;
}
console.log(tile.flag);
data[x][y] = tile;
return data;
}

42
dist/world/generator.js vendored Normal file
View file

@ -0,0 +1,42 @@
import * as util from "../util.js";
const searchLoc =
// [
// [0, 2],
// [-1, 1], [0, 1], [1, 1],
// [-2,0], [-1, 0],/*Start*/[1, 0], [2,0],
// [-1,-1], [0,-1], [1,-1],
// [0,-2]
//
// ]
[
[-1, 1], [0, 1], [1, 1],
[-1, 0], [1, 0],
[-1, -1], [0, -1], [1, -1]
];
export function generate(avoidX, avoidY, world) {
var minesPlanted = 0;
while (minesPlanted < world.mines || !(minesPlanted <= world.width * world.height - 15)) {
const x = util.randomNumber(0, world.width);
const y = util.randomNumber(0, world.height);
var suitable = true;
searchLoc.forEach(loc => {
const tempx = x + loc[0];
const tempy = y + loc[1];
if (tempx === avoidX && tempy === avoidX) {
suitable = false;
}
});
if (x == avoidX && y == avoidY) {
suitable = false;
}
if (world.data[x][y].type == 5) {
suitable = false;
}
if (suitable) {
world.data[x][y].type = 5;
minesPlanted++;
}
}
world.isGenerated = true;
return world;
}

29
dist/world/marker.js vendored Normal file
View file

@ -0,0 +1,29 @@
const searchLoc = [
[-1, 1], [0, 1], [1, 1],
[-1, 0], [1, 0],
[-1, -1], [0, -1], [1, -1]
];
// Place Numbers
export function mark(world) {
for (let x = 0; x < world.width; x++) {
for (let y = 0; y < world.height; y++) {
if (world.data[x][y].type === 1) {
var counter = 0;
searchLoc.forEach(location => {
const tempx = x + location[0];
const tempy = y + location[1];
if (tempx >= 0 && tempy >= 0 && tempx < world.width && tempy < world.height) {
if (world.data[tempx][tempy].type === 5) {
counter++;
}
}
});
if (counter !== 0) {
world.data[x][y].type = 15 + counter;
}
}
}
}
world.isMarked = true;
return world;
}

13
dist/world/obfuscator.js vendored Normal file
View file

@ -0,0 +1,13 @@
export function obfuscate(world) {
let tempWorld = world;
for (let x = 0; x < tempWorld.width; x++) {
for (let y = 0; y < tempWorld.height; y++) {
if (tempWorld.data[x][y].mask === true) {
tempWorld.data[x][y].type = 0;
}
;
tempWorld.isObfuscated = true;
}
}
return tempWorld;
}

12
dist/world/placer.js vendored Normal file
View file

@ -0,0 +1,12 @@
import * as revealer from "./revealer.js";
export function place(x, y, data) {
let tile = data[x][y];
if (tile.mask === true) {
if (tile.mask && tile.flag === 0) {
tile.mask = false;
}
data[x][y] = tile;
revealer.reveal(x, y, data);
}
return data;
}

35
dist/world/revealer.js vendored Normal file
View file

@ -0,0 +1,35 @@
const searchLoc = [
[-1, 1], [0, 1], [1, 1],
[-1, 0], [1, 0],
[-1, -1], [0, -1], [1, -1]
];
export function reveal(x, y, data) {
if (data[x][y].type !== 5) {
var toSearch = [];
var searchedLocations = [];
toSearch.push([x, y]);
if (data[x][y].type === 1) {
while (toSearch.length > 0) {
const x = toSearch[0][0];
const y = toSearch[0][1];
searchedLocations.push(toSearch[0]);
toSearch.shift();
searchLoc.forEach(loc => {
const tempx = x + loc[0];
const tempy = y + loc[1];
if (tempx >= 0 && tempy >= 0 && tempx < data.length && tempy < data[0].length) {
if (data[tempx][tempy].type === 1 && data[tempx][tempy].mask === true) {
if (!toSearch.includes([tempx, tempy]) && !searchedLocations.includes([tempx, tempy])) {
toSearch.push([tempx, tempy]);
}
}
if (data[tempx][tempy].type !== 5) {
data[tempx][tempy].mask = false;
}
}
});
}
}
return data;
}
}

53
dist/world/world.js vendored Normal file
View file

@ -0,0 +1,53 @@
import * as obfuscater from "./obfuscator.js";
import * as generator from "./generator.js";
import * as marker from "./marker.js";
import * as log from "../log.js";
import * as flagger from "./flagger.js";
import * as placer from "./placer.js";
export class World {
constructor(options) {
this.mines = options.mines;
this.width = options.width * 1;
this.height = options.height * 1;
this.isGenerated = false;
this.isObfuscated = false;
this.isMarked = false;
this.data = Array.from(Array(this.width), () => new Array(this.height));
for (let x = 0; x < this.width; x++) {
for (let y = 0; y < this.height; y++) {
this.data[x][y] = { type: 1, flag: 0, mask: true };
}
}
}
click(x, y, mode, player) {
if (this.isGenerated) {
if (mode === 2) {
this.data = flagger.flag(x, y, this.data, player);
}
if (mode === 0) {
this.data = placer.place(x, y, this.data, player);
}
}
else {
this.generate(x, y).mark();
this.data = placer.place(x, y, this.data, player);
}
}
generate(x, y) {
if (this.isGenerated)
return log.log("Already Generated");
return generator.generate(x, y, this);
}
mark() {
if (this.isMarked)
return log.log("Already Marked!");
return marker.mark(this);
}
obfuscate() {
if (this.isObfuscated)
return log.log("already done");
const tempWorld = JSON.parse(JSON.stringify(this));
;
return obfuscater.obfuscate(tempWorld);
}
}

View file

@ -1,10 +0,0 @@
import * as log from "./scripts/log.mjs"
import "./scripts/roomManager.mjs"
import "./scripts/server/netcode.mjs"
import {roomManager} from "./scripts/roomManager.mjs"
log.setMode(1);
setInterval(function(){ updateInfo()},5000)
function updateInfo() {
log.setInfo(roomManager.games)
}

402
package-lock.json generated
View file

@ -1,11 +1,11 @@
{
"name": "empires",
"name": "MultiplayerMinesweeper",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "empires",
"name": "MultiplayerMinesweeper",
"version": "1.0.0",
"license": "UNLICENSED",
"dependencies": {
@ -13,23 +13,92 @@
"sass": "^1.52.3",
"socket.io": "^4.5.0",
"socket.js": "^0.1.4",
"ts-node": "^10.8.1",
"typescript": "^4.7.4"
},
"devDependencies": {
"@tsconfig/node16": "^1.0.3"
"@tsconfig/node16": "^1.0.3",
"@types/express": "^4.17.13",
"@types/node": "^18.0.0"
}
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz",
"integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.13",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz",
"integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA=="
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"node_modules/@tsconfig/node16": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ=="
},
"node_modules/@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
"integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
"dev": true,
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
}
},
"node_modules/@types/component-emitter": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
"integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ=="
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
"integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
@ -40,11 +109,62 @@
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw=="
},
"node_modules/@types/express": {
"version": "4.17.13",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
"integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
"dev": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.18",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"node_modules/@types/express-serve-static-core": {
"version": "4.17.29",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz",
"integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==",
"dev": true,
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true
},
"node_modules/@types/node": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz",
"integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA=="
},
"node_modules/@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
"dev": true
},
"node_modules/@types/range-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true
},
"node_modules/@types/serve-static": {
"version": "1.13.10",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
"integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==",
"dev": true,
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -57,6 +177,25 @@
"node": ">= 0.6"
}
},
"node_modules/acorn": {
"version": "8.7.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@ -69,6 +208,11 @@
"node": ">= 8"
}
},
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@ -219,6 +363,11 @@
"node": ">= 0.10"
}
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -244,6 +393,14 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -558,6 +715,11 @@
"node": ">=0.12.0"
}
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -956,6 +1118,48 @@
"node": ">=0.6"
}
},
"node_modules/ts-node": {
"version": "10.8.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz",
"integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@ -996,6 +1200,11 @@
"node": ">= 0.4.0"
}
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@ -1023,20 +1232,88 @@
"optional": true
}
}
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"engines": {
"node": ">=6"
}
}
},
"dependencies": {
"@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"requires": {
"@jridgewell/trace-mapping": "0.3.9"
}
},
"@jridgewell/resolve-uri": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz",
"integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA=="
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.13",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz",
"integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w=="
},
"@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA=="
},
"@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"@tsconfig/node16": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ=="
},
"@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
"integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
"dev": true,
"requires": {
"@types/connect": "*",
"@types/node": "*"
}
},
"@types/component-emitter": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
"integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ=="
},
"@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
"integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
@ -1047,11 +1324,62 @@
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw=="
},
"@types/express": {
"version": "4.17.13",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
"integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
"dev": true,
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.18",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.17.29",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz",
"integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==",
"dev": true,
"requires": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true
},
"@types/node": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz",
"integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA=="
},
"@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
"dev": true
},
"@types/range-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true
},
"@types/serve-static": {
"version": "1.13.10",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
"integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==",
"dev": true,
"requires": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -1061,6 +1389,16 @@
"negotiator": "0.6.3"
}
},
"acorn": {
"version": "8.7.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
},
"acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
},
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@ -1070,6 +1408,11 @@
"picomatch": "^2.0.4"
}
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@ -1178,6 +1521,11 @@
"vary": "^1"
}
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -1196,6 +1544,11 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -1431,6 +1784,11 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -1712,6 +2070,26 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"ts-node": {
"version": "10.8.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz",
"integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==",
"requires": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
}
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@ -1736,6 +2114,11 @@
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
},
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@ -1746,6 +2129,11 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
"requires": {}
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
}
}
}

View file

@ -1,25 +1,30 @@
{
"name": "empires",
"name": "MultiplayerMinesweeper",
"version": "1.0.0",
"description": "",
"main": "index.mjs",
"main": "",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"build": ""
},
"repository": {
"type": "git",
"url": "empires"
},
"author": "",
"author": "Alexander Bass",
"license": "UNLICENSED",
"dependencies": {
"express": "^4.18.1",
"sass": "^1.52.3",
"socket.io": "^4.5.0",
"socket.js": "^0.1.4",
"ts-node": "^10.8.1",
"typescript": "^4.7.4"
},
"devDependencies": {
"@tsconfig/node16": "^1.0.3"
"@tsconfig/node16": "^1.0.3",
"@types/express": "^4.17.13",
"@types/node": "^18.0.0"
}
}

1
src/env.ts Normal file
View file

@ -0,0 +1 @@
export const port = 8082;

42
src/game.ts Normal file
View file

@ -0,0 +1,42 @@
import {Player} from "./player.js"
import * as log from "./log.js"
import {roomManager} from "./roomManager.js"
import { World} from "./world/world.js"
export class Game {
constructor(id, options) {
this.id = id;
this.players = [];
this.oldWorld = []
this.world = new World(options)
}
addPlayer(id, name, color) {
if (this.getAllNames().includes(name)) return false
const player = new Player(id, name, color);
this.players.push(player);
return player
}
removePlayerByID(id) {
this.players = this.players.filter(obj => obj.id != id);
if (this.players.length < 1) {
roomManager.removeGameByID(this.id);
}
}
getAllIDs() {
let ids = []
for (let i = 0; i < this.players.length; i++) {
ids.push(this.players[i].id)
}
return ids
}
getAllNames() {
let names = []
for (let i = 0; i < this.players.length; i++) {
names.push(this.players[i].name)
}
return names
}
}

8
src/main.ts Normal file
View file

@ -0,0 +1,8 @@
import "./roomManager.js"
import "./server/netcode.js"
import {roomManager} from "./roomManager.js"
setInterval(function(){ updateInfo()},5000)
function updateInfo() {
console.log("running...")
}

7
src/player.ts Normal file
View file

@ -0,0 +1,7 @@
export class Player {
constructor(id, name, color) {
this.id = id;
this.name = name;
this.color = color;
}
}

77
src/roomManager.ts Normal file
View file

@ -0,0 +1,77 @@
import {Game} from "./game.js"
import * as util from "./util.js"
import {IllegalAction} from "./server/illegalAction.js"
class RoomManager {
constructor(){
this.games = [];
}
getGameByID(id) {
const game = this.games.filter(obj => obj.id == id)[0]
if (game === undefined) {
return false
}
return game
}
addGame(id, options) {
const game = new Game(id, options);
this.games.push(game);
return game
}
removeGameByID(id) {
this.games = this.games.filter(obj => obj.id != id);
}
getAllPlayerIDs() {
let ids = []
for (let i = 0; i < this.games.length; i++) {
for (let j = 0; j < this.games[i].players.length; j++) {
ids.push(this.games[i].players[j].id)
}
}
return ids
}
getAllGameIDs() {
let ids = []
for (let i = 0; i < this.games.length; i++) {
ids.push(this.games[i].id)
}
return ids
}
playerJoinGame(roomCode, playerName, playerID) {
// See if the client is already in a game
if (this.getAllPlayerIDs().includes(playerID)) {
return new IllegalAction(id, 22)
}
if (!this.getAllGameIDs().includes(roomCode)) {
return new IllegalAction(id, 30)
}
const game = this.getGameByID(roomCode);
const player = game.addPlayer(playerID, playerName);
// See if player name is taken already
if (player === false) {
this.removeGame(game)
return new IllegalAction(id, 20)
}
return [game, player]
}
playerCreateGame(options, playerName, playerColor, playerID) {
if (this.getAllPlayerIDs().includes(playerID)) {
return new IllegalAction(id, 22)
}
console.log(options)
const id = util.createCode()
const game = this.addGame(id, options)
const player = game.addPlayer(playerID, playerName, playerColor);
return [game, player]
}
}
export var roomManager = new RoomManager();

View file

@ -0,0 +1,11 @@
import {io} from "./io.js"
export class IllegalAction {
constructor(id, action){
this.action = action
this.id = id
this.sendIllegalAction();
}
sendIllegalAction() {
io.to(this.id).emit('illegalAction', this.action)
}
}

4
src/server/io.ts Normal file
View file

@ -0,0 +1,4 @@
import {webServer} from "./server.js"
import { Server } from "socket.io";
export const io = new Server(webServer, {});

64
src/server/netcode.ts Normal file
View file

@ -0,0 +1,64 @@
import {IllegalAction} from "./illegalAction.js"
import * as log from "../log.js"
import {roomManager} from "../roomManager.js"
import {io} from "./io.js"
io.on('connection', function(client){
connected(client)
});
function connected(client) {
client.sync = function() {
const tempWorld = client.game.world.obfuscate();
io.to(client.game.id).emit('sync',{world: tempWorld})
}
client.sendMeta = function() {
const roomID = client.game.id
const roomPlayers = client.game.players; // Dont send client id's to everyone, TODO
const metadata = {players: roomPlayers, roomID: roomID}
io.to(client.game.id).emit('metadata', metadata)
const id = client.game.id
client.emit('message', id)
}
client.game = "";
client.player = "";
client.on('disconnect', function(){
if (!roomManager.getAllPlayerIDs().includes(client.id)) return new IllegalAction(client.id, 22)
client.game.removePlayerByID(client.id)
client.sendMeta();
})
client.on('joinGame', function(data){
const info = roomManager.playerJoinGame(data.room, data.name, client.id)
client.join(info[0].id)
client.game = info[0];
client.player = info[1]
client.sync()
client.emit('inGame', true)
client.sendMeta()
})
client.on('createGame', function(data){
const info = roomManager.playerCreateGame(data.options, data.name, data.color, client.id)
client.join(info[0].id)
client.game = info[0];
client.player = info[1]
client.emit('inGame', true)
client.sync()
client.sendMeta()
})
client.on('leaveGame', function(data){
client.game.removePlayerByID(client.id)
})
client.on('clickCanvas', function(data){
if (!roomManager.getAllPlayerIDs().includes(client.id)) return new IllegalAction(client.id, 1)
client.game.world.click(data.tilePosition[0],data.tilePosition[1], data.mode, client.player)
client.sync()
})
}

10
src/server/server.ts Normal file
View file

@ -0,0 +1,10 @@
import path from 'path';
import express from "express"
import { port } from "../env.js"
var app = express()
const __dirname = path.resolve(path.dirname(''));
app.use(express.static(__dirname + '/www/'));
export var webServer = app.listen(port, function () {
var port = webServer.address().port;
});

12
src/util.ts Normal file
View file

@ -0,0 +1,12 @@
import crypto from "crypto";
export function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
export function clamp(number, min, max) {
return Math.max(min, Math.min(number, max));
}
export function createCode() {
const randomString = crypto.randomBytes(3).toString("hex").toUpperCase()
return randomString
}

22
src/world/flagger.ts Normal file
View file

@ -0,0 +1,22 @@
export function flag(x, y, data, player) {
let tile = data[x][y]
if (!tile.mask || tile.color === 0) return data
const color = player.color * 1
console.log(player)
switch (tile.flag) {
case (0):
tile.flag = color;
break;
case (color):
tile.flag = color + 16;
break;
default:
tile.flag = 0;
}
console.log(tile.flag)
data[x][y] = tile
return data;
}

42
src/world/generator.ts Normal file
View file

@ -0,0 +1,42 @@
import * as util from "../util.js"
const searchLoc =
// [
// [0, 2],
// [-1, 1], [0, 1], [1, 1],
// [-2,0], [-1, 0],/*Start*/[1, 0], [2,0],
// [-1,-1], [0,-1], [1,-1],
// [0,-2]
//
// ]
[
[-1,1], [0,1], [1,1],
[-1,0], [1,0],
[-1,-1],[0,-1],[1,-1]
]
export function generate(avoidX, avoidY, world){
var minesPlanted = 0;
while (minesPlanted < world.mines || !(minesPlanted <= world.width*world.height-15)) {
const x = util.randomNumber(0,world.width)
const y = util.randomNumber(0,world.height)
var suitable = true;
searchLoc.forEach(loc => {
const tempx = x + loc[0]
const tempy = y + loc[1]
if (tempx === avoidX && tempy === avoidX) {
suitable = false;
}
})
if (x == avoidX && y == avoidY) { suitable = false }
if (world.data[x][y].type == 5) { suitable = false }
if (suitable) {
world.data[x][y].type = 5
minesPlanted++;
}
}
world.isGenerated = true;
return world;
}

32
src/world/marker.ts Normal file
View file

@ -0,0 +1,32 @@
const searchLoc =
[
[-1,1], [0,1], [1,1],
[-1,0], [1,0],
[-1,-1],[0,-1],[1,-1]
]
// Place Numbers
export function mark(world) {
for(let x = 0; x < world.width; x++){
for(let y = 0; y < world.height; y++){
if (world.data[x][y].type === 1) {
var counter = 0;
searchLoc.forEach(location => {
const tempx = x + location[0]
const tempy = y + location[1]
if (tempx >= 0 && tempy >= 0 && tempx < world.width && tempy < world.height) {
if (world.data[tempx][tempy].type === 5) {
counter++;
}
}
});
if (counter !== 0) {
world.data[x][y].type = 15 + counter
}
}
}
}
world.isMarked = true;
return world;
}

16
src/world/obfuscator.ts Normal file
View file

@ -0,0 +1,16 @@
export function obfuscate(world) {
let tempWorld = world;
for(let x = 0; x < tempWorld.width; x++){
for(let y = 0; y < tempWorld.height; y++){
if (tempWorld.data[x][y].mask === true) {
tempWorld.data[x][y].type = 0;
};
tempWorld.isObfuscated = true;
}
}
return tempWorld;
}

14
src/world/placer.ts Normal file
View file

@ -0,0 +1,14 @@
import * as log from "../log.js"
import * as revealer from "./revealer.js"
export function place(x, y, data) {
let tile = data[x][y];
if (tile.mask === true) {
if (tile.mask && tile.flag === 0) {
tile.mask = false;
}
data[x][y] = tile;
revealer.reveal(x, y, data)
}
return data;
}

43
src/world/revealer.ts Normal file
View file

@ -0,0 +1,43 @@
const searchLoc =
[
[-1,1], [0,1], [1,1],
[-1,0], [1,0],
[-1,-1],[0,-1],[1,-1]
]
export function reveal(x, y, data) {
if (data[x][y].type !== 5) {
var toSearch = [];
var searchedLocations = [];
toSearch.push([x, y])
if (data[x][y].type === 1) {
while (toSearch.length > 0) {
const x = toSearch[0][0]
const y = toSearch[0][1]
searchedLocations.push(toSearch[0])
toSearch.shift()
searchLoc.forEach(loc => {
const tempx = x + loc[0]
const tempy = y + loc[1]
if (tempx >= 0 && tempy >= 0 && tempx < data.length && tempy < data[0].length) {
if (data[tempx][tempy].type === 1 && data[tempx][tempy].mask === true) {
if (!toSearch.includes([tempx,tempy]) && !searchedLocations.includes([tempx,tempy])) {
toSearch.push([tempx,tempy])
}
}
if (data[tempx][tempy].type !== 5) {
data[tempx][tempy].mask = false;
}
}
})
}
}
return data
}
}

56
src/world/world.ts Normal file
View file

@ -0,0 +1,56 @@
import * as obfuscater from "./obfuscator.js";
import * as generator from "./generator.js"
import * as marker from "./marker.js"
import * as log from "../log.js"
import * as flagger from "./flagger.js"
import * as placer from "./placer.js"
export class World {
constructor(options) {
this.mines = options.mines
this.width = options.width*1
this.height = options.height*1
this.isGenerated = false;
this.isObfuscated = false;
this.isMarked = false;
this.data = Array.from(Array(this.width), () => new Array(this.height));
for (let x = 0; x < this.width; x++){
for (let y = 0; y < this.height; y++){
this.data[x][y] = {type: 1, flag: 0, mask: true}
}
}
}
click (x, y, mode, player) {
if (this.isGenerated) {
if (mode === 2) {
this.data = flagger.flag(x, y, this.data, player)
}
if (mode === 0) {
this.data = placer.place(x, y, this.data, player)
}
} else {
this.generate(x, y).mark();
this.data = placer.place(x, y, this.data, player)
}
}
generate(x, y) {
if (this.isGenerated) return log.log("Already Generated");
return generator.generate(x, y, this);
}
mark() {
if (this.isMarked) return log.log("Already Marked!");
return marker.mark(this);
}
obfuscate() {
if (this.isObfuscated) return log.log("already done")
const tempWorld = JSON.parse(JSON.stringify(this));;
return obfuscater.obfuscate(tempWorld);
}
}

View file

@ -1,6 +1,13 @@
{
"extends": "@tsconfig/node16/tsconfig.json",
"compilerOptions": {},
"compilerOptions": {
"module": "es2015",
"target": "es6",
"rootDir": "src",
"outDir": "dist",
"sourceMap": false,
"strict": true
},
"include": ["src"],
"exclude": ["node_modules"]
}