give all missing skins

This commit is contained in:
AMelonInsideLemon 2025-09-29 17:36:04 +02:00
parent f665a8e585
commit c4434b87c1
12 changed files with 85 additions and 82 deletions

View File

@ -15,6 +15,7 @@ import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "../../ser
import {
addEmailItem,
addItem,
addItems,
addMiscItems,
allDailyAffiliationKeys,
checkCalendarAutoAdvance,
@ -268,6 +269,65 @@ export const inventoryController: RequestHandler = async (request, response) =>
}
}
inventory.LastInventorySync = new Types.ObjectId();
const weaponMap = new Map<string, string>();
for (const skin of inventory.WeaponSkins) {
weaponMap.set(skin.ItemType, skin._id.toString());
}
const itemsToAdd = new Set<string>();
for (const key of equipmentKeys) {
if (key in inventory) {
for (const equipment of inventory[key]) {
for (const config of equipment.Configs) {
if (config.Skins) collectSkins(config.Skins, weaponMap, itemsToAdd);
}
}
}
}
for (const key of ["AdultOperatorLoadOuts", "OperatorLoadOuts", "KahlLoadOuts"] as const) {
if (key in inventory) {
for (const loadOut of inventory[key]) {
if (loadOut.Skins) collectSkins(loadOut.Skins, weaponMap, itemsToAdd);
}
}
}
if (inventory.LotusCustomization?.Skins) collectSkins(inventory.LotusCustomization.Skins, weaponMap, itemsToAdd);
if (itemsToAdd.size > 0) {
logger.debug(`Adding ${itemsToAdd.size} items due to migration from unlockAllSkins cheat`);
const inventoryChanges = await addItems(inventory, Array.from(itemsToAdd));
if (inventoryChanges.WeaponSkins) {
for (const skin of inventoryChanges.WeaponSkins as IWeaponSkinClient[]) {
weaponMap.set(skin.ItemType, skin.ItemId.toString());
}
}
for (const key of equipmentKeys) {
if (key in inventory) {
for (const equipment of inventory[key]) {
for (const config of equipment.Configs) {
if (config.Skins) replaceSkinIds(config.Skins, weaponMap);
}
}
}
}
for (const key of ["AdultOperatorLoadOuts", "OperatorLoadOuts", "KahlLoadOuts"] as const) {
if (key in inventory) {
for (const loadOut of inventory[key]) {
if (loadOut.Skins) replaceSkinIds(loadOut.Skins, weaponMap);
}
}
}
if (inventory.LotusCustomization?.Skins) replaceSkinIds(inventory.LotusCustomization.Skins, weaponMap);
}
await inventory.save();
response.json(
@ -334,45 +394,6 @@ export const getInventoryResponse = async (
});
}
if (inventory.unlockAllSkins) {
const missingWeaponSkins = new Set(Object.keys(ExportCustoms));
inventoryResponse.WeaponSkins.forEach(x => missingWeaponSkins.delete(x.ItemType));
for (const uniqueName of missingWeaponSkins) {
inventoryResponse.WeaponSkins.push({
ItemId: {
$oid: "ca70ca70ca70ca70" + catBreadHash(uniqueName).toString(16).padStart(8, "0")
},
ItemType: uniqueName
});
}
} else {
for (const key of equipmentKeys) {
if (key in inventoryResponse) {
for (const equipment of inventoryResponse[key]) {
equipment.Configs.forEach(config => {
if (config.Skins) processSkins(config.Skins, inventoryResponse.WeaponSkins, equipment.ItemType);
});
}
}
}
for (const key of ["AdultOperatorLoadOuts", "OperatorLoadOuts", "KahlLoadOuts"] as const) {
if (key in inventoryResponse) {
inventoryResponse[key].forEach(loadOut => {
if (loadOut.Skins) processSkins(loadOut.Skins, inventoryResponse.WeaponSkins, key);
});
}
}
if (inventoryResponse.LotusCustomization?.Skins) {
processSkins(
inventoryResponse.LotusCustomization.Skins,
inventoryResponse.WeaponSkins,
"LotusCustomization"
);
}
}
if (typeof config.spoofMasteryRank === "number" && config.spoofMasteryRank >= 0) {
inventoryResponse.PlayerLevel = config.spoofMasteryRank;
if (!xpBasedLevelCapDisabled) {
@ -508,20 +529,21 @@ for (const key of Object.keys(ExportCustoms)) {
skinLookupTable[catBreadHash(key)] = key;
}
const processSkins = (skins: string[], weaponSKins: IWeaponSkinClient[], contextName: string): void => {
skins.forEach((skinId, i) => {
const collectSkins = (skins: string[], weaponMap: Map<string, string>, itemsToAdd: Set<string>): void => {
for (const skinId of skins) {
if (skinId.startsWith("ca70ca70ca70ca70")) {
const skinItemType = skinLookupTable[parseInt(skinId.slice(16), 16)];
const inventoryItem = weaponSKins.find(x => x.ItemType === skinItemType);
if (inventoryItem) {
skins[i] = inventoryItem.ItemId.$oid;
} else {
skins[i] = skinItemType;
if (!ExportCustoms[skinItemType].alwaysAvailable) {
logger.warn(`Get ${skinItemType} or you may loose your appearance on ${contextName}`);
}
}
const typeName = skinLookupTable[parseInt(skinId.slice(16), 16)];
if (!weaponMap.has(typeName)) itemsToAdd.add(typeName);
}
});
}
};
const replaceSkinIds = (skins: string[], weaponMap: Map<string, string>): void => {
for (let i = 0; i < skins.length; i++) {
const skinId = skins[i];
if (skinId.startsWith("ca70ca70ca70ca70")) {
const inventoryId = weaponMap.get(skinLookupTable[parseInt(skinId.slice(16), 16)]);
if (inventoryId) skins[i] = inventoryId;
}
}
};

View File

@ -1445,7 +1445,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
unlockDoubleCapacityPotatoesEverywhere: Boolean,
unlockExilusEverywhere: Boolean,
unlockArcanesEverywhere: Boolean,
unlockAllSkins: Boolean,
syndicateMissionsRepeatable: Boolean,
instantFinishRivenChallenge: Boolean,
noDailyStandingLimits: Boolean,

View File

@ -139,22 +139,16 @@ export const handleInventoryItemConfigChange = async (
case "WeaponSkins": {
const itemEntries = equipment as IItemEntry;
for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) {
if (itemId.startsWith("ca70ca70ca70ca70")) {
logger.warn(
`unlockAllSkins does not work with favoriting items because you don't actually own it`
);
} else {
const inventoryItem = inventory.WeaponSkins.id(itemId);
if (!inventoryItem) {
logger.warn(`inventory item WeaponSkins not found with id ${itemId}`);
continue;
}
if ("Favorite" in itemConfigEntries) {
inventoryItem.Favorite = itemConfigEntries.Favorite;
}
if ("IsNew" in itemConfigEntries) {
inventoryItem.IsNew = itemConfigEntries.IsNew;
}
const inventoryItem = inventory.WeaponSkins.id(itemId);
if (!inventoryItem) {
logger.warn(`inventory item WeaponSkins not found with id ${itemId}`);
continue;
}
if ("Favorite" in itemConfigEntries) {
inventoryItem.Favorite = itemConfigEntries.Favorite;
}
if ("IsNew" in itemConfigEntries) {
inventoryItem.IsNew = itemConfigEntries.IsNew;
}
}
break;

View File

@ -38,7 +38,6 @@ export interface IAccountCheats {
unlockDoubleCapacityPotatoesEverywhere?: boolean;
unlockExilusEverywhere?: boolean;
unlockArcanesEverywhere?: boolean;
unlockAllSkins?: boolean;
syndicateMissionsRepeatable?: boolean;
instantFinishRivenChallenge?: boolean;
noDailyStandingLimits?: boolean;

View File

@ -962,10 +962,6 @@
<input class="form-check-input" type="checkbox" id="unlockArcanesEverywhere" />
<label class="form-check-label" for="unlockArcanesEverywhere" data-loc="cheats_unlockArcanesEverywhere"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllSkins" />
<label class="form-check-label" for="unlockAllSkins" data-loc="cheats_unlockAllSkins"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" />
<label class="form-check-label" for="syndicateMissionsRepeatable" data-loc="cheats_syndicateMissionsRepeatable"></label>

View File

@ -215,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Void-Spuren nicht verbrauchen`,
cheats_dontSubtractConsumables: `Verbrauchsgegenstände (Ausrüstung) nicht verbrauchen`,
cheats_unlockAllShipFeatures: `Alle Schiffs-Funktionen freischalten`,
cheats_unlockAllSkins: `Alle Skins freischalten`,
cheats_unlockAllCapturaScenes: `Alle Photora-Szenen freischalten`,
cheats_universalPolarityEverywhere: `Universelle Polarität überall`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Orokin Reaktor & Beschleuniger überall`,

View File

@ -214,7 +214,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Don't Subtract Void Traces`,
cheats_dontSubtractConsumables: `Don't Subtract Consumables`,
cheats_unlockAllShipFeatures: `Unlock All Ship Features`,
cheats_unlockAllSkins: `Unlock All Skins`,
cheats_unlockAllCapturaScenes: `Unlock All Captura Scenes`,
cheats_universalPolarityEverywhere: `Universal Polarity Everywhere`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Potatoes Everywhere`,

View File

@ -215,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `No descontar vestigios del Vacío`,
cheats_dontSubtractConsumables: `No restar consumibles`,
cheats_unlockAllShipFeatures: `Desbloquear todas las funciones de nave`,
cheats_unlockAllSkins: `Desbloquear todas las skins`,
cheats_unlockAllCapturaScenes: `Desbloquear todas las escenas de Captura`,
cheats_universalPolarityEverywhere: `Polaridad universal en todas partes`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Patatas en todas partes`,

View File

@ -215,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Ne pas consommer de Void Traces`,
cheats_dontSubtractConsumables: `Ne pas retirer de consommables`,
cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`,
cheats_unlockAllSkins: `Débloquer tous les skins`,
cheats_unlockAllCapturaScenes: `Débloquer toutes les scènes captura`,
cheats_universalPolarityEverywhere: `Polarités universelles partout`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Réacteurs et Catalyseurs partout`,

View File

@ -215,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Не вычитать количество Отголосков Бездны`,
cheats_dontSubtractConsumables: `Не вычитать количество расходников`,
cheats_unlockAllShipFeatures: `Разблокировать все функции корабля`,
cheats_unlockAllSkins: `Разблокировать все скины`,
cheats_unlockAllCapturaScenes: `Разблокировать все сцены Каптуры`,
cheats_universalPolarityEverywhere: `Универсальная полярность везде`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Реакторы/Катализаторы орокин везде`,

View File

@ -215,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Не вираховувати кількість Відлуння`,
cheats_dontSubtractConsumables: `Не вираховувати кількість витратних матеріалів`,
cheats_unlockAllShipFeatures: `Розблокувати всі функції судна`,
cheats_unlockAllSkins: `Розблокувати всі скіни`,
cheats_unlockAllCapturaScenes: `Розблокувати всі сцени Світлописця`,
cheats_universalPolarityEverywhere: `Будь-яка полярність скрізь`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Орокінські Реактори/Каталізатори скрізь`,

View File

@ -215,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `虚空光体无消耗`,
cheats_dontSubtractConsumables: `消耗物品使用时无损耗`,
cheats_unlockAllShipFeatures: `解锁所有飞船功能`,
cheats_unlockAllSkins: `解锁所有外观`,
cheats_unlockAllCapturaScenes: `解锁所有Captura场景`,
cheats_universalPolarityEverywhere: `全局万用极性`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `全物品自带Orokin反应堆`,