Merge branch 'develop' into changeRegisterAccess
Signed-off-by: Gregoire Parant <g.parant@thecodingmachine.com> # Conflicts: # front/src/Connexion/ConnectionManager.ts # front/vite.config.ts
This commit is contained in:
@@ -45,8 +45,10 @@ class ConnectionManager {
|
||||
|
||||
/**
|
||||
* TODO fix me to be move in game manager
|
||||
*
|
||||
* Returns the URL that we need to redirect to to load the OpenID screen, or "null" if no redirection needs to happen.
|
||||
*/
|
||||
public loadOpenIDScreen() {
|
||||
public loadOpenIDScreen(): URL | null {
|
||||
const state = localUserStore.generateState();
|
||||
const nonce = localUserStore.generateNonce();
|
||||
localUserStore.setAuthToken(null);
|
||||
@@ -55,11 +57,10 @@ class ConnectionManager {
|
||||
loginSceneVisibleIframeStore.set(false);
|
||||
return null;
|
||||
}
|
||||
const redirectUrl = new URL(`${this._currentRoom.iframeAuthentication}`);
|
||||
const redirectUrl = new URL(`${this._currentRoom.iframeAuthentication}`, window.location.href);
|
||||
redirectUrl.searchParams.append("state", state);
|
||||
redirectUrl.searchParams.append("nonce", nonce);
|
||||
redirectUrl.searchParams.append("playUri", this._currentRoom.key);
|
||||
window.location.assign(redirectUrl.toString());
|
||||
return redirectUrl;
|
||||
}
|
||||
|
||||
@@ -83,8 +84,10 @@ class ConnectionManager {
|
||||
|
||||
/**
|
||||
* Tries to login to the node server and return the starting map url to be loaded
|
||||
*
|
||||
* @return returns a promise to the Room we are going to load OR a pointer to the URL we must redirect to if authentication is needed.
|
||||
*/
|
||||
public async initGameConnexion(): Promise<Room> {
|
||||
public async initGameConnexion(): Promise<Room | URL> {
|
||||
this.connexionType = urlManager.getGameConnexionType();
|
||||
this._currentRoom = null;
|
||||
|
||||
@@ -100,8 +103,9 @@ class ConnectionManager {
|
||||
|
||||
if (this.connexionType === GameConnexionTypes.login) {
|
||||
this._currentRoom = await Room.createRoom(new URL(localUserStore.getLastRoomUrl()));
|
||||
if (this.loadOpenIDScreen() !== null) {
|
||||
return Promise.reject(new Error("You will be redirect on login page"));
|
||||
const redirect = this.loadOpenIDScreen();
|
||||
if (redirect !== null) {
|
||||
return redirect;
|
||||
}
|
||||
urlManager.pushRoomIdToUrl(this._currentRoom);
|
||||
} else if (this.connexionType === GameConnexionTypes.jwt) {
|
||||
@@ -124,8 +128,11 @@ class ConnectionManager {
|
||||
analyticsClient.loggedWithSso();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.loadOpenIDScreen();
|
||||
return Promise.reject(new Error("You will be redirect on login page"));
|
||||
const redirect = this.loadOpenIDScreen();
|
||||
if (redirect === null) {
|
||||
throw new Error("Unable to redirect on login page.");
|
||||
}
|
||||
return redirect;
|
||||
}
|
||||
urlManager.pushRoomIdToUrl(this._currentRoom);
|
||||
}
|
||||
@@ -213,8 +220,11 @@ class ConnectionManager {
|
||||
err.response?.data &&
|
||||
err.response.data !== "User cannot to be connected on openid provider")
|
||||
) {
|
||||
this.loadOpenIDScreen();
|
||||
return Promise.reject(new Error("You will be redirect on login page"));
|
||||
const redirect = this.loadOpenIDScreen();
|
||||
if (redirect === null) {
|
||||
throw new Error("Unable to redirect on login page.");
|
||||
}
|
||||
return redirect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ export interface GroupCreatedUpdatedMessageInterface {
|
||||
position: PositionInterface;
|
||||
groupId: number;
|
||||
groupSize: number;
|
||||
locked: boolean;
|
||||
}
|
||||
|
||||
export interface GroupUsersUpdateMessageInterface {
|
||||
groupId: number;
|
||||
userIds: number[];
|
||||
}
|
||||
|
||||
export interface WebRtcDisconnectMessageInterface {
|
||||
|
||||
@@ -15,6 +15,7 @@ const helpCameraSettingsShown = "helpCameraSettingsShown";
|
||||
const fullscreenKey = "fullscreen";
|
||||
const forceCowebsiteTriggerKey = "forceCowebsiteTrigger";
|
||||
const ignoreFollowRequests = "ignoreFollowRequests";
|
||||
const decreaseAudioPlayerVolumeWhileTalking = "decreaseAudioPlayerVolumeWhileTalking";
|
||||
const lastRoomUrl = "lastRoomUrl";
|
||||
const authToken = "authToken";
|
||||
const state = "state";
|
||||
@@ -24,11 +25,14 @@ const code = "code";
|
||||
const cameraSetup = "cameraSetup";
|
||||
const cacheAPIIndex = "workavdenture-cache";
|
||||
const userProperties = "user-properties";
|
||||
const cameraPrivacySettings = "cameraPrivacySettings";
|
||||
const microphonePrivacySettings = "microphonePrivacySettings";
|
||||
|
||||
class LocalUserStore {
|
||||
saveUser(localUser: LocalUser) {
|
||||
localStorage.setItem("localUser", JSON.stringify(localUser));
|
||||
}
|
||||
|
||||
getLocalUser(): LocalUser | null {
|
||||
const data = localStorage.getItem("localUser");
|
||||
return data ? JSON.parse(data) : null;
|
||||
@@ -37,6 +41,7 @@ class LocalUserStore {
|
||||
setName(name: string): void {
|
||||
localStorage.setItem(playerNameKey, name);
|
||||
}
|
||||
|
||||
getName(): string | null {
|
||||
const value = localStorage.getItem(playerNameKey) || "";
|
||||
return isUserNameValid(value) ? value : null;
|
||||
@@ -45,6 +50,7 @@ class LocalUserStore {
|
||||
setPlayerCharacterIndex(playerCharacterIndex: number): void {
|
||||
localStorage.setItem(selectedPlayerKey, "" + playerCharacterIndex);
|
||||
}
|
||||
|
||||
getPlayerCharacterIndex(): number {
|
||||
return parseInt(localStorage.getItem(selectedPlayerKey) || "");
|
||||
}
|
||||
@@ -52,6 +58,7 @@ class LocalUserStore {
|
||||
setCustomCursorPosition(activeRow: number, selectedLayers: number[]): void {
|
||||
localStorage.setItem(customCursorPositionKey, JSON.stringify({ activeRow, selectedLayers }));
|
||||
}
|
||||
|
||||
getCustomCursorPosition(): { activeRow: number; selectedLayers: number[] } | null {
|
||||
return JSON.parse(localStorage.getItem(customCursorPositionKey) || "null");
|
||||
}
|
||||
@@ -59,6 +66,7 @@ class LocalUserStore {
|
||||
setCharacterLayers(layers: string[]): void {
|
||||
localStorage.setItem(characterLayersKey, JSON.stringify(layers));
|
||||
}
|
||||
|
||||
getCharacterLayers(): string[] | null {
|
||||
const value = JSON.parse(localStorage.getItem(characterLayersKey) || "null");
|
||||
return areCharacterLayersValid(value) ? value : null;
|
||||
@@ -67,6 +75,7 @@ class LocalUserStore {
|
||||
setCompanion(companion: string | null): void {
|
||||
return localStorage.setItem(companionKey, JSON.stringify(companion));
|
||||
}
|
||||
|
||||
getCompanion(): string | null {
|
||||
const companion = JSON.parse(localStorage.getItem(companionKey) || "null");
|
||||
|
||||
@@ -76,6 +85,7 @@ class LocalUserStore {
|
||||
|
||||
return companion;
|
||||
}
|
||||
|
||||
wasCompanionSet(): boolean {
|
||||
return localStorage.getItem(companionKey) ? true : false;
|
||||
}
|
||||
@@ -83,6 +93,7 @@ class LocalUserStore {
|
||||
setGameQualityValue(value: number): void {
|
||||
localStorage.setItem(gameQualityKey, "" + value);
|
||||
}
|
||||
|
||||
getGameQualityValue(): number {
|
||||
return parseInt(localStorage.getItem(gameQualityKey) || "60");
|
||||
}
|
||||
@@ -90,6 +101,7 @@ class LocalUserStore {
|
||||
setVideoQualityValue(value: number): void {
|
||||
localStorage.setItem(videoQualityKey, "" + value);
|
||||
}
|
||||
|
||||
getVideoQualityValue(): number {
|
||||
return parseInt(localStorage.getItem(videoQualityKey) || "20");
|
||||
}
|
||||
@@ -97,6 +109,7 @@ class LocalUserStore {
|
||||
setAudioPlayerVolume(value: number): void {
|
||||
localStorage.setItem(audioPlayerVolumeKey, "" + value);
|
||||
}
|
||||
|
||||
getAudioPlayerVolume(): number {
|
||||
return parseFloat(localStorage.getItem(audioPlayerVolumeKey) || "1");
|
||||
}
|
||||
@@ -104,6 +117,7 @@ class LocalUserStore {
|
||||
setAudioPlayerMuted(value: boolean): void {
|
||||
localStorage.setItem(audioPlayerMuteKey, value.toString());
|
||||
}
|
||||
|
||||
getAudioPlayerMuted(): boolean {
|
||||
return localStorage.getItem(audioPlayerMuteKey) === "true";
|
||||
}
|
||||
@@ -111,6 +125,7 @@ class LocalUserStore {
|
||||
setHelpCameraSettingsShown(): void {
|
||||
localStorage.setItem(helpCameraSettingsShown, "1");
|
||||
}
|
||||
|
||||
getHelpCameraSettingsShown(): boolean {
|
||||
return localStorage.getItem(helpCameraSettingsShown) === "1";
|
||||
}
|
||||
@@ -118,6 +133,7 @@ class LocalUserStore {
|
||||
setFullscreen(value: boolean): void {
|
||||
localStorage.setItem(fullscreenKey, value.toString());
|
||||
}
|
||||
|
||||
getFullscreen(): boolean {
|
||||
return localStorage.getItem(fullscreenKey) === "true";
|
||||
}
|
||||
@@ -125,6 +141,7 @@ class LocalUserStore {
|
||||
setForceCowebsiteTrigger(value: boolean): void {
|
||||
localStorage.setItem(forceCowebsiteTriggerKey, value.toString());
|
||||
}
|
||||
|
||||
getForceCowebsiteTrigger(): boolean {
|
||||
return localStorage.getItem(forceCowebsiteTriggerKey) === "true";
|
||||
}
|
||||
@@ -132,9 +149,16 @@ class LocalUserStore {
|
||||
setIgnoreFollowRequests(value: boolean): void {
|
||||
localStorage.setItem(ignoreFollowRequests, value.toString());
|
||||
}
|
||||
|
||||
getIgnoreFollowRequests(): boolean {
|
||||
return localStorage.getItem(ignoreFollowRequests) === "true";
|
||||
}
|
||||
setDecreaseAudioPlayerVolumeWhileTalking(value: boolean): void {
|
||||
localStorage.setItem(decreaseAudioPlayerVolumeWhileTalking, value.toString());
|
||||
}
|
||||
getDecreaseAudioPlayerVolumeWhileTalking(): boolean {
|
||||
return localStorage.getItem(decreaseAudioPlayerVolumeWhileTalking) === "true";
|
||||
}
|
||||
|
||||
async setLastRoomUrl(roomUrl: string): Promise<void> {
|
||||
localStorage.setItem(lastRoomUrl, roomUrl.toString());
|
||||
@@ -148,11 +172,13 @@ class LocalUserStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getLastRoomUrl(): string {
|
||||
return (
|
||||
localStorage.getItem(lastRoomUrl) ?? window.location.protocol + "//" + window.location.host + START_ROOM_URL
|
||||
);
|
||||
}
|
||||
|
||||
getLastRoomUrlCacheApi(): Promise<string | undefined> {
|
||||
if (!("caches" in window)) {
|
||||
return Promise.resolve(undefined);
|
||||
@@ -169,6 +195,7 @@ class LocalUserStore {
|
||||
setAuthToken(value: string | null) {
|
||||
value ? localStorage.setItem(authToken, value) : localStorage.removeItem(authToken);
|
||||
}
|
||||
|
||||
getAuthToken(): string | null {
|
||||
return localStorage.getItem(authToken);
|
||||
}
|
||||
@@ -195,23 +222,29 @@ class LocalUserStore {
|
||||
}
|
||||
return oldValue === value;
|
||||
}
|
||||
|
||||
setState(value: string) {
|
||||
localStorage.setItem(state, value);
|
||||
}
|
||||
|
||||
getState(): string | null {
|
||||
return localStorage.getItem(state);
|
||||
}
|
||||
|
||||
generateNonce(): string {
|
||||
const newNonce = uuidv4();
|
||||
localStorage.setItem(nonce, newNonce);
|
||||
return newNonce;
|
||||
}
|
||||
|
||||
getNonce(): string | null {
|
||||
return localStorage.getItem(nonce);
|
||||
}
|
||||
|
||||
setCode(value: string): void {
|
||||
localStorage.setItem(code, value);
|
||||
}
|
||||
|
||||
getCode(): string | null {
|
||||
return localStorage.getItem(code);
|
||||
}
|
||||
@@ -219,11 +252,36 @@ class LocalUserStore {
|
||||
setCameraSetup(cameraId: string) {
|
||||
localStorage.setItem(cameraSetup, cameraId);
|
||||
}
|
||||
|
||||
getCameraSetup(): { video: unknown; audio: unknown } | undefined {
|
||||
const cameraSetupValues = localStorage.getItem(cameraSetup);
|
||||
return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined;
|
||||
}
|
||||
|
||||
setCameraPrivacySettings(option: boolean) {
|
||||
localStorage.setItem(cameraPrivacySettings, option.toString());
|
||||
}
|
||||
|
||||
getCameraPrivacySettings() {
|
||||
//if this setting doesn't exist in LocalUserStore, we set a default value
|
||||
if (localStorage.getItem(cameraPrivacySettings) == null) {
|
||||
localStorage.setItem(cameraPrivacySettings, "false");
|
||||
}
|
||||
return localStorage.getItem(cameraPrivacySettings) === "true";
|
||||
}
|
||||
|
||||
setMicrophonePrivacySettings(option: boolean) {
|
||||
localStorage.setItem(microphonePrivacySettings, option.toString());
|
||||
}
|
||||
|
||||
getMicrophonePrivacySettings() {
|
||||
//if this setting doesn't exist in LocalUserStore, we set a default value
|
||||
if (localStorage.getItem(microphonePrivacySettings) == null) {
|
||||
localStorage.setItem(microphonePrivacySettings, "true");
|
||||
}
|
||||
return localStorage.getItem(microphonePrivacySettings) === "true";
|
||||
}
|
||||
|
||||
getAllUserProperties(): Map<string, unknown> {
|
||||
const result = new Map<string, string>();
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
|
||||
@@ -31,6 +31,8 @@ export class Room {
|
||||
private _group: string | null = null;
|
||||
private _expireOn: Date | undefined;
|
||||
private _canReport: boolean = false;
|
||||
private _loadingLogo: string | undefined;
|
||||
private _loginSceneLogo: string | undefined;
|
||||
|
||||
private constructor(private roomUrl: URL) {
|
||||
this.id = roomUrl.pathname;
|
||||
@@ -126,6 +128,8 @@ export class Room {
|
||||
this._expireOn = new Date(data.expireOn);
|
||||
}
|
||||
this._canReport = data.canReport ?? false;
|
||||
this._loadingLogo = data.loadingLogo ?? undefined;
|
||||
this._loginSceneLogo = data.loginSceneLogo ?? undefined;
|
||||
return new MapDetail(data.mapUrl);
|
||||
} else {
|
||||
throw new Error("Data received by the /map endpoint of the Pusher is not in a valid format.");
|
||||
@@ -233,4 +237,12 @@ export class Room {
|
||||
get canReport(): boolean {
|
||||
return this._canReport;
|
||||
}
|
||||
|
||||
get loadingLogo(): string | undefined {
|
||||
return this._loadingLogo;
|
||||
}
|
||||
|
||||
get loginSceneLogo(): string | undefined {
|
||||
return this._loginSceneLogo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,47 +5,35 @@ import type { UserSimplePeerInterface } from "../WebRtc/SimplePeer";
|
||||
import { ProtobufClientUtils } from "../Network/ProtobufClientUtils";
|
||||
import type {
|
||||
GroupCreatedUpdatedMessageInterface,
|
||||
ItemEventMessageInterface,
|
||||
GroupUsersUpdateMessageInterface,
|
||||
MessageUserJoined,
|
||||
OnConnectInterface,
|
||||
PlayerDetailsUpdatedMessageInterface,
|
||||
PlayGlobalMessageInterface,
|
||||
PositionInterface,
|
||||
RoomJoinedMessageInterface,
|
||||
ViewportInterface,
|
||||
WebRtcDisconnectMessageInterface,
|
||||
WebRtcSignalReceivedMessageInterface,
|
||||
} from "./ConnexionModels";
|
||||
import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures";
|
||||
import { adminMessagesService } from "./AdminMessagesService";
|
||||
import { connectionManager } from "./ConnectionManager";
|
||||
import { get } from "svelte/store";
|
||||
import { followRoleStore, followUsersStore } from "../Stores/FollowStore";
|
||||
import { menuIconVisiblilityStore, menuVisiblilityStore, warningContainerStore } from "../Stores/MenuStore";
|
||||
import { followStateStore, followRoleStore, followUsersStore } from "../Stores/FollowStore";
|
||||
import { localUserStore } from "./LocalUserStore";
|
||||
import {
|
||||
RefreshRoomMessage,
|
||||
ServerToClientMessage as ServerToClientMessageTsProto,
|
||||
TokenExpiredMessage,
|
||||
WorldConnexionMessage,
|
||||
WorldFullMessage,
|
||||
ErrorMessage as ErrorMessageTsProto,
|
||||
UserMovedMessage as UserMovedMessageTsProto,
|
||||
GroupUpdateMessage as GroupUpdateMessageTsProto,
|
||||
GroupDeleteMessage as GroupDeleteMessageTsProto,
|
||||
UserJoinedMessage as UserJoinedMessageTsProto,
|
||||
UserLeftMessage as UserLeftMessageTsProto,
|
||||
ItemEventMessage as ItemEventMessageTsProto,
|
||||
EmoteEventMessage as EmoteEventMessageTsProto,
|
||||
VariableMessage as VariableMessageTsProto,
|
||||
PlayerDetailsUpdatedMessage as PlayerDetailsUpdatedMessageTsProto,
|
||||
WorldFullWarningMessage,
|
||||
WebRtcDisconnectMessage as WebRtcDisconnectMessageTsProto,
|
||||
PlayGlobalMessage as PlayGlobalMessageTsProto,
|
||||
StopGlobalMessage as StopGlobalMessageTsProto,
|
||||
SendJitsiJwtMessage as SendJitsiJwtMessageTsProto,
|
||||
SendUserMessage as SendUserMessageTsProto,
|
||||
BanUserMessage as BanUserMessageTsProto,
|
||||
ClientToServerMessage as ClientToServerMessageTsProto,
|
||||
PositionMessage as PositionMessageTsProto,
|
||||
ViewportMessage as ViewportMessageTsProto,
|
||||
@@ -55,8 +43,6 @@ import {
|
||||
CharacterLayerMessage,
|
||||
} from "../Messages/ts-proto-generated/messages";
|
||||
import { Subject } from "rxjs";
|
||||
import { OpenPopupEvent } from "../Api/Events/OpenPopupEvent";
|
||||
import { match } from "assert";
|
||||
import { selectCharacterSceneVisibleStore } from "../Stores/SelectCharacterStore";
|
||||
import { gameManager } from "../Phaser/Game/GameManager";
|
||||
import { SelectCharacterScene, SelectCharacterSceneName } from "../Phaser/Login/SelectCharacterScene";
|
||||
@@ -116,6 +102,9 @@ export class RoomConnection implements RoomConnection {
|
||||
private readonly _groupUpdateMessageStream = new Subject<GroupCreatedUpdatedMessageInterface>();
|
||||
public readonly groupUpdateMessageStream = this._groupUpdateMessageStream.asObservable();
|
||||
|
||||
private readonly _groupUsersUpdateMessageStream = new Subject<GroupUsersUpdateMessageInterface>();
|
||||
public readonly groupUsersUpdateMessageStream = this._groupUsersUpdateMessageStream.asObservable();
|
||||
|
||||
private readonly _groupDeleteMessageStream = new Subject<GroupDeleteMessageTsProto>();
|
||||
public readonly groupDeleteMessageStream = this._groupDeleteMessageStream.asObservable();
|
||||
|
||||
@@ -220,6 +209,7 @@ export class RoomConnection implements RoomConnection {
|
||||
|
||||
this.socket.onmessage = (messageEvent) => {
|
||||
const arrayBuffer: ArrayBuffer = messageEvent.data;
|
||||
const initCharacterLayers = characterLayers;
|
||||
|
||||
const serverToClientMessage = ServerToClientMessageTsProto.decode(new Uint8Array(arrayBuffer));
|
||||
//const message = ServerToClientMessage.deserializeBinary(new Uint8Array(arrayBuffer));
|
||||
@@ -342,14 +332,16 @@ export class RoomConnection implements RoomConnection {
|
||||
this._userRoomToken = roomJoinedMessage.userRoomToken;
|
||||
|
||||
// If one of the URLs sent to us does not exist, let's go to the Woka selection screen.
|
||||
for (const characterLayer of roomJoinedMessage.characterLayer) {
|
||||
if (!characterLayer.url) {
|
||||
this.goToSelectYourWokaScene();
|
||||
this.closed = true;
|
||||
break;
|
||||
}
|
||||
if (
|
||||
roomJoinedMessage.characterLayer.length !== initCharacterLayers.length ||
|
||||
roomJoinedMessage.characterLayer.find((layer) => !layer.url)
|
||||
) {
|
||||
this.goToSelectYourWokaScene();
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
if (this.closed) {
|
||||
this.closeConnection();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -440,6 +432,10 @@ export class RoomConnection implements RoomConnection {
|
||||
this._sendJitsiJwtMessageStream.next(message.sendJitsiJwtMessage);
|
||||
break;
|
||||
}
|
||||
case "groupUsersUpdateMessage": {
|
||||
this._groupUsersUpdateMessageStream.next(message.groupUsersUpdateMessage);
|
||||
break;
|
||||
}
|
||||
case "sendUserMessage": {
|
||||
adminMessagesService.onSendusermessage(message.sendUserMessage);
|
||||
break;
|
||||
@@ -672,6 +668,7 @@ export class RoomConnection implements RoomConnection {
|
||||
groupId: message.groupId,
|
||||
position: position,
|
||||
groupSize: message.groupSize,
|
||||
locked: message.locked,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -887,6 +884,19 @@ export class RoomConnection implements RoomConnection {
|
||||
this.socket.send(bytes);
|
||||
}
|
||||
|
||||
public emitLockGroup(lock: boolean = true): void {
|
||||
const bytes = ClientToServerMessageTsProto.encode({
|
||||
message: {
|
||||
$case: "lockGroupPromptMessage",
|
||||
lockGroupPromptMessage: {
|
||||
lock,
|
||||
},
|
||||
},
|
||||
}).finish();
|
||||
|
||||
this.socket.send(bytes);
|
||||
}
|
||||
|
||||
public getAllTags(): string[] {
|
||||
return this.tags;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user