diff --git a/config.json.example b/config.json.example index d12270ef..f1c29035 100644 --- a/config.json.example +++ b/config.json.example @@ -29,6 +29,7 @@ "unlockExilusEverywhere": false, "unlockArcanesEverywhere": false, "noDailyStandingLimits": false, + "noVendorPurchaseLimits": true, "instantResourceExtractorDrones": false, "noDojoRoomBuildStage": false, "fastDojoRoomDestruction": false, diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 880dd09e..c7446f41 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -76,7 +76,10 @@ import { IIncentiveState, ISongChallenge, ILibraryPersonalProgress, - ICrewShipWeaponDatabase + ICrewShipWeaponDatabase, + IRecentVendorPurchaseDatabase, + IVendorPurchaseHistoryEntryDatabase, + IVendorPurchaseHistoryEntryClient } from "../../types/inventoryTypes/inventoryTypes"; import { IOid } from "../../types/commonTypes"; import { @@ -974,6 +977,31 @@ const incentiveStateSchema = new Schema( { _id: false } ); +const vendorPurchaseHistoryEntrySchema = new Schema( + { + Expiry: Date, + NumPurchased: Number, + ItemId: String + }, + { _id: false } +); + +vendorPurchaseHistoryEntrySchema.set("toJSON", { + transform(_doc, obj) { + const db = obj as IVendorPurchaseHistoryEntryDatabase; + const client = obj as IVendorPurchaseHistoryEntryClient; + client.Expiry = toMongoDate(db.Expiry); + } +}); + +const recentVendorPurchaseSchema = new Schema( + { + VendorType: String, + PurchaseHistory: [vendorPurchaseHistoryEntrySchema] + }, + { _id: false } +); + const collectibleEntrySchema = new Schema( { CollectibleType: String, @@ -1361,7 +1389,7 @@ const inventorySchema = new Schema( RandomUpgradesIdentified: Number, BountyScore: Number, ChallengeInstanceStates: [Schema.Types.Mixed], - RecentVendorPurchases: [Schema.Types.Mixed], + RecentVendorPurchases: { type: [recentVendorPurchaseSchema], default: undefined }, Robotics: [Schema.Types.Mixed], UsedDailyDeals: [Schema.Types.Mixed], CollectibleSeries: { type: [collectibleEntrySchema], default: undefined }, diff --git a/src/services/configService.ts b/src/services/configService.ts index 07860f93..717dae35 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -55,6 +55,7 @@ interface IConfig { unlockExilusEverywhere?: boolean; unlockArcanesEverywhere?: boolean; noDailyStandingLimits?: boolean; + noVendorPurchaseLimits?: boolean; instantResourceExtractorDrones?: boolean; noDojoRoomBuildStage?: boolean; fastDojoRoomDestruction?: boolean; diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index b153c86c..07d46ef5 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -68,6 +68,45 @@ export const handlePurchase = async ( inventoryChanges ); } + if (!config.noVendorPurchaseLimits) { + inventory.RecentVendorPurchases ??= []; + let vendorPurchases = inventory.RecentVendorPurchases.find( + x => x.VendorType == manifest.VendorInfo.TypeName + ); + if (!vendorPurchases) { + vendorPurchases = + inventory.RecentVendorPurchases[ + inventory.RecentVendorPurchases.push({ + VendorType: manifest.VendorInfo.TypeName, + PurchaseHistory: [] + }) - 1 + ]; + } + const historyEntry = vendorPurchases.PurchaseHistory.find(x => x.ItemId == ItemId); + let numPurchased = purchaseRequest.PurchaseParams.Quantity; + if (historyEntry) { + numPurchased += historyEntry.NumPurchased; + historyEntry.NumPurchased += purchaseRequest.PurchaseParams.Quantity; + } else { + vendorPurchases.PurchaseHistory.push({ + ItemId: ItemId, + NumPurchased: purchaseRequest.PurchaseParams.Quantity, + Expiry: new Date(parseInt(offer.Expiry.$date.$numberLong)) + }); + } + inventoryChanges.RecentVendorPurchases = [ + { + VendorType: manifest.VendorInfo.TypeName, + PurchaseHistory: [ + { + ItemId: ItemId, + NumPurchased: numPurchased, + Expiry: offer.Expiry + } + ] + } + ]; + } purchaseRequest.PurchaseParams.Quantity *= offer.QuantityMultiplier; } else if (!ExportVendors[purchaseRequest.PurchaseParams.SourceId!]) { throw new Error(`unknown vendor: ${purchaseRequest.PurchaseParams.SourceId!}`); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index af029a34..1e46376c 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -41,6 +41,7 @@ export interface IInventoryDatabase | "KubrowPetEggs" | "PendingCoupon" | "Drones" + | "RecentVendorPurchases" | TEquipmentKey >, InventoryDatabaseEquipment { @@ -67,6 +68,7 @@ export interface IInventoryDatabase KubrowPetEggs?: IKubrowPetEggDatabase[]; PendingCoupon?: IPendingCouponDatabase; Drones: IDroneDatabase[]; + RecentVendorPurchases?: IRecentVendorPurchaseDatabase[]; } export interface IQuestKeyDatabase { @@ -277,7 +279,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu BountyScore: number; ChallengeInstanceStates: IChallengeInstanceState[]; LoginMilestoneRewards: string[]; - RecentVendorPurchases: Array; + RecentVendorPurchases?: IRecentVendorPurchaseClient[]; NodeIntrosCompleted: string[]; GuildId?: IOid; CompletedJobChains: ICompletedJobChain[]; @@ -361,6 +363,28 @@ export interface IParam { v: string; } +export interface IRecentVendorPurchaseClient { + VendorType: string; + PurchaseHistory: IVendorPurchaseHistoryEntryClient[]; +} + +export interface IVendorPurchaseHistoryEntryClient { + Expiry: IMongoDate; + NumPurchased: number; + ItemId: string; +} + +export interface IRecentVendorPurchaseDatabase { + VendorType: string; + PurchaseHistory: IVendorPurchaseHistoryEntryDatabase[]; +} + +export interface IVendorPurchaseHistoryEntryDatabase { + Expiry: Date; + NumPurchased: number; + ItemId: string; +} + export interface IChallengeProgress { Progress: number; Name: string; diff --git a/static/webui/index.html b/static/webui/index.html index f700994d..bd5f13cc 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -517,6 +517,10 @@ +
+ + +
diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 74ec43f4..0a329181 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -110,6 +110,7 @@ dict = { cheats_unlockExilusEverywhere: `Exilus-Adapter überall`, cheats_unlockArcanesEverywhere: `Arkana-Adapter überall`, cheats_noDailyStandingLimits: `Kein tägliches Ansehenslimit`, + cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`, cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`, cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`, cheats_fastDojoRoomDestruction: `Schnelle Dojo-Raum-Zerstörung`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index 484b0063..455ab2e4 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -109,6 +109,7 @@ dict = { cheats_unlockExilusEverywhere: `Exilus Adapters Everywhere`, cheats_unlockArcanesEverywhere: `Arcane Adapters Everywhere`, cheats_noDailyStandingLimits: `No Daily Standing Limits`, + cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`, cheats_instantResourceExtractorDrones: `Instant Resource Extractor Drones`, cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`, cheats_fastDojoRoomDestruction: `Fast Dojo Room Destruction`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 153aad2b..9840911a 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -110,6 +110,7 @@ dict = { cheats_unlockExilusEverywhere: `Adaptateurs Exilus partout`, cheats_unlockArcanesEverywhere: `Adaptateur d'Arcanes partout`, cheats_noDailyStandingLimits: `Pas de limite de réputation journalière`, + cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`, cheats_instantResourceExtractorDrones: `Ressources de drone d'extraction instantannées`, cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`, cheats_fastDojoRoomDestruction: `[UNTRANSLATED] Fast Dojo Room Destruction`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 44c6eb41..030c704b 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -110,6 +110,7 @@ dict = { cheats_unlockExilusEverywhere: `Адаптеры Эксилус везде`, cheats_unlockArcanesEverywhere: `Адаптеры для мистификаторов везде`, cheats_noDailyStandingLimits: `Без ежедневных ограничений репутации`, + cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`, cheats_instantResourceExtractorDrones: `Мгновенные Экстракторы Ресурсов`, cheats_noDojoRoomBuildStage: `Мгновенное Строительтво Комнат Додзё`, cheats_fastDojoRoomDestruction: `Мгновенные Уничтожение Комнат Додзё`,