feat: add dailylogin feature

This commit is contained in:
2026-05-01 05:07:54 +08:00
parent 54be7bbb25
commit 21875cdf8a
17 changed files with 1262 additions and 34 deletions
+155
View File
@@ -43,6 +43,12 @@ function InitModule(ctx, logger, nk, initializer) {
initializer.registerRpc("send_lobby_invite", rpcSendLobbyInvite);
initializer.registerRpc("send_friend_request", rpcSendFriendRequest);
// Daily Rewards RPCs
initializer.registerRpc("claim_daily_reward", rpcClaimDailyReward);
initializer.registerRpc("get_daily_reward_state", rpcGetDailyRewardState);
initializer.registerRpc("set_daily_reward_config", rpcSetDailyRewardConfig);
initializer.registerRpc("get_daily_reward_config_admin", rpcGetDailyRewardConfigAdmin);
// Steam auth hooks
initializer.registerAfterAuthenticateSteam(afterAuthenticateSteam);
@@ -593,6 +599,155 @@ function rpcPurchaseItem(ctx, logger, nk, payload) {
}
}
// =============================================================================
// Daily Rewards RPCs
// =============================================================================
function rpcClaimDailyReward(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("Not authenticated");
var now = new Date();
var currentMonth = now.toISOString().substring(5, 7); // e.g. "05"
var todayStr = now.toISOString().substring(0, 10);
var stateObjs = nk.storageRead([{ collection: "daily_rewards", key: "state", userId: ctx.userId }]);
var state = { claimed_days: 0, last_claim_date: "", month: "" };
if (stateObjs && stateObjs.length > 0) {
state = stateObjs[0].value;
}
if (state.month !== currentMonth) {
state.claimed_days = 0;
state.month = currentMonth;
}
if (state.last_claim_date === todayStr) {
throw new Error("Already claimed today");
}
var configObjs = nk.storageRead([{ collection: "config", key: "daily_rewards", userId: "00000000-0000-0000-0000-000000000000" }]);
var config = {};
if (configObjs && configObjs.length > 0) {
config = configObjs[0].value;
}
var monthRewards = config[currentMonth];
if (!monthRewards || monthRewards.length === 0) {
monthRewards = [];
for (var i = 0; i < 31; i++) {
monthRewards.push({ type: "star", amount: Math.min(10 + i * 5, 100) });
}
}
var dayIndex = state.claimed_days;
if (dayIndex >= monthRewards.length) {
throw new Error("Already claimed all rewards for this month");
}
var rewardData = monthRewards[dayIndex];
if (typeof rewardData === "number") {
rewardData = { type: "star", amount: rewardData };
}
var rewardType = rewardData.type || "star";
var rewardAmount = rewardData.amount || 0;
if (rewardType === "star" || rewardType === "gold") {
var changes = {};
changes[rewardType] = rewardAmount;
nk.walletUpdate(ctx.userId, changes, {}, true);
} else if (rewardType.startsWith("frag_")) {
var invObjs = nk.storageRead([{ collection: "inventory", key: "fragments", userId: ctx.userId }]);
var frags = {};
if (invObjs && invObjs.length > 0) {
frags = invObjs[0].value;
}
frags[rewardType] = (frags[rewardType] || 0) + rewardAmount;
nk.storageWrite([{
collection: "inventory",
key: "fragments",
userId: ctx.userId,
value: frags,
permissionRead: 1,
permissionWrite: 0
}]);
}
state.claimed_days++;
state.last_claim_date = todayStr;
nk.storageWrite([{
collection: "daily_rewards",
key: "state",
userId: ctx.userId,
value: state,
permissionRead: 1,
permissionWrite: 0
}]);
return JSON.stringify({ success: true, reward_type: rewardType, reward_amount: rewardAmount, day: state.claimed_days });
}
function rpcGetDailyRewardState(ctx, logger, nk, payload) {
if (!ctx.userId) throw new Error("Not authenticated");
var now = new Date();
var currentMonth = now.toISOString().substring(5, 7); // e.g. "05"
var todayStr = now.toISOString().substring(0, 10);
var stateObjs = nk.storageRead([{ collection: "daily_rewards", key: "state", userId: ctx.userId }]);
var state = { claimed_days: 0, last_claim_date: "", month: "" };
if (stateObjs && stateObjs.length > 0) {
state = stateObjs[0].value;
}
if (state.month !== currentMonth) {
state.claimed_days = 0;
state.month = currentMonth;
}
var configObjs = nk.storageRead([{ collection: "config", key: "daily_rewards", userId: "00000000-0000-0000-0000-000000000000" }]);
var config = {};
if (configObjs && configObjs.length > 0) {
config = configObjs[0].value;
}
var monthRewards = config[currentMonth];
if (!monthRewards || monthRewards.length === 0) {
monthRewards = [];
for (var i = 0; i < 31; i++) {
monthRewards.push({ type: "star", amount: Math.min(10 + i * 5, 100) });
}
}
return JSON.stringify({
state: state,
month_rewards: monthRewards,
can_claim_today: state.last_claim_date !== todayStr && state.claimed_days < monthRewards.length,
today_date: todayStr
});
}
function rpcSetDailyRewardConfig(ctx, logger, nk, payload) {
requireAdmin(ctx, nk);
var request = JSON.parse(payload || "{}");
nk.storageWrite([{
collection: "config",
key: "daily_rewards",
userId: "00000000-0000-0000-0000-000000000000",
value: request.config,
permissionRead: 2,
permissionWrite: 0
}]);
return JSON.stringify({ success: true });
}
function rpcGetDailyRewardConfigAdmin(ctx, logger, nk, payload) {
requireAdmin(ctx, nk);
var configObjs = nk.storageRead([{ collection: "config", key: "daily_rewards", userId: "00000000-0000-0000-0000-000000000000" }]);
var config = {};
if (configObjs && configObjs.length > 0) {
config = configObjs[0].value;
}
return JSON.stringify({ config: config });
}
// =============================================================================
// User Profile RPCs
// =============================================================================