Compare commits

..

1 Commits

Author SHA1 Message Date
9a20c1259e fix: only roll unique rewards for peely pix booster packs 2025-03-23 16:59:59 +01:00
12 changed files with 83 additions and 68188 deletions

8
package-lock.json generated
View File

@ -18,7 +18,7 @@
"mongoose": "^8.11.0",
"morgan": "^1.10.0",
"typescript": ">=5.5 <5.6.0",
"warframe-public-export-plus": "^0.5.47",
"warframe-public-export-plus": "^0.5.48",
"warframe-riven-info": "^0.1.2",
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0"
@ -4013,9 +4013,9 @@
}
},
"node_modules/warframe-public-export-plus": {
"version": "0.5.47",
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.47.tgz",
"integrity": "sha512-ZJK3VT1PdSPwZlhIzUVBlydwK4DM0sOmeCiixVMgOM8XuOPJ8OHfQUoLKydtw5rxCsowzFPbx5b3KBke5C4akQ=="
"version": "0.5.48",
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.48.tgz",
"integrity": "sha512-vJitVYnaViQo43xAkL/h3MJ/6wS7YknKEYhYs+N/GrsspYLMPGf9KSuR19tprB2g9KVGS5o67t0v5K8p0RTQCQ=="
},
"node_modules/warframe-riven-info": {
"version": "0.1.2",

View File

@ -23,7 +23,7 @@
"mongoose": "^8.11.0",
"morgan": "^1.10.0",
"typescript": ">=5.5 <5.6.0",
"warframe-public-export-plus": "^0.5.47",
"warframe-public-export-plus": "^0.5.48",
"warframe-riven-info": "^0.1.2",
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0"

View File

@ -1,23 +1,25 @@
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { updateTheme } from "@/src/services/inventoryService";
import { IThemeUpdateRequest } from "@/src/types/requestTypes";
import { RequestHandler } from "express";
import { getInventory } from "@/src/services/inventoryService";
export const updateThemeController: RequestHandler = async (request, response) => {
const updateThemeController: RequestHandler = async (request, response) => {
const accountId = await getAccountIdForRequest(request);
const data = getJSONfromString<IThemeUpdateRequest>(String(request.body));
const body = String(request.body);
const inventory = await getInventory(accountId, "ThemeStyle ThemeBackground ThemeSounds");
if (data.Style) inventory.ThemeStyle = data.Style;
if (data.Background) inventory.ThemeBackground = data.Background;
if (data.Sounds) inventory.ThemeSounds = data.Sounds;
await inventory.save();
try {
const json = getJSONfromString<IThemeUpdateRequest>(body);
if (typeof json !== "object") {
throw new Error("Invalid data format");
}
await updateTheme(json, accountId);
} catch (err) {
console.error("Error parsing JSON data:", err);
}
response.json({});
};
interface IThemeUpdateRequest {
Style?: string;
Background?: string;
Sounds?: string;
}
export { updateThemeController };

View File

@ -1,24 +1,9 @@
import { Account } from "@/src/models/loginModel";
import { getAccountForRequest } from "@/src/services/loginService";
import { RequestHandler } from "express";
export const ircDroppedController: RequestHandler = async (req, res) => {
if (!req.query.accountId) {
throw new Error("Request is missing accountId parameter");
}
const nonce: number = parseInt(req.query.nonce as string);
if (!nonce) {
throw new Error("Request is missing nonce parameter");
}
await Account.updateOne(
{
_id: req.query.accountId,
Nonce: nonce
},
{
Dropped: true
}
);
const account = await getAccountForRequest(req);
account.Dropped = true;
await account.save();
res.end();
};

View File

@ -1,6 +1,5 @@
import { RequestHandler } from "express";
import { getAccountForRequest, isAdministrator, isNameTaken } from "@/src/services/loginService";
import { config, saveConfig } from "@/src/services/configService";
import { getAccountForRequest, isNameTaken } from "@/src/services/loginService";
export const renameAccountController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req);
@ -8,18 +7,8 @@ export const renameAccountController: RequestHandler = async (req, res) => {
if (await isNameTaken(req.query.newname)) {
res.status(409).json("Name already in use");
} else {
if (isAdministrator(account)) {
for (let i = 0; i != config.administratorNames!.length; ++i) {
if (config.administratorNames![i] == account.DisplayName) {
config.administratorNames![i] = req.query.newname;
}
}
await saveConfig();
}
account.DisplayName = req.query.newname;
await account.save();
res.end();
}
} else {

View File

@ -19,13 +19,9 @@ import mongoose from "mongoose";
return "<BIGINT>" + this.toString() + "</BIGINT>";
};
const og_stringify = JSON.stringify;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
JSON.stringify = (obj: any, replacer?: any, space?: string | number): string => {
return og_stringify(obj, replacer as string[], space)
.split(`"<BIGINT>`)
.join(``)
.split(`</BIGINT>"`)
.join(``);
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
(JSON as any).stringify = (obj: any): string => {
return og_stringify(obj).split(`"<BIGINT>`).join(``).split(`</BIGINT>"`).join(``);
};
}

View File

@ -34,7 +34,7 @@ interface IConfig {
httpsPort?: number;
myIrcAddresses?: string[];
NRS?: string[];
administratorNames?: string[];
administratorNames?: string[] | string;
autoCreateAccount?: boolean;
skipTutorial?: boolean;
skipAllDialogue?: boolean;
@ -83,15 +83,10 @@ export const updateConfig = async (data: string): Promise<void> => {
Object.assign(config, JSON.parse(data));
};
export const saveConfig = async (): Promise<void> => {
amnesia = true;
await fsPromises.writeFile(configPath, JSON.stringify(config, null, 2));
};
export const validateConfig = (): void => {
if (typeof config.administratorNames == "string") {
logger.info(`Updating config.json to make administratorNames an array.`);
config.administratorNames = [config.administratorNames];
void saveConfig();
logger.warn(
`"administratorNames" should be an array; please add square brackets: ["${config.administratorNames}"]`
);
}
};

View File

@ -29,7 +29,11 @@ import {
ICrewShipWeaponClient
} from "@/src/types/inventoryTypes/inventoryTypes";
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
import { IMissionInventoryUpdateRequest, IUpdateChallengeProgressRequest } from "../types/requestTypes";
import {
IMissionInventoryUpdateRequest,
IThemeUpdateRequest,
IUpdateChallengeProgressRequest
} from "../types/requestTypes";
import { logger } from "@/src/utils/logger";
import { convertInboxMessage, fromStoreItem, getExalted, getKeyChainItems } from "@/src/services/itemDataService";
import {
@ -887,6 +891,15 @@ export const updateGeneric = async (data: IGenericUpdate, accountId: string): Pr
};
};
export const updateTheme = async (data: IThemeUpdateRequest, accountId: string): Promise<void> => {
const inventory = await getInventory(accountId);
if (data.Style) inventory.ThemeStyle = data.Style;
if (data.Background) inventory.ThemeBackground = data.Background;
if (data.Sounds) inventory.ThemeSounds = data.Sounds;
await inventory.save();
};
export const addEquipment = (
inventory: TInventoryDatabaseDocument,
category: TEquipmentKey,

View File

@ -69,31 +69,36 @@ export const getAccountForRequest = async (req: Request): Promise<TAccountDocume
if (!req.query.accountId) {
throw new Error("Request is missing accountId parameter");
}
const nonce: number = parseInt(req.query.nonce as string);
if (!nonce) {
if (!req.query.nonce || parseInt(req.query.nonce as string) === 0) {
throw new Error("Request is missing nonce parameter");
}
const account = await Account.findOne({
_id: req.query.accountId,
Nonce: nonce
Nonce: req.query.nonce
});
if (!account) {
throw new Error("Invalid accountId-nonce pair");
}
if (account.Dropped && req.query.ct) {
account.Dropped = undefined;
await account.save();
}
return account;
};
export const getAccountIdForRequest = async (req: Request): Promise<string> => {
return (await getAccountForRequest(req))._id.toString();
const account = await getAccountForRequest(req);
if (account.Dropped && req.query.ct) {
account.Dropped = undefined;
await account.save();
}
return account._id.toString();
};
export const isAdministrator = (account: TAccountDocument): boolean => {
return !!config.administratorNames?.find(x => x == account.DisplayName);
if (!config.administratorNames) {
return false;
}
if (typeof config.administratorNames == "string") {
return config.administratorNames == account.DisplayName;
}
return !!config.administratorNames.find(x => x == account.DisplayName);
};
const platform_magics = [753, 639, 247, 37, 60];

View File

@ -415,24 +415,24 @@ const handleBoosterPackPurchase = async (
"attempt to roll over 100 booster packs in a single go. possible but unlikely to be desirable for the user or the server."
);
}
if (typeName == "/Lotus/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFixed") {
for (const result of pack.components) {
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
combineInventoryChanges(purchaseResponse.InventoryChanges, await addItem(inventory, result.Item, 1));
}
} else {
for (let i = 0; i != quantity; ++i) {
for (const weights of pack.rarityWeightsPerRoll) {
const disallowedItems = new Set();
for (let roll = 0; roll != pack.rarityWeightsPerRoll.length; ) {
const weights = pack.rarityWeightsPerRoll[roll];
const result = getRandomWeightedRewardUc(pack.components, weights);
if (result) {
logger.debug(`booster pack rolled`, result);
if (disallowedItems.has(result.Item)) {
logger.debug(`oops, can't use that one; trying again`);
continue;
}
if (!pack.canGiveDuplicates) {
disallowedItems.add(result.Item);
}
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
combineInventoryChanges(
purchaseResponse.InventoryChanges,
await addItem(inventory, result.Item, 1)
);
}
combineInventoryChanges(purchaseResponse.InventoryChanges, await addItem(inventory, result.Item, 1));
}
++roll;
}
}
return purchaseResponse;

View File

@ -19,6 +19,12 @@ import {
ICollectibleEntry
} from "./inventoryTypes/inventoryTypes";
export interface IThemeUpdateRequest {
Style?: string;
Background?: string;
Sounds?: string;
}
export interface IAffiliationChange {
Tag: string;
Standing: number;

File diff suppressed because it is too large Load Diff