import { Server, Socket } from 'socket.io'; import { config } from '../config'; import { RequestHandler } from 'express'; import { IcyNetUser } from '../../common/types/user'; const PLACEHOLDER_USER = (socket: Socket): IcyNetUser => { const randomName = `player-${socket.id.substring(0, 8)}`; return { id: Math.random() * 1000 + 1000, username: randomName, display_name: randomName, uuid: socket.id, accessToken: 'player', }; }; export class Game { private _connections: Socket[] = []; constructor(private io: Server, private session: RequestHandler) {} private mapPlayer(user: IcyNetUser): any { return { id: user.id, username: user.username, display_name: user.display_name, }; } async 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(socket) : (session?.passport?.user as IcyNetUser); const publicUserInfo = user ? this.mapPlayer(user) : null; this._connections.push(socket); socket.data.user = user; socket.data.playerinfo = { velocity: [0, 0, 0], angular: [0, 0, 0], position: [0, 0, 0], rotation: [0, 0, 0], animState: 0, }; socket.emit('me', publicUserInfo); socket.emit( 'players', this._connections.map((conn) => ({ ...this.mapPlayer(conn.data.user), ...conn.data.playerinfo, })), ); socket.broadcast.emit('playerjoin', publicUserInfo); socket.on('disconnect', () => { this._connections.splice(this._connections.indexOf(socket), 1); this.io.emit('playerleave', publicUserInfo); }); socket.on('move', (packet) => { socket.data.playerinfo = { ...socket.data.playerinfo, ...packet, }; socket.broadcast.emit('playerupdate', { id: user.id, ...packet, }); }); socket.on('chat-send', (raw) => { const message = raw.trim().substring(0, 260); this.io.emit('chat', { sender: publicUserInfo, message }); }); }); } }