From f4b6cd4cdf09f96cfc733a59b8ee30015a851bee Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Sun, 3 Apr 2022 19:05:41 +0300 Subject: [PATCH] some clean-up --- src/client/canvas.ts | 2 +- src/client/picker.ts | 10 +-- src/client/scss/index.scss | 2 +- src/{server => common}/types/user.ts | 0 src/server/express.d.ts | 9 --- src/server/index.ts | 82 ++---------------------- src/server/object/canvas.ts | 10 ++- src/server/object/game.ts | 93 ++++++++++++++++++++++++++++ src/server/object/history.ts | 2 +- tsconfig.json | 3 +- 10 files changed, 115 insertions(+), 98 deletions(-) rename src/{server => common}/types/user.ts (100%) delete mode 100644 src/server/express.d.ts create mode 100644 src/server/object/game.ts diff --git a/src/client/canvas.ts b/src/client/canvas.ts index 5e8de91..36feaf2 100644 --- a/src/client/canvas.ts +++ b/src/client/canvas.ts @@ -1,7 +1,7 @@ import { convertHex } from '../common/convert'; import { clamp, debounce } from '../common/helper'; import { CanvasRecord, Placement } from '../common/types/canvas'; -import { IcyNetUser } from '../server/types/user'; +import { IcyNetUser } from '../common/types/user'; import { Picker } from './picker'; import { $ } from './utils/dom'; diff --git a/src/client/picker.ts b/src/client/picker.ts index 987afaa..11f3a1f 100644 --- a/src/client/picker.ts +++ b/src/client/picker.ts @@ -1,5 +1,5 @@ import { hexToString, storeHex } from '../common/convert'; -import { IcyNetUser } from '../server/types/user'; +import { IcyNetUser } from '../common/types/user'; import { $ } from './utils/dom'; export class Picker { @@ -72,7 +72,7 @@ export class Picker { }); this._pickbtn.addEventListener('click', () => { - if (this._pickerColor) { + if (this._pickerColor !== null) { this._setColor(this._pickerColor); this._storeColor(this._pickerColor); } @@ -104,17 +104,17 @@ export class Picker { this._pickbtn.classList.add('pickable'); this._pickbtn.style.setProperty('--pick-color', hexToString(pickColor)); } else if (this._pickerColor !== null && pickColor === null) { - console.log('aa'); this._pickbtn.setAttribute('disabled', 'true'); this._pickbtn.classList.remove('pickable'); this._pickbtn.style.removeProperty('--pick-color'); } + this._pickerColor = pickColor; } private _setColor(color: number): void { - this._color = color; - this._colorInput.value = hexToString(color); + this._color = color || 0; + this._colorInput.value = hexToString(color || 0); } private _drawColorList(): void { diff --git a/src/client/scss/index.scss b/src/client/scss/index.scss index d49a749..77ccfe2 100644 --- a/src/client/scss/index.scss +++ b/src/client/scss/index.scss @@ -119,7 +119,7 @@ body { text-align: center; background-color: rgba(221, 221, 221, 0.404); - *.btn, input, a { + .btn, input, a { pointer-events: all; } diff --git a/src/server/types/user.ts b/src/common/types/user.ts similarity index 100% rename from src/server/types/user.ts rename to src/common/types/user.ts diff --git a/src/server/express.d.ts b/src/server/express.d.ts deleted file mode 100644 index e6afe4c..0000000 --- a/src/server/express.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { IcyNetUser } from './types/user'; - -declare global { - namespace Express { - export interface Request { - user: IcyNetUser; - } - } -} diff --git a/src/server/index.ts b/src/server/index.ts index 732fb88..a730723 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -8,11 +8,12 @@ import connectRedis from 'connect-redis'; import http from 'http'; import { join } from 'path'; import { Server, Socket } from 'socket.io'; -import { IcyNetUser } from './types/user'; +import { IcyNetUser } from '../common/types/user'; import { Canvas } from './object/canvas'; import { CanvasRecord, Placement } from '../common/types/canvas'; import { config } from './config'; +import { Game } from './object/game'; const RedisStore = connectRedis(session); const redisClient = config.redis?.enabled ? redis.createClient() : undefined; @@ -109,84 +110,9 @@ app.use(express.static(join(__dirname, '..', 'public'))); /// -const canvas = new Canvas(config.game.boardSize); -const connections: Socket[] = []; -const changes: CanvasRecord[] = []; +const game = new Game(io, sessionMiddleware); -const dummyUser: IcyNetUser = { - id: 0, - username: 'placer', - display_name: 'placer', - uuid: 'placer', - accessToken: 'placer', -}; - -io.use((socket, next) => - sessionMiddleware(socket.request as any, {} as any, next as any), -); -io.on('connection', (socket) => { - const session = (socket.request as any).session; - const user = - process.env.SKIP_LOGIN === 'true' - ? dummyUser - : (session?.passport?.user as IcyNetUser); - - connections.push(socket); - - socket.emit( - 'me', - user - ? { - username: user.username, - display_name: user.display_name, - } - : null, - ); - - socket.emit('plane', { - size: canvas.size, - canvas: Object.values(canvas.getFullPlane()), - }); - - socket.on('color', ({ c, x, y, t }: Placement) => { - if (!user || c > 0xffffff || c < 0 || c === null) { - return; - } - - canvas.setPixelAt(c, x, y, user.username); - socket.emit('colorack', { c, x, y, t }); - }); - - socket.on('getplacer', ({ x, y, reqt }) => { - canvas.history - .getPlacerAt(x, y) - .then((placer) => { - if (placer) { - socket.emit('placerat', { ...placer, reqt }); - } - }) - .catch((e) => console.error(e)); - }); - - socket.on('disconnect', () => { - connections.splice(connections.indexOf(socket), 1); - }); -}); - -canvas.registerChangeHandler((record) => { - changes.push(record); -}); - -setInterval(() => { - if (changes.length && connections.length) { - connections.forEach((socket) => socket.emit('changes', changes)); - changes.length = 0; - } -}, 1000); - -/// - -canvas.initialize().then(() => +game.initialize().then(() => server.listen(config.server.port, config.server.bind, () => { console.log(`Listening at http://localhost:${config.server.port}/`); }), diff --git a/src/server/object/canvas.ts b/src/server/object/canvas.ts index b7fae32..941f7f9 100644 --- a/src/server/object/canvas.ts +++ b/src/server/object/canvas.ts @@ -2,13 +2,19 @@ import { storeHex, to1D } from '../../common/convert'; import { CanvasRecord } from '../../common/types/canvas'; import { History } from './history'; import { Imager } from './imager'; +import { config } from '../config'; export class Canvas { private _fn?: (change: CanvasRecord) => void; private _canvas!: Uint32Array; - private _imager = new Imager(this.size); + private _imager = new Imager( + this.size, + config.persistence?.filename, + config.persistence?.debounce, + config.persistence?.forcedInterval, + ); - public history = new History(); + public history = new History(config.persistence?.placeStorage); constructor(public size = 1000) {} diff --git a/src/server/object/game.ts b/src/server/object/game.ts new file mode 100644 index 0000000..cb122b7 --- /dev/null +++ b/src/server/object/game.ts @@ -0,0 +1,93 @@ +import { Server, Socket } from 'socket.io'; +import { Canvas } from './canvas'; +import { config } from '../config'; +import { RequestHandler } from 'express'; +import { CanvasRecord, Placement } from '../../common/types/canvas'; +import { IcyNetUser } from '../../common/types/user'; + +const PLACEHOLDER_USER: IcyNetUser = { + id: 0, + username: 'placer', + display_name: 'placer', + uuid: 'placer', + accessToken: 'placer', +}; + +export class Game { + private _canvas = new Canvas(config.game.boardSize); + private _connections: Socket[] = []; + private _changes: CanvasRecord[] = []; + private _interval: any; + + constructor(private io: Server, private session: RequestHandler) {} + + async initialize() { + await this._canvas.initialize(); + + this.io.use((socket, next) => + this.session(socket.request as any, {} as any, next as any), + ); + + this.io.on('connection', (socket) => { + const session = (socket.request as any).session; + const user = + process.env.SKIP_LOGIN === 'true' + ? PLACEHOLDER_USER + : (session?.passport?.user as IcyNetUser); + + this._connections.push(socket); + + socket.emit( + 'me', + user + ? { + username: user.username, + display_name: user.display_name, + } + : null, + ); + + socket.emit('plane', { + size: this._canvas.size, + canvas: Object.values(this._canvas.getFullPlane()), + }); + + socket.on('color', ({ c, x, y, t }: Placement) => { + if (!user || c > 0xffffff || c < 0 || c === null) { + return; + } + + this._canvas.setPixelAt(c, x, y, user.username); + socket.emit('colorack', { c, x, y, t }); + }); + + socket.on('getplacer', ({ x, y, reqt }) => { + this._canvas.history + .getPlacerAt(x, y) + .then((placer) => { + if (placer) { + socket.emit('placerat', { ...placer, reqt }); + } + }) + .catch((e) => console.error(e)); + }); + + socket.on('disconnect', () => { + this._connections.splice(this._connections.indexOf(socket), 1); + }); + }); + + this._canvas.registerChangeHandler((record) => { + this._changes.push(record); + }); + + this._interval = setInterval(() => { + if (this._changes.length && this._connections.length) { + this._connections.forEach((socket) => + socket.emit('changes', this._changes), + ); + this._changes.length = 0; + } + }, 1000); + } +} diff --git a/src/server/object/history.ts b/src/server/object/history.ts index 5e0466f..12f8d73 100644 --- a/src/server/object/history.ts +++ b/src/server/object/history.ts @@ -19,7 +19,7 @@ export class History { } async insert(record: CanvasRecord): Promise { - const color = record.color ? record.color : 0; + const color = record.color || 0; await this.db.run( `INSERT INTO Placement (user, x, y, ts, color) VALUES (?,?,?,?,?)`, record.user, diff --git a/tsconfig.json b/tsconfig.json index da14ebb..e9e3d86 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "include": [ - "src/server/**/*.ts" + "src/server/**/*.ts", + "src/common/types/user.ts" ], "exclude": [ "src/client/**/*.ts"