forked from OpenWF/SpaceNinjaServer
chore: more faithful handling of daily tribute (#1324)
Reviewed-on: OpenWF/SpaceNinjaServer#1324
This commit is contained in:
parent
bfcd928fde
commit
06ce4ac695
@ -1,31 +1,42 @@
|
|||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { getAccountForRequest } from "@/src/services/loginService";
|
import { getAccountForRequest } from "@/src/services/loginService";
|
||||||
import { claimLoginReward, getRandomLoginRewards, ILoginRewardsReponse } from "@/src/services/loginRewardService";
|
import {
|
||||||
|
claimLoginReward,
|
||||||
|
getRandomLoginRewards,
|
||||||
|
ILoginRewardsReponse,
|
||||||
|
isLoginRewardAChoice
|
||||||
|
} from "@/src/services/loginRewardService";
|
||||||
import { getInventory } from "@/src/services/inventoryService";
|
import { getInventory } from "@/src/services/inventoryService";
|
||||||
|
|
||||||
export const loginRewardsController: RequestHandler = async (req, res) => {
|
export const loginRewardsController: RequestHandler = async (req, res) => {
|
||||||
const account = await getAccountForRequest(req);
|
const account = await getAccountForRequest(req);
|
||||||
const today = Math.trunc(Date.now() / 86400000) * 86400;
|
const today = Math.trunc(Date.now() / 86400000) * 86400;
|
||||||
|
const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
|
||||||
|
const nextMilestoneDay = account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50;
|
||||||
|
|
||||||
if (today == account.LastLoginRewardDate) {
|
if (today == account.LastLoginRewardDate) {
|
||||||
res.end();
|
res.json({
|
||||||
|
DailyTributeInfo: {
|
||||||
|
IsMilestoneDay: isMilestoneDay,
|
||||||
|
IsChooseRewardSet: isLoginRewardAChoice(account),
|
||||||
|
LoginDays: account.LoginDays,
|
||||||
|
NextMilestoneReward: "",
|
||||||
|
NextMilestoneDay: nextMilestoneDay
|
||||||
|
}
|
||||||
|
} satisfies ILoginRewardsReponse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
account.LoginDays += 1;
|
|
||||||
account.LastLoginRewardDate = today;
|
|
||||||
await account.save();
|
|
||||||
|
|
||||||
const inventory = await getInventory(account._id.toString());
|
const inventory = await getInventory(account._id.toString());
|
||||||
const randomRewards = getRandomLoginRewards(account, inventory);
|
const randomRewards = getRandomLoginRewards(account, inventory);
|
||||||
const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
|
|
||||||
const response: ILoginRewardsReponse = {
|
const response: ILoginRewardsReponse = {
|
||||||
DailyTributeInfo: {
|
DailyTributeInfo: {
|
||||||
Rewards: randomRewards,
|
Rewards: randomRewards,
|
||||||
IsMilestoneDay: isMilestoneDay,
|
IsMilestoneDay: isMilestoneDay,
|
||||||
IsChooseRewardSet: randomRewards.length != 1,
|
IsChooseRewardSet: randomRewards.length != 1,
|
||||||
LoginDays: account.LoginDays,
|
LoginDays: account.LoginDays,
|
||||||
//NextMilestoneReward: "",
|
NextMilestoneReward: "",
|
||||||
NextMilestoneDay: account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50,
|
NextMilestoneDay: nextMilestoneDay,
|
||||||
HasChosenReward: false
|
HasChosenReward: false
|
||||||
},
|
},
|
||||||
LastLoginRewardDate: today
|
LastLoginRewardDate: today
|
||||||
@ -33,7 +44,7 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
|
|||||||
if (!isMilestoneDay && randomRewards.length == 1) {
|
if (!isMilestoneDay && randomRewards.length == 1) {
|
||||||
response.DailyTributeInfo.HasChosenReward = true;
|
response.DailyTributeInfo.HasChosenReward = true;
|
||||||
response.DailyTributeInfo.ChosenReward = randomRewards[0];
|
response.DailyTributeInfo.ChosenReward = randomRewards[0];
|
||||||
response.DailyTributeInfo.NewInventory = await claimLoginReward(inventory, randomRewards[0]);
|
response.DailyTributeInfo.NewInventory = await claimLoginReward(account, inventory, randomRewards[0]);
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
}
|
}
|
||||||
res.json(response);
|
res.json(response);
|
||||||
|
@ -28,7 +28,7 @@ export const loginRewardsSelectionController: RequestHandler = async (req, res)
|
|||||||
} else {
|
} else {
|
||||||
const randomRewards = getRandomLoginRewards(account, inventory);
|
const randomRewards = getRandomLoginRewards(account, inventory);
|
||||||
chosenReward = randomRewards.find(x => x.StoreItemType == body.ChosenReward)!;
|
chosenReward = randomRewards.find(x => x.StoreItemType == body.ChosenReward)!;
|
||||||
inventoryChanges = await claimLoginReward(inventory, chosenReward);
|
inventoryChanges = await claimLoginReward(account, inventory, chosenReward);
|
||||||
}
|
}
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.json({
|
res.json({
|
||||||
|
@ -23,7 +23,7 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
|
|||||||
Dropped: Boolean,
|
Dropped: Boolean,
|
||||||
LatestEventMessageDate: { type: Date, default: 0 },
|
LatestEventMessageDate: { type: Date, default: 0 },
|
||||||
LastLoginRewardDate: { type: Number, default: 0 },
|
LastLoginRewardDate: { type: Number, default: 0 },
|
||||||
LoginDays: { type: Number, default: 0 }
|
LoginDays: { type: Number, default: 1 }
|
||||||
},
|
},
|
||||||
opts
|
opts
|
||||||
);
|
);
|
||||||
|
@ -14,7 +14,7 @@ export interface ILoginRewardsReponse {
|
|||||||
IsMilestoneDay?: boolean;
|
IsMilestoneDay?: boolean;
|
||||||
IsChooseRewardSet?: boolean;
|
IsChooseRewardSet?: boolean;
|
||||||
LoginDays?: number; // when calling multiple times per day, this is already incremented to represent "tomorrow"
|
LoginDays?: number; // when calling multiple times per day, this is already incremented to represent "tomorrow"
|
||||||
//NextMilestoneReward?: "";
|
NextMilestoneReward?: "";
|
||||||
NextMilestoneDay?: number; // seems to not be used if IsMilestoneDay
|
NextMilestoneDay?: number; // seems to not be used if IsMilestoneDay
|
||||||
HasChosenReward?: boolean;
|
HasChosenReward?: boolean;
|
||||||
NewInventory?: IInventoryChanges;
|
NewInventory?: IInventoryChanges;
|
||||||
@ -46,6 +46,13 @@ const scaleAmount = (day: number, amount: number, scalingMultiplier: number): nu
|
|||||||
return amount + Math.min(day, 3000) / divisor;
|
return amount + Math.min(day, 3000) / divisor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Always produces the same result for the same account _id & LoginDays pair.
|
||||||
|
export const isLoginRewardAChoice = (account: TAccountDocument): boolean => {
|
||||||
|
const accountSeed = parseInt(account._id.toString().substring(16), 16);
|
||||||
|
const rng = new CRng(mixSeeds(accountSeed, account.LoginDays));
|
||||||
|
return rng.random() < 0.25; // Using 25% as an approximate chance for pick-a-doors. More conclusive data analysis is needed.
|
||||||
|
};
|
||||||
|
|
||||||
// Always produces the same result for the same account _id & LoginDays pair.
|
// Always produces the same result for the same account _id & LoginDays pair.
|
||||||
export const getRandomLoginRewards = (
|
export const getRandomLoginRewards = (
|
||||||
account: TAccountDocument,
|
account: TAccountDocument,
|
||||||
@ -53,9 +60,9 @@ export const getRandomLoginRewards = (
|
|||||||
): ILoginReward[] => {
|
): ILoginReward[] => {
|
||||||
const accountSeed = parseInt(account._id.toString().substring(16), 16);
|
const accountSeed = parseInt(account._id.toString().substring(16), 16);
|
||||||
const rng = new CRng(mixSeeds(accountSeed, account.LoginDays));
|
const rng = new CRng(mixSeeds(accountSeed, account.LoginDays));
|
||||||
|
const pick_a_door = rng.random() < 0.25; // Using 25% as an approximate chance for pick-a-doors. More conclusive data analysis is needed.
|
||||||
const rewards = [getRandomLoginReward(rng, account.LoginDays, inventory)];
|
const rewards = [getRandomLoginReward(rng, account.LoginDays, inventory)];
|
||||||
// Using 25% an approximate chance for pick-a-doors. More conclusive data analysis is needed.
|
if (pick_a_door) {
|
||||||
if (rng.random() < 0.25) {
|
|
||||||
do {
|
do {
|
||||||
const reward = getRandomLoginReward(rng, account.LoginDays, inventory);
|
const reward = getRandomLoginReward(rng, account.LoginDays, inventory);
|
||||||
if (!rewards.find(x => x.StoreItemType == reward.StoreItemType)) {
|
if (!rewards.find(x => x.StoreItemType == reward.StoreItemType)) {
|
||||||
@ -114,9 +121,14 @@ const getRandomLoginReward = (rng: CRng, day: number, inventory: TInventoryDatab
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const claimLoginReward = async (
|
export const claimLoginReward = async (
|
||||||
|
account: TAccountDocument,
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
reward: ILoginReward
|
reward: ILoginReward
|
||||||
): Promise<IInventoryChanges> => {
|
): Promise<IInventoryChanges> => {
|
||||||
|
account.LoginDays += 1;
|
||||||
|
account.LastLoginRewardDate = Math.trunc(Date.now() / 86400000) * 86400;
|
||||||
|
await account.save();
|
||||||
|
|
||||||
switch (reward.RewardType) {
|
switch (reward.RewardType) {
|
||||||
case "RT_RESOURCE":
|
case "RT_RESOURCE":
|
||||||
case "RT_STORE_ITEM":
|
case "RT_STORE_ITEM":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user