返回提交历史
Modified
src/controllers/api/loginRewardsController.ts
+20
-9
Modified
src/controllers/api/loginRewardsSelectionController.ts
+1
-1
Modified
src/models/loginModel.ts
+1
-1
Modified
src/services/loginRewardService.ts
+15
-3
XFEstudio/SpaceNinjaServer
chore: more faithful handling of daily tribute (#1324)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1324
06ce4ac6
代码差异
4 个文件
+37
-14
@@ -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);
@@ -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({
@@ -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
);
@@ -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":