diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..7a1b6292 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,17 @@ +## In General + +### Prerequisites + +Use `npm i` or `npm ci` to install all dependencies. + +### Testing + +Use `npm run verify` to verify that your changes pass TypeScript's checks. + +### Formatting + +Use `npm run prettier` to ensure your formatting matches the expected format. Failing to do so will cause CI failure. + +## WebUI Specific + +The translation system is designed around additions being made to `static/webui/translations/en.js`. They are copied over for translation via `npm run update-translations`. DO NOT produce non-English strings; we want them to be translated by humans who can understand the full context. diff --git a/config.json.example b/config.json.example index a92e3f8d..37300e0c 100644 --- a/config.json.example +++ b/config.json.example @@ -13,7 +13,6 @@ "skipTutorial": false, "skipAllDialogue": false, "unlockAllScans": false, - "unlockAllMissions": false, "infiniteCredits": false, "infinitePlatinum": false, "infiniteEndo": false, @@ -39,9 +38,10 @@ "noDailyFocusLimit": false, "noArgonCrystalDecay": false, "noMasteryRankUpCooldown": false, - "noVendorPurchaseLimits": true, + "noVendorPurchaseLimits": false, "noDeathMarks": false, "noKimCooldowns": false, + "fullyStockedVendors": false, "syndicateMissionsRepeatable": false, "unlockAllProfitTakerStages": false, "instantFinishRivenChallenge": false, @@ -55,8 +55,13 @@ "noDojoResearchTime": false, "fastClanAscension": false, "missionsCanGiveAllRelics": false, + "unlockAllSimarisResearchEntries": false, "spoofMasteryRank": -1, "nightwaveStandingMultiplier": 1, + "unfaithfulBugFixes": { + "ignore1999LastRegionPlayed": false, + "fixXtraCheeseTimer": false + }, "worldState": { "creditBoost": false, "affinityBoost": false, diff --git a/package-lock.json b/package-lock.json index dc6eb284..0fcd908d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@types/express": "^5", "@types/morgan": "^1.9.9", + "@types/websocket": "^1.0.10", "@types/ws": "^8.18.1", "crc-32": "^1.2.2", "express": "^5", @@ -19,6 +20,7 @@ "morgan": "^1.10.0", "ncp": "^2.0.0", "typescript": "^5.5", + "undici": "^7.10.0", "warframe-public-export-plus": "^0.5.68", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", @@ -382,6 +384,15 @@ "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", "license": "MIT" }, + "node_modules/@types/websocket": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.10.tgz", + "integrity": "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", @@ -910,6 +921,21 @@ "node": ">=16.20.1" } }, + "node_modules/bufferutil": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2449,6 +2475,19 @@ "node": ">= 0.6" } }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", @@ -3292,6 +3331,15 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.10.0.tgz", + "integrity": "sha512-u5otvFBOBZvmdjWLVW+5DAc9Nkq8f24g0O9oY7qw2JVIF1VocIFoyz9JFkuVOS2j41AufeO0xnlweJ2RLT8nGw==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -3317,6 +3365,21 @@ "punycode": "^2.1.0" } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index b5ca4fbd..35886233 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,11 @@ "build": "tsc --incremental --sourceMap && ncp static/webui build/static/webui", "build:dev": "tsc --incremental --sourceMap", "build-and-start": "npm run build && npm run start", + "build-and-start:bun": "npm run verify && npm run bun-run", "dev": "node scripts/dev.js", + "dev:bun": "bun scripts/dev.js", "verify": "tsgo --noEmit", + "bun-run": "bun src/index.ts", "lint": "eslint --ext .ts .", "lint:ci": "eslint --ext .ts --rule \"prettier/prettier: off\" .", "lint:fix": "eslint --fix --ext .ts .", @@ -20,6 +23,7 @@ "dependencies": { "@types/express": "^5", "@types/morgan": "^1.9.9", + "@types/websocket": "^1.0.10", "@types/ws": "^8.18.1", "crc-32": "^1.2.2", "express": "^5", @@ -28,6 +32,7 @@ "morgan": "^1.10.0", "ncp": "^2.0.0", "typescript": "^5.5", + "undici": "^7.10.0", "warframe-public-export-plus": "^0.5.68", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", diff --git a/scripts/dev.js b/scripts/dev.js index 1852a131..542528f1 100644 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -14,6 +14,7 @@ args.push("--secret"); args.push(secret); let buildproc, runproc; +const spawnopts = { stdio: "inherit", shell: true }; function run(changedFile) { if (changedFile) { console.log(`Change to ${changedFile} detected`); @@ -28,11 +29,17 @@ function run(changedFile) { runproc = undefined; } - buildproc = spawn("npm", ["run", "build:dev"], { stdio: "inherit", shell: true }); + const thisbuildproc = spawn("npm", ["run", process.versions.bun ? "verify" : "build:dev"], spawnopts); + const thisbuildstart = Date.now(); + buildproc = thisbuildproc; buildproc.on("exit", code => { + if (buildproc !== thisbuildproc) { + return; + } buildproc = undefined; if (code === 0) { - runproc = spawn("npm", ["run", "start", "--", ...args], { stdio: "inherit", shell: true }); + console.log(`${process.versions.bun ? "Verified" : "Built"} in ${Date.now() - thisbuildstart} ms`); + runproc = spawn("npm", ["run", process.versions.bun ? "bun-run" : "start", "--", ...args], spawnopts); runproc.on("exit", () => { runproc = undefined; }); @@ -44,6 +51,8 @@ run(); chokidar.watch("src").on("change", run); chokidar.watch("static/fixed_responses").on("change", run); -chokidar.watch("static/webui").on("change", () => { - fetch("http://localhost/custom/webuiFileChangeDetected?secret=" + secret); +chokidar.watch("static/webui").on("change", async () => { + try { + await fetch("http://localhost/custom/webuiFileChangeDetected?secret=" + secret); + } catch (e) {} }); diff --git a/src/controllers/api/completeCalendarEventController.ts b/src/controllers/api/completeCalendarEventController.ts index 20c8abb3..993b55c7 100644 --- a/src/controllers/api/completeCalendarEventController.ts +++ b/src/controllers/api/completeCalendarEventController.ts @@ -1,4 +1,4 @@ -import { getCalendarProgress, getInventory } from "@/src/services/inventoryService"; +import { checkCalendarChallengeCompletion, getCalendarProgress, getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; import { getWorldState } from "@/src/services/worldStateService"; @@ -12,27 +12,23 @@ export const completeCalendarEventController: RequestHandler = async (req, res) const calendarProgress = getCalendarProgress(inventory); const currentSeason = getWorldState().KnownCalendarSeasons[0]; let inventoryChanges: IInventoryChanges = {}; - let dayIndex = 0; - for (const day of currentSeason.Days) { - if (day.events.length == 0 || day.events[0].type != "CET_CHALLENGE") { - if (dayIndex == calendarProgress.SeasonProgress.LastCompletedDayIdx) { - if (day.events.length != 0) { - const selection = day.events[parseInt(req.query.CompletedEventIdx as string)]; - if (selection.type == "CET_REWARD") { - inventoryChanges = (await handleStoreItemAcquisition(selection.reward!, inventory)) - .InventoryChanges; - } else if (selection.type == "CET_UPGRADE") { - calendarProgress.YearProgress.Upgrades.push(selection.upgrade!); - } else if (selection.type != "CET_PLOT") { - throw new Error(`unexpected selection type: ${selection.type}`); - } - } - break; - } - ++dayIndex; + const dayIndex = calendarProgress.SeasonProgress.LastCompletedDayIdx + 1; + const day = currentSeason.Days[dayIndex]; + if (day.events.length != 0) { + if (day.events[0].type == "CET_CHALLENGE") { + throw new Error(`completeCalendarEvent should not be used for challenges`); + } + const selection = day.events[parseInt(req.query.CompletedEventIdx as string)]; + if (selection.type == "CET_REWARD") { + inventoryChanges = (await handleStoreItemAcquisition(selection.reward!, inventory)).InventoryChanges; + } else if (selection.type == "CET_UPGRADE") { + calendarProgress.YearProgress.Upgrades.push(selection.upgrade!); + } else if (selection.type != "CET_PLOT") { + throw new Error(`unexpected selection type: ${selection.type}`); } } - calendarProgress.SeasonProgress.LastCompletedDayIdx++; + calendarProgress.SeasonProgress.LastCompletedDayIdx = dayIndex; + checkCalendarChallengeCompletion(calendarProgress, currentSeason); await inventory.save(); res.json({ InventoryChanges: inventoryChanges, diff --git a/src/controllers/api/giftingController.ts b/src/controllers/api/giftingController.ts index 55865cee..9a532776 100644 --- a/src/controllers/api/giftingController.ts +++ b/src/controllers/api/giftingController.ts @@ -11,13 +11,13 @@ import { import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; import { IOid } from "@/src/types/commonTypes"; -import { IInventoryChanges, IPurchaseParams } from "@/src/types/purchaseTypes"; +import { IInventoryChanges, IPurchaseParams, PurchaseSource } from "@/src/types/purchaseTypes"; import { RequestHandler } from "express"; import { ExportBundles, ExportFlavour } from "warframe-public-export-plus"; export const giftingController: RequestHandler = async (req, res) => { const data = getJSONfromString(String(req.body)); - if (data.PurchaseParams.Source != 0 || !data.PurchaseParams.UsePremium) { + if (data.PurchaseParams.Source != PurchaseSource.Market || !data.PurchaseParams.UsePremium) { throw new Error(`unexpected purchase params in gifting request: ${String(req.body)}`); } diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index cdaf8d4d..ecc32ec3 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -6,13 +6,7 @@ import allDialogue from "@/static/fixed_responses/allDialogue.json"; import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { IInventoryClient, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes"; import { IPolarity, ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { - ExportCustoms, - ExportFlavour, - ExportRegions, - ExportResources, - ExportVirtuals -} from "warframe-public-export-plus"; +import { ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus"; import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService"; import { addMiscItems, @@ -22,7 +16,7 @@ import { generateRewardSeed } from "@/src/services/inventoryService"; import { logger } from "@/src/utils/logger"; -import { catBreadHash } from "@/src/helpers/stringHelpers"; +import { addString, catBreadHash } from "@/src/helpers/stringHelpers"; import { Types } from "mongoose"; import { getNemesisManifest } from "@/src/helpers/nemesisHelpers"; import { getPersonalRooms } from "@/src/services/personalRoomsService"; @@ -167,18 +161,6 @@ export const getInventoryResponse = async ( } } - if (config.unlockAllMissions) { - inventoryResponse.Missions = []; - for (const tag of Object.keys(ExportRegions)) { - inventoryResponse.Missions.push({ - Completes: 1, - Tier: 1, - Tag: tag - }); - } - addString(inventoryResponse.NodeIntrosCompleted, "TeshinHardModeUnlocked"); - } - if (config.unlockAllShipDecorations) { inventoryResponse.ShipDecorations = []; for (const [uniqueName, item] of Object.entries(ExportResources)) { @@ -352,6 +334,19 @@ export const getInventoryResponse = async ( } } + if (config.unlockAllSimarisResearchEntries) { + inventoryResponse.LibraryPersonalTarget = undefined; + inventoryResponse.LibraryPersonalProgress = [ + "/Lotus/Types/Game/Library/Targets/Research1Target", + "/Lotus/Types/Game/Library/Targets/Research2Target", + "/Lotus/Types/Game/Library/Targets/Research3Target", + "/Lotus/Types/Game/Library/Targets/Research4Target", + "/Lotus/Types/Game/Library/Targets/Research5Target", + "/Lotus/Types/Game/Library/Targets/Research6Target", + "/Lotus/Types/Game/Library/Targets/Research7Target" + ].map(type => ({ TargetType: type, Scans: 10, Completed: true })); + } + return inventoryResponse; }; @@ -362,12 +357,6 @@ const allEudicoHeistJobs = [ "/Lotus/Types/Gameplay/Venus/Jobs/Heists/HeistProfitTakerBountyFour" ]; -const addString = (arr: string[], str: string): void => { - if (arr.indexOf(str) == -1) { - arr.push(str); - } -}; - const getExpRequiredForMr = (rank: number): number => { if (rank <= 30) { return 2500 * rank * rank; diff --git a/src/controllers/api/loginController.ts b/src/controllers/api/loginController.ts index 3d510f26..c7b5c16d 100644 --- a/src/controllers/api/loginController.ts +++ b/src/controllers/api/loginController.ts @@ -4,16 +4,16 @@ import { config } from "@/src/services/configService"; import { buildConfig } from "@/src/services/buildConfigService"; import { Account } from "@/src/models/loginModel"; -import { createAccount, isCorrectPassword, isNameTaken } from "@/src/services/loginService"; +import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "@/src/services/loginService"; import { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "@/src/types/loginTypes"; import { logger } from "@/src/utils/logger"; import { version_compare } from "@/src/helpers/inventoryHelpers"; +import { sendWsBroadcastTo } from "@/src/services/webService"; export const loginController: RequestHandler = async (request, response) => { const loginRequest = JSON.parse(String(request.body)) as ILoginRequest; // parse octet stream of json data to json object const account = await Account.findOne({ email: loginRequest.email }); - const nonce = Math.round(Math.random() * Number.MAX_SAFE_INTEGER); const buildLabel: string = typeof request.query.buildLabel == "string" @@ -42,26 +42,14 @@ export const loginController: RequestHandler = async (request, response) => { loginRequest.ClientType == "webui-register") ) { try { - const nameFromEmail = loginRequest.email.substring(0, loginRequest.email.indexOf("@")); - let name = nameFromEmail || loginRequest.email.substring(1) || "SpaceNinja"; - if (await isNameTaken(name)) { - let suffix = 0; - do { - ++suffix; - name = nameFromEmail + suffix; - } while (await isNameTaken(name)); - } + const name = await getUsernameFromEmail(loginRequest.email); const newAccount = await createAccount({ email: loginRequest.email, password: loginRequest.password, DisplayName: name, CountryCode: loginRequest.lang?.toUpperCase() ?? "EN", - ClientType: loginRequest.ClientType == "webui-register" ? "webui" : loginRequest.ClientType, - CrossPlatformAllowed: true, - ForceLogoutVersion: 0, - ConsentNeeded: false, - TrackedSettings: [], - Nonce: nonce, + ClientType: loginRequest.ClientType, + Nonce: createNonce(), BuildLabel: buildLabel, LastLogin: new Date() }); @@ -80,38 +68,29 @@ export const loginController: RequestHandler = async (request, response) => { return; } - if (loginRequest.ClientType == "webui-register") { - response.status(400).json({ error: "account already exists" }); - return; - } - if (!isCorrectPassword(loginRequest.password, account.password)) { response.status(400).json({ error: "incorrect login data" }); return; } - if (loginRequest.ClientType == "webui") { - if (!account.Nonce) { - account.ClientType = "webui"; - account.Nonce = nonce; + if (account.Nonce && account.ClientType != "webui" && !account.Dropped && !loginRequest.kick) { + // U17 seems to handle "nonce still set" like a login failure. + if (version_compare(buildLabel, "2015.12.05.18.07") >= 0) { + response.status(400).send({ error: "nonce still set" }); + return; } - } else { - if (account.Nonce && account.ClientType != "webui" && !account.Dropped && !loginRequest.kick) { - // U17 seems to handle "nonce still set" like a login failure. - if (version_compare(buildLabel, "2015.12.05.18.07") >= 0) { - response.status(400).send({ error: "nonce still set" }); - return; - } - } - - account.ClientType = loginRequest.ClientType; - account.Nonce = nonce; - account.CountryCode = loginRequest.lang?.toUpperCase() ?? "EN"; - account.BuildLabel = buildLabel; - account.LastLogin = new Date(); } + + account.ClientType = loginRequest.ClientType; + account.Nonce = createNonce(); + account.CountryCode = loginRequest.lang?.toUpperCase() ?? "EN"; + account.BuildLabel = buildLabel; + account.LastLogin = new Date(); await account.save(); + // Tell WebUI its nonce has been invalidated + sendWsBroadcastTo(account._id.toString(), { logged_out: true }); + response.json(createLoginResponse(myAddress, myUrlBase, account.toJSON(), buildLabel)); }; diff --git a/src/controllers/api/logoutController.ts b/src/controllers/api/logoutController.ts index 889e7d78..e2074f76 100644 --- a/src/controllers/api/logoutController.ts +++ b/src/controllers/api/logoutController.ts @@ -1,5 +1,6 @@ import { RequestHandler } from "express"; import { Account } from "@/src/models/loginModel"; +import { sendWsBroadcastTo } from "@/src/services/webService"; export const logoutController: RequestHandler = async (req, res) => { if (!req.query.accountId) { @@ -10,7 +11,7 @@ export const logoutController: RequestHandler = async (req, res) => { throw new Error("Request is missing nonce parameter"); } - await Account.updateOne( + const stat = await Account.updateOne( { _id: req.query.accountId, Nonce: nonce @@ -19,6 +20,10 @@ export const logoutController: RequestHandler = async (req, res) => { Nonce: 0 } ); + if (stat.modifiedCount) { + // Tell WebUI its nonce has been invalidated + sendWsBroadcastTo(req.query.accountId as string, { logged_out: true }); + } res.writeHead(200, { "Content-Type": "text/html", diff --git a/src/controllers/api/missionInventoryUpdateController.ts b/src/controllers/api/missionInventoryUpdateController.ts index 3b5009c2..93f8033c 100644 --- a/src/controllers/api/missionInventoryUpdateController.ts +++ b/src/controllers/api/missionInventoryUpdateController.ts @@ -7,6 +7,7 @@ import { generateRewardSeed, getInventory } from "@/src/services/inventoryServic import { getInventoryResponse } from "./inventoryController"; import { logger } from "@/src/utils/logger"; import { IMissionInventoryUpdateResponse } from "@/src/types/missionTypes"; +import { sendWsBroadcastTo } from "@/src/services/webService"; /* **** INPUT **** @@ -76,6 +77,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res) InventoryJson: JSON.stringify(inventoryResponse), MissionRewards: [] }); + sendWsBroadcastTo(account._id.toString(), { update_inventory: true }); return; } @@ -106,6 +108,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res) AffiliationMods, ConquestCompletedMissionsCount } satisfies IMissionInventoryUpdateResponse); + sendWsBroadcastTo(account._id.toString(), { update_inventory: true }); }; /* diff --git a/src/controllers/api/nameWeaponController.ts b/src/controllers/api/nameWeaponController.ts index 5d1011be..8d378feb 100644 --- a/src/controllers/api/nameWeaponController.ts +++ b/src/controllers/api/nameWeaponController.ts @@ -3,6 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; +import { sendWsBroadcastTo } from "@/src/services/webService"; interface INameWeaponRequest { ItemName: string; @@ -27,4 +28,5 @@ export const nameWeaponController: RequestHandler = async (req, res) => { res.json({ InventoryChanges: currencyChanges }); + sendWsBroadcastTo(accountId, { update_inventory: true }); }; diff --git a/src/controllers/api/nemesisController.ts b/src/controllers/api/nemesisController.ts index 93ea4ee5..dbdb10e3 100644 --- a/src/controllers/api/nemesisController.ts +++ b/src/controllers/api/nemesisController.ts @@ -8,16 +8,15 @@ import { getKnifeUpgrade, getNemesisManifest, getNemesisPasscode, - getNemesisPasscodeModTypes, GUESS_CORRECT, GUESS_INCORRECT, GUESS_NEUTRAL, GUESS_NONE, GUESS_WILDCARD, - IKnifeResponse + IKnifeResponse, + parseUpgrade } from "@/src/helpers/nemesisHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { freeUpSlot, getInventory } from "@/src/services/inventoryService"; import { getAccountForRequest } from "@/src/services/loginService"; @@ -215,7 +214,19 @@ export const nemesisController: RequestHandler = async (req, res) => { } ]; inventory.Nemesis!.Weakened = true; - await consumePasscodeModCharges(inventory, response); + + // Subtract a charge from all requiem mods installed on parazon + const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; + const dataknifeLoadout = loadout.DATAKNIFE.id( + inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid + ); + const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; + const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; + for (let i = 3; i != 6; ++i) { + //logger.debug(`subtracting a charge from ${dataknifeUpgrades[i]}`); + const upgrade = parseUpgrade(inventory, dataknifeUpgrades[i]); + consumeModCharge(response, inventory, upgrade, dataknifeUpgrades); + } } } else { // Guess was incorrect, increase rank @@ -380,18 +391,3 @@ interface IKnife { AttachedUpgrades: IUpgradeClient[]; HiddenWhenHolstered: boolean; } - -const consumePasscodeModCharges = async ( - inventory: TInventoryDatabaseDocument, - response: IKnifeResponse -): Promise => { - const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; - const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid); - const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; - const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; - const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!); - for (const modType of modTypes) { - const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType); - consumeModCharge(response, inventory, upgrade, dataknifeUpgrades); - } -}; diff --git a/src/controllers/api/purchaseController.ts b/src/controllers/api/purchaseController.ts index 4b35e0c5..ba314845 100644 --- a/src/controllers/api/purchaseController.ts +++ b/src/controllers/api/purchaseController.ts @@ -3,6 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { IPurchaseRequest } from "@/src/types/purchaseTypes"; import { handlePurchase } from "@/src/services/purchaseService"; import { getInventory } from "@/src/services/inventoryService"; +import { sendWsBroadcastTo } from "@/src/services/webService"; export const purchaseController: RequestHandler = async (req, res) => { const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest; @@ -11,4 +12,5 @@ export const purchaseController: RequestHandler = async (req, res) => { const response = await handlePurchase(purchaseRequest, inventory); await inventory.save(); res.json(response); + sendWsBroadcastTo(accountId, { update_inventory: true }); }; diff --git a/src/controllers/api/renamePetController.ts b/src/controllers/api/renamePetController.ts index 61212641..40b4ec37 100644 --- a/src/controllers/api/renamePetController.ts +++ b/src/controllers/api/renamePetController.ts @@ -1,6 +1,7 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; +import { sendWsBroadcastTo } from "@/src/services/webService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { RequestHandler } from "express"; @@ -22,6 +23,7 @@ export const renamePetController: RequestHandler = async (req, res) => { ...data, inventoryChanges: inventoryChanges }); + sendWsBroadcastTo(accountId, { update_inventory: true }); }; interface IRenamePetRequest { diff --git a/src/controllers/api/sellController.ts b/src/controllers/api/sellController.ts index fdfb3a82..ff5c8f42 100644 --- a/src/controllers/api/sellController.ts +++ b/src/controllers/api/sellController.ts @@ -15,6 +15,7 @@ import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; import { ExportDojoRecipes } from "warframe-public-export-plus"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { sendWsBroadcastTo } from "@/src/services/webService"; export const sellController: RequestHandler = async (req, res) => { const payload = JSON.parse(String(req.body)) as ISellRequest; @@ -279,6 +280,7 @@ export const sellController: RequestHandler = async (req, res) => { res.json({ inventoryChanges: inventoryChanges // "inventoryChanges" for this response instead of the usual "InventoryChanges" }); + sendWsBroadcastTo(accountId, { update_inventory: true }); }; interface ISellRequest { diff --git a/src/controllers/api/updateChallengeProgressController.ts b/src/controllers/api/updateChallengeProgressController.ts index 9b7292e6..68ae6c55 100644 --- a/src/controllers/api/updateChallengeProgressController.ts +++ b/src/controllers/api/updateChallengeProgressController.ts @@ -13,7 +13,7 @@ export const updateChallengeProgressController: RequestHandler = async (req, res const inventory = await getInventory( account._id.toString(), - "ChallengesFixVersion ChallengeProgress SeasonChallengeHistory Affiliations" + "ChallengesFixVersion ChallengeProgress SeasonChallengeHistory Affiliations CalendarProgress" ); let affiliationMods: IAffiliationMods[] = []; if (challenges.ChallengeProgress) { diff --git a/src/controllers/custom/completeAllMissionsController.ts b/src/controllers/custom/completeAllMissionsController.ts new file mode 100644 index 00000000..2e7ac2fb --- /dev/null +++ b/src/controllers/custom/completeAllMissionsController.ts @@ -0,0 +1,34 @@ +import { addString } from "@/src/helpers/stringHelpers"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { addFixedLevelRewards } from "@/src/services/missionInventoryUpdateService"; +import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; +import { IMissionReward } from "@/src/types/missionTypes"; +import { RequestHandler } from "express"; +import { ExportRegions } from "warframe-public-export-plus"; + +export const completeAllMissionsController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const MissionRewards: IMissionReward[] = []; + for (const [tag, node] of Object.entries(ExportRegions)) { + if (!inventory.Missions.find(x => x.Tag == tag)) { + inventory.Missions.push({ + Completes: 1, + Tier: 1, + Tag: tag + }); + + if (node.missionReward) { + console.log(node.missionReward); + addFixedLevelRewards(node.missionReward, inventory, MissionRewards); + } + } + } + for (const reward of MissionRewards) { + await handleStoreItemAcquisition(reward.StoreItem, inventory, reward.ItemCount, undefined, true); + } + addString(inventory.NodeIntrosCompleted, "TeshinHardModeUnlocked"); + await inventory.save(); + res.end(); +}; diff --git a/src/controllers/custom/manageQuestsController.ts b/src/controllers/custom/manageQuestsController.ts index b951c754..365fb29c 100644 --- a/src/controllers/custom/manageQuestsController.ts +++ b/src/controllers/custom/manageQuestsController.ts @@ -128,7 +128,7 @@ export const manageQuestsController: RequestHandler = async (req, res) => { await completeQuest(inventory, questKey.ItemType); } else { const progress = { - c: questManifest.chainStages![currentStage].key ? -1 : 0, + c: 0, i: false, m: false, b: [] diff --git a/src/controllers/custom/webuiFileChangeDetectedController.ts b/src/controllers/custom/webuiFileChangeDetectedController.ts index 3ec52a48..aa6af978 100644 --- a/src/controllers/custom/webuiFileChangeDetectedController.ts +++ b/src/controllers/custom/webuiFileChangeDetectedController.ts @@ -1,11 +1,10 @@ import { args } from "@/src/helpers/commandLineArguments"; -import { config } from "@/src/services/configService"; import { sendWsBroadcast } from "@/src/services/webService"; import { RequestHandler } from "express"; export const webuiFileChangeDetectedController: RequestHandler = (req, res) => { if (args.dev && args.secret && req.query.secret == args.secret) { - sendWsBroadcast({ ports: { http: config.httpPort, https: config.httpsPort } }); + sendWsBroadcast({ reload: true }); } res.end(); }; diff --git a/src/helpers/nemesisHelpers.ts b/src/helpers/nemesisHelpers.ts index 0c7e5bdd..4a5de0fb 100644 --- a/src/helpers/nemesisHelpers.ts +++ b/src/helpers/nemesisHelpers.ts @@ -237,7 +237,7 @@ export const getNemesisPasscode = (nemesis: { fp: bigint; Faction: TNemesisFacti return passcode; }; -const requiemMods: readonly string[] = [ +/*const requiemMods: readonly string[] = [ "/Lotus/Upgrades/Mods/Immortal/ImmortalOneMod", "/Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod", "/Lotus/Upgrades/Mods/Immortal/ImmortalThreeMod", @@ -246,7 +246,7 @@ const requiemMods: readonly string[] = [ "/Lotus/Upgrades/Mods/Immortal/ImmortalSixMod", "/Lotus/Upgrades/Mods/Immortal/ImmortalSevenMod", "/Lotus/Upgrades/Mods/Immortal/ImmortalEightMod" -]; +];*/ export const antivirusMods: readonly string[] = [ "/Lotus/Upgrades/Mods/Immortal/AntivirusOneMod", @@ -259,12 +259,12 @@ export const antivirusMods: readonly string[] = [ "/Lotus/Upgrades/Mods/Immortal/AntivirusEightMod" ]; -export const getNemesisPasscodeModTypes = (nemesis: { fp: bigint; Faction: TNemesisFaction }): string[] => { +/*export const getNemesisPasscodeModTypes = (nemesis: { fp: bigint; Faction: TNemesisFaction }): string[] => { const passcode = getNemesisPasscode(nemesis); return nemesis.Faction == "FC_INFESTATION" ? passcode.map(i => antivirusMods[i]) : passcode.map(i => requiemMods[i]); -}; +};*/ // Symbols; 0-7 are the normal requiem mods. export const GUESS_NONE = 8; @@ -343,6 +343,27 @@ export const getKnifeUpgrade = ( throw new Error(`${type} does not seem to be installed on parazon?!`); }; +export const parseUpgrade = ( + inventory: TInventoryDatabaseDocument, + str: string +): { ItemId: IOid; ItemType: string } => { + if (str.length == 24) { + const upgrade = inventory.Upgrades.id(str); + if (upgrade) { + return { + ItemId: { $oid: str }, + ItemType: upgrade.ItemType + }; + } + throw new Error(`Could not resolve oid ${str}`); + } else { + return { + ItemId: { $oid: "000000000000000000000000" }, + ItemType: str + }; + } +}; + export const consumeModCharge = ( response: IKnifeResponse, inventory: TInventoryDatabaseDocument, diff --git a/src/helpers/stringHelpers.ts b/src/helpers/stringHelpers.ts index 06d2ac28..3512c1ea 100644 --- a/src/helpers/stringHelpers.ts +++ b/src/helpers/stringHelpers.ts @@ -54,3 +54,9 @@ export const regexEscape = (str: string): string => { str = str.split("}").join("\\}"); return str; }; + +export const addString = (arr: string[], str: string): void => { + if (arr.indexOf(str) == -1) { + arr.push(str); + } +}; diff --git a/src/models/loginModel.ts b/src/models/loginModel.ts index 0f83c0cb..44dab113 100644 --- a/src/models/loginModel.ts +++ b/src/models/loginModel.ts @@ -11,13 +11,13 @@ const databaseAccountSchema = new Schema( email: { type: String, required: true, unique: true }, password: { type: String, required: true }, DisplayName: { type: String, required: true, unique: true }, - CountryCode: { type: String, required: true }, + CountryCode: { type: String, default: "" }, ClientType: { type: String }, - CrossPlatformAllowed: { type: Boolean, required: true }, - ForceLogoutVersion: { type: Number, required: true }, + CrossPlatformAllowed: { type: Boolean, default: true }, + ForceLogoutVersion: { type: Number, default: 0 }, AmazonAuthToken: { type: String }, AmazonRefreshToken: { type: String }, - ConsentNeeded: { type: Boolean, required: true }, + ConsentNeeded: { type: Boolean, default: false }, TrackedSettings: { type: [String], default: [] }, Nonce: { type: Number, default: 0 }, BuildLabel: String, diff --git a/src/routes/api.ts b/src/routes/api.ts index df9e8b59..63df81d0 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -284,6 +284,7 @@ apiRouter.post("/inventorySlots.php", inventorySlotsController); apiRouter.post("/joinSession.php", joinSessionController); apiRouter.post("/login.php", loginController); apiRouter.post("/loginRewardsSelection.php", loginRewardsSelectionController); +apiRouter.post("/logout.php", logoutController); // from ~U16, don't know when they changed it to GET apiRouter.post("/maturePet.php", maturePetController); apiRouter.post("/missionInventoryUpdate.php", missionInventoryUpdateController); apiRouter.post("/modularWeaponCrafting.php", modularWeaponCraftingController); diff --git a/src/routes/custom.ts b/src/routes/custom.ts index 75eb80a4..35d89d4d 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -12,6 +12,7 @@ import { ircDroppedController } from "@/src/controllers/custom/ircDroppedControl import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAllIntrinsicsController"; import { addMissingMaxRankModsController } from "@/src/controllers/custom/addMissingMaxRankModsController"; import { webuiFileChangeDetectedController } from "@/src/controllers/custom/webuiFileChangeDetectedController"; +import { completeAllMissionsController } from "@/src/controllers/custom/completeAllMissionsController"; import { createAccountController } from "@/src/controllers/custom/createAccountController"; import { createMessageController } from "@/src/controllers/custom/createMessageController"; @@ -40,6 +41,7 @@ customRouter.get("/ircDropped", ircDroppedController); customRouter.get("/unlockAllIntrinsics", unlockAllIntrinsicsController); customRouter.get("/addMissingMaxRankMods", addMissingMaxRankModsController); customRouter.get("/webuiFileChangeDetected", webuiFileChangeDetectedController); +customRouter.get("/completeAllMissions", completeAllMissionsController); customRouter.post("/createAccount", createAccountController); customRouter.post("/createMessage", createMessageController); diff --git a/src/services/configService.ts b/src/services/configService.ts index 6ef2e96f..ff7c0670 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -19,7 +19,6 @@ export interface IConfig { skipTutorial?: boolean; skipAllDialogue?: boolean; unlockAllScans?: boolean; - unlockAllMissions?: boolean; infiniteCredits?: boolean; infinitePlatinum?: boolean; infiniteEndo?: boolean; @@ -49,6 +48,7 @@ export interface IConfig { noVendorPurchaseLimits?: boolean; noDeathMarks?: boolean; noKimCooldowns?: boolean; + fullyStockedVendors?: boolean; syndicateMissionsRepeatable?: boolean; unlockAllProfitTakerStages?: boolean; instantFinishRivenChallenge?: boolean; @@ -62,8 +62,13 @@ export interface IConfig { noDojoResearchTime?: boolean; fastClanAscension?: boolean; missionsCanGiveAllRelics?: boolean; + unlockAllSimarisResearchEntries?: boolean; spoofMasteryRank?: number; nightwaveStandingMultiplier?: number; + unfaithfulBugFixes?: { + ignore1999LastRegionPlayed?: boolean; + fixXtraCheeseTimer?: boolean; + }; worldState?: { creditBoost?: boolean; affinityBoost?: boolean; diff --git a/src/services/configWatcherService.ts b/src/services/configWatcherService.ts index b6f8e83c..bb64d5da 100644 --- a/src/services/configWatcherService.ts +++ b/src/services/configWatcherService.ts @@ -5,7 +5,12 @@ import { config, configPath, loadConfig } from "./configService"; import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService"; let amnesia = false; -fs.watchFile(configPath, () => { +fs.watchFile(configPath, (now, then) => { + // https://github.com/oven-sh/bun/issues/20542 + if (process.versions.bun && now.mtimeMs == then.mtimeMs) { + return; + } + if (amnesia) { amnesia = false; } else { diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 38c197f8..a2145d3b 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -84,9 +84,11 @@ import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from ". import { createMessage } from "./inboxService"; import { getMaxStanding, getMinStanding } from "@/src/helpers/syndicateStandingHelper"; import { getNightwaveSyndicateTag, getWorldState } from "./worldStateService"; +import { ICalendarSeason } from "@/src/types/worldStateTypes"; import { generateNemesisProfile, INemesisProfile } from "../helpers/nemesisHelpers"; import { TAccountDocument } from "./loginService"; import { unixTimesInMs } from "../constants/timeConstants"; +import { addString } from "../helpers/stringHelpers"; export const createInventory = async ( accountOwnerId: Types.ObjectId, @@ -1783,6 +1785,10 @@ export const addChallenges = ( } else { inventory.ChallengeProgress.push({ Name, Progress }); } + + if (Name.startsWith("Calendar")) { + addString(getCalendarProgress(inventory).SeasonProgress.ActivatedChallenges, Name); + } }); const affiliationMods: IAffiliationMods[] = []; @@ -1825,12 +1831,15 @@ export const addChallenges = ( return affiliationMods; }; -export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes }: IMission): void => { +export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag, Completes, Tier }: IMission): void => { const { Missions } = inventory; const itemIndex = Missions.findIndex(item => item.Tag === Tag); if (itemIndex !== -1) { Missions[itemIndex].Completes += Completes; + if (Tier) { + Missions[itemIndex].Tier = Tier; + } } else { Missions.push({ Tag, Completes }); } @@ -2026,6 +2035,20 @@ export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICal return inventory.CalendarProgress; }; +export const checkCalendarChallengeCompletion = ( + calendarProgress: ICalendarProgress, + currentSeason: ICalendarSeason +): void => { + const dayIndex = calendarProgress.SeasonProgress.LastCompletedDayIdx + 1; + if (calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx >= dayIndex) { + const day = currentSeason.Days[dayIndex]; + if (day.events.length != 0 && day.events[0].type == "CET_CHALLENGE") { + //logger.debug(`already completed the challenge, skipping ahead`); + calendarProgress.SeasonProgress.LastCompletedDayIdx++; + } + } +}; + export const giveNemesisWeaponRecipe = ( inventory: TInventoryDatabaseDocument, weaponType: string, diff --git a/src/services/loginService.ts b/src/services/loginService.ts index ccf5b958..44366f5c 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -18,6 +18,23 @@ export const isNameTaken = async (name: string): Promise => { return !!(await Account.findOne({ DisplayName: name })); }; +export const createNonce = (): number => { + return Math.round(Math.random() * Number.MAX_SAFE_INTEGER); +}; + +export const getUsernameFromEmail = async (email: string): Promise => { + const nameFromEmail = email.substring(0, email.indexOf("@")); + let name = nameFromEmail || email.substring(1) || "SpaceNinja"; + if (await isNameTaken(name)) { + let suffix = 0; + do { + ++suffix; + name = nameFromEmail + suffix; + } while (await isNameTaken(name)); + } + return nameFromEmail; +}; + export const createAccount = async (accountData: IDatabaseAccountRequiredFields): Promise => { const account = new Account(accountData); try { diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index 499115f9..cd523253 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -33,6 +33,7 @@ import { addSkin, addStanding, applyClientEquipmentUpdates, + checkCalendarChallengeCompletion, combineInventoryChanges, generateRewardSeed, getCalendarProgress, @@ -67,7 +68,15 @@ import { } from "@/src/helpers/nemesisHelpers"; import { Loadout } from "../models/inventoryModels/loadoutModel"; import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes"; -import { getLiteSortie, getSortie, idToBountyCycle, idToDay, idToWeek, pushClassicBounties } from "./worldStateService"; +import { + getLiteSortie, + getSortie, + getWorldState, + idToBountyCycle, + idToDay, + idToWeek, + pushClassicBounties +} from "./worldStateService"; import { config } from "./configService"; import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json"; import { ISyndicateMissionInfo } from "../types/worldStateTypes"; @@ -79,7 +88,7 @@ const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] if (rewardInfo.VaultsCracked) { const rotations: number[] = []; for (let i = 0; i != rewardInfo.VaultsCracked; ++i) { - rotations.push(i); + rotations.push(Math.min(i, 2)); } return rotations; } @@ -259,7 +268,9 @@ export const addMissionInventoryUpdates = async ( addMissionComplete(inventory, value); break; case "LastRegionPlayed": - inventory.LastRegionPlayed = value; + if (!(config.unfaithfulBugFixes?.ignore1999LastRegionPlayed && value === "1999MapName")) { + inventory.LastRegionPlayed = value; + } break; case "RawUpgrades": addMods(inventory, value); @@ -620,11 +631,11 @@ export const addMissionInventoryUpdates = async ( } case "CalendarProgress": { const calendarProgress = getCalendarProgress(inventory); - for (const progress of value) { - const challengeName = progress.challenge.substring(progress.challenge.lastIndexOf("/") + 1); - calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx++; - calendarProgress.SeasonProgress.ActivatedChallenges.push(challengeName); - } + const currentSeason = getWorldState().KnownCalendarSeasons[0]; + calendarProgress.SeasonProgress.LastCompletedChallengeDayIdx = currentSeason.Days.findIndex( + x => x.events[0].challenge == value[value.length - 1].challenge + ); + checkCalendarChallengeCompletion(calendarProgress, currentSeason); break; } case "duviriCaveOffers": { @@ -1367,7 +1378,7 @@ export const addFixedLevelRewards = ( if (rewards.countedItems) { for (const item of rewards.countedItems) { MissionRewards.push({ - StoreItem: `/Lotus/StoreItems${item.ItemType.substring("Lotus/".length)}`, + StoreItem: toStoreItem(item.ItemType), ItemCount: item.ItemCount }); } @@ -1628,7 +1639,19 @@ function getRandomMissionDrops( } rewardManifests = [job.rewards]; if (job.xpAmounts.length > 1) { - rotations = [RewardInfo.JobStage! % (job.xpAmounts.length - 1)]; + const curentStage = RewardInfo.JobStage! + 1; + const totalStage = job.xpAmounts.length; + let tableIndex = 1; // Stage 2, Stage 3 of 4, and Stage 3 of 5 + + if (curentStage == 1) { + tableIndex = 0; + } else if (curentStage == totalStage) { + tableIndex = 3; + } else if (totalStage == 5 && curentStage == 4) { + tableIndex = 2; + } + + rotations = [tableIndex]; } else { rotations = [0]; } @@ -1637,11 +1660,7 @@ function getRandomMissionDrops( (RewardInfo.JobStage === job.xpAmounts.length - 1 || job.isVault) && !isEndlessJob ) { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (ExportRewards[job.rewards]) { - rewardManifests.push(job.rewards); - rotations.push(ExportRewards[job.rewards].length - 1); - } + rotations.push(3); } } } diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 4fb5bb2d..56cc9ed7 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -11,7 +11,13 @@ import { import { getRandomWeightedRewardUc } from "@/src/services/rngService"; import { applyStandingToVendorManifest, getVendorManifestByOid } from "@/src/services/serversideVendorsService"; import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IPurchaseRequest, IPurchaseResponse, SlotPurchase, IInventoryChanges } from "@/src/types/purchaseTypes"; +import { + IPurchaseRequest, + IPurchaseResponse, + SlotPurchase, + IInventoryChanges, + PurchaseSource +} from "@/src/types/purchaseTypes"; import { logger } from "@/src/utils/logger"; import worldState from "@/static/fixed_responses/worldState/worldState.json"; import { @@ -52,7 +58,7 @@ export const handlePurchase = async ( const prePurchaseInventoryChanges: IInventoryChanges = {}; let seed: bigint | undefined; - if (purchaseRequest.PurchaseParams.Source == 7) { + if (purchaseRequest.PurchaseParams.Source == PurchaseSource.Vendor) { let manifest = getVendorManifestByOid(purchaseRequest.PurchaseParams.SourceId!); if (manifest) { manifest = applyStandingToVendorManifest(inventory, manifest); @@ -69,18 +75,12 @@ export const handlePurchase = async ( } if (!config.dontSubtractPurchaseCreditCost) { if (offer.RegularPrice) { - combineInventoryChanges( - prePurchaseInventoryChanges, - updateCurrency(inventory, offer.RegularPrice[0], false) - ); + updateCurrency(inventory, offer.RegularPrice[0], false, prePurchaseInventoryChanges); } } if (!config.dontSubtractPurchasePlatinumCost) { if (offer.PremiumPrice) { - combineInventoryChanges( - prePurchaseInventoryChanges, - updateCurrency(inventory, offer.PremiumPrice[0], true) - ); + updateCurrency(inventory, offer.PremiumPrice[0], true, prePurchaseInventoryChanges); } } if (!config.dontSubtractPurchaseItemCost) { @@ -166,18 +166,15 @@ export const handlePurchase = async ( ); combineInventoryChanges(purchaseResponse.InventoryChanges, prePurchaseInventoryChanges); - const currencyChanges = updateCurrency( + updateCurrency( inventory, purchaseRequest.PurchaseParams.ExpectedPrice, - purchaseRequest.PurchaseParams.UsePremium + purchaseRequest.PurchaseParams.UsePremium, + prePurchaseInventoryChanges ); - purchaseResponse.InventoryChanges = { - ...currencyChanges, - ...purchaseResponse.InventoryChanges - }; switch (purchaseRequest.PurchaseParams.Source) { - case 1: { + case PurchaseSource.VoidTrader: { if (purchaseRequest.PurchaseParams.SourceId! != worldState.VoidTraders[0]._id.$oid) { throw new Error("invalid request source"); } @@ -186,10 +183,7 @@ export const handlePurchase = async ( ); if (offer) { if (!config.dontSubtractPurchaseCreditCost) { - combineInventoryChanges( - purchaseResponse.InventoryChanges, - updateCurrency(inventory, offer.RegularPrice, false) - ); + updateCurrency(inventory, offer.RegularPrice, false, purchaseResponse.InventoryChanges); } if (purchaseRequest.PurchaseParams.ExpectedPrice) { throw new Error(`vendor purchase should not have an expected price`); @@ -207,7 +201,7 @@ export const handlePurchase = async ( } break; } - case 2: + case PurchaseSource.SyndicateFavor: { const syndicateTag = purchaseRequest.PurchaseParams.SyndicateTag!; if (purchaseRequest.PurchaseParams.UseFreeFavor!) { @@ -244,22 +238,16 @@ export const handlePurchase = async ( } } break; - case 7: + case PurchaseSource.Vendor: if (purchaseRequest.PurchaseParams.SourceId! in ExportVendors) { const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!]; const offer = vendor.items.find(x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem); if (offer) { if (typeof offer.credits == "number" && !config.dontSubtractPurchaseCreditCost) { - combineInventoryChanges( - purchaseResponse.InventoryChanges, - updateCurrency(inventory, offer.credits, false) - ); + updateCurrency(inventory, offer.credits, false, purchaseResponse.InventoryChanges); } if (typeof offer.platinum == "number" && !config.dontSubtractPurchasePlatinumCost) { - combineInventoryChanges( - purchaseResponse.InventoryChanges, - updateCurrency(inventory, offer.platinum, true) - ); + updateCurrency(inventory, offer.platinum, true, purchaseResponse.InventoryChanges); } if (offer.itemPrices && !config.dontSubtractPurchaseItemCost) { handleItemPrices( @@ -275,7 +263,7 @@ export const handlePurchase = async ( throw new Error(`vendor purchase should not have an expected price`); } break; - case 18: { + case PurchaseSource.PrimeVaultTrader: { if (purchaseRequest.PurchaseParams.SourceId! != worldState.PrimeVaultTraders[0]._id.$oid) { throw new Error("invalid request source"); } diff --git a/src/services/serversideVendorsService.ts b/src/services/serversideVendorsService.ts index 0e4b3856..d5ea7410 100644 --- a/src/services/serversideVendorsService.ts +++ b/src/services/serversideVendorsService.ts @@ -6,38 +6,7 @@ import { mixSeeds, SRng } from "@/src/services/rngService"; import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes"; import { logger } from "@/src/utils/logger"; import { ExportVendors, IRange, IVendor, IVendorOffer } from "warframe-public-export-plus"; - -import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json"; -import DeimosHivemindCommisionsManifestFishmonger from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestFishmonger.json"; -import DeimosHivemindCommisionsManifestPetVendor from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestPetVendor.json"; -import DeimosHivemindCommisionsManifestProspector from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestProspector.json"; -import DeimosHivemindCommisionsManifestTokenVendor from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestTokenVendor.json"; -import DeimosHivemindCommisionsManifestWeaponsmith from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestWeaponsmith.json"; -import DeimosHivemindTokenVendorManifest from "@/static/fixed_responses/getVendorInfo/DeimosHivemindTokenVendorManifest.json"; -import DeimosPetVendorManifest from "@/static/fixed_responses/getVendorInfo/DeimosPetVendorManifest.json"; -import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json"; -import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json"; -import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json"; -import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json"; -import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json"; -import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json"; - -const rawVendorManifests: IVendorManifest[] = [ - DeimosEntratiFragmentVendorProductsManifest, - DeimosHivemindCommisionsManifestFishmonger, - DeimosHivemindCommisionsManifestPetVendor, - DeimosHivemindCommisionsManifestProspector, - DeimosHivemindCommisionsManifestTokenVendor, - DeimosHivemindCommisionsManifestWeaponsmith, - DeimosHivemindTokenVendorManifest, - DeimosPetVendorManifest, - DuviriAcrithisVendorManifest, - EntratiLabsEntratiLabsCommisionsManifest, - EntratiLabsEntratiLabVendorManifest, - Nova1999ConquestShopManifest, - OstronPetVendorManifest, - SolarisDebtTokenVendorRepossessionsManifest -]; +import { config } from "./configService"; interface IGeneratableVendorInfo extends Omit { cycleOffset?: number; @@ -91,49 +60,45 @@ const getCycleDuration = (manifest: IVendor): number => { return dur * unixTimesInMs.hour; }; -export const getVendorManifestByTypeName = (typeName: string): IVendorManifest | undefined => { - for (const vendorManifest of rawVendorManifests) { - if (vendorManifest.VendorInfo.TypeName == typeName) { - return vendorManifest; - } - } +export const getVendorManifestByTypeName = (typeName: string, fullStock?: boolean): IVendorManifest | undefined => { for (const vendorInfo of generatableVendors) { if (vendorInfo.TypeName == typeName) { - return generateVendorManifest(vendorInfo); + return generateVendorManifest(vendorInfo, fullStock ?? config.fullyStockedVendors); } } if (typeName in ExportVendors) { const manifest = ExportVendors[typeName]; - return generateVendorManifest({ - _id: { $oid: getVendorOid(typeName) }, - TypeName: typeName, - RandomSeedType: manifest.randomSeedType, - cycleDuration: getCycleDuration(manifest) - }); + return generateVendorManifest( + { + _id: { $oid: getVendorOid(typeName) }, + TypeName: typeName, + RandomSeedType: manifest.randomSeedType, + cycleDuration: getCycleDuration(manifest) + }, + fullStock ?? config.fullyStockedVendors + ); } return undefined; }; export const getVendorManifestByOid = (oid: string): IVendorManifest | undefined => { - for (const vendorManifest of rawVendorManifests) { - if (vendorManifest.VendorInfo._id.$oid == oid) { - return vendorManifest; - } - } for (const vendorInfo of generatableVendors) { if (vendorInfo._id.$oid == oid) { - return generateVendorManifest(vendorInfo); + return generateVendorManifest(vendorInfo, config.fullyStockedVendors); } } for (const [typeName, manifest] of Object.entries(ExportVendors)) { const typeNameOid = getVendorOid(typeName); if (typeNameOid == oid) { - return generateVendorManifest({ - _id: { $oid: typeNameOid }, - TypeName: typeName, - RandomSeedType: manifest.randomSeedType, - cycleDuration: getCycleDuration(manifest) - }); + return generateVendorManifest( + { + _id: { $oid: typeNameOid }, + TypeName: typeName, + RandomSeedType: manifest.randomSeedType, + cycleDuration: getCycleDuration(manifest) + }, + config.fullyStockedVendors + ); } } return undefined; @@ -211,9 +176,26 @@ const getOfferId = (offer: IVendorOffer | IItemManifest): TOfferId => { } }; +let vendorManifestsUsingFullStock = false; const vendorManifestCache: Record = {}; -const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorManifest => { +const clearVendorCache = (): void => { + for (const k of Object.keys(vendorManifestCache)) { + delete vendorManifestCache[k]; + } +}; + +const generateVendorManifest = ( + vendorInfo: IGeneratableVendorInfo, + fullStock: boolean | undefined +): IVendorManifest => { + fullStock ??= config.fullyStockedVendors; + fullStock ??= false; + if (vendorManifestsUsingFullStock != fullStock) { + vendorManifestsUsingFullStock = fullStock; + clearVendorCache(); + } + if (!(vendorInfo.TypeName in vendorManifestCache)) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { cycleOffset, cycleDuration, ...clientVendorInfo } = vendorInfo; @@ -250,7 +232,20 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani const cycleIndex = Math.trunc((now - cycleOffset) / cycleDuration); const rng = new SRng(mixSeeds(vendorSeed, cycleIndex)); const offersToAdd: IVendorOffer[] = []; - if (!manifest.isOneBinPerCycle) { + if (manifest.isOneBinPerCycle) { + if (fullStock) { + for (const rawItem of manifest.items) { + offersToAdd.push(rawItem); + } + } else { + const binThisCycle = cycleIndex % 2; // Note: May want to check the actual number of bins, but this is only used for coda weapons right now. + for (const rawItem of manifest.items) { + if (rawItem.bin == binThisCycle) { + offersToAdd.push(rawItem); + } + } + } + } else { // Compute vendor requirements, subtracting existing offers const remainingItemCapacity: Record = {}; const missingItemsPerBin: Record = {}; @@ -296,12 +291,14 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani manifest.numItems && (manifest.numItems.minValue != manifest.numItems.maxValue || manifest.numItems.minValue != numCountedOffers); - const numItemsTarget = manifest.numItems - ? numUncountedOffers + - (useRng - ? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue) - : manifest.numItems.minValue) - : manifest.items.length; + const numItemsTarget = fullStock + ? numUncountedOffers + numCountedOffers + : manifest.numItems + ? numUncountedOffers + + (useRng + ? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue) + : manifest.numItems.minValue) + : manifest.items.length; let i = 0; const rollableOffers = manifest.items.filter(x => x.probability !== undefined) as (Omit< IVendorOffer, @@ -324,13 +321,6 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani i = 0; } } - } else { - const binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now. - for (const rawItem of manifest.items) { - if (rawItem.bin == binThisCycle) { - offersToAdd.push(rawItem); - } - } } const cycleStart = cycleOffset + cycleIndex * cycleDuration; for (const rawItem of offersToAdd) { @@ -429,34 +419,44 @@ if (args.dev) { logger.warn(`getCycleDuration self test failed`); } - const ads = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest")! - .VendorInfo.ItemManifest; - if ( - ads.length != 5 || - ads[0].Bin != "BIN_4" || - ads[1].Bin != "BIN_3" || - ads[2].Bin != "BIN_2" || - ads[3].Bin != "BIN_1" || - ads[4].Bin != "BIN_0" - ) { - logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`); + for (let i = 0; i != 2; ++i) { + const fullStock = !!i; + + const ads = getVendorManifestByTypeName( + "/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest", + fullStock + )!.VendorInfo.ItemManifest; + if ( + ads.length != 5 || + ads[0].Bin != "BIN_4" || + ads[1].Bin != "BIN_3" || + ads[2].Bin != "BIN_2" || + ads[3].Bin != "BIN_1" || + ads[4].Bin != "BIN_0" + ) { + logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`); + } + + const pall = getVendorManifestByTypeName( + "/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest", + fullStock + )!.VendorInfo.ItemManifest; + if ( + pall.length != 5 || + pall[0].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/HarrowQuestKeyOrnament" || + pall[1].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack" || + pall[2].StoreItem != "/Lotus/StoreItems/Types/StoreItems/CreditBundles/150000Credits" || + pall[3].StoreItem != "/Lotus/StoreItems/Types/Items/MiscItems/Kuva" || + pall[4].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack" + ) { + logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest`); + } } - const pall = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest")! - .VendorInfo.ItemManifest; - if ( - pall.length != 5 || - pall[0].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/HarrowQuestKeyOrnament" || - pall[1].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack" || - pall[2].StoreItem != "/Lotus/StoreItems/Types/StoreItems/CreditBundles/150000Credits" || - pall[3].StoreItem != "/Lotus/StoreItems/Types/Items/MiscItems/Kuva" || - pall[4].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack" - ) { - logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest`); - } - - const cms = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest")! - .VendorInfo.ItemManifest; + const cms = getVendorManifestByTypeName( + "/Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest", + false + )!.VendorInfo.ItemManifest; if ( cms.length != 9 || cms[0].Bin != "BIN_2" || @@ -468,13 +468,15 @@ if (args.dev) { logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest`); } - const temple = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest")! - .VendorInfo.ItemManifest; + const temple = getVendorManifestByTypeName( + "/Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest", + false + )!.VendorInfo.ItemManifest; if (!temple.find(x => x.StoreItem == "/Lotus/StoreItems/Types/Items/MiscItems/Kuva")) { logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest`); } - const nakak = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest")! + const nakak = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest", false)! .VendorInfo.ItemManifest; if ( nakak.length != 10 || diff --git a/src/services/webService.ts b/src/services/webService.ts index d4d1227c..ecc5a494 100644 --- a/src/services/webService.ts +++ b/src/services/webService.ts @@ -6,6 +6,11 @@ import { logger } from "../utils/logger"; import { app } from "../app"; import { AddressInfo } from "node:net"; import ws from "ws"; +import { Account } from "../models/loginModel"; +import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService"; +import { IDatabaseAccountJson } from "../types/loginTypes"; +import { HydratedDocument } from "mongoose"; +import { Agent, WebSocket as UnidiciWebSocket } from "undici"; let httpServer: http.Server | undefined; let httpsServer: https.Server | undefined; @@ -25,7 +30,7 @@ export const startWebServer = (): void => { httpServer = http.createServer(app); httpServer.listen(httpPort, () => { wsServer = new ws.Server({ server: httpServer }); - //wsServer.on("connection", wsOnConnect); + wsServer.on("connection", wsOnConnect); logger.info("HTTP server started on port " + httpPort); @@ -33,17 +38,56 @@ export const startWebServer = (): void => { httpsServer = https.createServer(tlsOptions, app); httpsServer.listen(httpsPort, () => { wssServer = new ws.Server({ server: httpsServer }); - //wssServer.on("connection", wsOnConnect); + wssServer.on("connection", wsOnConnect); logger.info("HTTPS server started on port " + httpsPort); logger.info( "Access the WebUI in your browser at http://localhost" + (httpPort == 80 ? "" : ":" + httpPort) ); + + void runWsSelfTest("wss", httpsPort).then(ok => { + if (!ok) { + logger.warn(`WSS self-test failed. The server may not actually be reachable at port ${httpsPort}.`); + if (process.platform == "win32") { + logger.warn( + `You can check who actually has that port via powershell: Get-Process -Id (Get-NetTCPConnection -LocalPort ${httpsPort}).OwningProcess` + ); + } + } + }); }); }); }; +const runWsSelfTest = (protocol: "ws" | "wss", port: number): Promise => { + return new Promise(resolve => { + // https://github.com/oven-sh/bun/issues/20547 + if (process.versions.bun) { + const client = new WebSocket(`${protocol}://localhost:${port}/custom/selftest`, { + tls: { rejectUnauthorized: false } + } as unknown as string); + client.onmessage = (e): void => { + resolve(e.data == "SpaceNinjaServer"); + }; + client.onerror = client.onclose = (): void => { + resolve(false); + }; + } else { + const agent = new Agent({ connect: { rejectUnauthorized: false } }); + const client = new UnidiciWebSocket(`${protocol}://localhost:${port}/custom/selftest`, { + dispatcher: agent + }); + client.onmessage = (e): void => { + resolve(e.data == "SpaceNinjaServer"); + }; + client.onerror = client.onclose = (): void => { + resolve(false); + }; + } + }); +}; + export const getWebPorts = (): Record<"http" | "https", number | undefined> => { return { http: (httpServer?.address() as AddressInfo | undefined)?.port, @@ -92,11 +136,108 @@ export const stopWebServer = async (): Promise => { await Promise.all(promises); }; -/*const wsOnConnect = (ws: ws, _req: http.IncomingMessage): void => { - ws.on("message", console.log); -};*/ +interface IWsCustomData extends ws { + accountId?: string; +} -export const sendWsBroadcast = (data: T): void => { +interface IWsMsgFromClient { + auth?: { + email: string; + password: string; + isRegister: boolean; + }; + logout?: boolean; +} + +interface IWsMsgToClient { + reload?: boolean; + ports?: { + http: number | undefined; + https: number | undefined; + }; + config_reloaded?: boolean; + auth_succ?: { + id: string; + DisplayName: string; + Nonce: number; + }; + auth_fail?: { + isRegister: boolean; + }; + logged_out?: boolean; + update_inventory?: boolean; +} + +const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => { + if (req.url == "/custom/selftest") { + ws.send("SpaceNinjaServer"); + ws.close(); + return; + } + // eslint-disable-next-line @typescript-eslint/no-misused-promises + ws.on("message", async msg => { + const data = JSON.parse(String(msg)) as IWsMsgFromClient; + if (data.auth) { + let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email }); + if (account) { + if (isCorrectPassword(data.auth.password, account.password)) { + if (!account.Nonce) { + account.ClientType = "webui"; + account.Nonce = createNonce(); + await (account as HydratedDocument).save(); + } + } else { + account = null; + } + } else if (data.auth.isRegister) { + const name = await getUsernameFromEmail(data.auth.email); + account = await createAccount({ + email: data.auth.email, + password: data.auth.password, + ClientType: "webui", + LastLogin: new Date(), + DisplayName: name, + Nonce: createNonce() + }); + } + if (account) { + (ws as IWsCustomData).accountId = account.id; + ws.send( + JSON.stringify({ + auth_succ: { + id: account.id, + DisplayName: account.DisplayName, + Nonce: account.Nonce + } + } satisfies IWsMsgToClient) + ); + } else { + ws.send( + JSON.stringify({ + auth_fail: { + isRegister: data.auth.isRegister + } + } satisfies IWsMsgToClient) + ); + } + } + if (data.logout) { + const accountId = (ws as IWsCustomData).accountId; + (ws as IWsCustomData).accountId = undefined; + await Account.updateOne( + { + _id: accountId, + ClientType: "webui" + }, + { + Nonce: 0 + } + ); + } + }); +}; + +export const sendWsBroadcast = (data: IWsMsgToClient): void => { const msg = JSON.stringify(data); if (wsServer) { for (const client of wsServer.clients) { @@ -109,3 +250,21 @@ export const sendWsBroadcast = (data: T): void => { } } }; + +export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => { + const msg = JSON.stringify(data); + if (wsServer) { + for (const client of wsServer.clients) { + if ((client as IWsCustomData).accountId == accountId) { + client.send(msg); + } + } + } + if (wssServer) { + for (const client of wssServer.clients) { + if ((client as IWsCustomData).accountId == accountId) { + client.send(msg); + } + } + } +}; diff --git a/src/services/worldStateService.ts b/src/services/worldStateService.ts index ea48ef44..a2902f40 100644 --- a/src/services/worldStateService.ts +++ b/src/services/worldStateService.ts @@ -1325,6 +1325,17 @@ export const getWorldState = (buildLabel?: string): IWorldState => { const cheeseInterval = hourInSeconds * 8; const cheeseDuration = hourInSeconds * 2; const cheeseIndex = Math.trunc(timeSecs / cheeseInterval); + let cheeseStart = cheeseIndex * cheeseInterval; + let cheeseEnd = cheeseStart + cheeseDuration; + let cheeseNext = (cheeseIndex + 1) * cheeseInterval; + // Live servers only update the start time once it happens, which makes the + // client show a negative countdown during off-hours. Optionally adjust the + // times so the next activation is always in the future. + if (config.unfaithfulBugFixes?.fixXtraCheeseTimer && timeSecs >= cheeseEnd) { + cheeseStart = cheeseNext; + cheeseEnd = cheeseStart + cheeseDuration; + cheeseNext += cheeseInterval; + } const tmp: ITmp = { cavabegin: "1690761600", PurchasePlatformLockEnabled: true, @@ -1349,9 +1360,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => { ennnd: true, mbrt: true, fbst: { - a: cheeseIndex * cheeseInterval, // This has a bug where the client shows a negative time for "Xtra cheese starts in ..." until it refreshes the world state. This is because we're only providing the new activation as soon as that time/date is reached. However, this is 100% faithful to live. - e: cheeseIndex * cheeseInterval + cheeseDuration, - n: (cheeseIndex + 1) * cheeseInterval + a: cheeseStart, + e: cheeseEnd, + n: cheeseNext }, sfn: [550, 553, 554, 555][halfHour % 4] }; diff --git a/src/types/loginTypes.ts b/src/types/loginTypes.ts index 159d39e9..ef280188 100644 --- a/src/types/loginTypes.ts +++ b/src/types/loginTypes.ts @@ -2,7 +2,7 @@ import { Types } from "mongoose"; export interface IAccountAndLoginResponseCommons { DisplayName: string; - CountryCode: string; + CountryCode?: string; ClientType?: string; CrossPlatformAllowed?: boolean; ForceLogoutVersion?: number; diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index 8cb92ccc..0ccff176 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -10,14 +10,42 @@ import { ICrewMemberClient } from "./inventoryTypes/inventoryTypes"; +export enum PurchaseSource { + Market = 0, + VoidTrader = 1, + SyndicateFavor = 2, + DailyDeal = 3, + Arsenal = 4, + Profile = 5, + Hub = 6, + Vendor = 7, + AppearancePreview = 8, + Museum = 9, + Operator = 10, + PlayerShip = 11, + Crewship = 12, + MenuStyle = 13, + MenuHud = 14, + Chat = 15, + Inventory = 16, + StarChart = 17, + PrimeVaultTrader = 18, + Incubator = 19, + Prompt = 20, + Kaithe = 21, + DuviriWeapon = 22, + UpdateScreen = 23, + Motorcycle = 24 +} + export interface IPurchaseRequest { PurchaseParams: IPurchaseParams; buildLabel: string; } export interface IPurchaseParams { - Source: number; - SourceId?: string; // for Source 1, 7 & 18 + Source: PurchaseSource; + SourceId?: string; // VoidTrader, Vendor, PrimeVaultTrader StoreItem: string; StorePage: string; SearchTerm: string; @@ -25,10 +53,10 @@ export interface IPurchaseParams { Quantity: number; UsePremium: boolean; ExpectedPrice: number; - SyndicateTag?: string; // for Source 2 - UseFreeFavor?: boolean; // for Source 2 - ExtraPurchaseInfoJson?: string; // for Source 7 - IsWeekly?: boolean; // for Source 7 + SyndicateTag?: string; // SyndicateFavor + UseFreeFavor?: boolean; // SyndicateFavor + ExtraPurchaseInfoJson?: string; // Vendor + IsWeekly?: boolean; // Vendor } export type IInventoryChanges = { diff --git a/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json b/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json deleted file mode 100644 index 07f94813..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json +++ /dev/null @@ -1,300 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e01c96976e97d6b802e" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/EntratiFragmentVendorProductsManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/SeriglassShard", - "ItemPrices": [ - { - "ItemCount": 20, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8390" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDeimosBouncy", - "ItemPrices": [ - { - "ItemCount": 50, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8391" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDeimosBreakthrough", - "ItemPrices": [ - { - "ItemCount": 50, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8392" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDeimosCatacombs", - "ItemPrices": [ - { - "ItemCount": 50, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8393" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDeimosDownfall", - "ItemPrices": [ - { - "ItemCount": 50, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8394" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDeimosObsession", - "ItemPrices": [ - { - "ItemCount": 50, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8395" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDeimosTunnels", - "ItemPrices": [ - { - "ItemCount": 50, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e8396" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Deimos/FatherTokenShipDeco", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonA", - "ProductCategory": "MiscItems" - }, - { - "ItemCount": 5, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e83f1" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Deimos/LisetPropEntratiLamp", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonB", - "ItemCount": 12, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e83f2" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Deimos/LisetPropInfestedCrate", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonA", - "ItemCount": 11, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e83f3" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Deimos/LisetPropInfestedCystC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e83f4" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/RequiemRisGlyph", - "ItemPrices": [ - { - "ItemCount": 15, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b10ba592c4c95e83f5" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Deimos/MotherTokenShipDeco", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonB", - "ProductCategory": "MiscItems" - }, - { - "ItemCount": 5, - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentRareA", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e83f6" - } - } - ], - "PropertyTextHash": "DB953EE163A65B3BCC0552902321D791", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestFishmonger.json b/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestFishmonger.json deleted file mode 100644 index fd6a561b..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestFishmonger.json +++ /dev/null @@ -1,241 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e01c96976e97d6b8009" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/HivemindCommisionsManifestFishmonger", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishFPartItem", - "ItemCount": 6, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 16, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 63978959, - "Id": { - "$oid": "66fd60b10ba592c4c95e82cc" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem", - "ItemCount": 5, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishDPartItem", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3808064409, - "Id": { - "$oid": "66fd60b10ba592c4c95e82cd" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishEPartItem", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3849710569, - "Id": { - "$oid": "66fd60b10ba592c4c95e82d0" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericInfestedFishPartItem", - "ItemCount": 5, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1687111317, - "Id": { - "$oid": "66fd60b10ba592c4c95e82d1" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishAPartItem", - "ItemCount": 4, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2267414276, - "Id": { - "$oid": "66fd60b10ba592c4c95e82d2" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericInfestedFishPartItem", - "ItemCount": 6, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericSharedFishPartItem", - "ItemCount": 6, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1497494256, - "Id": { - "$oid": "66fd60b10ba592c4c95e82d3" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericInfestedFishPartItem", - "ItemCount": 5, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2883527039, - "Id": { - "$oid": "66fd60b10ba592c4c95e82d4" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Daughter/DaughterTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishGPartItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 12, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 4116691539, - "Id": { - "$oid": "66fd60b10ba592c4c95e82d5" - } - } - ], - "PropertyTextHash": "54B6992C6314367F8EEA74B7F1A1C352", - "RandomSeedType": "VRST_FLAVOUR_TEXT", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestPetVendor.json b/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestPetVendor.json deleted file mode 100644 index 44966e70..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestPetVendor.json +++ /dev/null @@ -1,287 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e03c96976e97d6b80a3" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/HivemindCommisionsManifestPetVendor", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMaggotRare", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMaggotCommon", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2707699975, - "Id": { - "$oid": "66fd60b10ba592c4c95e8897" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedPredatorCommon", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMaggotCommon", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3610714639, - "Id": { - "$oid": "66fd60b10ba592c4c95e8898" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedPredatorCommon", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMaggotRare", - "ItemCount": 1, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1782149988, - "Id": { - "$oid": "66fd60b10ba592c4c95e8899" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMergooCommon", - "ItemCount": 3, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2149416825, - "Id": { - "$oid": "66fd60b10ba592c4c95e889a" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedCritterRare", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedKdriveUncommon", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 890863265, - "Id": { - "$oid": "66fd60b10ba592c4c95e889b" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedCritterCommon", - "ItemCount": 4, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedPredatorCommon", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2507606934, - "Id": { - "$oid": "66fd60b10ba592c4c95e889c" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedPredatorRare", - "ItemCount": 5, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1037784729, - "Id": { - "$oid": "66fd60b10ba592c4c95e889e" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMaggotCommon", - "ItemCount": 4, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedCritterCommon", - "ItemCount": 4, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2048707501, - "Id": { - "$oid": "66fd60b10ba592c4c95e889f" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedKdriveRare", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedPredatorCommon", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 4038149313, - "Id": { - "$oid": "66fd60b10ba592c4c95e88a0" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Son/SonTaskD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedMergooCommon", - "ItemCount": 3, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/AnimalTagInfestedPredatorRare", - "ItemCount": 3, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2155290001, - "Id": { - "$oid": "66fd60b10ba592c4c95e88a1" - } - } - ], - "PropertyTextHash": "61E66B4E9E5A121DD06A476AE2A81B24", - "RandomSeedType": "VRST_FLAVOUR_TEXT", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestProspector.json b/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestProspector.json deleted file mode 100644 index 7b1d1fad..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestProspector.json +++ /dev/null @@ -1,312 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e01c96976e97d6b7ff1" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/HivemindCommisionsManifestProspector", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemBItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1370972414, - "Id": { - "$oid": "66fd60b20ba592c4c95e8ef8" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreBItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosUncommonGemAItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosUncommonOreAItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2361790143, - "Id": { - "$oid": "66fd60b20ba592c4c95e8ef9" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemAItem", - "ItemCount": 6, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 472210739, - "Id": { - "$oid": "66fd60b20ba592c4c95e8efb" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreBItem", - "ItemCount": 12, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 15, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3072462886, - "Id": { - "$oid": "66fd60b20ba592c4c95e8efd" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemAItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 767765909, - "Id": { - "$oid": "66fd60b20ba592c4c95e8efe" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosEidolonGemAItem", - "ItemCount": 5, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosEidolonGemBItem", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosRareOreAItem", - "ItemCount": 22, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 512512880, - "Id": { - "$oid": "66fd60b20ba592c4c95e8eff" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemAItem", - "ItemCount": 6, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2037734419, - "Id": { - "$oid": "66fd60b20ba592c4c95e8f00" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosUncommonOreAItem", - "ItemCount": 13, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1433662587, - "Id": { - "$oid": "66fd60b20ba592c4c95e8f01" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonOreAItem", - "ItemCount": 12, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemAItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1618492734, - "Id": { - "$oid": "66fd60b20ba592c4c95e8f02" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Otak/OtakTaskD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosUncommonGemAItem", - "ItemCount": 7, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemBItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosRareOreAItem", - "ItemCount": 12, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 4032699594, - "Id": { - "$oid": "66fd60b20ba592c4c95e8f03" - } - } - ], - "PropertyTextHash": "0AC3C284471037011B36EC51238D13A9", - "RandomSeedType": "VRST_FLAVOUR_TEXT", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestTokenVendor.json b/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestTokenVendor.json deleted file mode 100644 index dcc45dc9..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestTokenVendor.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e03c96976e97d6b80d2" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/HivemindCommisionsManifestTokenVendor", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonC", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonA", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonB", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonA", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1415858946, - "Id": { - "$oid": "670a47b1872b2325705e746c" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonB", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonA", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonA", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonB", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3178511462, - "Id": { - "$oid": "670a47b1872b2325705e746e" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonA", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonC", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3313207881, - "Id": { - "$oid": "670a47b1872b2325705e7471" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonB", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2241288767, - "Id": { - "$oid": "670a47b1872b2325705e7472" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonB", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3395082536, - "Id": { - "$oid": "670a47b1872b2325705e7473" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonC", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonB", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 493457277, - "Id": { - "$oid": "670a47b1872b2325705e7474" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Grandmother/GrandmotherTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentUncommonB", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Deimos/EntratiFragmentCommonB", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 4225814786, - "Id": { - "$oid": "670a47b1872b2325705e7475" - } - } - ], - "PropertyTextHash": "58884EC7ECE7D22AD4BD9E9B436C37A8", - "RandomSeedType": "VRST_FLAVOUR_TEXT", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestWeaponsmith.json b/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestWeaponsmith.json deleted file mode 100644 index 9a3c5805..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestWeaponsmith.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e02c96976e97d6b8049" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/HivemindCommisionsManifestWeaponsmith", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 16, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2438288725, - "Id": { - "$oid": "66fd60b00ba592c4c95e7caf" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Game/FishBait/Infested/OrokinFishBaitA", - "ItemCount": 6, - "ProductCategory": "Consumables" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfMapricoFruitItem", - "ItemCount": 21, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Game/FishBait/Infested/InfestedFishBaitA", - "ItemCount": 6, - "ProductCategory": "Consumables" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2431016296, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb2" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfMapricoFruitItem", - "ItemCount": 16, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 18484856, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb3" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfMapricoFruitItem", - "ItemCount": 14, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2278976516, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb4" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Game/FishBait/Infested/OrokinFishBaitA", - "ItemCount": 7, - "ProductCategory": "Consumables" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/OrbStoneItem", - "ItemCount": 25, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Game/FishBait/Infested/InfestedFishBaitA", - "ItemCount": 6, - "ProductCategory": "Consumables" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3150323898, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb5" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfMapricoFruitItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 3971758486, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb6" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 17, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/OrbStoneItem", - "ItemCount": 18, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2512835718, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb7" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/OrbStoneItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 825411410, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb8" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Father/FatherTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 22, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/OrbStoneItem", - "ItemCount": 12, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2383349671, - "Id": { - "$oid": "66fd60b00ba592c4c95e7cb9" - } - } - ], - "PropertyTextHash": "CE9413585756FA39B793A9814E74E49F", - "RandomSeedType": "VRST_FLAVOUR_TEXT", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosHivemindTokenVendorManifest.json b/static/fixed_responses/getVendorInfo/DeimosHivemindTokenVendorManifest.json deleted file mode 100644 index 1d165fc7..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosHivemindTokenVendorManifest.json +++ /dev/null @@ -1,286 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5fb70313c96976e97d6be6fe" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/HivemindTokenVendorManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedySonB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem", - "ItemCount": 36, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishEPartItem", - "ItemCount": 36, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 379215713, - "Id": { - "$oid": "66fd60b20ba592c4c95e9308" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedyMotherB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericInfestedFishPartItem", - "ItemCount": 80, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 32, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 28, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2534781881, - "Id": { - "$oid": "66fd60b20ba592c4c95e9309" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedyDaughterB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosUncommonGemAItem", - "ItemCount": 28, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 32, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishAPartItem", - "ItemCount": 32, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 1507786123, - "Id": { - "$oid": "66fd60b20ba592c4c95e930a" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedySonA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosRareGemAItem", - "ItemCount": 15, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemAItem", - "ItemCount": 30, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 21, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 616241643, - "Id": { - "$oid": "66fd60b20ba592c4c95e930b" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedyOtakA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem", - "ItemCount": 21, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem", - "ItemCount": 27, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishEPartItem", - "ItemCount": 27, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2888479655, - "Id": { - "$oid": "66fd60b20ba592c4c95e930c" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedyGrandmotherA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemBItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem", - "ItemCount": 28, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 24, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosCommonGemAItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2874726481, - "Id": { - "$oid": "66fd60b20ba592c4c95e930d" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedyFatherA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericSharedFishPartItem", - "ItemCount": 75, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Deimos/DeimosUncommonGemAItem", - "ItemCount": 27, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/OrbStoneItem", - "ItemCount": 30, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 274676857, - "Id": { - "$oid": "66fd60b20ba592c4c95e930e" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/Deimos/Remedies/RemedyDaughterA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Resources/InfGorgaricusSeedItem", - "ItemCount": 24, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem", - "ItemCount": 30, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Deimos/FishParts/DeimosGenericSharedFishPartItem", - "ItemCount": 51, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "LocTagRandSeed": 2487943761, - "Id": { - "$oid": "66fd60b20ba592c4c95e930f" - } - } - ], - "PropertyTextHash": "C34BF0BEDEAF7CBB0EEBFFECDFD6646D", - "RandomSeedType": "VRST_FLAVOUR_TEXT", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DeimosPetVendorManifest.json b/static/fixed_responses/getVendorInfo/DeimosPetVendorManifest.json deleted file mode 100644 index 76d738ea..00000000 --- a/static/fixed_responses/getVendorInfo/DeimosPetVendorManifest.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5f456e02c96976e97d6b8080" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/PetVendorManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedNexiferaRare", - "PremiumPrice": [35, 35], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89f6" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedNexiferaUncommon", - "PremiumPrice": [22, 22], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89f7" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedMergooUncommon", - "PremiumPrice": [28, 28], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89f8" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedKdriveUncommon", - "PremiumPrice": [25, 25], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89f9" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedZongroCommon", - "PremiumPrice": [14, 14], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89fa" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedPredatorCommon", - "PremiumPrice": [12, 12], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89fb" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedMergooCommon", - "PremiumPrice": [13, 13], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89fc" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/Deimos/AnimalTagInfestedKdriveCommon", - "PremiumPrice": [14, 14], - "Bin": "BIN_0", - "QuantityMultiplier": 5, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b10ba592c4c95e89fd" - } - } - ], - "PropertyTextHash": "F14C6B6A61D7585A10537995661F5220", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json b/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json deleted file mode 100644 index 031db476..00000000 --- a/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json +++ /dev/null @@ -1,321 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "64493ca759e9b164c86a2e14" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Duviri/AcrithisVendorManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/Items/DangerRoom/DangerRoomTileDuviriDragonArena", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_5", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b00ba592c4c95e7d88" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Recipes/Components/FormaBlueprint", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b00ba592c4c95e7deb" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/UtilityUnlocker", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b00ba592c4c95e7dec" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 5000, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b00ba592c4c95e7ded" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b00ba592c4c95e7dee" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 5000, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "670c5e12576f461f1e5e739c" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Plastids", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriPlantItemD", - "ItemCount": 40, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": true, - "Id": { - "$oid": "6710c312fa0b2c5cd85e73c3" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Duviri/DUVxPlanterHangingPot", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriPlantItemE", - "ItemCount": 51, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6710c312fa0b2c5cd85e73c6" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Duviri/DUVxPlanterPotB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriRockItem", - "ItemCount": 44, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6710c312fa0b2c5cd85e73c7" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/NeuralSensor", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriPlantItemA", - "ItemCount": 52, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 3, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": true, - "Id": { - "$oid": "6710c312fa0b2c5cd85e73c8" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/ControlModule", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriPlantItemF", - "ItemCount": 42, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 3, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": true, - "Id": { - "$oid": "6710c312fa0b2c5cd85e73c9" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/PhotoboothTileDuviriArenaOpera", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriProcessedItem", - "ItemCount": 240, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b00ba592c4c95e7ddd" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/HealthWhileUsingChanneledAbilities", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriDragonDropItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b00ba592c4c95e7e01" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Upgrades/Boons/DuviriVendorBoonItem", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/Duviri/Resource/DuviriPlantItemG", - "ItemCount": 50, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_4", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": true, - "Id": { - "$oid": "6711a412ba1ba01e405e739c" - } - } - ], - "PropertyTextHash": "9EE40048EB685549ACA3D01AB1F65BF2", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json b/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json deleted file mode 100644 index 624e2d33..00000000 --- a/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json +++ /dev/null @@ -1,245 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "6579d82b553a20c6fc0067ca" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/EntratiLabs/EntratiLabVendorManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar", - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "RotatedWeekly": true, - "Affiliation": "EntratiLabSyndicate", - "MinAffiliationRank": 5, - "ReductionPerPositiveRank": 0, - "IncreasePerNegativeRank": 0, - "StandingCost": 30000, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b20ba592c4c95e920d" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal", - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "RotatedWeekly": true, - "Affiliation": "EntratiLabSyndicate", - "MinAffiliationRank": 5, - "ReductionPerPositiveRank": 0, - "IncreasePerNegativeRank": 0, - "StandingCost": 30000, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b20ba592c4c95e920e" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalNira", - "Bin": "BIN_3", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "RotatedWeekly": true, - "Affiliation": "EntratiLabSyndicate", - "MinAffiliationRank": 5, - "ReductionPerPositiveRank": 0, - "IncreasePerNegativeRank": 0, - "StandingCost": 30000, - "AllowMultipurchase": false, - "Id": { - "$oid": "66fd60b20ba592c4c95e920f" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/EntratiLabs/ORKxLabStool", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabDogTagUncommon", - "ItemCount": 2, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemA", - "ItemCount": 22, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 18, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9270" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/EntratiLabs/ORKxLabChairA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 15, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemA", - "ItemCount": 19, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemB", - "ItemCount": 19, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9271" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/EntratiLabs/ORKxLabLightWallCandleA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 12, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabDogTagCommon", - "ItemCount": 3, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9272" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/EntratiLabs/ORKxLabLightChandelierD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemB", - "ItemCount": 8, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabDogTagCommon", - "ItemCount": 3, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9273" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/EntratiLabs/ORKxLabLightChandelierB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemA", - "ItemCount": 12, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabDogTagCommon", - "ItemCount": 2, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9274" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/EntratiLabs/ORKxLabLightChandelierA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 15, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemA", - "ItemCount": 13, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9275" - } - } - ], - "PropertyTextHash": "44DA3839E6F7BDB32ACED53F2B0BE14E", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json b/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json deleted file mode 100644 index 41a9454e..00000000 --- a/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "6579d82b553a20c6fc0067ae" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/EntratiLabs/EntratiLabsCommisionsManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/EntratiLabs/LoidTaskC", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemB", - "ItemCount": 17, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 30, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_2", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "670a2b928ac7854ac55e73d3" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/EntratiLabs/LoidTaskB", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 20, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/EntratiLabMiscItemA", - "ItemCount": 228, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "670a2b928ac7854ac55e73d4" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/Tasks/EntratiLabs/LoidTaskA", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Gameplay/EntratiLab/Resources/MurmurItem", - "ItemCount": 15, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Gameplay/Zariman/Resources/ZarimanMiscItemB", - "ItemCount": 1, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "670a2b928ac7854ac55e73d5" - } - } - ], - "PropertyTextHash": "60C4D85A8DE5E6538AD23CDDFEEF0422", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json b/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json deleted file mode 100644 index 59afcd65..00000000 --- a/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "67dadc30e4b6e0e5979c8d6a" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/TheHex/Nova1999ConquestShopManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/1999StickersPackEchoesArchimedea", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "67db32b983b2ad79a9c1c18c" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFree", - "ItemPrices": [ - { - "ItemCount": 1, - "ItemType": "/Lotus/Types/Items/MiscItems/1999FreeStickersPack", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "67db32b983b2ad79a9c1c18d" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/1999StickersPackEchoesArchimedeaFixed", - "ItemPrices": [ - { - "ItemCount": 1, - "ItemType": "/Lotus/Types/Items/MiscItems/1999FixedStickersPack", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "67db32b983b2ad79a9c1c18e" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/SyndicateVosforPack", - "ItemPrices": [ - { - "ItemCount": 6, - "ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "67db32b983b2ad79a9c1c18f" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/StickerPictureFrame", - "ItemPrices": [ - { - "ItemCount": 10, - "ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "67db32b983b2ad79a9c1c190" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Utility/AbilityRadiationProcsCreateUniversalOrbsOnKill", - "ItemPrices": [ - { - "ItemCount": 5, - "ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "67db32b983b2ad79a9c1c191" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Offensive/AbilityHeatProcsGiveCritChance", - "ItemPrices": [ - { - "ItemCount": 5, - "ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "67db32b983b2ad79a9c1c192" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Defensive/InvulnerabilityOnDeathOnMercyKill", - "ItemPrices": [ - { - "ItemCount": 5, - "ItemType": "/Lotus/Types/Items/MiscItems/1999ConquestBucks", - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - }, - "PurchaseQuantityLimit": 1, - "AllowMultipurchase": false, - "Id": { - "$oid": "67db32b983b2ad79a9c1c193" - } - } - ], - "PropertyTextHash": "CB7D0E807FD5E2BCD059195201D963B9", - "RequiredGoalTag": "", - "Expiry": { - "$date": { - "$numberLong": "2051240400000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json b/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json deleted file mode 100644 index 521260cf..00000000 --- a/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5991d5e6bcc718474ee90c15" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Ostron/PetVendorManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/LisetPropOstBirdCage", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Gems/Eidolon/UncommonOreAAlloyAItem", - "ItemCount": 10, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/DayUncommonFishBPartItem", - "ItemCount": 8, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9a8e" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/KubrowColorPackDrahk", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/DayCommonFishBPartItem", - "ItemCount": 14, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothCommonFishBPartItem", - "ItemCount": 13, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9a8f" - } - }, - { - "StoreItem": "/Lotus/Types/StoreItems/Packages/KubrowColorPackFeral", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothCommonFishAPartItem", - "ItemCount": 19, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonOreBAlloyBItem", - "ItemCount": 34, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "66fd60b20ba592c4c95e9a90" - } - } - ], - "PropertyTextHash": "3D85F1A0A2B62734AE90370DEC214C26", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json b/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json deleted file mode 100644 index 67b234a2..00000000 --- a/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "VendorInfo": { - "_id": { - "$oid": "5be4a159b144f3cdf1c22edf" - }, - "TypeName": "/Lotus/Types/Game/VendorManifests/Solaris/DebtTokenVendorRepossessionsManifest", - "ItemManifest": [ - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Venus/SUToolBox", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Solaris/DebtTokenB", - "ItemCount": 6, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6711a412ba1ba01e405e739d" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Venus/SUBookAOpen", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Solaris/DebtTokenC", - "ItemCount": 6, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6711a412ba1ba01e405e739e" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Venus/SUFoodCans", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Solaris/DebtTokenC", - "ItemCount": 7, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6711a412ba1ba01e405e739f" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Venus/SUTechToolD", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Solaris/DebtTokenD", - "ItemCount": 5, - "ProductCategory": "MiscItems" - }, - { - "ItemType": "/Lotus/Types/Items/Solaris/DebtTokenA", - "ItemCount": 15, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_1", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6711a412ba1ba01e405e73a0" - } - }, - { - "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Venus/SUContainerCrate", - "ItemPrices": [ - { - "ItemType": "/Lotus/Types/Items/Solaris/DebtTokenA", - "ItemCount": 9, - "ProductCategory": "MiscItems" - } - ], - "Bin": "BIN_0", - "QuantityMultiplier": 1, - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - }, - "AllowMultipurchase": true, - "Id": { - "$oid": "6711a412ba1ba01e405e73a1" - } - } - ], - "PropertyTextHash": "E0E83157D73468DC578403CB9EBA9DA6", - "Expiry": { - "$date": { - "$numberLong": "9999999000000" - } - } - } -} diff --git a/static/webui/index.html b/static/webui/index.html index 5b92f727..e7fba33c 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -37,7 +37,7 @@