forked from OpenWF/SpaceNinjaServer
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d54b2c043 | |||
| b23979855e | |||
| c835471f0f | |||
| f82bd09ee4 |
@ -1,7 +1,7 @@
|
||||
import type { RequestHandler } from "express";
|
||||
import { getReflexiveAddress } from "../../services/configService.ts";
|
||||
|
||||
export const hubController: RequestHandler = (req, res) => {
|
||||
const { myAddress } = getReflexiveAddress(req);
|
||||
res.json(`hub ${myAddress}:6952`);
|
||||
const hubController: RequestHandler = (_req, res) => {
|
||||
res.json("hub 127.0.0.1:6952");
|
||||
};
|
||||
|
||||
export { hubController };
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { RequestHandler } from "express";
|
||||
|
||||
import { config, getReflexiveAddress } from "../../services/configService.ts";
|
||||
import { config } from "../../services/configService.ts";
|
||||
import { buildConfig } from "../../services/buildConfigService.ts";
|
||||
|
||||
import { Account } from "../../models/loginModel.ts";
|
||||
@ -8,7 +8,7 @@ import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } f
|
||||
import type { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "../../types/loginTypes.ts";
|
||||
import { logger } from "../../utils/logger.ts";
|
||||
import { version_compare } from "../../helpers/inventoryHelpers.ts";
|
||||
import { sendWsBroadcastTo } from "../../services/wsService.ts";
|
||||
import { handleNonceInvalidation } from "../../services/wsService.ts";
|
||||
|
||||
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
|
||||
@ -20,7 +20,21 @@ export const loginController: RequestHandler = async (request, response) => {
|
||||
? request.query.buildLabel.split(" ").join("+")
|
||||
: buildConfig.buildLabel;
|
||||
|
||||
const { myAddress, myUrlBase } = getReflexiveAddress(request);
|
||||
let myAddress: string;
|
||||
let myUrlBase: string = request.protocol + "://";
|
||||
if (request.host.indexOf("warframe.com") == -1) {
|
||||
// Client request was redirected cleanly, so we know it can reach us how it's reaching us now.
|
||||
myAddress = request.hostname;
|
||||
myUrlBase += request.host;
|
||||
} else {
|
||||
// Don't know how the client reached us, hoping the config does.
|
||||
myAddress = config.myAddress;
|
||||
myUrlBase += myAddress;
|
||||
const port: number = request.protocol == "http" ? config.httpPort || 80 : config.httpsPort || 443;
|
||||
if (port != (request.protocol == "http" ? 80 : 443)) {
|
||||
myUrlBase += ":" + port;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!account &&
|
||||
@ -74,7 +88,7 @@ export const loginController: RequestHandler = async (request, response) => {
|
||||
account.LastLogin = new Date();
|
||||
await account.save();
|
||||
|
||||
sendWsBroadcastTo(account._id.toString(), { nonce_updated: true });
|
||||
handleNonceInvalidation(account._id.toString());
|
||||
|
||||
response.json(createLoginResponse(myAddress, myUrlBase, account.toJSON(), buildLabel));
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { RequestHandler } from "express";
|
||||
import { Account } from "../../models/loginModel.ts";
|
||||
import { sendWsBroadcastTo } from "../../services/wsService.ts";
|
||||
import { handleNonceInvalidation } from "../../services/wsService.ts";
|
||||
|
||||
export const logoutController: RequestHandler = async (req, res) => {
|
||||
if (!req.query.accountId) {
|
||||
@ -21,7 +21,7 @@ export const logoutController: RequestHandler = async (req, res) => {
|
||||
}
|
||||
);
|
||||
if (stat.modifiedCount) {
|
||||
sendWsBroadcastTo(req.query.accountId as string, { nonce_updated: true });
|
||||
handleNonceInvalidation(req.query.accountId as string);
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
|
||||
@ -17,7 +17,7 @@ import { InventorySlot } from "../../types/inventoryTypes/inventoryTypes.ts";
|
||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||
import type { IInventoryChanges } from "../../types/purchaseTypes.ts";
|
||||
import type { TInventoryDatabaseDocument } from "../../models/inventoryModels/inventoryModel.ts";
|
||||
import { sendWsBroadcastEx } from "../../services/wsService.ts";
|
||||
import { sendWsBroadcastEx, sendWsBroadcastTo } from "../../services/wsService.ts";
|
||||
import { parseFusionTreasure } from "../../helpers/inventoryHelpers.ts";
|
||||
|
||||
export const sellController: RequestHandler = async (req, res) => {
|
||||
@ -308,6 +308,9 @@ export const sellController: RequestHandler = async (req, res) => {
|
||||
inventoryChanges: inventoryChanges // "inventoryChanges" for this response instead of the usual "InventoryChanges"
|
||||
});
|
||||
sendWsBroadcastEx({ update_inventory: true }, accountId, parseInt(String(req.query.wsid)));
|
||||
if (req.query.wsid) {
|
||||
sendWsBroadcastTo(accountId, { sync_inventory: true });
|
||||
}
|
||||
};
|
||||
|
||||
interface ISellRequest {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
|
||||
import { getInventory, addItem } from "../../services/inventoryService.ts";
|
||||
import type { RequestHandler } from "express";
|
||||
import { sendWsBroadcastTo } from "../../services/wsService.ts";
|
||||
|
||||
export const addItemsController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
@ -9,6 +10,7 @@ export const addItemsController: RequestHandler = async (req, res) => {
|
||||
for (const request of requests) {
|
||||
await addItem(inventory, request.ItemType, request.ItemCount, true, undefined, request.Fingerprint, true);
|
||||
}
|
||||
sendWsBroadcastTo(accountId, { sync_inventory: true });
|
||||
await inventory.save();
|
||||
res.end();
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { applyClientEquipmentUpdates, getInventory } from "../../services/inventoryService.ts";
|
||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
|
||||
import { sendWsBroadcastTo } from "../../services/wsService.ts";
|
||||
import type { IOid } from "../../types/commonTypes.ts";
|
||||
import type { IEquipmentClient } from "../../types/equipmentTypes.ts";
|
||||
import type { TEquipmentKey } from "../../types/inventoryTypes/inventoryTypes.ts";
|
||||
@ -23,6 +24,7 @@ export const addXpController: RequestHandler = async (req, res) => {
|
||||
}
|
||||
applyClientEquipmentUpdates(inventory, gear, category as TEquipmentKey);
|
||||
}
|
||||
sendWsBroadcastTo(accountId, { sync_inventory: true });
|
||||
await inventory.save();
|
||||
res.end();
|
||||
};
|
||||
|
||||
@ -3,7 +3,6 @@ import path from "path";
|
||||
import { repoDir } from "../helpers/pathHelper.ts";
|
||||
import { args } from "../helpers/commandLineArguments.ts";
|
||||
import { Inbox } from "../models/inboxModel.ts";
|
||||
import type { Request } from "express";
|
||||
|
||||
export interface IConfig {
|
||||
mongodbUrl: string;
|
||||
@ -166,22 +165,3 @@ export const syncConfigWithDatabase = (): void => {
|
||||
void Inbox.deleteMany({ goalTag: "GalleonRobbery" }).then(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
export const getReflexiveAddress = (request: Request): { myAddress: string; myUrlBase: string } => {
|
||||
let myAddress: string;
|
||||
let myUrlBase: string = request.protocol + "://";
|
||||
if (request.host.indexOf("warframe.com") == -1) {
|
||||
// Client request was redirected cleanly, so we know it can reach us how it's reaching us now.
|
||||
myAddress = request.hostname;
|
||||
myUrlBase += request.host;
|
||||
} else {
|
||||
// Don't know how the client reached us, hoping the config does.
|
||||
myAddress = config.myAddress;
|
||||
myUrlBase += myAddress;
|
||||
const port: number = request.protocol == "http" ? config.httpPort || 80 : config.httpsPort || 443;
|
||||
if (port != (request.protocol == "http" ? 80 : 443)) {
|
||||
myUrlBase += ":" + port;
|
||||
}
|
||||
}
|
||||
return { myAddress, myUrlBase };
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@ import { Account } from "../models/loginModel.ts";
|
||||
import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService.ts";
|
||||
import type { IDatabaseAccountJson } from "../types/loginTypes.ts";
|
||||
import type { HydratedDocument } from "mongoose";
|
||||
import { logError } from "../utils/logger.ts";
|
||||
import { logError, logger } from "../utils/logger.ts";
|
||||
|
||||
let wsServer: WebSocketServer | undefined;
|
||||
let wssServer: WebSocketServer | undefined;
|
||||
@ -47,6 +47,7 @@ let lastWsid: number = 0;
|
||||
interface IWsCustomData extends ws {
|
||||
id: number;
|
||||
accountId?: string;
|
||||
isGame?: boolean;
|
||||
}
|
||||
|
||||
interface IWsMsgFromClient {
|
||||
@ -55,11 +56,18 @@ interface IWsMsgFromClient {
|
||||
password: string;
|
||||
isRegister: boolean;
|
||||
};
|
||||
auth_game?: {
|
||||
accountId: string;
|
||||
nonce: number;
|
||||
};
|
||||
logout?: boolean;
|
||||
}
|
||||
|
||||
interface IWsMsgToClient {
|
||||
//wsid?: number;
|
||||
// common
|
||||
wsid?: number;
|
||||
|
||||
// to webui
|
||||
reload?: boolean;
|
||||
ports?: {
|
||||
http: number | undefined;
|
||||
@ -77,6 +85,9 @@ interface IWsMsgToClient {
|
||||
nonce_updated?: boolean;
|
||||
update_inventory?: boolean;
|
||||
logged_out?: boolean;
|
||||
|
||||
// to game
|
||||
sync_inventory?: boolean;
|
||||
}
|
||||
|
||||
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
||||
@ -87,11 +98,12 @@ const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
||||
}
|
||||
|
||||
(ws as IWsCustomData).id = ++lastWsid;
|
||||
ws.send(JSON.stringify({ wsid: lastWsid }));
|
||||
ws.send(JSON.stringify({ wsid: lastWsid } satisfies IWsMsgToClient));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
ws.on("message", async msg => {
|
||||
try {
|
||||
//console.log(String(msg));
|
||||
const data = JSON.parse(String(msg)) as IWsMsgFromClient;
|
||||
if (data.auth) {
|
||||
let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
|
||||
@ -137,6 +149,19 @@ const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
||||
);
|
||||
}
|
||||
}
|
||||
if (data.auth_game) {
|
||||
(ws as IWsCustomData).isGame = true;
|
||||
if (data.auth_game.nonce) {
|
||||
const account: IDatabaseAccountJson | null = await Account.findOne({
|
||||
_id: data.auth_game.accountId,
|
||||
Nonce: data.auth_game.nonce
|
||||
});
|
||||
if (account) {
|
||||
(ws as IWsCustomData).accountId = account.id;
|
||||
logger.debug(`got bootstrapper connection for ${account.id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.logout) {
|
||||
const accountId = (ws as IWsCustomData).accountId;
|
||||
(ws as IWsCustomData).accountId = undefined;
|
||||
@ -154,6 +179,17 @@ const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
||||
logError(e as Error, `processing websocket message`);
|
||||
}
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
ws.on("close", async () => {
|
||||
if ((ws as IWsCustomData).isGame && (ws as IWsCustomData).accountId) {
|
||||
logger.debug(`lost bootstrapper connection for ${(ws as IWsCustomData).accountId}`);
|
||||
const account = await Account.findOne({ _id: (ws as IWsCustomData).accountId });
|
||||
if (account?.Nonce) {
|
||||
account.Dropped = true;
|
||||
await account.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendWsBroadcast = (data: IWsMsgToClient): void => {
|
||||
@ -211,3 +247,28 @@ export const sendWsBroadcastEx = (data: IWsMsgToClient, accountId?: string, excl
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const handleNonceInvalidation = (accountId: string): void => {
|
||||
if (wsServer) {
|
||||
for (const client of wsServer.clients) {
|
||||
if ((client as IWsCustomData).accountId == accountId) {
|
||||
if ((client as IWsCustomData).isGame) {
|
||||
client.close();
|
||||
} else {
|
||||
client.send(JSON.stringify({ nonce_updated: true } satisfies IWsMsgToClient));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wssServer) {
|
||||
for (const client of wssServer.clients) {
|
||||
if ((client as IWsCustomData).accountId == accountId) {
|
||||
if ((client as IWsCustomData).isGame) {
|
||||
client.close();
|
||||
} else {
|
||||
client.send(JSON.stringify({ nonce_updated: true } satisfies IWsMsgToClient));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -2339,7 +2339,7 @@ function unlockFocusSchool(upgradeType) {
|
||||
$.post({
|
||||
url: "/api/focus.php?" + window.authz + "&op=5",
|
||||
contentType: "text/plain",
|
||||
data: JSON.stringify({ FocusType: null })
|
||||
data: "{}"
|
||||
}).done(function () {
|
||||
// Unlock the way now
|
||||
$.post({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user