icydraw/src/server/object/game.ts

94 lines
2.5 KiB
TypeScript

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);
}
}