XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat: more supported equipment types (#867)

97bec71b
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

8 个文件 +261 -293
Modified src/models/inventoryModels/inventoryModel.ts +140 -164
@@ -51,9 +51,13 @@ import {
51 51 ICompletedDialogue,
52 52 IDialogueClient,
53 53 IUpgradeDatabase,
54 ICrewShipDatabase,
55 54 ICrewShipMemberDatabase,
56 ICrewShipMemberClient
55 ICrewShipMemberClient,
56 TEquipmentKey,
57 equipmentKeys,
58 IKubrowPetDetailsDatabase,
59 ITraits,
60 IKubrowPetDetailsClient
57 61 } from "../../types/inventoryTypes/inventoryTypes";
58 62 import { IOid } from "../../types/commonTypes";
59 63 import {
@@ -223,55 +227,6 @@ ArchonCrystalUpgradeSchema.set("toJSON", {
223 227 }
224 228 });
225 229
226 const EquipmentSchema = new Schema<IEquipmentDatabase>(
227 {
228 ItemType: String,
229 Configs: [ItemConfigSchema],
230 UpgradeVer: Number,
231 XP: Number,
232 Features: Number,
233 Polarized: Number,
234 Polarity: [polaritySchema],
235 FocusLens: String,
236 ModSlotPurchases: Number,
237 CustomizationSlotPurchases: Number,
238 UpgradeType: String,
239 UpgradeFingerprint: String,
240 ItemName: String,
241 InfestationDate: Date,
242 InfestationDays: Number,
243 InfestationType: String,
244 ModularParts: { type: [String], default: undefined },
245 UnlockLevel: Number,
246 Expiry: Date,
247 SkillTree: String,
248 OffensiveUpgrade: String,
249 DefensiveUpgrade: String,
250 UpgradesExpiry: Date,
251 ArchonCrystalUpgrades: { type: [ArchonCrystalUpgradeSchema], default: undefined }
252 },
253 { id: false }
254 );
255
256 EquipmentSchema.virtual("ItemId").get(function () {
257 return { $oid: this._id.toString() } satisfies IOid;
258 });
259
260 EquipmentSchema.set("toJSON", {
261 virtuals: true,
262 transform(_document, returnedObject) {
263 delete returnedObject._id;
264 delete returnedObject.__v;
265
266 const db = returnedObject as IEquipmentDatabase;
267 const client = returnedObject as IEquipmentClient;
268
269 if (db.InfestationDate) {
270 client.InfestationDate = toMongoDate(db.InfestationDate);
271 }
272 }
273 });
274
275 230 const boosterSchema = new Schema<IBooster>(
276 231 {
277 232 ExpiryDate: Number,
@@ -505,31 +460,6 @@ const helminthResourceSchema = new Schema<IHelminthResource>(
505 460 { _id: false }
506 461 );
507 462
508 const infestedFoundrySchema = new Schema<IInfestedFoundryDatabase>(
509 {
510 Name: String,
511 Resources: { type: [helminthResourceSchema], default: undefined },
512 Slots: Number,
513 XP: Number,
514 ConsumedSuits: { type: [consumedSchuitsSchema], default: undefined },
515 InvigorationIndex: Number,
516 InvigorationSuitOfferings: { type: [String], default: undefined },
517 InvigorationsApplied: Number,
518 LastConsumedSuit: { type: EquipmentSchema, default: undefined },
519 AbilityOverrideUnlockCooldown: Date
520 },
521 { _id: false }
522 );
523
524 infestedFoundrySchema.set("toJSON", {
525 transform(_doc, ret, _options) {
526 if (ret.AbilityOverrideUnlockCooldown) {
527 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
528 ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown);
529 }
530 }
531 });
532
533 463 const questProgressSchema = new Schema<IQuestStage>({
534 464 c: Number,
535 465 i: Boolean,
@@ -715,26 +645,6 @@ const crewShipMembersSchema = new Schema<ICrewShipMembersDatabase>(
715 645 { _id: false }
716 646 );
717 647
718 const crewShipSchema = new Schema<ICrewShipDatabase>({
719 ItemType: { type: String, required: true },
720 Configs: { type: [ItemConfigSchema], default: [] },
721 Weapon: { type: crewShipWeaponSchema, default: undefined },
722 Customization: { type: crewShipCustomizationSchema, default: undefined },
723 ItemName: { type: String, default: "" },
724 RailjackImage: { type: FlavourItemSchema, default: undefined },
725 CrewMembers: { type: crewShipMembersSchema, default: undefined }
726 });
727 crewShipSchema.virtual("ItemId").get(function () {
728 return { $oid: this._id.toString() };
729 });
730 crewShipSchema.set("toJSON", {
731 virtuals: true,
732 transform(_doc, ret, _options) {
733 delete ret._id;
734 delete ret.__v;
735 }
736 });
737
738 648 const dialogueGiftSchema = new Schema<IDialogueGift>(
739 649 {
740 650 Item: String,
@@ -789,6 +699,134 @@ const dialogueHistorySchema = new Schema<IDialogueHistoryDatabase>(
789 699 { _id: false }
790 700 );
791 701
702 const traitsSchema = new Schema<ITraits>(
703 {
704 BaseColor: String,
705 SecondaryColor: String,
706 TertiaryColor: String,
707 AccentColor: String,
708 EyeColor: String,
709 FurPattern: String,
710 Personality: String,
711 BodyType: String,
712 Head: { type: String, required: false },
713 Tail: { type: String, required: false }
714 },
715 { _id: false }
716 );
717
718 const detailsSchema = new Schema<IKubrowPetDetailsDatabase>(
719 {
720 Name: String,
721 IsPuppy: Boolean,
722 HasCollar: Boolean,
723 PrintsRemaining: Number,
724 Status: String,
725 HatchDate: Date,
726 DominantTraits: traitsSchema,
727 RecessiveTraits: traitsSchema,
728 IsMale: Boolean,
729 Size: Number
730 },
731 { _id: false }
732 );
733
734 detailsSchema.set("toJSON", {
735 transform(_doc, returnedObject) {
736 delete returnedObject.__v;
737
738 const db = returnedObject as IKubrowPetDetailsDatabase;
739 const client = returnedObject as IKubrowPetDetailsClient;
740
741 client.HatchDate = toMongoDate(db.HatchDate);
742 }
743 });
744
745 const EquipmentSchema = new Schema<IEquipmentDatabase>(
746 {
747 ItemType: String,
748 Configs: [ItemConfigSchema],
749 UpgradeVer: { type: Number, default: 101 },
750 XP: { type: Number, default: 0 },
751 Features: Number,
752 Polarized: Number,
753 Polarity: [polaritySchema],
754 FocusLens: String,
755 ModSlotPurchases: Number,
756 CustomizationSlotPurchases: Number,
757 UpgradeType: String,
758 UpgradeFingerprint: String,
759 ItemName: String,
760 InfestationDate: Date,
761 InfestationDays: Number,
762 InfestationType: String,
763 ModularParts: { type: [String], default: undefined },
764 UnlockLevel: Number,
765 Expiry: Date,
766 SkillTree: String,
767 OffensiveUpgrade: String,
768 DefensiveUpgrade: String,
769 UpgradesExpiry: Date,
770 ArchonCrystalUpgrades: { type: [ArchonCrystalUpgradeSchema], default: undefined },
771 Weapon: crewShipWeaponSchema,
772 Customization: crewShipCustomizationSchema,
773 RailjackImage: FlavourItemSchema,
774 CrewMembers: crewShipMembersSchema,
775 Details: detailsSchema
776 },
777 { id: false }
778 );
779
780 EquipmentSchema.virtual("ItemId").get(function () {
781 return { $oid: this._id.toString() } satisfies IOid;
782 });
783
784 EquipmentSchema.set("toJSON", {
785 virtuals: true,
786 transform(_document, returnedObject) {
787 delete returnedObject._id;
788 delete returnedObject.__v;
789
790 const db = returnedObject as IEquipmentDatabase;
791 const client = returnedObject as IEquipmentClient;
792
793 if (db.InfestationDate) {
794 client.InfestationDate = toMongoDate(db.InfestationDate);
795 }
796 }
797 });
798
799 const equipmentFields: Record<string, { type: (typeof EquipmentSchema)[] }> = {};
800
801 equipmentKeys.forEach(key => {
802 equipmentFields[key] = { type: [EquipmentSchema] };
803 });
804
805 const infestedFoundrySchema = new Schema<IInfestedFoundryDatabase>(
806 {
807 Name: String,
808 Resources: { type: [helminthResourceSchema], default: undefined },
809 Slots: Number,
810 XP: Number,
811 ConsumedSuits: { type: [consumedSchuitsSchema], default: undefined },
812 InvigorationIndex: Number,
813 InvigorationSuitOfferings: { type: [String], default: undefined },
814 InvigorationsApplied: Number,
815 LastConsumedSuit: { type: EquipmentSchema, default: undefined },
816 AbilityOverrideUnlockCooldown: Date
817 },
818 { _id: false }
819 );
820
821 infestedFoundrySchema.set("toJSON", {
822 transform(_doc, ret, _options) {
823 if (ret.AbilityOverrideUnlockCooldown) {
824 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
825 ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown);
826 }
827 }
828 });
829
792 830 const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
793 831 {
794 832 accountOwnerId: Schema.Types.ObjectId,
@@ -821,6 +859,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
821 859 MechBin: { type: slotsBinSchema, default: { Slots: 4 } },
822 860 CrewMemberBin: { type: slotsBinSchema, default: { Slots: 3 } },
823 861
862 ...equipmentFields,
863
824 864 //How many trades do you have left
825 865 TradesRemaining: { type: Number, default: 0 },
826 866 //How many Gift do you have left*(gift spends the trade)
@@ -870,29 +910,10 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
870 910 //Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+""
871 911 Upgrades: [upgradeSchema],
872 912
873 //Warframe
874 Suits: [EquipmentSchema],
875 //Primary Weapon
876 LongGuns: [EquipmentSchema],
877 //Secondary Weapon
878 Pistols: [EquipmentSchema],
879 //Melee Weapon
880 Melee: [EquipmentSchema],
881 //Ability Weapon like Ultimate Mech\Excalibur\Ivara etc
882 SpecialItems: [EquipmentSchema],
883 913 //The Mandachord(Octavia) is a step sequencer
884 914 StepSequencers: [StepSequencersSchema],
885 915
886 //Sentinel(like Helios or modular)
887 Sentinels: [EquipmentSchema],
888 //Any /Sentinels/SentinelWeapons/ (like warframe weapon)
889 SentinelWeapons: [EquipmentSchema],
890 //Modular Pets
891 MoaPets: [EquipmentSchema],
892
893 916 KubrowPetEggs: [Schema.Types.Mixed],
894 //Like PowerSuit Cat\Kubrow or etc Pets
895 KubrowPets: [EquipmentSchema],
896 917 //Prints Cat(3 Prints)\Kubrow(2 Prints) Pets
897 918 KubrowPetPrints: [Schema.Types.Mixed],
898 919
@@ -905,42 +926,26 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
905 926 EquippedInstrument: String,
906 927 ReceivedStartingGear: Boolean,
907 928
908 //to use add SummonItem to Consumables+EquippedGear
909 //Archwing need Suits+Melee+Guns
910 SpaceSuits: [EquipmentSchema],
911 SpaceMelee: [EquipmentSchema],
912 SpaceGuns: [EquipmentSchema],
913 929 ArchwingEnabled: Boolean,
914 //Mech need Suits+SpaceGuns+SpecialItem
915 MechSuits: [EquipmentSchema],
916 ///Restoratives/HoverboardSummon (like Suit)
917 Hoverboards: [EquipmentSchema],
918 930
919 931 //Use Operator\Drifter
920 932 UseAdultOperatorLoadout: Boolean,
921 //Operator\Drifter Weapon
922 OperatorAmps: [EquipmentSchema],
923 933 //Operator
924 934 OperatorLoadOuts: [operatorConfigSchema],
925 935 //Drifter
926 936 AdultOperatorLoadOuts: [operatorConfigSchema],
927 DrifterMelee: [EquipmentSchema],
928 DrifterGuns: [EquipmentSchema],
929 //ErsatzHorsePowerSuit
930 Horses: [EquipmentSchema],
937 // Kahl
938 KahlLoadOuts: [operatorConfigSchema],
931 939
932 940 //LandingCraft like Liset
933 941 Ships: { type: [Schema.Types.ObjectId], ref: "Ships" },
934 942 // /Lotus/Types/Items/ShipDecos/
935 943 ShipDecorations: [typeCountSchema],
936 944
937 //RailJack Setting(Mods,Skin,Weapon,etc)
938 CrewShipHarnesses: [EquipmentSchema],
939 945 //Railjack/Components(https://warframe.fandom.com/wiki/Railjack/Components)
940 946 CrewShipRawSalvage: [Schema.Types.Mixed],
941 947
942 948 //Default RailJack
943 CrewShips: [crewShipSchema],
944 949 CrewShipAmmo: [typeCountSchema],
945 950 CrewShipWeapons: [Schema.Types.Mixed],
946 951 CrewShipWeaponSkins: [Schema.Types.Mixed],
@@ -962,9 +967,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
962 967 //Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc
963 968 FlavourItems: [FlavourItemSchema],
964 969
965 //Lunaro Weapon
966 Scoops: [EquipmentSchema],
967
968 970 //Mastery Rank*(Need item XPInfo to rank up)
969 971 PlayerLevel: { type: Number, default: 0 },
970 972 //Item Mastery Rank exp
@@ -1075,11 +1077,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1075 1077 //https://warframe.fandom.com/wiki/Invasion
1076 1078 InvasionChainProgress: [Schema.Types.Mixed],
1077 1079
1078 //https://warframe.fandom.com/wiki/Parazon
1079 DataKnives: [EquipmentSchema],
1080
1081 Motorcycles: [EquipmentSchema],
1082
1083 1080 //CorpusLich or GrineerLich
1084 1081 NemesisAbandonedRewards: [String],
1085 1082 //CorpusLich\KuvaLich
@@ -1116,7 +1113,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1116 1113 //Unknown and system
1117 1114 DuviriInfo: DuviriInfoSchema,
1118 1115 Mailbox: MailboxSchema,
1119 KahlLoadOuts: [Schema.Types.Mixed],
1120 1116 HandlerPoints: Number,
1121 1117 ChallengesFixVersion: Number,
1122 1118 PlayedParkourTutorial: Boolean,
@@ -1175,37 +1171,17 @@ inventorySchema.set("toJSON", {
1175 1171
1176 1172 // type overwrites for subdocuments/subdocument arrays
1177 1173 export type InventoryDocumentProps = {
1178 Suits: Types.DocumentArray<IEquipmentDatabase>;
1179 LongGuns: Types.DocumentArray<IEquipmentDatabase>;
1180 Pistols: Types.DocumentArray<IEquipmentDatabase>;
1181 Melee: Types.DocumentArray<IEquipmentDatabase>;
1182 OperatorAmps: Types.DocumentArray<IEquipmentDatabase>;
1183 1174 FlavourItems: Types.DocumentArray<IFlavourItem>;
1184 1175 RawUpgrades: Types.DocumentArray<IRawUpgrade>;
1185 1176 Upgrades: Types.DocumentArray<IUpgradeDatabase>;
1186 1177 MiscItems: Types.DocumentArray<IMiscItem>;
1187 1178 Boosters: Types.DocumentArray<IBooster>;
1188 1179 OperatorLoadOuts: Types.DocumentArray<IOperatorConfigDatabase>;
1189 SpecialItems: Types.DocumentArray<IEquipmentDatabase>;
1190 1180 AdultOperatorLoadOuts: Types.DocumentArray<IOperatorConfigDatabase>;
1191 MechSuits: Types.DocumentArray<IEquipmentDatabase>;
1192 Scoops: Types.DocumentArray<IEquipmentDatabase>;
1193 DataKnives: Types.DocumentArray<IEquipmentDatabase>;
1194 Motorcycles: Types.DocumentArray<IEquipmentDatabase>;
1195 DrifterMelee: Types.DocumentArray<IEquipmentDatabase>;
1196 Sentinels: Types.DocumentArray<IEquipmentDatabase>;
1197 Horses: Types.DocumentArray<IEquipmentDatabase>;
1181 KahlLoadOuts: Types.DocumentArray<IOperatorConfigDatabase>;
1198 1182 PendingRecipes: Types.DocumentArray<IPendingRecipeDatabase>;
1199 SpaceSuits: Types.DocumentArray<IEquipmentDatabase>;
1200 SpaceGuns: Types.DocumentArray<IEquipmentDatabase>;
1201 SpaceMelee: Types.DocumentArray<IEquipmentDatabase>;
1202 SentinelWeapons: Types.DocumentArray<IEquipmentDatabase>;
1203 Hoverboards: Types.DocumentArray<IEquipmentDatabase>;
1204 MoaPets: Types.DocumentArray<IEquipmentDatabase>;
1205 1183 WeaponSkins: Types.DocumentArray<IWeaponSkinDatabase>;
1206 CrewShips: Types.DocumentArray<ICrewShipDatabase>;
1207 CrewShipHarnesses: Types.DocumentArray<IEquipmentDatabase>;
1208 };
1184 } & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
1209 1185
1210 1186 // eslint-disable-next-line @typescript-eslint/ban-types
1211 1187 type InventoryModelType = Model<IInventoryDatabase, {}, InventoryDocumentProps>;
Modified src/services/importService.ts +20 -16
@@ -8,8 +8,6 @@ import {
8 8 import { IMongoDate } from "../types/commonTypes";
9 9 import {
10 10 equipmentKeys,
11 ICrewShipClient,
12 ICrewShipDatabase,
13 11 ICrewShipMemberClient,
14 12 ICrewShipMemberDatabase,
15 13 ICrewShipMembersClient,
@@ -21,6 +19,8 @@ import {
21 19 IInfestedFoundryClient,
22 20 IInfestedFoundryDatabase,
23 21 IInventoryClient,
22 IKubrowPetDetailsClient,
23 IKubrowPetDetailsDatabase,
24 24 ILoadoutConfigClient,
25 25 ILoadOutPresets,
26 26 ISlots,
@@ -47,7 +47,16 @@ const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase => {
47 47 _id: new Types.ObjectId(ItemId.$oid),
48 48 InfestationDate: convertOptionalDate(client.InfestationDate),
49 49 Expiry: convertOptionalDate(client.Expiry),
50 UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry)
50 UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry),
51 CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined,
52 Details: client.Details ? convertKubrowDetails(client.Details) : undefined,
53 Configs: client.Configs
54 ? client.Configs.map(obj =>
55 Object.fromEntries(
56 Object.entries(obj).filter(([_, value]) => !Array.isArray(value) || value.length > 0)
57 )
58 )
59 : []
51 60 };
52 61 };
53 62
@@ -102,15 +111,6 @@ const convertCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMember
102 111 };
103 112 };
104 113
105 const convertCrewShip = (client: ICrewShipClient): ICrewShipDatabase => {
106 const { ItemId, ...rest } = client;
107 return {
108 ...rest,
109 _id: new Types.ObjectId(ItemId.$oid),
110 CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined
111 };
112 };
113
114 114 const convertInfestedFoundry = (client: IInfestedFoundryClient): IInfestedFoundryDatabase => {
115 115 return {
116 116 ...client,
@@ -136,6 +136,13 @@ const convertDialogueHistory = (client: IDialogueHistoryClient): IDialogueHistor
136 136 };
137 137 };
138 138
139 const convertKubrowDetails = (client: IKubrowPetDetailsClient): IKubrowPetDetailsDatabase => {
140 return {
141 ...client,
142 HatchDate: convertDate(client.HatchDate)
143 };
144 };
145
139 146 export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<IInventoryClient>): void => {
140 147 for (const key of equipmentKeys) {
141 148 if (client[key] !== undefined) {
@@ -159,7 +166,7 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
159 166 });
160 167 }
161 168 }
162 for (const key of ["OperatorLoadOuts", "AdultOperatorLoadOuts"] as const) {
169 for (const key of ["AdultOperatorLoadOuts", "OperatorLoadOuts", "KahlLoadOuts"] as const) {
163 170 if (client[key] !== undefined) {
164 171 replaceArray<IOperatorConfigDatabase>(db[key], client[key].map(convertOperatorConfig));
165 172 }
@@ -222,9 +229,6 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
222 229 if (client.FocusUpgrades !== undefined) {
223 230 db.FocusUpgrades = client.FocusUpgrades;
224 231 }
225 if (client.CrewShips !== undefined) {
226 replaceArray<ICrewShipDatabase>(db.CrewShips, client.CrewShips.map(convertCrewShip));
227 }
228 232 if (client.InfestedFoundry !== undefined) {
229 233 db.InfestedFoundry = convertInfestedFoundry(client.InfestedFoundry);
230 234 }
Modified src/services/missionInventoryUpdateService.ts +7 -17
@@ -2,7 +2,7 @@ import { ExportRegions, ExportRewards, IReward } from "warframe-public-export-pl
2 2 import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
3 3 import { logger } from "@/src/utils/logger";
4 4 import { IRngResult, getRandomReward } from "@/src/services/rngService";
5 import { IInventoryDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
5 import { equipmentKeys, IInventoryDatabase, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
6 6 import {
7 7 addChallenges,
8 8 addConsumables,
@@ -22,6 +22,7 @@ import { IInventoryChanges } from "@/src/types/purchaseTypes";
22 22 import { getLevelKeyRewards, getNode } from "@/src/services/itemDataService";
23 23 import { InventoryDocumentProps, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
24 24 import { getEntriesUnsafe } from "@/src/utils/ts-utils";
25 import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
25 26
26 27 const getRotations = (rotationCount: number): number[] => {
27 28 if (rotationCount === 0) return [0];
@@ -144,23 +145,12 @@ export const addMissionInventoryUpdates = (
144 145 inventoryChanges.FusionPoints = fusionPoints;
145 146 break;
146 147 }
147 // Equipment XP updates
148 case "Suits":
149 case "LongGuns":
150 case "Pistols":
151 case "Melee":
152 case "SpecialItems":
153 case "Sentinels":
154 case "SentinelWeapons":
155 case "SpaceSuits":
156 case "SpaceGuns":
157 case "SpaceMelee":
158 case "Hoverboards":
159 case "OperatorAmps":
160 case "MoaPets":
161 addGearExpByCategory(inventory, value, key);
162 break;
163 148 default:
149 // Equipment XP updates
150 if (equipmentKeys.includes(key as TEquipmentKey)) {
151 addGearExpByCategory(inventory, value as IEquipmentClient[], key as TEquipmentKey);
152 }
153 break;
164 154 // if (
165 155 // (ignoredInventoryUpdateKeys as readonly string[]).includes(key) ||
166 156 // knownUnhandledKeys.includes(key)
Modified src/services/saveLoadoutService.ts +26 -44
@@ -12,6 +12,7 @@ import { IOid } from "@/src/types/commonTypes";
12 12 import { Types } from "mongoose";
13 13 import { isEmptyObject } from "@/src/helpers/general";
14 14 import { logger } from "@/src/utils/logger";
15 import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
15 16
16 17 //TODO: setup default items on account creation or like originally in giveStartingItems.php
17 18
@@ -36,8 +37,9 @@ export const handleInventoryItemConfigChange = async (
36 37 }
37 38 // non-empty is a change in loadout(or suit...)
38 39 switch (equipmentName) {
40 case "AdultOperatorLoadOuts":
39 41 case "OperatorLoadOuts":
40 case "AdultOperatorLoadOuts": {
42 case "KahlLoadOuts": {
41 43 const operatorConfig = equipment as IOperatorConfigEntry;
42 44 const operatorLoadout = inventory[equipmentName];
43 45 logger.debug(`operator loadout received ${equipmentName} `, operatorConfig);
@@ -124,45 +126,6 @@ export const handleInventoryItemConfigChange = async (
124 126 }
125 127 break;
126 128 }
127 case "LongGuns":
128 case "Pistols":
129 case "Suits":
130 case "Melee":
131 case "Scoops":
132 case "DataKnives":
133 case "DrifterMelee":
134 case "Sentinels":
135 case "Horses":
136 case "OperatorAmps":
137 case "SentinelWeapons":
138 case "KubrowPets":
139 case "SpaceSuits":
140 case "SpaceGuns":
141 case "SpaceMelee":
142 case "SpecialItems":
143 case "MoaPets":
144 case "Hoverboards":
145 case "MechSuits":
146 case "CrewShipHarnesses":
147 case "CrewShips":
148 case "Motorcycles": {
149 logger.debug(`general Item config saved of type ${equipmentName}`, { config: equipment });
150
151 const itemEntries = equipment as IItemEntry;
152 for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) {
153 const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId);
154
155 if (!inventoryItem) {
156 throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`);
157 }
158
159 //config ids are 0,1,2 can there be a 3?
160 for (const [configId, config] of Object.entries(itemConfigEntries)) {
161 inventoryItem.Configs[parseInt(configId)] = config;
162 }
163 }
164 break;
165 }
166 129 case "CurrentLoadOutIds": {
167 130 const loadoutIds = equipment as IOid[]; // TODO: Check for more than just an array of oids, I think i remember one instance
168 131 inventory.CurrentLoadOutIds = loadoutIds;
@@ -178,11 +141,30 @@ export const handleInventoryItemConfigChange = async (
178 141 break;
179 142 }
180 143 default: {
181 logger.warn(`loadout category not implemented, changes may be lost: ${equipmentName}`, {
182 config: equipment
183 });
144 if (equipmentKeys.includes(equipmentName as TEquipmentKey) && equipmentName != "ValidNewLoadoutId") {
145 logger.debug(`general Item config saved of type ${equipmentName}`, {
146 config: equipment
147 });
148
149 const itemEntries = equipment as IItemEntry;
150 for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) {
151 const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId);
152
153 if (!inventoryItem) {
154 throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`);
155 }
156
157 for (const [configId, config] of Object.entries(itemConfigEntries)) {
158 inventoryItem.Configs[parseInt(configId)] = config;
159 }
160 }
161 break;
162 } else {
163 logger.warn(`loadout category not implemented, changes may be lost: ${equipmentName}`, {
164 config: equipment
165 });
166 }
184 167 }
185 //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory
186 168 }
187 169 }
188 170 await inventory.save();
Modified src/types/inventoryTypes/commonInventoryTypes.ts +20 -1
@@ -1,5 +1,14 @@
1 1 import { IMongoDate, IOid } from "@/src/types/commonTypes";
2 2 import { Types } from "mongoose";
3 import {
4 ICrewShipCustomization,
5 ICrewShipMembersClient,
6 ICrewShipMembersDatabase,
7 ICrewShipWeapon,
8 IFlavourItem,
9 IKubrowPetDetailsClient,
10 IKubrowPetDetailsDatabase
11 } from "@/src/types/inventoryTypes/inventoryTypes";
3 12
4 13 export interface IPolarity {
5 14 Slot: number;
@@ -79,11 +88,16 @@ export interface IEquipmentSelection {
79 88 }
80 89
81 90 export interface IEquipmentClient
82 extends Omit<IEquipmentDatabase, "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry"> {
91 extends Omit<
92 IEquipmentDatabase,
93 "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "CrewMembers" | "Details"
94 > {
83 95 ItemId: IOid;
84 96 InfestationDate?: IMongoDate;
85 97 Expiry?: IMongoDate;
86 98 UpgradesExpiry?: IMongoDate;
99 CrewMembers?: ICrewShipMembersClient;
100 Details?: IKubrowPetDetailsClient;
87 101 }
88 102
89 103 export enum EquipmentFeatures {
@@ -120,6 +134,11 @@ export interface IEquipmentDatabase {
120 134 DefensiveUpgrade?: string;
121 135 UpgradesExpiry?: Date;
122 136 ArchonCrystalUpgrades?: IArchonCrystalUpgrade[];
137 Weapon?: ICrewShipWeapon;
138 Customization?: ICrewShipCustomization;
139 RailjackImage?: IFlavourItem;
140 CrewMembers?: ICrewShipMembersDatabase;
141 Details?: IKubrowPetDetailsDatabase;
123 142 _id: Types.ObjectId;
124 143 }
125 144
Modified src/types/inventoryTypes/inventoryTypes.ts +44 -36
@@ -28,9 +28,9 @@ export interface IInventoryDatabase
28 28 | "Upgrades"
29 29 | "CrewShipSalvagedWeaponSkins"
30 30 | "CrewShipWeaponSkins"
31 | "OperatorLoadOuts"
32 31 | "AdultOperatorLoadOuts"
33 | "CrewShips"
32 | "OperatorLoadOuts"
33 | "KahlLoadOuts"
34 34 | "InfestedFoundry"
35 35 | "DialogueHistory"
36 36 | TEquipmentKey
@@ -49,9 +49,9 @@ export interface IInventoryDatabase
49 49 Upgrades: IUpgradeDatabase[];
50 50 CrewShipSalvagedWeaponSkins: IUpgradeDatabase[];
51 51 CrewShipWeaponSkins: IUpgradeDatabase[];
52 OperatorLoadOuts: IOperatorConfigDatabase[];
53 52 AdultOperatorLoadOuts: IOperatorConfigDatabase[];
54 CrewShips: ICrewShipDatabase[];
53 OperatorLoadOuts: IOperatorConfigDatabase[];
54 KahlLoadOuts: IOperatorConfigDatabase[];
55 55 InfestedFoundry?: IInfestedFoundryDatabase;
56 56 DialogueHistory?: IDialogueHistoryDatabase;
57 57
@@ -68,6 +68,16 @@ export interface IInventoryDatabase
68 68 Hoverboards: IEquipmentDatabase[];
69 69 OperatorAmps: IEquipmentDatabase[];
70 70 MoaPets: IEquipmentDatabase[];
71 Scoops: IEquipmentDatabase[];
72 Horses: IEquipmentDatabase[];
73 DrifterGuns: IEquipmentDatabase[];
74 DrifterMelee: IEquipmentDatabase[];
75 Motorcycles: IEquipmentDatabase[];
76 CrewShips: IEquipmentDatabase[];
77 DataKnives: IEquipmentDatabase[];
78 MechSuits: IEquipmentDatabase[];
79 CrewShipHarnesses: IEquipmentDatabase[];
80 KubrowPets: IEquipmentDatabase[];
71 81 }
72 82
73 83 export interface IQuestKeyDatabase {
@@ -97,7 +107,17 @@ export const equipmentKeys = [
97 107 "SpaceMelee",
98 108 "Hoverboards",
99 109 "OperatorAmps",
100 "MoaPets"
110 "MoaPets",
111 "Scoops",
112 "Horses",
113 "DrifterGuns",
114 "DrifterMelee",
115 "Motorcycles",
116 "CrewShips",
117 "DataKnives",
118 "MechSuits",
119 "CrewShipHarnesses",
120 "KubrowPets"
101 121 ] as const;
102 122
103 123 export type TEquipmentKey = (typeof equipmentKeys)[number];
@@ -167,13 +187,22 @@ export interface IInventoryClient extends IDailyAffiliations {
167 187 Hoverboards: IEquipmentClient[];
168 188 OperatorAmps: IEquipmentClient[];
169 189 MoaPets: IEquipmentClient[];
190 Scoops: IEquipmentClient[];
191 Horses: IEquipmentClient[];
192 DrifterGuns: IEquipmentClient[];
193 DrifterMelee: IEquipmentClient[];
194 Motorcycles: IEquipmentClient[];
195 CrewShips: IEquipmentClient[];
196 DataKnives: IEquipmentClient[];
197 MechSuits: IEquipmentClient[];
198 CrewShipHarnesses: IEquipmentClient[];
199 KubrowPets: IEquipmentClient[];
200 AdultOperatorLoadOuts: IOperatorConfigClient[];
201 OperatorLoadOuts: IOperatorConfigClient[];
202 KahlLoadOuts: IOperatorConfigClient[];
170 203
171 Horses: IEquipmentDatabase[];
172 DrifterMelee: IEquipmentDatabase[];
173 DrifterGuns: IEquipmentDatabase[];
174 204 DuviriInfo: IDuviriInfo;
175 205 Mailbox: IMailbox;
176 KahlLoadOuts: IEquipmentDatabase[];
177 206 SubscribedToEmails: number;
178 207 Created: IMongoDate;
179 208 RewardSeed: number;
@@ -208,7 +237,6 @@ export interface IInventoryClient extends IDailyAffiliations {
208 237 QuestKeys: IQuestKeyClient[];
209 238 ActiveQuest: string;
210 239 FlavourItems: IFlavourItem[];
211 Scoops: IEquipmentDatabase[];
212 240 LoadOutPresets: ILoadOutPresets;
213 241 CurrentLoadOutIds: IOid[]; // we store it in the database using this representation as well :/
214 242 Missions: IMission[];
@@ -263,7 +291,6 @@ export interface IInventoryClient extends IDailyAffiliations {
263 291 Drones: IDrone[];
264 292 StepSequencers: IStepSequencer[];
265 293 ActiveAvatarImageType: string;
266 KubrowPets: IEquipmentDatabase[];
267 294 ShipDecorations: IConsumable[];
268 295 DiscoveredMarkers: IDiscoveredMarker[];
269 296 CompletedJobs: ICompletedJob[];
@@ -280,7 +307,6 @@ export interface IInventoryClient extends IDailyAffiliations {
280 307 BountyScore: number;
281 308 ChallengeInstanceStates: IChallengeInstanceState[];
282 309 LoginMilestoneRewards: string[];
283 OperatorLoadOuts: IOperatorConfigClient[];
284 310 RecentVendorPurchases: Array<number | string>;
285 311 NodeIntrosCompleted: string[];
286 312 GuildId?: IOid;
@@ -288,13 +314,10 @@ export interface IInventoryClient extends IDailyAffiliations {
288 314 SeasonChallengeHistory: ISeasonChallenge[];
289 315 EquippedInstrument?: string;
290 316 InvasionChainProgress: IInvasionChainProgress[];
291 DataKnives: IEquipmentDatabase[];
292 Motorcycles: IEquipmentDatabase[];
293 317 NemesisHistory: INemesisHistory[];
294 318 LastNemesisAllySpawnTime?: IMongoDate;
295 319 Settings: ISettings;
296 320 PersonalTechProjects: IPersonalTechProject[];
297 CrewShips: ICrewShipClient[];
298 321 PlayerSkills: IPlayerSkills;
299 322 CrewShipAmmo: IConsumable[];
300 323 CrewShipSalvagedWeaponSkins: IUpgradeClient[];
@@ -304,13 +327,10 @@ export interface IInventoryClient extends IDailyAffiliations {
304 327 TradeBannedUntil?: IMongoDate;
305 328 PlayedParkourTutorial: boolean;
306 329 SubscribedToEmailsPersonalized: number;
307 MechSuits: IEquipmentDatabase[];
308 330 InfestedFoundry?: IInfestedFoundryClient;
309 331 BlessingCooldown: IMongoDate;
310 CrewShipHarnesses: IEquipmentDatabase[];
311 332 CrewShipRawSalvage: IConsumable[];
312 333 CrewMembers: ICrewMember[];
313 AdultOperatorLoadOuts: IOperatorConfigClient[];
314 334 LotusCustomization: ILotusCustomization;
315 335 UseAdultOperatorLoadout?: boolean;
316 336 NemesisAbandonedRewards: string[];
@@ -454,22 +474,6 @@ export interface IUpgradeDatabase extends Omit<IUpgradeClient, "ItemId"> {
454 474 _id: Types.ObjectId;
455 475 }
456 476
457 export interface ICrewShipClient {
458 ItemType: string;
459 Configs: IItemConfig[];
460 Weapon?: ICrewShipWeapon;
461 Customization?: ICrewShipCustomization;
462 ItemName: string;
463 RailjackImage?: IFlavourItem;
464 CrewMembers?: ICrewShipMembersClient;
465 ItemId: IOid;
466 }
467
468 export interface ICrewShipDatabase extends Omit<ICrewShipClient, "CrewMembers" | "ItemId"> {
469 CrewMembers?: ICrewShipMembersDatabase;
470 _id: Types.ObjectId;
471 }
472
473 477 export interface ICrewShipMembersClient {
474 478 SLOT_A?: ICrewShipMemberClient;
475 479 SLOT_B?: ICrewShipMemberClient;
@@ -643,19 +647,23 @@ export enum KubrowPetPrintItemType {
643 647 LotusTypesGameKubrowPetImprintedTraitPrint = "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint"
644 648 }
645 649
646 export interface IDetails {
650 export interface IKubrowPetDetailsDatabase {
647 651 Name: string;
648 652 IsPuppy: boolean;
649 653 HasCollar: boolean;
650 654 PrintsRemaining: number;
651 655 Status: Status;
652 HatchDate: IMongoDate;
656 HatchDate: Date;
653 657 DominantTraits: ITraits;
654 658 RecessiveTraits: ITraits;
655 659 IsMale: boolean;
656 660 Size: number;
657 661 }
658 662
663 export interface IKubrowPetDetailsClient extends Omit<IKubrowPetDetailsDatabase, "HatchDate"> {
664 HatchDate: IMongoDate;
665 }
666
659 667 export enum Status {
660 668 StatusAvailable = "STATUS_AVAILABLE",
661 669 StatusStasis = "STATUS_STASIS"
Modified src/types/requestTypes.ts +2 -13
@@ -39,19 +39,6 @@ export type IMissionInventoryUpdateRequest = {
39 39 GoalTag: string;
40 40 LevelKeyName: string;
41 41 ActiveBoosters?: IBooster[];
42 Suits?: IEquipmentClient[];
43 LongGuns?: IEquipmentClient[];
44 Pistols?: IEquipmentClient[];
45 Melee?: IEquipmentClient[];
46 SpecialItems?: IEquipmentClient[];
47 Sentinels?: IEquipmentClient[];
48 SentinelWeapons?: IEquipmentClient[];
49 SpaceSuits?: IEquipmentClient[];
50 SpaceGuns?: IEquipmentClient[];
51 SpaceMelee?: IEquipmentClient[];
52 Hoverboards?: IEquipmentClient[];
53 OperatorAmps?: IEquipmentClient[];
54 MoaPets?: IEquipmentClient[];
55 42 FusionBundles?: ITypeCount[];
56 43 RawUpgrades?: IRawUpgrade[];
57 44 MiscItems?: ITypeCount[];
@@ -85,6 +72,8 @@ export type IMissionInventoryUpdateRequest = {
85 72 FpsMax: number;
86 73 FpsSamples: number;
87 74 EvolutionProgress?: IEvolutionProgress[];
75 } & {
76 [K in TEquipmentKey]?: IEquipmentClient[];
88 77 };
89 78
90 79 export interface IRewardInfo {
Modified src/types/saveLoadoutTypes.ts +2 -2
@@ -27,9 +27,9 @@ export interface ISaveLoadoutRequest {
27 27 Horses: IItemEntry;
28 28 DrifterMelee: IItemEntry;
29 29 UpgradeVer: number;
30 OperatorLoadOuts: IOperatorConfigEntry;
31 30 AdultOperatorLoadOuts: IOperatorConfigEntry;
32 KahlLoadOuts: IItemEntry;
31 OperatorLoadOuts: IOperatorConfigEntry;
32 KahlLoadOuts: IOperatorConfigEntry;
33 33 CrewShips: IItemEntry;
34 34 CurrentLoadOutIds: IOid[];
35 35 ValidNewLoadoutId: string;