Added WebSocket handlers for new connections and messages received through the default EFT socket (!339)
Co-authored-by: clodan <clodan@clodan.com> Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/339 Co-authored-by: Alex <clodan@noreply.dev.sp-tarkov.com> Co-committed-by: Alex <clodan@noreply.dev.sp-tarkov.com>
This commit is contained in:
parent
3163e5cd0c
commit
5b5bf8bd7c
@ -70,12 +70,12 @@
|
||||
"@yao-pkg/pkg-fetch": "3.5.9",
|
||||
"cross-env": "~7.0",
|
||||
"eslint": "~8.57",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-prettier": "~9.1",
|
||||
"eslint-import-resolver-typescript": "~3.6",
|
||||
"eslint-plugin-import": "~2.29",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-switch-allman": "^1.0.2",
|
||||
"eslint-plugin-unused-imports": "^3.2.0",
|
||||
"eslint-plugin-prettier": "~5.1",
|
||||
"eslint-plugin-switch-allman": "~1.0",
|
||||
"eslint-plugin-unused-imports": "~3.2",
|
||||
"fs-extra": "~11.2",
|
||||
"gulp": "~4.0",
|
||||
"gulp-decompress": "~3.0",
|
||||
@ -84,11 +84,11 @@
|
||||
"gulp-rename": "~2.0",
|
||||
"madge": "~6.1",
|
||||
"minimist": "~1.2",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "~3.2",
|
||||
"resedit": "~2.0",
|
||||
"ts-node-dev": "~2.0",
|
||||
"tsconfig-paths": "~4.2",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"tslint-config-prettier": "~1.18",
|
||||
"typedoc": "~0.25",
|
||||
"typemoq": "~2.1",
|
||||
"typescript-eslint": "~7.8",
|
||||
|
@ -192,6 +192,10 @@ import { HttpServer } from "@spt-aki/servers/HttpServer";
|
||||
import { RagfairServer } from "@spt-aki/servers/RagfairServer";
|
||||
import { SaveServer } from "@spt-aki/servers/SaveServer";
|
||||
import { WebSocketServer } from "@spt-aki/servers/WebSocketServer";
|
||||
import { AkiWebSocketConnectionHandler } from "@spt-aki/servers/ws/AkiWebSocketConnectionHandler";
|
||||
import { IWebSocketConnectionHandler } from "@spt-aki/servers/ws/IWebSocketConnectionHandler";
|
||||
import { DefaultAkiWebSocketMessageHandler } from "@spt-aki/servers/ws/message/DefaultAkiWebSocketMessageHandler";
|
||||
import { IAkiWebSocketMessageHandler } from "@spt-aki/servers/ws/message/IAkiWebSocketMessageHandler";
|
||||
import { BotEquipmentFilterService } from "@spt-aki/services/BotEquipmentFilterService";
|
||||
import { BotEquipmentModPoolService } from "@spt-aki/services/BotEquipmentModPoolService";
|
||||
import { BotGenerationCacheService } from "@spt-aki/services/BotGenerationCacheService";
|
||||
@ -383,6 +387,12 @@ export class Container
|
||||
depContainer.registerType("SptCommand", "GiveSptCommand");
|
||||
depContainer.registerType("SptCommand", "TraderSptCommand");
|
||||
depContainer.registerType("SptCommand", "ProfileSptCommand");
|
||||
|
||||
// WebSocketHandlers
|
||||
depContainer.registerType("WebSocketConnectionHandler", "AkiWebSocketConnectionHandler");
|
||||
|
||||
// WebSocketMessageHandlers
|
||||
depContainer.registerType("AkiWebSocketMessageHandler", "DefaultAkiWebSocketMessageHandler");
|
||||
}
|
||||
|
||||
private static registerUtils(depContainer: DependencyContainer): void
|
||||
@ -778,6 +788,8 @@ export class Container
|
||||
depContainer.register<DatabaseServer>("DatabaseServer", DatabaseServer, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<HttpServer>("HttpServer", HttpServer, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<WebSocketServer>("WebSocketServer", WebSocketServer, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<IWebSocketConnectionHandler>("AkiWebSocketConnectionHandler", AkiWebSocketConnectionHandler, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<IAkiWebSocketMessageHandler>("DefaultAkiWebSocketMessageHandler", DefaultAkiWebSocketMessageHandler, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<RagfairServer>("RagfairServer", RagfairServer);
|
||||
depContainer.register<SaveServer>("SaveServer", SaveServer, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<ConfigServer>("ConfigServer", ConfigServer, { lifecycle: Lifecycle.Singleton });
|
||||
|
@ -191,8 +191,8 @@ export class GiveSptCommand implements ISptCommand
|
||||
}
|
||||
}
|
||||
|
||||
const localizedGlobal
|
||||
= this.databaseServer.getTables().locales.global[locale] ?? this.databaseServer.getTables().locales.global.en;
|
||||
const localizedGlobal = this.databaseServer.getTables().locales.global[locale]
|
||||
?? this.databaseServer.getTables().locales.global.en;
|
||||
// If item is an item name, we need to search using that item name and the locale which one we want otherwise
|
||||
// item is just the tplId.
|
||||
const tplId = isItemName
|
||||
|
@ -6,7 +6,7 @@ import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
|
||||
import { MessageType } from "@spt-aki/models/enums/MessageType";
|
||||
import { NotificationEventType } from "@spt-aki/models/enums/NotificationEventType";
|
||||
import { SaveServer } from "@spt-aki/servers/SaveServer";
|
||||
import { WebSocketServer } from "@spt-aki/servers/WebSocketServer";
|
||||
import { AkiWebSocketConnectionHandler } from "@spt-aki/servers/ws/AkiWebSocketConnectionHandler";
|
||||
import { NotificationService } from "@spt-aki/services/NotificationService";
|
||||
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
||||
|
||||
@ -14,7 +14,7 @@ import { HashUtil } from "@spt-aki/utils/HashUtil";
|
||||
export class NotificationSendHelper
|
||||
{
|
||||
constructor(
|
||||
@inject("WebSocketServer") protected webSocketServer: WebSocketServer,
|
||||
@inject("AkiWebSocketConnectionHandler") protected akiWebSocketConnection: AkiWebSocketConnectionHandler,
|
||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
||||
@inject("SaveServer") protected saveServer: SaveServer,
|
||||
@inject("NotificationService") protected notificationService: NotificationService,
|
||||
@ -28,9 +28,9 @@ export class NotificationSendHelper
|
||||
*/
|
||||
public sendMessage(sessionID: string, notificationMessage: IWsNotificationEvent): void
|
||||
{
|
||||
if (this.webSocketServer.isConnectionWebSocket(sessionID))
|
||||
if (this.akiWebSocketConnection.isConnectionWebSocket(sessionID))
|
||||
{
|
||||
this.webSocketServer.sendMessage(sessionID, notificationMessage);
|
||||
this.akiWebSocketConnection.sendMessage(sessionID, notificationMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,54 +1,37 @@
|
||||
import http, { IncomingMessage } from "node:http";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import WebSocket from "ws";
|
||||
import { inject, injectAll, injectable } from "tsyringe";
|
||||
import { WebSocket, Server } from "ws";
|
||||
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { IWsNotificationEvent } from "@spt-aki/models/eft/ws/IWsNotificationEvent";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { NotificationEventType } from "@spt-aki/models/enums/NotificationEventType";
|
||||
import { IHttpConfig } from "@spt-aki/models/spt/config/IHttpConfig";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
||||
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
||||
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
|
||||
import { IWebSocketConnectionHandler } from "./ws/IWebSocketConnectionHandler";
|
||||
|
||||
@injectable()
|
||||
export class WebSocketServer
|
||||
{
|
||||
protected webSocketServer: Server;
|
||||
|
||||
constructor(
|
||||
@inject("WinstonLogger") protected logger: ILogger,
|
||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||
@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper,
|
||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||
@injectAll("WebSocketConnectionHandler") protected webSocketConnectionHandlers: IWebSocketConnectionHandler[],
|
||||
)
|
||||
{
|
||||
this.httpConfig = this.configServer.getConfig(ConfigTypes.HTTP);
|
||||
}
|
||||
|
||||
protected httpConfig: IHttpConfig;
|
||||
protected defaultNotification: IWsNotificationEvent = { type: NotificationEventType.PING, eventId: "ping" };
|
||||
|
||||
protected webSocketServer: WebSocket.Server;
|
||||
protected webSockets: Record<string, WebSocket.WebSocket> = {};
|
||||
protected websocketPingHandler = null;
|
||||
|
||||
public getWebSocketServer(): WebSocket.Server
|
||||
public getWebSocketServer(): Server
|
||||
{
|
||||
return this.webSocketServer;
|
||||
}
|
||||
|
||||
public getSessionWebSocket(sessionID: string): WebSocket.WebSocket
|
||||
{
|
||||
return this.webSockets[sessionID];
|
||||
}
|
||||
|
||||
public setupWebSocket(httpServer: http.Server): void
|
||||
{
|
||||
this.webSocketServer = new WebSocket.Server({ server: httpServer });
|
||||
this.webSocketServer = new Server({ server: httpServer });
|
||||
|
||||
this.webSocketServer.addListener("listening", () =>
|
||||
{
|
||||
@ -63,26 +46,6 @@ export class WebSocketServer
|
||||
this.webSocketServer.addListener("connection", this.wsOnConnection.bind(this));
|
||||
}
|
||||
|
||||
public sendMessage(sessionID: string, output: IWsNotificationEvent): void
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.isConnectionWebSocket(sessionID))
|
||||
{
|
||||
this.webSockets[sessionID].send(this.jsonUtil.serialize(output));
|
||||
this.logger.debug(this.localisationService.getText("websocket-message_sent"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logger.debug(this.localisationService.getText("websocket-not_ready_message_not_sent", sessionID));
|
||||
}
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
this.logger.error(this.localisationService.getText("websocket-message_send_failed_with_error", err));
|
||||
}
|
||||
}
|
||||
|
||||
protected getRandomisedMessage(): string
|
||||
{
|
||||
if (this.randomUtil.getInt(1, 1000) > 999)
|
||||
@ -95,49 +58,21 @@ export class WebSocketServer
|
||||
: this.localisationService.getText("server_start_success");
|
||||
}
|
||||
|
||||
public isConnectionWebSocket(sessionID: string): boolean
|
||||
protected wsOnConnection(ws: WebSocket, req: IncomingMessage): void
|
||||
{
|
||||
return this.webSockets[sessionID] !== undefined && this.webSockets[sessionID].readyState === WebSocket.OPEN;
|
||||
}
|
||||
|
||||
protected wsOnConnection(ws: WebSocket.WebSocket, req: IncomingMessage): void
|
||||
{
|
||||
// Strip request and break it into sections
|
||||
const splitUrl = req.url.substring(0, req.url.indexOf("?")).split("/");
|
||||
const sessionID = splitUrl.pop();
|
||||
const playerProfile = this.profileHelper.getFullProfile(sessionID);
|
||||
const playerInfoText = `${playerProfile.info.username} (${sessionID})`;
|
||||
|
||||
this.logger.info(this.localisationService.getText("websocket-player_connected", playerInfoText));
|
||||
|
||||
const logger = this.logger;
|
||||
const msgToLog = this.localisationService.getText("websocket-received_message", playerInfoText);
|
||||
ws.on("message", (msg) =>
|
||||
const socketHandlers = this.webSocketConnectionHandlers.filter((wsh) => req.url.includes(wsh.getHookUrl()));
|
||||
if ((socketHandlers?.length ?? 0) === 0)
|
||||
{
|
||||
logger.info(`${msgToLog} ${msg}`);
|
||||
});
|
||||
|
||||
this.webSockets[sessionID] = ws;
|
||||
|
||||
if (this.websocketPingHandler)
|
||||
{
|
||||
clearInterval(this.websocketPingHandler);
|
||||
const message = `Socket connection received for url ${req.url}, but there is not websocket handler configured for it`;
|
||||
this.logger.warning(message);
|
||||
ws.send(this.jsonUtil.serialize({ error: message }));
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
|
||||
this.websocketPingHandler = setInterval(() =>
|
||||
socketHandlers.forEach((wsh) =>
|
||||
{
|
||||
this.logger.debug(this.localisationService.getText("websocket-pinging_player", sessionID));
|
||||
|
||||
if (ws.readyState === WebSocket.OPEN)
|
||||
{
|
||||
ws.send(this.jsonUtil.serialize(this.defaultNotification));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logger.debug(this.localisationService.getText("websocket-socket_lost_deleting_handle"));
|
||||
clearInterval(this.websocketPingHandler);
|
||||
delete this.webSockets[sessionID];
|
||||
}
|
||||
}, this.httpConfig.webSocketPingDelayMs);
|
||||
wsh.onConnection(ws, req);
|
||||
this.logger.info(`WebSocketHandler "${wsh.getSocketId()}" connected`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
112
project/src/servers/ws/AkiWebSocketConnectionHandler.ts
Normal file
112
project/src/servers/ws/AkiWebSocketConnectionHandler.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import { IncomingMessage } from "http";
|
||||
import { inject, injectAll, injectable } from "tsyringe";
|
||||
import { WebSocket } from "ws";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { IWsNotificationEvent } from "@spt-aki/models/eft/ws/IWsNotificationEvent";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { NotificationEventType } from "@spt-aki/models/enums/NotificationEventType";
|
||||
import { IHttpConfig } from "@spt-aki/models/spt/config/IHttpConfig";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { IWebSocketConnectionHandler } from "@spt-aki/servers/ws/IWebSocketConnectionHandler";
|
||||
import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
||||
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
||||
import { IAkiWebSocketMessageHandler } from "./message/IAkiWebSocketMessageHandler";
|
||||
|
||||
@injectable()
|
||||
export class AkiWebSocketConnectionHandler implements IWebSocketConnectionHandler
|
||||
{
|
||||
protected httpConfig: IHttpConfig;
|
||||
protected webSockets: Map<string, WebSocket> = new Map<string, WebSocket>();
|
||||
protected defaultNotification: IWsNotificationEvent = { type: NotificationEventType.PING, eventId: "ping" };
|
||||
|
||||
protected websocketPingHandler = null;
|
||||
constructor(
|
||||
@inject("WinstonLogger") protected logger: ILogger,
|
||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
||||
@injectAll("AkiWebSocketMessageHandler") protected akiWebSocketMessageHandlers: IAkiWebSocketMessageHandler[],
|
||||
)
|
||||
{
|
||||
this.httpConfig = this.configServer.getConfig(ConfigTypes.HTTP);
|
||||
}
|
||||
|
||||
public getSocketId(): string
|
||||
{
|
||||
return "AKI WebSocket Handler";
|
||||
}
|
||||
|
||||
public getHookUrl(): string
|
||||
{
|
||||
return "/notifierServer/getwebsocket/";
|
||||
}
|
||||
|
||||
public onConnection(ws: WebSocket, req: IncomingMessage): void
|
||||
{
|
||||
// Strip request and break it into sections
|
||||
const splitUrl = req.url.substring(0, req.url.indexOf("?")).split("/");
|
||||
const sessionID = splitUrl.pop();
|
||||
const playerProfile = this.profileHelper.getFullProfile(sessionID);
|
||||
const playerInfoText = `${playerProfile.info.username} (${sessionID})`;
|
||||
|
||||
this.logger.info(this.localisationService.getText("websocket-player_connected", playerInfoText));
|
||||
|
||||
// throw new Error("Method not implemented.");
|
||||
this.webSockets.set(sessionID, ws);
|
||||
|
||||
if (this.websocketPingHandler)
|
||||
{
|
||||
clearInterval(this.websocketPingHandler);
|
||||
}
|
||||
|
||||
ws.on("message", (msg) => this.akiWebSocketMessageHandlers.forEach((wsmh) => wsmh.onAkiMessage(sessionID, this.webSockets.get(sessionID), msg)));
|
||||
|
||||
this.websocketPingHandler = setInterval(() =>
|
||||
{
|
||||
this.logger.debug(this.localisationService.getText("websocket-pinging_player", sessionID));
|
||||
|
||||
if (ws.readyState === WebSocket.OPEN)
|
||||
{
|
||||
ws.send(this.jsonUtil.serialize(this.defaultNotification));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logger.debug(this.localisationService.getText("websocket-socket_lost_deleting_handle"));
|
||||
clearInterval(this.websocketPingHandler);
|
||||
this.webSockets.delete(sessionID);
|
||||
}
|
||||
}, this.httpConfig.webSocketPingDelayMs);
|
||||
}
|
||||
|
||||
public sendMessage(sessionID: string, output: IWsNotificationEvent): void
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.isConnectionWebSocket(sessionID))
|
||||
{
|
||||
this.webSockets.get(sessionID).send(this.jsonUtil.serialize(output));
|
||||
this.logger.debug(this.localisationService.getText("websocket-message_sent"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logger.debug(this.localisationService.getText("websocket-not_ready_message_not_sent", sessionID));
|
||||
}
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
this.logger.error(this.localisationService.getText("websocket-message_send_failed_with_error", err));
|
||||
}
|
||||
}
|
||||
|
||||
public isConnectionWebSocket(sessionID: string): boolean
|
||||
{
|
||||
return this.webSockets.has(sessionID) && this.webSockets.get(sessionID).readyState === WebSocket.OPEN;
|
||||
}
|
||||
|
||||
public getSessionWebSocket(sessionID: string): WebSocket
|
||||
{
|
||||
return this.webSockets[sessionID];
|
||||
}
|
||||
}
|
9
project/src/servers/ws/IWebSocketConnectionHandler.ts
Normal file
9
project/src/servers/ws/IWebSocketConnectionHandler.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { IncomingMessage } from "node:http";
|
||||
import { WebSocket } from "ws";
|
||||
|
||||
export interface IWebSocketConnectionHandler
|
||||
{
|
||||
getSocketId(): string
|
||||
getHookUrl(): string
|
||||
onConnection(ws: WebSocket, req: IncomingMessage): void
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { RawData, WebSocket } from "ws";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { IAkiWebSocketMessageHandler } from "@spt-aki/servers/ws/message/IAkiWebSocketMessageHandler";
|
||||
|
||||
@injectable()
|
||||
export class DefaultAkiWebSocketMessageHandler implements IAkiWebSocketMessageHandler
|
||||
{
|
||||
constructor(@inject("WinstonLogger") protected logger: ILogger)
|
||||
{}
|
||||
|
||||
public onAkiMessage(sessionId: string, client: WebSocket, message: RawData): void
|
||||
{
|
||||
this.logger.debug(`[${sessionId}] AKI message received: ${message}`);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { RawData, WebSocket } from "ws";
|
||||
|
||||
export interface IAkiWebSocketMessageHandler
|
||||
{
|
||||
onAkiMessage(sessionID: string, client: WebSocket, message: RawData): void
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { ILocaleConfig } from "@spt-aki/models/spt/config/ILocaleConfig";
|
||||
import { ILocaleBase } from "@spt-aki/models/spt/server/ILocaleBase";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
@ -13,7 +12,6 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
export class LocaleService
|
||||
{
|
||||
protected localeConfig: ILocaleConfig;
|
||||
protected localesTable: ILocaleBase;
|
||||
|
||||
constructor(
|
||||
@inject("WinstonLogger") protected logger: ILogger,
|
||||
@ -22,7 +20,6 @@ export class LocaleService
|
||||
)
|
||||
{
|
||||
this.localeConfig = this.configServer.getConfig(ConfigTypes.LOCALE);
|
||||
this.localesTable = this.databaseServer.getTables().locales;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,7 +28,7 @@ export class LocaleService
|
||||
*/
|
||||
public getLocaleDb(): Record<string, string>
|
||||
{
|
||||
const desiredLocale = this.localesTable.global[this.getDesiredGameLocale()];
|
||||
const desiredLocale = this.databaseServer.getTables().locales.global[this.getDesiredGameLocale()];
|
||||
if (desiredLocale)
|
||||
{
|
||||
return desiredLocale;
|
||||
@ -41,7 +38,7 @@ export class LocaleService
|
||||
`Unable to find desired locale file using locale: ${this.getDesiredGameLocale()} from config/locale.json, falling back to 'en'`,
|
||||
);
|
||||
|
||||
return this.localesTable.global.en;
|
||||
return this.databaseServer.getTables().locales.global.en;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,19 +135,19 @@ export class LocaleService
|
||||
}
|
||||
|
||||
const baseNameCode = platformLocale.baseName?.toLocaleLowerCase();
|
||||
if (baseNameCode && this.localesTable.global[baseNameCode])
|
||||
if (baseNameCode && this.databaseServer.getTables().locales.global[baseNameCode])
|
||||
{
|
||||
return baseNameCode;
|
||||
}
|
||||
|
||||
const languageCode = platformLocale.language?.toLowerCase();
|
||||
if (languageCode && this.localesTable.global[languageCode])
|
||||
if (languageCode && this.databaseServer.getTables().locales.global[languageCode])
|
||||
{
|
||||
return languageCode;
|
||||
}
|
||||
|
||||
const regionCode = platformLocale.region?.toLocaleLowerCase();
|
||||
if (regionCode && this.localesTable.global[regionCode])
|
||||
if (regionCode && this.databaseServer.getTables().locales.global[regionCode])
|
||||
{
|
||||
return regionCode;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user