Users blocking now rely on UUID rather than ID

This way, if a user A blocks another user B, if user B refreshes the browser or leaves and re-enters the room, user B will still be blocked.
As a side effect, this allows us to completely remove the "sockets" property in the SocketManager on the Pusher.
This commit is contained in:
David Négrier 2021-07-07 11:24:51 +02:00
parent 28e4f59e50
commit 34cb0ebf39
15 changed files with 143 additions and 141 deletions

View file

@ -16,6 +16,7 @@
- Use `WA.room.getCurrentRoom(): Promise<Room>` to get the ID, JSON map file, url of the map of the current room and the layer where the current player started - Use `WA.room.getCurrentRoom(): Promise<Room>` to get the ID, JSON map file, url of the map of the current room and the layer where the current player started
- Use `WA.ui.registerMenuCommand(): void` to add a custom menu - Use `WA.ui.registerMenuCommand(): void` to add a custom menu
- Use `WA.room.setTiles(): void` to change an array of tiles - Use `WA.room.setTiles(): void` to change an array of tiles
- Users blocking now relies on UUID rather than ID. A blocked user that leaves a room and comes back will stay blocked.
## Version 1.4.3 - 1.4.4 - 1.4.5 ## Version 1.4.3 - 1.4.4 - 1.4.5

View file

@ -308,6 +308,7 @@ export class SocketManager {
throw new Error("clientUser.userId is not an integer " + thing.id); throw new Error("clientUser.userId is not an integer " + thing.id);
} }
userJoinedZoneMessage.setUserid(thing.id); userJoinedZoneMessage.setUserid(thing.id);
userJoinedZoneMessage.setUseruuid(thing.uuid);
userJoinedZoneMessage.setName(thing.name); userJoinedZoneMessage.setName(thing.name);
userJoinedZoneMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers)); userJoinedZoneMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers));
userJoinedZoneMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition())); userJoinedZoneMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition()));
@ -612,6 +613,7 @@ export class SocketManager {
if (thing instanceof User) { if (thing instanceof User) {
const userJoinedMessage = new UserJoinedZoneMessage(); const userJoinedMessage = new UserJoinedZoneMessage();
userJoinedMessage.setUserid(thing.id); userJoinedMessage.setUserid(thing.id);
userJoinedMessage.setUseruuid(thing.uuid);
userJoinedMessage.setName(thing.name); userJoinedMessage.setName(thing.name);
userJoinedMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers)); userJoinedMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers));
userJoinedMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition())); userJoinedMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition()));

View file

@ -1,8 +1,8 @@
import type {SignalData} from "simple-peer"; import type { SignalData } from "simple-peer";
import type {RoomConnection} from "./RoomConnection"; import type { RoomConnection } from "./RoomConnection";
import type {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures"; import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures";
export enum EventMessage{ export enum EventMessage {
CONNECT = "connect", CONNECT = "connect",
WEBRTC_SIGNAL = "webrtc-signal", WEBRTC_SIGNAL = "webrtc-signal",
WEBRTC_SCREEN_SHARING_SIGNAL = "webrtc-screen-sharing-signal", WEBRTC_SCREEN_SHARING_SIGNAL = "webrtc-screen-sharing-signal",
@ -17,7 +17,7 @@ export enum EventMessage{
GROUP_CREATE_UPDATE = "group-create-update", GROUP_CREATE_UPDATE = "group-create-update",
GROUP_DELETE = "group-delete", GROUP_DELETE = "group-delete",
SET_PLAYER_DETAILS = "set-player-details", // Send the name and character to the server (on connect), receive back the id. SET_PLAYER_DETAILS = "set-player-details", // Send the name and character to the server (on connect), receive back the id.
ITEM_EVENT = 'item-event', ITEM_EVENT = "item-event",
CONNECT_ERROR = "connect_error", CONNECT_ERROR = "connect_error",
CONNECTING_ERROR = "connecting_error", CONNECTING_ERROR = "connecting_error",
@ -36,7 +36,7 @@ export enum EventMessage{
export interface PointInterface { export interface PointInterface {
x: number; x: number;
y: number; y: number;
direction : string; direction: string;
moving: boolean; moving: boolean;
} }
@ -45,8 +45,9 @@ export interface MessageUserPositionInterface {
name: string; name: string;
characterLayers: BodyResourceDescriptionInterface[]; characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface; position: PointInterface;
visitCardUrl: string|null; visitCardUrl: string | null;
companion: string|null; companion: string | null;
userUuid: string;
} }
export interface MessageUserMovedInterface { export interface MessageUserMovedInterface {
@ -60,58 +61,59 @@ export interface MessageUserJoined {
characterLayers: BodyResourceDescriptionInterface[]; characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface; position: PointInterface;
visitCardUrl: string | null; visitCardUrl: string | null;
companion: string|null; companion: string | null;
userUuid: string;
} }
export interface PositionInterface { export interface PositionInterface {
x: number, x: number;
y: number y: number;
} }
export interface GroupCreatedUpdatedMessageInterface { export interface GroupCreatedUpdatedMessageInterface {
position: PositionInterface, position: PositionInterface;
groupId: number, groupId: number;
groupSize: number groupSize: number;
} }
export interface WebRtcDisconnectMessageInterface { export interface WebRtcDisconnectMessageInterface {
userId: number userId: number;
} }
export interface WebRtcSignalReceivedMessageInterface { export interface WebRtcSignalReceivedMessageInterface {
userId: number, userId: number;
signal: SignalData, signal: SignalData;
webRtcUser: string | undefined, webRtcUser: string | undefined;
webRtcPassword: string | undefined webRtcPassword: string | undefined;
} }
export interface ViewportInterface { export interface ViewportInterface {
left: number, left: number;
top: number, top: number;
right: number, right: number;
bottom: number, bottom: number;
} }
export interface ItemEventMessageInterface { export interface ItemEventMessageInterface {
itemId: number, itemId: number;
event: string, event: string;
state: unknown, state: unknown;
parameters: unknown parameters: unknown;
} }
export interface RoomJoinedMessageInterface { export interface RoomJoinedMessageInterface {
//users: MessageUserPositionInterface[], //users: MessageUserPositionInterface[],
//groups: GroupCreatedUpdatedMessageInterface[], //groups: GroupCreatedUpdatedMessageInterface[],
items: { [itemId: number] : unknown } items: { [itemId: number]: unknown };
} }
export interface PlayGlobalMessageInterface { export interface PlayGlobalMessageInterface {
id: string id: string;
type: string type: string;
message: string message: string;
} }
export interface OnConnectInterface { export interface OnConnectInterface {
connection: RoomConnection, connection: RoomConnection;
room: RoomJoinedMessageInterface room: RoomJoinedMessageInterface;
} }

View file

@ -365,6 +365,7 @@ export class RoomConnection implements RoomConnection {
visitCardUrl: message.getVisitcardurl(), visitCardUrl: message.getVisitcardurl(),
position: ProtobufClientUtils.toPointInterface(position), position: ProtobufClientUtils.toPointInterface(position),
companion: companion ? companion.getName() : null, companion: companion ? companion.getName() : null,
userUuid: message.getUseruuid(),
}; };
} }
@ -591,9 +592,9 @@ export class RoomConnection implements RoomConnection {
this.socket.send(clientToServerMessage.serializeBinary().buffer); this.socket.send(clientToServerMessage.serializeBinary().buffer);
} }
public emitReportPlayerMessage(reportedUserId: number, reportComment: string): void { public emitReportPlayerMessage(reportedUserUuid: string, reportComment: string): void {
const reportPlayerMessage = new ReportPlayerMessage(); const reportPlayerMessage = new ReportPlayerMessage();
reportPlayerMessage.setReporteduserid(reportedUserId); reportPlayerMessage.setReporteduseruuid(reportedUserUuid);
reportPlayerMessage.setReportcomment(reportComment); reportPlayerMessage.setReportcomment(reportComment);
const clientToServerMessage = new ClientToServerMessage(); const clientToServerMessage = new ClientToServerMessage();

View file

@ -91,7 +91,7 @@ import { soundManager } from "./SoundManager";
import { peerStore, screenSharingPeerStore } from "../../Stores/PeerStore"; import { peerStore, screenSharingPeerStore } from "../../Stores/PeerStore";
import { videoFocusStore } from "../../Stores/VideoFocusStore"; import { videoFocusStore } from "../../Stores/VideoFocusStore";
import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore";
import {playersStore} from "../../Stores/PlayersStore"; import { playersStore } from "../../Stores/PlayersStore";
export interface GameSceneInitInterface { export interface GameSceneInitInterface {
initPosition: PointInterface | null; initPosition: PointInterface | null;
@ -608,6 +608,7 @@ export class GameScene extends DirtyScene {
position: message.position, position: message.position,
visitCardUrl: message.visitCardUrl, visitCardUrl: message.visitCardUrl,
companion: message.companion, companion: message.companion,
userUuid: message.userUuid,
}; };
this.addPlayer(userMessage); this.addPlayer(userMessage);
}); });
@ -1047,7 +1048,7 @@ ${escapedMessage}
}) })
); );
iframeListener.registerAnswerer('getState', () => { iframeListener.registerAnswerer("getState", () => {
return { return {
mapUrl: this.MapUrlFile, mapUrl: this.MapUrlFile,
startLayerName: this.startPositionCalculator.startLayerName, startLayerName: this.startPositionCalculator.startLayerName,
@ -1150,7 +1151,7 @@ ${escapedMessage}
this.emoteManager.destroy(); this.emoteManager.destroy();
this.peerStoreUnsubscribe(); this.peerStoreUnsubscribe();
this.biggestAvailableAreaStoreUnsubscribe(); this.biggestAvailableAreaStoreUnsubscribe();
iframeListener.unregisterAnswerer('getState'); iframeListener.unregisterAnswerer("getState");
mediaManager.hideGameOverlay(); mediaManager.hideGameOverlay();

View file

@ -1,9 +1,10 @@
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; import type { BodyResourceDescriptionInterface } from "../Entity/PlayerTextures";
export interface PlayerInterface { export interface PlayerInterface {
userId: number; userId: number;
name: string; name: string;
characterLayers: BodyResourceDescriptionInterface[]; characterLayers: BodyResourceDescriptionInterface[];
visitCardUrl: string|null; visitCardUrl: string | null;
companion: string|null; companion: string | null;
userUuid: string;
} }

View file

@ -18,6 +18,7 @@ import { registerMenuCommandStream } from "../../Api/Events/ui/MenuItemRegisterE
import { sendMenuClickedEvent } from "../../Api/iframe/Ui/MenuItem"; import { sendMenuClickedEvent } from "../../Api/iframe/Ui/MenuItem";
import { consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore"; import { consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { playersStore } from "../../Stores/PlayersStore";
export const MenuSceneName = "MenuScene"; export const MenuSceneName = "MenuScene";
const gameMenuKey = "gameMenu"; const gameMenuKey = "gameMenu";
@ -120,7 +121,11 @@ export class MenuScene extends Phaser.Scene {
showReportScreenStore.subscribe((user) => { showReportScreenStore.subscribe((user) => {
if (user !== null) { if (user !== null) {
this.closeAll(); this.closeAll();
this.gameReportElement.open(user.userId, user.userName); const uuid = playersStore.getPlayerById(user.userId)?.userUuid;
if (uuid === undefined) {
throw new Error("Could not find UUID for user with ID " + user.userId);
}
this.gameReportElement.open(uuid, user.userName);
} }
}); });

View file

@ -1,15 +1,16 @@
import {MenuScene} from "./MenuScene"; import { MenuScene } from "./MenuScene";
import {gameManager} from "../Game/GameManager"; import { gameManager } from "../Game/GameManager";
import {blackListManager} from "../../WebRtc/BlackListManager"; import { blackListManager } from "../../WebRtc/BlackListManager";
import { playersStore } from "../../Stores/PlayersStore";
export const gameReportKey = 'gameReport'; export const gameReportKey = "gameReport";
export const gameReportRessource = 'resources/html/gameReport.html'; export const gameReportRessource = "resources/html/gameReport.html";
export class ReportMenu extends Phaser.GameObjects.DOMElement { export class ReportMenu extends Phaser.GameObjects.DOMElement {
private opened: boolean = false; private opened: boolean = false;
private userId!: number; private userUuid!: string;
private userName!: string|undefined; private userName!: string | undefined;
private anonymous: boolean; private anonymous: boolean;
constructor(scene: Phaser.Scene, anonymous: boolean) { constructor(scene: Phaser.Scene, anonymous: boolean) {
@ -18,46 +19,46 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
this.createFromCache(gameReportKey); this.createFromCache(gameReportKey);
if (this.anonymous) { if (this.anonymous) {
const divToHide = this.getChildByID('reportSection') as HTMLElement; const divToHide = this.getChildByID("reportSection") as HTMLElement;
divToHide.hidden = true; divToHide.hidden = true;
const textToHide = this.getChildByID('askActionP') as HTMLElement; const textToHide = this.getChildByID("askActionP") as HTMLElement;
textToHide.hidden = true; textToHide.hidden = true;
} }
scene.add.existing(this); scene.add.existing(this);
MenuScene.revealMenusAfterInit(this, gameReportKey); MenuScene.revealMenusAfterInit(this, gameReportKey);
this.addListener('click'); this.addListener("click");
this.on('click', (event:MouseEvent) => { this.on("click", (event: MouseEvent) => {
event.preventDefault(); event.preventDefault();
if ((event?.target as HTMLInputElement).id === 'gameReportFormSubmit') { if ((event?.target as HTMLInputElement).id === "gameReportFormSubmit") {
this.submitReport(); this.submitReport();
} else if((event?.target as HTMLInputElement).id === 'gameReportFormCancel') { } else if ((event?.target as HTMLInputElement).id === "gameReportFormCancel") {
this.close(); this.close();
} else if((event?.target as HTMLInputElement).id === 'toggleBlockButton') { } else if ((event?.target as HTMLInputElement).id === "toggleBlockButton") {
this.toggleBlock(); this.toggleBlock();
} }
}); });
} }
public open(userId: number, userName: string|undefined): void { public open(userUuid: string, userName: string | undefined): void {
if (this.opened) { if (this.opened) {
this.close(); this.close();
return; return;
} }
this.userId = userId; this.userUuid = userUuid;
this.userName = userName; this.userName = userName;
const mainEl = this.getChildByID('gameReport') as HTMLElement; const mainEl = this.getChildByID("gameReport") as HTMLElement;
this.x = this.getCenteredX(mainEl); this.x = this.getCenteredX(mainEl);
this.y = this.getHiddenY(mainEl); this.y = this.getHiddenY(mainEl);
const gameTitleReport = this.getChildByID('nameReported') as HTMLElement; const gameTitleReport = this.getChildByID("nameReported") as HTMLElement;
gameTitleReport.innerText = userName || ''; gameTitleReport.innerText = userName || "";
const blockButton = this.getChildByID('toggleBlockButton') as HTMLElement; const blockButton = this.getChildByID("toggleBlockButton") as HTMLElement;
blockButton.innerText = blackListManager.isBlackListed(this.userId) ? 'Unblock this user' : 'Block this user'; blockButton.innerText = blackListManager.isBlackListed(this.userUuid) ? "Unblock this user" : "Block this user";
this.opened = true; this.opened = true;
@ -67,19 +68,19 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
targets: this, targets: this,
y: this.getCenteredY(mainEl), y: this.getCenteredY(mainEl),
duration: 1000, duration: 1000,
ease: 'Power3' ease: "Power3",
}); });
} }
public close(): void { public close(): void {
gameManager.getCurrentGameScene(this.scene).userInputManager.restoreControls(); gameManager.getCurrentGameScene(this.scene).userInputManager.restoreControls();
this.opened = false; this.opened = false;
const mainEl = this.getChildByID('gameReport') as HTMLElement; const mainEl = this.getChildByID("gameReport") as HTMLElement;
this.scene.tweens.add({ this.scene.tweens.add({
targets: this, targets: this,
y: this.getHiddenY(mainEl), y: this.getHiddenY(mainEl),
duration: 1000, duration: 1000,
ease: 'Power3' ease: "Power3",
}); });
} }
@ -88,31 +89,32 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
return window.innerWidth / 4 - mainEl.clientWidth / 2; return window.innerWidth / 4 - mainEl.clientWidth / 2;
} }
private getHiddenY(mainEl: HTMLElement): number { private getHiddenY(mainEl: HTMLElement): number {
return - mainEl.clientHeight - 50; return -mainEl.clientHeight - 50;
} }
private getCenteredY(mainEl: HTMLElement): number { private getCenteredY(mainEl: HTMLElement): number {
return window.innerHeight / 4 - mainEl.clientHeight / 2; return window.innerHeight / 4 - mainEl.clientHeight / 2;
} }
private toggleBlock(): void { private toggleBlock(): void {
!blackListManager.isBlackListed(this.userId) ? blackListManager.blackList(this.userId) : blackListManager.cancelBlackList(this.userId); !blackListManager.isBlackListed(this.userUuid)
? blackListManager.blackList(this.userUuid)
: blackListManager.cancelBlackList(this.userUuid);
this.close(); this.close();
} }
private submitReport(): void{ private submitReport(): void {
const gamePError = this.getChildByID('gameReportErr') as HTMLParagraphElement; const gamePError = this.getChildByID("gameReportErr") as HTMLParagraphElement;
gamePError.innerText = ''; gamePError.innerText = "";
gamePError.style.display = 'none'; gamePError.style.display = "none";
const gameTextArea = this.getChildByID('gameReportInput') as HTMLInputElement; const gameTextArea = this.getChildByID("gameReportInput") as HTMLInputElement;
if(!gameTextArea || !gameTextArea.value){ if (!gameTextArea || !gameTextArea.value) {
gamePError.innerText = 'Report message cannot to be empty.'; gamePError.innerText = "Report message cannot to be empty.";
gamePError.style.display = 'block'; gamePError.style.display = "block";
return; return;
} }
gameManager.getCurrentGameScene(this.scene).connection?.emitReportPlayerMessage( gameManager
this.userId, .getCurrentGameScene(this.scene)
gameTextArea.value .connection?.emitReportPlayerMessage(this.userUuid, gameTextArea.value);
);
this.close(); this.close();
} }
} }

View file

@ -1,6 +1,6 @@
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import type {PlayerInterface} from "../Phaser/Game/PlayerInterface"; import type { PlayerInterface } from "../Phaser/Game/PlayerInterface";
import type {RoomConnection} from "../Connexion/RoomConnection"; import type { RoomConnection } from "../Connexion/RoomConnection";
/** /**
* A store that contains the list of players currently known. * A store that contains the list of players currently known.
@ -23,6 +23,7 @@ function createPlayersStore() {
characterLayers: message.characterLayers, characterLayers: message.characterLayers,
visitCardUrl: message.visitCardUrl, visitCardUrl: message.visitCardUrl,
companion: message.companion, companion: message.companion,
userUuid: message.userUuid,
}); });
return users; return users;
}); });
@ -34,9 +35,9 @@ function createPlayersStore() {
}); });
}); });
}, },
getPlayerById(userId: number): PlayerInterface|undefined { getPlayerById(userId: number): PlayerInterface | undefined {
return players.get(userId); return players.get(userId);
} },
}; };
} }

View file

@ -1,24 +1,27 @@
import {Subject} from 'rxjs'; import { Subject } from "rxjs";
class BlackListManager { class BlackListManager {
private list: number[] = []; private list: string[] = [];
public onBlockStream: Subject<number> = new Subject(); public onBlockStream: Subject<string> = new Subject();
public onUnBlockStream: Subject<number> = new Subject(); public onUnBlockStream: Subject<string> = new Subject();
isBlackListed(userId: number): boolean { isBlackListed(userUuid: string): boolean {
return this.list.find((data) => data === userId) !== undefined; return this.list.find((data) => data === userUuid) !== undefined;
}
blackList(userId: number): void {
if (this.isBlackListed(userId)) return;
this.list.push(userId);
this.onBlockStream.next(userId);
} }
cancelBlackList(userId: number): void { blackList(userUuid: string): void {
this.list.splice(this.list.findIndex(data => data === userId), 1); if (this.isBlackListed(userUuid)) return;
this.onUnBlockStream.next(userId); this.list.push(userUuid);
this.onBlockStream.next(userUuid);
}
cancelBlackList(userUuid: string): void {
this.list.splice(
this.list.findIndex((data) => data === userUuid),
1
);
this.onUnBlockStream.next(userUuid);
} }
} }
export const blackListManager = new BlackListManager(); export const blackListManager = new BlackListManager();

View file

@ -11,7 +11,7 @@ import { get } from "svelte/store";
import { localStreamStore, LocalStreamStoreValue, obtainedMediaConstraintStore } from "../Stores/MediaStore"; import { localStreamStore, LocalStreamStoreValue, obtainedMediaConstraintStore } from "../Stores/MediaStore";
import { screenSharingLocalStreamStore } from "../Stores/ScreenSharingStore"; import { screenSharingLocalStreamStore } from "../Stores/ScreenSharingStore";
import { discussionManager } from "./DiscussionManager"; import { discussionManager } from "./DiscussionManager";
import {playersStore} from "../Stores/PlayersStore"; import { playersStore } from "../Stores/PlayersStore";
export interface UserSimplePeerInterface { export interface UserSimplePeerInterface {
userId: number; userId: number;
@ -199,7 +199,7 @@ export class SimplePeer {
} }
private getName(userId: number): string { private getName(userId: number): string {
return playersStore.getPlayerById(userId)?.name || ''; return playersStore.getPlayerById(userId)?.name || "";
} }
/** /**
@ -364,7 +364,8 @@ export class SimplePeer {
} }
private receiveWebrtcScreenSharingSignal(data: WebRtcSignalReceivedMessageInterface) { private receiveWebrtcScreenSharingSignal(data: WebRtcSignalReceivedMessageInterface) {
if (blackListManager.isBlackListed(data.userId)) return; const uuid = playersStore.getPlayerById(data.userId)?.userUuid || "";
if (blackListManager.isBlackListed(uuid)) return;
console.log("receiveWebrtcScreenSharingSignal", data); console.log("receiveWebrtcScreenSharingSignal", data);
const streamResult = get(screenSharingLocalStreamStore); const streamResult = get(screenSharingLocalStreamStore);
let stream: MediaStream | null = null; let stream: MediaStream | null = null;
@ -465,7 +466,8 @@ export class SimplePeer {
} }
private sendLocalScreenSharingStreamToUser(userId: number, localScreenCapture: MediaStream): void { private sendLocalScreenSharingStreamToUser(userId: number, localScreenCapture: MediaStream): void {
if (blackListManager.isBlackListed(userId)) return; const uuid = playersStore.getPlayerById(userId)?.userUuid || "";
if (blackListManager.isBlackListed(uuid)) return;
// If a connection already exists with user (because it is already sharing a screen with us... let's use this connection) // If a connection already exists with user (because it is already sharing a screen with us... let's use this connection)
if (this.PeerScreenSharingConnectionArray.has(userId)) { if (this.PeerScreenSharingConnectionArray.has(userId)) {
this.pushScreenSharingToRemoteUser(userId, localScreenCapture); this.pushScreenSharingToRemoteUser(userId, localScreenCapture);

View file

@ -8,6 +8,7 @@ import type { UserSimplePeerInterface } from "./SimplePeer";
import { get, readable, Readable } from "svelte/store"; import { get, readable, Readable } from "svelte/store";
import { obtainedMediaConstraintStore } from "../Stores/MediaStore"; import { obtainedMediaConstraintStore } from "../Stores/MediaStore";
import { discussionManager } from "./DiscussionManager"; import { discussionManager } from "./DiscussionManager";
import { playersStore } from "../Stores/PlayersStore";
const Peer: SimplePeerNamespace.SimplePeer = require("simple-peer"); const Peer: SimplePeerNamespace.SimplePeer = require("simple-peer");
@ -26,6 +27,7 @@ export class VideoPeer extends Peer {
private remoteStream!: MediaStream; private remoteStream!: MediaStream;
private blocked: boolean = false; private blocked: boolean = false;
public readonly userId: number; public readonly userId: number;
public readonly userUuid: string;
public readonly uniqueId: string; public readonly uniqueId: string;
private onBlockSubscribe: Subscription; private onBlockSubscribe: Subscription;
private onUnBlockSubscribe: Subscription; private onUnBlockSubscribe: Subscription;
@ -60,6 +62,7 @@ export class VideoPeer extends Peer {
}); });
this.userId = user.userId; this.userId = user.userId;
this.userUuid = playersStore.getPlayerById(this.userId)?.userUuid || "";
this.uniqueId = "video_" + this.userId; this.uniqueId = "video_" + this.userId;
this.streamStore = readable<MediaStream | null>(null, (set) => { this.streamStore = readable<MediaStream | null>(null, (set) => {
@ -181,20 +184,20 @@ export class VideoPeer extends Peer {
}); });
this.pushVideoToRemoteUser(localStream); this.pushVideoToRemoteUser(localStream);
this.onBlockSubscribe = blackListManager.onBlockStream.subscribe((userId) => { this.onBlockSubscribe = blackListManager.onBlockStream.subscribe((userUuid) => {
if (userId === this.userId) { if (userUuid === this.userUuid) {
this.toggleRemoteStream(false); this.toggleRemoteStream(false);
this.sendBlockMessage(true); this.sendBlockMessage(true);
} }
}); });
this.onUnBlockSubscribe = blackListManager.onUnBlockStream.subscribe((userId) => { this.onUnBlockSubscribe = blackListManager.onUnBlockStream.subscribe((userUuid) => {
if (userId === this.userId) { if (userUuid === this.userUuid) {
this.toggleRemoteStream(true); this.toggleRemoteStream(true);
this.sendBlockMessage(false); this.sendBlockMessage(false);
} }
}); });
if (blackListManager.isBlackListed(this.userId)) { if (blackListManager.isBlackListed(this.userUuid)) {
this.sendBlockMessage(true); this.sendBlockMessage(true);
} }
} }
@ -231,7 +234,7 @@ export class VideoPeer extends Peer {
private stream(stream: MediaStream) { private stream(stream: MediaStream) {
try { try {
this.remoteStream = stream; this.remoteStream = stream;
if (blackListManager.isBlackListed(this.userId) || this.blocked) { if (blackListManager.isBlackListed(this.userUuid) || this.blocked) {
this.toggleRemoteStream(false); this.toggleRemoteStream(false);
} }
} catch (err) { } catch (err) {

View file

@ -62,7 +62,7 @@ message WebRtcSignalToServerMessage {
} }
message ReportPlayerMessage { message ReportPlayerMessage {
int32 reportedUserId = 1; string reportedUserUuid = 1;
string reportComment = 2; string reportComment = 2;
} }
@ -158,6 +158,7 @@ message UserJoinedMessage {
PositionMessage position = 4; PositionMessage position = 4;
CompanionMessage companion = 5; CompanionMessage companion = 5;
string visitCardUrl = 6; string visitCardUrl = 6;
string userUuid = 7;
} }
message UserLeftMessage { message UserLeftMessage {
@ -285,6 +286,7 @@ message UserJoinedZoneMessage {
Zone fromZone = 5; Zone fromZone = 5;
CompanionMessage companion = 6; CompanionMessage companion = 6;
string visitCardUrl = 7; string visitCardUrl = 7;
string userUuid = 8;
} }
message UserLeftZoneMessage { message UserLeftZoneMessage {

View file

@ -39,6 +39,7 @@ export type LeavesCallback = (thing: Movable, listener: User) => void;*/
export class UserDescriptor { export class UserDescriptor {
private constructor( private constructor(
public readonly userId: number, public readonly userId: number,
private userUuid: string,
private name: string, private name: string,
private characterLayers: CharacterLayerMessage[], private characterLayers: CharacterLayerMessage[],
private position: PositionMessage, private position: PositionMessage,
@ -57,6 +58,7 @@ export class UserDescriptor {
} }
return new UserDescriptor( return new UserDescriptor(
message.getUserid(), message.getUserid(),
message.getUseruuid(),
message.getName(), message.getName(),
message.getCharacterlayersList(), message.getCharacterlayersList(),
position, position,
@ -84,6 +86,7 @@ export class UserDescriptor {
userJoinedMessage.setVisitcardurl(this.visitCardUrl); userJoinedMessage.setVisitcardurl(this.visitCardUrl);
} }
userJoinedMessage.setCompanion(this.companion); userJoinedMessage.setCompanion(this.companion);
userJoinedMessage.setUseruuid(this.userUuid);
return userJoinedMessage; return userJoinedMessage;
} }

View file

@ -61,7 +61,6 @@ export interface AdminSocketData {
export class SocketManager implements ZoneEventListener { export class SocketManager implements ZoneEventListener {
private rooms: 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>();
constructor() { constructor() {
clientEventsEmitter.registerToClientJoin((clientUUid: string, roomId: string) => { clientEventsEmitter.registerToClientJoin((clientUUid: string, roomId: string) => {
@ -191,8 +190,6 @@ export class SocketManager implements ZoneEventListener {
.on("data", (message: ServerToClientMessage) => { .on("data", (message: ServerToClientMessage) => {
if (message.hasRoomjoinedmessage()) { if (message.hasRoomjoinedmessage()) {
client.userId = (message.getRoomjoinedmessage() as RoomJoinedMessage).getCurrentuserid(); client.userId = (message.getRoomjoinedmessage() as RoomJoinedMessage).getCurrentuserid();
// TODO: do we need this.sockets anymore?
this.sockets.set(client.userId, client);
// If this is the first message sent, send back the viewport. // If this is the first message sent, send back the viewport.
this.handleViewport(client, viewport); this.handleViewport(client, viewport);
@ -302,14 +299,8 @@ export class SocketManager implements ZoneEventListener {
async handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) { async handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) {
try { try {
const reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid());
if (!reportedSocket) {
throw "reported socket user not found";
}
//TODO report user on admin application
//todo: move to back because this fail if the reported player is in another pusher.
await adminApi.reportPlayer( await adminApi.reportPlayer(
reportedSocket.userUuid, reportPlayerMessage.getReporteduseruuid(),
reportPlayerMessage.getReportcomment(), reportPlayerMessage.getReportcomment(),
client.userUuid, client.userUuid,
client.roomId.split("/")[2] client.roomId.split("/")[2]
@ -334,14 +325,6 @@ export class SocketManager implements ZoneEventListener {
socket.backConnection.write(pusherToBackMessage); socket.backConnection.write(pusherToBackMessage);
} }
private searchClientByIdOrFail(userId: number): ExSocketInterface {
const client: ExSocketInterface | undefined = this.sockets.get(userId);
if (client === undefined) {
throw new Error("Could not find user with id " + userId);
}
return client;
}
leaveRoom(socket: ExSocketInterface) { leaveRoom(socket: ExSocketInterface) {
// leave previous room and world // leave previous room and world
try { try {
@ -364,9 +347,8 @@ export class SocketManager implements ZoneEventListener {
//Client.leave(Client.roomId); //Client.leave(Client.roomId);
} finally { } finally {
//delete Client.roomId; //delete Client.roomId;
this.sockets.delete(socket.userId);
clientEventsEmitter.emitClientLeave(socket.userUuid, socket.roomId); clientEventsEmitter.emitClientLeave(socket.userUuid, socket.roomId);
console.log("A user left (", this.sockets.size, " connected users)"); console.log("A user left");
} }
} }
} finally { } finally {
@ -410,15 +392,6 @@ export class SocketManager implements ZoneEventListener {
return this.rooms; return this.rooms;
} }
searchClientByUuid(uuid: string): ExSocketInterface | null {
for (const socket of this.sockets.values()) {
if (socket.userUuid === uuid) {
return socket;
}
}
return null;
}
public handleQueryJitsiJwtMessage(client: ExSocketInterface, queryJitsiJwtMessage: QueryJitsiJwtMessage) { public handleQueryJitsiJwtMessage(client: ExSocketInterface, queryJitsiJwtMessage: QueryJitsiJwtMessage) {
try { try {
const room = queryJitsiJwtMessage.getJitsiroom(); const room = queryJitsiJwtMessage.getJitsiroom();