main
Benjamin Kraft 2 years ago
parent 26d6c3c4e3
commit 486e5863cb
  1. 14
      package.json
  2. 54
      src/definitions/settings.d.ts
  3. 4
      src/game_standard.ts
  4. 104
      src/games/chainreact.ts
  5. 149
      src/games/global_draw.ts
  6. 14
      src/games/memory.ts
  7. 10
      src/games/pong.ts
  8. 4
      src/manager.ts
  9. 14
      src/room.ts
  10. 1
      tsconfig.json

@ -2,8 +2,13 @@
"name": "game-server",
"version": "2.0",
"private": true,
"main": "out/index.js",
"types": "src/index.ts",
"exports": {
".": "./out/index.js",
"./room": "./out/room.js",
"./server-game": "./out/game_standard.js",
"./client": "./out/client.js",
"./logger": "./out/logger.js"
},
"dependencies": {
"dotenv": "^16.0.3",
"https": "^1.0.0",
@ -12,6 +17,9 @@
},
"devDependencies": {
"@types/node": "^17.0.18",
"typescript": "^4.5.5"
"typescript": "^4.8.4"
},
"scripts": {
"start": "node out/index.js"
}
}

@ -2,7 +2,7 @@ declare module Settings {
interface Global {
project: Project
frameWork: FrameWork
game: Game
game: any
always: boolean
spectators: boolean
}
@ -19,56 +19,4 @@ declare module Settings {
width: number
height: number
}
interface Game {
ball: Ball
player: Player
cw: number
ch: number
}
interface Ball {
radius: number
velocity: number
acceleration: number
runUp: Ball.RunUp
color: Color
cw: number
ch: number
}
interface Player {
width: number
height: number
margin: number
points: number
normal: State
weakened: State
enhanced: State
cw: number
ch: number
}
interface Color {
stroke: string
fill: string
}
interface State {
vel: Vector
color: Color
moveMargin: number
}
interface Vector {
x: number
y: number
}
module Ball {
interface RunUp {
min: number
max: number
}
}
}

@ -1,5 +1,5 @@
import {Room} from "../room"
import {Client} from "../client"
import {Room} from "./room"
import {Client} from "./client"
export class ServerGame {

@ -1,104 +0,0 @@
import {Room} from "../room"
import {ServerGame} from "./game_standard"
import {Client} from "../client"
export class Chainreact extends ServerGame {
readyForTurn: Client[];
currentTurnIndex: number;
currentGameData: any;
colorHues: { [id: string]: number };
constructor(room: Room, settings: Settings.Global) {
super(room, settings);
this.readyForTurn = []
}
setEvents(client: Client) {
let socket = client.socket;
socket.on('ready-for-turn', isDead => {
if (isDead) {
client.isPlayer = false;
client.isSpectator = true;
this.room.toAll('client-list', this.room.clients)
} else {
this.readyForTurn.push(client)
}
let allReady = true;
this.room.players.forEach(c => {
if (this.readyForTurn.find(r => r.id === c.id) == null) {
allReady = false
}
});
if (allReady) {
this.nextTurn();
this.readyForTurn = []
}
});
socket.on('set-slot', (fieldsIndex: number, slotsIndex: number) => {
this.room.toAll('set-slot', fieldsIndex, slotsIndex, socket.id)
});
socket.on('game-data', data => this.currentGameData = data)
}
addClient(client: Client): void {
super.addClient(client);
if (client.isSpectator) {
let room = this.room;
let data = this.currentGameData;
let hues = this.colorHues;
let turnId = '';
if (this.room.players[this.currentTurnIndex])
turnId = this.room.players[this.currentTurnIndex].id;
client.send('start-spectate', room, data, hues, turnId)
}
}
removeClient(client: Client): void {
super.removeClient(client);
if (this.room.players.indexOf(client) === this.currentTurnIndex)
this.nextTurn(true);
let s = client.socket;
s.removeAllListeners('set-slot');
s.removeAllListeners('ready-for-turn');
s.removeAllListeners('game-data')
}
nextTurn(skip?: boolean) {
if (this.currentTurnIndex != null && !skip) {
this.currentTurnIndex++;
if (this.currentTurnIndex >= this.room.players.length) {
this.currentTurnIndex = 0
}
} else if (!skip) {
this.setTurnAndColors()
}
let index = this.currentTurnIndex;
if (skip) {
index = this.currentTurnIndex + 1;
if (index >= this.room.players.length) {
index = 0;
this.currentTurnIndex = 0
}
}
if (this.room.players.length) {
this.room.toAll('current-turn', this.room.players[index].id)
}
}
setTurnAndColors() {
this.currentTurnIndex = Math.floor(Math.random() * this.room.players.length);
let colorHues = [0, 60, 120, 240];
this.colorHues = {};
for (let c of this.room.players) {
let index = Math.floor(Math.random() * colorHues.length);
let hue = colorHues[index];
colorHues.splice(index, 1);
this.colorHues[c.id] = hue
}
this.room.toAll('player-colors', this.colorHues)
}
}

@ -1,149 +0,0 @@
import {ServerGame} from "./game_standard"
import {Room} from "../room"
import {Client} from "../client"
import {log} from "../logger";
import fs = require("fs");
export class GlobalDraw extends ServerGame {
lines: any[];
pixels: any[][];
linesPath = "json_data/global_draw/lines.json";
pixelsPath = "json_data/global_draw/pixels.json";
pixelCount = 1000;
constructor(lobby: Room, settings: Settings.Global) {
super(lobby, settings);
this.lines = [];
this.pixels = [];
for (let x = 0; x < this.pixelCount; x++) {
let column = [];
for (let y = 0; y < this.pixelCount; y++) {
column.push({x: x, y: y, c: "#ffffff"});
}
this.pixels.push(column);
}
let linesLoaded = false;
let pixelsLoaded = false;
this.loadDrawingsFromFile(this.linesPath, (data: any[]) => {
this.lines = data;
}, () => {
linesLoaded = true;
if (pixelsLoaded) {
this.startSaveInterval();
}
});
this.loadDrawingsFromFile(this.pixelsPath, (data: any[]) => {
for (let x = 0; x < this.pixelCount; x++) {
for (let y = 0; y < this.pixelCount; y++) {
if (data[x])
if (data[x][y])
this.pixels[x][y].c = data[x][y].c
}
}
}, () => {
pixelsLoaded = true;
if (linesLoaded) {
this.startSaveInterval();
}
});
}
startSaveInterval() {
this.saveAllDrawingsToFile();
//Saves once every day
setInterval(() => this.saveAllDrawingsToFile(), 1000 * 60 * 60 * 24);
}
addLine(line: any) {
this.lines.push(line);
this.room.toAll('add-line', line)
}
fillPixel(pixel: any) {
this.pixels[pixel.x][pixel.y].c = pixel.c;
this.room.toAll('fill-pixel', pixel)
}
loadDrawingsFromFile(drawingsPath: string, successs: (data: any[]) => void, done: () => void) {
fs.readFile(drawingsPath, 'utf8', (err, data) => {
if (err)
log('load-error', null, this.room, err.message);
else {
try {
let parsed = JSON.parse(data);
log('load-success', null, this.room);
successs(parsed);
} catch (e) {
log('parse-error', null, this.room, e.message);
}
}
done();
});
}
saveDrawingsToFile(drawings: any[], drawingsPath: string, callback: (err: any) => void) {
let splits = drawingsPath.split('/');
let path = splits.slice(0, splits.length - 1).reduce((prev, curr) => prev + '/' + curr);
let name = splits[splits.length - 1];
if (!fs.existsSync(path)) {
fs.mkdirSync(path, {recursive: true});
}
fs.writeFile(drawingsPath, JSON.stringify(drawings), callback);
}
saveAllDrawingsToFile() {
let linesSaved = false;
let pixelsSaved = false;
this.saveDrawingsToFile(this.lines, this.linesPath, (err) => {
if (err)
log('save-error', null, this.room, err.message);
else {
linesSaved = true;
if (pixelsSaved) {
this.room.toAll('all-saved');
linesSaved = false;
pixelsSaved = false
}
log('save-success', null, this.room, 'Successfully saved lines to file')
}
});
this.saveDrawingsToFile(this.pixels, this.pixelsPath, (err) => {
if (err)
log('save-error', null, this.room, err.message);
else {
pixelsSaved = true;
if (linesSaved) {
this.room.toAll('all-saved');
pixelsSaved = false;
linesSaved = false
}
log('save-success', null, this.room, 'Successfully saved pixels to file')
}
});
}
addClient(client: Client): void {
this.setEvents(client);
}
setEvents(client: Client): void {
super.setEvents(client);
let socket = client.socket;
socket.on('add-line', (line) => this.addLine(line));
socket.on('fill-pixel', (pixel) => this.fillPixel(pixel));
socket.on('request-all-lines', () => socket.emit('add-all', this.lines));
socket.on('request-all-pixels', () => socket.emit('fill-all', this.pixels));
socket.on('save-all', () => this.saveAllDrawingsToFile());
}
}

@ -1,14 +0,0 @@
import {Room} from "../room"
import {ServerGame} from "./game_standard"
export class Memory extends ServerGame {
constructor(room: Room, settings: Settings.Global) {
super(room, settings);
}
gameAction(action: string, ...args: any[]) {
this.room.toAll('game-action', action, ...args);
}
}

@ -1,10 +0,0 @@
import {ServerGame} from "./game_standard"
import {Room} from "../room";
export class Pong extends ServerGame {
constructor(lobby: Room, settings: Settings.Global) {
super(lobby, settings)
}
}

@ -16,7 +16,7 @@ export class ConnectionManager {
this.io = io;
this.rooms = [];
let drawSettings = {
/*let drawSettings = {
project: {
name: 'global-draw',
playerCounts: null
@ -27,7 +27,7 @@ export class ConnectionManager {
let drawRoom = this.createRoom(drawSettings, '');
drawRoom.id = 'global-draw-room';
drawRoom.startGame();
this.rooms.push(drawRoom);
this.rooms.push(drawRoom);*/
}
static RoomListByGame(game: string): Room[] {

@ -1,9 +1,5 @@
import {Client} from "./client"
import {ServerGame} from "./games/game_standard"
import {Memory} from "./games/memory"
import {Pong} from "./games/pong"
import {GlobalDraw} from "./games/global_draw"
import {Chainreact} from "./games/chainreact"
import {ServerGame} from "./game_standard"
import {serializeObject} from "./manager";
import {Server} from "socket.io";
@ -129,16 +125,16 @@ export class Room {
runGame(): void {
switch (this.gameName) {
case 'memory':
this.runningGame = new Memory(this, this.settings);
//this.runningGame = new Memory(this, this.settings);
break;
case 'pong':
this.runningGame = new Pong(this, this.settings);
//this.runningGame = new Pong(this, this.settings);
break;
case 'global-draw':
this.runningGame = new GlobalDraw(this, this.settings);
//this.runningGame = new GlobalDraw(this, this.settings);
break;
case 'chainreact':
this.runningGame = new Chainreact(this, this.settings);
//this.runningGame = new Chainreact(this, this.settings);
break;
}
}

@ -8,6 +8,7 @@
"declaration": true,
"declarationMap": true,
"outDir": "./out",
"moduleResolution": "Node16"
},
"include": [
"./src"

Loading…
Cancel
Save