Files
tekton/server/nakama/lua/daily_rewards.lua
T
2026-05-19 17:30:29 +08:00

206 lines
7.1 KiB
Lua

local nk = require("nakama")
local utils = require("lua.utils")
local daily_rewards = {}
function daily_rewards.rpc_claim_daily_reward(context, payload)
if not context.user_id then error("Not authenticated") end
local now = os.date("!*t")
local currentMonth = string.format("%02d", now.month)
local todayStr = string.format("%04d-%02d-%02d", now.year, now.month, now.day)
local todayIndex = now.day - 1 -- 0 to 30
local stateObjs = nk.storage_read({{ collection = "daily_rewards", key = "state", user_id = context.user_id }})
local state = { claimed_days = {}, last_claim_date = "", month = "" }
if stateObjs and #stateObjs > 0 then
local val = stateObjs[1].value
state.last_claim_date = val.last_claim_date or ""
state.month = val.month or ""
if type(val.claimed_days) == "number" then
for i = 0, val.claimed_days - 1 do
table.insert(state.claimed_days, i)
end
elseif type(val.claimed_days) == "table" then
state.claimed_days = val.claimed_days
end
end
if state.month ~= currentMonth then
state.claimed_days = {}
state.month = currentMonth
end
if state.last_claim_date == todayStr then
error("Already claimed today")
end
local configObjs = nk.storage_read({{ collection = "config", key = "daily_rewards", user_id = "00000000-0000-0000-0000-000000000000" }})
local config = {}
if configObjs and #configObjs > 0 then
config = configObjs[1].value
end
local monthRewards = config[currentMonth]
if not monthRewards or #monthRewards == 0 then
monthRewards = {}
for i = 0, 30 do
table.insert(monthRewards, { type = "star", amount = math.min(10 + i * 5, 100) })
end
end
local dayIndex = todayIndex
-- In lua array size is #monthRewards
if dayIndex >= #monthRewards then
error("Already claimed all rewards for this month")
end
local hasClaimed = false
for _, claimed_day in ipairs(state.claimed_days) do
if claimed_day == dayIndex then
hasClaimed = true
break
end
end
if hasClaimed then
error("Already claimed today's reward")
end
-- Lua arrays are 1-indexed!
local rewardData = monthRewards[dayIndex + 1]
if type(rewardData) == "number" then
rewardData = { type = "star", amount = rewardData }
end
local rewardType = rewardData.type or "star"
local rewardAmount = rewardData.amount or 0
if rewardType == "star" or rewardType == "gold" then
local changes = {}
changes[rewardType] = rewardAmount
nk.wallet_update(context.user_id, changes, {}, true)
elseif string.sub(rewardType, 1, 5) == "frag_" then
local invObjs = nk.storage_read({{ collection = "inventory", key = "fragments", user_id = context.user_id }})
local frags = {}
if invObjs and #invObjs > 0 then
frags = invObjs[1].value
end
frags[rewardType] = (frags[rewardType] or 0) + rewardAmount
nk.storage_write({{
collection = "inventory",
key = "fragments",
user_id = context.user_id,
value = frags,
permission_read = 1,
permission_write = 0
}})
end
table.insert(state.claimed_days, dayIndex)
state.last_claim_date = todayStr
nk.storage_write({{
collection = "daily_rewards",
key = "state",
user_id = context.user_id,
value = state,
permission_read = 1,
permission_write = 0
}})
return nk.json_encode({ success = true, reward_type = rewardType, reward_amount = rewardAmount, day = dayIndex + 1 })
end
function daily_rewards.rpc_get_daily_reward_state(context, payload)
if not context.user_id then error("Not authenticated") end
local now = os.date("!*t")
local currentMonth = string.format("%02d", now.month)
local todayStr = string.format("%04d-%02d-%02d", now.year, now.month, now.day)
local todayIndex = now.day - 1
local stateObjs = nk.storage_read({{ collection = "daily_rewards", key = "state", user_id = context.user_id }})
local state = { claimed_days = {}, last_claim_date = "", month = "" }
if stateObjs and #stateObjs > 0 then
local val = stateObjs[1].value
state.last_claim_date = val.last_claim_date or ""
state.month = val.month or ""
if type(val.claimed_days) == "number" then
for i = 0, val.claimed_days - 1 do
table.insert(state.claimed_days, i)
end
elseif type(val.claimed_days) == "table" then
state.claimed_days = val.claimed_days
end
end
if state.month ~= currentMonth then
state.claimed_days = {}
state.month = currentMonth
end
local configObjs = nk.storage_read({{ collection = "config", key = "daily_rewards", user_id = "00000000-0000-0000-0000-000000000000" }})
local config = {}
if configObjs and #configObjs > 0 then
config = configObjs[1].value
end
local monthRewards = config[currentMonth]
if not monthRewards or #monthRewards == 0 then
monthRewards = {}
for i = 0, 30 do
table.insert(monthRewards, { type = "star", amount = math.min(10 + i * 5, 100) })
end
end
local hasClaimedToday = false
for _, claimed_day in ipairs(state.claimed_days) do
if claimed_day == todayIndex then hasClaimedToday = true break end
end
local canClaimToday = (state.last_claim_date ~= todayStr) and (not hasClaimedToday) and (todayIndex < #monthRewards)
return nk.json_encode({
state = state,
month_rewards = monthRewards,
can_claim_today = canClaimToday,
today_date = todayStr,
today_index = todayIndex,
server_month = now.month
})
end
function daily_rewards.rpc_set_daily_reward_config(context, payload)
utils.require_admin(context)
local request = nk.json_decode(payload or "{}")
nk.storage_write({{
collection = "config",
key = "daily_rewards",
user_id = "00000000-0000-0000-0000-000000000000",
value = request.config,
permission_read = 2,
permission_write = 0
}})
return nk.json_encode({ success = true })
end
function daily_rewards.rpc_get_daily_reward_config_admin(context, payload)
utils.require_admin(context)
local configObjs = nk.storage_read({{ collection = "config", key = "daily_rewards", user_id = "00000000-0000-0000-0000-000000000000" }})
local config = {}
if configObjs and #configObjs > 0 then
config = configObjs[1].value
end
return nk.json_encode({ config = config })
end
nk.register_rpc(daily_rewards.rpc_claim_daily_reward, "claim_daily_reward")
nk.register_rpc(daily_rewards.rpc_get_daily_reward_state, "get_daily_reward_state")
nk.register_rpc(daily_rewards.rpc_set_daily_reward_config, "set_daily_reward_config")
nk.register_rpc(daily_rewards.rpc_get_daily_reward_config_admin, "get_daily_reward_config_admin")
nk.logger_info("LUA TEST: daily rewards module loaded")
return daily_rewards