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
|
-- 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
|
-- 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.
|
-- auto-hack target on its extension so the game's own validation accepts the order.
|
||||||
if not mod.omni_hack_spoof_hooked then
|
-- the owning class is discovered lazily from a LIVE extension instance (the CLASS registry
|
||||||
local spoof_class, spoof_class_name
|
-- scan at load time found nothing - extension classes aren't in it yet at that point).
|
||||||
for name, cls in pairs(CLASS) do
|
local function ensure_automark_spoof_hook()
|
||||||
if type(cls) == "table" and rawget(cls, "_contextual_tag_template_name") ~= nil then
|
if mod.omni_hack_spoof_hooked then
|
||||||
spoof_class, spoof_class_name = cls, name
|
return
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if spoof_class then
|
local smart_tag_system = context.smart_tag_system
|
||||||
mod.omni_hack_spoof_hooked = true
|
local unit_extension_data = smart_tag_system and smart_tag_system._unit_extension_data
|
||||||
mod.omni_hack_spoof_class = spoof_class_name
|
local _, any_ext = unit_extension_data and next(unit_extension_data)
|
||||||
mod:hook(spoof_class, "_contextual_tag_template_name", function(previous_hook, self, player_unit, tag_name)
|
if not any_ext then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
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
|
if tag_name == "companion_order" and self._automark_hack_order then
|
||||||
return HACK_TAG_NAME
|
return HACK_TAG_NAME
|
||||||
end
|
end
|
||||||
return previous_hook(self, player_unit, tag_name)
|
return previous_hook(self, player_unit, tag_name)
|
||||||
end)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -256,6 +282,7 @@ local function find_hackable_target_unit_omni()
|
|||||||
if not smart_tag_system or not player_unit then
|
if not smart_tag_system or not player_unit then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
ensure_automark_spoof_hook()
|
||||||
|
|
||||||
local player_position = Unit_world_position(player_unit, 1)
|
local player_position = Unit_world_position(player_unit, 1)
|
||||||
local selected_unit, selected_distance, selected_name, selected_extension
|
local selected_unit, selected_distance, selected_name, selected_extension
|
||||||
|
|||||||
Reference in New Issue
Block a user