This commit is contained in:
Jānis 2024-09-03 17:23:42 +03:00
parent 372dde7d88
commit 58b1cfc30f
15 changed files with 242 additions and 579 deletions

View File

@ -15,12 +15,32 @@ import { statsRouter } from "@/src/routes/stats";
import { webuiRouter } from "@/src/routes/webui"; import { webuiRouter } from "@/src/routes/webui";
import { connectDatabase } from "@/src/services/mongoService"; import { connectDatabase } from "@/src/services/mongoService";
import { registerLogFileCreationListener } from "@/src/utils/logger"; import { registerLogFileCreationListener } from "@/src/utils/logger";
import * as zlib from 'zlib';
void registerLogFileCreationListener(); void registerLogFileCreationListener();
void connectDatabase(); void connectDatabase();
const app = express(); const app = express();
app.use(function (req, _res, next) {
var buffer: Buffer[] = []
req.on('data', function (chunk: Buffer) {
if (chunk !== undefined && chunk.length > 2 && chunk[0] == 0x1f && chunk[1] == 0x8b) {
buffer.push(Buffer.from(chunk));
}
});
req.on('end', function () {
zlib.gunzip(Buffer.concat(buffer), function (_err, dezipped) {
if (typeof dezipped != 'undefined') {
req.body = dezipped.toString('utf-8');
}
next();
});
});
});
app.use(bodyParser.raw()); app.use(bodyParser.raw());
app.use(express.json()); app.use(express.json());
app.use(bodyParser.text()); app.use(bodyParser.text());

View File

@ -4,70 +4,7 @@ import { Guild } from "@/src/models/guildModel";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { toOid } from "@/src/helpers/inventoryHelpers"; import { toOid } from "@/src/helpers/inventoryHelpers";
// eslint-disable-next-line @typescript-eslint/no-misused-promises const getGuildController: RequestHandler = async (_, res) => {
const getGuildController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const inventory = await Inventory.findOne({ accountOwnerId: accountId });
if (!inventory) {
res.status(400).json({ error: "inventory was undefined" });
return;
}
if (inventory.GuildId) {
const guild = await Guild.findOne({ _id: inventory.GuildId });
if (guild) {
res.json({
_id: toOid(guild._id),
Name: guild.Name,
Members: [
{
_id: { $oid: req.query.accountId },
Rank: 0,
Status: 0
}
],
Ranks: [
{
Name: "/Lotus/Language/Game/Rank_Creator",
Permissions: 16351
},
{
Name: "/Lotus/Language/Game/Rank_Warlord",
Permissions: 14303
},
{
Name: "/Lotus/Language/Game/Rank_General",
Permissions: 4318
},
{
Name: "/Lotus/Language/Game/Rank_Officer",
Permissions: 4314
},
{
Name: "/Lotus/Language/Game/Rank_Leader",
Permissions: 4106
},
{
Name: "/Lotus/Language/Game/Rank_Sage",
Permissions: 4304
},
{
Name: "/Lotus/Language/Game/Rank_Soldier",
Permissions: 4098
},
{
Name: "/Lotus/Language/Game/Rank_Initiate",
Permissions: 4096
},
{
Name: "/Lotus/Language/Game/Rank_Utility",
Permissions: 4096
}
],
Tier: 1
});
return;
}
}
res.json({}); res.json({});
}; };

View File

@ -9,6 +9,7 @@ import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes";
import { IInventoryDatabase, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes"; import { IInventoryDatabase, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes";
import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { ExportCustoms, ExportFlavour, ExportKeys, ExportResources } from "warframe-public-export-plus"; import { ExportCustoms, ExportFlavour, ExportKeys, ExportResources } from "warframe-public-export-plus";
import { IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
const inventoryController: RequestHandler = async (request, response) => { const inventoryController: RequestHandler = async (request, response) => {
@ -20,9 +21,7 @@ const inventoryController: RequestHandler = async (request, response) => {
return; return;
} }
const inventory = await Inventory.findOne({ accountOwnerId: accountId }) const inventory = await Inventory.findOne({ accountOwnerId: accountId });
.populate<{ LoadOutPresets: ILoadoutDatabase }>("LoadOutPresets")
.populate<{ Ships: IShipInventory }>("Ships", "-ShipInteriorColors");
if (!inventory) { if (!inventory) {
response.status(400).json({ error: "inventory was undefined" }); response.status(400).json({ error: "inventory was undefined" });
@ -38,62 +37,17 @@ const inventoryController: RequestHandler = async (request, response) => {
if (config.infiniteResources) { if (config.infiniteResources) {
inventoryResponse.RegularCredits = 999999999; inventoryResponse.RegularCredits = 999999999;
inventoryResponse.TradesRemaining = 999999999; inventoryResponse.TradesRemaining = 999999999;
inventoryResponse.PremiumCreditsFree = 999999999;
inventoryResponse.PremiumCredits = 999999999; inventoryResponse.PremiumCredits = 999999999;
} }
if (config.skipAllDialogue) { if (config.unlockAllMissions) {
inventoryResponse.TauntHistory = [ //inventoryResponse.Missions = allMissions;
{ //inventoryResponse.NodeIntrosCompleted.push("TeshinHardModeUnlocked");
node: "TreasureTutorial",
state: "TS_COMPLETED"
}
];
for (const str of allDialogue) {
addString(inventoryResponse.NodeIntrosCompleted, str);
}
} }
if (config.unlockAllMissions) { if (config.unlockAllMissions) {
inventoryResponse.Missions = allMissions; //inventoryResponse.Missions = allMissions;
addString(inventoryResponse.NodeIntrosCompleted, "TeshinHardModeUnlocked"); //addString(inventoryResponse.NodeIntrosCompleted, "TeshinHardModeUnlocked");
}
if (config.unlockAllQuests) {
for (const [k, v] of Object.entries(ExportKeys)) {
if ("chainStages" in v) {
if (!inventoryResponse.QuestKeys.find(quest => quest.ItemType == k)) {
inventoryResponse.QuestKeys.push({ ItemType: k });
}
}
}
}
if (config.completeAllQuests) {
for (const quest of inventoryResponse.QuestKeys) {
quest.Completed = true;
quest.Progress = [
{
c: 0,
i: false,
m: false,
b: []
}
];
}
inventoryResponse.ArchwingEnabled = true;
// Skip "Watch The Maker"
addString(inventoryResponse.NodeIntrosCompleted, "/Lotus/Levels/Cinematics/NewWarIntro/NewWarStageTwo.level");
}
if (config.unlockAllShipDecorations) {
inventoryResponse.ShipDecorations = [];
for (const [uniqueName, item] of Object.entries(ExportResources)) {
if (item.productCategory == "ShipDecorations") {
inventoryResponse.ShipDecorations.push({ ItemType: uniqueName, ItemCount: 1 });
}
}
} }
if (config.unlockAllFlavourItems) { if (config.unlockAllFlavourItems) {
@ -130,23 +84,6 @@ const inventoryController: RequestHandler = async (request, response) => {
} }
} }
if (config.universalPolarityEverywhere) {
const Polarity: IPolarity[] = [];
for (let i = 0; i != 10; ++i) {
Polarity.push({
Slot: i,
Value: ArtifactPolarity.Any
});
}
for (const key of equipmentKeys) {
if (key in inventoryResponse) {
for (const equipment of inventoryResponse[key]) {
equipment.Polarity = Polarity;
}
}
}
}
// Fix for #380 // Fix for #380
inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } }; inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } };

View File

@ -8,7 +8,6 @@ import { toLoginRequest } from "@/src/helpers/loginHelpers";
import { Account } from "@/src/models/loginModel"; import { Account } from "@/src/models/loginModel";
import { createAccount, isCorrectPassword } from "@/src/services/loginService"; import { createAccount, isCorrectPassword } from "@/src/services/loginService";
import { ILoginResponse } from "@/src/types/loginTypes"; import { ILoginResponse } from "@/src/types/loginTypes";
import { DTLS, groups, HUB, platformCDNs } from "@/static/fixed_responses/login_static";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
@ -17,7 +16,7 @@ const loginController: RequestHandler = async (request, response) => {
const body = JSON.parse(request.body); // parse octet stream of json data to json object const body = JSON.parse(request.body); // parse octet stream of json data to json object
const loginRequest = toLoginRequest(body); const loginRequest = toLoginRequest(body);
const account = await Account.findOne({ email: loginRequest.email }); //{ _id: 0, __v: 0 } const account = await Account.findOne({ email: loginRequest.email });
const nonce = Math.round(Math.random() * Number.MAX_SAFE_INTEGER); const nonce = Math.round(Math.random() * Number.MAX_SAFE_INTEGER);
if (!account && config.autoCreateAccount && loginRequest.ClientType != "webui") { if (!account && config.autoCreateAccount && loginRequest.ClientType != "webui") {
@ -26,27 +25,16 @@ const loginController: RequestHandler = async (request, response) => {
email: loginRequest.email, email: loginRequest.email,
password: loginRequest.password, password: loginRequest.password,
DisplayName: loginRequest.email.substring(0, loginRequest.email.indexOf("@")), DisplayName: loginRequest.email.substring(0, loginRequest.email.indexOf("@")),
CountryCode: loginRequest.lang.toUpperCase(), Nonce: nonce,
ClientType: loginRequest.ClientType,
CrossPlatformAllowed: true,
ForceLogoutVersion: 0,
ConsentNeeded: false,
TrackedSettings: [],
Nonce: nonce
}); });
logger.debug("created new account"); logger.debug("created new account");
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { email, password, ...databaseAccount } = newAccount; const { email, password, ...databaseAccount } = newAccount;
const newLoginResponse: ILoginResponse = { const newLoginResponse: ILoginResponse = {
...databaseAccount, ...databaseAccount,
Groups: groups,
platformCDNs: platformCDNs,
NRS: [config.myAddress],
DTLS: DTLS,
IRC: config.myIrcAddresses ?? [config.myAddress],
HUB: HUB,
BuildLabel: buildConfig.buildLabel, BuildLabel: buildConfig.buildLabel,
MatchmakingBuildId: buildConfig.matchmakingBuildId NatHash: "0",
SteamId: "0"
}; };
response.json(newLoginResponse); response.json(newLoginResponse);
@ -67,22 +55,15 @@ const loginController: RequestHandler = async (request, response) => {
if (account.Nonce == 0 || loginRequest.ClientType != "webui") { if (account.Nonce == 0 || loginRequest.ClientType != "webui") {
account.Nonce = nonce; account.Nonce = nonce;
} }
if (loginRequest.ClientType != "webui") {
account.CountryCode = loginRequest.lang.toUpperCase();
}
await account.save(); await account.save();
const { email, password, ...databaseAccount } = account.toJSON(); const { email, password, ...databaseAccount } = account.toJSON();
const newLoginResponse: ILoginResponse = { const newLoginResponse: ILoginResponse = {
...databaseAccount, ...databaseAccount,
Groups: groups,
platformCDNs: platformCDNs,
NRS: [config.myAddress],
DTLS: DTLS,
IRC: config.myIrcAddresses ?? [config.myAddress],
HUB: HUB,
BuildLabel: buildConfig.buildLabel, BuildLabel: buildConfig.buildLabel,
MatchmakingBuildId: buildConfig.matchmakingBuildId NatHash: "0",
SteamId: "0"
}; };
response.json(newLoginResponse); response.json(newLoginResponse);

View File

@ -8,15 +8,21 @@ import { logger } from "@/src/utils/logger";
export const tauntHistoryController: RequestHandler = async (req, res) => { export const tauntHistoryController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
const clientTaunt = JSON.parse(String(req.body)) as ITaunt; if(req.body !== undefined)
logger.debug(`updating taunt ${clientTaunt.node} to state ${clientTaunt.state}`); {
inventory.TauntHistory ??= []; const clientTaunt = JSON.parse(String(req.body)) as ITaunt;
const taunt = inventory.TauntHistory.find(x => x.node == clientTaunt.node); logger.debug(`updating taunt ${clientTaunt.node} to state ${clientTaunt.state}`);
if (taunt) { inventory.TauntHistory ??= [];
taunt.state = clientTaunt.state; const taunt = inventory.TauntHistory.find(x => x.node == clientTaunt.node);
} else { if (taunt) {
inventory.TauntHistory.push(clientTaunt); taunt.state = clientTaunt.state;
} else {
inventory.TauntHistory.push(clientTaunt);
}
await inventory.save();
res.end();
}else
{
res.json({});
} }
await inventory.save();
res.end();
}; };

View File

@ -0,0 +1,151 @@
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { startRecipe } from "@/src/services/recipeService";
import { logger } from "@/src/utils/logger";
import { RequestHandler } from "express";
import { getInventory } from "@/src/services/inventoryService";
// eslint-disable-next-line @typescript-eslint/no-misused-promises
export const updateInventoryController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const body = JSON.parse(req.body);
const inventory = await getInventory(accountId);
inventory.Missions.push({Tag: body.Missions.Tag, Completes: body.Missions.Completes, BestRating: 0.2 })
await inventory.save();
console.log(body);
res.json({})
};
/*
{
"LongGuns" : [
{
"ItemType" : "",
"ItemId" : {
"$id" : ""
},
"XP" : 882,
"UpgradeVer" : 0,
"UnlockLevel" : 0,
"ExtraCapacity" : 4,
"ExtraRemaining" : 4
}
],
"Pistols" : [
{
"ItemType" : "",
"ItemId" : {
"$id" : ""
},
"XP" : 0,
"UpgradeVer" : 0,
"UnlockLevel" : 0,
"ExtraCapacity" : 4,
"ExtraRemaining" : 4
}
],
"Suits" : [
{
"ItemType" : "",
"ItemId" : {
"$id" : ""
},
"XP" : 982,
"UpgradeVer" : 101,
"UnlockLevel" : 0,
"ExtraCapacity" : 4,
"ExtraRemaining" : 4
}
],
"Melee" : [
{
"ItemType" : "",
"ItemId" : {
"$id" : ""
},
"XP" : 0,
"UpgradeVer" : 0,
"UnlockLevel" : 0,
"ExtraCapacity" : 4,
"ExtraRemaining" : 4
}
],
"WeaponSkins" : [],
"Upgrades" : [],
"Boosters" : [],
"Robotics" : [],
"Consumables" : [],
"FlavourItems" : [],
"MiscItems" : [],
"Cards" : [],
"Recipes" : [],
"XPInfo" : [],
"Sentinels" : [],
"SentinelWeapons" : [],
"SuitBin" : {
"Slots" : 0,
"Extra" : 0
},
"WeaponBin" : {
"Slots" : 0,
"Extra" : 0
},
"MiscBin" : {
"Slots" : 0,
"Extra" : 0
},
"SentinelBin" : {
"Slots" : 0,
"Extra" : 0
},
"RegularCredits" : 1304,
"PremiumCredits" : 0,
"PlayerXP" : 784,
"AdditionalPlayerXP" : 0,
"Rating" : 15,
"PlayerLevel" : 0,
"TrainingDate" : {
"sec" : "",
"usec" : ""
},
"AliveTime" : 193.78572,
"Missions" : {
"Tag" : "SolNode103",
"Completes" : 1,
"BestRating" : 0.2
},
"AssignedMissions" : [],
"CompletedAlerts" : [],
"DeathMarks" : [],
"MissionReport" : {
"HostId" : "",
"MishStartTime" : "1725359860",
"MishName" : "SolNode103",
"PlayerReport" : {
"ReporterId" : "",
"FullReport" : true,
"PlayerMishInfos" : [
{
"Pid" : "",
"Creds" : 304,
"CredBonus" : 1000,
"Xp" : 784,
"XpBonus" : 0,
"SuitXpBonus" : 590,
"PistolXpBonus" : 0,
"RfileXpBonus" : 490,
"MeleeXpBonus" : 0,
"SentnlXPBonus" : 0,
"SentnlWepXpBonus" : 0,
"Rating" : 0.2,
"Upgrades" : []
}
]
}
}
}
*/

View File

@ -43,11 +43,6 @@ const toAccountCreation = (accountCreation: unknown): IAccountCreation => {
const toDatabaseAccount = (createAccount: IAccountCreation): IDatabaseAccount => { const toDatabaseAccount = (createAccount: IAccountCreation): IDatabaseAccount => {
return { return {
...createAccount, ...createAccount,
ClientType: "",
ConsentNeeded: false,
CrossPlatformAllowed: true,
ForceLogoutVersion: 0,
TrackedSettings: [],
Nonce: 0 Nonce: 0
} satisfies IDatabaseAccount; } satisfies IDatabaseAccount;
}; };

View File

@ -9,23 +9,11 @@ const toLoginRequest = (loginRequest: unknown): ILoginRequest => {
// TODO: function that checks whether every field of interface is in object // TODO: function that checks whether every field of interface is in object
if ( if (
"email" in loginRequest && "email" in loginRequest &&
"password" in loginRequest && "password" in loginRequest
"time" in loginRequest &&
"s" in loginRequest &&
"lang" in loginRequest &&
"date" in loginRequest &&
"ClientType" in loginRequest &&
"PS" in loginRequest
) { ) {
return { return {
email: parseEmail(loginRequest.email), email: parseEmail(loginRequest.email),
password: parseString(loginRequest.password), password: parseString(loginRequest.password)
time: parseNumber(loginRequest.time),
s: parseString(loginRequest.s),
lang: parseString(loginRequest.lang),
date: parseNumber(loginRequest.date),
ClientType: parseString(loginRequest.ClientType),
PS: parseString(loginRequest.PS)
}; };
} }

View File

@ -589,61 +589,13 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
RegularCredits: Number, RegularCredits: Number,
//Platinum //Platinum
PremiumCredits: Number, PremiumCredits: Number,
//Gift Platinum(Non trade)
PremiumCreditsFree: Number,
//Endo
FusionPoints: Number,
//Slots //Slots
SuitBin: slotsBinSchema, SuitBin: slotsBinSchema,
WeaponBin: slotsBinSchema, WeaponBin: slotsBinSchema,
SentinelBin: slotsBinSchema, SentinelBin: slotsBinSchema,
SpaceSuitBin: slotsBinSchema,
SpaceWeaponBin: slotsBinSchema,
PvpBonusLoadoutBin: slotsBinSchema,
PveBonusLoadoutBin: slotsBinSchema,
RandomModBin: slotsBinSchema, RandomModBin: slotsBinSchema,
OperatorAmpBin: slotsBinSchema,
CrewShipSalvageBin: slotsBinSchema,
MechBin: slotsBinSchema, MechBin: slotsBinSchema,
CrewMemberBin: slotsBinSchema,
//How many trades do you have left
TradesRemaining: Number,
//How many Gift do you have left*(gift spends the trade)
GiftsRemaining: Number,
//Curent trade info Giving or Getting items
PendingTrades: [Schema.Types.Mixed],
//Syndicate currently being pledged to.
SupportedSyndicate: String,
//Curent Syndicates rank\exp
Affiliations: [affiliationsSchema],
//Syndicates Missions complate(Navigation->Syndicate)
CompletedSyndicates: [String],
//Daily Syndicates Exp
DailyAffiliation: Number,
DailyAffiliationPvp: Number,
DailyAffiliationLibrary: Number,
DailyAffiliationCetus: Number,
DailyAffiliationQuills: Number,
DailyAffiliationSolaris: Number,
DailyAffiliationVentkids: Number,
DailyAffiliationVox: Number,
DailyAffiliationEntrati: Number,
DailyAffiliationNecraloid: Number,
DailyAffiliationZariman: Number,
DailyAffiliationKahl: Number,
DailyAffiliationCavia: Number,
//Daily Focus limit
DailyFocus: Number,
//Focus XP per School
FocusXP: focusXPSchema,
//Curent active like Active school focuses is = "Zenurik"
FocusAbility: String,
//The treeways of the Focus school.(Active and passive Ability)
FocusUpgrades: [focusUpgradesSchema],
//Achievement //Achievement
ChallengeProgress: [challengeProgressSchema], ChallengeProgress: [challengeProgressSchema],
@ -651,8 +603,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
//Account Item like Ferrite,Form,Kuva etc //Account Item like Ferrite,Form,Kuva etc
MiscItems: [typeCountSchema], MiscItems: [typeCountSchema],
//Non Upgrade Mods Example:I have 999 item WeaponElectricityDamageMod (only "ItemCount"+"ItemType")
RawUpgrades: [RawUpgrades],
//Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+"" //Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+""
Upgrades: [upgradesSchema], Upgrades: [upgradesSchema],
@ -672,95 +622,26 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
//Sentinel(like Helios or modular) //Sentinel(like Helios or modular)
Sentinels: [EquipmentSchema], Sentinels: [EquipmentSchema],
//Any /Sentinels/SentinelWeapons/ (like warframe weapon) //Any /Sentinels/SentinelWeapons/ (like warframe weapon)
SentinelWeapons: [EquipmentSchema], SentinelWeapons: [Schema.Types.Mixed],
//Modular Pets
MoaPets: [EquipmentSchema],
KubrowPetEggs: [Schema.Types.Mixed],
//Like PowerSuit Cat\Kubrow or etc Pets
KubrowPets: [EquipmentSchema],
//Prints Cat(3 Prints)\Kubrow(2 Prints) Pets
KubrowPetPrints: [Schema.Types.Mixed],
//Item for EquippedGear example:Scaner,LoadoutTechSummon etc //Item for EquippedGear example:Scaner,LoadoutTechSummon etc
Consumables: [typeCountSchema], Consumables: [typeCountSchema],
//Weel Emotes+Gear //Weel Emotes+Gear
EquippedEmotes: [String],
EquippedGear: [String],
//Equipped Shawzin //Equipped Shawzin
EquippedInstrument: String,
ReceivedStartingGear: Boolean, ReceivedStartingGear: Boolean,
//to use add SummonItem to Consumables+EquippedGear //Complete Mission
//Archwing need Suits+Melee+Guns
SpaceSuits: [EquipmentSchema],
SpaceMelee: [EquipmentSchema],
SpaceGuns: [EquipmentSchema],
ArchwingEnabled: Boolean,
//Mech need Suits+SpaceGuns+SpecialItem
MechSuits: [EquipmentSchema],
///Restoratives/HoverboardSummon (like Suit)
Hoverboards: [EquipmentSchema],
//Use Operator\Drifter
UseAdultOperatorLoadout: Boolean,
//Operator\Drifter Weapon
OperatorAmps: [EquipmentSchema],
//Operator
OperatorLoadOuts: [operatorConfigSchema],
//Drifter
AdultOperatorLoadOuts: [operatorConfigSchema],
DrifterMelee: [EquipmentSchema],
DrifterGuns: [EquipmentSchema],
//ErsatzHorsePowerSuit
Horses: [EquipmentSchema],
//LandingCraft like Liset
Ships: { type: [Schema.Types.ObjectId], ref: "Ships" },
// /Lotus/Types/Items/ShipDecos/
ShipDecorations: [typeCountSchema],
//RailJack Setting(Mods,Skin,Weapon,etc)
CrewShipHarnesses: [EquipmentSchema],
//Railjack/Components(https://warframe.fandom.com/wiki/Railjack/Components)
CrewShipRawSalvage: [Schema.Types.Mixed],
//Default RailJack
CrewShips: [Schema.Types.Mixed],
CrewShipAmmo: [typeCountSchema],
CrewShipWeapons: [Schema.Types.Mixed],
CrewShipWeaponSkins: [Schema.Types.Mixed],
//NPC Crew and weapon
CrewMembers: [Schema.Types.Mixed],
CrewShipSalvagedWeaponSkins: [Schema.Types.Mixed],
CrewShipSalvagedWeapons: [Schema.Types.Mixed],
//Complete Mission\Quests
Missions: [Schema.Types.Mixed], Missions: [Schema.Types.Mixed],
QuestKeys: [questKeysSchema],
//item like DojoKey or Boss missions key
LevelKeys: [Schema.Types.Mixed],
//Active quests
Quests: [Schema.Types.Mixed],
//Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc //Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc
FlavourItems: [FlavourItemSchema], FlavourItems: [FlavourItemSchema],
//Lunaro Weapon
Scoops: [EquipmentSchema],
//Mastery Rank*(Need item XPInfo to rank up) //Mastery Rank*(Need item XPInfo to rank up)
PlayerLevel: Number, PlayerLevel: Number,
//Item Mastery Rank exp //Item Mastery Rank exp
XPInfo: [TypeXPItemSchema], XPInfo: [TypeXPItemSchema],
//Mastery Rank next availability //Mastery Rank next availability
TrainingDate: Date, TrainingDate: Date,
//Retries rank up(3 time)
TrainingRetriesLeft: Number,
//you saw last played Region when you opened the star map
LastRegionPlayed: String,
//Blueprints for Foundry //Blueprints for Foundry
Recipes: [typeCountSchema], Recipes: [typeCountSchema],
@ -770,116 +651,35 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
//Skins for Suits, Weapons etc. //Skins for Suits, Weapons etc.
WeaponSkins: [weaponSkinsSchema], WeaponSkins: [weaponSkinsSchema],
//Ayatan Item
FusionTreasures: [fusionTreasuresSchema],
//only used for Maroo apparently - { "node": "TreasureTutorial", "state": "TS_COMPLETED" }
TauntHistory: { type: [tauntSchema], default: undefined },
//noShow2FA,VisitPrimeVault etc //noShow2FA,VisitPrimeVault etc
WebFlags: Schema.Types.Mixed, WebFlags: Schema.Types.Mixed,
//Id CompletedAlerts //Id CompletedAlerts
CompletedAlerts: [String], CompletedAlerts: [String],
//Warframe\Duviri
StoryModeChoice: String,
//Alert->Kuva Siphon
PeriodicMissionCompletions: [periodicMissionCompletionsSchema],
//Codex->LoreFragment
LoreFragmentScans: [loreFragmentScansSchema],
//Resource,Credit,Affinity etc or Bless any boosters //Resource,Credit,Affinity etc or Bless any boosters
Boosters: [boosterSchema], Boosters: [boosterSchema],
BlessingCooldown: Date, // Date convert to IMongoDate
//the color your clan requests like Items/Research/DojoColors/DojoColorPlainsB
ActiveDojoColorResearch: String,
SentientSpawnChanceBoosters: Schema.Types.Mixed,
QualifyingInvasions: [Schema.Types.Mixed],
FactionScores: [Number],
//Have only Suit+Pistols+LongGuns+Melee+ItemType(BronzeSpectre,GoldSpectre,PlatinumSpectreArmy,SilverSpectreArmy)
//"/Lotus/Types/Game/SpectreArmies/BronzeSpectreArmy": "Vapor Specter Regiment",
SpectreLoadouts: [spectreLoadoutsSchema],
//If you want change Spectre Gear id
PendingSpectreLoadouts: [Schema.Types.Mixed],
//New Quest Email //New Quest Email
EmailItems: [TypeXPItemSchema], EmailItems: [TypeXPItemSchema],
//Profile->Wishlist
Wishlist: [String],
//https://warframe.fandom.com/wiki/Alignment //https://warframe.fandom.com/wiki/Alignment
//like "Alignment": { "Wisdom": 9, "Alignment": 1 }, //like "Alignment": { "Wisdom": 9, "Alignment": 1 },
Alignment: Schema.Types.Mixed, Alignment: Schema.Types.Mixed,
AlignmentReplay: Schema.Types.Mixed, AlignmentReplay: Schema.Types.Mixed,
//https://warframe.fandom.com/wiki/Sortie
CompletedSorties: [String],
LastSortieReward: [Schema.Types.Mixed],
//Resource_Drone[Uselees stuff]
Drones: [Schema.Types.Mixed],
//Active profile ico //Active profile ico
ActiveAvatarImageType: String, ActiveAvatarImageType: String,
// open location store like EidolonPlainsDiscoverable or OrbVallisCaveDiscoverable
DiscoveredMarkers: [Schema.Types.Mixed],
//Open location mission like "JobId" + "StageCompletions"
CompletedJobs: [Schema.Types.Mixed],
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
PersonalGoalProgress: [Schema.Types.Mixed],
//Setting interface Style
ThemeStyle: String,
ThemeBackground: String,
ThemeSounds: String,
//Daily LoginRewards
LoginMilestoneRewards: [String],
//You first Dialog with NPC or use new Item //You first Dialog with NPC or use new Item
NodeIntrosCompleted: [String], NodeIntrosCompleted: [String],
//Current guild id, if applicable. //Current guild id, if applicable.
GuildId: { type: Schema.Types.ObjectId, ref: "Guild" }, GuildId: { type: Schema.Types.ObjectId, ref: "Guild" },
//https://warframe.fandom.com/wiki/Heist
//ProfitTaker(1-4) Example:"LocationTag": "EudicoHeists", "Jobs":Mission name
CompletedJobChains: [completedJobChainsSchema],
//Night Wave Challenge
SeasonChallengeHistory: [seasonChallengeHistorySchema],
//Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false
LibraryPersonalProgress: [Schema.Types.Mixed],
//Cephalon Simaris Daily Task
LibraryAvailableDailyTaskInfo: Schema.Types.Mixed,
//https://warframe.fandom.com/wiki/Invasion
InvasionChainProgress: [Schema.Types.Mixed],
//https://warframe.fandom.com/wiki/Parazon
DataKnives: [EquipmentSchema],
//CorpusLich or GrineerLich
NemesisAbandonedRewards: [String],
//CorpusLich\KuvaLich
NemesisHistory: [Schema.Types.Mixed],
LastNemesisAllySpawnTime: Schema.Types.Mixed,
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social) //TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
Settings: settingsSchema, Settings: settingsSchema,
//Railjack craft
//https://warframe.fandom.com/wiki/Rising_Tide
PersonalTechProjects: [Schema.Types.Mixed],
//Modulars lvl and exp(Railjack|Duviri) //Modulars lvl and exp(Railjack|Duviri)
//https://warframe.fandom.com/wiki/Intrinsics //https://warframe.fandom.com/wiki/Intrinsics
PlayerSkills: playerSkillsSchema, PlayerSkills: playerSkillsSchema,
@ -887,42 +687,15 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
//TradeBannedUntil data //TradeBannedUntil data
TradeBannedUntil: Schema.Types.Mixed, TradeBannedUntil: Schema.Types.Mixed,
//https://warframe.fandom.com/wiki/Helminth
InfestedFoundry: infestedFoundrySchema,
NextRefill: Schema.Types.Mixed, // Date, convert to IMongoDate
//Purchase this new permanent skin from the Lotus customization options in Personal Quarters located in your Orbiter.
//https://warframe.fandom.com/wiki/Lotus#The_New_War
LotusCustomization: Schema.Types.Mixed,
//Progress+Rank+ItemType(ZarimanPumpShotgun)
//https://warframe.fandom.com/wiki/Incarnon
EvolutionProgress: { type: [evolutionProgressSchema], default: undefined },
//Unknown and system //Unknown and system
DuviriInfo: DuviriInfoSchema,
Mailbox: MailboxSchema, Mailbox: MailboxSchema,
KahlLoadOuts: [Schema.Types.Mixed],
HandlerPoints: Number, HandlerPoints: Number,
ChallengesFixVersion: Number, ChallengesFixVersion: Number,
PlayedParkourTutorial: Boolean, PlayedParkourTutorial: Boolean,
SubscribedToEmailsPersonalized: Number, SubscribedToEmailsPersonalized: Number,
LastInventorySync: Schema.Types.Mixed, // this should be Schema.Types.ObjectId, but older inventories may break with that. LastInventorySync: Schema.Types.Mixed,
ActiveLandscapeTraps: [Schema.Types.Mixed],
RepVotes: [Schema.Types.Mixed],
LeagueTickets: [Schema.Types.Mixed],
HasContributedToDojo: Boolean,
HWIDProtectEnabled: Boolean,
LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" },
CurrentLoadOutIds: [Schema.Types.Mixed],
RandomUpgradesIdentified: Number,
BountyScore: Number,
ChallengeInstanceStates: [Schema.Types.Mixed],
RecentVendorPurchases: [Schema.Types.Mixed],
Robotics: [Schema.Types.Mixed], Robotics: [Schema.Types.Mixed],
UsedDailyDeals: [Schema.Types.Mixed],
CollectibleSeries: [Schema.Types.Mixed],
HasResetAccount: Boolean, HasResetAccount: Boolean,
//Discount Coupon //Discount Coupon

View File

@ -25,15 +25,7 @@ const databaseAccountSchema = new Schema<IDatabaseAccountDocument>(
email: { type: String, required: true, unique: true }, email: { type: String, required: true, unique: true },
password: { type: String, required: true }, password: { type: String, required: true },
DisplayName: { type: String, required: true }, DisplayName: { type: String, required: true },
CountryCode: { type: String, required: true }, Nonce: { type: Number, required: true }
ClientType: { type: String },
CrossPlatformAllowed: { type: Boolean, required: true },
ForceLogoutVersion: { type: Number, required: true },
AmazonAuthToken: { type: String },
AmazonRefreshToken: { type: String },
ConsentNeeded: { type: Boolean, required: true },
TrackedSettings: { type: [String], default: [] },
Nonce: { type: Number, default: 0 }
}, },
opts opts
); );

View File

@ -64,6 +64,8 @@ import { updateChallengeProgressController } from "@/src/controllers/api/updateC
import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController"; import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController";
import { updateThemeController } from "../controllers/api/updateThemeController"; import { updateThemeController } from "../controllers/api/updateThemeController";
import { upgradesController } from "@/src/controllers/api/upgradesController"; import { upgradesController } from "@/src/controllers/api/upgradesController";
import { worldStateController } from "../controllers/dynamic/worldStateController";
import { updateInventoryController } from "../controllers/api/updateInventoryController";
const apiRouter = express.Router(); const apiRouter = express.Router();
@ -99,6 +101,16 @@ apiRouter.get("/setSupportedSyndicate.php", setSupportedSyndicateController);
apiRouter.get("/surveys.php", surveysController); apiRouter.get("/surveys.php", surveysController);
apiRouter.get("/updateSession.php", updateSessionGetController); apiRouter.get("/updateSession.php", updateSessionGetController);
apiRouter.get('/getMessages.php', (_, response) => {
response.json({});
})
apiRouter.get('/trainingResult.php', (_, response) => {
response.status(200);
})
apiRouter.get('/giveStartingGear.php', (_, response) => {
response.status(200);
})
apiRouter.get('/worldState.php', worldStateController);
// post // post
apiRouter.post("/addFriendImage.php", addFriendImageController); apiRouter.post("/addFriendImage.php", addFriendImageController);
apiRouter.post("/artifacts.php", artifactsController); apiRouter.post("/artifacts.php", artifactsController);
@ -138,5 +150,6 @@ apiRouter.post("/updateNodeIntros.php", genericUpdateController);
apiRouter.post("/updateSession.php", updateSessionPostController); apiRouter.post("/updateSession.php", updateSessionPostController);
apiRouter.post("/updateTheme.php", updateThemeController); apiRouter.post("/updateTheme.php", updateThemeController);
apiRouter.post("/upgrades.php", upgradesController); apiRouter.post("/upgrades.php", upgradesController);
apiRouter.post("/updateInventory.php", updateInventoryController);
export { apiRouter }; export { apiRouter };

View File

@ -12,6 +12,11 @@ cacheRouter.get("/B.Cache.Windows_en.bin*", (_req, res) => {
res.sendFile("static/data/B.Cache.Windows_en_33.0.10.bin", { root: "./" }); res.sendFile("static/data/B.Cache.Windows_en_33.0.10.bin", { root: "./" });
}); });
cacheRouter.get("/H.Cache.bin!03_---------------------w", (_req, res) => {
res.sendFile(`static/data/H.Cache.bin`, { root: "./" });
});
cacheRouter.get(/^\/origin\/[a-zA-Z0-9]+\/[0-9]+\/H\.Cache\.bin.*$/, (_req, res) => { cacheRouter.get(/^\/origin\/[a-zA-Z0-9]+\/[0-9]+\/H\.Cache\.bin.*$/, (_req, res) => {
res.sendFile(`static/data/H.Cache_${buildConfig.version}.bin`, { root: "./" }); res.sendFile(`static/data/H.Cache_${buildConfig.version}.bin`, { root: "./" });
}); });

View File

@ -666,9 +666,8 @@ export interface ILotusCustomization extends IItemConfig {
export interface IMission { export interface IMission {
Completes: number; Completes: number;
Tier?: number;
Tag: string; Tag: string;
RewardsCooldownTime?: IMongoDate; BestRating?: number;
} }
export interface INemesisHistory { export interface INemesisHistory {

View File

@ -1,12 +1,7 @@
export interface ILoginResponse extends Omit<IDatabaseAccountDocument, "email" | "password"> { export interface ILoginResponse extends Omit<IDatabaseAccountDocument, "email" | "password"> {
Groups: IGroup[]; BuildLabel?: string;
BuildLabel: string; NatHash?: string;
MatchmakingBuildId: string; SteamId?: string;
platformCDNs: string[];
NRS: string[];
DTLS: number;
IRC: string[];
HUB: string;
} }
// Includes virtual ID // Includes virtual ID
@ -20,27 +15,14 @@ export interface IGroup {
} }
export interface IDatabaseAccount { export interface IDatabaseAccount {
email: string; email?: string;
password: string; password: string;
DisplayName: string; DisplayName?: string;
CountryCode: string; Nonce?: number;
ClientType: string;
CrossPlatformAllowed: boolean;
ForceLogoutVersion: number;
AmazonAuthToken?: string;
AmazonRefreshToken?: string;
ConsentNeeded: boolean;
TrackedSettings: string[];
Nonce: number;
} }
export interface ILoginRequest { export interface ILoginRequest {
email: string; email: string;
password: string; password: string;
time: number; ClientType?: string;
s: string;
lang: string;
date: number;
ClientType: string;
PS: string;
} }

View File

@ -2,163 +2,47 @@
"SubscribedToEmails": 0, "SubscribedToEmails": 0,
"SubscribedToEmailsPersonalized": 0, "SubscribedToEmailsPersonalized": 0,
"RewardSeed": -5604904486637265640, "RewardSeed": -5604904486637265640,
"CrewMemberBin": { "Slots": 3 },
"CrewShipSalvageBin": { "Slots": 8 },
"DrifterMelee": [{ "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"FusionPoints": 0,
"MechBin": { "Slots": 4 },
"OperatorAmpBin": { "Slots": 8 },
"PveBonusLoadoutBin": { "Slots": 0 },
"PvpBonusLoadoutBin": { "Slots": 0 },
"RandomModBin": { "Slots": 15 },
"RegularCredits": 3000, "RegularCredits": 3000,
"SentinelBin": { "Slots": 10 }, "SentinelBin": { "Slots": 10 },
"SpaceSuitBin": { "Slots": 4 }, "SpaceSuitBin": { "Slots": 4 },
"SpaceWeaponBin": { "Slots": 4 }, "SpaceWeaponBin": { "Slots": 4 },
"SuitBin": { "Slots": 1 }, "SuitBin": { "Slots": 1 },
"WeaponBin": { "Slots": 5 }, "WeaponBin": { "Slots": 5 },
"DailyAffiliation": 16000,
"DailyAffiliationCetus": 16000,
"DailyAffiliationEntrati": 16000,
"DailyAffiliationKahl": 16000,
"DailyAffiliationLibrary": 16000,
"DailyAffiliationNecraloid": 16000,
"DailyAffiliationPvp": 16000,
"DailyAffiliationQuills": 16000,
"DailyAffiliationSolaris": 16000,
"DailyAffiliationVentkids": 16000,
"DailyAffiliationVox": 16000,
"DailyAffiliationZariman": 16000,
"DailyAffiliationCavia": 16000,
"DailyFocus": 250000,
"DuviriInfo": { "Seed": 5898912197983600352, "NumCompletions": 0 },
"GiftsRemaining": 8,
"TradesRemaining": 0,
"Recipes": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Recipes/Weapons/BoltonfaBlueprint" }], "Recipes": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Recipes/Weapons/BoltonfaBlueprint" }],
"SeasonChallengeHistory": [
{ "challenge": "SeasonDailySolveCiphers", "id": "001000220000000000000308" },
{ "challenge": "SeasonDailyVisitFeaturedDojo", "id": "001000230000000000000316" },
{ "challenge": "SeasonDailyKillEnemiesWithRadiation", "id": "001000230000000000000317" },
{ "challenge": "SeasonWeeklyCompleteSortie", "id": "001000230000000000000309" },
{ "challenge": "SeasonWeeklyVenusBounties", "id": "001000230000000000000310" },
{ "challenge": "SeasonWeeklyZarimanBountyHunter", "id": "001000230000000000000311" },
{ "challenge": "SeasonWeeklyCatchRarePlainsFish", "id": "001000230000000000000312" },
{ "challenge": "SeasonWeeklyKillArchgunEnemies", "id": "001000230000000000000313" },
{ "challenge": "SeasonWeeklyHardKillSilverGroveSpecters", "id": "001000230000000000000314" },
{ "challenge": "SeasonWeeklyHardKillRopalolyst", "id": "001000230000000000000315" }
],
"StoryModeChoice": "WARFRAME",
"ChallengeProgress": [{ "Progress": 2, "Name": "EMGetKills" }], "ChallengeProgress": [{ "Progress": 2, "Name": "EMGetKills" }],
"ChallengesFixVersion": 6,
"ActiveQuest": "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain",
"Consumables": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Restoratives/LisetAutoHack" }], "Consumables": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Restoratives/LisetAutoHack" }],
"DataKnives": [{ "ItemType": "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon", "XP": 450000, "ItemId": { "$oid": "647bd274f22fc794a2cd3d33" } }],
"FlavourItems": [ "FlavourItems": [
{ "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" }, { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" },
{ "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" }, { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" },
{ "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" }, { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" },
{ "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" } { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" }
], ],
"LongGuns": [{ "ItemType": "/Lotus/Weapons/MK1Series/MK1Paris", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], "LongGuns": [{ "ItemType": "/Lotus/Weapons/Tenno/Bows/HuntingBow", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"Melee": [{ "ItemType": "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], "Melee": [{ "ItemType": "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"Pistols": [{ "ItemType": "/Lotus/Weapons/MK1Series/MK1Kunai", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], "Pistols": [{ "ItemType": "/Lotus/Weapons/Tenno/Pistol/TutorialPistol", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"PlayedParkourTutorial": true,
"PremiumCreditsFree": 50,
"QuestKeys": [{ "ItemType": "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" }],
"RawUpgrades": [{ "ItemCount": 1, "LastAdded": { "$oid": "6450f9bfe0714a4d6703f05f" }, "ItemType": "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }], "RawUpgrades": [{ "ItemCount": 1, "LastAdded": { "$oid": "6450f9bfe0714a4d6703f05f" }, "ItemType": "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }],
"ReceivedStartingGear": true, "ReceivedStartingGear": true,
"Scoops": [{ "ItemType": "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"Ships": [{ "ItemType": "/Lotus/Types/Items/Ships/DefaultShip", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"Suits": [{ "ItemType": "/Lotus/Powersuits/Volt/Volt", "XP": 0, "Configs": [{}, {}, {}], "UpgradeVer": 101, "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], "Suits": [{ "ItemType": "/Lotus/Powersuits/Volt/Volt", "XP": 0, "Configs": [{}, {}, {}], "UpgradeVer": 101, "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"TrainingRetriesLeft": 0,
"WeaponSkins": [{ "ItemType": "/Lotus/Upgrades/Skins/Volt/VoltHelmet", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], "WeaponSkins": [{ "ItemType": "/Lotus/Upgrades/Skins/Volt/VoltHelmet", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }],
"LastInventorySync": { "$oid": "647bd27cf856530b4f3bf343" },
"NextRefill": { "$date": { "$numberLong": "1685829131" } },
"ActiveLandscapeTraps": [],
"CrewMembers": [],
"CrewShips": [],
"CrewShipHarnesses": [],
"CrewShipSalvagedWeapons": [],
"CrewShipSalvagedWeaponSkins": [],
"CrewShipWeapons": [],
"CrewShipWeaponSkins": [],
"DrifterGuns": [],
"Drones": [],
"Horses": [
{
"ItemType": "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit",
"Configs": [
{
"Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"]
},
{
"Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"]
},
{
"Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"]
}
],
"UpgradeVer": 101,
"ItemId": { "$oid": "647bd27cf856530b4f3bf343" }
}
],
"Hoverboards": [],
"KubrowPets": [],
"KubrowPetEggs": [],
"KubrowPetPrints": [],
"MechSuits": [],
"MoaPets": [],
"OperatorAmps": [],
"OperatorLoadOuts": [],
"AdultOperatorLoadOuts": [],
"KahlLoadOuts": [],
"PendingRecipes": [], "PendingRecipes": [],
"TrainingDate": 0, "TrainingDate": 0,
"PlayerLevel": 0, "PlayerLevel": 0,
"PersonalGoalProgress": [], "CompletedAlerts": [],
"PersonalTechProjects": [],
"QualifyingInvasions": [],
"RepVotes": [],
"Sentinels": [], "Sentinels": [],
"SentinelWeapons": [], "SentinelWeapons": [],
"SpaceGuns": [],
"SpaceMelee": [],
"SpaceSuits": [],
"SpecialItems": [], "SpecialItems": [],
"StepSequencers": [], "StepSequencers": [],
"Upgrades": [], "Upgrades": [],
"Boosters": [], "Boosters": [],
"EmailItems": [], "EmailItems": [],
"FocusUpgrades": [],
"FusionTreasures": [],
"LeagueTickets": [], "LeagueTickets": [],
"LevelKeys": [],
"LoreFragmentScans": [],
"MiscItems": [], "MiscItems": [],
"PendingSpectreLoadouts": [],
"Quests": [],
"Robotics": [], "Robotics": [],
"ShipDecorations": [],
"SpectreLoadouts": [],
"XPInfo": [], "XPInfo": [],
"CrewShipAmmo": [], "Missions": [ {
"CrewShipRawSalvage": [], "Tag" : "SolNode103",
"EvolutionProgress": [], "Completes" : 1,
"Missions": [], "BestRating" : 0.2
"TauntHistory": [], }],
"CompletedSyndicates": [],
"UsedDailyDeals": [],
"LibraryAvailableDailyTaskInfo": {
"EnemyTypes": ["/Lotus/Types/Enemies/Orokin/OrokinBladeSawmanAvatar"],
"EnemyLocTag": "/Lotus/Language/Game/OrokinBladeSawman",
"EnemyIcon": "/Lotus/Interface/Icons/Npcs/Orokin/OrokinBladeSawman.png",
"ScansRequired": 4,
"RewardStoreItem": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle",
"RewardQuantity": 10,
"RewardStanding": 10000
},
"HasContributedToDojo": false,
"HasResetAccount": false,
"PendingCoupon": { "Expiry": { "$date": { "$numberLong": "0" } }, "Discount": 0 },
"PremiumCredits": 50 "PremiumCredits": 50
} }