chore: cleanup missionInventoryUpdateService (#349)

Co-authored-by: Sainan <Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2024-06-22 02:39:29 +02:00 committed by GitHub
parent 56f9be9725
commit 079d67807a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 76 additions and 4890 deletions

8
package-lock.json generated
View File

@ -13,7 +13,7 @@
"express": "^5.0.0-beta.3",
"mongoose": "^8.1.1",
"warframe-items": "^1.1262.74",
"warframe-public-export-plus": "^0.2.5",
"warframe-public-export-plus": "^0.3.0",
"warframe-riven-info": "^0.1.0",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1"
@ -3678,9 +3678,9 @@
}
},
"node_modules/warframe-public-export-plus": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.2.5.tgz",
"integrity": "sha512-IsS2Z14CeTpGSpfeUxqTi8wAQjQ6qjh2kV8RC9St5hcDmII3NpwEFXmStEqz7r+JPfea72D3cZMMl+4QLHqvXw=="
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.3.0.tgz",
"integrity": "sha512-BYkTkCq9jsA8NzSiWsTW48ezK7kI/op2NrLf+j4j3bJi2cNjoSLf/D4bMEui6yCADjcoV89ramRTFbPjn6UpLA=="
},
"node_modules/warframe-riven-info": {
"version": "0.1.0",

View File

@ -17,7 +17,7 @@
"express": "^5.0.0-beta.3",
"mongoose": "^8.1.1",
"warframe-items": "^1.1262.74",
"warframe-public-export-plus": "^0.2.5",
"warframe-public-export-plus": "^0.3.0",
"warframe-riven-info": "^0.1.0",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1"

View File

@ -1,7 +1,6 @@
import { getIndexAfter } from "@/src/helpers/stringHelpers";
import { logger } from "@/src/utils/logger";
import Items, { Category, MinimalItem, Warframe, Weapon } from "warframe-items";
import badItems from "@/static/json/exclude-mods.json";
import Items, { MinimalItem, Warframe, Weapon } from "warframe-items";
import {
dict_en,
ExportRecipes,
@ -53,23 +52,6 @@ export const getWeaponType = (weaponName: string): WeaponTypeInternal => {
return weaponType;
};
const getNamesObj = (category: Category) =>
new Items({ category: [category] }).reduce<{ [index: string]: string }>((acc, item) => {
if (!(item.uniqueName! in badItems)) {
acc[item.name!.replace("'S", "'s")] = item.uniqueName!;
}
return acc;
}, {});
export const modNames = getNamesObj("Mods");
export const resourceNames = getNamesObj("Resources");
export const miscNames = getNamesObj("Misc");
export const relicNames = getNamesObj("Relics");
export const skinNames = getNamesObj("Skins");
export const arcaneNames = getNamesObj("Arcanes");
export const gearNames = getNamesObj("Gear");
//logger.debug(`gear names`, { gearNames });
export const craftNames = Object.fromEntries(
(
new Items({

View File

@ -1,14 +1,14 @@
import { IMissionRewardResponse, IReward, IInventoryFieldType, inventoryFields } from "@/src/types/missionTypes";
import { IMissionRewardResponse, IInventoryFieldType, inventoryFields } from "@/src/types/missionTypes";
import missionsDropTable from "@/static/json/missions-drop-table.json";
import {
modNames,
relicNames,
miscNames,
resourceNames,
gearNames,
blueprintNames
} from "@/src/services/itemDataService";
ExportRegions,
ExportRewards,
ExportUpgrades,
ExportGear,
ExportRecipes,
ExportRelics,
IReward
} from "warframe-public-export-plus";
import { IMissionInventoryUpdateRequest } from "../types/requestTypes";
import { logger } from "@/src/utils/logger";
@ -23,49 +23,25 @@ const getRewards = ({
return { InventoryChanges: {}, MissionRewards: [] };
}
const rewards = (missionsDropTable as { [key: string]: IReward[] })[RewardInfo.node];
if (!rewards) {
const rewardManifests = ExportRegions[RewardInfo.node]?.rewardManifests ?? [];
if (rewardManifests.length == 0) {
return { InventoryChanges: {}, MissionRewards: [] };
}
const rotationCount = RewardInfo.rewardQualifications?.length || 0;
const rotations = getRotations(rotationCount);
const drops: IReward[] = [];
rewardManifests
.map(name => ExportRewards[name])
.forEach(table => {
for (const rotation of rotations) {
const rotationRewards = rewards.filter(reward => reward.rotation === rotation);
// Separate guaranteed and chance drops
const guaranteedDrops: IReward[] = [];
const chanceDrops: IReward[] = [];
for (const reward of rotationRewards) {
if (reward.chance === 100) {
guaranteedDrops.push(reward);
} else {
chanceDrops.push(reward);
const rotationRewards = table[rotation];
const drop = getRandomRewardByChance(rotationRewards);
if (drop) {
drops.push(drop);
}
}
const randomDrop = getRandomRewardByChance(chanceDrops);
if (randomDrop) {
guaranteedDrops.push(randomDrop);
}
drops.push(...guaranteedDrops);
}
// const testDrops = [
// { chance: 7.69, name: "Lith W3 Relic", rotation: "B" },
// { chance: 7.69, name: "Lith W3 Relic", rotation: "B" },
// { chance: 10.82, name: "2X Orokin Cell", rotation: "C" },
// { chance: 10.82, name: "Arrow Mutation", rotation: "C" },
// { chance: 10.82, name: "200 Endo", rotation: "C" },
// { chance: 10.82, name: "200 Endo", rotation: "C" },
// { chance: 10.82, name: "2,000,000 Credits Cache", rotation: "C" },
// { chance: 7.69, name: "Health Restore (Large)", rotation: "C" },
// { chance: 7.69, name: "Vapor Specter Blueprint", rotation: "C" }
// ];
// logger.debug("Mission rewards:", testDrops);
// return formatRewardsToInventoryType(testDrops);
});
logger.debug("Mission rewards:", drops);
return formatRewardsToInventoryType(drops);
@ -100,10 +76,10 @@ const combineRewardAndLootInventory = (
};
};
const getRotations = (rotationCount: number): (string | undefined)[] => {
if (rotationCount === 0) return [undefined];
const getRotations = (rotationCount: number): number[] => {
if (rotationCount === 0) return [0];
const rotationPattern = ["A", "A", "B", "C"];
const rotationPattern = [0, 0, 1, 2]; // A, A, B, C
const rotatedValues = [];
for (let i = 0; i < rotationCount; i++) {
@ -113,15 +89,15 @@ const getRotations = (rotationCount: number): (string | undefined)[] => {
return rotatedValues;
};
const getRandomRewardByChance = (data: IReward[] | undefined): IReward | undefined => {
if (!data || data.length == 0) return;
const getRandomRewardByChance = (data: IReward[]): IReward | undefined => {
if (data.length == 0) return;
const totalChance = data.reduce((sum, item) => sum + item.chance, 0);
const totalChance = data.reduce((sum, item) => sum + item.probability!, 0);
const randomValue = Math.random() * totalChance;
let cumulativeChance = 0;
for (const item of data) {
cumulativeChance += item.chance;
cumulativeChance += item.probability!;
if (randomValue <= cumulativeChance) {
return item;
}
@ -130,68 +106,62 @@ const getRandomRewardByChance = (data: IReward[] | undefined): IReward | undefin
return;
};
const creditBundles: Record<string, number> = {
"/Lotus/StoreItems/Types/PickUps/Credits/1500Credits": 1500,
"/Lotus/StoreItems/Types/PickUps/Credits/2000Credits": 2000,
"/Lotus/StoreItems/Types/PickUps/Credits/2500Credits": 2500,
"/Lotus/StoreItems/Types/PickUps/Credits/3000Credits": 3000,
"/Lotus/StoreItems/Types/PickUps/Credits/4000Credits": 4000,
"/Lotus/StoreItems/Types/PickUps/Credits/5000Credits": 5000,
"/Lotus/StoreItems/Types/PickUps/Credits/7500Credits": 7500,
"/Lotus/StoreItems/Types/PickUps/Credits/10000Credits": 10000,
"/Lotus/StoreItems/Types/StoreItems/CreditBundles/Zariman/TableACreditsCommon": 15000,
"/Lotus/StoreItems/Types/StoreItems/CreditBundles/Zariman/TableACreditsUncommon": 30000,
"/Lotus/StoreItems/Types/PickUps/Credits/CorpusArenaCreditRewards/CorpusArenaRewardOneHard": 105000,
"/Lotus/StoreItems/Types/PickUps/Credits/CorpusArenaCreditRewards/CorpusArenaRewardTwoHard": 175000,
"/Lotus/StoreItems/Types/PickUps/Credits/CorpusArenaCreditRewards/CorpusArenaRewardThreeHard": 25000
};
const fusionBundles: Record<string, number> = {
"/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle": 50,
"/Lotus/StoreItems/Upgrades/Mods/FusionBundles/RareFusionBundle": 80
};
const formatRewardsToInventoryType = (
rewards: IReward[]
): { InventoryChanges: IMissionInventoryUpdateRequest; MissionRewards: IMissionRewardResponse[] } => {
const InventoryChanges: IMissionInventoryUpdateRequest = {};
const MissionRewards: IMissionRewardResponse[] = [];
for (const reward of rewards) {
if (itemCheck(InventoryChanges, MissionRewards, reward.name)) {
continue;
if (reward.type in creditBundles) {
InventoryChanges.RegularCredits ??= 0;
InventoryChanges.RegularCredits += creditBundles[reward.type] * reward.itemCount;
} else if (reward.type in fusionBundles) {
InventoryChanges.FusionPoints ??= 0;
InventoryChanges.FusionPoints += fusionBundles[reward.type] * reward.itemCount;
} else {
const type = reward.type.replace("/Lotus/StoreItems/", "/Lotus/");
if (type in ExportUpgrades) {
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "RawUpgrades");
} else if (type in ExportGear) {
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "Consumables");
} else if (type in ExportRecipes) {
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "Recipes");
} else if (type in ExportRelics) {
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "MiscItems");
} else {
logger.error(`rolled reward ${reward.itemCount}X ${reward.type} but unsure how to give it`);
}
if (reward.name.includes(" Endo")) {
if (!InventoryChanges.FusionPoints) {
InventoryChanges.FusionPoints = 0;
}
InventoryChanges.FusionPoints += getCountFromName(reward.name);
} else if (reward.name.includes(" Credits Cache") || reward.name.includes("Return: ")) {
if (!InventoryChanges.RegularCredits) {
InventoryChanges.RegularCredits = 0;
}
InventoryChanges.RegularCredits += getCountFromName(reward.name);
}
}
return { InventoryChanges, MissionRewards };
};
const itemCheck = (
InventoryChanges: IMissionInventoryUpdateRequest,
MissionRewards: IMissionRewardResponse[],
name: string
) => {
const rewardCheck = {
RawUpgrades: modNames[name],
Consumables: gearNames[name],
MiscItems:
miscNames[name] ||
miscNames[name.replace(/\d+X\s*/, "")] ||
resourceNames[name] ||
resourceNames[name.replace(/\d+X\s*/, "")] ||
relicNames[name.replace("Relic", "Intact")] ||
relicNames[name.replace("Relic (Radiant)", "Radiant")],
Recipes: blueprintNames[name]
};
for (const key of Object.keys(rewardCheck) as IInventoryFieldType[]) {
if (rewardCheck[key]) {
addRewardResponse(InventoryChanges, MissionRewards, name, rewardCheck[key], key);
return true;
}
}
return false;
};
const getCountFromName = (name: string) => {
const regex = /(^(?:\d{1,3}(?:,\d{3})*(?:\.\d+)?)(\s|X))|(\s(?:\d{1,3}(?:,\d{3})*(?:\.\d+)?)$)/;
const countMatches = name.match(regex);
return countMatches ? parseInt(countMatches[0].replace(/,/g, ""), 10) : 1;
};
const addRewardResponse = (
InventoryChanges: IMissionInventoryUpdateRequest,
MissionRewards: IMissionRewardResponse[],
ItemName: string,
ItemType: string,
ItemCount: number,
InventoryCategory: IInventoryFieldType
) => {
if (!ItemType) return;
@ -200,9 +170,6 @@ const addRewardResponse = (
InventoryChanges[InventoryCategory] = [];
}
const ItemCount = getCountFromName(ItemName);
const TweetText = `${ItemName}`;
const existReward = InventoryChanges[InventoryCategory]!.find(item => item.ItemType === ItemType);
if (existReward) {
existReward.ItemCount += ItemCount;
@ -214,7 +181,7 @@ const addRewardResponse = (
InventoryChanges[InventoryCategory]!.push({ ItemType, ItemCount });
MissionRewards.push({
ItemCount,
TweetText,
TweetText: ItemType, // ensure if/how this even still used, or if it's needed at all
ProductCategory: InventoryCategory,
StoreItem: ItemType.replace("/Lotus/", "/Lotus/StoreItems/"),
TypeName: ItemType
@ -222,32 +189,4 @@ const addRewardResponse = (
}
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _missionRewardsCheckAllNamings = () => {
let tempRewards: IReward[] = [];
Object.values(missionsDropTable as { [key: string]: IReward[] }).forEach(rewards => {
rewards.forEach(reward => {
tempRewards.push(reward);
});
});
tempRewards = tempRewards
.filter(reward => !modNames[reward.name])
.filter(reward => !miscNames[reward.name])
.filter(reward => !miscNames[reward.name.replace(/\d+X\s*/, "")])
.filter(reward => !resourceNames[reward.name])
.filter(reward => !resourceNames[reward.name.replace(/\d+X\s*/, "")])
.filter(reward => !gearNames[reward.name])
.filter(reward => {
return (
!relicNames[reward.name.replace("Relic", "Intact")] &&
!relicNames[reward.name.replace("Relic (Radiant)", "Radiant")]
);
})
.filter(reward => !blueprintNames[reward.name])
.filter(reward => !reward.name.includes(" Endo"))
.filter(reward => !reward.name.includes(" Credits Cache") && !reward.name.includes("Return: "));
logger.debug(`temp rewards`, { tempRewards });
};
// _missionRewardsCheckAllNamings();
export { getRewards, combineRewardAndLootInventory };

View File

@ -9,9 +9,3 @@ export interface IMissionRewardResponse {
TweetText: string;
ProductCategory: string;
}
export interface IReward {
name: string;
chance: number;
rotation?: string;
}

View File

@ -67,7 +67,7 @@ export interface IMissionInventoryUpdateRequestRewardInfo {
lostTargetWave?: number;
defenseTargetCount?: number;
EOM_AFK?: number;
rewardQualifications?: string;
rewardQualifications?: string; // did a Survival for 5 minutes and this was "1"
PurgatoryRewardQualifications?: string;
rewardSeed?: number;
}

File diff suppressed because it is too large Load Diff