fix: install spoof hook lazily from a live extension instance (getmetatable/__index) — CLASS-registry scan at mod load found nothing because extension classes register later; failure path now dumps class keys for next diagnosis
This commit is contained in:
@@ -32,23 +32,49 @@ local CANCEL_INTERVAL = 0.5
|
||||
-- set_tag() for off-LOS units is silently rejected because the game re-validates the tag
|
||||
-- through the target extension's forward-LOS _contextual_tag_template_name(); flag the single
|
||||
-- auto-hack target on its extension so the game's own validation accepts the order.
|
||||
if not mod.omni_hack_spoof_hooked then
|
||||
local spoof_class, spoof_class_name
|
||||
for name, cls in pairs(CLASS) do
|
||||
if type(cls) == "table" and rawget(cls, "_contextual_tag_template_name") ~= nil then
|
||||
spoof_class, spoof_class_name = cls, name
|
||||
break
|
||||
-- the owning class is discovered lazily from a LIVE extension instance (the CLASS registry
|
||||
-- scan at load time found nothing - extension classes aren't in it yet at that point).
|
||||
local function ensure_automark_spoof_hook()
|
||||
if mod.omni_hack_spoof_hooked then
|
||||
return
|
||||
end
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
local unit_extension_data = smart_tag_system and smart_tag_system._unit_extension_data
|
||||
local _, any_ext = unit_extension_data and next(unit_extension_data)
|
||||
if not any_ext then
|
||||
return
|
||||
end
|
||||
if spoof_class then
|
||||
mod.omni_hack_spoof_hooked = true
|
||||
mod.omni_hack_spoof_class = spoof_class_name
|
||||
mod:hook(spoof_class, "_contextual_tag_template_name", function(previous_hook, self, player_unit, tag_name)
|
||||
local mt = getmetatable(any_ext)
|
||||
local cls = mt
|
||||
if cls and type(cls) == "table" and cls._contextual_tag_template_name == nil then
|
||||
cls = rawget(cls, "__index")
|
||||
end
|
||||
if type(cls) == "table" and cls._contextual_tag_template_name ~= nil then
|
||||
mod:hook(cls, "_contextual_tag_template_name", function(previous_hook, self, player_unit, tag_name)
|
||||
if tag_name == "companion_order" and self._automark_hack_order then
|
||||
return HACK_TAG_NAME
|
||||
end
|
||||
return previous_hook(self, player_unit, tag_name)
|
||||
end)
|
||||
mod.omni_hack_spoof_hooked = true
|
||||
mod.omni_hack_spoof_class = "lazy_class"
|
||||
if mod_settings.debug_mode then
|
||||
mod:diag("OMNI-HACK-DIAG spoof hook INSTALLED")
|
||||
end
|
||||
elseif mod_settings.debug_mode and not mod.omni_hack_spoof_fail_logged then
|
||||
mod.omni_hack_spoof_fail_logged = true
|
||||
local method_keys = {}
|
||||
if type(cls) == "table" then
|
||||
local seen = 0
|
||||
for k, v in pairs(cls) do
|
||||
if type(k) == "string" and seen < 40 then
|
||||
method_keys[#method_keys + 1] = k .. ":" .. type(v)
|
||||
seen = seen + 1
|
||||
end
|
||||
end
|
||||
table.sort(method_keys)
|
||||
end
|
||||
mod:diag("OMNI-HACK-DIAG spoof HOOK FAILED mt=", tostring(mt), " cls=", tostring(cls), " instance_has_method=", tostring(any_ext._contextual_tag_template_name ~= nil), " cls_keys=", table.concat(method_keys, ","))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -256,6 +282,7 @@ local function find_hackable_target_unit_omni()
|
||||
if not smart_tag_system or not player_unit then
|
||||
return
|
||||
end
|
||||
ensure_automark_spoof_hook()
|
||||
|
||||
local player_position = Unit_world_position(player_unit, 1)
|
||||
local selected_unit, selected_distance, selected_name, selected_extension
|
||||
|
||||
Reference in New Issue
Block a user