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