merge upstream

This commit is contained in:
Corvus 2025-06-30 16:12:18 -07:00
commit d1a570380e
10 changed files with 89 additions and 14 deletions

View File

@ -4,9 +4,15 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
export const creditsController: RequestHandler = async (req, res) => { export const creditsController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const inventory = (
await Promise.all([
const inventory = await getInventory(accountId, "RegularCredits TradesRemaining PremiumCreditsFree PremiumCredits"); getAccountIdForRequest(req),
getInventory(
req.query.accountId as string,
"RegularCredits TradesRemaining PremiumCreditsFree PremiumCredits"
)
])
)[1];
const response = { const response = {
RegularCredits: inventory.RegularCredits, RegularCredits: inventory.RegularCredits,

View File

@ -13,7 +13,8 @@ import {
allDailyAffiliationKeys, allDailyAffiliationKeys,
cleanupInventory, cleanupInventory,
createLibraryDailyTask, createLibraryDailyTask,
generateRewardSeed generateRewardSeed,
getCalendarProgress
} from "@/src/services/inventoryService"; } from "@/src/services/inventoryService";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { addString, catBreadHash } from "@/src/helpers/stringHelpers"; import { addString, catBreadHash } from "@/src/helpers/stringHelpers";
@ -108,6 +109,10 @@ export const inventoryController: RequestHandler = async (request, response) =>
} }
} }
if (inventory.CalendarProgress) {
getCalendarProgress(inventory); // handle year rollover; the client expects to receive an inventory with an up-to-date CalendarProgress
}
cleanupInventory(inventory); cleanupInventory(inventory);
inventory.NextRefill = new Date((today + 1) * 86400000); // tomorrow at 0 UTC inventory.NextRefill = new Date((today + 1) * 86400000); // tomorrow at 0 UTC

View File

@ -9,6 +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";
export const loginRewardsController: RequestHandler = async (req, res) => { export const loginRewardsController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req); const account = await getAccountForRequest(req);
@ -51,6 +52,8 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
setAccountGotLoginRewardToday(account); setAccountGotLoginRewardToday(account);
await account.save(); await account.save();
sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
} }
res.json(response); res.json(response);
}; };

View File

@ -6,6 +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 { 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";
@ -39,6 +40,7 @@ export const loginRewardsSelectionController: RequestHandler = async (req, res)
setAccountGotLoginRewardToday(account); setAccountGotLoginRewardToday(account);
await account.save(); await account.save();
sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
res.json({ res.json({
DailyTributeInfo: { DailyTributeInfo: {
NewInventory: inventoryChanges, NewInventory: inventoryChanges,

View File

@ -58,6 +58,9 @@ export const sellController: RequestHandler = async (req, res) => {
if (payload.Items.Hoverboards) { if (payload.Items.Hoverboards) {
requiredFields.add(InventorySlot.SPACESUITS); requiredFields.add(InventorySlot.SPACESUITS);
} }
if (payload.Items.CrewMembers) {
requiredFields.add(InventorySlot.CREWMEMBERS);
}
if (payload.Items.CrewShipWeapons || payload.Items.CrewShipWeaponSkins) { if (payload.Items.CrewShipWeapons || payload.Items.CrewShipWeaponSkins) {
requiredFields.add(InventorySlot.RJ_COMPONENT_AND_ARMAMENTS); requiredFields.add(InventorySlot.RJ_COMPONENT_AND_ARMAMENTS);
requiredFields.add("CrewShipRawSalvage"); requiredFields.add("CrewShipRawSalvage");
@ -181,6 +184,12 @@ export const sellController: RequestHandler = async (req, res) => {
inventory.Drones.pull({ _id: sellItem.String }); inventory.Drones.pull({ _id: sellItem.String });
}); });
} }
if (payload.Items.CrewMembers) {
payload.Items.CrewMembers.forEach(sellItem => {
inventory.CrewMembers.pull({ _id: sellItem.String });
freeUpSlot(inventory, InventorySlot.CREWMEMBERS);
});
}
if (payload.Items.CrewShipWeapons) { if (payload.Items.CrewShipWeapons) {
payload.Items.CrewShipWeapons.forEach(sellItem => { payload.Items.CrewShipWeapons.forEach(sellItem => {
if (sellItem.String[0] == "/") { if (sellItem.String[0] == "/") {
@ -303,6 +312,7 @@ interface ISellRequest {
OperatorAmps?: ISellItem[]; OperatorAmps?: ISellItem[];
Hoverboards?: ISellItem[]; Hoverboards?: ISellItem[];
Drones?: ISellItem[]; Drones?: ISellItem[];
CrewMembers?: ISellItem[];
CrewShipWeapons?: ISellItem[]; CrewShipWeapons?: ISellItem[];
CrewShipWeaponSkins?: ISellItem[]; CrewShipWeaponSkins?: ISellItem[];
}; };

View File

@ -45,6 +45,39 @@ export type WeaponTypeInternal =
| "SpecialItems"; | "SpecialItems";
export const getRecipe = (uniqueName: string): IRecipe | undefined => { export const getRecipe = (uniqueName: string): IRecipe | undefined => {
// Handle crafting of archwing summon for versions prior to 39.0.0 as this blueprint was removed then.
if (uniqueName == "/Lotus/Types/Recipes/EidolonRecipes/OpenArchwingSummonBlueprint") {
return {
resultType: "/Lotus/Types/Restoratives/OpenArchwingSummon",
buildPrice: 7500,
buildTime: 1800,
skipBuildTimePrice: 10,
consumeOnUse: false,
num: 1,
codexSecret: false,
alwaysAvailable: true,
ingredients: [
{
ItemType: "/Lotus/Types/Gameplay/Eidolon/Resources/IraditeItem",
ItemCount: 50
},
{
ItemType: "/Lotus/Types/Gameplay/Eidolon/Resources/GrokdrulItem",
ItemCount: 50
},
{
ItemType: "/Lotus/Types/Items/Fish/Eidolon/FishParts/EidolonFishOilItem",
ItemCount: 30
},
{
ItemType: "/Lotus/Types/Items/MiscItems/Circuits",
ItemCount: 600
}
],
excludeFromMarket: true
};
}
return ExportRecipes[uniqueName]; return ExportRecipes[uniqueName];
}; };

View File

@ -75,7 +75,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="w-100"> <div id="main-content" class="w-100">
<div data-route="/webui/" data-title="Login | OpenWF WebUI"> <div data-route="/webui/" data-title="Login | OpenWF WebUI">
<p data-loc="login_description"></p> <p data-loc="login_description"></p>
<form onsubmit="doLogin();return false;"> <form onsubmit="doLogin();return false;">

View File

@ -2738,3 +2738,9 @@ function handleValenceBonusChange(event) {
}); });
}); });
} }
document.querySelectorAll("#sidebar .nav-link").forEach(function (elm) {
elm.addEventListener("click", function () {
window.scrollTo(0, 0);
});
});

View File

@ -4,9 +4,19 @@
} }
body.logged-in #sidebar { body.logged-in #sidebar {
position: sticky; position: fixed;
top: 5rem; }
margin-right: 3rem;
body.logged-in #main-content {
margin-left: 7rem;
}
body.logged-in:has([data-lang="de"].active) #main-content {
margin-left: 8rem;
}
body.logged-in:has([data-lang="zh"].active) #main-content {
margin-left: 6rem;
} }
body:not(.logged-in) #sidebar { body:not(.logged-in) #sidebar {

View File

@ -2,8 +2,8 @@
dict = { dict = {
general_inventoryUpdateNote: `Para ver los cambios en el juego, necesitas volver a sincronizar tu inventario, por ejemplo, usando el comando /sync del bootstrapper, visitando un dojo o repetidor, o volviendo a iniciar sesión.`, general_inventoryUpdateNote: `Para ver los cambios en el juego, necesitas volver a sincronizar tu inventario, por ejemplo, usando el comando /sync del bootstrapper, visitando un dojo o repetidor, o volviendo a iniciar sesión.`,
general_addButton: `Agregar`, general_addButton: `Agregar`,
general_setButton: `[UNTRANSLATED] Set`, general_setButton: `Establecer`,
general_removeButton: `[UNTRANSLATED] Remove`, general_removeButton: `Quitar`,
general_bulkActions: `Acciones masivas`, general_bulkActions: `Acciones masivas`,
code_loginFail: `Error al iniciar sesión. Verifica el correo electrónico y la contraseña.`, code_loginFail: `Error al iniciar sesión. Verifica el correo electrónico y la contraseña.`,
@ -120,7 +120,7 @@ dict = {
detailedView_archonShardsDescription: `Puedes usar estas ranuras ilimitadas para aplicar una amplia variedad de mejoras`, detailedView_archonShardsDescription: `Puedes usar estas ranuras ilimitadas para aplicar una amplia variedad de mejoras`,
detailedView_archonShardsDescription2: `Ten en cuenta que cada fragmento de archón tarda un poco en aplicarse al cargar`, detailedView_archonShardsDescription2: `Ten en cuenta que cada fragmento de archón tarda un poco en aplicarse al cargar`,
detailedView_valenceBonusLabel: `Bônus de Valência`, detailedView_valenceBonusLabel: `Bônus de Valência`,
detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`, detailedView_valenceBonusDescription: `Puedes establecer o quitar el bono de valencia de tu arma.`,
mods_addRiven: `Agregar Agrietado`, mods_addRiven: `Agregar Agrietado`,
mods_fingerprint: `Huella digital`, mods_fingerprint: `Huella digital`,
@ -136,7 +136,7 @@ dict = {
cheats_skipAllDialogue: `Omitir todos los diálogos`, cheats_skipAllDialogue: `Omitir todos los diálogos`,
cheats_unlockAllScans: `Desbloquear todos los escaneos`, cheats_unlockAllScans: `Desbloquear todos los escaneos`,
cheats_unlockAllMissions: `Desbloquear todas las misiones`, cheats_unlockAllMissions: `Desbloquear todas las misiones`,
cheats_unlockAllMissions_ok: `[UNTRANSLATED] Success. Please note that you'll need to enter a dojo/relay or relog for the client to refresh the star chart.`, cheats_unlockAllMissions_ok: `Éxito. Ten en cuenta que deberás entrar a un dojo, repetidor o volver a iniciar sesión para que el cliente actualice el mapa estelar.`,
cheats_infiniteCredits: `Créditos infinitos`, cheats_infiniteCredits: `Créditos infinitos`,
cheats_infinitePlatinum: `Platino infinito`, cheats_infinitePlatinum: `Platino infinito`,
cheats_infiniteEndo: `Endo infinito`, cheats_infiniteEndo: `Endo infinito`,
@ -306,8 +306,8 @@ dict = {
damageType_Poison: `Tóxico`, damageType_Poison: `Tóxico`,
damageType_Radiation: `Radioativo`, damageType_Radiation: `Radioativo`,
theme_dark: `[UNTRANSLATED] Dark Theme`, theme_dark: `Tema Oscuro`,
theme_light: `[UNTRANSLATED] Light Theme`, theme_light: `Tema Claro`,
prettier_sucks_ass: `` prettier_sucks_ass: ``
}; };