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

SpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/SpaceNinjaServer

chore: more faithful handling of daily tribute (#1324)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1324

06ce4ac6
Sainan <sainan@calamity.inc>
提交于

代码差异

4 个文件 +37 -14
Modified src/controllers/api/loginRewardsController.ts +20 -9
@@ -1,31 +1,42 @@
1 1 import { RequestHandler } from "express";
2 2 import { getAccountForRequest } from "@/src/services/loginService";
3 import { claimLoginReward, getRandomLoginRewards, ILoginRewardsReponse } from "@/src/services/loginRewardService";
3 import {
4 claimLoginReward,
5 getRandomLoginRewards,
6 ILoginRewardsReponse,
7 isLoginRewardAChoice
8 } from "@/src/services/loginRewardService";
4 9 import { getInventory } from "@/src/services/inventoryService";
5 10
6 11 export const loginRewardsController: RequestHandler = async (req, res) => {
7 12 const account = await getAccountForRequest(req);
8 13 const today = Math.trunc(Date.now() / 86400000) * 86400;
14 const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
15 const nextMilestoneDay = account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50;
9 16
10 17 if (today == account.LastLoginRewardDate) {
11 res.end();
18 res.json({
19 DailyTributeInfo: {
20 IsMilestoneDay: isMilestoneDay,
21 IsChooseRewardSet: isLoginRewardAChoice(account),
22 LoginDays: account.LoginDays,
23 NextMilestoneReward: "",
24 NextMilestoneDay: nextMilestoneDay
25 }
26 } satisfies ILoginRewardsReponse);
12 27 return;
13 28 }
14 account.LoginDays += 1;
15 account.LastLoginRewardDate = today;
16 await account.save();
17 29
18 30 const inventory = await getInventory(account._id.toString());
19 31 const randomRewards = getRandomLoginRewards(account, inventory);
20 const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
21 32 const response: ILoginRewardsReponse = {
22 33 DailyTributeInfo: {
23 34 Rewards: randomRewards,
24 35 IsMilestoneDay: isMilestoneDay,
25 36 IsChooseRewardSet: randomRewards.length != 1,
26 37 LoginDays: account.LoginDays,
27 //NextMilestoneReward: "",
28 NextMilestoneDay: account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50,
38 NextMilestoneReward: "",
39 NextMilestoneDay: nextMilestoneDay,
29 40 HasChosenReward: false
30 41 },
31 42 LastLoginRewardDate: today
@@ -33,7 +44,7 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
33 44 if (!isMilestoneDay && randomRewards.length == 1) {
34 45 response.DailyTributeInfo.HasChosenReward = true;
35 46 response.DailyTributeInfo.ChosenReward = randomRewards[0];
36 response.DailyTributeInfo.NewInventory = await claimLoginReward(inventory, randomRewards[0]);
47 response.DailyTributeInfo.NewInventory = await claimLoginReward(account, inventory, randomRewards[0]);
37 48 await inventory.save();
38 49 }
39 50 res.json(response);
Modified src/controllers/api/loginRewardsSelectionController.ts +1 -1
@@ -28,7 +28,7 @@ export const loginRewardsSelectionController: RequestHandler = async (req, res)
28 28 } else {
29 29 const randomRewards = getRandomLoginRewards(account, inventory);
30 30 chosenReward = randomRewards.find(x => x.StoreItemType == body.ChosenReward)!;
31 inventoryChanges = await claimLoginReward(inventory, chosenReward);
31 inventoryChanges = await claimLoginReward(account, inventory, chosenReward);
32 32 }
33 33 await inventory.save();
34 34 res.json({
Modified src/models/loginModel.ts +1 -1
@@ -23,7 +23,7 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
23 23 Dropped: Boolean,
24 24 LatestEventMessageDate: { type: Date, default: 0 },
25 25 LastLoginRewardDate: { type: Number, default: 0 },
26 LoginDays: { type: Number, default: 0 }
26 LoginDays: { type: Number, default: 1 }
27 27 },
28 28 opts
29 29 );
Modified src/services/loginRewardService.ts +15 -3
@@ -14,7 +14,7 @@ export interface ILoginRewardsReponse {
14 14 IsMilestoneDay?: boolean;
15 15 IsChooseRewardSet?: boolean;
16 16 LoginDays?: number; // when calling multiple times per day, this is already incremented to represent "tomorrow"
17 //NextMilestoneReward?: "";
17 NextMilestoneReward?: "";
18 18 NextMilestoneDay?: number; // seems to not be used if IsMilestoneDay
19 19 HasChosenReward?: boolean;
20 20 NewInventory?: IInventoryChanges;
@@ -46,6 +46,13 @@ const scaleAmount = (day: number, amount: number, scalingMultiplier: number): nu
46 46 return amount + Math.min(day, 3000) / divisor;
47 47 };
48 48
49 // Always produces the same result for the same account _id & LoginDays pair.
50 export const isLoginRewardAChoice = (account: TAccountDocument): boolean => {
51 const accountSeed = parseInt(account._id.toString().substring(16), 16);
52 const rng = new CRng(mixSeeds(accountSeed, account.LoginDays));
53 return rng.random() < 0.25; // Using 25% as an approximate chance for pick-a-doors. More conclusive data analysis is needed.
54 };
55
49 56 // Always produces the same result for the same account _id & LoginDays pair.
50 57 export const getRandomLoginRewards = (
51 58 account: TAccountDocument,
@@ -53,9 +60,9 @@ export const getRandomLoginRewards = (
53 60 ): ILoginReward[] => {
54 61 const accountSeed = parseInt(account._id.toString().substring(16), 16);
55 62 const rng = new CRng(mixSeeds(accountSeed, account.LoginDays));
63 const pick_a_door = rng.random() < 0.25; // Using 25% as an approximate chance for pick-a-doors. More conclusive data analysis is needed.
56 64 const rewards = [getRandomLoginReward(rng, account.LoginDays, inventory)];
57 // Using 25% an approximate chance for pick-a-doors. More conclusive data analysis is needed.
58 if (rng.random() < 0.25) {
65 if (pick_a_door) {
59 66 do {
60 67 const reward = getRandomLoginReward(rng, account.LoginDays, inventory);
61 68 if (!rewards.find(x => x.StoreItemType == reward.StoreItemType)) {
@@ -114,9 +121,14 @@ const getRandomLoginReward = (rng: CRng, day: number, inventory: TInventoryDatab
114 121 };
115 122
116 123 export const claimLoginReward = async (
124 account: TAccountDocument,
117 125 inventory: TInventoryDatabaseDocument,
118 126 reward: ILoginReward
119 127 ): Promise<IInventoryChanges> => {
128 account.LoginDays += 1;
129 account.LastLoginRewardDate = Math.trunc(Date.now() / 86400000) * 86400;
130 await account.save();
131
120 132 switch (reward.RewardType) {
121 133 case "RT_RESOURCE":
122 134 case "RT_STORE_ITEM":