Merge pull request #601 from thecodingmachine/featureBan
Create ban feature by admin console
This commit is contained in:
commit
c466ba8ca5
43
.github/workflows/continuous_integration.yml
vendored
43
.github/workflows/continuous_integration.yml
vendored
@ -53,6 +53,49 @@ jobs:
|
||||
run: yarn test
|
||||
working-directory: "front"
|
||||
|
||||
continuous-integration-pusher:
|
||||
name: "Continuous Integration Pusher"
|
||||
|
||||
runs-on: "ubuntu-latest"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2.0.0"
|
||||
|
||||
- name: "Setup NodeJS"
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.x'
|
||||
|
||||
- name: Install Protoc
|
||||
uses: arduino/setup-protoc@v1
|
||||
with:
|
||||
version: '3.x'
|
||||
|
||||
- name: "Install dependencies"
|
||||
run: yarn install
|
||||
working-directory: "pusher"
|
||||
|
||||
- name: "Install messages dependencies"
|
||||
run: yarn install
|
||||
working-directory: "messages"
|
||||
|
||||
- name: "Build proto messages"
|
||||
run: yarn run proto && yarn run copy-to-pusher
|
||||
working-directory: "messages"
|
||||
|
||||
- name: "Build"
|
||||
run: yarn run tsc
|
||||
working-directory: "pusher"
|
||||
|
||||
- name: "Lint"
|
||||
run: yarn run lint
|
||||
working-directory: "pusher"
|
||||
|
||||
- name: "Jasmine"
|
||||
run: yarn test
|
||||
working-directory: "pusher"
|
||||
|
||||
continuous-integration-back:
|
||||
name: "Continuous Integration Back"
|
||||
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
PusherToBackMessage,
|
||||
ServerToAdminClientMessage,
|
||||
ServerToClientMessage,
|
||||
SubMessage
|
||||
SubMessage, UserJoinedRoomMessage, UserLeftRoomMessage
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import {CharacterLayer} from "_Model/Websocket/CharacterLayer";
|
||||
import {AdminSocket} from "../RoomManager";
|
||||
@ -21,16 +21,26 @@ export class Admin {
|
||||
) {
|
||||
}
|
||||
|
||||
public sendUserJoin(uuid: string): void {
|
||||
public sendUserJoin(uuid: string, name: string, ip: string): void {
|
||||
const serverToAdminClientMessage = new ServerToAdminClientMessage();
|
||||
serverToAdminClientMessage.setUseruuidjoinedroom(uuid);
|
||||
|
||||
const userJoinedRoomMessage = new UserJoinedRoomMessage();
|
||||
userJoinedRoomMessage.setUuid(uuid);
|
||||
userJoinedRoomMessage.setName(name);
|
||||
userJoinedRoomMessage.setIpaddress(ip);
|
||||
|
||||
serverToAdminClientMessage.setUserjoinedroom(userJoinedRoomMessage);
|
||||
|
||||
this.socket.write(serverToAdminClientMessage);
|
||||
}
|
||||
|
||||
public sendUserLeft(uuid: string): void {
|
||||
public sendUserLeft(uuid: string/*, name: string, ip: string*/): void {
|
||||
const serverToAdminClientMessage = new ServerToAdminClientMessage();
|
||||
serverToAdminClientMessage.setUseruuidleftroom(uuid);
|
||||
|
||||
const userLeftRoomMessage = new UserLeftRoomMessage();
|
||||
userLeftRoomMessage.setUuid(uuid);
|
||||
|
||||
serverToAdminClientMessage.setUserleftroom(userLeftRoomMessage);
|
||||
|
||||
this.socket.write(serverToAdminClientMessage);
|
||||
}
|
||||
|
@ -102,7 +102,17 @@ export class GameRoom {
|
||||
}
|
||||
const position = ProtobufUtils.toPointInterface(positionMessage);
|
||||
|
||||
const user = new User(this.nextUserId, joinRoomMessage.getUseruuid(), position, false, this.positionNotifier, socket, joinRoomMessage.getTagList(), joinRoomMessage.getName(), ProtobufUtils.toCharacterLayerObjects(joinRoomMessage.getCharacterlayerList()));
|
||||
const user = new User(this.nextUserId,
|
||||
joinRoomMessage.getUseruuid(),
|
||||
joinRoomMessage.getIpaddress(),
|
||||
position,
|
||||
false,
|
||||
this.positionNotifier,
|
||||
socket,
|
||||
joinRoomMessage.getTagList(),
|
||||
joinRoomMessage.getName(),
|
||||
ProtobufUtils.toCharacterLayerObjects(joinRoomMessage.getCharacterlayerList())
|
||||
);
|
||||
this.nextUserId++;
|
||||
this.users.set(user.id, user);
|
||||
this.usersByUuid.set(user.uuid, user);
|
||||
@ -112,7 +122,7 @@ export class GameRoom {
|
||||
|
||||
// Notify admins
|
||||
for (const admin of this.admins) {
|
||||
admin.sendUserJoin(user.uuid);
|
||||
admin.sendUserJoin(user.uuid, user.name, user.IPAddress);
|
||||
}
|
||||
|
||||
return user;
|
||||
@ -135,7 +145,7 @@ export class GameRoom {
|
||||
|
||||
// Notify admins
|
||||
for (const admin of this.admins) {
|
||||
admin.sendUserLeft(user.uuid);
|
||||
admin.sendUserLeft(user.uuid/*, user.name, user.IPAddress*/);
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,7 +328,7 @@ export class GameRoom {
|
||||
|
||||
// Let's send all connected users
|
||||
for (const user of this.users.values()) {
|
||||
admin.sendUserJoin(user.uuid);
|
||||
admin.sendUserJoin(user.uuid, user.name, user.IPAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ export class User implements Movable {
|
||||
public constructor(
|
||||
public id: number,
|
||||
public readonly uuid: string,
|
||||
public readonly IPAddress: string,
|
||||
private position: PointInterface,
|
||||
public silent: boolean,
|
||||
private positionNotifier: PositionNotifier,
|
||||
|
@ -2,25 +2,22 @@ import {IRoomManagerServer} from "./Messages/generated/messages_grpc_pb";
|
||||
import {
|
||||
AdminGlobalMessage,
|
||||
AdminMessage,
|
||||
AdminPusherToBackMessage, BanMessage,
|
||||
ClientToServerMessage, EmptyMessage,
|
||||
AdminPusherToBackMessage,
|
||||
BanMessage,
|
||||
EmptyMessage,
|
||||
ItemEventMessage,
|
||||
JoinRoomMessage,
|
||||
PlayGlobalMessage,
|
||||
PusherToBackMessage,
|
||||
QueryJitsiJwtMessage,
|
||||
ReportPlayerMessage,
|
||||
RoomJoinedMessage,
|
||||
ServerToAdminClientMessage,
|
||||
ServerToClientMessage,
|
||||
SilentMessage,
|
||||
UserMovesMessage,
|
||||
ViewportMessage,
|
||||
WebRtcSignalToServerMessage,
|
||||
ZoneMessage
|
||||
} from "./Messages/generated/messages_pb";
|
||||
import grpc, {sendUnaryData, ServerDuplexStream, ServerUnaryCall, ServerWritableStream} from "grpc";
|
||||
import {Empty} from "google-protobuf/google/protobuf/empty_pb";
|
||||
import {sendUnaryData, ServerDuplexStream, ServerUnaryCall, ServerWritableStream} from "grpc";
|
||||
import {socketManager} from "./Services/SocketManager";
|
||||
import {emitError} from "./Services/MessageHelpers";
|
||||
import {User, UserSocket} from "./Model/User";
|
||||
@ -74,6 +71,16 @@ const roomManager: IRoomManagerServer = {
|
||||
socketManager.handleReportMessage(client, message.getReportplayermessage() as ReportPlayerMessage);*/
|
||||
} else if (message.hasQueryjitsijwtmessage()){
|
||||
socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage);
|
||||
}else if (message.hasSendusermessage()) {
|
||||
const sendUserMessage = message.getSendusermessage();
|
||||
if(sendUserMessage !== undefined) {
|
||||
socketManager.handlerSendUserMessage(user, sendUserMessage);
|
||||
}
|
||||
}else if (message.hasBanusermessage()) {
|
||||
const banUserMessage = message.getBanusermessage();
|
||||
if(banUserMessage !== undefined) {
|
||||
socketManager.handlerBanUserMessage(room, user, banUserMessage);
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unhandled message type');
|
||||
}
|
||||
@ -196,8 +203,8 @@ const roomManager: IRoomManagerServer = {
|
||||
callback(null, new EmptyMessage());
|
||||
},
|
||||
ban(call: ServerUnaryCall<BanMessage>, callback: sendUnaryData<EmptyMessage>): void {
|
||||
|
||||
socketManager.banUser(call.request.getRoomid(), call.request.getRecipientuuid());
|
||||
// FIXME Work in progress
|
||||
socketManager.banUser(call.request.getRoomid(), call.request.getRecipientuuid(), 'foo bar TODO change this');
|
||||
|
||||
callback(null, new EmptyMessage());
|
||||
},
|
||||
|
@ -1,24 +1,16 @@
|
||||
import {GameRoom} from "../Model/GameRoom";
|
||||
import {CharacterLayer} from "_Model/Websocket/CharacterLayer";
|
||||
import {
|
||||
GroupDeleteMessage,
|
||||
GroupUpdateMessage,
|
||||
ItemEventMessage,
|
||||
ItemStateMessage,
|
||||
PlayGlobalMessage,
|
||||
PointMessage,
|
||||
PositionMessage,
|
||||
RoomJoinedMessage,
|
||||
ServerToClientMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
SilentMessage,
|
||||
SubMessage,
|
||||
ReportPlayerMessage,
|
||||
UserJoinedMessage,
|
||||
UserLeftMessage,
|
||||
UserMovedMessage,
|
||||
UserMovesMessage,
|
||||
ViewportMessage,
|
||||
WebRtcDisconnectMessage,
|
||||
WebRtcSignalToClientMessage,
|
||||
WebRtcSignalToServerMessage,
|
||||
@ -28,24 +20,23 @@ import {
|
||||
SendUserMessage,
|
||||
JoinRoomMessage,
|
||||
Zone as ProtoZone,
|
||||
BatchMessage,
|
||||
BatchToPusherMessage,
|
||||
SubToPusherMessage,
|
||||
UserJoinedZoneMessage, GroupUpdateZoneMessage, GroupLeftZoneMessage, UserLeftZoneMessage, AdminMessage, BanMessage
|
||||
UserJoinedZoneMessage, GroupUpdateZoneMessage, GroupLeftZoneMessage, UserLeftZoneMessage, BanUserMessage
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import {User, UserSocket} from "../Model/User";
|
||||
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
||||
import {Group} from "../Model/Group";
|
||||
import {cpuTracker} from "./CpuTracker";
|
||||
import {ADMIN_API_URL, GROUP_RADIUS, JITSI_ISS, MINIMUM_DISTANCE, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
|
||||
import {GROUP_RADIUS, JITSI_ISS, MINIMUM_DISTANCE, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
|
||||
import {Movable} from "../Model/Movable";
|
||||
import {PositionInterface} from "../Model/PositionInterface";
|
||||
import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "./AdminApi";
|
||||
import {adminApi, CharacterTexture} from "./AdminApi";
|
||||
import Jwt from "jsonwebtoken";
|
||||
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
||||
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
||||
import {gaugeManager} from "./GaugeManager";
|
||||
import {AdminSocket, ZoneSocket} from "../RoomManager";
|
||||
import {ZoneSocket} from "../RoomManager";
|
||||
import {Zone} from "_Model/Zone";
|
||||
import Debug from "debug";
|
||||
import {Admin} from "_Model/Admin";
|
||||
@ -119,7 +110,7 @@ export class SocketManager {
|
||||
//const things = room.setViewport(client, viewport);
|
||||
|
||||
const roomJoinedMessage = new RoomJoinedMessage();
|
||||
|
||||
roomJoinedMessage.setTagList(joinRoomMessage.getTagList());
|
||||
/*for (const thing of things) {
|
||||
if (thing instanceof User) {
|
||||
const player: ExSocketInterface|undefined = this.sockets.get(thing.id);
|
||||
@ -626,6 +617,33 @@ export class SocketManager {
|
||||
user.socket.write(serverToClientMessage);
|
||||
}
|
||||
|
||||
public handlerSendUserMessage(user: User, sendUserMessageToSend: SendUserMessage){
|
||||
const sendUserMessage = new SendUserMessage();
|
||||
sendUserMessage.setMessage(sendUserMessageToSend.getMessage());
|
||||
sendUserMessage.setType(sendUserMessageToSend.getType());
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
serverToClientMessage.setSendusermessage(sendUserMessage);
|
||||
user.socket.write(serverToClientMessage);
|
||||
}
|
||||
|
||||
public handlerBanUserMessage(room: GameRoom, user: User, banUserMessageToSend: BanUserMessage){
|
||||
const banUserMessage = new BanUserMessage();
|
||||
banUserMessage.setMessage(banUserMessageToSend.getMessage());
|
||||
banUserMessage.setType(banUserMessageToSend.getType());
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
serverToClientMessage.setSendusermessage(banUserMessage);
|
||||
user.socket.write(serverToClientMessage);
|
||||
|
||||
setTimeout(() => {
|
||||
// Let's leave the room now.
|
||||
room.leave(user);
|
||||
// Let's close the connection when the user is banned.
|
||||
user.socket.end();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the characterLayers received from the front (as an array of string) with the custom textures from the back.
|
||||
*/
|
||||
@ -748,7 +766,7 @@ export class SocketManager {
|
||||
recipient.socket.write(subToPusherMessage);
|
||||
}
|
||||
|
||||
public banUser(roomId: string, recipientUuid: string): void {
|
||||
public banUser(roomId: string, recipientUuid: string, message: string): void {
|
||||
const room = this.rooms.get(roomId);
|
||||
if (!room) {
|
||||
console.error("In banUser, could not find room with id '" + roomId + "'. Maybe the room was closed a few milliseconds ago and there was a race condition?");
|
||||
@ -765,6 +783,7 @@ export class SocketManager {
|
||||
room.leave(recipient);
|
||||
|
||||
const sendUserMessage = new SendUserMessage();
|
||||
sendUserMessage.setMessage(message);
|
||||
sendUserMessage.setType('banned');
|
||||
|
||||
const subToPusherMessage = new SubToPusherMessage();
|
||||
|
@ -26,6 +26,7 @@ function createJoinRoomMessage(uuid: string, x: number, y: number): JoinRoomMess
|
||||
positionMessage.setMoving(false);
|
||||
const joinRoomMessage = new JoinRoomMessage();
|
||||
joinRoomMessage.setUseruuid('1');
|
||||
joinRoomMessage.setIpaddress('10.0.0.2');
|
||||
joinRoomMessage.setName('foo');
|
||||
joinRoomMessage.setRoomid('_/global/test.json');
|
||||
joinRoomMessage.setPositionmessage(positionMessage);
|
||||
|
@ -25,14 +25,14 @@ describe("PositionNotifier", () => {
|
||||
leaveTriggered = true;
|
||||
});
|
||||
|
||||
const user1 = new User(1, 'test', {
|
||||
const user1 = new User(1, 'test', '10.0.0.2', {
|
||||
x: 500,
|
||||
y: 500,
|
||||
moving: false,
|
||||
direction: 'down'
|
||||
}, false, positionNotifier, {} as UserSocket, [], 'foo', []);
|
||||
|
||||
const user2 = new User(2, 'test', {
|
||||
const user2 = new User(2, 'test', '10.0.0.2', {
|
||||
x: -9999,
|
||||
y: -9999,
|
||||
moving: false,
|
||||
@ -100,14 +100,14 @@ describe("PositionNotifier", () => {
|
||||
leaveTriggered = true;
|
||||
});
|
||||
|
||||
const user1 = new User(1, 'test', {
|
||||
const user1 = new User(1, 'test', '10.0.0.2', {
|
||||
x: 500,
|
||||
y: 500,
|
||||
moving: false,
|
||||
direction: 'down'
|
||||
}, false, positionNotifier, {} as UserSocket, [], 'foo', []);
|
||||
|
||||
const user2 = new User(2, 'test', {
|
||||
const user2 = new User(2, 'test', '10.0.0.2', {
|
||||
x: 0,
|
||||
y: 0,
|
||||
moving: false,
|
||||
|
@ -72,8 +72,9 @@ export class Room {
|
||||
console.log('Map ', this.id, ' resolves to URL ', data.mapUrl);
|
||||
resolve(data.mapUrl);
|
||||
return;
|
||||
}).catch((reason) => {
|
||||
reject(reason);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
||||
import {GameMap} from "./GameMap";
|
||||
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
||||
import {mediaManager} from "../../WebRtc/MediaManager";
|
||||
import {FourOFourSceneName} from "../Reconnecting/FourOFourScene";
|
||||
import {ItemFactoryInterface} from "../Items/ItemFactoryInterface";
|
||||
import {ActionableItem} from "../Items/ActionableItem";
|
||||
import {UserInputManager} from "../UserInput/UserInputManager";
|
||||
@ -67,6 +66,7 @@ import {OpenChatIcon, openChatIconName} from "../Components/OpenChatIcon";
|
||||
import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCharacterScene";
|
||||
import {TextureError} from "../../Exception/TextureError";
|
||||
import {addLoader} from "../Components/Loader";
|
||||
import {ErrorSceneName} from "../Reconnecting/ErrorScene";
|
||||
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface|null,
|
||||
@ -185,8 +185,10 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
|
||||
this.load.image(openChatIconName, 'resources/objects/talk.png');
|
||||
this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => {
|
||||
this.scene.start(FourOFourSceneName, {
|
||||
file: file.src
|
||||
this.scene.start(ErrorSceneName, {
|
||||
title: 'Network error',
|
||||
subTitle: 'An error occurred while loading resource:',
|
||||
message: file.src
|
||||
});
|
||||
});
|
||||
this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {gameManager} from "../Game/GameManager";
|
||||
import {Scene} from "phaser";
|
||||
import {LoginSceneName} from "./LoginScene";
|
||||
import {FourOFourSceneName} from "../Reconnecting/FourOFourScene";
|
||||
import {ErrorScene} from "../Reconnecting/ErrorScene";
|
||||
import {WAError} from "../Reconnecting/WAError";
|
||||
|
||||
export const EntrySceneName = "EntryScene";
|
||||
|
||||
@ -20,10 +20,11 @@ export class EntryScene extends Scene {
|
||||
gameManager.init(this.scene).then((nextSceneName) => {
|
||||
this.scene.start(nextSceneName);
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
this.scene.start(FourOFourSceneName, {
|
||||
url: window.location.pathname.toString()
|
||||
});
|
||||
if (err.response && err.response.status == 404) {
|
||||
ErrorScene.showError(new WAError('Page Not Found', 'Could not find map', window.location.pathname), this.scene);
|
||||
} else {
|
||||
ErrorScene.showError(err, this.scene);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
120
front/src/Phaser/Reconnecting/ErrorScene.ts
Normal file
120
front/src/Phaser/Reconnecting/ErrorScene.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import {TextField} from "../Components/TextField";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import Text = Phaser.GameObjects.Text;
|
||||
import ScenePlugin = Phaser.Scenes.ScenePlugin;
|
||||
import {WAError} from "./WAError";
|
||||
|
||||
export const ErrorSceneName = "ErrorScene";
|
||||
enum Textures {
|
||||
icon = "icon",
|
||||
mainFont = "main_font"
|
||||
}
|
||||
|
||||
export class ErrorScene extends Phaser.Scene {
|
||||
private titleField!: TextField;
|
||||
private subTitleField!: TextField;
|
||||
private messageField!: Text;
|
||||
private logo!: Image;
|
||||
private cat!: Sprite;
|
||||
private title!: string;
|
||||
private subTitle!: string;
|
||||
private message!: string;
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
key: ErrorSceneName
|
||||
});
|
||||
}
|
||||
|
||||
init({title, subTitle, message}: { title?: string, subTitle?: string, message?: string }) {
|
||||
this.title = title ? title : '';
|
||||
this.subTitle = subTitle ? subTitle : '';
|
||||
this.message = message ? message : '';
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.image(Textures.icon, "resources/logos/tcm_full.png");
|
||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||
this.load.bitmapFont(Textures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||
this.load.spritesheet(
|
||||
'cat',
|
||||
'resources/characters/pipoya/Cat 01-1.png',
|
||||
{frameWidth: 32, frameHeight: 32}
|
||||
);
|
||||
}
|
||||
|
||||
create() {
|
||||
this.logo = new Image(this, this.game.renderer.width - 30, this.game.renderer.height - 20, Textures.icon);
|
||||
this.add.existing(this.logo);
|
||||
|
||||
this.titleField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2, this.title);
|
||||
|
||||
this.subTitleField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2 + 24, this.subTitle);
|
||||
|
||||
this.messageField = this.add.text(this.game.renderer.width / 2, this.game.renderer.height / 2 + 38, this.message, {
|
||||
fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif',
|
||||
fontSize: '10px'
|
||||
});
|
||||
this.messageField.setOrigin(0.5, 0.5);
|
||||
|
||||
this.cat = this.physics.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, 'cat', 6);
|
||||
this.cat.flipY = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the error page, with an error message matching the "error" parameters passed in.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public static showError(error: any, scene: ScenePlugin): void {
|
||||
console.error(error);
|
||||
|
||||
if (typeof error === 'string' || error instanceof String) {
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'An error occurred',
|
||||
subTitle: error
|
||||
});
|
||||
} else if (error instanceof WAError) {
|
||||
scene.start(ErrorSceneName, {
|
||||
title: error.title,
|
||||
subTitle: error.subTitle,
|
||||
message: error.details
|
||||
});
|
||||
} else if (error.response) {
|
||||
// Axios HTTP error
|
||||
// client received an error response (5xx, 4xx)
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'HTTP ' + error.response.status + ' - ' + error.response.statusText,
|
||||
subTitle: 'An error occurred while accessing URL:',
|
||||
message: error.response.config.url
|
||||
});
|
||||
} else if (error.request) {
|
||||
// Axios HTTP error
|
||||
// client never received a response, or request never left
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'Network error',
|
||||
subTitle: error.message
|
||||
});
|
||||
} else if (error instanceof Error) {
|
||||
// Error
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'An error occurred',
|
||||
subTitle: error.name,
|
||||
message: error.message
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the error page, with an error message matching the "error" parameters passed in.
|
||||
*/
|
||||
public static startErrorPage(title: string, subTitle: string, message: string, scene: ScenePlugin): void {
|
||||
scene.start(ErrorSceneName, {
|
||||
title,
|
||||
subTitle,
|
||||
message
|
||||
});
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
import {TextField} from "../Components/TextField";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import Text = Phaser.GameObjects.Text;
|
||||
|
||||
export const FourOFourSceneName = "FourOFourScene";
|
||||
enum Textures {
|
||||
icon = "icon",
|
||||
mainFont = "main_font"
|
||||
}
|
||||
|
||||
export class FourOFourScene extends Phaser.Scene {
|
||||
private mapNotFoundField!: TextField;
|
||||
private couldNotFindField!: TextField;
|
||||
private fileNameField!: Text;
|
||||
private logo!: Image;
|
||||
private cat!: Sprite;
|
||||
private file: string|undefined;
|
||||
private url: string|undefined;
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
key: FourOFourSceneName
|
||||
});
|
||||
}
|
||||
|
||||
init({ file, url }: { file?: string, url?: string }) {
|
||||
this.file = file;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.image(Textures.icon, "resources/logos/tcm_full.png");
|
||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||
this.load.bitmapFont(Textures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||
this.load.spritesheet(
|
||||
'cat',
|
||||
'resources/characters/pipoya/Cat 01-1.png',
|
||||
{frameWidth: 32, frameHeight: 32}
|
||||
);
|
||||
}
|
||||
|
||||
create() {
|
||||
this.logo = new Image(this, this.game.renderer.width - 30, this.game.renderer.height - 20, Textures.icon);
|
||||
this.add.existing(this.logo);
|
||||
|
||||
this.mapNotFoundField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2, "404 - File not found");
|
||||
|
||||
let text: string = '';
|
||||
if (this.file !== undefined) {
|
||||
text = "Could not load map"
|
||||
}
|
||||
if (this.url !== undefined) {
|
||||
text = "Invalid URL"
|
||||
}
|
||||
|
||||
this.couldNotFindField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2 + 24, text);
|
||||
|
||||
const url = this.file ? this.file : this.url;
|
||||
if (url !== undefined) {
|
||||
this.fileNameField = this.add.text(this.game.renderer.width / 2, this.game.renderer.height / 2 + 38, url, { fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif', fontSize: '10px' });
|
||||
this.fileNameField.setOrigin(0.5, 0.5);
|
||||
}
|
||||
|
||||
this.cat = this.physics.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, 'cat', 6);
|
||||
this.cat.flipY=true;
|
||||
}
|
||||
}
|
26
front/src/Phaser/Reconnecting/WAError.ts
Normal file
26
front/src/Phaser/Reconnecting/WAError.ts
Normal file
@ -0,0 +1,26 @@
|
||||
export class WAError extends Error {
|
||||
private _title: string;
|
||||
private _subTitle: string;
|
||||
private _details: string;
|
||||
|
||||
constructor (title: string, subTitle: string, details: string) {
|
||||
super(title+' - '+subTitle+' - '+details);
|
||||
this._title = title;
|
||||
this._subTitle = subTitle;
|
||||
this._details = details;
|
||||
// Set the prototype explicitly.
|
||||
Object.setPrototypeOf (this, WAError.prototype);
|
||||
}
|
||||
|
||||
get title(): string {
|
||||
return this._title;
|
||||
}
|
||||
|
||||
get subTitle(): string {
|
||||
return this._subTitle;
|
||||
}
|
||||
|
||||
get details(): string {
|
||||
return this._details;
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import {LoginScene} from "./Phaser/Login/LoginScene";
|
||||
import {ReconnectingScene} from "./Phaser/Reconnecting/ReconnectingScene";
|
||||
import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene";
|
||||
import {EnableCameraScene} from "./Phaser/Login/EnableCameraScene";
|
||||
import {FourOFourScene} from "./Phaser/Reconnecting/FourOFourScene";
|
||||
import WebGLRenderer = Phaser.Renderer.WebGL.WebGLRenderer;
|
||||
import {OutlinePipeline} from "./Phaser/Shaders/OutlinePipeline";
|
||||
import {CustomizeScene} from "./Phaser/Login/CustomizeScene";
|
||||
@ -15,6 +14,7 @@ import {EntryScene} from "./Phaser/Login/EntryScene";
|
||||
import {coWebsiteManager} from "./WebRtc/CoWebsiteManager";
|
||||
import {MenuScene} from "./Phaser/Menu/MenuScene";
|
||||
import {localUserStore} from "./Connexion/LocalUserStore";
|
||||
import {ErrorScene} from "./Phaser/Reconnecting/ErrorScene";
|
||||
|
||||
// Load Jitsi if the environment variable is set.
|
||||
if (JITSI_URL) {
|
||||
@ -59,7 +59,7 @@ const config: GameConfig = {
|
||||
width: width / RESOLUTION,
|
||||
height: height / RESOLUTION,
|
||||
parent: "game",
|
||||
scene: [EntryScene, LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, FourOFourScene, CustomizeScene, MenuScene],
|
||||
scene: [EntryScene, LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, ErrorScene, CustomizeScene, MenuScene],
|
||||
zoom: RESOLUTION,
|
||||
fps: fps,
|
||||
dom: {
|
||||
|
@ -278,7 +278,7 @@
|
||||
{
|
||||
"name":"exitUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor1\/floor1.json"
|
||||
"value":"\/@\/tcm\/workadventure\/floor1"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
|
@ -85,7 +85,7 @@
|
||||
{
|
||||
"name":"exitSceneUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor0\/floor0.json#down-the-stairs"
|
||||
"value":"\/@\/tcm\/workadventure\/floor0#down-the-stairs"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
@ -103,7 +103,7 @@
|
||||
{
|
||||
"name":"exitSceneUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor2\/floor2.json#down-the-stairs"
|
||||
"value":"\/@\/tcm\/workadventure\/floor2#down-the-stairs"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
@ -121,7 +121,7 @@
|
||||
{
|
||||
"name":"exitSceneUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor2\/floor2.json#down-the-stairs-secours"
|
||||
"value":"\/@\/tcm\/workadventure\/floor2#down-the-stairs-secours"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
|
@ -103,7 +103,7 @@
|
||||
{
|
||||
"name":"exitSceneUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor1\/floor1.json#down-the-stairs"
|
||||
"value":"\/@\/tcm\/workadventure\/floor1#down-the-stairs"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
@ -139,7 +139,7 @@
|
||||
{
|
||||
"name":"exitSceneUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor1\/floor1.json#down-the-stairs-secours"
|
||||
"value":"\/@\/tcm\/workadventure\/floor1#down-the-stairs-secours"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
|
@ -37,7 +37,7 @@
|
||||
{
|
||||
"name":"exitSceneUrl",
|
||||
"type":"string",
|
||||
"value":"..\/Floor0\/floor0.json"
|
||||
"value":"\/@\/tcm\/workadventure\/floor0"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
|
@ -193,6 +193,11 @@ message SendUserMessage{
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
message BanUserMessage{
|
||||
string type = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
message ServerToClientMessage {
|
||||
oneof message {
|
||||
BatchMessage batchMessage = 1;
|
||||
@ -207,6 +212,7 @@ message ServerToClientMessage {
|
||||
TeleportMessageMessage teleportMessageMessage = 10;
|
||||
SendJitsiJwtMessage sendJitsiJwtMessage = 11;
|
||||
SendUserMessage sendUserMessage = 12;
|
||||
BanUserMessage banUserMessage = 13;
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,6 +226,7 @@ message JoinRoomMessage {
|
||||
string userUuid = 4;
|
||||
string roomId = 5;
|
||||
repeated string tag = 6;
|
||||
string IPAddress = 7;
|
||||
}
|
||||
|
||||
message UserJoinedZoneMessage {
|
||||
@ -272,6 +279,8 @@ message PusherToBackMessage {
|
||||
StopGlobalMessage stopGlobalMessage = 9;
|
||||
ReportPlayerMessage reportPlayerMessage = 10;
|
||||
QueryJitsiJwtMessage queryJitsiJwtMessage = 11;
|
||||
SendUserMessage sendUserMessage = 12;
|
||||
BanUserMessage banUserMessage = 13;
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,6 +297,7 @@ message SubToPusherMessage {
|
||||
UserLeftZoneMessage userLeftZoneMessage = 5;
|
||||
ItemEventMessage itemEventMessage = 6;
|
||||
SendUserMessage sendUserMessage = 7;
|
||||
BanUserMessage banUserMessage = 8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,10 +316,20 @@ message ServerToAdminClientMessage {
|
||||
repeated SubToAdminPusherMessage payload = 2;
|
||||
}*/
|
||||
|
||||
message UserJoinedRoomMessage {
|
||||
string uuid = 1;
|
||||
string ipAddress = 2;
|
||||
string name = 3;
|
||||
}
|
||||
|
||||
message UserLeftRoomMessage {
|
||||
string uuid = 1;
|
||||
}
|
||||
|
||||
message ServerToAdminClientMessage {
|
||||
oneof message {
|
||||
string userUuidJoinedRoom = 1;
|
||||
string userUuidLeftRoom = 2;
|
||||
UserJoinedRoomMessage userJoinedRoom = 1;
|
||||
UserLeftRoomMessage userLeftRoom = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
"runprod": "node --max-old-space-size=4096 ./dist/server.js",
|
||||
"profile": "tsc && node --prof ./dist/server.js",
|
||||
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
||||
"lint": "node_modules/.bin/eslint src/ . --ext .ts",
|
||||
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts"
|
||||
"lint": "DEBUG= node_modules/.bin/eslint src/ . --ext .ts",
|
||||
"fix": "DEBUG= node_modules/.bin/eslint --fix src/ . --ext .ts"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -60,10 +60,7 @@ export class AuthenticateController extends BaseController {
|
||||
}));
|
||||
|
||||
} catch (e) {
|
||||
console.error("An error happened", e)
|
||||
res.writeStatus(e.status || "500 Internal Server Error");
|
||||
this.addCorsHeaders(res);
|
||||
res.end('An error happened');
|
||||
this.errorToResponse(e, res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,4 +8,21 @@ export class BaseController {
|
||||
res.writeHeader('access-control-allow-methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
|
||||
res.writeHeader('access-control-allow-origin', '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns any exception into a HTTP response (and logs the error)
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
protected errorToResponse(e: any, res: HttpResponse): void {
|
||||
console.error("An error happened", e);
|
||||
if (e.response) {
|
||||
res.writeStatus(e.response.status+" "+e.response.statusText);
|
||||
this.addCorsHeaders(res);
|
||||
res.end("An error occurred: "+e.response.status+" "+e.response.statusText);
|
||||
} else {
|
||||
res.writeStatus("500 Internal Server Error")
|
||||
this.addCorsHeaders(res);
|
||||
res.end("An error occurred");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,18 +91,11 @@ export class IoSocketController {
|
||||
|
||||
if(message.event === 'user-message') {
|
||||
const messageToEmit = (message.message as { message: string, type: string, userUuid: string });
|
||||
switch (message.message.type) {
|
||||
case 'ban': {
|
||||
socketManager.emitSendUserMessage(messageToEmit.userUuid, messageToEmit.message, roomId);
|
||||
break;
|
||||
}
|
||||
case 'banned': {
|
||||
socketManager.emitBan(messageToEmit.userUuid, messageToEmit.message, roomId);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
if(messageToEmit.type === 'banned'){
|
||||
socketManager.emitBan(messageToEmit.userUuid, messageToEmit.message, messageToEmit.type);
|
||||
}
|
||||
if(messageToEmit.type === 'ban') {
|
||||
socketManager.emitSendUserMessage(messageToEmit.userUuid, messageToEmit.message, messageToEmit.type);
|
||||
}
|
||||
}
|
||||
}catch (err) {
|
||||
@ -148,6 +141,7 @@ export class IoSocketController {
|
||||
const websocketKey = req.getHeader('sec-websocket-key');
|
||||
const websocketProtocol = req.getHeader('sec-websocket-protocol');
|
||||
const websocketExtensions = req.getHeader('sec-websocket-extensions');
|
||||
const IPAddress = req.getHeader('x-forwarded-for');
|
||||
|
||||
const roomId = query.roomId;
|
||||
if (typeof roomId !== 'string') {
|
||||
@ -176,7 +170,7 @@ export class IoSocketController {
|
||||
characterLayers = [ characterLayers ];
|
||||
}
|
||||
|
||||
const userUuid = await jwtTokenManager.getUserUuidFromToken(token);
|
||||
const userUuid = await jwtTokenManager.getUserUuidFromToken(token, IPAddress, roomId);
|
||||
|
||||
let memberTags: string[] = [];
|
||||
let memberTextures: CharacterTexture[] = [];
|
||||
@ -217,6 +211,7 @@ export class IoSocketController {
|
||||
url,
|
||||
token,
|
||||
userUuid,
|
||||
IPAddress,
|
||||
roomId,
|
||||
name,
|
||||
characterLayers: characterLayerObjs,
|
||||
@ -336,6 +331,7 @@ export class IoSocketController {
|
||||
client.userId = this.nextUserId;
|
||||
this.nextUserId++;
|
||||
client.userUuid = ws.userUuid;
|
||||
client.IPAddress = ws.IPAddress;
|
||||
client.token = ws.token;
|
||||
client.batchedMessages = new BatchMessage();
|
||||
client.batchTimeout = null;
|
||||
|
@ -59,10 +59,7 @@ export class MapController extends BaseController{
|
||||
this.addCorsHeaders(res);
|
||||
res.end(JSON.stringify(mapDetails));
|
||||
} catch (e) {
|
||||
console.error(e.message || e);
|
||||
res.writeStatus("500 Internal Server Error")
|
||||
this.addCorsHeaders(res);
|
||||
res.end("An error occurred");
|
||||
this.errorToResponse(e, res);
|
||||
}
|
||||
})();
|
||||
|
||||
|
@ -24,6 +24,7 @@ export interface ExSocketInterface extends WebSocket, Identificable {
|
||||
roomId: string;
|
||||
//userId: number; // A temporary (autoincremented) identifier for this user
|
||||
userUuid: string; // A unique identifier for this user
|
||||
IPAddress: string; // IP address
|
||||
name: string;
|
||||
characterLayers: CharacterLayer[];
|
||||
position: PointInterface;
|
||||
|
@ -14,6 +14,11 @@ export interface AdminApiData {
|
||||
textures: CharacterTexture[]
|
||||
}
|
||||
|
||||
export interface AdminBannedData {
|
||||
is_banned: boolean,
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface CharacterTexture {
|
||||
id: number,
|
||||
level: number,
|
||||
@ -110,6 +115,18 @@ class AdminApi {
|
||||
headers: {"Authorization": `${ADMIN_API_TOKEN}`}
|
||||
});
|
||||
}
|
||||
|
||||
async verifyBanUser(organizationMemberToken: string, ipAddress: string, organization: string, world: string): Promise<AdminBannedData> {
|
||||
if (!ADMIN_API_URL) {
|
||||
return Promise.reject('No admin backoffice set!');
|
||||
}
|
||||
//todo: this call can fail if the corresponding world is not activated or if the token is invalid. Handle that case.
|
||||
return Axios.get(ADMIN_API_URL + '/api/check-moderate-user/'+organization+'/'+world+'?ipAddress='+ipAddress+'&token='+organizationMemberToken,
|
||||
{headers: {"Authorization": `${ADMIN_API_TOKEN}`}}
|
||||
).then((data) => {
|
||||
return data.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const adminApi = new AdminApi();
|
||||
|
@ -2,7 +2,7 @@ import {ADMIN_API_URL, ALLOW_ARTILLERY, SECRET_KEY} from "../Enum/EnvironmentVar
|
||||
import {uuid} from "uuidv4";
|
||||
import Jwt from "jsonwebtoken";
|
||||
import {TokenInterface} from "../Controller/AuthenticateController";
|
||||
import {adminApi, AdminApiData} from "../Services/AdminApi";
|
||||
import {adminApi, AdminBannedData} from "../Services/AdminApi";
|
||||
|
||||
class JWTTokenManager {
|
||||
|
||||
@ -10,7 +10,7 @@ class JWTTokenManager {
|
||||
return Jwt.sign({userUuid: userUuid}, SECRET_KEY, {expiresIn: '200d'}); //todo: add a mechanic to refresh or recreate token
|
||||
}
|
||||
|
||||
public async getUserUuidFromToken(token: unknown): Promise<string> {
|
||||
public async getUserUuidFromToken(token: unknown, ipAddress?: string, room?: string): Promise<string> {
|
||||
|
||||
if (!token) {
|
||||
throw new Error('An authentication error happened, a user tried to connect without a token.');
|
||||
@ -50,14 +50,22 @@ class JWTTokenManager {
|
||||
|
||||
if (ADMIN_API_URL) {
|
||||
//verify user in admin
|
||||
adminApi.fetchCheckUserByToken(tokenInterface.userUuid).then(() => {
|
||||
resolve(tokenInterface.userUuid);
|
||||
}).catch((err) => {
|
||||
//anonymous user
|
||||
if(err.response && err.response.status && err.response.status === 404){
|
||||
let promise = new Promise((resolve) => resolve());
|
||||
if(ipAddress && room) {
|
||||
promise = this.verifyBanUser(tokenInterface.userUuid, ipAddress, room);
|
||||
}
|
||||
promise.then(() => {
|
||||
adminApi.fetchCheckUserByToken(tokenInterface.userUuid).then(() => {
|
||||
resolve(tokenInterface.userUuid);
|
||||
return;
|
||||
}
|
||||
}).catch((err) => {
|
||||
//anonymous user
|
||||
if (err.response && err.response.status && err.response.status === 404) {
|
||||
resolve(tokenInterface.userUuid);
|
||||
return;
|
||||
}
|
||||
reject(err);
|
||||
});
|
||||
}).catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
@ -67,6 +75,27 @@ class JWTTokenManager {
|
||||
});
|
||||
}
|
||||
|
||||
private verifyBanUser(userUuid: string, ipAddress: string, room: string): Promise<AdminBannedData> {
|
||||
const parts = room.split('/');
|
||||
if (parts.length < 3 || parts[0] !== '@') {
|
||||
return Promise.resolve({
|
||||
is_banned: false,
|
||||
message: ''
|
||||
});
|
||||
}
|
||||
|
||||
const organization = parts[1];
|
||||
const world = parts[2];
|
||||
return adminApi.verifyBanUser(userUuid, ipAddress, organization, world).then((data: AdminBannedData) => {
|
||||
if (data && data.is_banned) {
|
||||
throw new Error('User was banned');
|
||||
}
|
||||
return data;
|
||||
}).catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
private isValidToken(token: object): token is TokenInterface {
|
||||
return !(typeof((token as TokenInterface).userUuid) !== 'string');
|
||||
}
|
||||
|
@ -2,11 +2,8 @@ import {PusherRoom} from "../Model/PusherRoom";
|
||||
import {CharacterLayer, ExSocketInterface} from "../Model/Websocket/ExSocketInterface";
|
||||
import {
|
||||
GroupDeleteMessage,
|
||||
GroupUpdateMessage,
|
||||
ItemEventMessage,
|
||||
ItemStateMessage,
|
||||
PlayGlobalMessage,
|
||||
PointMessage,
|
||||
PositionMessage,
|
||||
RoomJoinedMessage,
|
||||
ServerToClientMessage,
|
||||
@ -14,23 +11,19 @@ import {
|
||||
SilentMessage,
|
||||
SubMessage,
|
||||
ReportPlayerMessage,
|
||||
UserJoinedMessage,
|
||||
UserLeftMessage,
|
||||
UserMovedMessage,
|
||||
UserMovesMessage,
|
||||
ViewportMessage,
|
||||
WebRtcDisconnectMessage,
|
||||
WebRtcSignalToClientMessage,
|
||||
WebRtcSignalToServerMessage,
|
||||
WebRtcStartMessage,
|
||||
QueryJitsiJwtMessage,
|
||||
SendJitsiJwtMessage,
|
||||
SendUserMessage,
|
||||
JoinRoomMessage,
|
||||
CharacterLayerMessage,
|
||||
PusherToBackMessage,
|
||||
AdminPusherToBackMessage,
|
||||
ServerToAdminClientMessage, AdminMessage, BanMessage
|
||||
ServerToAdminClientMessage,
|
||||
SendUserMessage,
|
||||
BanUserMessage, UserJoinedRoomMessage, UserLeftRoomMessage
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import {PointInterface} from "../Model/Websocket/PointInterface";
|
||||
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
||||
@ -79,23 +72,33 @@ export class SocketManager implements ZoneEventListener {
|
||||
}
|
||||
|
||||
async handleAdminRoom(client: ExAdminSocketInterface, roomId: string): Promise<void> {
|
||||
console.log('Calling adminRoom')
|
||||
const apiClient = await apiClientRepository.getClient(roomId);
|
||||
const adminRoomStream = apiClient.adminRoom();
|
||||
client.adminConnection = adminRoomStream;
|
||||
|
||||
adminRoomStream.on('data', (message: ServerToAdminClientMessage) => {
|
||||
if (message.hasUseruuidjoinedroom()) {
|
||||
const userUuid = message.getUseruuidjoinedroom();
|
||||
|
||||
if (message.hasUserjoinedroom()) {
|
||||
const userJoinedRoomMessage = message.getUserjoinedroom() as UserJoinedRoomMessage;
|
||||
if (!client.disconnecting) {
|
||||
client.send('MemberJoin:'+userUuid+';'+roomId);
|
||||
client.send(JSON.stringify({
|
||||
type: 'MemberJoin',
|
||||
data: {
|
||||
uuid: userJoinedRoomMessage.getUuid(),
|
||||
name: userJoinedRoomMessage.getName(),
|
||||
ipAddress: userJoinedRoomMessage.getIpaddress(),
|
||||
roomId: roomId,
|
||||
}
|
||||
}));
|
||||
}
|
||||
} else if (message.hasUseruuidleftroom()) {
|
||||
const userUuid = message.getUseruuidleftroom();
|
||||
|
||||
} else if (message.hasUserleftroom()) {
|
||||
const userLeftRoomMessage = message.getUserleftroom() as UserLeftRoomMessage;
|
||||
if (!client.disconnecting) {
|
||||
client.send('MemberLeave:'+userUuid+';'+roomId);
|
||||
client.send(JSON.stringify({
|
||||
type: 'MemberLeave',
|
||||
data: {
|
||||
uuid: userLeftRoomMessage.getUuid()
|
||||
}
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unexpected admin message');
|
||||
@ -145,15 +148,16 @@ export class SocketManager implements ZoneEventListener {
|
||||
}
|
||||
|
||||
async handleJoinRoom(client: ExSocketInterface): Promise<void> {
|
||||
const position = client.position;
|
||||
const viewport = client.viewport;
|
||||
try {
|
||||
|
||||
const joinRoomMessage = new JoinRoomMessage();
|
||||
joinRoomMessage.setUseruuid(client.userUuid);
|
||||
joinRoomMessage.setIpaddress(client.IPAddress);
|
||||
joinRoomMessage.setRoomid(client.roomId);
|
||||
joinRoomMessage.setName(client.name);
|
||||
joinRoomMessage.setPositionmessage(ProtobufUtils.toPositionMessage(client.position));
|
||||
joinRoomMessage.setTagList(client.tags);
|
||||
for (const characterLayer of client.characterLayers) {
|
||||
const characterLayerMessage = new CharacterLayerMessage();
|
||||
characterLayerMessage.setName(characterLayer.name);
|
||||
@ -540,51 +544,54 @@ export class SocketManager implements ZoneEventListener {
|
||||
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
||||
}
|
||||
|
||||
public async emitSendUserMessage(userUuid: string, message: string, roomId: string): Promise<void> {
|
||||
public emitSendUserMessage(userUuid: string, message: string, type: string): void {
|
||||
const client = this.searchClientByUuid(userUuid);
|
||||
if(!client){
|
||||
throw Error('client not found');
|
||||
}
|
||||
|
||||
const backConnection = await apiClientRepository.getClient(roomId);
|
||||
|
||||
const adminMessage = new AdminMessage();
|
||||
adminMessage.setRecipientuuid(userUuid);
|
||||
const adminMessage = new SendUserMessage();
|
||||
adminMessage.setMessage(message);
|
||||
adminMessage.setRoomid(roomId);
|
||||
adminMessage.setType(type);
|
||||
const pusherToBackMessage = new PusherToBackMessage();
|
||||
pusherToBackMessage.setSendusermessage(adminMessage);
|
||||
client.backConnection.write(pusherToBackMessage);
|
||||
|
||||
/*const backConnection = await apiClientRepository.getClient(client.roomId);
|
||||
const adminMessage = new AdminMessage();
|
||||
adminMessage.setMessage(message);
|
||||
adminMessage.setRoomid(client.roomId);
|
||||
adminMessage.setRecipientuuid(client.userUuid);
|
||||
backConnection.sendAdminMessage(adminMessage, (error) => {
|
||||
if (error !== null) {
|
||||
console.error('Error while sending admin message', error);
|
||||
}
|
||||
});
|
||||
/*
|
||||
const socket = this.searchClientByUuid(messageToSend.userUuid);
|
||||
if(!socket){
|
||||
throw 'socket was not found';
|
||||
}
|
||||
|
||||
const sendUserMessage = new SendUserMessage();
|
||||
sendUserMessage.setMessage(messageToSend.message);
|
||||
sendUserMessage.setType(messageToSend.type);
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
serverToClientMessage.setSendusermessage(sendUserMessage);
|
||||
|
||||
if (!socket.disconnecting) {
|
||||
socket.send(serverToClientMessage.serializeBinary().buffer, true);
|
||||
}
|
||||
return socket;*/
|
||||
});*/
|
||||
}
|
||||
|
||||
public async emitBan(userUuid: string, message: string, roomId: string): Promise<void> {
|
||||
const backConnection = await apiClientRepository.getClient(roomId);
|
||||
public emitBan(userUuid: string, message: string, type: string): void {
|
||||
const client = this.searchClientByUuid(userUuid);
|
||||
if(!client){
|
||||
throw Error('client not found');
|
||||
}
|
||||
|
||||
const banMessage = new BanMessage();
|
||||
banMessage.setRecipientuuid(userUuid);
|
||||
banMessage.setRoomid(roomId);
|
||||
const banUserMessage = new BanUserMessage();
|
||||
banUserMessage.setMessage(message);
|
||||
banUserMessage.setType(type);
|
||||
const pusherToBackMessage = new PusherToBackMessage();
|
||||
pusherToBackMessage.setBanusermessage(banUserMessage);
|
||||
client.backConnection.write(pusherToBackMessage);
|
||||
|
||||
backConnection.ban(banMessage, (error) => {
|
||||
/*const backConnection = await apiClientRepository.getClient(client.roomId);
|
||||
const adminMessage = new AdminMessage();
|
||||
adminMessage.setMessage(message);
|
||||
adminMessage.setRoomid(client.roomId);
|
||||
adminMessage.setRecipientuuid(client.userUuid);
|
||||
backConnection.sendAdminMessage(adminMessage, (error) => {
|
||||
if (error !== null) {
|
||||
console.error('Error while sending ban message', error);
|
||||
console.error('Error while sending admin message', error);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user