Heavy changes: refactoring the pusher to always send the textures (and the front to accept them)
This commit is contained in:
@@ -273,7 +273,6 @@ export class AuthenticateController extends BaseHttpController {
|
||||
const email = data.email;
|
||||
const roomUrl = data.roomUrl;
|
||||
const mapUrlStart = data.mapUrlStart;
|
||||
const textures = data.textures;
|
||||
|
||||
const authToken = jwtTokenManager.createAuthToken(email || userUuid);
|
||||
res.json({
|
||||
@@ -283,7 +282,6 @@ export class AuthenticateController extends BaseHttpController {
|
||||
roomUrl,
|
||||
mapUrlStart,
|
||||
organizationMemberToken,
|
||||
textures,
|
||||
} as RegisterData);
|
||||
} catch (e) {
|
||||
console.error("register => ERROR", e);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CharacterLayer, ExSocketInterface } from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
|
||||
import { ExSocketInterface } from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
|
||||
import { GameRoomPolicyTypes } from "../Model/PusherRoom";
|
||||
import { PointInterface } from "../Model/Websocket/PointInterface";
|
||||
import {
|
||||
@@ -31,11 +31,46 @@ import { emitInBatch } from "../Services/IoSocketHelpers";
|
||||
import { ADMIN_API_URL, ADMIN_SOCKETS_TOKEN, DISABLE_ANONYMOUS, SOCKET_IDLE_TIMER } from "../Enum/EnvironmentVariable";
|
||||
import { Zone } from "_Model/Zone";
|
||||
import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface";
|
||||
import { CharacterTexture } from "../Messages/JsonMessages/CharacterTexture";
|
||||
import { isAdminMessageInterface } from "../Model/Websocket/Admin/AdminMessages";
|
||||
import Axios from "axios";
|
||||
import { InvalidTokenError } from "../Controller/InvalidTokenError";
|
||||
import HyperExpress from "hyper-express";
|
||||
import { localWokaService } from "../Services/LocalWokaService";
|
||||
import { WebSocket } from "uWebSockets.js";
|
||||
import { WokaDetail } from "../Enum/PlayerTextures";
|
||||
|
||||
/**
|
||||
* The object passed between the "open" and the "upgrade" methods when opening a websocket
|
||||
*/
|
||||
interface UpgradeData {
|
||||
// Data passed here is accessible on the "websocket" socket object.
|
||||
rejected: false;
|
||||
token: string;
|
||||
userUuid: string;
|
||||
IPAddress: string;
|
||||
roomId: string;
|
||||
name: string;
|
||||
companion: CompanionMessage | undefined;
|
||||
characterLayers: WokaDetail[];
|
||||
messages: unknown[];
|
||||
tags: string[];
|
||||
visitCardUrl: string | null;
|
||||
userRoomToken: string | undefined;
|
||||
position: PointInterface;
|
||||
viewport: {
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
left: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface UpgradeFailedData {
|
||||
rejected: true;
|
||||
reason: "tokenInvalid" | "textureInvalid" | null;
|
||||
message: string;
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
export class IoSocketController {
|
||||
private nextUserId: number = 1;
|
||||
@@ -244,7 +279,7 @@ export class IoSocketController {
|
||||
let memberVisitCardUrl: string | null = null;
|
||||
let memberMessages: unknown;
|
||||
let memberUserRoomToken: string | undefined;
|
||||
let memberTextures: CharacterTexture[] = [];
|
||||
let memberTextures: WokaDetail[] = [];
|
||||
const room = await socketManager.getOrCreateRoom(roomId);
|
||||
let userData: FetchMemberDataByUuidResponse = {
|
||||
email: userIdentifier,
|
||||
@@ -256,6 +291,9 @@ export class IoSocketController {
|
||||
anonymous: true,
|
||||
userRoomToken: undefined,
|
||||
};
|
||||
|
||||
let characterLayerObjs: WokaDetail[];
|
||||
|
||||
if (ADMIN_API_URL) {
|
||||
try {
|
||||
try {
|
||||
@@ -308,6 +346,8 @@ export class IoSocketController {
|
||||
) {
|
||||
throw new Error("Use the login URL to connect");
|
||||
}
|
||||
|
||||
characterLayerObjs = memberTextures;
|
||||
} catch (e) {
|
||||
console.log(
|
||||
"access not granted for user " +
|
||||
@@ -318,11 +358,31 @@ export class IoSocketController {
|
||||
console.error(e);
|
||||
throw new Error("User cannot access this world");
|
||||
}
|
||||
} else {
|
||||
const fetchedTextures = await localWokaService.fetchWokaDetails(characterLayers);
|
||||
if (fetchedTextures === undefined) {
|
||||
// The textures we want to use do not exist!
|
||||
// We need to go in error.
|
||||
res.upgrade(
|
||||
{
|
||||
rejected: true,
|
||||
reason: "textureInvalid",
|
||||
message: "",
|
||||
roomId,
|
||||
} as UpgradeFailedData,
|
||||
websocketKey,
|
||||
websocketProtocol,
|
||||
websocketExtensions,
|
||||
context
|
||||
);
|
||||
return;
|
||||
}
|
||||
characterLayerObjs = fetchedTextures;
|
||||
}
|
||||
|
||||
// Generate characterLayers objects from characterLayers string[]
|
||||
const characterLayerObjs: CharacterLayer[] =
|
||||
SocketManager.mergeCharacterLayersAndCustomTextures(characterLayers, memberTextures);
|
||||
/*const characterLayerObjs: CharacterLayer[] =
|
||||
SocketManager.mergeCharacterLayersAndCustomTextures(characterLayers, memberTextures);*/
|
||||
|
||||
if (upgradeAborted.aborted) {
|
||||
console.log("Ouch! Client disconnected before we could upgrade it!");
|
||||
@@ -334,7 +394,7 @@ export class IoSocketController {
|
||||
res.upgrade(
|
||||
{
|
||||
// Data passed here is accessible on the "websocket" socket object.
|
||||
url,
|
||||
rejected: false,
|
||||
token,
|
||||
userUuid: userData.userUuid,
|
||||
IPAddress,
|
||||
@@ -346,7 +406,6 @@ export class IoSocketController {
|
||||
tags: memberTags,
|
||||
visitCardUrl: memberVisitCardUrl,
|
||||
userRoomToken: memberUserRoomToken,
|
||||
textures: memberTextures,
|
||||
position: {
|
||||
x: x,
|
||||
y: y,
|
||||
@@ -359,7 +418,7 @@ export class IoSocketController {
|
||||
bottom,
|
||||
left,
|
||||
},
|
||||
},
|
||||
} as UpgradeData,
|
||||
/* Spell these correctly */
|
||||
websocketKey,
|
||||
websocketProtocol,
|
||||
@@ -374,7 +433,7 @@ export class IoSocketController {
|
||||
reason: e instanceof InvalidTokenError ? tokenInvalidException : null,
|
||||
message: e.message,
|
||||
roomId,
|
||||
},
|
||||
} as UpgradeFailedData,
|
||||
websocketKey,
|
||||
websocketProtocol,
|
||||
websocketExtensions,
|
||||
@@ -387,7 +446,7 @@ export class IoSocketController {
|
||||
reason: null,
|
||||
message: "500 Internal Server Error",
|
||||
roomId,
|
||||
},
|
||||
} as UpgradeFailedData,
|
||||
websocketKey,
|
||||
websocketProtocol,
|
||||
websocketExtensions,
|
||||
@@ -398,20 +457,23 @@ export class IoSocketController {
|
||||
})();
|
||||
},
|
||||
/* Handlers */
|
||||
open: (ws) => {
|
||||
open: (_ws: WebSocket) => {
|
||||
const ws = _ws as WebSocket & (UpgradeData | UpgradeFailedData);
|
||||
if (ws.rejected === true) {
|
||||
// If there is a room in the error, let's check if we need to clean it.
|
||||
if (ws.roomId) {
|
||||
socketManager.deleteRoomIfEmptyFromId(ws.roomId as string);
|
||||
socketManager.deleteRoomIfEmptyFromId(ws.roomId);
|
||||
}
|
||||
|
||||
//FIX ME to use status code
|
||||
if (ws.reason === tokenInvalidException) {
|
||||
socketManager.emitTokenExpiredMessage(ws);
|
||||
} else if (ws.reason === "textureInvalid") {
|
||||
socketManager.emitInvalidTextureMessage(ws);
|
||||
} else if (ws.message === "World is full") {
|
||||
socketManager.emitWorldFullMessage(ws);
|
||||
} else {
|
||||
socketManager.emitConnexionErrorMessage(ws, ws.message as string);
|
||||
socketManager.emitConnexionErrorMessage(ws, ws.message);
|
||||
}
|
||||
setTimeout(() => ws.close(), 0);
|
||||
return;
|
||||
@@ -535,7 +597,6 @@ export class IoSocketController {
|
||||
client.name = ws.name;
|
||||
client.tags = ws.tags;
|
||||
client.visitCardUrl = ws.visitCardUrl;
|
||||
client.textures = ws.textures;
|
||||
client.characterLayers = ws.characterLayers;
|
||||
client.companion = ws.companion;
|
||||
client.roomId = ws.roomId;
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
import { hasToken } from "../Middleware/HasToken";
|
||||
import { BaseHttpController } from "./BaseHttpController";
|
||||
import { ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
||||
import { adminWokaService } from "..//Services/AdminWokaService";
|
||||
import { localWokaService } from "..//Services/LocalWokaService";
|
||||
import { WokaServiceInterface } from "src/Services/WokaServiceInterface";
|
||||
import { Server } from "hyper-express";
|
||||
import { wokaService } from "../Services/WokaService";
|
||||
|
||||
export class WokaListController extends BaseHttpController {
|
||||
private wokaService: WokaServiceInterface;
|
||||
|
||||
constructor(app: Server) {
|
||||
super(app);
|
||||
this.wokaService = ADMIN_API_URL ? adminWokaService : localWokaService;
|
||||
}
|
||||
|
||||
routes() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
this.app.get("/woka-list", {}, async (req, res) => {
|
||||
const token = req.header("Authorization");
|
||||
const wokaList = await this.wokaService.getWokaList(token);
|
||||
const wokaList = await wokaService.getWokaList(token);
|
||||
|
||||
if (!wokaList) {
|
||||
return res.status(500).send("Error on getting woka list");
|
||||
@@ -28,20 +17,20 @@ export class WokaListController extends BaseHttpController {
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
this.app.post("/woka-details", async (req, res) => {
|
||||
/*this.app.post("/woka-details", async (req, res) => {
|
||||
const body = await req.json();
|
||||
if (!body || !body.textureIds) {
|
||||
return res.status(400);
|
||||
}
|
||||
|
||||
const textureIds = body.textureIds;
|
||||
const wokaDetails = await this.wokaService.fetchWokaDetails(textureIds);
|
||||
const wokaDetails = await wokaService.fetchWokaDetails(textureIds);
|
||||
|
||||
if (!wokaDetails) {
|
||||
return res.json({ details: [] });
|
||||
}
|
||||
|
||||
return res.json(wokaDetails);
|
||||
});
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,16 +49,11 @@ export const isWokaDetail = new tg.IsInterface()
|
||||
id: tg.isString,
|
||||
})
|
||||
.withOptionalProperties({
|
||||
texture: tg.isString,
|
||||
url: tg.isString,
|
||||
layer: tg.isString,
|
||||
})
|
||||
.get();
|
||||
|
||||
export type WokaDetail = tg.GuardedType<typeof isWokaDetail>;
|
||||
|
||||
export const isWokaDetailsResult = new tg.IsInterface()
|
||||
.withProperties({
|
||||
details: tg.isArray(isWokaDetail),
|
||||
})
|
||||
.get();
|
||||
|
||||
export type WokaDetailsResult = tg.GuardedType<typeof isWokaDetailsResult>;
|
||||
export type WokaDetailsResult = WokaDetail[];
|
||||
|
||||
@@ -13,14 +13,10 @@ import { ClientDuplexStream } from "grpc";
|
||||
import { Zone } from "_Model/Zone";
|
||||
import { CharacterTexture } from "../../Messages/JsonMessages/CharacterTexture";
|
||||
import { compressors } from "hyper-express";
|
||||
import { WokaDetail } from "_Enum/PlayerTextures";
|
||||
|
||||
export type BackConnection = ClientDuplexStream<PusherToBackMessage, ServerToClientMessage>;
|
||||
|
||||
export interface CharacterLayer {
|
||||
name: string;
|
||||
url: string | undefined;
|
||||
}
|
||||
|
||||
export interface ExSocketInterface extends compressors.WebSocket, Identificable {
|
||||
token: string;
|
||||
roomId: string;
|
||||
@@ -28,7 +24,7 @@ export interface ExSocketInterface extends compressors.WebSocket, Identificable
|
||||
userUuid: string; // A unique identifier for this user
|
||||
IPAddress: string; // IP address
|
||||
name: string;
|
||||
characterLayers: CharacterLayer[];
|
||||
characterLayers: WokaDetail[];
|
||||
position: PointInterface;
|
||||
viewport: ViewportInterface;
|
||||
companion?: CompanionMessage;
|
||||
@@ -42,7 +38,6 @@ export interface ExSocketInterface extends compressors.WebSocket, Identificable
|
||||
messages: unknown;
|
||||
tags: string[];
|
||||
visitCardUrl: string | null;
|
||||
textures: CharacterTexture[];
|
||||
backConnection: BackConnection;
|
||||
listenedZones: Set<Zone>;
|
||||
userRoomToken: string | undefined;
|
||||
|
||||
@@ -5,10 +5,11 @@ import {
|
||||
PointMessage,
|
||||
PositionMessage,
|
||||
} from "../../Messages/generated/messages_pb";
|
||||
import { CharacterLayer, ExSocketInterface } from "_Model/Websocket/ExSocketInterface";
|
||||
import { ExSocketInterface } from "_Model/Websocket/ExSocketInterface";
|
||||
import Direction = PositionMessage.Direction;
|
||||
import { ItemEventMessageInterface } from "_Model/Websocket/ItemEventMessage";
|
||||
import { PositionInterface } from "_Model/PositionInterface";
|
||||
import { WokaDetail } from "_Enum/PlayerTextures";
|
||||
|
||||
export class ProtobufUtils {
|
||||
public static toPositionMessage(point: PointInterface): PositionMessage {
|
||||
@@ -94,13 +95,16 @@ export class ProtobufUtils {
|
||||
return itemEventMessage;
|
||||
}
|
||||
|
||||
public static toCharacterLayerMessages(characterLayers: CharacterLayer[]): CharacterLayerMessage[] {
|
||||
public static toCharacterLayerMessages(characterLayers: WokaDetail[]): CharacterLayerMessage[] {
|
||||
return characterLayers.map(function (characterLayer): CharacterLayerMessage {
|
||||
const message = new CharacterLayerMessage();
|
||||
message.setName(characterLayer.name);
|
||||
message.setName(characterLayer.id);
|
||||
if (characterLayer.url) {
|
||||
message.setUrl(characterLayer.url);
|
||||
}
|
||||
if (characterLayer.layer) {
|
||||
message.setLayer(characterLayer.layer);
|
||||
}
|
||||
return message;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable";
|
||||
import Axios from "axios";
|
||||
import { CharacterTexture } from "../Messages/JsonMessages/CharacterTexture";
|
||||
import Axios, { AxiosResponse } from "axios";
|
||||
import { MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
|
||||
import { RoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
|
||||
import { AdminApiData, isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
|
||||
import * as tg from "generic-type-guard";
|
||||
import { isNumber } from "generic-type-guard";
|
||||
import { isWokaDetail } from "../Enum/PlayerTextures";
|
||||
|
||||
export interface AdminBannedData {
|
||||
is_banned: boolean;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface FetchMemberDataByUuidResponse {
|
||||
email: string;
|
||||
userUuid: string;
|
||||
tags: string[];
|
||||
visitCardUrl: string | null;
|
||||
textures: CharacterTexture[];
|
||||
messages: unknown[];
|
||||
anonymous?: boolean;
|
||||
userRoomToken: string | undefined;
|
||||
}
|
||||
const isFetchMemberDataByUuidResponse = new tg.IsInterface()
|
||||
.withProperties({
|
||||
email: tg.isString,
|
||||
userUuid: tg.isString,
|
||||
tags: tg.isArray(tg.isString),
|
||||
visitCardUrl: tg.isNullable(tg.isString),
|
||||
textures: tg.isArray(isWokaDetail),
|
||||
messages: tg.isArray(tg.isUnknown),
|
||||
})
|
||||
.withOptionalProperties({
|
||||
anonymous: tg.isBoolean,
|
||||
userRoomToken: tg.isString,
|
||||
})
|
||||
.get();
|
||||
|
||||
export type FetchMemberDataByUuidResponse = tg.GuardedType<typeof isFetchMemberDataByUuidResponse>;
|
||||
|
||||
class AdminApi {
|
||||
/**
|
||||
@@ -52,10 +60,16 @@ class AdminApi {
|
||||
if (!ADMIN_API_URL) {
|
||||
return Promise.reject(new Error("No admin backoffice set!"));
|
||||
}
|
||||
const res = await Axios.get(ADMIN_API_URL + "/api/room/access", {
|
||||
const res = await Axios.get<unknown, AxiosResponse<unknown>>(ADMIN_API_URL + "/api/room/access", {
|
||||
params: { userIdentifier, roomId, ipAddress },
|
||||
headers: { Authorization: `${ADMIN_API_TOKEN}` },
|
||||
});
|
||||
if (!isFetchMemberDataByUuidResponse(res.data)) {
|
||||
throw new Error(
|
||||
"Invalid answer received from the admin for the /api/map endpoint. Received: " +
|
||||
JSON.stringify(res.data)
|
||||
);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import axios from "axios";
|
||||
import { ADMIN_API_TOKEN, ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
||||
import { isWokaDetailsResult, isWokaList, WokaDetailsResult, WokaList } from "../Enum/PlayerTextures";
|
||||
import { isWokaList, WokaList } from "../Enum/PlayerTextures";
|
||||
import { WokaServiceInterface } from "./WokaServiceInterface";
|
||||
|
||||
class AdminWokaService implements WokaServiceInterface {
|
||||
@@ -32,7 +32,7 @@ class AdminWokaService implements WokaServiceInterface {
|
||||
*
|
||||
* If one of the textures cannot be found, undefined is returned
|
||||
*/
|
||||
fetchWokaDetails(textureIds: string[]): Promise<WokaDetailsResult | undefined> {
|
||||
/*fetchWokaDetails(textureIds: string[]): Promise<WokaDetailsResult | undefined> {
|
||||
return axios
|
||||
.post(
|
||||
`${ADMIN_API_URL}/api/woka-details`,
|
||||
@@ -49,11 +49,11 @@ class AdminWokaService implements WokaServiceInterface {
|
||||
}
|
||||
|
||||
const result: WokaDetailsResult = res.data;
|
||||
if (result.details.length !== textureIds.length) {
|
||||
if (result.length !== textureIds.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (const detail of result.details) {
|
||||
for (const detail of result) {
|
||||
if (!detail.texture) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ class AdminWokaService implements WokaServiceInterface {
|
||||
console.error(`Cannot get woka details from admin API with ids: ${textureIds}`, err);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
export const adminWokaService = new AdminWokaService();
|
||||
|
||||
@@ -23,7 +23,13 @@ class LocalWokaService implements WokaServiceInterface {
|
||||
*/
|
||||
async fetchWokaDetails(textureIds: string[]): Promise<WokaDetailsResult | undefined> {
|
||||
const wokaData: WokaList = await require("../../data/woka.json");
|
||||
const textures = new Map<string, string>();
|
||||
const textures = new Map<
|
||||
string,
|
||||
{
|
||||
url: string;
|
||||
layer: string;
|
||||
}
|
||||
>();
|
||||
const searchIds = new Set(textureIds);
|
||||
|
||||
for (const part of wokaPartNames) {
|
||||
@@ -37,7 +43,10 @@ class LocalWokaService implements WokaServiceInterface {
|
||||
const texture = collection.textures.find((texture) => texture.id === id);
|
||||
|
||||
if (texture) {
|
||||
textures.set(id, texture.url);
|
||||
textures.set(id, {
|
||||
url: texture.url,
|
||||
layer: part,
|
||||
});
|
||||
searchIds.delete(id);
|
||||
}
|
||||
}
|
||||
@@ -53,11 +62,12 @@ class LocalWokaService implements WokaServiceInterface {
|
||||
textures.forEach((value, key) => {
|
||||
details.push({
|
||||
id: key,
|
||||
texture: value,
|
||||
url: value.url,
|
||||
layer: value.layer,
|
||||
});
|
||||
});
|
||||
|
||||
return { details };
|
||||
return details;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PusherRoom } from "../Model/PusherRoom";
|
||||
import { CharacterLayer, ExSocketInterface } from "../Model/Websocket/ExSocketInterface";
|
||||
import { ExSocketInterface } from "../Model/Websocket/ExSocketInterface";
|
||||
import {
|
||||
AdminMessage,
|
||||
AdminPusherToBackMessage,
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
ErrorMessage,
|
||||
WorldFullMessage,
|
||||
PlayerDetailsUpdatedMessage,
|
||||
InvalidTextureMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
|
||||
import { ADMIN_API_URL, JITSI_ISS, JITSI_URL, SECRET_JITSI_KEY } from "../Enum/EnvironmentVariable";
|
||||
@@ -52,7 +53,7 @@ import Debug from "debug";
|
||||
import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface";
|
||||
import { WebSocket } from "uWebSockets.js";
|
||||
import { isRoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
|
||||
import { CharacterTexture } from "../Messages/JsonMessages/CharacterTexture";
|
||||
//import { CharacterTexture } from "../Messages/JsonMessages/CharacterTexture";
|
||||
import { compressors } from "hyper-express";
|
||||
|
||||
const debug = Debug("socket");
|
||||
@@ -175,10 +176,13 @@ export class SocketManager implements ZoneEventListener {
|
||||
|
||||
for (const characterLayer of client.characterLayers) {
|
||||
const characterLayerMessage = new CharacterLayerMessage();
|
||||
characterLayerMessage.setName(characterLayer.name);
|
||||
characterLayerMessage.setName(characterLayer.id);
|
||||
if (characterLayer.url !== undefined) {
|
||||
characterLayerMessage.setUrl(characterLayer.url);
|
||||
}
|
||||
if (characterLayer.layer !== undefined) {
|
||||
characterLayerMessage.setLayer(characterLayer.layer);
|
||||
}
|
||||
|
||||
joinRoomMessage.addCharacterlayer(characterLayerMessage);
|
||||
}
|
||||
@@ -545,36 +549,6 @@ export class SocketManager implements ZoneEventListener {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the characterLayers received from the front (as an array of string) with the custom textures from the back.
|
||||
*/
|
||||
static mergeCharacterLayersAndCustomTextures(
|
||||
characterLayers: string[],
|
||||
memberTextures: CharacterTexture[]
|
||||
): CharacterLayer[] {
|
||||
const characterLayerObjs: CharacterLayer[] = [];
|
||||
for (const characterLayer of characterLayers) {
|
||||
if (characterLayer.startsWith("customCharacterTexture")) {
|
||||
const customCharacterLayerId: number = +characterLayer.substr(22);
|
||||
for (const memberTexture of memberTextures) {
|
||||
if (memberTexture.id == customCharacterLayerId) {
|
||||
characterLayerObjs.push({
|
||||
name: characterLayer,
|
||||
url: memberTexture.url,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
characterLayerObjs.push({
|
||||
name: characterLayer,
|
||||
url: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
return characterLayerObjs;
|
||||
}
|
||||
|
||||
public onUserEnters(user: UserDescriptor, listener: ExSocketInterface): void {
|
||||
const subMessage = new SubMessage();
|
||||
subMessage.setUserjoinedmessage(user.toUserJoinedMessage());
|
||||
@@ -642,6 +616,17 @@ export class SocketManager implements ZoneEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
public emitInvalidTextureMessage(client: compressors.WebSocket) {
|
||||
const errorMessage = new InvalidTextureMessage();
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
serverToClientMessage.setInvalidtexturemessage(errorMessage);
|
||||
|
||||
if (!client.disconnecting) {
|
||||
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
||||
}
|
||||
}
|
||||
|
||||
public emitConnexionErrorMessage(client: compressors.WebSocket, message: string) {
|
||||
const errorMessage = new WorldConnexionMessage();
|
||||
errorMessage.setMessage(message);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ADMIN_API_URL } from "../Enum/EnvironmentVariable";
|
||||
import { adminWokaService } from "./AdminWokaService";
|
||||
import { localWokaService } from "./LocalWokaService";
|
||||
|
||||
export const wokaService = ADMIN_API_URL ? adminWokaService : localWokaService;
|
||||
@@ -14,5 +14,5 @@ export interface WokaServiceInterface {
|
||||
*
|
||||
* If one of the textures cannot be found, undefined is returned (and the user should be redirected to Woka choice page!)
|
||||
*/
|
||||
fetchWokaDetails(textureIds: string[]): Promise<WokaDetailsResult | undefined>;
|
||||
//fetchWokaDetails(textureIds: string[]): Promise<WokaDetailsResult | undefined>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user