XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

feat: filter login rewards by buildLabel (#4127)

Closes #3903 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/4127 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

8108fefa
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

5 个文件 +261 -219
Modified src/controllers/api/giveLoginRewardController.ts +3 -2
@@ -6,13 +6,14 @@ import {
6 6 type ILoginReward
7 7 } from "../../services/loginRewardService.ts";
8 8 import { getJSONfromString } from "../../helpers/stringHelpers.ts";
9 import { getAccountForRequest } from "../../services/loginService.ts";
9 import { getAccountForRequest, getBuildLabel } from "../../services/loginService.ts";
10 10 import { getInventory } from "../../services/inventoryService.ts";
11 11 import { sendWsBroadcastTo } from "../../services/wsService.ts";
12 12 import { logger } from "../../utils/logger.ts";
13 13
14 14 export const giveLoginRewardController: RequestHandler = async (req, res) => {
15 15 const account = await getAccountForRequest(req);
16 const buildLabel = getBuildLabel(req, account);
16 17 const today = Math.trunc(Date.now() / 86400000) * 86400;
17 18 if (account.LastLoginRewardDate == today) {
18 19 logger.debug(`login reward was already pre-emptively claimed server-side, so ignoring manual claim`);
@@ -21,7 +22,7 @@ export const giveLoginRewardController: RequestHandler = async (req, res) => {
21 22 const body = getJSONfromString<IGiveLoginRewardRequest>(String(req.body));
22 23 const inventory = await getInventory(account._id, undefined);
23 24
24 const randomRewards = getRandomLoginRewards(account, inventory);
25 const randomRewards = await getRandomLoginRewards(account, inventory, buildLabel);
25 26 const chosenReward = randomRewards.find(x => x.StoreItemType == body.reward.StoreItemType)!;
26 27 const inventoryChanges = await claimLoginReward(inventory, chosenReward);
27 28
Modified src/controllers/api/loginRewardsController.ts +3 -4
@@ -22,7 +22,8 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
22 22 if (today != account.LastLoginRewardDate) {
23 23 const inventory = await getInventory(account._id, undefined);
24 24 if (!inventory.disableDailyTribute) {
25 const randomRewards = getRandomLoginRewards(account, inventory);
25 const buildLabel = getBuildLabel(req, account);
26 const randomRewards = await getRandomLoginRewards(account, inventory, buildLabel);
26 27 const response: ILoginRewardsReponse = {
27 28 DailyTributeInfo: {
28 29 Rewards: randomRewards,
@@ -37,8 +38,6 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
37 38 LastLoginRewardDate: today
38 39 };
39 40
40 const buildLabel = getBuildLabel(req, account);
41
42 41 // https://wiki.warframe.com/w/Login_Rewards
43 42 const is_pre_daily_tribute = version_compare(buildLabel, gameToBuildVersion["18.0.2"]) < 0;
44 43 const is_pre_milestones = version_compare(buildLabel, gameToBuildVersion["23.10.0"]) < 0;
@@ -61,7 +60,7 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
61 60 if (reward.Icon == "/Lotus/Interface/Icons/StoreIcons/Currency/CreditsLarge.png") {
62 61 reward.Icon = "/Lotus/Interface/Icons/Store/CreditBooster.png";
63 62 } else if (reward.RewardType == "RT_RESOURCE") {
64 reward.Icon = ExportResources[reward.ItemType].icon.replaceAll(
63 reward.Icon = ExportResources[reward.ItemType!].icon.replaceAll(
65 64 "/Lotus/Interface/Icons/StoreIcons/Resources/CraftingComponents/",
66 65 "/Lotus/Interface/Icons/Store/"
67 66 );
Modified src/controllers/api/loginRewardsSelectionController.ts +3 -2
@@ -4,7 +4,7 @@ import {
4 4 getRandomLoginRewards,
5 5 setAccountGotLoginRewardToday
6 6 } from "../../services/loginRewardService.ts";
7 import { getAccountForRequest } from "../../services/loginService.ts";
7 import { getAccountForRequest, getBuildLabel } from "../../services/loginService.ts";
8 8 import { handleStoreItemAcquisition } from "../../services/purchaseService.ts";
9 9 import { sendWsBroadcastTo } from "../../services/wsService.ts";
10 10 import type { IInventoryChanges } from "../../types/purchaseTypes.ts";
@@ -13,6 +13,7 @@ import type { RequestHandler } from "express";
13 13
14 14 export const loginRewardsSelectionController: RequestHandler = async (req, res) => {
15 15 const account = await getAccountForRequest(req);
16 const buildLabel = getBuildLabel(req, account);
16 17 const inventory = await getInventory(account._id, undefined);
17 18 const body = JSON.parse(String(req.body)) as ILoginRewardsSelectionRequest;
18 19 const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
@@ -31,7 +32,7 @@ export const loginRewardsSelectionController: RequestHandler = async (req, res)
31 32 inventory.LoginMilestoneRewards.push(body.ChosenReward);
32 33 }
33 34 } else {
34 const randomRewards = getRandomLoginRewards(account, inventory);
35 const randomRewards = await getRandomLoginRewards(account, inventory, buildLabel);
35 36 chosenReward = randomRewards.find(x => x.StoreItemType == body.ChosenReward)!;
36 37 inventoryChanges = await claimLoginReward(inventory, chosenReward);
37 38 }
Modified src/services/loginRewardService.ts +252 -24
@@ -1,4 +1,3 @@
1 import randomRewards from "../../static/fixed_responses/loginRewards/randomRewards.json" with { type: "json" };
2 1 import type { IInventoryChanges } from "../types/purchaseTypes.ts";
3 2 import type { TAccountDocument } from "./loginService.ts";
4 3 import { mixSeeds, SRng } from "./rngService.ts";
@@ -6,14 +5,16 @@ import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inven
6 5 import { addBooster, updateCurrency } from "./inventoryService.ts";
7 6 import { handleStoreItemAcquisition } from "./purchaseService.ts";
8 7 import {
9 ExportBoosterPacks,
10 8 ExportBoosters,
11 9 ExportRecipes,
12 10 ExportWarframes,
13 ExportWeapons
11 ExportWeapons,
12 type TRarity
14 13 } from "warframe-public-export-plus";
15 import { fromStoreItem, toStoreItem } from "./itemDataService.ts";
14 import { fromStoreItem, getBoosterPack, toStoreItem } from "./itemDataService.ts";
16 15 import { logger } from "../utils/logger.ts";
16 import { version_compare } from "../helpers/inventoryHelpers.ts";
17 import gameToBuildVersion from "../constants/gameToBuildVersion.ts";
17 18
18 19 export interface ILoginRewardsReponse {
19 20 DailyTributeInfo: {
@@ -35,15 +36,15 @@ export interface ILoginReward {
35 36 //_id: IOid;
36 37 RewardType: string;
37 38 //CouponType: "CPT_PLATINUM";
38 Icon: string;
39 ItemType: string; // pre-daily tribute
39 Icon?: string;
40 ItemType?: string; // pre-daily tribute
40 41 StoreItemType: string; // uniquely identifies the reward
41 42 //ProductCategory: "Pistols";
42 43 Amount: number;
43 44 ScalingMultiplier: number;
44 45 //Durability: "COMMON";
45 46 //DisplayName: "";
46 Duration: number;
47 Duration?: number;
47 48 //CouponSku: number;
48 49 //Rarity: number;
49 50 Transmission: string;
@@ -63,17 +64,18 @@ export const isLoginRewardAChoice = (account: TAccountDocument): boolean => {
63 64 };
64 65
65 66 // Always produces the same result for the same account _id & LoginDays pair.
66 export const getRandomLoginRewards = (
67 export const getRandomLoginRewards = async (
67 68 account: TAccountDocument,
68 inventory: TInventoryDatabaseDocument
69 ): ILoginReward[] => {
69 inventory: TInventoryDatabaseDocument,
70 buildLabel: string
71 ): Promise<ILoginReward[]> => {
70 72 const accountSeed = parseInt(account._id.toString().substring(16), 16);
71 73 const rng = new SRng(mixSeeds(accountSeed, account.LoginDays));
72 74 const pick_a_door = rng.randomFloat() < 0.25;
73 const rewards = [getRandomLoginReward(rng, account.LoginDays, inventory)];
75 const rewards = [await getRandomLoginReward(rng, account.LoginDays, inventory, buildLabel)];
74 76 if (pick_a_door) {
75 77 do {
76 const reward = getRandomLoginReward(rng, account.LoginDays, inventory);
78 const reward = await getRandomLoginReward(rng, account.LoginDays, inventory, buildLabel);
77 79 if (!rewards.find(x => x.StoreItemType == reward.StoreItemType)) {
78 80 rewards.push(reward);
79 81 }
@@ -82,8 +84,27 @@ export const getRandomLoginRewards = (
82 84 return rewards;
83 85 };
84 86
85 const getRandomLoginReward = (rng: SRng, day: number, inventory: TInventoryDatabaseDocument): ILoginReward => {
86 const reward = rng.randomReward(randomRewards)!;
87 const getRandomLoginReward = async (
88 rng: SRng,
89 day: number,
90 inventory: TInventoryDatabaseDocument,
91 buildLabel: string
92 ): Promise<ILoginReward> => {
93 const filteredPool = randomRewards.filter(r => {
94 return !r.minBuildLabel || version_compare(buildLabel, r.minBuildLabel) >= 0;
95 });
96 const resultPool: (ILoginReward & { probability: number })[] = [];
97 const rarityCounts: Record<TRarity, number> = { COMMON: 0, UNCOMMON: 0, RARE: 0, LEGENDARY: 0 };
98 for (const entry of filteredPool) {
99 ++rarityCounts[entry.Rarity];
100 }
101 for (const entry of filteredPool) {
102 resultPool.push({
103 ...entry,
104 probability: randomRewardsWeights[entry.Rarity] / rarityCounts[entry.Rarity]
105 });
106 }
107 const reward = rng.randomReward(resultPool)!;
87 108 //const reward = randomRewards.find(x => x.RewardType == "RT_BOOSTER")!;
88 109 let storeItemType: string = reward.StoreItemType;
89 110 if (reward.RewardType == "RT_RANDOM_RECIPE") {
@@ -93,13 +114,34 @@ const getRandomLoginReward = (rng: SRng, day: number, inventory: TInventoryDatab
93 114 }
94 115 const unmasteredItems = new Set();
95 116 for (const [uniqueName, data] of Object.entries(ExportWeapons)) {
96 if (data.totalDamage != 0 && data.variantType == "VT_NORMAL" && !masteredItems.has(uniqueName)) {
97 unmasteredItems.add(uniqueName);
117 if (
118 data.totalDamage != 0 &&
119 data.variantType == "VT_NORMAL" &&
120 !masteredItems.has(uniqueName) &&
121 data.introducedAt
122 ) {
123 const date = new Date(data.introducedAt * 1000);
124 if (
125 version_compare(
126 buildLabel,
127 `${date.getUTCFullYear()}.${date.getUTCMonth()}.${date.getUTCDate()}.${date.getUTCHours()}.${date.getUTCMinutes()}`
128 ) >= 0
129 ) {
130 unmasteredItems.add(uniqueName);
131 }
98 132 }
99 133 }
100 134 for (const [uniqueName, data] of Object.entries(ExportWarframes)) {
101 if (data.variantType == "VT_NORMAL" && !masteredItems.has(uniqueName)) {
102 unmasteredItems.add(uniqueName);
135 if (data.variantType == "VT_NORMAL" && !masteredItems.has(uniqueName) && data.introducedAt) {
136 const date = new Date(data.introducedAt * 1000);
137 if (
138 version_compare(
139 buildLabel,
140 `${date.getUTCFullYear()}.${date.getUTCMonth()}.${date.getUTCDate()}.${date.getUTCHours()}.${date.getUTCMinutes()}`
141 ) >= 0
142 ) {
143 unmasteredItems.add(uniqueName);
144 }
103 145 }
104 146 }
105 147 const eligibleRecipes: string[] = [];
@@ -110,14 +152,16 @@ const getRandomLoginReward = (rng: SRng, day: number, inventory: TInventoryDatab
110 152 }
111 153 if (eligibleRecipes.length == 0) {
112 154 // This account has all applicable warframes and weapons already mastered (filthy cheater), need a different reward.
113 return getRandomLoginReward(rng, day, inventory);
155 return await getRandomLoginReward(rng, day, inventory, buildLabel);
114 156 }
115 157 storeItemType = toStoreItem(rng.randomElement(eligibleRecipes)!);
116 158 } else if (reward.StoreItemType == "/Lotus/StoreItems/Types/BoosterPacks/LoginRewardRandomProjection") {
117 storeItemType = toStoreItem(
118 rng.randomElement(ExportBoosterPacks["/Lotus/Types/BoosterPacks/LoginRewardRandomProjection"].components)!
119 .Item
120 );
159 const boosterPackType =
160 version_compare(buildLabel, gameToBuildVersion["18.16.0"]) >= 0
161 ? "/Lotus/Types/BoosterPacks/LoginRewardRandomProjection"
162 : "/Lotus/Types/BoosterPacks/RandomKey";
163 const boosterPack = await getBoosterPack(boosterPackType, buildLabel);
164 storeItemType = toStoreItem(rng.randomElement(boosterPack!.components)!.Item);
121 165 }
122 166 return {
123 167 //_id: toOid(new Types.ObjectId()),
@@ -167,7 +211,7 @@ export const claimLoginReward = async (
167 211 case "RT_BOOSTER": {
168 212 logger.debug(`claim login reward`, reward); // all other paths already log in some other way
169 213 const ItemType = ExportBoosters[reward.StoreItemType].typeName;
170 const ExpiryDate = 3600 * reward.Duration;
214 const ExpiryDate = 3600 * reward.Duration!;
171 215 addBooster(ItemType, ExpiryDate, inventory);
172 216 return {
173 217 Boosters: [{ ItemType, ExpiryDate }]
@@ -188,3 +232,187 @@ export const setAccountGotLoginRewardToday = (
188 232 }
189 233 account.LastLoginRewardDate = Math.trunc(Date.now() / 86400000) * 86400;
190 234 };
235
236 const randomRewardsWeights: Record<TRarity, number> = {
237 COMMON: 151,
238 UNCOMMON: 0,
239 RARE: 4,
240 LEGENDARY: 0
241 };
242
243 const randomRewards: (ILoginReward & { Rarity: TRarity; minBuildLabel?: string })[] = [
244 {
245 RewardType: "RT_RESOURCE",
246 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/OxiumAlloy",
247 Amount: 100,
248 ScalingMultiplier: 1,
249 Rarity: "COMMON",
250 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Ordis/DDayTribOrdis",
251 minBuildLabel: gameToBuildVersion["12.1.2"] // Should be U11.9
252 },
253 {
254 RewardType: "RT_RESOURCE",
255 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/Gallium",
256 Amount: 1,
257 ScalingMultiplier: 1,
258 Rarity: "COMMON",
259 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
260 },
261 {
262 RewardType: "RT_RESOURCE",
263 StoreItemType: "/Lotus/StoreItems/Types/Items/Research/ChemFragment",
264 Amount: 2,
265 ScalingMultiplier: 1,
266 Rarity: "COMMON",
267 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo",
268 minBuildLabel: gameToBuildVersion["8.0.0"]
269 },
270 {
271 RewardType: "RT_RESOURCE",
272 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/Morphic",
273 Amount: 1,
274 ScalingMultiplier: 1,
275 Rarity: "COMMON",
276 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
277 },
278 {
279 RewardType: "RT_RESOURCE",
280 StoreItemType: "/Lotus/StoreItems/Types/Items/Research/EnergyFragment",
281 Amount: 2,
282 ScalingMultiplier: 1,
283 Rarity: "COMMON",
284 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo",
285 minBuildLabel: gameToBuildVersion["8.0.0"]
286 },
287 {
288 RewardType: "RT_RESOURCE",
289 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/NeuralSensor",
290 Amount: 1,
291 ScalingMultiplier: 1,
292 Rarity: "COMMON",
293 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
294 },
295 {
296 RewardType: "RT_RESOURCE",
297 StoreItemType: "/Lotus/StoreItems/Types/Items/Research/BioFragment",
298 Amount: 2,
299 ScalingMultiplier: 1,
300 Rarity: "COMMON",
301 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo",
302 minBuildLabel: gameToBuildVersion["8.0.0"]
303 },
304 {
305 RewardType: "RT_RESOURCE",
306 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/Neurode",
307 Amount: 1,
308 ScalingMultiplier: 1,
309 Rarity: "COMMON",
310 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
311 },
312 {
313 RewardType: "RT_RESOURCE",
314 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/OrokinCell",
315 Amount: 1,
316 ScalingMultiplier: 1,
317 Rarity: "COMMON",
318 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
319 },
320 {
321 RewardType: "RT_RESOURCE",
322 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/Cryotic",
323 Amount: 50,
324 ScalingMultiplier: 1,
325 Rarity: "COMMON",
326 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo",
327 minBuildLabel: gameToBuildVersion["15.0.0"] // Should be U14.5
328 },
329 {
330 RewardType: "RT_RESOURCE",
331 StoreItemType: "/Lotus/StoreItems/Types/Items/MiscItems/Tellurium",
332 Amount: 1,
333 ScalingMultiplier: 1,
334 Rarity: "COMMON",
335 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo",
336 minBuildLabel: gameToBuildVersion["15.14.1"] // Should be U15.7.2
337 },
338 {
339 RewardType: "RT_CREDITS",
340 StoreItemType: "",
341 Icon: "/Lotus/Interface/Icons/StoreIcons/Currency/CreditsLarge.png",
342 Amount: 10000,
343 ScalingMultiplier: 1,
344 Rarity: "COMMON",
345 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
346 },
347 {
348 RewardType: "RT_BOOSTER",
349 StoreItemType: "/Lotus/Types/StoreItems/Boosters/AffinityBoosterStoreItem",
350 Amount: 1,
351 ScalingMultiplier: 2,
352 Duration: 3,
353 Rarity: "COMMON",
354 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
355 },
356 {
357 RewardType: "RT_BOOSTER",
358 StoreItemType: "/Lotus/Types/StoreItems/Boosters/CreditBoosterStoreItem",
359 Amount: 1,
360 ScalingMultiplier: 2,
361 Duration: 3,
362 Rarity: "COMMON",
363 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
364 },
365 {
366 RewardType: "RT_BOOSTER",
367 StoreItemType: "/Lotus/Types/StoreItems/Boosters/ResourceAmountBoosterStoreItem",
368 Amount: 1,
369 ScalingMultiplier: 2,
370 Duration: 3,
371 Rarity: "COMMON",
372 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs",
373 minBuildLabel: gameToBuildVersion["11.1.3"] // Wiki says its in game since Vanilla
374 },
375 {
376 RewardType: "RT_BOOSTER",
377 StoreItemType: "/Lotus/Types/StoreItems/Boosters/ResourceDropChanceBoosterStoreItem",
378 Amount: 1,
379 ScalingMultiplier: 2,
380 Duration: 3,
381 Rarity: "COMMON",
382 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs",
383 minBuildLabel: gameToBuildVersion["11.1.3"] // Wiki says its in game since Vanilla
384 },
385 {
386 RewardType: "RT_STORE_ITEM",
387 StoreItemType: "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/RareFusionBundle",
388 Amount: 1,
389 ScalingMultiplier: 1,
390 Rarity: "COMMON",
391 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Maroo/DDayTribMaroo",
392 minBuildLabel: gameToBuildVersion["18.18.0"]
393 },
394 {
395 RewardType: "RT_RECIPE",
396 StoreItemType: "/Lotus/StoreItems/Types/Recipes/Components/FormaBlueprint",
397 Amount: 1,
398 ScalingMultiplier: 0.5,
399 Rarity: "RARE",
400 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Maroo/DDayTribMaroo"
401 },
402 {
403 RewardType: "RT_RANDOM_RECIPE",
404 StoreItemType: "",
405 Amount: 1,
406 ScalingMultiplier: 0,
407 Rarity: "COMMON",
408 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Teshin/DDayTribTeshin"
409 },
410 {
411 RewardType: "RT_STORE_ITEM",
412 StoreItemType: "/Lotus/StoreItems/Types/BoosterPacks/LoginRewardRandomProjection",
413 Amount: 1,
414 ScalingMultiplier: 1,
415 Rarity: "RARE",
416 Transmission: "/Lotus/Sounds/Dialog/DailyTribute/Ordis/DDayTribOrdis"
417 }
418 ];
Deleted static/fixed_responses/loginRewards/randomRewards.json +0 -187
@@ -1,187 +0,0 @@
1 [
2 {
3 "RewardType": "RT_RESOURCE",
4 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/OxiumAlloy",
5 "Amount": 100,
6 "ScalingMultiplier": 1,
7 "Rarity": "COMMON",
8 "probability": 0.055392516507703576,
9 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Ordis/DDayTribOrdis"
10 },
11 {
12 "RewardType": "RT_RESOURCE",
13 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/Gallium",
14 "Amount": 1,
15 "ScalingMultiplier": 1,
16 "Rarity": "COMMON",
17 "probability": 0.055392516507703576,
18 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
19 },
20 {
21 "RewardType": "RT_RESOURCE",
22 "StoreItemType": "/Lotus/StoreItems/Types/Items/Research/ChemFragment",
23 "Amount": 2,
24 "ScalingMultiplier": 1,
25 "Rarity": "COMMON",
26 "probability": 0.055392516507703576,
27 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
28 },
29 {
30 "RewardType": "RT_RESOURCE",
31 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/Morphic",
32 "Amount": 1,
33 "ScalingMultiplier": 1,
34 "Rarity": "COMMON",
35 "probability": 0.055392516507703576,
36 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
37 },
38 {
39 "RewardType": "RT_RESOURCE",
40 "StoreItemType": "/Lotus/StoreItems/Types/Items/Research/EnergyFragment",
41 "Amount": 2,
42 "ScalingMultiplier": 1,
43 "Rarity": "COMMON",
44 "probability": 0.055392516507703576,
45 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
46 },
47 {
48 "RewardType": "RT_RESOURCE",
49 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/NeuralSensor",
50 "Amount": 1,
51 "ScalingMultiplier": 1,
52 "Rarity": "COMMON",
53 "probability": 0.055392516507703576,
54 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
55 },
56 {
57 "RewardType": "RT_RESOURCE",
58 "StoreItemType": "/Lotus/StoreItems/Types/Items/Research/BioFragment",
59 "Amount": 2,
60 "ScalingMultiplier": 1,
61 "Rarity": "COMMON",
62 "probability": 0.055392516507703576,
63 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
64 },
65 {
66 "RewardType": "RT_RESOURCE",
67 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/Neurode",
68 "Amount": 1,
69 "ScalingMultiplier": 1,
70 "Rarity": "COMMON",
71 "probability": 0.055392516507703576,
72 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
73 },
74 {
75 "RewardType": "RT_RESOURCE",
76 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/OrokinCell",
77 "Amount": 1,
78 "ScalingMultiplier": 1,
79 "Rarity": "COMMON",
80 "probability": 0.055392516507703576,
81 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
82 },
83 {
84 "RewardType": "RT_RESOURCE",
85 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/Cryotic",
86 "Amount": 50,
87 "ScalingMultiplier": 1,
88 "Rarity": "COMMON",
89 "probability": 0.055392516507703576,
90 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
91 },
92 {
93 "RewardType": "RT_RESOURCE",
94 "StoreItemType": "/Lotus/StoreItems/Types/Items/MiscItems/Tellurium",
95 "Amount": 1,
96 "ScalingMultiplier": 1,
97 "Rarity": "COMMON",
98 "probability": 0.055392516507703576,
99 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Darvo/DDayTribDarvo"
100 },
101 {
102 "RewardType": "RT_CREDITS",
103 "StoreItemType": "",
104 "Icon": "/Lotus/Interface/Icons/StoreIcons/Currency/CreditsLarge.png",
105 "Amount": 10000,
106 "ScalingMultiplier": 1,
107 "Rarity": "COMMON",
108 "probability": 0.055392516507703576,
109 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
110 },
111 {
112 "RewardType": "RT_BOOSTER",
113 "StoreItemType": "/Lotus/Types/StoreItems/Boosters/AffinityBoosterStoreItem",
114 "Amount": 1,
115 "ScalingMultiplier": 2,
116 "Duration": 3,
117 "Rarity": "COMMON",
118 "probability": 0.055392516507703576,
119 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
120 },
121 {
122 "RewardType": "RT_BOOSTER",
123 "StoreItemType": "/Lotus/Types/StoreItems/Boosters/CreditBoosterStoreItem",
124 "Amount": 1,
125 "ScalingMultiplier": 2,
126 "Duration": 3,
127 "Rarity": "COMMON",
128 "probability": 0.055392516507703576,
129 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
130 },
131 {
132 "RewardType": "RT_BOOSTER",
133 "StoreItemType": "/Lotus/Types/StoreItems/Boosters/ResourceAmountBoosterStoreItem",
134 "Amount": 1,
135 "ScalingMultiplier": 2,
136 "Duration": 3,
137 "Rarity": "COMMON",
138 "probability": 0.055392516507703576,
139 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
140 },
141 {
142 "RewardType": "RT_BOOSTER",
143 "StoreItemType": "/Lotus/Types/StoreItems/Boosters/ResourceDropChanceBoosterStoreItem",
144 "Amount": 1,
145 "ScalingMultiplier": 2,
146 "Duration": 3,
147 "Rarity": "COMMON",
148 "probability": 0.055392516507703576,
149 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Simaris/DDayTribSmrs"
150 },
151 {
152 "RewardType": "RT_STORE_ITEM",
153 "StoreItemType": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/RareFusionBundle",
154 "Amount": 1,
155 "ScalingMultiplier": 1,
156 "Rarity": "COMMON",
157 "probability": 0.055392516507703576,
158 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Maroo/DDayTribMaroo"
159 },
160 {
161 "RewardType": "RT_RECIPE",
162 "StoreItemType": "/Lotus/StoreItems/Types/Recipes/Components/FormaBlueprint",
163 "Amount": 1,
164 "ScalingMultiplier": 0.5,
165 "Rarity": "RARE",
166 "probability": 0.001467351430667816,
167 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Maroo/DDayTribMaroo"
168 },
169 {
170 "RewardType": "RT_RANDOM_RECIPE",
171 "StoreItemType": "",
172 "Amount": 1,
173 "ScalingMultiplier": 0,
174 "Rarity": "COMMON",
175 "probability": 0.055392516507703576,
176 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Teshin/DDayTribTeshin"
177 },
178 {
179 "RewardType": "RT_STORE_ITEM",
180 "StoreItemType": "/Lotus/StoreItems/Types/BoosterPacks/LoginRewardRandomProjection",
181 "Amount": 1,
182 "ScalingMultiplier": 1,
183 "Rarity": "RARE",
184 "probability": 0.001467351430667816,
185 "Transmission": "/Lotus/Sounds/Dialog/DailyTribute/Ordis/DDayTribOrdis"
186 }
187 ]