chore: auto-generate guild advertisment vendor (#1845)
With this, preprocessing is simplified to just refreshing expiry dates. No real change to auto-generation logic. Reviewed-on: #1845 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
3f6734ac1c
commit
90e97d7888
@ -1,13 +1,7 @@
|
|||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||||
import { CRng, mixSeeds } from "@/src/services/rngService";
|
import { CRng, mixSeeds } from "@/src/services/rngService";
|
||||||
import { IMongoDate } from "@/src/types/commonTypes";
|
import { IMongoDate } from "@/src/types/commonTypes";
|
||||||
import {
|
import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
|
||||||
IItemManifestPreprocessed,
|
|
||||||
IRawVendorManifest,
|
|
||||||
IVendorInfo,
|
|
||||||
IVendorInfoPreprocessed,
|
|
||||||
IVendorManifestPreprocessed
|
|
||||||
} from "@/src/types/vendorTypes";
|
|
||||||
import { ExportVendors, IRange } from "warframe-public-export-plus";
|
import { ExportVendors, IRange } from "warframe-public-export-plus";
|
||||||
|
|
||||||
import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
|
import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
|
||||||
@ -24,7 +18,6 @@ import DeimosProspectorVendorManifest from "@/static/fixed_responses/getVendorIn
|
|||||||
import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json";
|
import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json";
|
||||||
import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json";
|
import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json";
|
||||||
import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json";
|
import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json";
|
||||||
import GuildAdvertisementVendorManifest from "@/static/fixed_responses/getVendorInfo/GuildAdvertisementVendorManifest.json";
|
|
||||||
import HubsIronwakeDondaVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsIronwakeDondaVendorManifest.json";
|
import HubsIronwakeDondaVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsIronwakeDondaVendorManifest.json";
|
||||||
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
|
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
|
||||||
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
|
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
|
||||||
@ -39,7 +32,7 @@ import SolarisProspectorVendorManifest from "@/static/fixed_responses/getVendorI
|
|||||||
import TeshinHardModeVendorManifest from "@/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json";
|
import TeshinHardModeVendorManifest from "@/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json";
|
||||||
import ZarimanCommisionsManifestArchimedean from "@/static/fixed_responses/getVendorInfo/ZarimanCommisionsManifestArchimedean.json";
|
import ZarimanCommisionsManifestArchimedean from "@/static/fixed_responses/getVendorInfo/ZarimanCommisionsManifestArchimedean.json";
|
||||||
|
|
||||||
const rawVendorManifests: IRawVendorManifest[] = [
|
const rawVendorManifests: IVendorManifest[] = [
|
||||||
ArchimedeanVendorManifest,
|
ArchimedeanVendorManifest,
|
||||||
DeimosEntratiFragmentVendorProductsManifest,
|
DeimosEntratiFragmentVendorProductsManifest,
|
||||||
DeimosFishmongerVendorManifest,
|
DeimosFishmongerVendorManifest,
|
||||||
@ -54,7 +47,6 @@ const rawVendorManifests: IRawVendorManifest[] = [
|
|||||||
DuviriAcrithisVendorManifest,
|
DuviriAcrithisVendorManifest,
|
||||||
EntratiLabsEntratiLabsCommisionsManifest,
|
EntratiLabsEntratiLabsCommisionsManifest,
|
||||||
EntratiLabsEntratiLabVendorManifest,
|
EntratiLabsEntratiLabVendorManifest,
|
||||||
GuildAdvertisementVendorManifest, // uses preprocessing
|
|
||||||
HubsIronwakeDondaVendorManifest, // uses preprocessing
|
HubsIronwakeDondaVendorManifest, // uses preprocessing
|
||||||
HubsRailjackCrewMemberVendorManifest,
|
HubsRailjackCrewMemberVendorManifest,
|
||||||
MaskSalesmanManifest,
|
MaskSalesmanManifest,
|
||||||
@ -71,8 +63,8 @@ const rawVendorManifests: IRawVendorManifest[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
|
interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
|
||||||
cycleOffset: number;
|
cycleOffset?: number;
|
||||||
cycleDuration: number;
|
cycleDuration?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const generatableVendors: IGeneratableVendorInfo[] = [
|
const generatableVendors: IGeneratableVendorInfo[] = [
|
||||||
@ -99,9 +91,13 @@ const generatableVendors: IGeneratableVendorInfo[] = [
|
|||||||
_id: { $oid: "5be4a159b144f3cdf1c22efa" },
|
_id: { $oid: "5be4a159b144f3cdf1c22efa" },
|
||||||
TypeName: "/Lotus/Types/Game/VendorManifests/Solaris/DebtTokenVendorManifest",
|
TypeName: "/Lotus/Types/Game/VendorManifests/Solaris/DebtTokenVendorManifest",
|
||||||
PropertyTextHash: "A39621049CA3CA13761028CD21C239EF",
|
PropertyTextHash: "A39621049CA3CA13761028CD21C239EF",
|
||||||
RandomSeedType: "VRST_FLAVOUR_TEXT",
|
RandomSeedType: "VRST_FLAVOUR_TEXT"
|
||||||
cycleOffset: 1734307200_000,
|
},
|
||||||
cycleDuration: unixTimesInMs.hour
|
{
|
||||||
|
_id: { $oid: "61ba123467e5d37975aeeb03" },
|
||||||
|
TypeName: "/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest",
|
||||||
|
PropertyTextHash: "255AFE2169BAE4130B4B20D7C55D14FA",
|
||||||
|
RandomSeedType: "VRST_FLAVOUR_TEXT"
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
// _id: { $oid: "5dbb4c41e966f7886c3ce939" },
|
// _id: { $oid: "5dbb4c41e966f7886c3ce939" },
|
||||||
@ -110,7 +106,7 @@ const generatableVendors: IGeneratableVendorInfo[] = [
|
|||||||
// }
|
// }
|
||||||
];
|
];
|
||||||
|
|
||||||
export const getVendorManifestByTypeName = (typeName: string): IVendorManifestPreprocessed | undefined => {
|
export const getVendorManifestByTypeName = (typeName: string): IVendorManifest | undefined => {
|
||||||
for (const vendorManifest of rawVendorManifests) {
|
for (const vendorManifest of rawVendorManifests) {
|
||||||
if (vendorManifest.VendorInfo.TypeName == typeName) {
|
if (vendorManifest.VendorInfo.TypeName == typeName) {
|
||||||
return preprocessVendorManifest(vendorManifest);
|
return preprocessVendorManifest(vendorManifest);
|
||||||
@ -124,7 +120,7 @@ export const getVendorManifestByTypeName = (typeName: string): IVendorManifestPr
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getVendorManifestByOid = (oid: string): IVendorManifestPreprocessed | undefined => {
|
export const getVendorManifestByOid = (oid: string): IVendorManifest | undefined => {
|
||||||
for (const vendorManifest of rawVendorManifests) {
|
for (const vendorManifest of rawVendorManifests) {
|
||||||
if (vendorManifest.VendorInfo._id.$oid == oid) {
|
if (vendorManifest.VendorInfo._id.$oid == oid) {
|
||||||
return preprocessVendorManifest(vendorManifest);
|
return preprocessVendorManifest(vendorManifest);
|
||||||
@ -138,29 +134,20 @@ export const getVendorManifestByOid = (oid: string): IVendorManifestPreprocessed
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const preprocessVendorManifest = (originalManifest: IRawVendorManifest): IVendorManifestPreprocessed => {
|
const preprocessVendorManifest = (originalManifest: IVendorManifest): IVendorManifest => {
|
||||||
if (Date.now() >= parseInt(originalManifest.VendorInfo.Expiry.$date.$numberLong)) {
|
if (Date.now() >= parseInt(originalManifest.VendorInfo.Expiry.$date.$numberLong)) {
|
||||||
const manifest = structuredClone(originalManifest);
|
const manifest = structuredClone(originalManifest);
|
||||||
const info = manifest.VendorInfo;
|
const info = manifest.VendorInfo;
|
||||||
refreshExpiry(info.Expiry);
|
refreshExpiry(info.Expiry);
|
||||||
for (const offer of info.ItemManifest) {
|
for (const offer of info.ItemManifest) {
|
||||||
const iteration = refreshExpiry(offer.Expiry);
|
refreshExpiry(offer.Expiry);
|
||||||
if (offer.ItemPrices) {
|
|
||||||
for (const price of offer.ItemPrices) {
|
|
||||||
if (typeof price.ItemType != "string") {
|
|
||||||
const itemSeed = parseInt(offer.Id.$oid.substring(16), 16);
|
|
||||||
const rng = new CRng(mixSeeds(itemSeed, iteration));
|
|
||||||
price.ItemType = rng.randomElement(price.ItemType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return manifest as IVendorManifestPreprocessed;
|
return manifest;
|
||||||
}
|
}
|
||||||
return originalManifest as IVendorManifestPreprocessed;
|
return originalManifest;
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshExpiry = (expiry: IMongoDate): number => {
|
const refreshExpiry = (expiry: IMongoDate): void => {
|
||||||
const period = parseInt(expiry.$date.$numberLong);
|
const period = parseInt(expiry.$date.$numberLong);
|
||||||
if (Date.now() >= period) {
|
if (Date.now() >= period) {
|
||||||
const epoch = 1734307200_000; // Monday (for weekly schedules)
|
const epoch = 1734307200_000; // Monday (for weekly schedules)
|
||||||
@ -168,9 +155,7 @@ const refreshExpiry = (expiry: IMongoDate): number => {
|
|||||||
const start = epoch + iteration * period;
|
const start = epoch + iteration * period;
|
||||||
const end = start + period;
|
const end = start + period;
|
||||||
expiry.$date.$numberLong = end.toString();
|
expiry.$date.$numberLong = end.toString();
|
||||||
return iteration;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const toRange = (value: IRange | number): IRange => {
|
const toRange = (value: IRange | number): IRange => {
|
||||||
@ -180,9 +165,9 @@ const toRange = (value: IRange | number): IRange => {
|
|||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const vendorInfoCache: Record<string, IVendorInfoPreprocessed> = {};
|
const vendorInfoCache: Record<string, IVendorInfo> = {};
|
||||||
|
|
||||||
const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorManifestPreprocessed => {
|
const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorManifest => {
|
||||||
if (!(vendorInfo.TypeName in vendorInfoCache)) {
|
if (!(vendorInfo.TypeName in vendorInfoCache)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { cycleOffset, cycleDuration, ...clientVendorInfo } = vendorInfo;
|
const { cycleOffset, cycleDuration, ...clientVendorInfo } = vendorInfo;
|
||||||
@ -205,7 +190,9 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
|
|
||||||
// Add new offers
|
// Add new offers
|
||||||
const vendorSeed = parseInt(vendorInfo._id.$oid.substring(16), 16);
|
const vendorSeed = parseInt(vendorInfo._id.$oid.substring(16), 16);
|
||||||
const cycleIndex = Math.trunc((Date.now() - vendorInfo.cycleOffset) / vendorInfo.cycleDuration);
|
const cycleOffset = vendorInfo.cycleOffset ?? 1734307200_000;
|
||||||
|
const cycleDuration = vendorInfo.cycleDuration ?? unixTimesInMs.hour;
|
||||||
|
const cycleIndex = Math.trunc((Date.now() - cycleOffset) / cycleDuration);
|
||||||
const rng = new CRng(mixSeeds(vendorSeed, cycleIndex));
|
const rng = new CRng(mixSeeds(vendorSeed, cycleIndex));
|
||||||
const manifest = ExportVendors[vendorInfo.TypeName];
|
const manifest = ExportVendors[vendorInfo.TypeName];
|
||||||
const offersToAdd = [];
|
const offersToAdd = [];
|
||||||
@ -226,14 +213,19 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
offersToAdd.push(rawItem);
|
offersToAdd.push(rawItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For most vendors, the offers seem to roughly be in reverse order from the manifest. Coda weapons are an odd exception.
|
||||||
|
if (!manifest.isOneBinPerCycle) {
|
||||||
|
offersToAdd.reverse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const cycleStart = vendorInfo.cycleOffset + cycleIndex * vendorInfo.cycleDuration;
|
const cycleStart = cycleOffset + cycleIndex * cycleDuration;
|
||||||
for (const rawItem of offersToAdd) {
|
for (const rawItem of offersToAdd) {
|
||||||
const durationHoursRange = toRange(rawItem.durationHours);
|
const durationHoursRange = toRange(rawItem.durationHours);
|
||||||
const expiry =
|
const expiry =
|
||||||
cycleStart +
|
cycleStart +
|
||||||
rng.randomInt(durationHoursRange.minValue, durationHoursRange.maxValue) * unixTimesInMs.hour;
|
rng.randomInt(durationHoursRange.minValue, durationHoursRange.maxValue) * unixTimesInMs.hour;
|
||||||
const item: IItemManifestPreprocessed = {
|
const item: IItemManifest = {
|
||||||
StoreItem: rawItem.storeItem,
|
StoreItem: rawItem.storeItem,
|
||||||
ItemPrices: rawItem.itemPrices?.map(itemPrice => ({ ...itemPrice, ProductCategory: "MiscItems" })),
|
ItemPrices: rawItem.itemPrices?.map(itemPrice => ({ ...itemPrice, ProductCategory: "MiscItems" })),
|
||||||
Bin: "BIN_" + rawItem.bin,
|
Bin: "BIN_" + rawItem.bin,
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import { IMongoDate, IOid } from "./commonTypes";
|
import { IMongoDate, IOid } from "./commonTypes";
|
||||||
|
|
||||||
export interface IItemPrice {
|
export interface IItemPrice {
|
||||||
ItemType: string | string[]; // If string[], preprocessing will use RNG to pick one for the current period.
|
ItemType: string;
|
||||||
ItemCount: number;
|
ItemCount: number;
|
||||||
ProductCategory: string;
|
ProductCategory: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IItemPricePreprocessed extends Omit<IItemPrice, "ItemType"> {
|
|
||||||
ItemType: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IItemManifest {
|
export interface IItemManifest {
|
||||||
StoreItem: string;
|
StoreItem: string;
|
||||||
ItemPrices?: IItemPrice[];
|
ItemPrices?: IItemPrice[];
|
||||||
@ -24,10 +20,6 @@ export interface IItemManifest {
|
|||||||
Id: IOid;
|
Id: IOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IItemManifestPreprocessed extends Omit<IItemManifest, "ItemPrices"> {
|
|
||||||
ItemPrices?: IItemPricePreprocessed[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IVendorInfo {
|
export interface IVendorInfo {
|
||||||
_id: IOid;
|
_id: IOid;
|
||||||
TypeName: string;
|
TypeName: string;
|
||||||
@ -39,14 +31,6 @@ export interface IVendorInfo {
|
|||||||
Expiry: IMongoDate; // Either a date in the distant future or a period in milliseconds for preprocessing.
|
Expiry: IMongoDate; // Either a date in the distant future or a period in milliseconds for preprocessing.
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorInfoPreprocessed extends Omit<IVendorInfo, "ItemManifest"> {
|
export interface IVendorManifest {
|
||||||
ItemManifest: IItemManifestPreprocessed[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IRawVendorManifest {
|
|
||||||
VendorInfo: IVendorInfo;
|
VendorInfo: IVendorInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorManifestPreprocessed {
|
|
||||||
VendorInfo: IVendorInfoPreprocessed;
|
|
||||||
}
|
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
{
|
|
||||||
"VendorInfo": {
|
|
||||||
"_id": { "$oid": "61ba123467e5d37975aeeb03" },
|
|
||||||
"TypeName": "/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest",
|
|
||||||
"ItemManifest": [
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Guild/GuildAdvertisementMoon",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemType": ["/Lotus/Types/Items/Research/BioFragment", "/Lotus/Types/Items/Research/ChemComponent", "/Lotus/Types/Items/Research/EnergyFragment"],
|
|
||||||
"ItemCount": 12,
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"RegularPrice": [1, 1],
|
|
||||||
"Bin": "BIN_4",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": { "$date": { "$numberLong": "604800000" } },
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"LocTagRandSeed": 79554843,
|
|
||||||
"Id": { "$oid": "67bbb592e1534511d6c1c1e2" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Guild/GuildAdvertisementMountain",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemType": ["/Lotus/Types/Items/Research/BioFragment", "/Lotus/Types/Items/Research/ChemComponent", "/Lotus/Types/Items/Research/EnergyFragment"],
|
|
||||||
"ItemCount": 7,
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"RegularPrice": [1, 1],
|
|
||||||
"Bin": "BIN_3",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": { "$date": { "$numberLong": "604800000" } },
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"LocTagRandSeed": 2413820225,
|
|
||||||
"Id": { "$oid": "67bbb592e1534511d6c1c1e3" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Guild/GuildAdvertisementStorm",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemType": ["/Lotus/Types/Items/Research/BioFragment", "/Lotus/Types/Items/Research/ChemComponent", "/Lotus/Types/Items/Research/EnergyFragment"],
|
|
||||||
"ItemCount": 3,
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"RegularPrice": [1, 1],
|
|
||||||
"Bin": "BIN_2",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": { "$date": { "$numberLong": "604800000" } },
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"LocTagRandSeed": 3262300883,
|
|
||||||
"Id": { "$oid": "67bbb592e1534511d6c1c1e4" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Guild/GuildAdvertisementShadow",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemType": ["/Lotus/Types/Items/Research/BioFragment", "/Lotus/Types/Items/Research/ChemComponent", "/Lotus/Types/Items/Research/EnergyFragment"],
|
|
||||||
"ItemCount": 20,
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"RegularPrice": [1, 1],
|
|
||||||
"Bin": "BIN_1",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": { "$date": { "$numberLong": "604800000" } },
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"LocTagRandSeed": 2797325750,
|
|
||||||
"Id": { "$oid": "67bbb592e1534511d6c1c1e5" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Guild/GuildAdvertisementGhost",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemType": ["/Lotus/Types/Items/Research/BioFragment", "/Lotus/Types/Items/Research/ChemComponent", "/Lotus/Types/Items/Research/EnergyFragment"],
|
|
||||||
"ItemCount": 10,
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"RegularPrice": [1, 1],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": { "$date": { "$numberLong": "604800000" } },
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"LocTagRandSeed": 554932310,
|
|
||||||
"Id": { "$oid": "67bbb592e1534511d6c1c1e6" }
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PropertyTextHash": "255AFE2169BAE4130B4B20D7C55D14FA",
|
|
||||||
"RandomSeedType": "VRST_FLAVOUR_TEXT",
|
|
||||||
"Expiry": { "$date": { "$numberLong": "604800000" } }
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user