Skip to content

Commit

Permalink
Mission rewards save (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
holmityd authored Aug 31, 2023
1 parent 2ed10a8 commit db0aaff
Show file tree
Hide file tree
Showing 11 changed files with 292 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/.env
/static/data/*.bin
yarn.lock
/tmp
57 changes: 56 additions & 1 deletion src/controllers/api/missionInventoryUpdateController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,61 @@
import { RequestHandler } from "express";
import { missionInventoryUpdate } from "@/src/services/inventoryService";
import { MissionInventoryUpdate } from "@/src/types/missionInventoryUpdateType";
/*
- [ ] crossPlaySetting
- [ ] rewardsMultiplier
- [ ] ActiveBoosters
- [x] LongGuns
- [x] Pistols
- [x] Suits
- [x] Melee
- [x] RawUpgrades
- [x] MiscItems
- [x] RegularCredits
- [ ] RandomUpgradesIdentified
- [ ] MissionFailed
- [ ] MissionStatus
- [ ] CurrentLoadOutIds
- [ ] AliveTime
- [ ] MissionTime
- [ ] Missions
- [ ] CompletedAlerts
- [ ] LastRegionPlayed
- [ ] GameModeId
- [ ] hosts
- [x] ChallengeProgress
- [ ] SeasonChallengeHistory
- [ ] PS
- [ ] ActiveDojoColorResearch
- [ ] RewardInfo
- [ ] ReceivedCeremonyMsg
- [ ] LastCeremonyResetDate
- [ ] MissionPTS
- [ ] RepHash
- [ ] EndOfMatchUpload
- [ ] ObjectiveReached
- [ ] FpsAvg
- [ ] FpsMin
- [ ] FpsMax
- [ ] FpsSamples
*/

const missionInventoryUpdateController: RequestHandler = (_req, res) => {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const missionInventoryUpdateController: RequestHandler = async (req, res) => {
const [data] = String(req.body).split("\n");
const id = req.query.accountId as string;

// TODO - salt check

try {
const parsedData = JSON.parse(data) as MissionInventoryUpdate;
if (typeof parsedData !== "object" || parsedData === null) throw new Error("Invalid data format");
await missionInventoryUpdate(parsedData, id);
} catch (err) {
console.error("Error parsing JSON data:", err);
}

// TODO - get original response
res.json({});
};

Expand Down
7 changes: 7 additions & 0 deletions src/controllers/stats/viewController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { RequestHandler } from "express";

const viewController: RequestHandler = (_req, res) => {
res.json({});
};

export { viewController };
12 changes: 10 additions & 2 deletions src/models/inventoryModel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Model, Schema, Types, model } from "mongoose";
import { FlavourItem, IInventoryDatabase } from "../types/inventoryTypes/inventoryTypes";
import { FlavourItem, RawUpgrade, MiscItem, IInventoryDatabase, Booster } from "../types/inventoryTypes/inventoryTypes";
import { Oid } from "../types/commonTypes";
import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes";
import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes";
Expand Down Expand Up @@ -66,6 +66,11 @@ const WeaponSchema = new Schema({
UnlockLevel: Number
});

const BoosterSchema = new Schema({
ExpiryDate: Number,
ItemType: String
});

WeaponSchema.set("toJSON", {
transform(_document, returnedObject) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
Expand Down Expand Up @@ -213,7 +218,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
LoreFragmentScans: [Schema.Types.Mixed],
EquippedEmotes: [String],
PendingTrades: [Schema.Types.Mixed],
Boosters: [Schema.Types.Mixed],
Boosters: [BoosterSchema],
ActiveDojoColorResearch: String,
SentientSpawnChanceBoosters: Schema.Types.Mixed,
Affiliations: [Schema.Types.Mixed],
Expand Down Expand Up @@ -334,6 +339,9 @@ type InventoryDocumentProps = {
Pistols: Types.DocumentArray<IWeaponDatabase>;
Melee: Types.DocumentArray<IWeaponDatabase>;
FlavourItems: Types.DocumentArray<FlavourItem>;
RawUpgrades: Types.DocumentArray<RawUpgrade>;
MiscItems: Types.DocumentArray<MiscItem>;
Boosters: Types.DocumentArray<Booster>;
};

type InventoryModelType = Model<IInventoryDatabase, {}, InventoryDocumentProps>;
Expand Down
4 changes: 4 additions & 0 deletions src/routes/stats.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { viewController } from "../controllers/api/viewController";
import { uploadController } from "@/src/controllers/stats/uploadController";

import express from "express";

const statsRouter = express.Router();

statsRouter.get("/view.php", viewController);
statsRouter.post("/upload.php", uploadController);

export { statsRouter };
101 changes: 100 additions & 1 deletion src/services/inventoryService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import { Types } from "mongoose";
import { ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes";
import { SlotType } from "@/src/types/purchaseTypes";
import { IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes";
import { FlavourItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { ChallengeProgress, FlavourItem, IInventoryDatabaseDocument } from "@/src/types/inventoryTypes/inventoryTypes";
import {
MissionInventoryUpdate,
MissionInventoryUpdateCard,
MissionInventoryUpdateGear,
MissionInventoryUpdateItem
} from "../types/missionInventoryUpdateType";

const createInventory = async (accountOwnerId: Types.ObjectId) => {
try {
Expand Down Expand Up @@ -106,4 +112,97 @@ export const addCustomization = async (customizatonName: string, accountId: stri
return changedInventory.FlavourItems[flavourItemIndex].toJSON(); //mongoose bug forces as FlavourItem
};

const addGearExpByCategory = (
inventory: IInventoryDatabaseDocument,
gearArray: MissionInventoryUpdateGear[] | undefined,
categoryName: "Pistols" | "LongGuns" | "Melee" | "Suits"
) => {
const category = inventory[categoryName];

gearArray?.forEach(({ ItemId, XP }) => {
const itemIndex = category.findIndex(i => i._id?.equals(ItemId.$oid));
const item = category[itemIndex];

if (itemIndex !== -1 && item.XP != undefined) {
item.XP += XP;
inventory.markModified(`${categoryName}.${itemIndex}.XP`);
}
});
};

const addItemsByCategory = (
inventory: IInventoryDatabaseDocument,
itemsArray: (MissionInventoryUpdateItem | MissionInventoryUpdateCard)[] | undefined,
categoryName: "RawUpgrades" | "MiscItems"
) => {
const category = inventory[categoryName];

itemsArray?.forEach(({ ItemCount, ItemType }) => {
const itemIndex = category.findIndex(i => i.ItemType === ItemType);

if (itemIndex !== -1) {
category[itemIndex].ItemCount += ItemCount;
inventory.markModified(`${categoryName}.${itemIndex}.ItemCount`);
} else {
category.push({ ItemCount, ItemType });
}
});
};

const addChallenges = (inventory: IInventoryDatabaseDocument, itemsArray: ChallengeProgress[] | undefined) => {
const category = inventory.ChallengeProgress;

itemsArray?.forEach(({ Name, Progress }) => {
const itemIndex = category.findIndex(i => i.Name === Name);

if (itemIndex !== -1) {
category[itemIndex].Progress += Progress;
inventory.markModified(`ChallengeProgress.${itemIndex}.ItemCount`);
} else {
category.push({ Name, Progress });
}
});
};

const gearKeys = ["Suits", "Pistols", "LongGuns", "Melee"] as const;
type GearKeysType = (typeof gearKeys)[number];

export const missionInventoryUpdate = async (data: MissionInventoryUpdate, accountId: string): Promise<void> => {
const { RawUpgrades, MiscItems, RegularCredits, ChallengeProgress } = data;
const inventory = await getInventory(accountId);

// TODO - multipliers logic
// credits
inventory.RegularCredits += RegularCredits || 0;

// gear exp
gearKeys.forEach((key: GearKeysType) => addGearExpByCategory(inventory, data[key], key));

// other
addItemsByCategory(inventory, RawUpgrades, "RawUpgrades"); // TODO - check mods fusion level
addItemsByCategory(inventory, MiscItems, "MiscItems");
addChallenges(inventory, ChallengeProgress);

await inventory.save();
};

export const addBooster = async (ItemType: string, time: number, accountId: string): Promise<void> => {
const currentTime = Math.floor(Date.now() / 1000) - 129600; // booster time getting more without 129600, probably defence logic, idk

const inventory = await getInventory(accountId);
const { Boosters } = inventory;

const itemIndex = Boosters.findIndex(i => i.ItemType === ItemType);

if (itemIndex !== -1) {
const existingBooster = Boosters[itemIndex];
existingBooster.ExpiryDate = Math.max(existingBooster.ExpiryDate, currentTime) + time;
inventory.markModified(`Boosters.${itemIndex}.ExpiryDate`);
} else {
Boosters.push({ ItemType, ExpiryDate: currentTime + time }) - 1;
}

await inventory.save();
};

export { createInventory, addPowerSuit };
39 changes: 31 additions & 8 deletions src/services/purchaseService.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { getWeaponType } from "@/src/helpers/purchaseHelpers";
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
import {
addCustomization,
addPowerSuit,
addWeapon,
updateCurrency,
updateSlots
} from "@/src/services/inventoryService";
import { IPurchaseRequest, IPurchaseResponse, SlotType } from "@/src/types/purchaseTypes";
import { addBooster, addCustomization, addPowerSuit, addWeapon, updateSlots } from "@/src/services/inventoryService";
import { IPurchaseRequest, SlotType } from "@/src/types/purchaseTypes";

export const getStoreItemCategory = (storeItem: string) => {
const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
Expand Down Expand Up @@ -41,6 +35,9 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI
case "Types":
purchaseResponse = await handleTypesPurchase(internalName, accountId);
break;
case "Boosters":
purchaseResponse = await handleBoostersPurchase(internalName, accountId);
break;

default:
throw new Error(`unknown store category: ${storeCategory} not implemented or new`);
Expand Down Expand Up @@ -114,3 +111,29 @@ const handleSuitCustomizationsPurchase = async (customizationName: string, accou
}
};
};

const boosterCollection = [
"/Lotus/Types/Boosters/ResourceAmountBooster",
"/Lotus/Types/Boosters/AffinityBooster",
"/Lotus/Types/Boosters/ResourceDropChanceBooster",
"/Lotus/Types/Boosters/CreditBooster"
];

const handleBoostersPurchase = async (boosterStoreName: string, accountId: string) => {
const match = boosterStoreName.match(/(\d+)Day/);
if (!match) return;

const extractedDigit = Number(match[1]);
const ItemType = boosterCollection.find(i =>
boosterStoreName.includes(i.split("/").pop()!.replace("Booster", ""))
)!;
const ExpiryDate = extractedDigit * 86400;

await addBooster(ItemType, ExpiryDate, accountId);

return {
InventoryChanges: {
Boosters: [{ ItemType, ExpiryDate }]
}
};
};
8 changes: 6 additions & 2 deletions src/types/inventoryTypes/SuitTypes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Oid } from "@/src/types/commonTypes";
import { AbilityOverride, Color, Polarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Document } from "mongoose";
import { Document, Types } from "mongoose";

export interface ISuitDocument extends ISuitResponse, Document {}
// export interface ISuitDocument extends ISuitResponse, Document {}
export interface ISuitDocument extends Document, ISuitResponse {
_id: Types.ObjectId;
}

export interface ISuitResponse extends ISuitDatabase {
ItemId: Oid;
Expand All @@ -20,6 +23,7 @@ export interface ISuitDatabase {
ModSlotPurchases?: number;
FocusLens?: string;
UnlockLevel?: number;
_id: Types.ObjectId;
}

export interface SuitConfig {
Expand Down
12 changes: 11 additions & 1 deletion src/types/inventoryTypes/inventoryTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,16 @@ export interface FlavourItem {
ItemType: string;
}

export interface RawUpgrade {
ItemCount: number;
ItemType: string;
}

export interface MiscItem {
ItemCount: number;
ItemType: string;
}

export interface CrewshipWeapon {
PILOT: Pilot;
PORT_GUNS: PortGuns;
Expand Down Expand Up @@ -919,7 +929,7 @@ export interface Progress {

export interface RawUpgrade {
ItemCount: number;
LastAdded: Oid;
LastAdded?: Oid;
ItemType: string;
}

Expand Down
2 changes: 2 additions & 0 deletions src/types/inventoryTypes/weaponTypes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Oid } from "@/src/types/commonTypes";
import { Color, Polarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Types } from "mongoose";

export interface IWeaponResponse extends IWeaponDatabase {
ItemId: Oid;
Expand All @@ -20,6 +21,7 @@ export interface IWeaponDatabase {
ItemName?: string;
ModularParts?: string[];
UnlockLevel?: number;
_id?: Types.ObjectId;
}

export interface WeaponConfig {
Expand Down
Loading

0 comments on commit db0aaff

Please sign in to comment.