Basic purchasing + custom purchasing API
Endpoint for custom API: https://localhost:443/custom/addItem example request: { "type": "Weapon", "internalName": "/Lotus/Weapons/Grineer/Pistols/GrineerMicrowavegun/GrnMicrowavePistol", "accountId": "6488fd2e7bec200069ca4242" }
This commit is contained in:
parent
0c146d85d4
commit
9c436699f9
8
package-lock.json
generated
8
package-lock.json
generated
@ -11,7 +11,8 @@
|
||||
"dependencies": {
|
||||
"dotenv": "^16.1.3",
|
||||
"express": "^5.0.0-beta.1",
|
||||
"mongoose": "^7.1.1"
|
||||
"mongoose": "^7.1.1",
|
||||
"warframe-items": "1.1260.50"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^1.0.0",
|
||||
@ -3140,6 +3141,11 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/warframe-items": {
|
||||
"version": "1.1260.50",
|
||||
"resolved": "https://registry.npmjs.org/warframe-items/-/warframe-items-1.1260.50.tgz",
|
||||
"integrity": "sha512-03oNB6Yg61yUd7glewUUg0avnaGaAqc9oVPJk+1THFB0o/d4ppQSgL38yTUxMwmw0avCrqd+8z5TMrfXtvPDXQ=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
|
@ -14,7 +14,8 @@
|
||||
"dependencies": {
|
||||
"dotenv": "^16.1.3",
|
||||
"express": "^5.0.0-beta.1",
|
||||
"mongoose": "^7.1.1"
|
||||
"mongoose": "^7.1.1",
|
||||
"warframe-items": "1.1260.50"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^1.0.0",
|
||||
|
@ -23,7 +23,7 @@ app.use(bodyParser.raw());
|
||||
app.use(express.json());
|
||||
app.use(bodyParser.text());
|
||||
app.use(morgan("dev"));
|
||||
app.use(requestLogger);
|
||||
//app.use(requestLogger);
|
||||
|
||||
app.use("/api", apiRouter);
|
||||
//app.use("/test", testRouter);
|
||||
|
@ -13,7 +13,6 @@ const inventoryController: RequestHandler = async (request: Request, response: R
|
||||
response.status(400).json({ error: "accountId was not provided" });
|
||||
return;
|
||||
}
|
||||
console.log(accountId);
|
||||
|
||||
const inventory = await Inventory.findOne({ accountOwnerId: accountId });
|
||||
|
||||
|
@ -1,8 +1,13 @@
|
||||
import purchase from "@/static/fixed_responses/purchase.json";
|
||||
import { parseString } from "@/src/helpers/general";
|
||||
import { toPurchaseRequest } from "@/src/helpers/purchaseHelpers";
|
||||
import { handlePurchase } from "@/src/services/purchaseService";
|
||||
import { Request, Response } from "express";
|
||||
|
||||
const purchaseController = (_req: Request, res: Response): void => {
|
||||
res.json(purchase);
|
||||
const purchaseController = async (req: Request, res: Response) => {
|
||||
const purchaseRequest = toPurchaseRequest(JSON.parse(String(req.body)));
|
||||
const accountId = parseString(req.query.accountId);
|
||||
const response = await handlePurchase(purchaseRequest, accountId);
|
||||
res.json(response);
|
||||
};
|
||||
|
||||
export { purchaseController };
|
||||
|
13
src/controllers/api/saveLoadout.ts
Normal file
13
src/controllers/api/saveLoadout.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Inventory } from "@/src/models/inventoryModel";
|
||||
import { RequestHandler } from "express";
|
||||
import util from "util";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
const saveLoadoutController: RequestHandler = async (req, res) => {
|
||||
const body = JSON.parse(req.body);
|
||||
console.log(util.inspect(body, { showHidden: false, depth: null, colors: true }));
|
||||
|
||||
res.sendStatus(200);
|
||||
};
|
||||
|
||||
export { saveLoadoutController };
|
26
src/controllers/custom/addItemController.ts
Normal file
26
src/controllers/custom/addItemController.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { ItemType, toAddItemRequest } from "@/src/helpers/customHelpers/addItemHelpers";
|
||||
import { getWeaponType } from "@/src/helpers/purchaseHelpers";
|
||||
import { addPowerSuit, addWeapon } from "@/src/services/inventoryService";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
const addItemController: RequestHandler = async (req, res) => {
|
||||
const request = toAddItemRequest(req.body);
|
||||
|
||||
switch (request.type) {
|
||||
case ItemType.Powersuit:
|
||||
const powersuit = await addPowerSuit(request.InternalName, request.accountId);
|
||||
res.json(powersuit);
|
||||
return;
|
||||
case ItemType.Weapon:
|
||||
const weaponType = getWeaponType(request.InternalName);
|
||||
const weapon = await addWeapon(weaponType, request.InternalName, request.accountId);
|
||||
res.json(weapon);
|
||||
break;
|
||||
default:
|
||||
res.status(400).json({ error: "something went wrong" });
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
export { addItemController };
|
@ -1,7 +1,8 @@
|
||||
import { toCreateAccount, toDatabaseAccount } from "@/src/helpers/customHelpers";
|
||||
import { toCreateAccount, toDatabaseAccount } from "@/src/helpers/customHelpers/customHelpers";
|
||||
import { createAccount } from "@/src/services/loginService";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
const createAccountController: RequestHandler = async (req, res) => {
|
||||
const createAccountData = toCreateAccount(req.body);
|
||||
const databaseAccount = toDatabaseAccount(createAccountData);
|
||||
|
55
src/helpers/customHelpers/addItemHelpers.ts
Normal file
55
src/helpers/customHelpers/addItemHelpers.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { isString, parseString } from "@/src/helpers/general";
|
||||
import { items } from "@/static/data/items";
|
||||
|
||||
export enum ItemType {
|
||||
Powersuit = "Powersuit",
|
||||
Weapon = "Weapon"
|
||||
}
|
||||
|
||||
export const isItemType = (itemType: string): itemType is ItemType => {
|
||||
return Object.keys(ItemType).includes(itemType);
|
||||
};
|
||||
|
||||
const parseItemType = (itemType: unknown): ItemType => {
|
||||
if (!itemType || !isString(itemType) || !isItemType(itemType)) {
|
||||
throw new Error("incorrect item type");
|
||||
}
|
||||
|
||||
return itemType;
|
||||
};
|
||||
|
||||
interface IAddItemRequest {
|
||||
type: ItemType;
|
||||
InternalName: string;
|
||||
accountId: string;
|
||||
}
|
||||
export const isInternalName = (internalName: string): boolean => {
|
||||
const item = items.find(i => i.uniqueName === internalName);
|
||||
return Boolean(item);
|
||||
};
|
||||
|
||||
const parseInternalName = (internalName: unknown): string => {
|
||||
if (!isString(internalName) || !isInternalName(internalName)) {
|
||||
throw new Error("incorrect internal name");
|
||||
}
|
||||
|
||||
return internalName;
|
||||
};
|
||||
|
||||
const toAddItemRequest = (body: unknown): IAddItemRequest => {
|
||||
if (!body || typeof body !== "object") {
|
||||
throw new Error("incorrect or missing add item request data");
|
||||
}
|
||||
|
||||
if ("type" in body && "internalName" in body && "accountId" in body) {
|
||||
return {
|
||||
type: parseItemType(body.type),
|
||||
InternalName: parseInternalName(body.internalName),
|
||||
accountId: parseString(body.accountId)
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error("malformed add item request");
|
||||
};
|
||||
|
||||
export { toAddItemRequest };
|
@ -1,7 +1,7 @@
|
||||
import { IAccountCreation } from "@/src/types/customTypes";
|
||||
import { IDatabaseAccount } from "@/src/types/loginTypes";
|
||||
import crypto from "crypto";
|
||||
import { isString, parseEmail, parseString } from "./general";
|
||||
import { isString, parseEmail, parseString } from "../general";
|
||||
|
||||
const getWhirlpoolHash = (rawPassword: string): string => {
|
||||
const whirlpool = crypto.createHash("whirlpool");
|
||||
@ -30,7 +30,6 @@ const toAccountCreation = (accountCreation: unknown): IAccountCreation => {
|
||||
"CountryCode" in accountCreation
|
||||
) {
|
||||
const rawPassword = parsePassword(accountCreation.password);
|
||||
console.log("email", accountCreation.email);
|
||||
return {
|
||||
email: parseEmail(accountCreation.email),
|
||||
password: getWhirlpoolHash(rawPassword),
|
@ -1,4 +1,4 @@
|
||||
import { IInventoryDatabase, IInventoryResponse } from "@/src/types/inventoryTypes";
|
||||
import { IInventoryDatabase, IInventoryResponse } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
|
||||
const toInventoryResponse = (inventoryDatabase: IInventoryDatabase): IInventoryResponse => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
59
src/helpers/purchaseHelpers.ts
Normal file
59
src/helpers/purchaseHelpers.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { parseBoolean, parseNumber, parseString } from "@/src/helpers/general";
|
||||
import { WeaponTypeInternal } from "@/src/services/inventoryService";
|
||||
import { IPurchaseRequest } from "@/src/types/purchaseTypes";
|
||||
import { weapons } from "@/static/data/items";
|
||||
|
||||
const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest => {
|
||||
if (!purchaseRequest || typeof purchaseRequest !== "object") {
|
||||
throw new Error("incorrect or missing purchase request data");
|
||||
}
|
||||
|
||||
if (
|
||||
"PurchaseParams" in purchaseRequest &&
|
||||
"buildLabel" in purchaseRequest &&
|
||||
purchaseRequest.PurchaseParams &&
|
||||
typeof purchaseRequest.PurchaseParams === "object" &&
|
||||
"Source" in purchaseRequest.PurchaseParams &&
|
||||
"StoreItem" in purchaseRequest.PurchaseParams &&
|
||||
"StorePage" in purchaseRequest.PurchaseParams &&
|
||||
"SearchTerm" in purchaseRequest.PurchaseParams &&
|
||||
"CurrentLocation" in purchaseRequest.PurchaseParams &&
|
||||
"Quantity" in purchaseRequest.PurchaseParams &&
|
||||
"UsePremium" in purchaseRequest.PurchaseParams &&
|
||||
"ExpectedPrice" in purchaseRequest.PurchaseParams
|
||||
) {
|
||||
return {
|
||||
PurchaseParams: {
|
||||
Source: parseNumber(purchaseRequest.PurchaseParams.Source),
|
||||
StoreItem: parseString(purchaseRequest.PurchaseParams.StoreItem),
|
||||
StorePage: parseString(purchaseRequest.PurchaseParams.StorePage),
|
||||
SearchTerm: parseString(purchaseRequest.PurchaseParams.SearchTerm),
|
||||
CurrentLocation: parseString(purchaseRequest.PurchaseParams.CurrentLocation),
|
||||
Quantity: parseNumber(purchaseRequest.PurchaseParams.Quantity),
|
||||
UsePremium: parseBoolean(purchaseRequest.PurchaseParams.UsePremium),
|
||||
ExpectedPrice: parseNumber(purchaseRequest.PurchaseParams.ExpectedPrice)
|
||||
},
|
||||
buildLabel: parseString(purchaseRequest.buildLabel)
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error("invalid purchaseRequest");
|
||||
};
|
||||
|
||||
const getWeaponType = (weaponName: string) => {
|
||||
const weaponInfo = weapons.find(i => i.uniqueName === weaponName);
|
||||
|
||||
if (!weaponInfo) {
|
||||
throw new Error(`unknown weapon ${weaponName}`);
|
||||
}
|
||||
|
||||
const weaponType = weaponInfo.productCategory as WeaponTypeInternal;
|
||||
|
||||
if (!weaponType) {
|
||||
throw new Error(`unknown weapon category for item ${weaponName}`);
|
||||
}
|
||||
|
||||
return weaponType;
|
||||
};
|
||||
|
||||
export { toPurchaseRequest, getWeaponType };
|
18
src/helpers/stringHelpers.ts
Normal file
18
src/helpers/stringHelpers.ts
Normal file
@ -0,0 +1,18 @@
|
||||
const getJSONfromString = (str: string): any => {
|
||||
const jsonSubstring = str.substring(0, str.lastIndexOf("}") + 1);
|
||||
return JSON.parse(jsonSubstring);
|
||||
};
|
||||
|
||||
export const getSubstringFromKeyword = (str: string, keyword: string): string => {
|
||||
const index = str.indexOf(keyword);
|
||||
if (index == -1) {
|
||||
throw new Error(`keyword ${keyword} not found in string ${str}`);
|
||||
}
|
||||
return str.substring(index);
|
||||
};
|
||||
|
||||
export const getSubstringFromKeywordToKeyword = (str: string, keywordBegin: string, keywordEnd: string): string => {
|
||||
const beginIndex = str.lastIndexOf(keywordBegin) + 1;
|
||||
const endIndex = str.indexOf(keywordEnd);
|
||||
return str.substring(beginIndex, endIndex + 1);
|
||||
};
|
@ -1,17 +1,13 @@
|
||||
import { Schema, model } from "mongoose";
|
||||
import { IInventoryDatabase, ISuitDatabase } from "../types/inventoryTypes";
|
||||
import { Model, Schema, SchemaType, Types, model } from "mongoose";
|
||||
import { FlavourItem, IInventoryDatabase } from "../types/inventoryTypes/inventoryTypes";
|
||||
import { Oid } from "../types/commonTypes";
|
||||
|
||||
const polaritySchema = new Schema({
|
||||
Slot: Number,
|
||||
Value: String
|
||||
});
|
||||
import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes";
|
||||
import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes";
|
||||
|
||||
const abilityOverrideSchema = new Schema({
|
||||
Ability: String,
|
||||
Index: Number
|
||||
});
|
||||
|
||||
const colorSchema = new Schema({
|
||||
t0: Number,
|
||||
t1: Number,
|
||||
@ -23,6 +19,67 @@ const colorSchema = new Schema({
|
||||
m1: Number
|
||||
});
|
||||
|
||||
const longGunConfigSchema = new Schema({
|
||||
Skins: [String],
|
||||
pricol: colorSchema,
|
||||
attcol: colorSchema,
|
||||
eyecol: colorSchema,
|
||||
sigcol: colorSchema,
|
||||
Upgrades: [String],
|
||||
Songs: [
|
||||
{
|
||||
m: String,
|
||||
b: String,
|
||||
p: String,
|
||||
s: String
|
||||
}
|
||||
],
|
||||
Name: String,
|
||||
AbilityOverride: abilityOverrideSchema,
|
||||
PvpUpgrades: [String],
|
||||
ugly: Boolean
|
||||
});
|
||||
|
||||
// longGunConfigSchema.set("toJSON", {
|
||||
// transform(_document, returnedObject: ISuitDocument) {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
||||
// returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies Oid;
|
||||
// delete returnedObject._id;
|
||||
// delete returnedObject.__v;
|
||||
// }
|
||||
// });
|
||||
|
||||
const WeaponSchema = new Schema({
|
||||
ItemType: String,
|
||||
Configs: [longGunConfigSchema],
|
||||
UpgradeVer: Number,
|
||||
XP: Number,
|
||||
Features: Number,
|
||||
Polarized: Number,
|
||||
Polarity: Schema.Types.Mixed, //todo
|
||||
FocusLens: String,
|
||||
ModSlotPurchases: Number,
|
||||
UpgradeType: Schema.Types.Mixed, //todo
|
||||
UpgradeFingerprint: String,
|
||||
ItemName: String,
|
||||
ModularParts: [String],
|
||||
UnlockLevel: Number
|
||||
});
|
||||
|
||||
WeaponSchema.set("toJSON", {
|
||||
transform(_document, returnedObject: ISuitDocument) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
||||
returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies Oid;
|
||||
delete returnedObject._id;
|
||||
delete returnedObject.__v;
|
||||
}
|
||||
});
|
||||
|
||||
const polaritySchema = new Schema({
|
||||
Slot: Number,
|
||||
Value: String
|
||||
});
|
||||
|
||||
const suitConfigSchema = new Schema({
|
||||
Skins: [String],
|
||||
pricol: colorSchema,
|
||||
@ -51,7 +108,7 @@ suitConfigSchema.set("toJSON", {
|
||||
}
|
||||
});
|
||||
|
||||
const suitSchema = new Schema({
|
||||
const suitSchema = new Schema<ISuitDatabase>({
|
||||
ItemType: String,
|
||||
Configs: [suitConfigSchema],
|
||||
UpgradeVer: Number,
|
||||
@ -66,7 +123,7 @@ const suitSchema = new Schema({
|
||||
});
|
||||
|
||||
suitSchema.set("toJSON", {
|
||||
transform(_document, returnedObject) {
|
||||
transform(_document, returnedObject: ISuitDocument) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
||||
returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies Oid;
|
||||
delete returnedObject._id;
|
||||
@ -74,7 +131,25 @@ suitSchema.set("toJSON", {
|
||||
}
|
||||
});
|
||||
|
||||
const inventorySchema = new Schema({
|
||||
const slotsBinSchema = new Schema(
|
||||
{
|
||||
Slots: Number
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const FlavourItemSchema = new Schema({
|
||||
ItemType: String
|
||||
});
|
||||
|
||||
FlavourItemSchema.set("toJSON", {
|
||||
transform(_document, returnedObject: ISuitDocument) {
|
||||
delete returnedObject._id;
|
||||
delete returnedObject.__v;
|
||||
}
|
||||
});
|
||||
|
||||
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
||||
accountOwnerId: Schema.Types.ObjectId,
|
||||
SubscribedToEmails: Number,
|
||||
Created: Schema.Types.Mixed,
|
||||
@ -83,9 +158,9 @@ const inventorySchema = new Schema({
|
||||
PremiumCredits: Number,
|
||||
PremiumCreditsFree: Number,
|
||||
FusionPoints: Number,
|
||||
SuitBin: Schema.Types.Mixed,
|
||||
WeaponBin: Schema.Types.Mixed,
|
||||
SentinelBin: Schema.Types.Mixed,
|
||||
SuitBin: slotsBinSchema,
|
||||
WeaponBin: slotsBinSchema,
|
||||
SentinelBin: slotsBinSchema,
|
||||
SpaceSuitBin: Schema.Types.Mixed,
|
||||
SpaceWeaponBin: Schema.Types.Mixed,
|
||||
PvpBonusLoadoutBin: Schema.Types.Mixed,
|
||||
@ -104,12 +179,12 @@ const inventorySchema = new Schema({
|
||||
RawUpgrades: [Schema.Types.Mixed],
|
||||
ReceivedStartingGear: Boolean,
|
||||
Suits: [suitSchema],
|
||||
LongGuns: [Schema.Types.Mixed],
|
||||
Pistols: [Schema.Types.Mixed],
|
||||
Melee: [Schema.Types.Mixed],
|
||||
LongGuns: [WeaponSchema],
|
||||
Pistols: [WeaponSchema],
|
||||
Melee: [WeaponSchema],
|
||||
Ships: [Schema.Types.Mixed],
|
||||
QuestKeys: [Schema.Types.Mixed],
|
||||
FlavourItems: [Schema.Types.Mixed],
|
||||
FlavourItems: [FlavourItemSchema],
|
||||
Scoops: [Schema.Types.Mixed],
|
||||
TrainingRetriesLeft: Number,
|
||||
LoadOutPresets: Schema.Types.Mixed,
|
||||
@ -253,7 +328,16 @@ inventorySchema.set("toJSON", {
|
||||
}
|
||||
});
|
||||
|
||||
const Suit = model<ISuitDatabase>("Suit", suitSchema);
|
||||
const Inventory = model<IInventoryDatabase>("Inventory", inventorySchema);
|
||||
type InventoryDocumentProps = {
|
||||
Suits: Types.DocumentArray<ISuitDatabase>;
|
||||
LongGuns: Types.DocumentArray<IWeaponDatabase>;
|
||||
Pistols: Types.DocumentArray<IWeaponDatabase>;
|
||||
Melee: Types.DocumentArray<IWeaponDatabase>;
|
||||
FlavourItems: Types.DocumentArray<FlavourItem>;
|
||||
};
|
||||
|
||||
export { Inventory, Suit };
|
||||
type InventoryModelType = Model<IInventoryDatabase, {}, InventoryDocumentProps>;
|
||||
|
||||
const Inventory = model<IInventoryDatabase, InventoryModelType>("Inventory", inventorySchema);
|
||||
|
||||
export { Inventory };
|
||||
|
@ -1,17 +0,0 @@
|
||||
import mongoose from "mongoose";
|
||||
|
||||
const accountSchema = new mongoose.Schema({
|
||||
data: JSON
|
||||
});
|
||||
|
||||
// personSchema.set("toJSON", {
|
||||
// transform: (document, returnedObject:) => {
|
||||
// returnedObject.id = returnedObject._id.toString();
|
||||
// delete returnedObject._id;
|
||||
// delete returnedObject.__v;
|
||||
// },
|
||||
// });
|
||||
|
||||
const Account = mongoose.model("account", accountSchema);
|
||||
|
||||
export { Account };
|
@ -28,6 +28,7 @@ import { updateChallengeProgressController } from "@/src/controllers/api/updateC
|
||||
import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController";
|
||||
import { viewController } from "@/src/controllers/api/viewController";
|
||||
import { joinSessionController } from "@/src/controllers/api/joinSessionController";
|
||||
import { saveLoadoutController } from "@/src/controllers/api/saveLoadout";
|
||||
|
||||
import express from "express";
|
||||
|
||||
@ -68,4 +69,5 @@ apiRouter.post("/missionInventoryUpdate.php", missionInventoryUpdateController);
|
||||
apiRouter.post("/genericUpdate.php", genericUpdateController);
|
||||
apiRouter.post("/rerollRandomMod.php", rerollRandomModController);
|
||||
apiRouter.post("/joinSession.php", joinSessionController);
|
||||
apiRouter.post("/saveLoadout.php", saveLoadoutController);
|
||||
export { apiRouter };
|
||||
|
@ -4,18 +4,14 @@ import config from "@/config.json";
|
||||
const cacheRouter = express.Router();
|
||||
|
||||
cacheRouter.get("/B.Cache.Dx11.bin.*", (_req, res) => {
|
||||
//console.log("asd", path.join(__dirname, "../data"));
|
||||
res.sendFile("static/data/B.Cache.Dx11_33.0.6.bin", { root: "./" });
|
||||
});
|
||||
|
||||
cacheRouter.get("/B.Cache.Windows_en.bin*", (_req, res) => {
|
||||
//console.log("asd", path.join(__dirname, "../data"));
|
||||
res.sendFile("static/data/B.Cache.Windows_en_33.0.10.bin", { root: "./" });
|
||||
});
|
||||
|
||||
cacheRouter.get(/^\/origin\/([a-zA-Z0-9]+)\/H\.Cache\.bin.*$/, (_req, res) => {
|
||||
// console.log("asd", path.join(__dirname, "../data"));
|
||||
// console.log("asd", __dirname);
|
||||
res.sendFile(`static/data/H.Cache_${config.version}.bin`, { root: "./" });
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { addItemController } from "@/src/controllers/custom/addItemController";
|
||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
||||
import express from "express";
|
||||
|
||||
const customRouter = express.Router();
|
||||
|
||||
customRouter.post("/createAccount", createAccountController);
|
||||
customRouter.post("/addItem", addItemController);
|
||||
|
||||
export { customRouter };
|
||||
|
@ -2,6 +2,9 @@ import { Inventory } from "@/src/models/inventoryModel";
|
||||
import new_inventory from "@/static/fixed_responses/postTutorialInventory.json";
|
||||
import config from "@/config.json";
|
||||
import { Types } from "mongoose";
|
||||
import { ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes";
|
||||
import { SlotType } from "@/src/types/purchaseTypes";
|
||||
import { IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes";
|
||||
|
||||
const createInventory = async (accountOwnerId: Types.ObjectId) => {
|
||||
try {
|
||||
@ -22,4 +25,84 @@ const createInventory = async (accountOwnerId: Types.ObjectId) => {
|
||||
}
|
||||
};
|
||||
|
||||
export { createInventory };
|
||||
//const updateInventory = async (accountOwnerId: Types.ObjectId, inventoryChanges: any) => {};
|
||||
|
||||
const getInventory = async (accountOwnerId: string) => {
|
||||
const inventory = await Inventory.findOne({ accountOwnerId: accountOwnerId });
|
||||
|
||||
if (!inventory) {
|
||||
throw new Error(`Didn't find an inventory for ${accountOwnerId}`);
|
||||
}
|
||||
|
||||
return inventory;
|
||||
};
|
||||
|
||||
const addPowerSuit = async (powersuitName: string, accountId: string): Promise<ISuitResponse> => {
|
||||
const inventory = await getInventory(accountId);
|
||||
const suitIndex = inventory.Suits.push({ ItemType: powersuitName, Configs: [], UpgradeVer: 101, XP: 0 });
|
||||
const changedInventory = await inventory.save();
|
||||
return changedInventory.Suits[suitIndex - 1].toJSON();
|
||||
};
|
||||
|
||||
export const updateSlots = async (slotType: SlotType, accountId: string, slots: number) => {
|
||||
const inventory = await getInventory(accountId);
|
||||
|
||||
switch (slotType) {
|
||||
case SlotType.SUIT:
|
||||
inventory.SuitBin.Slots += slots;
|
||||
break;
|
||||
case SlotType.WEAPON:
|
||||
inventory.WeaponBin.Slots += slots;
|
||||
break;
|
||||
default:
|
||||
throw new Error("invalid slot type");
|
||||
}
|
||||
await inventory.save();
|
||||
};
|
||||
|
||||
export const updateCurrency = async (price: number, usePremium: boolean, accountId: string) => {
|
||||
const currencyName = usePremium ? "PremiumCredits" : "RegularCredits";
|
||||
|
||||
const inventory = await getInventory(accountId);
|
||||
inventory[currencyName] = inventory[currencyName] - price;
|
||||
await inventory.save();
|
||||
return { [currencyName]: -price };
|
||||
};
|
||||
|
||||
export type WeaponTypeInternal = "LongGuns" | "Pistols" | "Melee";
|
||||
|
||||
export const addWeapon = async (
|
||||
weaponType: WeaponTypeInternal,
|
||||
weaponName: string,
|
||||
accountId: string
|
||||
): Promise<IWeaponResponse> => {
|
||||
const inventory = await getInventory(accountId);
|
||||
|
||||
let weaponIndex;
|
||||
switch (weaponType) {
|
||||
case "LongGuns":
|
||||
weaponIndex = inventory.LongGuns.push({ ItemType: weaponName, Configs: [], XP: 0 });
|
||||
break;
|
||||
case "Pistols":
|
||||
weaponIndex = inventory.Pistols.push({ ItemType: weaponName, Configs: [], XP: 0 });
|
||||
break;
|
||||
case "Melee":
|
||||
weaponIndex = inventory.Melee.push({ ItemType: weaponName, Configs: [], XP: 0 });
|
||||
break;
|
||||
default:
|
||||
throw new Error("unknown weapon type");
|
||||
}
|
||||
|
||||
const changedInventory = await inventory.save();
|
||||
return changedInventory[weaponType][weaponIndex - 1].toJSON();
|
||||
};
|
||||
|
||||
export const addCustomization = async (customizatonName: string, accountId: string) => {
|
||||
const inventory = await getInventory(accountId);
|
||||
|
||||
const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizatonName }) - 1;
|
||||
const changedInventory = await inventory.save();
|
||||
return changedInventory.FlavourItems[flavourItemIndex].toJSON();
|
||||
};
|
||||
|
||||
export { createInventory, addPowerSuit };
|
||||
|
110
src/services/purchaseService.ts
Normal file
110
src/services/purchaseService.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import { getWeaponType } from "@/src/helpers/purchaseHelpers";
|
||||
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
|
||||
import { 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/");
|
||||
const storeItemElements = storeItemString.split("/");
|
||||
return storeItemElements[1];
|
||||
};
|
||||
|
||||
export const getStoreItemTypesCategory = (typesItem: string) => {
|
||||
const typesString = getSubstringFromKeyword(typesItem, "Types");
|
||||
const typeElements = typesString.split("/");
|
||||
if (typesItem.includes("StoreItems")) {
|
||||
return typeElements[2];
|
||||
}
|
||||
return typeElements[1];
|
||||
};
|
||||
|
||||
export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountId: string) => {
|
||||
console.log(purchaseRequest);
|
||||
const storeCategory = getStoreItemCategory(purchaseRequest.PurchaseParams.StoreItem);
|
||||
const internalName = purchaseRequest.PurchaseParams.StoreItem.replace("/StoreItems", "");
|
||||
console.log("Store category", storeCategory);
|
||||
|
||||
let purchaseResponse;
|
||||
switch (storeCategory) {
|
||||
case "Powersuits":
|
||||
purchaseResponse = await handlePowersuitPurchase(internalName, accountId);
|
||||
break;
|
||||
case "Weapons":
|
||||
purchaseResponse = await handleWeaponsPurchase(internalName, accountId);
|
||||
break;
|
||||
case "Types":
|
||||
purchaseResponse = await handleTypesPurchase(internalName, accountId);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`unknown store category: ${storeCategory} not implemented or new`);
|
||||
}
|
||||
|
||||
// const currencyResponse = await updateCurrency(
|
||||
// purchaseRequest.PurchaseParams.ExpectedPrice,
|
||||
// purchaseRequest.PurchaseParams.UsePremium,
|
||||
// accountId
|
||||
// );
|
||||
|
||||
// (purchaseResponse as IPurchaseResponse).InventoryChanges = {
|
||||
// ...purchaseResponse.InventoryChanges,
|
||||
// ...currencyResponse
|
||||
// };
|
||||
|
||||
return purchaseResponse;
|
||||
};
|
||||
|
||||
const handleWeaponsPurchase = async (weaponName: string, accountId: string) => {
|
||||
const weaponType = getWeaponType(weaponName);
|
||||
const addedWeapon = await addWeapon(weaponType, weaponName, accountId);
|
||||
|
||||
await updateSlots(SlotType.WEAPON, accountId, -1);
|
||||
|
||||
return {
|
||||
InventoryChanges: {
|
||||
WeaponBin: { count: 1, platinum: 0, Slots: -1 },
|
||||
[weaponType]: [addedWeapon]
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handlePowersuitPurchase = async (powersuitName: string, accountId: string) => {
|
||||
const suit = await addPowerSuit(powersuitName, accountId);
|
||||
await updateSlots(SlotType.WEAPON, accountId, -1);
|
||||
|
||||
return {
|
||||
InventoryChanges: {
|
||||
SuitBin: {
|
||||
count: 1,
|
||||
platinum: 0,
|
||||
Slots: -1
|
||||
},
|
||||
Suits: [suit]
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleTypesPurchase = async (typesName: string, accountId: string) => {
|
||||
const typeCategory = getStoreItemTypesCategory(typesName);
|
||||
console.log("type category", typeCategory);
|
||||
switch (typeCategory) {
|
||||
case "SuitCustomizations":
|
||||
return await handleSuitCustomizationsPurchase(typesName, accountId);
|
||||
// case "Recipes":
|
||||
// break;
|
||||
// case "Sentinels":
|
||||
// break;
|
||||
default:
|
||||
throw new Error(`unknown Types category: ${typeCategory} not implemented or new`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSuitCustomizationsPurchase = async (customizationName: string, accountId: string) => {
|
||||
const customization = await addCustomization(customizationName, accountId);
|
||||
|
||||
return {
|
||||
InventoryChanges: {
|
||||
FlavourItems: [customization]
|
||||
}
|
||||
};
|
||||
};
|
44
src/types/inventoryTypes/SuitTypes.ts
Normal file
44
src/types/inventoryTypes/SuitTypes.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Oid } from "@/src/types/commonTypes";
|
||||
import { AbilityOverride, Color, Polarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import { Document } from "mongoose";
|
||||
|
||||
export interface ISuitDocument extends ISuitResponse, Document {}
|
||||
|
||||
export interface ISuitResponse extends ISuitDatabase {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface ISuitDatabase {
|
||||
ItemType: string;
|
||||
Configs: SuitConfig[];
|
||||
UpgradeVer?: number;
|
||||
XP?: number;
|
||||
InfestationDate?: Date;
|
||||
Features?: number;
|
||||
Polarity?: Polarity[];
|
||||
Polarized?: number;
|
||||
ModSlotPurchases?: number;
|
||||
FocusLens?: string;
|
||||
UnlockLevel?: number;
|
||||
}
|
||||
|
||||
export interface SuitConfig {
|
||||
Skins?: string[];
|
||||
pricol?: Color;
|
||||
attcol?: Color;
|
||||
eyecol?: Color;
|
||||
sigcol?: Color;
|
||||
Upgrades?: string[];
|
||||
Songs?: Song[];
|
||||
Name?: string;
|
||||
AbilityOverride?: AbilityOverride;
|
||||
PvpUpgrades?: string[];
|
||||
ugly?: boolean;
|
||||
}
|
||||
|
||||
export interface Song {
|
||||
m?: string;
|
||||
b?: string;
|
||||
p?: string;
|
||||
s: string;
|
||||
}
|
42
src/types/inventoryTypes/commonInventoryTypes.ts
Normal file
42
src/types/inventoryTypes/commonInventoryTypes.ts
Normal file
@ -0,0 +1,42 @@
|
||||
export interface Polarity {
|
||||
Slot: number;
|
||||
Value: FocusSchool;
|
||||
}
|
||||
|
||||
export enum FocusSchool {
|
||||
ApAny = "AP_ANY",
|
||||
ApAttack = "AP_ATTACK",
|
||||
ApDefense = "AP_DEFENSE",
|
||||
ApPower = "AP_POWER",
|
||||
ApPrecept = "AP_PRECEPT",
|
||||
ApTactic = "AP_TACTIC",
|
||||
ApUmbra = "AP_UMBRA",
|
||||
ApUniversal = "AP_UNIVERSAL",
|
||||
ApWard = "AP_WARD"
|
||||
}
|
||||
|
||||
export interface Color {
|
||||
t0?: number;
|
||||
t1?: number;
|
||||
t2?: number;
|
||||
t3?: number;
|
||||
en?: number;
|
||||
e1?: number;
|
||||
m0?: number;
|
||||
m1?: number;
|
||||
}
|
||||
|
||||
export interface AbilityOverride {
|
||||
Ability: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export interface SlotsBin {
|
||||
Slots: number;
|
||||
}
|
||||
|
||||
export interface sigcol {
|
||||
t0: number;
|
||||
t1: number;
|
||||
en: number;
|
||||
}
|
@ -1,12 +1,17 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import { Document, Types } from "mongoose";
|
||||
import { Oid } from "./commonTypes";
|
||||
import { Oid } from "../commonTypes";
|
||||
import { AbilityOverride, Color, FocusSchool, Polarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes";
|
||||
import { OperatorLoadOutSigcol, IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes";
|
||||
|
||||
export interface IInventoryDatabase extends IInventoryResponse {
|
||||
accountOwnerId: Types.ObjectId;
|
||||
}
|
||||
|
||||
export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {}
|
||||
|
||||
export interface IInventoryResponse {
|
||||
SubscribedToEmails: number;
|
||||
Created: Date;
|
||||
@ -36,9 +41,9 @@ export interface IInventoryResponse {
|
||||
RawUpgrades: RawUpgrade[];
|
||||
ReceivedStartingGear: boolean;
|
||||
Suits: ISuitDatabase[];
|
||||
LongGuns: LongGun[];
|
||||
Pistols: LongGun[];
|
||||
Melee: Melee[];
|
||||
LongGuns: IWeaponDatabase[];
|
||||
Pistols: IWeaponDatabase[];
|
||||
Melee: IWeaponDatabase[];
|
||||
Ships: Ship[];
|
||||
QuestKeys: QuestKey[];
|
||||
FlavourItems: FlavourItem[];
|
||||
@ -188,17 +193,6 @@ export interface AdultOperatorLoadOut {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface Color {
|
||||
t0?: number;
|
||||
t1?: number;
|
||||
t2?: number;
|
||||
t3?: number;
|
||||
en?: number;
|
||||
e1?: number;
|
||||
m0?: number;
|
||||
m1?: number;
|
||||
}
|
||||
|
||||
export interface Affiliation {
|
||||
Initiated?: boolean;
|
||||
Standing: number;
|
||||
@ -319,23 +313,6 @@ export interface CrewShipHarnessConfig {
|
||||
Upgrades?: string[];
|
||||
}
|
||||
|
||||
export interface Polarity {
|
||||
Slot: number;
|
||||
Value: FocusSchool;
|
||||
}
|
||||
|
||||
export enum FocusSchool {
|
||||
ApAny = "AP_ANY",
|
||||
ApAttack = "AP_ATTACK",
|
||||
ApDefense = "AP_DEFENSE",
|
||||
ApPower = "AP_POWER",
|
||||
ApPrecept = "AP_PRECEPT",
|
||||
ApTactic = "AP_TACTIC",
|
||||
ApUmbra = "AP_UMBRA",
|
||||
ApUniversal = "AP_UNIVERSAL",
|
||||
ApWard = "AP_WARD"
|
||||
}
|
||||
|
||||
export interface CrewShipSalvageBinClass {
|
||||
Extra: number;
|
||||
Slots: number;
|
||||
@ -359,7 +336,7 @@ export interface CrewShipWeapon {
|
||||
export interface CrewShip {
|
||||
ItemType: string;
|
||||
Configs: CrewShipConfig[];
|
||||
Weapon: Weapon;
|
||||
Weapon: CrewshipWeapon;
|
||||
Customization: Customization;
|
||||
ItemName: string;
|
||||
RailjackImage: FlavourItem;
|
||||
@ -400,7 +377,7 @@ export interface FlavourItem {
|
||||
ItemType: string;
|
||||
}
|
||||
|
||||
export interface Weapon {
|
||||
export interface CrewshipWeapon {
|
||||
PILOT: Pilot;
|
||||
PORT_GUNS: PortGuns;
|
||||
}
|
||||
@ -713,33 +690,6 @@ export interface Normal {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface LongGun {
|
||||
ItemType: string;
|
||||
Configs: LongGunConfig[];
|
||||
UpgradeVer?: number;
|
||||
XP?: number;
|
||||
Features?: number;
|
||||
ItemId: Oid;
|
||||
Polarized?: number;
|
||||
Polarity?: Polarity[];
|
||||
FocusLens?: string;
|
||||
ModSlotPurchases?: number;
|
||||
UpgradeType?: UpgradeType;
|
||||
UpgradeFingerprint?: string;
|
||||
ItemName?: string;
|
||||
ModularParts?: string[];
|
||||
UnlockLevel?: number;
|
||||
}
|
||||
|
||||
export interface LongGunConfig {
|
||||
Upgrades?: string[];
|
||||
Skins?: string[];
|
||||
pricol?: Color;
|
||||
attcol?: Color;
|
||||
PvpUpgrades?: string[];
|
||||
Name?: string;
|
||||
}
|
||||
|
||||
export enum UpgradeType {
|
||||
LotusWeaponsGrineerKuvaLichUpgradesInnateDamageRandomMod = "/Lotus/Weapons/Grineer/KuvaLich/Upgrades/InnateDamageRandomMod"
|
||||
}
|
||||
@ -774,40 +724,6 @@ export interface MechSuit {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface Melee {
|
||||
ItemType: string;
|
||||
Configs: MeleeConfig[];
|
||||
UpgradeVer?: number;
|
||||
XP?: number;
|
||||
Features?: number;
|
||||
Polarity?: Polarity[];
|
||||
Polarized?: number;
|
||||
ModSlotPurchases?: number;
|
||||
ItemId: Oid;
|
||||
FocusLens?: string;
|
||||
ModularParts?: string[];
|
||||
ItemName?: string;
|
||||
UpgradeType?: UpgradeType;
|
||||
UpgradeFingerprint?: string;
|
||||
UnlockLevel?: number;
|
||||
}
|
||||
|
||||
export interface MeleeConfig {
|
||||
Skins?: string[];
|
||||
pricol?: Color;
|
||||
Upgrades?: string[];
|
||||
attcol?: Color;
|
||||
eyecol?: OperatorLoadOutSigcol;
|
||||
Name?: string;
|
||||
PvpUpgrades?: string[];
|
||||
}
|
||||
|
||||
export interface OperatorLoadOutSigcol {
|
||||
t0?: number;
|
||||
t1?: number;
|
||||
en?: number;
|
||||
}
|
||||
|
||||
export interface Mission {
|
||||
Completes: number;
|
||||
Tier?: number;
|
||||
@ -885,11 +801,6 @@ export interface OperatorLoadOut {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface AbilityOverride {
|
||||
Ability: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export interface PendingCoupon {
|
||||
Expiry: Date;
|
||||
Discount: number;
|
||||
@ -1159,48 +1070,6 @@ export interface NotePacks {
|
||||
PERCUSSION: string;
|
||||
}
|
||||
|
||||
export interface ISuitDocument extends ISuitDatabase, Document {}
|
||||
|
||||
export interface ISuitResponse extends ISuitDatabase {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface ISuitDatabase {
|
||||
ItemType: string;
|
||||
Configs: SuitConfig[];
|
||||
UpgradeVer?: number;
|
||||
XP?: number;
|
||||
InfestationDate?: Date;
|
||||
Features?: number;
|
||||
Polarity?: Polarity[];
|
||||
Polarized?: number;
|
||||
ModSlotPurchases?: number;
|
||||
ItemId: Oid;
|
||||
FocusLens?: string;
|
||||
UnlockLevel?: number;
|
||||
}
|
||||
|
||||
export interface SuitConfig {
|
||||
Skins?: string[];
|
||||
pricol?: Color;
|
||||
attcol?: Color;
|
||||
eyecol?: Color;
|
||||
sigcol?: Color;
|
||||
Upgrades?: string[];
|
||||
Songs?: Song[];
|
||||
Name?: string;
|
||||
AbilityOverride?: AbilityOverride;
|
||||
PvpUpgrades?: string[];
|
||||
ugly?: boolean;
|
||||
}
|
||||
|
||||
export interface Song {
|
||||
m?: string;
|
||||
b?: string;
|
||||
p?: string;
|
||||
s: string;
|
||||
}
|
||||
|
||||
export interface TauntHistory {
|
||||
node: string;
|
||||
state: string;
|
39
src/types/inventoryTypes/weaponTypes.ts
Normal file
39
src/types/inventoryTypes/weaponTypes.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Oid } from "@/src/types/commonTypes";
|
||||
import { Color, Polarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||
|
||||
export interface IWeaponResponse extends IWeaponDatabase {
|
||||
ItemId: Oid;
|
||||
}
|
||||
|
||||
export interface IWeaponDatabase {
|
||||
ItemType: string;
|
||||
Configs: WeaponConfig[];
|
||||
UpgradeVer?: number;
|
||||
XP?: number;
|
||||
Features?: number;
|
||||
Polarized?: number;
|
||||
Polarity?: Polarity[];
|
||||
FocusLens?: string;
|
||||
ModSlotPurchases?: number;
|
||||
UpgradeType?: string;
|
||||
UpgradeFingerprint?: string;
|
||||
ItemName?: string;
|
||||
ModularParts?: string[];
|
||||
UnlockLevel?: number;
|
||||
}
|
||||
|
||||
export interface WeaponConfig {
|
||||
Skins?: string[];
|
||||
pricol?: Color;
|
||||
Upgrades?: string[];
|
||||
attcol?: Color;
|
||||
eyecol?: OperatorLoadOutSigcol;
|
||||
Name?: string;
|
||||
PvpUpgrades?: string[];
|
||||
}
|
||||
|
||||
export interface OperatorLoadOutSigcol {
|
||||
t0?: number;
|
||||
t1?: number;
|
||||
en?: number;
|
||||
}
|
43
src/types/purchaseTypes.ts
Normal file
43
src/types/purchaseTypes.ts
Normal file
@ -0,0 +1,43 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes";
|
||||
import { IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes";
|
||||
|
||||
export interface IPurchaseRequest {
|
||||
PurchaseParams: IPurchaseParams;
|
||||
buildLabel: string;
|
||||
}
|
||||
|
||||
export interface IPurchaseParams {
|
||||
Source: number;
|
||||
StoreItem: string;
|
||||
StorePage: string;
|
||||
SearchTerm: string;
|
||||
CurrentLocation: string;
|
||||
Quantity: number;
|
||||
UsePremium: boolean;
|
||||
ExpectedPrice: number;
|
||||
}
|
||||
|
||||
export interface IPurchaseResponse {
|
||||
InventoryChanges: {
|
||||
SuitBin?: IBinChanges;
|
||||
WeaponBin?: IBinChanges;
|
||||
Suits?: ISuitDatabase[];
|
||||
LongGuns?: IWeaponResponse[];
|
||||
Pistols?: IWeaponResponse[];
|
||||
Melee?: IWeaponResponse[];
|
||||
PremiumCredits?: number;
|
||||
RegularCredits?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export type IBinChanges = {
|
||||
count: number;
|
||||
platinum: number;
|
||||
Slots: number;
|
||||
};
|
||||
|
||||
export enum SlotType {
|
||||
SUIT = "SuitBin",
|
||||
WEAPON = "WeaponBin"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user