-- interest.lua (Deadlock problem fixed) local BALANCE_INTEREST_RATE = tonumber(minetest.settings:get("bank_accounts.interest_rate_balance")) or 0.005 local CREDIT_INTEREST_RATE = tonumber(minetest.settings:get("bank_accounts.interest_rate_credit")) or 0.03 local INTEREST_CHECK_INTERVAL = tonumber(minetest.settings:get("bank_accounts.interest_check_interval")) or 600 local ONE_DAY_IN_SECONDS = 86400 local timestamp_file_path = minetest.get_worldpath() .. "/bank_interest_timestamp.txt" local function read_timestamp() local f = io.open(timestamp_file_path, "r") if not f then return 0 end local time = tonumber(f:read("*a")) f:close() return time or 0 end local function write_timestamp(time) local f = io.open(timestamp_file_path, "w") if not f then return end f:write(tostring(time)) f:close() end local time_since_last_check = 0 bank_accounts.is_calculating_interest = false minetest.register_globalstep(function(dtime) if not minetest.settings:get_bool("bank_accounts.interest_enabled", true) then return end time_since_last_check = time_since_last_check + dtime if time_since_last_check < INTEREST_CHECK_INTERVAL then return end time_since_last_check = 0 local last_timestamp = read_timestamp() if os.time() - last_timestamp >= ONE_DAY_IN_SECONDS then if bank_accounts.is_calculating_interest then return end minetest.log("action", "[bank_accounts] Starting daily interest calculation...") bank_accounts.is_calculating_interest = true local data = bank_accounts.get_all_data() local changes_made = false -- Calculate interest on positive balances if BALANCE_INTEREST_RATE > 0 then for player_name, balance in pairs(data.balance) do if balance > 0 then local interest = balance * BALANCE_INTEREST_RATE data.balance[player_name] = balance + interest if not data.history then data.history = {} end if not data.history[player_name] then data.history[player_name] = {} end table.insert(data.history[player_name], 1, { timestamp = os.time(), type = "Interest Paid", account = "balance", amount = interest, new_total = data.balance[player_name], purpose = S("Daily interest (@1%)", BALANCE_INTEREST_RATE * 100), other = "Bank" }) changes_made = true end end end -- Calculate interest on credit debt if CREDIT_INTEREST_RATE > 0 then for player_name, credit in pairs(data.credit) do if credit > 0 then local interest = credit * CREDIT_INTEREST_RATE data.credit[player_name] = credit + interest if not data.history then data.history = {} end if not data.history[player_name] then data.history[player_name] = {} end table.insert(data.history[player_name], 1, { timestamp = os.time(), type = "Interest Charged", account = "credit", amount = interest, new_total = data.credit[player_name], purpose = S("Daily interest (@1%)", CREDIT_INTEREST_RATE * 100), other = "Bank" }) changes_made = true end end end if changes_made then -- CORRECTED: Now calls the API function that bypasses the lock local success = bank_accounts.save_all(data) if success then minetest.log("action", "[bank_accounts] Daily interest calculation complete and saved.") -- CORRECTED: Timestamp is only updated after a successful save. write_timestamp(os.time()) else minetest.log("error", "[bank_accounts] Saving interest data FAILED. Will retry later.") end else -- If no changes were made, still update the timestamp to prevent re-running immediately. write_timestamp(os.time()) end bank_accounts.is_calculating_interest = false end end)