You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Payday 2 BLT模组中的Lua Stack Overflow错误?

Fixing Stack Overflow and Access Violations in Your Payday 2 BLT Mod

Let's break down your issues step by step and work through fixes:

1. Root Cause of the Initial Stack Overflow

The stack overflow on line 13 (local _id = "id_" .. tostring(self._id)) is almost certainly tied to one of two problems:

  • Circular references in self._id: If self._id is a table with a circular reference (e.g., it points back to itself or another table that loops back to it), tostring() will recursively traverse the table until the stack runs out of space.
  • Infinite recursive calls: Your custom on_executed hook calls the original function at the end, but if your Run_Script logic triggers another on_executed call (like invoking the mission element's own on_executed method), this creates an infinite loop that piles up function calls until the stack overflows.

Fix for Stack Overflow

Add a guard to block recursive execution, and handle self._id safely to avoid circular reference crashes:

core:module("CoreMissionScriptElement")
core:import("CoreXml")
core:import("CoreCode")
core:import("CoreClass")
_G.ShadowRaidLoud = _G.ShadowRaidLoud or {}
ShadowRaidLoud = _G.ShadowRaidLoud
ShadowRaidLoud.Run_Script_Data = ShadowRaidLoud.Run_Script_Data or {}

local ShadowRaidLoud_OpenVault = MissionScriptElement.on_executed
function MissionScriptElement:on_executed(instigator, ...)
    -- Guard against recursive hook calls
    if self._shadow_raid_executing then
        return ShadowRaidLoud_OpenVault(self, instigator, ...)
    end
    self._shadow_raid_executing = true

    -- Safely handle self._id to avoid circular reference crashes
    local _id
    local id_type = type(self._id)
    if id_type == "number" or id_type == "string" then
        _id = "id_" .. self._id
    else
        _id = "id_unknown"
        -- Optional: Log the issue for debugging
        log("[ShadowRaidLoud] Unexpected _id type: " .. id_type .. " for element: " .. tostring(self))
    end

    if ShadowRaidLoud and ShadowRaidLoud.Enable and not Network:is_client() and not Global.loading then
        if (_id == "id_100961" or _id == "id_100962") and not ShadowRaidLoud.Run_Script_Data[_id] then
            local element = self:get_mission_element(100964)
            if element then
                local msg = "[System] Vault will open in ".. ShadowRaidLoud.Time4Use.OpenVault .." seconds"
                ShadowRaidLoud:Announce(msg)
                local _tmp = ShadowRaidLoud:Run_Script("id_100964", self, 100964, element, instigator, ShadowRaidLoud.Time4Use.OpenVault)
                ShadowRaidLoud.Run_Script_Data["id_100961"] = _tmp
                ShadowRaidLoud.Run_Script_Data["id_100962"] = _tmp
            end
        end
    end

    -- Call the original function
    ShadowRaidLoud_OpenVault(self, instigator, ...)
    
    -- Clear the guard flag
    self._shadow_raid_executing = nil
end

Key improvements here:

  • Added a _shadow_raid_executing flag to block recursive hook execution
  • Added type checking for self._id to avoid tostring() on circular tables
  • Added not Global.loading to skip logic during loading (directly addresses your access violation issue)

2. Fixing the Access Violation

The access violation in the LoadingEnvironment thread happens because your code was trying to access game systems that aren't fully initialized yet during the loading phase. Calls like Network:is_client() and get_mission_element() aren't safe to run while the game is still loading—they can attempt to read uninitialized memory, causing the crash.

The not Global.loading check added above ensures your custom logic only runs when the game has finished loading, preventing these unsafe memory accesses.

Additional Best Practices

  • Use BLT's Hook API: Instead of manually overriding the function, consider using BLT's Hook:PostHook which handles calling the original function automatically and reduces recursion risk:
    Hook:PostHook(MissionScriptElement, "on_executed", "ShadowRaidLoud_OnExecuted", function(self, instigator, ...)
        -- Your custom logic here (runs after the original on_executed)
        -- No need to call the original function manually
    end)
    
  • Add debug logging: If you're still troubleshooting, add log statements to track when your code runs and what values self._id has:
    log("[ShadowRaidLoud] Executed element with _id: " .. tostring(self._id) .. " type: " .. type(self._id))
    

内容的提问来源于stack exchange,提问作者DarkCeptor44

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:56:02