move websocket stuff into its own service
All checks were successful
Build / build (pull_request) Successful in 48s
All checks were successful
Build / build (pull_request) Successful in 48s
This commit is contained in:
parent
6ff32aa9db
commit
31523ddd19
@ -8,7 +8,7 @@ import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } f
|
|||||||
import { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "@/src/types/loginTypes";
|
import { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "@/src/types/loginTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
|
|
||||||
export const loginController: RequestHandler = async (request, response) => {
|
export const loginController: RequestHandler = async (request, response) => {
|
||||||
const loginRequest = JSON.parse(String(request.body)) as ILoginRequest; // parse octet stream of json data to json object
|
const loginRequest = JSON.parse(String(request.body)) as ILoginRequest; // parse octet stream of json data to json object
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from "@/src/services/loginRewardService";
|
} from "@/src/services/loginRewardService";
|
||||||
import { getInventory } from "@/src/services/inventoryService";
|
import { getInventory } from "@/src/services/inventoryService";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
|
|
||||||
export const loginRewardsController: RequestHandler = async (req, res) => {
|
export const loginRewardsController: RequestHandler = async (req, res) => {
|
||||||
const account = await getAccountForRequest(req);
|
const account = await getAccountForRequest(req);
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
} from "@/src/services/loginRewardService";
|
} from "@/src/services/loginRewardService";
|
||||||
import { getAccountForRequest } from "@/src/services/loginService";
|
import { getAccountForRequest } from "@/src/services/loginService";
|
||||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { Account } from "@/src/models/loginModel";
|
import { Account } from "@/src/models/loginModel";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
|
|
||||||
export const logoutController: RequestHandler = async (req, res) => {
|
export const logoutController: RequestHandler = async (req, res) => {
|
||||||
if (!req.query.accountId) {
|
if (!req.query.accountId) {
|
||||||
|
@ -7,7 +7,7 @@ import { getInventory } from "@/src/services/inventoryService";
|
|||||||
import { getInventoryResponse } from "./inventoryController";
|
import { getInventoryResponse } from "./inventoryController";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { IMissionInventoryUpdateResponse } from "@/src/types/missionTypes";
|
import { IMissionInventoryUpdateResponse } from "@/src/types/missionTypes";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
import { generateRewardSeed } from "@/src/services/rngService";
|
import { generateRewardSeed } from "@/src/services/rngService";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
|
|||||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
|
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
|
||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
|
|
||||||
interface INameWeaponRequest {
|
interface INameWeaponRequest {
|
||||||
ItemName: string;
|
ItemName: string;
|
||||||
|
@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
|
|||||||
import { IPurchaseRequest } from "@/src/types/purchaseTypes";
|
import { IPurchaseRequest } from "@/src/types/purchaseTypes";
|
||||||
import { handlePurchase } from "@/src/services/purchaseService";
|
import { handlePurchase } from "@/src/services/purchaseService";
|
||||||
import { getInventory } from "@/src/services/inventoryService";
|
import { getInventory } from "@/src/services/inventoryService";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
|
|
||||||
export const purchaseController: RequestHandler = async (req, res) => {
|
export const purchaseController: RequestHandler = async (req, res) => {
|
||||||
const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest;
|
const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
|
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
|
|||||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
|
|
||||||
export const sellController: RequestHandler = async (req, res) => {
|
export const sellController: RequestHandler = async (req, res) => {
|
||||||
const payload = JSON.parse(String(req.body)) as ISellRequest;
|
const payload = JSON.parse(String(req.body)) as ISellRequest;
|
||||||
|
@ -8,7 +8,7 @@ import { getRecipeByResult } from "@/src/services/itemDataService";
|
|||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService";
|
import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { sendWsBroadcastTo } from "@/src/services/webService";
|
import { sendWsBroadcastTo } from "@/src/services/wsService";
|
||||||
import { EquipmentFeatures, IEquipmentDatabase } from "@/src/types/equipmentTypes";
|
import { EquipmentFeatures, IEquipmentDatabase } from "@/src/types/equipmentTypes";
|
||||||
|
|
||||||
export const upgradesController: RequestHandler = async (req, res) => {
|
export const upgradesController: RequestHandler = async (req, res) => {
|
||||||
|
@ -2,7 +2,7 @@ import { RequestHandler } from "express";
|
|||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
|
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
|
||||||
import { saveConfig } from "@/src/services/configWatcherService";
|
import { saveConfig } from "@/src/services/configWatcherService";
|
||||||
import { sendWsBroadcastExcept } from "@/src/services/webService";
|
import { sendWsBroadcastExcept } from "@/src/services/wsService";
|
||||||
|
|
||||||
export const getConfigController: RequestHandler = async (req, res) => {
|
export const getConfigController: RequestHandler = async (req, res) => {
|
||||||
const account = await getAccountForRequest(req);
|
const account = await getAccountForRequest(req);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { args } from "@/src/helpers/commandLineArguments";
|
import { args } from "@/src/helpers/commandLineArguments";
|
||||||
import { sendWsBroadcast } from "@/src/services/webService";
|
import { sendWsBroadcast } from "@/src/services/wsService";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
export const webuiFileChangeDetectedController: RequestHandler = (req, res) => {
|
export const webuiFileChangeDetectedController: RequestHandler = (req, res) => {
|
||||||
|
@ -2,7 +2,8 @@ import chokidar from "chokidar";
|
|||||||
import fsPromises from "fs/promises";
|
import fsPromises from "fs/promises";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { config, configPath, loadConfig } from "./configService";
|
import { config, configPath, loadConfig } from "./configService";
|
||||||
import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService";
|
import { getWebPorts, startWebServer, stopWebServer } from "./webService";
|
||||||
|
import { sendWsBroadcast } from "./wsService";
|
||||||
import { Inbox } from "../models/inboxModel";
|
import { Inbox } from "../models/inboxModel";
|
||||||
import varzia from "@/static/fixed_responses/worldState/varzia.json";
|
import varzia from "@/static/fixed_responses/worldState/varzia.json";
|
||||||
|
|
||||||
|
@ -5,17 +5,11 @@ import { config } from "./configService";
|
|||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { app } from "../app";
|
import { app } from "../app";
|
||||||
import { AddressInfo } from "node:net";
|
import { AddressInfo } from "node:net";
|
||||||
import ws from "ws";
|
|
||||||
import { Account } from "../models/loginModel";
|
|
||||||
import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService";
|
|
||||||
import { IDatabaseAccountJson } from "../types/loginTypes";
|
|
||||||
import { HydratedDocument } from "mongoose";
|
|
||||||
import { Agent, WebSocket as UnidiciWebSocket } from "undici";
|
import { Agent, WebSocket as UnidiciWebSocket } from "undici";
|
||||||
|
import { startWsServer, startWssServer, stopWsServers } from "./wsService";
|
||||||
|
|
||||||
let httpServer: http.Server | undefined;
|
let httpServer: http.Server | undefined;
|
||||||
let httpsServer: https.Server | undefined;
|
let httpsServer: https.Server | undefined;
|
||||||
let wsServer: ws.Server | undefined;
|
|
||||||
let wssServer: ws.Server | undefined;
|
|
||||||
|
|
||||||
const tlsOptions = {
|
const tlsOptions = {
|
||||||
key: fs.readFileSync("static/certs/key.pem"),
|
key: fs.readFileSync("static/certs/key.pem"),
|
||||||
@ -29,16 +23,14 @@ export const startWebServer = (): void => {
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
httpServer = http.createServer(app);
|
httpServer = http.createServer(app);
|
||||||
httpServer.listen(httpPort, () => {
|
httpServer.listen(httpPort, () => {
|
||||||
wsServer = new ws.Server({ server: httpServer });
|
startWsServer(httpServer!);
|
||||||
wsServer.on("connection", wsOnConnect);
|
|
||||||
|
|
||||||
logger.info("HTTP server started on port " + httpPort);
|
logger.info("HTTP server started on port " + httpPort);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
httpsServer = https.createServer(tlsOptions, app);
|
httpsServer = https.createServer(tlsOptions, app);
|
||||||
httpsServer.listen(httpsPort, () => {
|
httpsServer.listen(httpsPort, () => {
|
||||||
wssServer = new ws.Server({ server: httpsServer });
|
startWssServer(httpsServer!);
|
||||||
wssServer.on("connection", wsOnConnect);
|
|
||||||
|
|
||||||
logger.info("HTTPS server started on port " + httpsPort);
|
logger.info("HTTPS server started on port " + httpsPort);
|
||||||
|
|
||||||
@ -115,182 +107,6 @@ export const stopWebServer = async (): Promise<void> => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (wsServer) {
|
stopWsServers(promises);
|
||||||
promises.push(
|
|
||||||
new Promise(resolve => {
|
|
||||||
wsServer!.close(() => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (wssServer) {
|
|
||||||
promises.push(
|
|
||||||
new Promise(resolve => {
|
|
||||||
wssServer!.close(() => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
};
|
};
|
||||||
|
|
||||||
let lastWsid: number = 0;
|
|
||||||
|
|
||||||
interface IWsCustomData extends ws {
|
|
||||||
id?: number;
|
|
||||||
accountId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IWsMsgFromClient {
|
|
||||||
auth?: {
|
|
||||||
email: string;
|
|
||||||
password: string;
|
|
||||||
isRegister: boolean;
|
|
||||||
};
|
|
||||||
logout?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IWsMsgToClient {
|
|
||||||
//wsid?: number;
|
|
||||||
reload?: boolean;
|
|
||||||
ports?: {
|
|
||||||
http: number | undefined;
|
|
||||||
https: number | undefined;
|
|
||||||
};
|
|
||||||
config_reloaded?: boolean;
|
|
||||||
auth_succ?: {
|
|
||||||
id: string;
|
|
||||||
DisplayName: string;
|
|
||||||
Nonce: number;
|
|
||||||
};
|
|
||||||
auth_fail?: {
|
|
||||||
isRegister: boolean;
|
|
||||||
};
|
|
||||||
logged_out?: boolean;
|
|
||||||
update_inventory?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
|
||||||
if (req.url == "/custom/selftest") {
|
|
||||||
ws.send("SpaceNinjaServer");
|
|
||||||
ws.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(ws as IWsCustomData).id = ++lastWsid;
|
|
||||||
ws.send(JSON.stringify({ wsid: lastWsid }));
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
ws.on("message", async msg => {
|
|
||||||
const data = JSON.parse(String(msg)) as IWsMsgFromClient;
|
|
||||||
if (data.auth) {
|
|
||||||
let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
|
|
||||||
if (account) {
|
|
||||||
if (isCorrectPassword(data.auth.password, account.password)) {
|
|
||||||
if (!account.Nonce) {
|
|
||||||
account.ClientType = "webui";
|
|
||||||
account.Nonce = createNonce();
|
|
||||||
await (account as HydratedDocument<IDatabaseAccountJson>).save();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
account = null;
|
|
||||||
}
|
|
||||||
} else if (data.auth.isRegister) {
|
|
||||||
const name = await getUsernameFromEmail(data.auth.email);
|
|
||||||
account = await createAccount({
|
|
||||||
email: data.auth.email,
|
|
||||||
password: data.auth.password,
|
|
||||||
ClientType: "webui",
|
|
||||||
LastLogin: new Date(),
|
|
||||||
DisplayName: name,
|
|
||||||
Nonce: createNonce()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (account) {
|
|
||||||
(ws as IWsCustomData).accountId = account.id;
|
|
||||||
ws.send(
|
|
||||||
JSON.stringify({
|
|
||||||
auth_succ: {
|
|
||||||
id: account.id,
|
|
||||||
DisplayName: account.DisplayName,
|
|
||||||
Nonce: account.Nonce
|
|
||||||
}
|
|
||||||
} satisfies IWsMsgToClient)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
ws.send(
|
|
||||||
JSON.stringify({
|
|
||||||
auth_fail: {
|
|
||||||
isRegister: data.auth.isRegister
|
|
||||||
}
|
|
||||||
} satisfies IWsMsgToClient)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.logout) {
|
|
||||||
const accountId = (ws as IWsCustomData).accountId;
|
|
||||||
(ws as IWsCustomData).accountId = undefined;
|
|
||||||
await Account.updateOne(
|
|
||||||
{
|
|
||||||
_id: accountId,
|
|
||||||
ClientType: "webui"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Nonce: 0
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendWsBroadcast = (data: IWsMsgToClient): void => {
|
|
||||||
const msg = JSON.stringify(data);
|
|
||||||
if (wsServer) {
|
|
||||||
for (const client of wsServer.clients) {
|
|
||||||
client.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wssServer) {
|
|
||||||
for (const client of wssServer.clients) {
|
|
||||||
client.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => {
|
|
||||||
const msg = JSON.stringify(data);
|
|
||||||
if (wsServer) {
|
|
||||||
for (const client of wsServer.clients) {
|
|
||||||
if ((client as IWsCustomData).accountId == accountId) {
|
|
||||||
client.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wssServer) {
|
|
||||||
for (const client of wssServer.clients) {
|
|
||||||
if ((client as IWsCustomData).accountId == accountId) {
|
|
||||||
client.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => {
|
|
||||||
const msg = JSON.stringify(data);
|
|
||||||
if (wsServer) {
|
|
||||||
for (const client of wsServer.clients) {
|
|
||||||
if ((client as IWsCustomData).id != wsid) {
|
|
||||||
client.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wssServer) {
|
|
||||||
for (const client of wssServer.clients) {
|
|
||||||
if ((client as IWsCustomData).id != wsid) {
|
|
||||||
client.send(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
200
src/services/wsService.ts
Normal file
200
src/services/wsService.ts
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
import http from "http";
|
||||||
|
import https from "https";
|
||||||
|
import ws from "ws";
|
||||||
|
import { Account } from "../models/loginModel";
|
||||||
|
import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService";
|
||||||
|
import { IDatabaseAccountJson } from "../types/loginTypes";
|
||||||
|
import { HydratedDocument } from "mongoose";
|
||||||
|
|
||||||
|
let wsServer: ws.Server | undefined;
|
||||||
|
let wssServer: ws.Server | undefined;
|
||||||
|
|
||||||
|
export const startWsServer = (httpServer: http.Server): void => {
|
||||||
|
wsServer = new ws.Server({ server: httpServer });
|
||||||
|
wsServer.on("connection", wsOnConnect);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const startWssServer = (httpsServer: https.Server): void => {
|
||||||
|
wssServer = new ws.Server({ server: httpsServer });
|
||||||
|
wssServer.on("connection", wsOnConnect);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stopWsServers = (promises: Promise<void>[]): void => {
|
||||||
|
if (wsServer) {
|
||||||
|
promises.push(
|
||||||
|
new Promise(resolve => {
|
||||||
|
wsServer!.close(() => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (wssServer) {
|
||||||
|
promises.push(
|
||||||
|
new Promise(resolve => {
|
||||||
|
wssServer!.close(() => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastWsid: number = 0;
|
||||||
|
|
||||||
|
interface IWsCustomData extends ws {
|
||||||
|
id?: number;
|
||||||
|
accountId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IWsMsgFromClient {
|
||||||
|
auth?: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
isRegister: boolean;
|
||||||
|
};
|
||||||
|
logout?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IWsMsgToClient {
|
||||||
|
//wsid?: number;
|
||||||
|
reload?: boolean;
|
||||||
|
ports?: {
|
||||||
|
http: number | undefined;
|
||||||
|
https: number | undefined;
|
||||||
|
};
|
||||||
|
config_reloaded?: boolean;
|
||||||
|
auth_succ?: {
|
||||||
|
id: string;
|
||||||
|
DisplayName: string;
|
||||||
|
Nonce: number;
|
||||||
|
};
|
||||||
|
auth_fail?: {
|
||||||
|
isRegister: boolean;
|
||||||
|
};
|
||||||
|
logged_out?: boolean;
|
||||||
|
update_inventory?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
||||||
|
if (req.url == "/custom/selftest") {
|
||||||
|
ws.send("SpaceNinjaServer");
|
||||||
|
ws.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(ws as IWsCustomData).id = ++lastWsid;
|
||||||
|
ws.send(JSON.stringify({ wsid: lastWsid }));
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
|
ws.on("message", async msg => {
|
||||||
|
const data = JSON.parse(String(msg)) as IWsMsgFromClient;
|
||||||
|
if (data.auth) {
|
||||||
|
let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
|
||||||
|
if (account) {
|
||||||
|
if (isCorrectPassword(data.auth.password, account.password)) {
|
||||||
|
if (!account.Nonce) {
|
||||||
|
account.ClientType = "webui";
|
||||||
|
account.Nonce = createNonce();
|
||||||
|
await (account as HydratedDocument<IDatabaseAccountJson>).save();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
account = null;
|
||||||
|
}
|
||||||
|
} else if (data.auth.isRegister) {
|
||||||
|
const name = await getUsernameFromEmail(data.auth.email);
|
||||||
|
account = await createAccount({
|
||||||
|
email: data.auth.email,
|
||||||
|
password: data.auth.password,
|
||||||
|
ClientType: "webui",
|
||||||
|
LastLogin: new Date(),
|
||||||
|
DisplayName: name,
|
||||||
|
Nonce: createNonce()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (account) {
|
||||||
|
(ws as IWsCustomData).accountId = account.id;
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
auth_succ: {
|
||||||
|
id: account.id,
|
||||||
|
DisplayName: account.DisplayName,
|
||||||
|
Nonce: account.Nonce
|
||||||
|
}
|
||||||
|
} satisfies IWsMsgToClient)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
auth_fail: {
|
||||||
|
isRegister: data.auth.isRegister
|
||||||
|
}
|
||||||
|
} satisfies IWsMsgToClient)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data.logout) {
|
||||||
|
const accountId = (ws as IWsCustomData).accountId;
|
||||||
|
(ws as IWsCustomData).accountId = undefined;
|
||||||
|
await Account.updateOne(
|
||||||
|
{
|
||||||
|
_id: accountId,
|
||||||
|
ClientType: "webui"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Nonce: 0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendWsBroadcast = (data: IWsMsgToClient): void => {
|
||||||
|
const msg = JSON.stringify(data);
|
||||||
|
if (wsServer) {
|
||||||
|
for (const client of wsServer.clients) {
|
||||||
|
client.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wssServer) {
|
||||||
|
for (const client of wssServer.clients) {
|
||||||
|
client.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => {
|
||||||
|
const msg = JSON.stringify(data);
|
||||||
|
if (wsServer) {
|
||||||
|
for (const client of wsServer.clients) {
|
||||||
|
if ((client as IWsCustomData).accountId == accountId) {
|
||||||
|
client.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wssServer) {
|
||||||
|
for (const client of wssServer.clients) {
|
||||||
|
if ((client as IWsCustomData).accountId == accountId) {
|
||||||
|
client.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => {
|
||||||
|
const msg = JSON.stringify(data);
|
||||||
|
if (wsServer) {
|
||||||
|
for (const client of wsServer.clients) {
|
||||||
|
if ((client as IWsCustomData).id != wsid) {
|
||||||
|
client.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wssServer) {
|
||||||
|
for (const client of wssServer.clients) {
|
||||||
|
if ((client as IWsCustomData).id != wsid) {
|
||||||
|
client.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user