Compare commits

...

7 Commits

Author SHA1 Message Date
eb4698109e merge upstream 2025-06-21 23:43:44 -07:00
3bcd5827f9 chore(webui): unset nonce when logging out (#2242)
Reviewed-on: OpenWF/SpaceNinjaServer#2242
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-06-21 14:38:48 -07:00
d16d763977 chore: handle logout POST request for older versions (#2240)
Reviewed-on: OpenWF/SpaceNinjaServer#2240
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-06-21 14:38:24 -07:00
ff8ec8dbed chore(webui): update bootstrap, add sourcemaps for it (#2238)
Reviewed-on: OpenWF/SpaceNinjaServer#2238
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-06-21 14:38:04 -07:00
6cdd103c3d chore(dev): improve bulk change handling (#2234)
Fixed abandoned build processes sometimes still triggering a start (causing double-starts) made it more robust in regards to webui changes being intermixed: making the fetch a fire-and-forget to avoid errors, and waiting for the websocket connection to be re-established to avoid the browser attempting to reload when the server may not be up for a few seconds.

Reviewed-on: OpenWF/SpaceNinjaServer#2234
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-06-21 11:33:59 -07:00
b6f79c1e5c fix: save steel path mission completion (#2233)
Fixes #2228

Reviewed-on: OpenWF/SpaceNinjaServer#2233
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-06-21 11:25:42 -07:00
2bb3e2afdd chore(webui): update to Spanish translation (#2236)
Reviewed-on: OpenWF/SpaceNinjaServer#2236
Co-authored-by: hxedcl <hxedcl@noreply.localhost>
Co-committed-by: hxedcl <hxedcl@noreply.localhost>
2025-06-21 10:51:57 -07:00
11 changed files with 55 additions and 24 deletions

View File

@ -28,8 +28,12 @@ function run(changedFile) {
runproc = undefined;
}
buildproc = spawn("npm", ["run", "build:dev"], { stdio: "inherit", shell: true });
const thisbuildproc = spawn("npm", ["run", "build:dev"], { stdio: "inherit", shell: true });
buildproc = thisbuildproc;
buildproc.on("exit", code => {
if (buildproc !== thisbuildproc) {
return;
}
buildproc = undefined;
if (code === 0) {
runproc = spawn("npm", ["run", "start", "--", ...args], { stdio: "inherit", shell: true });
@ -44,6 +48,8 @@ run();
chokidar.watch("src").on("change", run);
chokidar.watch("static/fixed_responses").on("change", run);
chokidar.watch("static/webui").on("change", () => {
fetch("http://localhost/custom/webuiFileChangeDetected?secret=" + secret);
chokidar.watch("static/webui").on("change", async () => {
try {
await fetch("http://localhost/custom/webuiFileChangeDetected?secret=" + secret);
} catch (e) {}
});

View File

@ -1,11 +1,10 @@
import { args } from "@/src/helpers/commandLineArguments";
import { config } from "@/src/services/configService";
import { sendWsBroadcast } from "@/src/services/webService";
import { RequestHandler } from "express";
export const webuiFileChangeDetectedController: RequestHandler = (req, res) => {
if (args.dev && args.secret && req.query.secret == args.secret) {
sendWsBroadcast({ ports: { http: config.httpPort, https: config.httpsPort } });
sendWsBroadcast({ reload: true });
}
res.end();
};

View File

@ -284,6 +284,7 @@ apiRouter.post("/inventorySlots.php", inventorySlotsController);
apiRouter.post("/joinSession.php", joinSessionController);
apiRouter.post("/login.php", loginController);
apiRouter.post("/loginRewardsSelection.php", loginRewardsSelectionController);
apiRouter.post("/logout.php", logoutController); // from ~U16, don't know when they changed it to GET
apiRouter.post("/maturePet.php", maturePetController);
apiRouter.post("/missionInventoryUpdate.php", missionInventoryUpdateController);
apiRouter.post("/modularWeaponCrafting.php", modularWeaponCraftingController);

View File

@ -1825,12 +1825,15 @@ export const addChallenges = (
return affiliationMods;
};
export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes }: IMission): void => {
export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes, Tier }: IMission): void => {
const { Missions } = inventory;
const itemIndex = Missions.findIndex(item => item.Tag === Tag);
if (itemIndex !== -1) {
Missions[itemIndex].Completes += Completes;
if (Tier) {
Missions[itemIndex].Tier = Tier;
}
} else {
Missions.push({ Tag, Completes });
}

View File

@ -110,6 +110,7 @@ interface IWsMsgFromClient {
}
interface IWsMsgToClient {
reload?: boolean;
ports?: {
http: number | undefined;
https: number | undefined;
@ -175,7 +176,17 @@ const wsOnConnect = (ws: ws, _req: http.IncomingMessage): void => {
}
}
if (data.logout) {
const accountId = (ws as IWsCustomData).accountId;
(ws as IWsCustomData).accountId = undefined;
await Account.updateOne(
{
_id: accountId,
ClientType: "webui"
},
{
Nonce: 0
}
);
}
});
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,9 +9,10 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
let auth_pending = false,
did_initial_auth = false;
did_initial_auth = false,
ws_is_open = false;
const sendAuth = isRegister => {
if (localStorage.getItem("email") && localStorage.getItem("password")) {
if (ws_is_open && localStorage.getItem("email") && localStorage.getItem("password")) {
auth_pending = true;
window.ws.send(
JSON.stringify({
@ -28,10 +29,18 @@ const sendAuth = isRegister => {
function openWebSocket() {
window.ws = new WebSocket("/custom/ws");
window.ws.onopen = () => {
ws_is_open = true;
sendAuth(false);
};
window.ws.onmessage = e => {
const msg = JSON.parse(e.data);
if ("reload" in msg) {
setTimeout(() => {
getWebSocket().then(() => {
location.reload();
});
}, 100);
}
if ("ports" in msg) {
location.port = location.protocol == "https:" ? msg.ports.https : msg.ports.http;
}
@ -72,7 +81,7 @@ function openWebSocket() {
}
};
window.ws.onclose = function () {
window.ws = undefined;
ws_is_open = false;
setTimeout(openWebSocket, 3000);
};
}
@ -82,7 +91,7 @@ function getWebSocket() {
return new Promise(resolve => {
let interval;
interval = setInterval(() => {
if (window.ws) {
if (ws_is_open) {
clearInterval(interval);
resolve(window.ws);
}
@ -117,7 +126,7 @@ function logout() {
function doLogout() {
logout();
if (window.ws) {
if (ws_is_open) {
// Unsubscribe from notifications about nonce invalidation
window.ws.send(JSON.stringify({ logout: true }));
}

View File

@ -100,7 +100,7 @@ dict = {
inventory_bulkRankUpSentinels: `Maximizar rango de todos los centinelas`,
inventory_bulkRankUpSentinelWeapons: `Maximizar rango de todas las armas de centinela`,
inventory_bulkRankUpEvolutionProgress: `Maximizar todo el progreso de evolución Incarnon`,
inventory_maxPlexus: `[UNTRANSLATED] Max Rank Plexus`,
inventory_maxPlexus: `Rango máximo de Plexus`,
quests_list: `Misiones`,
quests_completeAll: `Completar todas las misiones`,
@ -135,10 +135,10 @@ dict = {
cheats_infiniteRegalAya: `Aya Real infinita`,
cheats_infiniteHelminthMaterials: `Materiales Helminto infinitos`,
cheats_claimingBlueprintRefundsIngredients: `Reclamar ingredientes devueltos por planos`,
cheats_dontSubtractPurchaseCreditCost: `[UNTRANSLATED] Don't Subtract Purchase Credit Cost`,
cheats_dontSubtractPurchasePlatinumCost: `[UNTRANSLATED] Don't Subtract Purchase Platinum Cost`,
cheats_dontSubtractPurchaseItemCost: `[UNTRANSLATED] Don't Subtract Purchase Item Cost`,
cheats_dontSubtractPurchaseStandingCost: `[UNTRANSLATED] Don't Subtract Purchase Standing Cost`,
cheats_dontSubtractPurchaseCreditCost: `No restar costo en créditos de la compra`,
cheats_dontSubtractPurchasePlatinumCost: `No restar costo en platino de la compra`,
cheats_dontSubtractPurchaseItemCost: `No restar costo de ítem en la compra`,
cheats_dontSubtractPurchaseStandingCost: `No restar costo en reputación de la compra`,
cheats_dontSubtractVoidTraces: `No descontar vestigios del Vacío`,
cheats_dontSubtractConsumables: `No restar consumibles`,
cheats_unlockAllShipFeatures: `Desbloquear todas las funciones de nave`,
@ -159,7 +159,7 @@ dict = {
cheats_noDeathMarks: `Sin marcas de muerte`,
cheats_noKimCooldowns: `Sin tiempo de espera para conversaciones KIM`,
cheats_syndicateMissionsRepeatable: `Misiones de sindicato rejugables`,
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
cheats_unlockAllProfitTakerStages: `Deslobquea todas las etapas del Roba-ganancias`,
cheats_instantFinishRivenChallenge: `Terminar desafío de agrietado inmediatamente`,
cheats_instantResourceExtractorDrones: `Drones de extracción de recursos instantáneos`,
cheats_noResourceExtractorDronesDamage: `Sin daño a los drones extractores de recursos`,
@ -170,7 +170,7 @@ dict = {
cheats_noDojoResearchCosts: `Sin costo de investigación del dojo`,
cheats_noDojoResearchTime: `Sin tiempo de investigación del dojo`,
cheats_fastClanAscension: `Ascenso rápido del clan`,
cheats_missionsCanGiveAllRelics: `[UNTRANSLATED] Missions Can Give All Relics`,
cheats_missionsCanGiveAllRelics: `Las misiones pueden otorgar todas las reliquias`,
cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`,
cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`,
cheats_save: `Guardar`,