workadventure/back/src/RoomManager.ts

235 lines
9.6 KiB
TypeScript
Raw Normal View History

2021-06-24 10:09:10 +02:00
import { IRoomManagerServer } from "./Messages/generated/messages_grpc_pb";
import {
2020-12-11 12:23:50 +01:00
AdminGlobalMessage,
AdminMessage,
AdminPusherToBackMessage,
AdminRoomMessage,
2021-01-17 22:44:22 +01:00
BanMessage,
EmotePromptMessage,
2021-01-17 03:07:46 +01:00
EmptyMessage,
2020-12-11 12:23:50 +01:00
ItemEventMessage,
JoinRoomMessage,
PlayGlobalMessage,
PusherToBackMessage,
2021-06-24 10:09:10 +02:00
QueryJitsiJwtMessage,
RefreshRoomPromptMessage,
2020-12-11 12:23:50 +01:00
ServerToAdminClientMessage,
ServerToClientMessage,
SilentMessage,
UserMovesMessage,
2021-06-24 10:09:10 +02:00
WebRtcSignalToServerMessage,
WorldFullWarningToRoomMessage,
ZoneMessage,
} from "./Messages/generated/messages_pb";
2021-06-24 10:09:10 +02:00
import { sendUnaryData, ServerDuplexStream, ServerUnaryCall, ServerWritableStream } from "grpc";
import { socketManager } from "./Services/SocketManager";
import { emitError } from "./Services/MessageHelpers";
import { User, UserSocket } from "./Model/User";
import { GameRoom } from "./Model/GameRoom";
import Debug from "debug";
2021-06-24 10:09:10 +02:00
import { Admin } from "./Model/Admin";
2021-06-24 10:09:10 +02:00
const debug = Debug("roommanager");
export type AdminSocket = ServerDuplexStream<AdminPusherToBackMessage, ServerToAdminClientMessage>;
export type ZoneSocket = ServerWritableStream<ZoneMessage, ServerToClientMessage>;
const roomManager: IRoomManagerServer = {
joinRoom: (call: UserSocket): void => {
2021-06-24 10:09:10 +02:00
console.log("joinRoom called");
2021-06-24 10:09:10 +02:00
let room: GameRoom | null = null;
let user: User | null = null;
2021-06-24 10:09:10 +02:00
call.on("data", (message: PusherToBackMessage) => {
try {
if (room === null || user === null) {
if (message.hasJoinroommessage()) {
2021-06-24 10:09:10 +02:00
socketManager
.handleJoinRoom(call, message.getJoinroommessage() as JoinRoomMessage)
.then(({ room: gameRoom, user: myUser }) => {
if (call.writable) {
room = gameRoom;
user = myUser;
} else {
//Connexion may have been closed before the init was finished, so we have to manually disconnect the user.
socketManager.leaveRoom(gameRoom, myUser);
}
});
} else {
2021-06-24 10:09:10 +02:00
throw new Error("The first message sent MUST be of type JoinRoomMessage");
}
} else {
if (message.hasJoinroommessage()) {
2021-06-24 10:09:10 +02:00
throw new Error("Cannot call JoinRoomMessage twice!");
} else if (message.hasUsermovesmessage()) {
2021-06-24 10:09:10 +02:00
socketManager.handleUserMovesMessage(
room,
user,
message.getUsermovesmessage() as UserMovesMessage
);
} else if (message.hasSilentmessage()) {
socketManager.handleSilentMessage(room, user, message.getSilentmessage() as SilentMessage);
} else if (message.hasItemeventmessage()) {
socketManager.handleItemEvent(room, user, message.getItemeventmessage() as ItemEventMessage);
} else if (message.hasWebrtcsignaltoservermessage()) {
2021-06-24 10:09:10 +02:00
socketManager.emitVideo(
room,
user,
message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage
);
} else if (message.hasWebrtcscreensharingsignaltoservermessage()) {
2021-06-24 10:09:10 +02:00
socketManager.emitScreenSharing(
room,
user,
message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage
);
} else if (message.hasPlayglobalmessage()) {
socketManager.emitPlayGlobalMessage(room, message.getPlayglobalmessage() as PlayGlobalMessage);
2021-06-24 10:09:10 +02:00
} else if (message.hasQueryjitsijwtmessage()) {
socketManager.handleQueryJitsiJwtMessage(
user,
message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage
);
} else if (message.hasEmotepromptmessage()) {
socketManager.handleEmoteEventMessage(
room,
user,
message.getEmotepromptmessage() as EmotePromptMessage
);
} else if (message.hasSendusermessage()) {
2021-01-17 03:07:46 +01:00
const sendUserMessage = message.getSendusermessage();
2021-06-24 10:09:10 +02:00
if (sendUserMessage !== undefined) {
2021-01-17 03:07:46 +01:00
socketManager.handlerSendUserMessage(user, sendUserMessage);
}
2021-06-24 10:09:10 +02:00
} else if (message.hasBanusermessage()) {
2021-01-17 03:07:46 +01:00
const banUserMessage = message.getBanusermessage();
2021-06-24 10:09:10 +02:00
if (banUserMessage !== undefined) {
2021-01-17 03:07:46 +01:00
socketManager.handlerBanUserMessage(room, user, banUserMessage);
}
} else {
2021-06-24 10:09:10 +02:00
throw new Error("Unhandled message type");
}
}
} catch (e) {
emitError(call, e);
call.end();
}
});
2021-06-24 10:09:10 +02:00
call.on("end", () => {
debug("joinRoom ended");
if (user !== null && room !== null) {
socketManager.leaveRoom(room, user);
}
call.end();
room = null;
user = null;
});
2021-06-24 10:09:10 +02:00
call.on("error", (err: Error) => {
console.error("An error occurred in joinRoom stream:", err);
});
},
listenZone(call: ZoneSocket): void {
2021-06-24 10:09:10 +02:00
debug("listenZone called");
const zoneMessage = call.request;
socketManager.addZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY());
2021-06-24 10:09:10 +02:00
call.on("cancelled", () => {
debug("listenZone cancelled");
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY());
call.end();
2021-06-24 10:09:10 +02:00
});
call.on("close", () => {
debug("listenZone connection closed");
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY());
2021-06-24 10:09:10 +02:00
}).on("error", (e) => {
console.error("An error occurred in listenZone stream:", e);
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY());
call.end();
});
},
adminRoom(call: AdminSocket): void {
2021-06-24 10:09:10 +02:00
console.log("adminRoom called");
const admin = new Admin(call);
2021-06-24 10:09:10 +02:00
let room: GameRoom | null = null;
2021-06-24 10:09:10 +02:00
call.on("data", (message: AdminPusherToBackMessage) => {
try {
if (room === null) {
if (message.hasSubscribetoroom()) {
const roomId = message.getSubscribetoroom();
socketManager.handleJoinAdminRoom(admin, roomId).then((gameRoom: GameRoom) => {
room = gameRoom;
});
} else {
2021-06-24 10:09:10 +02:00
throw new Error("The first message sent MUST be of type JoinRoomMessage");
}
}
} catch (e) {
emitError(call, e);
call.end();
}
});
2021-06-24 10:09:10 +02:00
call.on("end", () => {
debug("joinRoom ended");
if (room !== null) {
socketManager.leaveAdminRoom(room, admin);
}
call.end();
room = null;
});
2021-06-24 10:09:10 +02:00
call.on("error", (err: Error) => {
console.error("An error occurred in joinAdminRoom stream:", err);
});
},
2020-12-11 12:23:50 +01:00
sendAdminMessage(call: ServerUnaryCall<AdminMessage>, callback: sendUnaryData<EmptyMessage>): void {
2021-06-24 10:09:10 +02:00
socketManager.sendAdminMessage(
call.request.getRoomid(),
call.request.getRecipientuuid(),
call.request.getMessage()
);
2020-12-11 12:23:50 +01:00
callback(null, new EmptyMessage());
},
sendGlobalAdminMessage(call: ServerUnaryCall<AdminGlobalMessage>, callback: sendUnaryData<EmptyMessage>): void {
2021-06-24 10:09:10 +02:00
throw new Error("Not implemented yet");
2020-12-11 12:23:50 +01:00
// TODO
callback(null, new EmptyMessage());
},
ban(call: ServerUnaryCall<BanMessage>, callback: sendUnaryData<EmptyMessage>): void {
2021-01-18 15:07:40 +01:00
// FIXME Work in progress
2021-03-11 01:25:36 +01:00
socketManager.banUser(call.request.getRoomid(), call.request.getRecipientuuid(), call.request.getMessage());
2020-12-11 12:23:50 +01:00
callback(null, new EmptyMessage());
},
sendAdminMessageToRoom(call: ServerUnaryCall<AdminRoomMessage>, callback: sendUnaryData<EmptyMessage>): void {
socketManager.sendAdminRoomMessage(call.request.getRoomid(), call.request.getMessage());
callback(null, new EmptyMessage());
},
2021-06-24 10:09:10 +02:00
sendWorldFullWarningToRoom(
call: ServerUnaryCall<WorldFullWarningToRoomMessage>,
callback: sendUnaryData<EmptyMessage>
): void {
socketManager.dispatchWorlFullWarning(call.request.getRoomid());
callback(null, new EmptyMessage());
},
2021-06-24 10:09:10 +02:00
sendRefreshRoomPrompt(
call: ServerUnaryCall<RefreshRoomPromptMessage>,
callback: sendUnaryData<EmptyMessage>
): void {
socketManager.dispatchRoomRefresh(call.request.getRoomid());
callback(null, new EmptyMessage());
},
};
2021-06-24 10:09:10 +02:00
export { roomManager };