Merge pull request #867 from thecodingmachine/roomEdition
FEATURE: editing a room in the admin trigger a refresh system
This commit is contained in:
commit
6e7b1f3ef6
@ -1,9 +1,3 @@
|
|||||||
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 {
|
import {
|
||||||
BatchMessage,
|
BatchMessage,
|
||||||
PusherToBackMessage,
|
PusherToBackMessage,
|
||||||
@ -11,7 +5,6 @@ import {
|
|||||||
ServerToClientMessage,
|
ServerToClientMessage,
|
||||||
SubMessage, UserJoinedRoomMessage, UserLeftRoomMessage
|
SubMessage, UserJoinedRoomMessage, UserLeftRoomMessage
|
||||||
} from "../Messages/generated/messages_pb";
|
} from "../Messages/generated/messages_pb";
|
||||||
import {CharacterLayer} from "_Model/Websocket/CharacterLayer";
|
|
||||||
import {AdminSocket} from "../RoomManager";
|
import {AdminSocket} from "../RoomManager";
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,12 +38,10 @@ export class GameRoom {
|
|||||||
|
|
||||||
private readonly positionNotifier: PositionNotifier;
|
private readonly positionNotifier: PositionNotifier;
|
||||||
public readonly roomId: string;
|
public readonly roomId: string;
|
||||||
public readonly anonymous: boolean;
|
|
||||||
public tags: string[];
|
|
||||||
public policyType: GameRoomPolicyTypes;
|
|
||||||
public readonly roomSlug: string;
|
public readonly roomSlug: string;
|
||||||
public readonly worldSlug: string = '';
|
public readonly worldSlug: string = '';
|
||||||
public readonly organizationSlug: string = '';
|
public readonly organizationSlug: string = '';
|
||||||
|
private versionNumber:number = 1;
|
||||||
private nextUserId: number = 1;
|
private nextUserId: number = 1;
|
||||||
|
|
||||||
constructor(roomId: string,
|
constructor(roomId: string,
|
||||||
@ -56,11 +54,8 @@ export class GameRoom {
|
|||||||
onLeaves: LeavesCallback)
|
onLeaves: LeavesCallback)
|
||||||
{
|
{
|
||||||
this.roomId = roomId;
|
this.roomId = roomId;
|
||||||
this.anonymous = isRoomAnonymous(roomId);
|
|
||||||
this.tags = [];
|
|
||||||
this.policyType = GameRoomPolicyTypes.ANONYMOUS_POLICY;
|
|
||||||
|
|
||||||
if (this.anonymous) {
|
if (isRoomAnonymous(roomId)) {
|
||||||
this.roomSlug = extractRoomSlugPublicRoomId(this.roomId);
|
this.roomSlug = extractRoomSlugPublicRoomId(this.roomId);
|
||||||
} else {
|
} else {
|
||||||
const {organizationSlug, worldSlug, roomSlug} = extractDataFromPrivateRoomId(this.roomId);
|
const {organizationSlug, worldSlug, roomSlug} = extractDataFromPrivateRoomId(this.roomId);
|
||||||
@ -304,10 +299,6 @@ export class GameRoom {
|
|||||||
return this.itemsState;
|
return this.itemsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public canAccess(userTags: string[]): boolean {
|
|
||||||
return arrayIntersect(userTags, this.tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addZoneListener(call: ZoneSocket, x: number, y: number): Set<Movable> {
|
public addZoneListener(call: ZoneSocket, x: number, y: number): Set<Movable> {
|
||||||
return this.positionNotifier.addZoneListener(call, x, y);
|
return this.positionNotifier.addZoneListener(call, x, y);
|
||||||
}
|
}
|
||||||
@ -328,4 +319,9 @@ export class GameRoom {
|
|||||||
public adminLeave(admin: Admin): void {
|
public adminLeave(admin: Admin): void {
|
||||||
this.admins.delete(admin);
|
this.admins.delete(admin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public incrementVersion(): number {
|
||||||
|
this.versionNumber++
|
||||||
|
return this.versionNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
JoinRoomMessage,
|
JoinRoomMessage,
|
||||||
PlayGlobalMessage,
|
PlayGlobalMessage,
|
||||||
PusherToBackMessage,
|
PusherToBackMessage,
|
||||||
QueryJitsiJwtMessage,
|
QueryJitsiJwtMessage, RefreshRoomPromptMessage,
|
||||||
ServerToAdminClientMessage,
|
ServerToAdminClientMessage,
|
||||||
ServerToClientMessage,
|
ServerToClientMessage,
|
||||||
SilentMessage,
|
SilentMessage,
|
||||||
@ -193,6 +193,10 @@ const roomManager: IRoomManagerServer = {
|
|||||||
socketManager.dispatchWorlFullWarning(call.request.getRoomid());
|
socketManager.dispatchWorlFullWarning(call.request.getRoomid());
|
||||||
callback(null, new EmptyMessage());
|
callback(null, new EmptyMessage());
|
||||||
},
|
},
|
||||||
|
sendRefreshRoomPrompt(call: ServerUnaryCall<RefreshRoomPromptMessage>, callback: sendUnaryData<EmptyMessage>): void {
|
||||||
|
socketManager.dispatchRoomRefresh(call.request.getRoomid());
|
||||||
|
callback(null, new EmptyMessage());
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export {roomManager};
|
export {roomManager};
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
|
|
||||||
import Axios from "axios";
|
|
||||||
|
|
||||||
export interface AdminApiData {
|
|
||||||
organizationSlug: string
|
|
||||||
worldSlug: string
|
|
||||||
roomSlug: string
|
|
||||||
mapUrlStart: string
|
|
||||||
tags: string[]
|
|
||||||
policy_type: number
|
|
||||||
userUuid: string
|
|
||||||
messages?: unknown[],
|
|
||||||
textures: CharacterTexture[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CharacterTexture {
|
|
||||||
id: number,
|
|
||||||
level: number,
|
|
||||||
url: string,
|
|
||||||
rights: string
|
|
||||||
}
|
|
||||||
|
|
||||||
class AdminApi {
|
|
||||||
|
|
||||||
async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise<AdminApiData> {
|
|
||||||
if (!ADMIN_API_URL) {
|
|
||||||
return Promise.reject(new Error('No admin backoffice set!'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const params: { organizationSlug: string, worldSlug: string, roomSlug?: string } = {
|
|
||||||
organizationSlug,
|
|
||||||
worldSlug
|
|
||||||
};
|
|
||||||
|
|
||||||
if (roomSlug) {
|
|
||||||
params.roomSlug = roomSlug;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await Axios.get(ADMIN_API_URL + '/api/map',
|
|
||||||
{
|
|
||||||
headers: {"Authorization": `${ADMIN_API_TOKEN}`},
|
|
||||||
params
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const adminApi = new AdminApi();
|
|
@ -26,7 +26,7 @@ import {
|
|||||||
GroupLeftZoneMessage,
|
GroupLeftZoneMessage,
|
||||||
WorldFullWarningMessage,
|
WorldFullWarningMessage,
|
||||||
UserLeftZoneMessage,
|
UserLeftZoneMessage,
|
||||||
BanUserMessage,
|
BanUserMessage, RefreshRoomMessage,
|
||||||
} from "../Messages/generated/messages_pb";
|
} from "../Messages/generated/messages_pb";
|
||||||
import {User, UserSocket} from "../Model/User";
|
import {User, UserSocket} from "../Model/User";
|
||||||
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
||||||
@ -41,7 +41,6 @@ import {
|
|||||||
} from "../Enum/EnvironmentVariable";
|
} from "../Enum/EnvironmentVariable";
|
||||||
import {Movable} from "../Model/Movable";
|
import {Movable} from "../Model/Movable";
|
||||||
import {PositionInterface} from "../Model/PositionInterface";
|
import {PositionInterface} from "../Model/PositionInterface";
|
||||||
import {adminApi, CharacterTexture} from "./AdminApi";
|
|
||||||
import Jwt from "jsonwebtoken";
|
import Jwt from "jsonwebtoken";
|
||||||
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
||||||
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
||||||
@ -130,14 +129,6 @@ export class SocketManager {
|
|||||||
throw new Error('Viewport not found in message');
|
throw new Error('Viewport not found in message');
|
||||||
}
|
}
|
||||||
|
|
||||||
// sending to all clients in room except sender
|
|
||||||
/*client.position = {
|
|
||||||
x: position.x,
|
|
||||||
y: position.y,
|
|
||||||
direction,
|
|
||||||
moving: position.moving,
|
|
||||||
};
|
|
||||||
client.viewport = viewport;*/
|
|
||||||
|
|
||||||
// update position in the world
|
// update position in the world
|
||||||
room.updatePosition(user, ProtobufUtils.toPointInterface(position));
|
room.updatePosition(user, ProtobufUtils.toPointInterface(position));
|
||||||
@ -192,21 +183,6 @@ export class SocketManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle this message in pusher
|
|
||||||
/*async handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) {
|
|
||||||
try {
|
|
||||||
const reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid());
|
|
||||||
if (!reportedSocket) {
|
|
||||||
throw 'reported socket user not found';
|
|
||||||
}
|
|
||||||
//TODO report user on admin application
|
|
||||||
await adminApi.reportPlayer(reportedSocket.userUuid, reportPlayerMessage.getReportcomment(), client.userUuid)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('An error occurred on "handleReportMessage"');
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
emitVideo(room: GameRoom, user: User, data: WebRtcSignalToServerMessage): void {
|
emitVideo(room: GameRoom, user: User, data: WebRtcSignalToServerMessage): void {
|
||||||
//send only at user
|
//send only at user
|
||||||
const remoteUser = room.getUsers().get(data.getReceiverid());
|
const remoteUser = room.getUsers().get(data.getReceiverid());
|
||||||
@ -289,11 +265,6 @@ export class SocketManager {
|
|||||||
(thing: Movable, position:PositionInterface, listener: ZoneSocket) => this.onClientMove(thing, position, listener),
|
(thing: Movable, position:PositionInterface, listener: ZoneSocket) => this.onClientMove(thing, position, listener),
|
||||||
(thing: Movable, newZone: Zone|null, listener: ZoneSocket) => this.onClientLeave(thing, newZone, listener)
|
(thing: Movable, newZone: Zone|null, listener: ZoneSocket) => this.onClientLeave(thing, newZone, listener)
|
||||||
);
|
);
|
||||||
if (!world.anonymous) {
|
|
||||||
const data = await adminApi.fetchMapDetails(world.organizationSlug, world.worldSlug, world.roomSlug)
|
|
||||||
world.tags = data.tags
|
|
||||||
world.policyType = Number(data.policy_type)
|
|
||||||
}
|
|
||||||
gaugeManager.incNbRoomGauge();
|
gaugeManager.incNbRoomGauge();
|
||||||
this.rooms.set(roomId, world);
|
this.rooms.set(roomId, world);
|
||||||
}
|
}
|
||||||
@ -772,6 +743,25 @@ export class SocketManager {
|
|||||||
recipient.socket.write(clientMessage);
|
recipient.socket.write(clientMessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatchRoomRefresh(roomId: string,): void {
|
||||||
|
const room = this.rooms.get(roomId);
|
||||||
|
if (!room) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const versionNumber = room.incrementVersion();
|
||||||
|
room.getUsers().forEach((recipient) => {
|
||||||
|
const worldFullMessage = new RefreshRoomMessage();
|
||||||
|
worldFullMessage.setRoomid(roomId)
|
||||||
|
worldFullMessage.setVersionnumber(versionNumber)
|
||||||
|
|
||||||
|
const clientMessage = new ServerToClientMessage();
|
||||||
|
clientMessage.setRefreshroommessage(worldFullMessage);
|
||||||
|
|
||||||
|
recipient.socket.write(clientMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const socketManager = new SocketManager();
|
export const socketManager = new SocketManager();
|
||||||
|
@ -187,6 +187,8 @@ export class RoomConnection implements RoomConnection {
|
|||||||
adminMessagesService.onSendusermessage(message.getSendusermessage() as BanUserMessage);
|
adminMessagesService.onSendusermessage(message.getSendusermessage() as BanUserMessage);
|
||||||
} else if (message.hasWorldfullwarningmessage()) {
|
} else if (message.hasWorldfullwarningmessage()) {
|
||||||
worldFullWarningStream.onMessage();
|
worldFullWarningStream.onMessage();
|
||||||
|
} else if (message.hasRefreshroommessage()) {
|
||||||
|
//todo: implement a way to notify the user the room was refreshed.
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown message received');
|
throw new Error('Unknown message received');
|
||||||
}
|
}
|
||||||
|
@ -202,6 +202,13 @@ message WorldFullWarningMessage{
|
|||||||
message WorldFullWarningToRoomMessage{
|
message WorldFullWarningToRoomMessage{
|
||||||
string roomId = 1;
|
string roomId = 1;
|
||||||
}
|
}
|
||||||
|
message RefreshRoomPromptMessage{
|
||||||
|
string roomId = 1;
|
||||||
|
}
|
||||||
|
message RefreshRoomMessage{
|
||||||
|
string roomId = 1;
|
||||||
|
int32 versionNumber = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message WorldFullMessage{
|
message WorldFullMessage{
|
||||||
}
|
}
|
||||||
@ -229,6 +236,7 @@ message ServerToClientMessage {
|
|||||||
AdminRoomMessage adminRoomMessage = 14;
|
AdminRoomMessage adminRoomMessage = 14;
|
||||||
WorldFullWarningMessage worldFullWarningMessage = 15;
|
WorldFullWarningMessage worldFullWarningMessage = 15;
|
||||||
WorldFullMessage worldFullMessage = 16;
|
WorldFullMessage worldFullMessage = 16;
|
||||||
|
RefreshRoomMessage refreshRoomMessage = 17;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,4 +403,5 @@ service RoomManager {
|
|||||||
rpc ban(BanMessage) returns (EmptyMessage);
|
rpc ban(BanMessage) returns (EmptyMessage);
|
||||||
rpc sendAdminMessageToRoom(AdminRoomMessage) returns (EmptyMessage);
|
rpc sendAdminMessageToRoom(AdminRoomMessage) returns (EmptyMessage);
|
||||||
rpc sendWorldFullWarningToRoom(WorldFullWarningToRoomMessage) returns (EmptyMessage);
|
rpc sendWorldFullWarningToRoom(WorldFullWarningToRoomMessage) returns (EmptyMessage);
|
||||||
|
rpc sendRefreshRoomPrompt(RefreshRoomPromptMessage) returns (EmptyMessage);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import {BaseController} from "./BaseController";
|
|||||||
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
|
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
|
||||||
import {ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable";
|
import {ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable";
|
||||||
import {apiClientRepository} from "../Services/ApiClientRepository";
|
import {apiClientRepository} from "../Services/ApiClientRepository";
|
||||||
import {AdminRoomMessage, WorldFullWarningToRoomMessage} from "../Messages/generated/messages_pb";
|
import {AdminRoomMessage, WorldFullWarningToRoomMessage, RefreshRoomPromptMessage} from "../Messages/generated/messages_pb";
|
||||||
|
|
||||||
|
|
||||||
export class AdminController extends BaseController{
|
export class AdminController extends BaseController{
|
||||||
@ -11,6 +11,56 @@ export class AdminController extends BaseController{
|
|||||||
super();
|
super();
|
||||||
this.App = App;
|
this.App = App;
|
||||||
this.receiveGlobalMessagePrompt();
|
this.receiveGlobalMessagePrompt();
|
||||||
|
this.receiveRoomEditionPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
receiveRoomEditionPrompt() {
|
||||||
|
this.App.options("/room/refresh", (res: HttpResponse, req: HttpRequest) => {
|
||||||
|
this.addCorsHeaders(res);
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
|
this.App.post("/room/refresh", async (res: HttpResponse, req: HttpRequest) => {
|
||||||
|
res.onAborted(() => {
|
||||||
|
console.warn('/message request was aborted');
|
||||||
|
})
|
||||||
|
|
||||||
|
const token = req.getHeader('admin-token');
|
||||||
|
const body = await res.json();
|
||||||
|
|
||||||
|
if (token !== ADMIN_API_TOKEN) {
|
||||||
|
console.error('Admin access refused for token: '+token)
|
||||||
|
res.writeStatus("401 Unauthorized").end('Incorrect token');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof body.roomId !== 'string') {
|
||||||
|
throw 'Incorrect roomId parameter'
|
||||||
|
}
|
||||||
|
const roomId: string = body.roomId;
|
||||||
|
|
||||||
|
await apiClientRepository.getClient(roomId).then((roomClient) =>{
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
const roomMessage = new RefreshRoomPromptMessage();
|
||||||
|
roomMessage.setRoomid(roomId);
|
||||||
|
|
||||||
|
roomClient.sendRefreshRoomPrompt(roomMessage, (err) => {
|
||||||
|
err ? rej(err) : res();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.errorToResponse(err, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeStatus("200");
|
||||||
|
res.end('ok');
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
receiveGlobalMessagePrompt() {
|
receiveGlobalMessagePrompt() {
|
||||||
|
@ -190,10 +190,10 @@ export class IoSocketController {
|
|||||||
memberMessages = userData.messages;
|
memberMessages = userData.messages;
|
||||||
memberTags = userData.tags;
|
memberTags = userData.tags;
|
||||||
memberTextures = userData.textures;
|
memberTextures = userData.textures;
|
||||||
if (!room.anonymous && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags))) {
|
if (!room.public && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags))) {
|
||||||
throw new Error('No correct tags')
|
throw new Error('No correct tags')
|
||||||
}
|
}
|
||||||
if (!room.anonymous && room.policyType === GameRoomPolicyTypes.MEMBERS_ONLY_POLICY && userData.anonymous === true) {
|
if (!room.public && room.policyType === GameRoomPolicyTypes.MEMBERS_ONLY_POLICY && userData.anonymous === true) {
|
||||||
throw new Error('No correct member')
|
throw new Error('No correct member')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -13,21 +13,22 @@ export enum GameRoomPolicyTypes {
|
|||||||
|
|
||||||
export class PusherRoom {
|
export class PusherRoom {
|
||||||
private readonly positionNotifier: PositionDispatcher;
|
private readonly positionNotifier: PositionDispatcher;
|
||||||
public readonly anonymous: boolean;
|
public readonly public: boolean;
|
||||||
public tags: string[];
|
public tags: string[];
|
||||||
public policyType: GameRoomPolicyTypes;
|
public policyType: GameRoomPolicyTypes;
|
||||||
public readonly roomSlug: string;
|
public readonly roomSlug: string;
|
||||||
public readonly worldSlug: string = '';
|
public readonly worldSlug: string = '';
|
||||||
public readonly organizationSlug: string = '';
|
public readonly organizationSlug: string = '';
|
||||||
|
private versionNumber: number = 1;
|
||||||
|
|
||||||
constructor(public readonly roomId: string,
|
constructor(public readonly roomId: string,
|
||||||
private socketListener: ZoneEventListener)
|
private socketListener: ZoneEventListener)
|
||||||
{
|
{
|
||||||
this.anonymous = isRoomAnonymous(roomId);
|
this.public = isRoomAnonymous(roomId);
|
||||||
this.tags = [];
|
this.tags = [];
|
||||||
this.policyType = GameRoomPolicyTypes.ANONYMUS_POLICY;
|
this.policyType = GameRoomPolicyTypes.ANONYMUS_POLICY;
|
||||||
|
|
||||||
if (this.anonymous) {
|
if (this.public) {
|
||||||
this.roomSlug = extractRoomSlugPublicRoomId(this.roomId);
|
this.roomSlug = extractRoomSlugPublicRoomId(this.roomId);
|
||||||
} else {
|
} else {
|
||||||
const {organizationSlug, worldSlug, roomSlug} = extractDataFromPrivateRoomId(this.roomId);
|
const {organizationSlug, worldSlug, roomSlug} = extractDataFromPrivateRoomId(this.roomId);
|
||||||
@ -55,4 +56,13 @@ export class PusherRoom {
|
|||||||
public isEmpty(): boolean {
|
public isEmpty(): boolean {
|
||||||
return this.positionNotifier.isEmpty();
|
return this.positionNotifier.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public needsUpdate(versionNumber: number): boolean {
|
||||||
|
if (this.versionNumber < versionNumber) {
|
||||||
|
this.versionNumber = versionNumber;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
|
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
|
import {GameRoomPolicyTypes} from "_Model/PusherRoom";
|
||||||
|
|
||||||
export interface AdminApiData {
|
export interface AdminApiData {
|
||||||
organizationSlug: string
|
organizationSlug: string
|
||||||
@ -13,6 +14,13 @@ export interface AdminApiData {
|
|||||||
textures: CharacterTexture[]
|
textures: CharacterTexture[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MapDetailsData {
|
||||||
|
roomSlug: string,
|
||||||
|
mapUrl: string,
|
||||||
|
policy_type: GameRoomPolicyTypes,
|
||||||
|
tags: string[],
|
||||||
|
}
|
||||||
|
|
||||||
export interface AdminBannedData {
|
export interface AdminBannedData {
|
||||||
is_banned: boolean,
|
is_banned: boolean,
|
||||||
message: string
|
message: string
|
||||||
@ -35,7 +43,7 @@ export interface FetchMemberDataByUuidResponse {
|
|||||||
|
|
||||||
class AdminApi {
|
class AdminApi {
|
||||||
|
|
||||||
async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise<AdminApiData> {
|
async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise<MapDetailsData> {
|
||||||
if (!ADMIN_API_URL) {
|
if (!ADMIN_API_URL) {
|
||||||
return Promise.reject(new Error('No admin backoffice set!'));
|
return Promise.reject(new Error('No admin backoffice set!'));
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import {
|
|||||||
WorldFullMessage,
|
WorldFullMessage,
|
||||||
AdminPusherToBackMessage,
|
AdminPusherToBackMessage,
|
||||||
ServerToAdminClientMessage,
|
ServerToAdminClientMessage,
|
||||||
UserJoinedRoomMessage, UserLeftRoomMessage, AdminMessage, BanMessage
|
UserJoinedRoomMessage, UserLeftRoomMessage, AdminMessage, BanMessage, RefreshRoomMessage
|
||||||
} from "../Messages/generated/messages_pb";
|
} from "../Messages/generated/messages_pb";
|
||||||
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
||||||
import {JITSI_ISS, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
|
import {JITSI_ISS, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
|
||||||
@ -54,7 +54,7 @@ export interface AdminSocketData {
|
|||||||
|
|
||||||
export class SocketManager implements ZoneEventListener {
|
export class SocketManager implements ZoneEventListener {
|
||||||
|
|
||||||
private Worlds: Map<string, PusherRoom> = new Map<string, PusherRoom>();
|
private rooms: Map<string, PusherRoom> = new Map<string, PusherRoom>();
|
||||||
private sockets: Map<number, ExSocketInterface> = new Map<number, ExSocketInterface>();
|
private sockets: Map<number, ExSocketInterface> = new Map<number, ExSocketInterface>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -181,6 +181,11 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
this.handleViewport(client, viewport);
|
this.handleViewport(client, viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.hasRefreshroommessage()) {
|
||||||
|
const refreshMessage:RefreshRoomMessage = message.getRefreshroommessage() as unknown as RefreshRoomMessage;
|
||||||
|
this.refreshRoomData(refreshMessage.getRoomid(), refreshMessage.getVersionnumber())
|
||||||
|
}
|
||||||
|
|
||||||
// Let's pass data over from the back to the client.
|
// Let's pass data over from the back to the client.
|
||||||
if (!client.disconnecting) {
|
if (!client.disconnecting) {
|
||||||
client.send(message.serializeBinary().buffer, true);
|
client.send(message.serializeBinary().buffer, true);
|
||||||
@ -219,7 +224,7 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
try {
|
try {
|
||||||
client.viewport = viewport;
|
client.viewport = viewport;
|
||||||
|
|
||||||
const world = this.Worlds.get(client.roomId);
|
const world = this.rooms.get(client.roomId);
|
||||||
if (!world) {
|
if (!world) {
|
||||||
console.error("In SET_VIEWPORT, could not find world with id '", client.roomId, "'");
|
console.error("In SET_VIEWPORT, could not find world with id '", client.roomId, "'");
|
||||||
return;
|
return;
|
||||||
@ -310,12 +315,12 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
if (socket.roomId) {
|
if (socket.roomId) {
|
||||||
try {
|
try {
|
||||||
//user leaves room
|
//user leaves room
|
||||||
const room: PusherRoom | undefined = this.Worlds.get(socket.roomId);
|
const room: PusherRoom | undefined = this.rooms.get(socket.roomId);
|
||||||
if (room) {
|
if (room) {
|
||||||
debug('Leaving room %s.', socket.roomId);
|
debug('Leaving room %s.', socket.roomId);
|
||||||
room.leave(socket);
|
room.leave(socket);
|
||||||
if (room.isEmpty()) {
|
if (room.isEmpty()) {
|
||||||
this.Worlds.delete(socket.roomId);
|
this.rooms.delete(socket.roomId);
|
||||||
debug('Room %s is empty. Deleting.', socket.roomId);
|
debug('Room %s is empty. Deleting.', socket.roomId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -339,19 +344,23 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
|
|
||||||
async getOrCreateRoom(roomId: string): Promise<PusherRoom> {
|
async getOrCreateRoom(roomId: string): Promise<PusherRoom> {
|
||||||
//check and create new world for a room
|
//check and create new world for a room
|
||||||
let world = this.Worlds.get(roomId)
|
let world = this.rooms.get(roomId)
|
||||||
if(world === undefined){
|
if(world === undefined){
|
||||||
world = new PusherRoom(roomId, this);
|
world = new PusherRoom(roomId, this);
|
||||||
if (!world.anonymous) {
|
if (!world.public) {
|
||||||
const data = await adminApi.fetchMapDetails(world.organizationSlug, world.worldSlug, world.roomSlug)
|
await this.updateRoomWithAdminData(world);
|
||||||
world.tags = data.tags
|
|
||||||
world.policyType = Number(data.policy_type)
|
|
||||||
}
|
}
|
||||||
this.Worlds.set(roomId, world);
|
this.rooms.set(roomId, world);
|
||||||
}
|
}
|
||||||
return Promise.resolve(world)
|
return Promise.resolve(world)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async updateRoomWithAdminData(world: PusherRoom): Promise<void> {
|
||||||
|
const data = await adminApi.fetchMapDetails(world.organizationSlug, world.worldSlug, world.roomSlug)
|
||||||
|
world.tags = data.tags;
|
||||||
|
world.policyType = Number(data.policy_type);
|
||||||
|
}
|
||||||
|
|
||||||
emitPlayGlobalMessage(client: ExSocketInterface, playglobalmessage: PlayGlobalMessage) {
|
emitPlayGlobalMessage(client: ExSocketInterface, playglobalmessage: PlayGlobalMessage) {
|
||||||
const pusherToBackMessage = new PusherToBackMessage();
|
const pusherToBackMessage = new PusherToBackMessage();
|
||||||
pusherToBackMessage.setPlayglobalmessage(playglobalmessage);
|
pusherToBackMessage.setPlayglobalmessage(playglobalmessage);
|
||||||
@ -360,7 +369,7 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getWorlds(): Map<string, PusherRoom> {
|
public getWorlds(): Map<string, PusherRoom> {
|
||||||
return this.Worlds;
|
return this.rooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
searchClientByUuid(uuid: string): ExSocketInterface | null {
|
searchClientByUuid(uuid: string): ExSocketInterface | null {
|
||||||
@ -544,6 +553,14 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
|
|
||||||
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private refreshRoomData(roomId: string, versionNumber: number): void {
|
||||||
|
const room = this.rooms.get(roomId);
|
||||||
|
//this function is run for every users connected to the room, so we need to make sure the room wasn't already refreshed.
|
||||||
|
if (!room || !room.needsUpdate(versionNumber)) return;
|
||||||
|
|
||||||
|
this.updateRoomWithAdminData(room);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const socketManager = new SocketManager();
|
export const socketManager = new SocketManager();
|
||||||
|
Loading…
Reference in New Issue
Block a user