Kopie van https://gitlab.com/studieverenigingvia/ict/centurion met een paar aanpassingen
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.1 KiB
120 lines
3.1 KiB
import {Socket} from "socket.io";
|
|
|
|
import User from './User'
|
|
import Room from './Room'
|
|
import {getCurrentTime, randomInt} from "./util";
|
|
|
|
export default class Service {
|
|
private roomIdToRooms = new Map<number, Room>();
|
|
private socketsToUsers = new Map<string, User>();
|
|
|
|
onSocketConnect(socket: Socket) {
|
|
let user = new User(socket);
|
|
this.socketsToUsers.set(socket.id, user);
|
|
}
|
|
|
|
onSocketDisconnect(socket: Socket) {
|
|
let user = this.getUser(socket);
|
|
|
|
if (user.room != null) {
|
|
user.room.leave(user);
|
|
}
|
|
|
|
this.deleteEmptyRooms();
|
|
|
|
user.onDisconnect();
|
|
}
|
|
|
|
onTimeSync(socket: Socket, requestId: number, clientTime: number) {
|
|
let user = this.getUser(socket);
|
|
|
|
let now = getCurrentTime();
|
|
user.emit('time_sync', {
|
|
'requestId': requestId,
|
|
'clientDiff': now - clientTime,
|
|
'serverTime': now
|
|
})
|
|
}
|
|
|
|
onRequestStart(socket: Socket) {
|
|
let user = this.getUser(socket);
|
|
|
|
if (user.room?.getLeader() == user) {
|
|
user.room!!.start();
|
|
}
|
|
}
|
|
|
|
onRequestJoin(socket: Socket, roomId: number): boolean {
|
|
let user = this.getUser(socket);
|
|
if (!this.roomIdToRooms.has(roomId)) return false;
|
|
if (user.room && user.room.id == roomId) return false;
|
|
|
|
if (user.room) {
|
|
user.room.leave(user);
|
|
this.deleteEmptyRooms();
|
|
}
|
|
|
|
let room = this.roomIdToRooms.get(roomId)!!;
|
|
room.join(user);
|
|
return true;
|
|
}
|
|
|
|
onRequestJoinRandom(socket: Socket) {
|
|
let user = this.getUser(socket);
|
|
|
|
if (user.room) {
|
|
user.room.leave(user);
|
|
this.deleteEmptyRooms();
|
|
}
|
|
|
|
const room = this.createRandomRoom();
|
|
if (!room) throw Error('Too many rooms active');
|
|
room.join(user);
|
|
}
|
|
|
|
hasRoomId(roomId: number): boolean {
|
|
return this.roomIdToRooms.has(roomId);
|
|
}
|
|
|
|
private getUser(socket: Socket): User {
|
|
let user = this.socketsToUsers.get(socket.id);
|
|
if (!user) {
|
|
throw new Error('User not found');
|
|
}
|
|
return user;
|
|
}
|
|
|
|
private deleteEmptyRooms() {
|
|
for (let room of this.roomIdToRooms.values()) {
|
|
if (room.users.length == 0) {
|
|
this.deleteRoom(room);
|
|
}
|
|
}
|
|
}
|
|
|
|
private createRandomRoom(): Room | null {
|
|
let tries = 0;
|
|
while (tries++ < 1000) {
|
|
const randomId = randomInt(100, Math.max(1000, this.roomIdToRooms.size * 2));
|
|
if (this.roomIdToRooms.has(randomId)) continue;
|
|
|
|
return this.createRoomWithId(randomId);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private createRoomWithId(roomId: number): Room {
|
|
if (this.roomIdToRooms.has(roomId)) {
|
|
throw new Error('A room with the given id already exists');
|
|
}
|
|
|
|
let room = new Room(roomId);
|
|
this.roomIdToRooms.set(roomId, room);
|
|
return room;
|
|
}
|
|
|
|
private deleteRoom(room: Room) {
|
|
this.roomIdToRooms.get(room.id)!!.onBeforeDelete();
|
|
this.roomIdToRooms.delete(room.id)
|
|
}
|
|
}
|
|
|