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.
163 lines
3.6 KiB
163 lines
3.6 KiB
import { Socket } from "socket.io";
|
|
|
|
import User from "./User";
|
|
import Room, { RoomOptions } from "./Room";
|
|
import { getCurrentTime } from "./util";
|
|
|
|
export default class Service {
|
|
private roomIdToRooms = new Map<number, Room>();
|
|
private socketsToUsers = new Map<string, User>();
|
|
|
|
get rooms(): Room[] {
|
|
const rooms = [];
|
|
for (const [, room] of this.roomIdToRooms) {
|
|
rooms.push(room);
|
|
}
|
|
|
|
return rooms;
|
|
}
|
|
|
|
onSocketConnect(socket: Socket) {
|
|
const user = new User(socket);
|
|
this.socketsToUsers.set(socket.id, user);
|
|
user.sync();
|
|
}
|
|
|
|
async onSocketDisconnect(socket: Socket) {
|
|
const user = this.getUser(socket);
|
|
|
|
if (user.room != null) {
|
|
await user.room.leave(user);
|
|
}
|
|
|
|
this.deleteEmptyRooms();
|
|
}
|
|
|
|
onTimeSync(socket: Socket, requestId: number, clientTime: number) {
|
|
const user = this.getUser(socket);
|
|
|
|
const now = getCurrentTime();
|
|
user.emit("time_sync", {
|
|
requestId: requestId,
|
|
clientDiff: now - clientTime,
|
|
serverTime: now,
|
|
});
|
|
}
|
|
|
|
onSetRoomOptions(socket: Socket, options: RoomOptions) {
|
|
const user = this.getUser(socket);
|
|
|
|
if (user.room?.getLeader() == user) {
|
|
user.room.setOptions(options);
|
|
}
|
|
}
|
|
|
|
onRequestStart(socket: Socket) {
|
|
const user = this.getUser(socket);
|
|
|
|
if (user.room?.getLeader() === user) {
|
|
user.room.start();
|
|
user.room.sync();
|
|
}
|
|
}
|
|
|
|
async onRequestJoin(socket: Socket, roomId: number) {
|
|
const user = this.getUser(socket);
|
|
if (user.room && user.room.id == roomId) return false;
|
|
|
|
if (user.room) {
|
|
await user.room.leave(user);
|
|
this.deleteEmptyRooms();
|
|
}
|
|
|
|
if (!this.roomIdToRooms.has(roomId)) {
|
|
this.createRoomWithId(roomId);
|
|
}
|
|
|
|
const room = this.roomIdToRooms.get(roomId);
|
|
if (!room) {
|
|
return false;
|
|
}
|
|
|
|
await room.join(user);
|
|
|
|
return true;
|
|
}
|
|
|
|
onRequestSetReady(socket: Socket) {
|
|
const user = this.getUser(socket);
|
|
if (!user.room || user.readyToParticipate) return;
|
|
user.readyToParticipate = true;
|
|
user.room.sync();
|
|
}
|
|
|
|
async onRequestJoinRandom(socket: Socket) {
|
|
const user = this.getUser(socket);
|
|
|
|
if (user.room) {
|
|
await user.room.leave(user);
|
|
this.deleteEmptyRooms();
|
|
}
|
|
|
|
const room = this.createRandomRoom();
|
|
if (!room) throw Error("Too many rooms active");
|
|
await room.join(user);
|
|
}
|
|
|
|
hasRoomId(roomId: number): boolean {
|
|
return this.roomIdToRooms.has(roomId);
|
|
}
|
|
|
|
submitTickerMessage(socket: Socket, message: string) {
|
|
const user = this.getUser(socket);
|
|
|
|
if (!user.room) {
|
|
throw new Error("User has no room");
|
|
}
|
|
|
|
user.room.submitTickerMessage(user, message);
|
|
}
|
|
|
|
private getUser(socket: Socket): User {
|
|
const user = this.socketsToUsers.get(socket.id);
|
|
if (!user) {
|
|
throw new Error("User not found");
|
|
}
|
|
return user;
|
|
}
|
|
|
|
private deleteEmptyRooms() {
|
|
for (const room of this.roomIdToRooms.values()) {
|
|
if (room.users.length == 0) {
|
|
this.deleteRoom(room);
|
|
}
|
|
}
|
|
}
|
|
|
|
private createRandomRoom(): Room | null {
|
|
let tries = 0;
|
|
let i = 1;
|
|
while (tries++ < 1000) {
|
|
if (this.roomIdToRooms.has(i)) {
|
|
i++;
|
|
} else {
|
|
return this.createRoomWithId(i);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private createRoomWithId(roomId: number): Room {
|
|
if (this.roomIdToRooms.has(roomId)) {
|
|
throw new Error("A room with the given id already exists");
|
|
}
|
|
|
|
const room = new Room(roomId);
|
|
this.roomIdToRooms.set(roomId, room);
|
|
return room;
|
|
}
|
|
|
|
private deleteRoom(room: Room) {
|
|
this.roomIdToRooms.delete(room.id);
|
|
}
|
|
}
|
|
|