Merge remote-tracking branch 'upstream/main' into inventoryTypes
This commit is contained in:
commit
3dcd40dd6f
@ -16,7 +16,7 @@
|
|||||||
"unlockAllQuests": true,
|
"unlockAllQuests": true,
|
||||||
"completeAllQuests": false,
|
"completeAllQuests": false,
|
||||||
"infiniteResources": true,
|
"infiniteResources": true,
|
||||||
"unlockallShipFeatures": true,
|
"unlockAllShipFeatures": true,
|
||||||
"unlockAllShipDecorations": true,
|
"unlockAllShipDecorations": true,
|
||||||
"unlockAllFlavourItems": true,
|
"unlockAllFlavourItems": true,
|
||||||
"unlockAllSkins": true,
|
"unlockAllSkins": true,
|
||||||
|
28
package-lock.json
generated
28
package-lock.json
generated
@ -1153,12 +1153,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@ -1922,9 +1922,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
@ -2022,6 +2022,20 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { getItemByBlueprint, getItemCategoryByUniqueName } from "@/src/services/itemDataService";
|
import { getItemByBlueprint } from "@/src/services/itemDataService";
|
||||||
import { IOid } from "@/src/types/commonTypes";
|
import { IOid } from "@/src/types/commonTypes";
|
||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { getInventory } from "@/src/services/inventoryService";
|
import { getInventory, updateCurrency, addItem } from "@/src/services/inventoryService";
|
||||||
|
|
||||||
export interface IClaimCompletedRecipeRequest {
|
export interface IClaimCompletedRecipeRequest {
|
||||||
RecipeIds: IOid[];
|
RecipeIds: IOid[];
|
||||||
@ -19,12 +19,10 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
|
|||||||
const accountId = await getAccountIdForRequest(req);
|
const accountId = await getAccountIdForRequest(req);
|
||||||
if (!accountId) throw new Error("no account id");
|
if (!accountId) throw new Error("no account id");
|
||||||
|
|
||||||
console.log(claimCompletedRecipeRequest);
|
|
||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
const pendingRecipe = inventory.PendingRecipes.find(
|
const pendingRecipe = inventory.PendingRecipes.find(
|
||||||
recipe => recipe._id?.toString() === claimCompletedRecipeRequest.RecipeIds[0].$oid
|
recipe => recipe._id?.toString() === claimCompletedRecipeRequest.RecipeIds[0].$oid
|
||||||
);
|
);
|
||||||
console.log(pendingRecipe);
|
|
||||||
if (!pendingRecipe) {
|
if (!pendingRecipe) {
|
||||||
logger.error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
|
logger.error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
|
||||||
throw new Error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
|
throw new Error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
|
||||||
@ -36,29 +34,29 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
|
|||||||
// throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
|
// throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//get completed Items
|
inventory.PendingRecipes.pull(pendingRecipe._id);
|
||||||
const completedItemName = getItemByBlueprint(pendingRecipe.ItemType)?.uniqueName;
|
await inventory.save();
|
||||||
|
|
||||||
if (!completedItemName) {
|
const buildable = getItemByBlueprint(pendingRecipe.ItemType);
|
||||||
|
if (!buildable) {
|
||||||
logger.error(`no completed item found for recipe ${pendingRecipe._id}`);
|
logger.error(`no completed item found for recipe ${pendingRecipe._id}`);
|
||||||
throw new Error(`no completed item found for recipe ${pendingRecipe._id}`);
|
throw new Error(`no completed item found for recipe ${pendingRecipe._id}`);
|
||||||
}
|
}
|
||||||
const itemCategory = getItemCategoryByUniqueName(completedItemName) as keyof typeof inventory;
|
|
||||||
console.log(itemCategory);
|
|
||||||
//TODO: remove all Schema.Mixed for inventory[itemCategory] not to be any
|
|
||||||
//add item
|
|
||||||
//inventory[itemCategory].
|
|
||||||
|
|
||||||
//add additional item components like mods or weapons for a sentinel.
|
if (req.query.cancel) {
|
||||||
//const additionalItemComponents = itemComponents[uniqueName]
|
// TODO: Refund items
|
||||||
//add these items to inventory
|
res.json({});
|
||||||
//return changes as InventoryChanges
|
} else {
|
||||||
|
logger.debug("Claiming Recipe", { buildable, pendingRecipe });
|
||||||
//remove pending recipe
|
let currencyChanges = {};
|
||||||
inventory.PendingRecipes.pull(pendingRecipe._id);
|
if (req.query.rush && buildable.skipBuildTimePrice) {
|
||||||
// await inventory.save();
|
currencyChanges = await updateCurrency(buildable.skipBuildTimePrice, true, accountId);
|
||||||
|
}
|
||||||
logger.debug("Claiming Completed Recipe", { completedItemName });
|
res.json({
|
||||||
|
InventoryChanges: {
|
||||||
res.json({ InventoryChanges: {} });
|
...currencyChanges,
|
||||||
|
...(await addItem(accountId, buildable.uniqueName, buildable.buildQuantity)).InventoryChanges
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -31,7 +31,7 @@ export const getShipController: RequestHandler = async (req, res) => {
|
|||||||
Apartment: personalRooms.Apartment
|
Apartment: personalRooms.Apartment
|
||||||
};
|
};
|
||||||
|
|
||||||
if (config.unlockallShipFeatures) {
|
if (config.unlockAllShipFeatures) {
|
||||||
getShipResponse.Ship.Features = allShipFeatures;
|
getShipResponse.Ship.Features = allShipFeatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
|
|||||||
import { updateCurrency } from "@/src/services/inventoryService";
|
import { updateCurrency } from "@/src/services/inventoryService";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { updateSlots } from "@/src/services/inventoryService";
|
import { updateSlots } from "@/src/services/inventoryService";
|
||||||
import { SlotNameToInventoryName } from "@/src/types/purchaseTypes";
|
import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
loadout slots are additionally purchased slots only
|
loadout slots are additionally purchased slots only
|
||||||
@ -28,7 +28,7 @@ export const inventorySlotsController: RequestHandler = async (req, res) => {
|
|||||||
//TODO: check which slot was purchased because pvpBonus is also possible
|
//TODO: check which slot was purchased because pvpBonus is also possible
|
||||||
|
|
||||||
const currencyChanges = await updateCurrency(20, true, accountId);
|
const currencyChanges = await updateCurrency(20, true, accountId);
|
||||||
await updateSlots(accountId, SlotNameToInventoryName.LOADOUT, 1, 1);
|
await updateSlots(accountId, InventorySlot.PVE_LOADOUTS, 1, 1);
|
||||||
|
|
||||||
//console.log({ InventoryChanges: currencyChanges }, " added loadout changes:");
|
//console.log({ InventoryChanges: currencyChanges }, " added loadout changes:");
|
||||||
|
|
||||||
|
8
src/controllers/custom/getConfigDataController.ts
Normal file
8
src/controllers/custom/getConfigDataController.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { RequestHandler } from "express";
|
||||||
|
import { config } from "@/src/services/configService";
|
||||||
|
|
||||||
|
const getConfigDataController: RequestHandler = (_req, res) => {
|
||||||
|
res.json(config);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getConfigDataController };
|
9
src/controllers/custom/updateConfigDataController.ts
Normal file
9
src/controllers/custom/updateConfigDataController.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { RequestHandler } from "express";
|
||||||
|
import { updateConfig } from "@/src/services/configService";
|
||||||
|
|
||||||
|
const updateConfigDataController: RequestHandler = async (req, res) => {
|
||||||
|
await updateConfig(req.body.toString());
|
||||||
|
res.end();
|
||||||
|
};
|
||||||
|
|
||||||
|
export { updateConfigDataController };
|
@ -2,6 +2,8 @@ import express from "express";
|
|||||||
import { getItemListsController } from "@/src/controllers/custom/getItemListsController";
|
import { getItemListsController } from "@/src/controllers/custom/getItemListsController";
|
||||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
||||||
import { addItemController } from "@/src/controllers/custom/addItemController";
|
import { addItemController } from "@/src/controllers/custom/addItemController";
|
||||||
|
import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController";
|
||||||
|
import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController";
|
||||||
|
|
||||||
const customRouter = express.Router();
|
const customRouter = express.Router();
|
||||||
|
|
||||||
@ -10,4 +12,7 @@ customRouter.get("/getItemLists", getItemListsController);
|
|||||||
customRouter.post("/createAccount", createAccountController);
|
customRouter.post("/createAccount", createAccountController);
|
||||||
customRouter.post("/addItem", addItemController);
|
customRouter.post("/addItem", addItemController);
|
||||||
|
|
||||||
|
customRouter.get("/config", getConfigDataController);
|
||||||
|
customRouter.post("/config", updateConfigDataController);
|
||||||
|
|
||||||
export { customRouter };
|
export { customRouter };
|
||||||
|
@ -19,6 +19,9 @@ webuiRouter.use("/webui", (req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Serve virtual routes
|
// Serve virtual routes
|
||||||
|
webuiRouter.get("/webui/settings", (_req, res) => {
|
||||||
|
res.sendFile(path.join(rootDir, "static/webui/index.html"));
|
||||||
|
});
|
||||||
webuiRouter.get("/webui/inventory", (_req, res) => {
|
webuiRouter.get("/webui/inventory", (_req, res) => {
|
||||||
res.sendFile(path.join(rootDir, "static/webui/index.html"));
|
res.sendFile(path.join(rootDir, "static/webui/index.html"));
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,22 @@
|
|||||||
import rawConfig from "@/config.json";
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
import fsPromises from "fs/promises";
|
||||||
|
import { logger } from "@/src/utils/logger";
|
||||||
|
|
||||||
|
const rootDir = path.join(__dirname, "../..");
|
||||||
|
const repoDir = path.basename(rootDir) == "build" ? path.join(rootDir, "..") : rootDir;
|
||||||
|
const configPath = path.join(repoDir, "config.json");
|
||||||
|
export const config: IConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
||||||
|
|
||||||
|
let amnesia = false;
|
||||||
|
fs.watchFile(configPath, () => {
|
||||||
|
if (amnesia) {
|
||||||
|
amnesia = false;
|
||||||
|
} else {
|
||||||
|
logger.info("Detected a change to config.json, reloading its contents.");
|
||||||
|
Object.assign(config, JSON.parse(fs.readFileSync(configPath, "utf-8")));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
interface IConfig {
|
interface IConfig {
|
||||||
mongodbUrl: string;
|
mongodbUrl: string;
|
||||||
@ -14,7 +32,7 @@ interface IConfig {
|
|||||||
unlockAllQuests?: boolean;
|
unlockAllQuests?: boolean;
|
||||||
completeAllQuests?: boolean;
|
completeAllQuests?: boolean;
|
||||||
infiniteResources?: boolean;
|
infiniteResources?: boolean;
|
||||||
unlockallShipFeatures?: boolean;
|
unlockAllShipFeatures?: boolean;
|
||||||
unlockAllShipDecorations?: boolean;
|
unlockAllShipDecorations?: boolean;
|
||||||
unlockAllFlavourItems?: boolean;
|
unlockAllFlavourItems?: boolean;
|
||||||
unlockAllSkins?: boolean;
|
unlockAllSkins?: boolean;
|
||||||
@ -26,4 +44,7 @@ interface ILoggerConfig {
|
|||||||
level: string; // "fatal" | "error" | "warn" | "info" | "http" | "debug" | "trace";
|
level: string; // "fatal" | "error" | "warn" | "info" | "http" | "debug" | "trace";
|
||||||
}
|
}
|
||||||
|
|
||||||
export const config: IConfig = rawConfig;
|
export const updateConfig = async (data: string) => {
|
||||||
|
amnesia = true;
|
||||||
|
return await fsPromises.writeFile(configPath, data);
|
||||||
|
};
|
||||||
|
@ -12,7 +12,8 @@ import {
|
|||||||
IMission,
|
IMission,
|
||||||
IRawUpgrade,
|
IRawUpgrade,
|
||||||
ISeasonChallenge,
|
ISeasonChallenge,
|
||||||
ITypeCount
|
ITypeCount,
|
||||||
|
InventorySlot
|
||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IGenericUpdate } from "../types/genericUpdate";
|
import { IGenericUpdate } from "../types/genericUpdate";
|
||||||
import {
|
import {
|
||||||
@ -22,7 +23,7 @@ import {
|
|||||||
IUpdateChallengeProgressRequest
|
IUpdateChallengeProgressRequest
|
||||||
} from "../types/requestTypes";
|
} from "../types/requestTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { WeaponTypeInternal, getExalted } from "@/src/services/itemDataService";
|
import { WeaponTypeInternal, getWeaponType, getExalted } from "@/src/services/itemDataService";
|
||||||
import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
|
import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
|
||||||
import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes";
|
import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes";
|
||||||
|
|
||||||
@ -64,6 +65,132 @@ export const getInventory = async (accountOwnerId: string) => {
|
|||||||
return inventory;
|
return inventory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addItem = async (
|
||||||
|
accountId: string,
|
||||||
|
typeName: string,
|
||||||
|
quantity: number = 1
|
||||||
|
): Promise<{ InventoryChanges: object }> => {
|
||||||
|
switch (typeName.substr(1).split("/")[1]) {
|
||||||
|
case "Powersuits":
|
||||||
|
if (typeName.includes("EntratiMech")) {
|
||||||
|
const mechSuit = await addMechSuit(typeName, accountId);
|
||||||
|
await updateSlots(accountId, InventorySlot.MECHSUITS, 0, 1);
|
||||||
|
logger.debug("mech suit", mechSuit);
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
MechBin: {
|
||||||
|
count: 1,
|
||||||
|
platinum: 0,
|
||||||
|
Slots: -1
|
||||||
|
},
|
||||||
|
MechSuits: [mechSuit]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const suit = await addPowerSuit(typeName, accountId);
|
||||||
|
await updateSlots(accountId, InventorySlot.SUITS, 0, 1);
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
SuitBin: {
|
||||||
|
count: 1,
|
||||||
|
platinum: 0,
|
||||||
|
Slots: -1
|
||||||
|
},
|
||||||
|
Suits: [suit]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case "Weapons":
|
||||||
|
const weaponType = getWeaponType(typeName);
|
||||||
|
const weapon = await addWeapon(weaponType, typeName, accountId);
|
||||||
|
await updateSlots(accountId, InventorySlot.WEAPONS, 0, 1);
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
WeaponBin: { count: 1, platinum: 0, Slots: -1 },
|
||||||
|
[weaponType]: [weapon]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case "Interface":
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
FlavourItems: [await addCustomization(typeName, accountId)]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case "Types":
|
||||||
|
switch (typeName.substr(1).split("/")[2]) {
|
||||||
|
case "AvatarImages":
|
||||||
|
case "SuitCustomizations":
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
FlavourItems: [await addCustomization(typeName, accountId)]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case "Sentinels":
|
||||||
|
// TOOD: Sentinels should also grant their DefaultUpgrades & SentinelWeapon.
|
||||||
|
const sentinel = await addSentinel(typeName, accountId);
|
||||||
|
await updateSlots(accountId, InventorySlot.SENTINELS, 0, 1);
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
SentinelBin: { count: 1, platinum: 0, Slots: -1 },
|
||||||
|
Sentinels: [sentinel]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case "Items": {
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
const miscItemChanges = [
|
||||||
|
{
|
||||||
|
ItemType: typeName,
|
||||||
|
ItemCount: quantity
|
||||||
|
} satisfies IMiscItem
|
||||||
|
];
|
||||||
|
addMiscItems(inventory, miscItemChanges);
|
||||||
|
await inventory.save();
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
MiscItems: miscItemChanges
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "Recipes":
|
||||||
|
case "Consumables": {
|
||||||
|
// Blueprints for Ciphers, Antitoxins
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
const recipeChanges = [
|
||||||
|
{
|
||||||
|
ItemType: typeName,
|
||||||
|
ItemCount: quantity
|
||||||
|
} satisfies ITypeCount
|
||||||
|
];
|
||||||
|
addRecipes(inventory, recipeChanges);
|
||||||
|
await inventory.save();
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
Recipes: recipeChanges
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "Restoratives": // Codex Scanner, Remote Observer, Starburst
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
const consumablesChanges = [
|
||||||
|
{
|
||||||
|
ItemType: typeName,
|
||||||
|
ItemCount: quantity
|
||||||
|
} satisfies IConsumable
|
||||||
|
];
|
||||||
|
addConsumables(inventory, consumablesChanges);
|
||||||
|
await inventory.save();
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
Consumables: consumablesChanges
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const errorMessage = `unable to add item: ${typeName}`;
|
||||||
|
logger.error(errorMessage);
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
};
|
||||||
|
|
||||||
//TODO: maybe genericMethod for all the add methods, they share a lot of logic
|
//TODO: maybe genericMethod for all the add methods, they share a lot of logic
|
||||||
export const addSentinel = async (sentinelName: string, accountId: string) => {
|
export const addSentinel = async (sentinelName: string, accountId: string) => {
|
||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
|
@ -1,22 +1,7 @@
|
|||||||
import { parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
|
import { parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
|
||||||
import { getWeaponType } from "@/src/services/itemDataService";
|
|
||||||
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
|
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
|
||||||
import {
|
import { addItem, addBooster, updateCurrency, updateSlots } from "@/src/services/inventoryService";
|
||||||
addBooster,
|
import { IPurchaseRequest, SlotPurchase } from "@/src/types/purchaseTypes";
|
||||||
addConsumables,
|
|
||||||
addCustomization,
|
|
||||||
addMechSuit,
|
|
||||||
addMiscItems,
|
|
||||||
addPowerSuit,
|
|
||||||
addRecipes,
|
|
||||||
addSentinel,
|
|
||||||
addWeapon,
|
|
||||||
getInventory,
|
|
||||||
updateCurrency,
|
|
||||||
updateSlots
|
|
||||||
} from "@/src/services/inventoryService";
|
|
||||||
import { IConsumable, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
|
|
||||||
import { IPurchaseRequest, IPurchaseResponse, SlotNameToInventoryName, SlotPurchase } from "@/src/types/purchaseTypes";
|
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
|
|
||||||
export const getStoreItemCategory = (storeItem: string) => {
|
export const getStoreItemCategory = (storeItem: string) => {
|
||||||
@ -40,34 +25,24 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI
|
|||||||
const internalName = purchaseRequest.PurchaseParams.StoreItem.replace("/StoreItems", "");
|
const internalName = purchaseRequest.PurchaseParams.StoreItem.replace("/StoreItems", "");
|
||||||
logger.debug(`store category ${storeCategory}`);
|
logger.debug(`store category ${storeCategory}`);
|
||||||
|
|
||||||
let inventoryChanges;
|
let purchaseResponse;
|
||||||
switch (storeCategory) {
|
switch (storeCategory) {
|
||||||
case "Powersuits":
|
default:
|
||||||
inventoryChanges = await handlePowersuitPurchase(internalName, accountId);
|
purchaseResponse = await addItem(accountId, internalName);
|
||||||
break;
|
|
||||||
case "Weapons":
|
|
||||||
inventoryChanges = await handleWeaponsPurchase(internalName, accountId);
|
|
||||||
break;
|
break;
|
||||||
case "Types":
|
case "Types":
|
||||||
inventoryChanges = await handleTypesPurchase(
|
purchaseResponse = await handleTypesPurchase(
|
||||||
internalName,
|
internalName,
|
||||||
accountId,
|
accountId,
|
||||||
purchaseRequest.PurchaseParams.Quantity
|
purchaseRequest.PurchaseParams.Quantity
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "Boosters":
|
case "Boosters":
|
||||||
inventoryChanges = await handleBoostersPurchase(internalName, accountId);
|
purchaseResponse = await handleBoostersPurchase(internalName, accountId);
|
||||||
break;
|
break;
|
||||||
case "Interface":
|
|
||||||
inventoryChanges = await handleCustomizationPurchase(internalName, accountId);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
const errorMessage = `unknown store category: ${storeCategory} not implemented or new`;
|
|
||||||
logger.error(errorMessage);
|
|
||||||
throw new Error(errorMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inventoryChanges) throw new Error("purchase response was undefined");
|
if (!purchaseResponse) throw new Error("purchase response was undefined");
|
||||||
|
|
||||||
const currencyChanges = await updateCurrency(
|
const currencyChanges = await updateCurrency(
|
||||||
purchaseRequest.PurchaseParams.ExpectedPrice,
|
purchaseRequest.PurchaseParams.ExpectedPrice,
|
||||||
@ -75,12 +50,12 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI
|
|||||||
accountId
|
accountId
|
||||||
);
|
);
|
||||||
|
|
||||||
inventoryChanges.InventoryChanges = {
|
purchaseResponse.InventoryChanges = {
|
||||||
...currencyChanges,
|
...currencyChanges,
|
||||||
...inventoryChanges.InventoryChanges
|
...purchaseResponse.InventoryChanges
|
||||||
};
|
};
|
||||||
|
|
||||||
return inventoryChanges;
|
return purchaseResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const slotPurchaseNameToSlotName: SlotPurchase = {
|
export const slotPurchaseNameToSlotName: SlotPurchase = {
|
||||||
@ -126,102 +101,18 @@ const handleSlotPurchase = async (slotPurchaseNameFull: string, accountId: strin
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleWeaponsPurchase = async (weaponName: string, accountId: string) => {
|
|
||||||
const weaponType = getWeaponType(weaponName);
|
|
||||||
const addedWeapon = await addWeapon(weaponType, weaponName, accountId);
|
|
||||||
|
|
||||||
await updateSlots(accountId, SlotNameToInventoryName.WEAPON, 0, 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
WeaponBin: { count: 1, platinum: 0, Slots: -1 },
|
|
||||||
[weaponType]: [addedWeapon]
|
|
||||||
}
|
|
||||||
} as IPurchaseResponse;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePowersuitPurchase = async (powersuitName: string, accountId: string) => {
|
|
||||||
if (powersuitName.includes("EntratiMech")) {
|
|
||||||
const mechSuit = await addMechSuit(powersuitName, accountId);
|
|
||||||
|
|
||||||
await updateSlots(accountId, SlotNameToInventoryName.MECHSUIT, 0, 1);
|
|
||||||
logger.debug("mech suit", mechSuit);
|
|
||||||
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
MechBin: {
|
|
||||||
count: 1,
|
|
||||||
platinum: 0,
|
|
||||||
Slots: -1
|
|
||||||
},
|
|
||||||
MechSuits: [mechSuit]
|
|
||||||
}
|
|
||||||
} as IPurchaseResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
const suit = await addPowerSuit(powersuitName, accountId);
|
|
||||||
await updateSlots(accountId, SlotNameToInventoryName.SUIT, 0, 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
SuitBin: {
|
|
||||||
count: 1,
|
|
||||||
platinum: 0,
|
|
||||||
Slots: -1
|
|
||||||
},
|
|
||||||
Suits: [suit]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//TODO: change to getInventory, apply changes then save at the end
|
//TODO: change to getInventory, apply changes then save at the end
|
||||||
const handleTypesPurchase = async (typesName: string, accountId: string, quantity: number) => {
|
const handleTypesPurchase = async (typesName: string, accountId: string, quantity: number) => {
|
||||||
const typeCategory = getStoreItemTypesCategory(typesName);
|
const typeCategory = getStoreItemTypesCategory(typesName);
|
||||||
logger.debug(`type category ${typeCategory}`);
|
logger.debug(`type category ${typeCategory}`);
|
||||||
switch (typeCategory) {
|
switch (typeCategory) {
|
||||||
case "AvatarImages":
|
default:
|
||||||
case "SuitCustomizations":
|
return await addItem(accountId, typesName, quantity);
|
||||||
return await handleCustomizationPurchase(typesName, accountId);
|
|
||||||
case "Sentinels":
|
|
||||||
return await handleSentinelPurchase(typesName, accountId);
|
|
||||||
case "SlotItems":
|
case "SlotItems":
|
||||||
return await handleSlotPurchase(typesName, accountId);
|
return await handleSlotPurchase(typesName, accountId);
|
||||||
case "Items":
|
|
||||||
return await handleMiscItemPurchase(typesName, accountId, quantity);
|
|
||||||
case "Recipes":
|
|
||||||
case "Consumables": // Blueprints for Ciphers, Antitoxins
|
|
||||||
return await handleRecipesPurchase(typesName, accountId, quantity);
|
|
||||||
case "Restoratives": // Codex Scanner, Remote Observer, Starburst
|
|
||||||
return await handleRestorativesPurchase(typesName, accountId, quantity);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error(`unknown Types category: ${typeCategory} not implemented or new`);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSentinelPurchase = async (sentinelName: string, accountId: string) => {
|
|
||||||
const sentinel = await addSentinel(sentinelName, accountId);
|
|
||||||
|
|
||||||
await updateSlots(accountId, SlotNameToInventoryName.SENTINEL, 0, 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
SentinelBin: { count: 1, platinum: 0, Slots: -1 },
|
|
||||||
Sentinels: [sentinel]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCustomizationPurchase = async (customizationName: string, accountId: string) => {
|
|
||||||
const customization = await addCustomization(customizationName, accountId);
|
|
||||||
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
FlavourItems: [customization]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const boosterCollection = [
|
const boosterCollection = [
|
||||||
"/Lotus/Types/Boosters/ResourceAmountBooster",
|
"/Lotus/Types/Boosters/ResourceAmountBooster",
|
||||||
"/Lotus/Types/Boosters/AffinityBooster",
|
"/Lotus/Types/Boosters/AffinityBooster",
|
||||||
@ -247,54 +138,3 @@ const handleBoostersPurchase = async (boosterStoreName: string, accountId: strin
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMiscItemPurchase = async (uniqueName: string, accountId: string, quantity: number) => {
|
|
||||||
const inventory = await getInventory(accountId);
|
|
||||||
const miscItemChanges = [
|
|
||||||
{
|
|
||||||
ItemType: uniqueName,
|
|
||||||
ItemCount: quantity
|
|
||||||
} satisfies IMiscItem
|
|
||||||
];
|
|
||||||
addMiscItems(inventory, miscItemChanges);
|
|
||||||
await inventory.save();
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
MiscItems: miscItemChanges
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRecipesPurchase = async (uniqueName: string, accountId: string, quantity: number) => {
|
|
||||||
const inventory = await getInventory(accountId);
|
|
||||||
const recipeChanges = [
|
|
||||||
{
|
|
||||||
ItemType: uniqueName,
|
|
||||||
ItemCount: quantity
|
|
||||||
} satisfies ITypeCount
|
|
||||||
];
|
|
||||||
addRecipes(inventory, recipeChanges);
|
|
||||||
await inventory.save();
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
Recipes: recipeChanges
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRestorativesPurchase = async (uniqueName: string, accountId: string, quantity: number) => {
|
|
||||||
const inventory = await getInventory(accountId);
|
|
||||||
const consumablesChanges = [
|
|
||||||
{
|
|
||||||
ItemType: uniqueName,
|
|
||||||
ItemCount: quantity
|
|
||||||
} satisfies IConsumable
|
|
||||||
];
|
|
||||||
addConsumables(inventory, consumablesChanges);
|
|
||||||
await inventory.save();
|
|
||||||
return {
|
|
||||||
InventoryChanges: {
|
|
||||||
Consumables: consumablesChanges
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
@ -367,6 +367,14 @@ export interface ICrewShipHarness {
|
|||||||
ItemId: IOid;
|
ItemId: IOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum InventorySlot {
|
||||||
|
SUITS = "SuitBin",
|
||||||
|
WEAPONS = "WeaponBin",
|
||||||
|
MECHSUITS = "MechBin",
|
||||||
|
PVE_LOADOUTS = "PveBonusLoadoutBin",
|
||||||
|
SENTINELS = "SentinelBin"
|
||||||
|
}
|
||||||
|
|
||||||
export interface ISlots {
|
export interface ISlots {
|
||||||
Extra: number; // can be undefined, but not if used via mongoose
|
Extra: number; // can be undefined, but not if used via mongoose
|
||||||
Slots: number;
|
Slots: number;
|
||||||
|
@ -41,14 +41,6 @@ export type IBinChanges = {
|
|||||||
Extra?: number;
|
Extra?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum SlotNameToInventoryName {
|
|
||||||
SUIT = "SuitBin",
|
|
||||||
WEAPON = "WeaponBin",
|
|
||||||
MECHSUIT = "MechBin",
|
|
||||||
LOADOUT = "PveBonusLoadoutBin",
|
|
||||||
SENTINEL = "SentinelBin"
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SlotPurchaseName =
|
export type SlotPurchaseName =
|
||||||
| "SuitSlotItem"
|
| "SuitSlotItem"
|
||||||
| "TwoSentinelSlotItem"
|
| "TwoSentinelSlotItem"
|
||||||
|
@ -67,15 +67,21 @@
|
|||||||
Mods
|
Mods
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link"
|
||||||
|
href="/webui/settings"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
data-bs-target="#sidebar"
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p id="refresh-note" class="mb-4">
|
|
||||||
Note: Changes made here will only be reflected in-game when the game re-downloads your inventory.
|
|
||||||
Visiting the navigation should be the easiest way to trigger that.
|
|
||||||
</p>
|
|
||||||
<div data-route="/webui/" data-title="Login | OpenWF WebUI">
|
<div data-route="/webui/" data-title="Login | OpenWF WebUI">
|
||||||
<p>Login using your OpenWF account credentials.</p>
|
<p>Login using your OpenWF account credentials.</p>
|
||||||
<form onsubmit="doLogin();return false;">
|
<form onsubmit="doLogin();return false;">
|
||||||
@ -89,6 +95,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
|
<div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
|
||||||
|
<p id="refresh-note" class="mb-4">
|
||||||
|
Note: Changes made here will only be reflected in-game when the game re-downloads your
|
||||||
|
inventory. Visiting the navigation should be the easiest way to trigger that.
|
||||||
|
</p>
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<h5 class="card-header">Add Items</h5>
|
<h5 class="card-header">Add Items</h5>
|
||||||
<form class="card-body input-group" onsubmit="doAcquireMiscItems();return false;">
|
<form class="card-body input-group" onsubmit="doAcquireMiscItems();return false;">
|
||||||
@ -133,6 +143,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div data-route="/webui/mods" data-title="Mods | OpenWF WebUI">
|
<div data-route="/webui/mods" data-title="Mods | OpenWF WebUI">
|
||||||
|
<p id="refresh-note" class="mb-4">
|
||||||
|
Note: Changes made here will only be reflected in-game when the game re-downloads your
|
||||||
|
inventory. Visiting the navigation should be the easiest way to trigger that.
|
||||||
|
</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xxl-6">
|
<div class="col-xxl-6">
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
@ -189,6 +203,65 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div data-route="/webui/settings" data-title="Settings | OpenWF WebUI">
|
||||||
|
<form onsubmit="doChangeSettings();return false;">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="skipStoryModeChoice" />
|
||||||
|
<label class="form-check-label" for="skipStoryModeChoice">Skip Story Mode Choice</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="skipTutorial" />
|
||||||
|
<label class="form-check-label" for="skipTutorial">Skip Tutorial</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllScans" />
|
||||||
|
<label class="form-check-label" for="unlockAllScans">Unlock All Scans</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllMissions" />
|
||||||
|
<label class="form-check-label" for="unlockAllMissions">Unlock All Missions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllQuests" />
|
||||||
|
<label class="form-check-label" for="unlockAllQuests">Unlock All Quests</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="completeAllQuests" />
|
||||||
|
<label class="form-check-label" for="completeAllQuests">Complete All Quests</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="infiniteResources" />
|
||||||
|
<label class="form-check-label" for="infiniteResources"
|
||||||
|
>Infinite Credits and Platinum</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" />
|
||||||
|
<label class="form-check-label" for="unlockAllShipFeatures">Unlock All Ship Features</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllShipDecorations" />
|
||||||
|
<label class="form-check-label" for="unlockAllShipDecorations"
|
||||||
|
>Unlock All Ship Decorations</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllFlavourItems" />
|
||||||
|
<label class="form-check-label" for="unlockAllFlavourItems">Unlock All Accessories</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="unlockAllSkins" />
|
||||||
|
<label class="form-check-label" for="unlockAllSkins">Unlock All Skins</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="spoofMasteryRank"
|
||||||
|
>Spoofed Mastery Rank (-1 to disable)</label
|
||||||
|
>
|
||||||
|
<input class="form-control" id="spoofMasteryRank" type="number" min="-1" />
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary mt-3" type="submit">Save Settings</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<datalist id="datalist-warframes"></datalist>
|
<datalist id="datalist-warframes"></datalist>
|
||||||
|
@ -15,6 +15,7 @@ function loginFromLocalStorage() {
|
|||||||
window.accountId = data.id;
|
window.accountId = data.id;
|
||||||
window.authz = "accountId=" + data.id + "&nonce=" + data.Nonce;
|
window.authz = "accountId=" + data.id + "&nonce=" + data.Nonce;
|
||||||
updateInventory();
|
updateInventory();
|
||||||
|
fetchSettings();
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
logout();
|
logout();
|
||||||
@ -102,7 +103,10 @@ window.itemListPromise = new Promise(resolve => {
|
|||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
if (item.uniqueName in data.badItems) {
|
if (item.uniqueName in data.badItems) {
|
||||||
item.name += " (Imposter)";
|
item.name += " (Imposter)";
|
||||||
} else if (item.uniqueName.substr(0, 18) != "/Lotus/Types/Game/") {
|
} else if (
|
||||||
|
item.uniqueName.substr(0, 18) != "/Lotus/Types/Game/" &&
|
||||||
|
item.uniqueName.substr(0, 18) != "/Lotus/StoreItems/"
|
||||||
|
) {
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.setAttribute("data-key", item.uniqueName);
|
option.setAttribute("data-key", item.uniqueName);
|
||||||
option.value = item.name;
|
option.value = item.name;
|
||||||
@ -615,3 +619,49 @@ function doAcquireMod() {
|
|||||||
$("#mod-to-acquire").on("input", () => {
|
$("#mod-to-acquire").on("input", () => {
|
||||||
$("#mod-to-acquire").removeClass("is-invalid");
|
$("#mod-to-acquire").removeClass("is-invalid");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function fetchSettings() {
|
||||||
|
fetch("/custom/config")
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json =>
|
||||||
|
Object.entries(json).forEach(entry => {
|
||||||
|
const [key, value] = entry;
|
||||||
|
var x = document.getElementById(`${key}`);
|
||||||
|
if (x != null) {
|
||||||
|
if (x.type == "checkbox") {
|
||||||
|
if (value === true) {
|
||||||
|
x.setAttribute("checked", "checked");
|
||||||
|
}
|
||||||
|
} else if (x.type == "number") {
|
||||||
|
x.setAttribute("value", `${value}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doChangeSettings() {
|
||||||
|
fetch("/custom/config")
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
for (var i in json) {
|
||||||
|
var x = document.getElementById(`${i}`);
|
||||||
|
if (x != null) {
|
||||||
|
if (x.type == "checkbox") {
|
||||||
|
if (x.checked === true) {
|
||||||
|
json[i] = true;
|
||||||
|
} else {
|
||||||
|
json[i] = false;
|
||||||
|
}
|
||||||
|
} else if (x.type == "number") {
|
||||||
|
json[i] = parseInt(x.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.post({
|
||||||
|
url: "/custom/config",
|
||||||
|
contentType: "text/plain",
|
||||||
|
data: JSON.stringify(json, null, 2)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user