forked from OpenWF/SpaceNinjaServer
		
	feat: auto-generate debt token vendor manifest (#1827)
Yet another pretty big change to how these things are generated, but getting closer to where we wanna be now. Reviewed-on: OpenWF/SpaceNinjaServer#1827 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
							
								
									70646160c3
								
							
						
					
					
						commit
						506365f97e
					
				@ -97,9 +97,17 @@ export class CRng {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    randomInt(min: number, max: number): number {
 | 
					    randomInt(min: number, max: number): number {
 | 
				
			||||||
        min = Math.ceil(min);
 | 
					        const diff = max - min;
 | 
				
			||||||
        max = Math.floor(max);
 | 
					        if (diff != 0) {
 | 
				
			||||||
        return Math.floor(this.random() * (max - min + 1)) + min;
 | 
					            if (diff < 0) {
 | 
				
			||||||
 | 
					                throw new Error(`max must be greater than min`);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (diff > 0x3fffffff) {
 | 
				
			||||||
 | 
					                throw new Error(`insufficient entropy`);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            min += Math.floor(this.random() * (diff + 1));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return min;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    randomElement<T>(arr: T[]): T {
 | 
					    randomElement<T>(arr: T[]): T {
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,10 @@ import {
 | 
				
			|||||||
    IItemManifestPreprocessed,
 | 
					    IItemManifestPreprocessed,
 | 
				
			||||||
    IRawVendorManifest,
 | 
					    IRawVendorManifest,
 | 
				
			||||||
    IVendorInfo,
 | 
					    IVendorInfo,
 | 
				
			||||||
 | 
					    IVendorInfoPreprocessed,
 | 
				
			||||||
    IVendorManifestPreprocessed
 | 
					    IVendorManifestPreprocessed
 | 
				
			||||||
} from "@/src/types/vendorTypes";
 | 
					} from "@/src/types/vendorTypes";
 | 
				
			||||||
import { ExportVendors } 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";
 | 
				
			||||||
import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
 | 
					import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
 | 
				
			||||||
@ -32,7 +33,6 @@ import OstronFishmongerVendorManifest from "@/static/fixed_responses/getVendorIn
 | 
				
			|||||||
import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json";
 | 
					import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json";
 | 
				
			||||||
import OstronProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronProspectorVendorManifest.json";
 | 
					import OstronProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronProspectorVendorManifest.json";
 | 
				
			||||||
import RadioLegionIntermission12VendorManifest from "@/static/fixed_responses/getVendorInfo/RadioLegionIntermission12VendorManifest.json";
 | 
					import RadioLegionIntermission12VendorManifest from "@/static/fixed_responses/getVendorInfo/RadioLegionIntermission12VendorManifest.json";
 | 
				
			||||||
import SolarisDebtTokenVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorManifest.json";
 | 
					 | 
				
			||||||
import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json";
 | 
					import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json";
 | 
				
			||||||
import SolarisFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisFishmongerVendorManifest.json";
 | 
					import SolarisFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisFishmongerVendorManifest.json";
 | 
				
			||||||
import SolarisProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisProspectorVendorManifest.json";
 | 
					import SolarisProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisProspectorVendorManifest.json";
 | 
				
			||||||
@ -63,7 +63,6 @@ const rawVendorManifests: IRawVendorManifest[] = [
 | 
				
			|||||||
    OstronPetVendorManifest,
 | 
					    OstronPetVendorManifest,
 | 
				
			||||||
    OstronProspectorVendorManifest,
 | 
					    OstronProspectorVendorManifest,
 | 
				
			||||||
    RadioLegionIntermission12VendorManifest,
 | 
					    RadioLegionIntermission12VendorManifest,
 | 
				
			||||||
    SolarisDebtTokenVendorManifest,
 | 
					 | 
				
			||||||
    SolarisDebtTokenVendorRepossessionsManifest,
 | 
					    SolarisDebtTokenVendorRepossessionsManifest,
 | 
				
			||||||
    SolarisFishmongerVendorManifest,
 | 
					    SolarisFishmongerVendorManifest,
 | 
				
			||||||
    SolarisProspectorVendorManifest,
 | 
					    SolarisProspectorVendorManifest,
 | 
				
			||||||
@ -72,7 +71,7 @@ const rawVendorManifests: IRawVendorManifest[] = [
 | 
				
			|||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
 | 
					interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
 | 
				
			||||||
    cycleStart: number;
 | 
					    cycleOffset: number;
 | 
				
			||||||
    cycleDuration: number;
 | 
					    cycleDuration: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -84,7 +83,7 @@ const generatableVendors: IGeneratableVendorInfo[] = [
 | 
				
			|||||||
        RandomSeedType: "VRST_WEAPON",
 | 
					        RandomSeedType: "VRST_WEAPON",
 | 
				
			||||||
        RequiredGoalTag: "",
 | 
					        RequiredGoalTag: "",
 | 
				
			||||||
        WeaponUpgradeValueAttenuationExponent: 2.25,
 | 
					        WeaponUpgradeValueAttenuationExponent: 2.25,
 | 
				
			||||||
        cycleStart: 1740960000_000,
 | 
					        cycleOffset: 1740960000_000,
 | 
				
			||||||
        cycleDuration: 4 * unixTimesInMs.day
 | 
					        cycleDuration: 4 * unixTimesInMs.day
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -93,8 +92,16 @@ const generatableVendors: IGeneratableVendorInfo[] = [
 | 
				
			|||||||
        PropertyTextHash: "34F8CF1DFF745F0D67433A5EF0A03E70",
 | 
					        PropertyTextHash: "34F8CF1DFF745F0D67433A5EF0A03E70",
 | 
				
			||||||
        RandomSeedType: "VRST_WEAPON",
 | 
					        RandomSeedType: "VRST_WEAPON",
 | 
				
			||||||
        WeaponUpgradeValueAttenuationExponent: 2.25,
 | 
					        WeaponUpgradeValueAttenuationExponent: 2.25,
 | 
				
			||||||
        cycleStart: 1744934400_000,
 | 
					        cycleOffset: 1744934400_000,
 | 
				
			||||||
        cycleDuration: 4 * unixTimesInMs.day
 | 
					        cycleDuration: 4 * unixTimesInMs.day
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _id: { $oid: "5be4a159b144f3cdf1c22efa" },
 | 
				
			||||||
 | 
					        TypeName: "/Lotus/Types/Game/VendorManifests/Solaris/DebtTokenVendorManifest",
 | 
				
			||||||
 | 
					        PropertyTextHash: "A39621049CA3CA13761028CD21C239EF",
 | 
				
			||||||
 | 
					        RandomSeedType: "VRST_FLAVOUR_TEXT",
 | 
				
			||||||
 | 
					        cycleOffset: 1734307200_000,
 | 
				
			||||||
 | 
					        cycleDuration: unixTimesInMs.hour
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // {
 | 
					    // {
 | 
				
			||||||
    //     _id: { $oid: "5dbb4c41e966f7886c3ce939" },
 | 
					    //     _id: { $oid: "5dbb4c41e966f7886c3ce939" },
 | 
				
			||||||
@ -166,60 +173,128 @@ const refreshExpiry = (expiry: IMongoDate): number => {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const toRange = (value: IRange | number): IRange => {
 | 
				
			||||||
 | 
					    if (typeof value == "number") {
 | 
				
			||||||
 | 
					        return { minValue: value, maxValue: value };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const vendorInfoCache: Record<string, IVendorInfoPreprocessed> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorManifestPreprocessed => {
 | 
					const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorManifestPreprocessed => {
 | 
				
			||||||
    const EPOCH = vendorInfo.cycleStart;
 | 
					    if (!(vendorInfo.TypeName in vendorInfoCache)) {
 | 
				
			||||||
 | 
					        // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
				
			||||||
 | 
					        const { cycleOffset, cycleDuration, ...clientVendorInfo } = vendorInfo;
 | 
				
			||||||
 | 
					        vendorInfoCache[vendorInfo.TypeName] = {
 | 
				
			||||||
 | 
					            ...clientVendorInfo,
 | 
				
			||||||
 | 
					            ItemManifest: [],
 | 
				
			||||||
 | 
					            Expiry: { $date: { $numberLong: "0" } }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const processed = vendorInfoCache[vendorInfo.TypeName];
 | 
				
			||||||
 | 
					    if (Date.now() >= parseInt(processed.Expiry.$date.$numberLong)) {
 | 
				
			||||||
 | 
					        // Remove expired offers
 | 
				
			||||||
 | 
					        for (let i = 0; i != processed.ItemManifest.length; ) {
 | 
				
			||||||
 | 
					            if (Date.now() >= parseInt(processed.ItemManifest[i].Expiry.$date.$numberLong)) {
 | 
				
			||||||
 | 
					                processed.ItemManifest.splice(i, 1);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                ++i;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Add new offers
 | 
				
			||||||
 | 
					        const vendorSeed = parseInt(vendorInfo._id.$oid.substring(16), 16);
 | 
				
			||||||
 | 
					        const cycleIndex = Math.trunc((Date.now() - vendorInfo.cycleOffset) / vendorInfo.cycleDuration);
 | 
				
			||||||
 | 
					        const rng = new CRng(mixSeeds(vendorSeed, cycleIndex));
 | 
				
			||||||
        const manifest = ExportVendors[vendorInfo.TypeName];
 | 
					        const manifest = ExportVendors[vendorInfo.TypeName];
 | 
				
			||||||
 | 
					        const offersToAdd = [];
 | 
				
			||||||
 | 
					        if (manifest.numItems && manifest.numItems.minValue != manifest.numItems.maxValue) {
 | 
				
			||||||
 | 
					            const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
 | 
				
			||||||
 | 
					            while (processed.ItemManifest.length + offersToAdd.length < numItemsTarget) {
 | 
				
			||||||
 | 
					                // TODO: Consider per-bin item limits
 | 
				
			||||||
 | 
					                // TODO: Consider item probability weightings
 | 
				
			||||||
 | 
					                offersToAdd.push(rng.randomElement(manifest.items));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
            let binThisCycle;
 | 
					            let binThisCycle;
 | 
				
			||||||
            if (manifest.isOneBinPerCycle) {
 | 
					            if (manifest.isOneBinPerCycle) {
 | 
				
			||||||
        const cycleDuration = vendorInfo.cycleDuration; // manifest.items[0].durationHours! * 3600_000;
 | 
					 | 
				
			||||||
        const cycleIndex = Math.trunc((Date.now() - EPOCH) / cycleDuration);
 | 
					 | 
				
			||||||
                binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now.
 | 
					                binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now.
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    const items: IItemManifestPreprocessed[] = [];
 | 
					            for (const rawItem of manifest.items) {
 | 
				
			||||||
    let soonestOfferExpiry: number = Number.MAX_SAFE_INTEGER;
 | 
					                if (!manifest.isOneBinPerCycle || rawItem.bin == binThisCycle) {
 | 
				
			||||||
    for (let i = 0; i != manifest.items.length; ++i) {
 | 
					                    offersToAdd.push(rawItem);
 | 
				
			||||||
        const rawItem = manifest.items[i];
 | 
					 | 
				
			||||||
        if (manifest.isOneBinPerCycle && rawItem.bin != binThisCycle) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        const cycleDuration = vendorInfo.cycleDuration; // rawItem.durationHours! * 3600_000;
 | 
					 | 
				
			||||||
        const cycleIndex = Math.trunc((Date.now() - EPOCH) / cycleDuration);
 | 
					 | 
				
			||||||
        const cycleStart = EPOCH + cycleIndex * cycleDuration;
 | 
					 | 
				
			||||||
        const cycleEnd = cycleStart + cycleDuration;
 | 
					 | 
				
			||||||
        if (soonestOfferExpiry > cycleEnd) {
 | 
					 | 
				
			||||||
            soonestOfferExpiry = cycleEnd;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        const rng = new CRng(cycleIndex);
 | 
					        }
 | 
				
			||||||
        rng.churnSeed(i);
 | 
					        const cycleStart = vendorInfo.cycleOffset + cycleIndex * vendorInfo.cycleDuration;
 | 
				
			||||||
        /*for (let j = -1; j != rawItem.duplicates; ++j)*/ {
 | 
					        for (const rawItem of offersToAdd) {
 | 
				
			||||||
 | 
					            const durationHoursRange = toRange(rawItem.durationHours);
 | 
				
			||||||
 | 
					            const expiry =
 | 
				
			||||||
 | 
					                cycleStart +
 | 
				
			||||||
 | 
					                rng.randomInt(durationHoursRange.minValue, durationHoursRange.maxValue) * unixTimesInMs.hour;
 | 
				
			||||||
            const item: IItemManifestPreprocessed = {
 | 
					            const item: IItemManifestPreprocessed = {
 | 
				
			||||||
                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,
 | 
				
			||||||
                QuantityMultiplier: 1,
 | 
					                QuantityMultiplier: 1,
 | 
				
			||||||
                Expiry: { $date: { $numberLong: cycleEnd.toString() } },
 | 
					                Expiry: { $date: { $numberLong: expiry.toString() } },
 | 
				
			||||||
                AllowMultipurchase: false,
 | 
					                AllowMultipurchase: false,
 | 
				
			||||||
                Id: {
 | 
					                Id: {
 | 
				
			||||||
                    $oid:
 | 
					                    $oid:
 | 
				
			||||||
                        i.toString(16).padStart(8, "0") +
 | 
					                        Math.trunc(cycleStart / 1000)
 | 
				
			||||||
 | 
					                            .toString(16)
 | 
				
			||||||
 | 
					                            .padStart(8, "0") +
 | 
				
			||||||
                        vendorInfo._id.$oid.substring(8, 16) +
 | 
					                        vendorInfo._id.$oid.substring(8, 16) +
 | 
				
			||||||
                        rng.randomInt(0, 0xffffffff).toString(16).padStart(8, "0")
 | 
					                        rng.randomInt(0, 0xffff).toString(16).padStart(4, "0") +
 | 
				
			||||||
 | 
					                        rng.randomInt(0, 0xffff).toString(16).padStart(4, "0")
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					            if (rawItem.numRandomItemPrices) {
 | 
				
			||||||
 | 
					                item.ItemPrices = [];
 | 
				
			||||||
 | 
					                for (let i = 0; i != rawItem.numRandomItemPrices; ++i) {
 | 
				
			||||||
 | 
					                    let itemPrice: { type: string; count: IRange };
 | 
				
			||||||
 | 
					                    do {
 | 
				
			||||||
 | 
					                        itemPrice = rng.randomElement(manifest.randomItemPricesPerBin![rawItem.bin]);
 | 
				
			||||||
 | 
					                    } while (item.ItemPrices.find(x => x.ItemType == itemPrice.type));
 | 
				
			||||||
 | 
					                    item.ItemPrices.push({
 | 
				
			||||||
 | 
					                        ItemType: itemPrice.type,
 | 
				
			||||||
 | 
					                        ItemCount: rng.randomInt(itemPrice.count.minValue, itemPrice.count.maxValue),
 | 
				
			||||||
 | 
					                        ProductCategory: "MiscItems"
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (rawItem.credits) {
 | 
				
			||||||
 | 
					                const value =
 | 
				
			||||||
 | 
					                    typeof rawItem.credits == "number"
 | 
				
			||||||
 | 
					                        ? rawItem.credits
 | 
				
			||||||
 | 
					                        : rng.randomInt(
 | 
				
			||||||
 | 
					                              rawItem.credits.minValue / rawItem.credits.step,
 | 
				
			||||||
 | 
					                              rawItem.credits.maxValue / rawItem.credits.step
 | 
				
			||||||
 | 
					                          ) * rawItem.credits.step;
 | 
				
			||||||
 | 
					                item.RegularPrice = [value, value];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (vendorInfo.RandomSeedType) {
 | 
					            if (vendorInfo.RandomSeedType) {
 | 
				
			||||||
                item.LocTagRandSeed =
 | 
					                item.LocTagRandSeed = (rng.randomInt(0, 0xffff) << 16) | rng.randomInt(0, 0xffff);
 | 
				
			||||||
                    (BigInt(rng.randomInt(0, 0xffffffff)) << 32n) | BigInt(rng.randomInt(0, 0xffffffff));
 | 
					                if (vendorInfo.RandomSeedType == "VRST_WEAPON") {
 | 
				
			||||||
            }
 | 
					                    const highDword = (rng.randomInt(0, 0xffff) << 16) | rng.randomInt(0, 0xffff);
 | 
				
			||||||
            items.push(item);
 | 
					                    item.LocTagRandSeed = (BigInt(highDword) << 32n) | BigInt(item.LocTagRandSeed);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
					            processed.ItemManifest.push(item);
 | 
				
			||||||
    const { cycleStart, cycleDuration, ...clientVendorInfo } = vendorInfo;
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Update vendor expiry
 | 
				
			||||||
 | 
					        let soonestOfferExpiry: number = Number.MAX_SAFE_INTEGER;
 | 
				
			||||||
 | 
					        for (const offer of processed.ItemManifest) {
 | 
				
			||||||
 | 
					            const offerExpiry = parseInt(offer.Expiry.$date.$numberLong);
 | 
				
			||||||
 | 
					            if (soonestOfferExpiry > offerExpiry) {
 | 
				
			||||||
 | 
					                soonestOfferExpiry = offerExpiry;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        processed.Expiry.$date.$numberLong = soonestOfferExpiry.toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        VendorInfo: {
 | 
					        VendorInfo: processed
 | 
				
			||||||
            ...clientVendorInfo,
 | 
					 | 
				
			||||||
            ItemManifest: items,
 | 
					 | 
				
			||||||
            Expiry: { $date: { $numberLong: soonestOfferExpiry.toString() } }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ export interface IItemPricePreprocessed extends Omit<IItemPrice, "ItemType"> {
 | 
				
			|||||||
export interface IItemManifest {
 | 
					export interface IItemManifest {
 | 
				
			||||||
    StoreItem: string;
 | 
					    StoreItem: string;
 | 
				
			||||||
    ItemPrices?: IItemPrice[];
 | 
					    ItemPrices?: IItemPrice[];
 | 
				
			||||||
 | 
					    RegularPrice?: number[];
 | 
				
			||||||
    Bin: string;
 | 
					    Bin: string;
 | 
				
			||||||
    QuantityMultiplier: number;
 | 
					    QuantityMultiplier: number;
 | 
				
			||||||
    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.
 | 
				
			||||||
 | 
				
			|||||||
@ -1,248 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "VendorInfo": {
 | 
					 | 
				
			||||||
    "_id": {
 | 
					 | 
				
			||||||
      "$oid": "5be4a159b144f3cdf1c22efa"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "TypeName": "/Lotus/Types/Game/VendorManifests/Solaris/DebtTokenVendorManifest",
 | 
					 | 
				
			||||||
    "ItemManifest": [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleUncommonD",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Gameplay/Venus/Resources/VenusCoconutItem",
 | 
					 | 
				
			||||||
            "ItemCount": 5,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/MiscItems/Circuits",
 | 
					 | 
				
			||||||
            "ItemCount": 3664,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [87300, 87300],
 | 
					 | 
				
			||||||
        "Bin": "BIN_1",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 1881404827,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "670daf92d21f34757a5e73b4"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleRareC",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/MiscItems/NeuralSensor",
 | 
					 | 
				
			||||||
            "ItemCount": 1,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [53300, 53300],
 | 
					 | 
				
			||||||
        "Bin": "BIN_2",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 1943984533,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "6710b5029e1a3080a65e73a7"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleCommonG",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/MiscItems/Salvage",
 | 
					 | 
				
			||||||
            "ItemCount": 11540,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [27300, 27300],
 | 
					 | 
				
			||||||
        "Bin": "BIN_0",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 744199559,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "67112582cc115756985e73a4"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleUncommonB",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/Fish/Solaris/FishParts/CorpusFishThermalLaserItem",
 | 
					 | 
				
			||||||
            "ItemCount": 9,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [75800, 75800],
 | 
					 | 
				
			||||||
        "Bin": "BIN_1",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 3744711432,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "670de7d28a6ec82cd25e73a2"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleUncommonB",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/MiscItems/Rubedo",
 | 
					 | 
				
			||||||
            "ItemCount": 3343,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [52200, 52200],
 | 
					 | 
				
			||||||
        "Bin": "BIN_1",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 1579000687,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "670e58526171148e125e73ad"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleCommonA",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Gameplay/Venus/Resources/CoolantItem",
 | 
					 | 
				
			||||||
            "ItemCount": 9,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/Fish/Solaris/FishParts/CorpusFishAnoscopicSensorItem",
 | 
					 | 
				
			||||||
            "ItemCount": 5,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [12400, 12400],
 | 
					 | 
				
			||||||
        "Bin": "BIN_0",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 3589081466,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "67112582cc115756985e73a5"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleUncommonC",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/Gems/Solaris/SolarisCommonOreBAlloyItem",
 | 
					 | 
				
			||||||
            "ItemCount": 13,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [77500, 77500],
 | 
					 | 
				
			||||||
        "Bin": "BIN_1",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 1510234814,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "670f0f21250ad046c35e73ee"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleUncommonD",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/Fish/Solaris/FishParts/CorpusFishParralelBiodeItem",
 | 
					 | 
				
			||||||
            "ItemCount": 7,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/Gems/Solaris/SolarisCommonGemBCutItem",
 | 
					 | 
				
			||||||
            "ItemCount": 12,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [94600, 94600],
 | 
					 | 
				
			||||||
        "Bin": "BIN_1",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 4222095721,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "670f63827be40254f95e739d"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "StoreItem": "/Lotus/Types/StoreItems/Packages/DebtTokenBundles/DebtTokenBundleCommonJ",
 | 
					 | 
				
			||||||
        "ItemPrices": [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            "ItemType": "/Lotus/Types/Items/MiscItems/Nanospores",
 | 
					 | 
				
			||||||
            "ItemCount": 14830,
 | 
					 | 
				
			||||||
            "ProductCategory": "MiscItems"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "RegularPrice": [25600, 25600],
 | 
					 | 
				
			||||||
        "Bin": "BIN_0",
 | 
					 | 
				
			||||||
        "QuantityMultiplier": 1,
 | 
					 | 
				
			||||||
        "Expiry": {
 | 
					 | 
				
			||||||
          "$date": {
 | 
					 | 
				
			||||||
            "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "PurchaseQuantityLimit": 1,
 | 
					 | 
				
			||||||
        "AllowMultipurchase": true,
 | 
					 | 
				
			||||||
        "LocTagRandSeed": 2694388669,
 | 
					 | 
				
			||||||
        "Id": {
 | 
					 | 
				
			||||||
          "$oid": "67112582cc115756985e73a6"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "PropertyTextHash": "A39621049CA3CA13761028CD21C239EF",
 | 
					 | 
				
			||||||
    "RandomSeedType": "VRST_FLAVOUR_TEXT",
 | 
					 | 
				
			||||||
    "Expiry": {
 | 
					 | 
				
			||||||
      "$date": {
 | 
					 | 
				
			||||||
        "$numberLong": "9999999000000"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user