Adapting admin connection to pusher.
Done: onUserLeave / onUserEnter To be done: ban / unban
This commit is contained in:
parent
bf797085e6
commit
24cb85cc7c
10 changed files with 306 additions and 522 deletions
37
back/src/Model/Admin.ts
Normal file
37
back/src/Model/Admin.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { Group } from "./Group";
|
||||
import { PointInterface } from "./Websocket/PointInterface";
|
||||
import {Zone} from "_Model/Zone";
|
||||
import {Movable} from "_Model/Movable";
|
||||
import {PositionNotifier} from "_Model/PositionNotifier";
|
||||
import {ServerDuplexStream} from "grpc";
|
||||
import {
|
||||
BatchMessage,
|
||||
PusherToBackMessage,
|
||||
ServerToAdminClientMessage,
|
||||
ServerToClientMessage,
|
||||
SubMessage
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import {CharacterLayer} from "_Model/Websocket/CharacterLayer";
|
||||
import {AdminSocket} from "../RoomManager";
|
||||
|
||||
|
||||
export class Admin {
|
||||
public constructor(
|
||||
private readonly socket: AdminSocket
|
||||
) {
|
||||
}
|
||||
|
||||
public sendUserJoin(uuid: string): void {
|
||||
const serverToAdminClientMessage = new ServerToAdminClientMessage();
|
||||
serverToAdminClientMessage.setUseruuidjoinedroom(uuid);
|
||||
|
||||
this.socket.write(serverToAdminClientMessage);
|
||||
}
|
||||
|
||||
public sendUserLeft(uuid: string): void {
|
||||
const serverToAdminClientMessage = new ServerToAdminClientMessage();
|
||||
serverToAdminClientMessage.setUseruuidleftroom(uuid);
|
||||
|
||||
this.socket.write(serverToAdminClientMessage);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,8 @@ import {arrayIntersect} from "../Services/ArrayHelper";
|
|||
import {MAX_USERS_PER_ROOM} from "../Enum/EnvironmentVariable";
|
||||
import {JoinRoomMessage} from "../Messages/generated/messages_pb";
|
||||
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
||||
import { ZoneSocket } from "src/RoomManager";
|
||||
import {ZoneSocket} from "src/RoomManager";
|
||||
import {Admin} from "../Model/Admin";
|
||||
|
||||
export type ConnectCallback = (user: User, group: Group) => void;
|
||||
export type DisconnectCallback = (user: User, group: Group) => void;
|
||||
|
@ -28,6 +29,7 @@ export class GameRoom {
|
|||
// Users, sorted by ID
|
||||
private readonly users: Map<number, User>;
|
||||
private readonly groups: Set<Group>;
|
||||
private readonly admins: Set<Admin>;
|
||||
|
||||
private readonly connectCallback: ConnectCallback;
|
||||
private readonly disconnectCallback: DisconnectCallback;
|
||||
|
@ -69,6 +71,7 @@ export class GameRoom {
|
|||
|
||||
|
||||
this.users = new Map<number, User>();
|
||||
this.admins = new Set<Admin>();
|
||||
this.groups = new Set<Group>();
|
||||
this.connectCallback = connectCallback;
|
||||
this.disconnectCallback = disconnectCallback;
|
||||
|
@ -99,6 +102,12 @@ export class GameRoom {
|
|||
// Let's call update position to trigger the join / leave room
|
||||
//this.updatePosition(socket, userPosition);
|
||||
this.updateUserGroup(user);
|
||||
|
||||
// Notify admins
|
||||
for (const admin of this.admins) {
|
||||
admin.sendUserJoin(user.uuid);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
|
@ -115,6 +124,11 @@ export class GameRoom {
|
|||
if (userObj !== undefined) {
|
||||
this.positionNotifier.leave(userObj);
|
||||
}
|
||||
|
||||
// Notify admins
|
||||
for (const admin of this.admins) {
|
||||
admin.sendUserLeft(user.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
get isFull(): boolean {
|
||||
|
@ -122,7 +136,7 @@ export class GameRoom {
|
|||
}
|
||||
|
||||
public isEmpty(): boolean {
|
||||
return this.users.size === 0;
|
||||
return this.users.size === 0 && this.admins.size === 0;
|
||||
}
|
||||
|
||||
public updatePosition(user : User, userPosition: PointInterface): void {
|
||||
|
@ -290,4 +304,17 @@ export class GameRoom {
|
|||
public removeZoneListener(call: ZoneSocket, x: number, y: number): void {
|
||||
return this.positionNotifier.removeZoneListener(call, x, y);
|
||||
}
|
||||
|
||||
public adminJoin(admin: Admin): void {
|
||||
this.admins.add(admin);
|
||||
|
||||
// Let's send all connected users
|
||||
for (const user of this.users.values()) {
|
||||
admin.sendUserJoin(user.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public adminLeave(admin: Admin): void {
|
||||
this.admins.delete(admin);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
import {IRoomManagerServer} from "./Messages/generated/messages_grpc_pb";
|
||||
import {
|
||||
AdminPusherToBackMessage,
|
||||
ClientToServerMessage, ItemEventMessage,
|
||||
JoinRoomMessage, PlayGlobalMessage, PusherToBackMessage, QueryJitsiJwtMessage, ReportPlayerMessage,
|
||||
RoomJoinedMessage,
|
||||
RoomJoinedMessage, ServerToAdminClientMessage,
|
||||
ServerToClientMessage, SilentMessage, UserMovesMessage, ViewportMessage, WebRtcSignalToServerMessage, ZoneMessage
|
||||
} from "./Messages/generated/messages_pb";
|
||||
import grpc, {ServerWritableStream} from "grpc";
|
||||
import grpc, {ServerDuplexStream, ServerWritableStream} from "grpc";
|
||||
import {Empty} from "google-protobuf/google/protobuf/empty_pb";
|
||||
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";
|
||||
import {Admin} from "./Model/Admin";
|
||||
|
||||
const debug = Debug('roommanager');
|
||||
|
||||
export type AdminSocket = ServerDuplexStream<AdminPusherToBackMessage, ServerToAdminClientMessage>;
|
||||
export type ZoneSocket = ServerWritableStream<ZoneMessage, ServerToClientMessage>;
|
||||
|
||||
const roomManager: IRoomManagerServer = {
|
||||
|
@ -109,6 +112,65 @@ const roomManager: IRoomManagerServer = {
|
|||
call.end();
|
||||
});
|
||||
},
|
||||
|
||||
adminRoom(call: AdminSocket): void {
|
||||
console.log('adminRoom called');
|
||||
|
||||
const admin = new Admin(call);
|
||||
let room: GameRoom|null = null;
|
||||
|
||||
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 {
|
||||
throw new Error('The first message sent MUST be of type JoinRoomMessage');
|
||||
}
|
||||
} else {
|
||||
/*if (message.hasJoinroommessage()) {
|
||||
throw new Error('Cannot call JoinRoomMessage twice!');
|
||||
} else if (message.hasUsermovesmessage()) {
|
||||
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()) {
|
||||
socketManager.emitVideo(room, user, message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage);
|
||||
} else if (message.hasWebrtcscreensharingsignaltoservermessage()) {
|
||||
socketManager.emitScreenSharing(room, user, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage);
|
||||
} else if (message.hasPlayglobalmessage()) {
|
||||
socketManager.emitPlayGlobalMessage(room, message.getPlayglobalmessage() as PlayGlobalMessage);
|
||||
} else if (message.hasQueryjitsijwtmessage()){
|
||||
socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage);
|
||||
} else {
|
||||
throw new Error('Unhandled message type');
|
||||
}*/
|
||||
}
|
||||
} catch (e) {
|
||||
emitError(call, e);
|
||||
call.end();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
call.on('end', () => {
|
||||
debug('joinRoom ended');
|
||||
if (room !== null) {
|
||||
socketManager.leaveAdminRoom(room, admin);
|
||||
}
|
||||
call.end();
|
||||
room = null;
|
||||
});
|
||||
|
||||
call.on('error', (err: Error) => {
|
||||
console.error('An error occurred in joinAdminRoom stream:', err);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export {roomManager};
|
||||
|
|
|
@ -11,7 +11,7 @@ class ClientEventsEmitter extends EventEmitter {
|
|||
emitClientLeave(clientUUid: string, roomId: string): void {
|
||||
this.emit(clientLeaveEvent, clientUUid, roomId);
|
||||
}
|
||||
|
||||
|
||||
registerToClientJoin(callback: (clientUUid: string, roomId: string) => void): void {
|
||||
this.on(clientJoinEvent, callback);
|
||||
}
|
||||
|
@ -29,4 +29,4 @@ class ClientEventsEmitter extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
export const clientEventsEmitter = new ClientEventsEmitter();
|
||||
export const clientEventsEmitter = new ClientEventsEmitter();
|
||||
|
|
|
@ -45,9 +45,10 @@ import Jwt from "jsonwebtoken";
|
|||
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
||||
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
||||
import {gaugeManager} from "./GaugeManager";
|
||||
import {ZoneSocket} from "../RoomManager";
|
||||
import {AdminSocket, ZoneSocket} from "../RoomManager";
|
||||
import {Zone} from "_Model/Zone";
|
||||
import Debug from "debug";
|
||||
import {Admin} from "_Model/Admin";
|
||||
|
||||
const debug = Debug('sockermanager');
|
||||
|
||||
|
@ -83,7 +84,7 @@ export class SocketManager {
|
|||
});
|
||||
}
|
||||
|
||||
getAdminSocketDataFor(roomId:string): AdminSocketData {
|
||||
/*getAdminSocketDataFor(roomId:string): AdminSocketData {
|
||||
const data:AdminSocketData = {
|
||||
rooms: {},
|
||||
users: {},
|
||||
|
@ -98,7 +99,7 @@ export class SocketManager {
|
|||
data.users[user.uuid] = true
|
||||
})
|
||||
return data;
|
||||
}
|
||||
}*/
|
||||
|
||||
public async handleJoinRoom(socket: UserSocket, joinRoomMessage: JoinRoomMessage): Promise<{ room: GameRoom; user: User }> {
|
||||
/*const positionMessage = joinRoomMessage.getPositionmessage();
|
||||
|
@ -385,6 +386,7 @@ export class SocketManager {
|
|||
|
||||
//join world
|
||||
const user = world.join(socket, joinRoomMessage);
|
||||
|
||||
clientEventsEmitter.emitClientJoin(user.uuid, roomId);
|
||||
//console.log(new Date().toISOString() + ' A user joined (', this.sockets.size, ' connected users)');
|
||||
console.log(new Date().toISOString() + ' A user joined');
|
||||
|
@ -738,6 +740,28 @@ export class SocketManager {
|
|||
|
||||
room.removeZoneListener(call, x, y);
|
||||
}
|
||||
|
||||
public async handleJoinAdminRoom(admin: Admin, roomId: string): Promise<GameRoom> {
|
||||
const room = await socketManager.getOrCreateRoom(roomId);
|
||||
|
||||
// Dispatch groups position to newly connected user
|
||||
/*world.getGroups().forEach((group: Group) => {
|
||||
this.emitCreateUpdateGroupEvent(socket, group);
|
||||
});*/
|
||||
|
||||
room.adminJoin(admin);
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
public leaveAdminRoom(room: GameRoom, admin: Admin){
|
||||
room.adminLeave(admin);
|
||||
if (room.isEmpty()) {
|
||||
this.rooms.delete(room.roomId);
|
||||
debug('Room is empty. Deleting room "%s"', room.roomId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const socketManager = new SocketManager();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue