First version with variables that actually work
This commit is contained in:
parent
5116b82e77
commit
e65e8b2097
11 changed files with 250 additions and 50 deletions
|
@ -7,9 +7,14 @@ import { PositionNotifier } from "./PositionNotifier";
|
|||
import { Movable } from "_Model/Movable";
|
||||
import { extractDataFromPrivateRoomId, extractRoomSlugPublicRoomId, isRoomAnonymous } from "./RoomIdentifier";
|
||||
import { arrayIntersect } from "../Services/ArrayHelper";
|
||||
import { EmoteEventMessage, JoinRoomMessage } from "../Messages/generated/messages_pb";
|
||||
import {
|
||||
BatchToPusherMessage,
|
||||
BatchToPusherRoomMessage,
|
||||
EmoteEventMessage,
|
||||
JoinRoomMessage, SubToPusherRoomMessage, VariableMessage
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
|
||||
import { ZoneSocket } from "src/RoomManager";
|
||||
import {RoomSocket, ZoneSocket} from "src/RoomManager";
|
||||
import { Admin } from "../Model/Admin";
|
||||
|
||||
export type ConnectCallback = (user: User, group: Group) => void;
|
||||
|
@ -35,7 +40,7 @@ export class GameRoom {
|
|||
private readonly disconnectCallback: DisconnectCallback;
|
||||
|
||||
private itemsState = new Map<number, unknown>();
|
||||
private variables = new Map<string, string>();
|
||||
public readonly variables = new Map<string, string>();
|
||||
|
||||
private readonly positionNotifier: PositionNotifier;
|
||||
public readonly roomId: string;
|
||||
|
@ -45,6 +50,8 @@ export class GameRoom {
|
|||
private versionNumber: number = 1;
|
||||
private nextUserId: number = 1;
|
||||
|
||||
private roomListeners: Set<RoomSocket> = new Set<RoomSocket>();
|
||||
|
||||
constructor(
|
||||
roomId: string,
|
||||
connectCallback: ConnectCallback,
|
||||
|
@ -312,6 +319,22 @@ export class GameRoom {
|
|||
|
||||
public setVariable(name: string, value: string): void {
|
||||
this.variables.set(name, value);
|
||||
|
||||
// TODO: should we batch those every 100ms?
|
||||
const variableMessage = new VariableMessage();
|
||||
variableMessage.setName(name);
|
||||
variableMessage.setValue(value);
|
||||
|
||||
const subMessage = new SubToPusherRoomMessage();
|
||||
subMessage.setVariablemessage(variableMessage);
|
||||
|
||||
const batchMessage = new BatchToPusherRoomMessage();
|
||||
batchMessage.addPayload(subMessage);
|
||||
|
||||
// Dispatch the message on the room listeners
|
||||
for (const socket of this.roomListeners) {
|
||||
socket.write(batchMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public addZoneListener(call: ZoneSocket, x: number, y: number): Set<Movable> {
|
||||
|
@ -343,4 +366,12 @@ export class GameRoom {
|
|||
public emitEmoteEvent(user: User, emoteEventMessage: EmoteEventMessage) {
|
||||
this.positionNotifier.emitEmoteEvent(user, emoteEventMessage);
|
||||
}
|
||||
|
||||
public addRoomListener(socket: RoomSocket) {
|
||||
this.roomListeners.add(socket);
|
||||
}
|
||||
|
||||
public removeRoomListener(socket: RoomSocket) {
|
||||
this.roomListeners.delete(socket);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
AdminMessage,
|
||||
AdminPusherToBackMessage,
|
||||
AdminRoomMessage,
|
||||
BanMessage,
|
||||
BanMessage, BatchToPusherRoomMessage,
|
||||
EmotePromptMessage,
|
||||
EmptyMessage,
|
||||
ItemEventMessage,
|
||||
|
@ -12,7 +12,7 @@ import {
|
|||
PlayGlobalMessage,
|
||||
PusherToBackMessage,
|
||||
QueryJitsiJwtMessage,
|
||||
RefreshRoomPromptMessage,
|
||||
RefreshRoomPromptMessage, RoomMessage,
|
||||
ServerToAdminClientMessage,
|
||||
ServerToClientMessage,
|
||||
SilentMessage,
|
||||
|
@ -33,6 +33,7 @@ const debug = Debug("roommanager");
|
|||
|
||||
export type AdminSocket = ServerDuplexStream<AdminPusherToBackMessage, ServerToAdminClientMessage>;
|
||||
export type ZoneSocket = ServerWritableStream<ZoneMessage, ServerToClientMessage>;
|
||||
export type RoomSocket = ServerWritableStream<RoomMessage, BatchToPusherRoomMessage>;
|
||||
|
||||
const roomManager: IRoomManagerServer = {
|
||||
joinRoom: (call: UserSocket): void => {
|
||||
|
@ -156,6 +157,29 @@ const roomManager: IRoomManagerServer = {
|
|||
});
|
||||
},
|
||||
|
||||
listenRoom(call: RoomSocket): void {
|
||||
debug("listenRoom called");
|
||||
const roomMessage = call.request;
|
||||
|
||||
socketManager.addRoomListener(call, roomMessage.getRoomid());
|
||||
|
||||
call.on("cancelled", () => {
|
||||
debug("listenRoom cancelled");
|
||||
socketManager.removeRoomListener(call, roomMessage.getRoomid());
|
||||
call.end();
|
||||
});
|
||||
|
||||
call.on("close", () => {
|
||||
debug("listenRoom connection closed");
|
||||
socketManager.removeRoomListener(call, roomMessage.getRoomid());
|
||||
}).on("error", (e) => {
|
||||
console.error("An error occurred in listenRoom stream:", e);
|
||||
socketManager.removeRoomListener(call, roomMessage.getRoomid());
|
||||
call.end();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
adminRoom(call: AdminSocket): void {
|
||||
console.log("adminRoom called");
|
||||
|
||||
|
@ -230,7 +254,7 @@ const roomManager: IRoomManagerServer = {
|
|||
): void {
|
||||
socketManager.dispatchRoomRefresh(call.request.getRoomid());
|
||||
callback(null, new EmptyMessage());
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export { roomManager };
|
||||
|
|
|
@ -30,7 +30,7 @@ import {
|
|||
BanUserMessage,
|
||||
RefreshRoomMessage,
|
||||
EmotePromptMessage,
|
||||
VariableMessage,
|
||||
VariableMessage, BatchToPusherRoomMessage, SubToPusherRoomMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { User, UserSocket } from "../Model/User";
|
||||
import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
|
||||
|
@ -49,7 +49,7 @@ import Jwt from "jsonwebtoken";
|
|||
import { JITSI_URL } from "../Enum/EnvironmentVariable";
|
||||
import { clientEventsEmitter } from "./ClientEventsEmitter";
|
||||
import { gaugeManager } from "./GaugeManager";
|
||||
import { ZoneSocket } from "../RoomManager";
|
||||
import {RoomSocket, ZoneSocket} from "../RoomManager";
|
||||
import { Zone } from "_Model/Zone";
|
||||
import Debug from "debug";
|
||||
import { Admin } from "_Model/Admin";
|
||||
|
@ -66,7 +66,9 @@ function emitZoneMessage(subMessage: SubToPusherMessage, socket: ZoneSocket): vo
|
|||
}
|
||||
|
||||
export class SocketManager {
|
||||
private rooms: Map<string, GameRoom> = new Map<string, GameRoom>();
|
||||
private rooms = new Map<string, GameRoom>();
|
||||
// List of rooms in process of loading.
|
||||
private roomsPromises = new Map<string, PromiseLike<GameRoom>>();
|
||||
|
||||
constructor() {
|
||||
clientEventsEmitter.registerToClientJoin((clientUUid: string, roomId: string) => {
|
||||
|
@ -102,6 +104,14 @@ export class SocketManager {
|
|||
roomJoinedMessage.addItem(itemStateMessage);
|
||||
}
|
||||
|
||||
for (const [name, value] of room.variables.entries()) {
|
||||
const variableMessage = new VariableMessage();
|
||||
variableMessage.setName(name);
|
||||
variableMessage.setValue(value);
|
||||
|
||||
roomJoinedMessage.addVariable(variableMessage);
|
||||
}
|
||||
|
||||
roomJoinedMessage.setCurrentuserid(user.id);
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
|
@ -186,23 +196,10 @@ export class SocketManager {
|
|||
}
|
||||
|
||||
handleVariableEvent(room: GameRoom, user: User, variableMessage: VariableMessage) {
|
||||
const itemEvent = ProtobufUtils.toItemEvent(itemEventMessage);
|
||||
|
||||
try {
|
||||
// TODO: DISPATCH ON NEW ROOM CHANNEL
|
||||
|
||||
const subMessage = new SubMessage();
|
||||
subMessage.setItemeventmessage(itemEventMessage);
|
||||
|
||||
// Let's send the event without using the SocketIO room.
|
||||
// TODO: move this in the GameRoom class.
|
||||
for (const user of room.getUsers().values()) {
|
||||
user.emitInBatch(subMessage);
|
||||
}
|
||||
|
||||
room.setVariable(variableMessage.getName(), variableMessage.getValue());
|
||||
} catch (e) {
|
||||
console.error('An error occurred on "item_event"');
|
||||
console.error('An error occurred on "handleVariableEvent"');
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
@ -284,10 +281,18 @@ export class SocketManager {
|
|||
}
|
||||
|
||||
async getOrCreateRoom(roomId: string): Promise<GameRoom> {
|
||||
//check and create new world for a room
|
||||
let world = this.rooms.get(roomId);
|
||||
if (world === undefined) {
|
||||
world = new GameRoom(
|
||||
//check and create new room
|
||||
let room = this.rooms.get(roomId);
|
||||
if (room === undefined) {
|
||||
let roomPromise = this.roomsPromises.get(roomId);
|
||||
if (roomPromise) {
|
||||
return roomPromise;
|
||||
}
|
||||
|
||||
// Note: for now, the promise is useless (because this is synchronous, but soon, we will need to
|
||||
// load the map server side.
|
||||
|
||||
room = new GameRoom(
|
||||
roomId,
|
||||
(user: User, group: Group) => this.joinWebRtcRoom(user, group),
|
||||
(user: User, group: Group) => this.disConnectedUser(user, group),
|
||||
|
@ -303,9 +308,12 @@ export class SocketManager {
|
|||
this.onEmote(emoteEventMessage, listener)
|
||||
);
|
||||
gaugeManager.incNbRoomGauge();
|
||||
this.rooms.set(roomId, world);
|
||||
this.rooms.set(roomId, room);
|
||||
|
||||
// TODO: change this the to new Promise()... when the method becomes actually asynchronous
|
||||
roomPromise = Promise.resolve(room);
|
||||
}
|
||||
return Promise.resolve(world);
|
||||
return Promise.resolve(room);
|
||||
}
|
||||
|
||||
private async joinRoom(
|
||||
|
@ -676,6 +684,42 @@ export class SocketManager {
|
|||
room.removeZoneListener(call, x, y);
|
||||
}
|
||||
|
||||
async addRoomListener(call: RoomSocket, roomId: string) {
|
||||
const room = await this.getOrCreateRoom(roomId);
|
||||
if (!room) {
|
||||
console.error("In addRoomListener, could not find room with id '" + roomId + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
room.addRoomListener(call);
|
||||
//const things = room.addZoneListener(call, x, y);
|
||||
|
||||
const batchMessage = new BatchToPusherRoomMessage();
|
||||
|
||||
for (const [name, value] of room.variables.entries()) {
|
||||
const variableMessage = new VariableMessage();
|
||||
variableMessage.setName(name);
|
||||
variableMessage.setValue(value);
|
||||
|
||||
const subMessage = new SubToPusherRoomMessage();
|
||||
subMessage.setVariablemessage(variableMessage);
|
||||
|
||||
batchMessage.addPayload(subMessage);
|
||||
}
|
||||
|
||||
call.write(batchMessage);
|
||||
}
|
||||
|
||||
removeRoomListener(call: RoomSocket, roomId: string) {
|
||||
const room = this.rooms.get(roomId);
|
||||
if (!room) {
|
||||
console.error("In removeRoomListener, could not find room with id '" + roomId + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
room.removeRoomListener(call);
|
||||
}
|
||||
|
||||
public async handleJoinAdminRoom(admin: Admin, roomId: string): Promise<GameRoom> {
|
||||
const room = await socketManager.getOrCreateRoom(roomId);
|
||||
|
||||
|
@ -831,6 +875,7 @@ export class SocketManager {
|
|||
emoteEventMessage.setActoruserid(user.id);
|
||||
room.emitEmoteEvent(user, emoteEventMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const socketManager = new SocketManager();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue