Files
GaCy-GO/tools/cw_teabreak_runtime.lua
2026-10-28 18:54:43 +07:00

119 lines
5.2 KiB
Lua

-- Read-only, bounded Tea Break investigation. Keep outside scripts/ until an
-- operator deliberately stages it. Does not send packets or change UI/state.
do local function capture()
local state=_G.__gacCwTeaBreakRuntime2
if not state then
state={step=1,index=0,beats=0};_G.__gacCwTeaBreakRuntime2=state
end
if state.done then return end
state.beats=state.beats+1
local function log(s)CS.UnityEngine.Debug.Log('[GAC_CW_TEA_RUNTIME2] '..tostring(s))end
if state.beats>36 then state.done=true;log('END beat budget');return end
local flags=CS.System.Enum.ToObject(typeof(CS.System.Reflection.BindingFlags),60)
local gm=CS.RPG.Client.GlobalVars.s_GamePhaseManager
local current=gm and gm:GetType():GetField('_CurrentPhase',flags)
local phase=current and current:GetValue(gm)
if not phase then log('WAIT game phase');return end
if typeof(CS.RPG.Client.BattleGamePhase):IsInstanceOfType(phase)then return end
if state.step==1 then
local t=typeof(CS.RPG.Client.GridFightModule)
local p=t:GetProperty('Instance',flags)
if p then local ok,obj=pcall(function()return p:GetValue(nil,nil)end);if ok then state.module=obj end end
if not state.module then
local manager=CS.RPG.Client.GlobalVars.s_ModuleManager
if manager then local ok,obj=pcall(function()return manager.GridFightModule end);if ok then state.module=obj end end
end
log('MODULE '..tostring(state.module and state.module:GetType().FullName))
state.session=state.module and state.module.CurGameSession
local sf=state.session and state.session:GetType():GetField('_GameEventData',flags)
state.event=sf and sf:GetValue(state.session)
log('EVENT_TYPE '..tostring(state.event and state.event:GetType().FullName))
local stage=state.session and state.session.Stage
local node=stage and stage.CurNode
if node then
log('NODE route='..tostring(stage.RouteID)..' chapter='..tostring(stage.ChapterID)..' section='..tostring(stage.SectionID)..' bonfire='..tostring(node.IsBonfireNode))
local ids=node.BonfireEventIds
if ids then
if ids.Count>16 then error('bonfire event bound')end
for i=0,ids.Count-1 do log('BONFIRE_EVENT '..tostring(ids[i]))end
end
local nf=node:GetType():GetField('_NodeParam',flags)
local param=nf and nf:GetValue(node)
if param then
local raw=CS.Newtonsoft.Json.JsonConvert.SerializeObject(param)
if #raw>16384 then error('node parameter bound')end
log('NODE_PARAM '..raw)
end
end
state.types={t.Assembly:GetType('RPG.Client.GridFightGameEventData'),t.Assembly:GetType('RPG.Client.GridFightStageNode')}
state.typeindex=1;state.step=2;return
end
if state.step==2 then
local t=state.types[state.typeindex]
if not t then state.typeindex=state.typeindex+1;if state.typeindex>2 then state.step=3 end;return end
if not state.methods then
log('TYPE '..t.FullName)
if state.typeindex==2 then
for _,name in ipairs({'_RefreshBonfireEventIds','get_IsBonfireNode','get_BonfireEventIds'})do
local m=t:GetMethod(name,flags)
if m then log('METHOD '..tostring(m)..' HANDLE '..tostring(m.MethodHandle.Value))end
end
state.step=3;return
end
state.methods=t:GetMethods(flags);state.fields=t:GetFields(flags);state.index=0
end
for i=state.index,math.min(state.index+7,state.methods.Length-1)do
local m=state.methods[i]
if m.DeclaringType==t then
local n=m.Name:lower()
if state.typeindex==1 or n:find('bonfire')then log('METHOD '..tostring(m)..' HANDLE '..tostring(m.MethodHandle.Value))end
end
end
state.index=state.index+8
if state.index>=state.methods.Length then state.step=4;state.index=0 end
return
end
if state.step==4 then
local t=state.types[state.typeindex]
for i=state.index,math.min(state.index+7,state.fields.Length-1)do
local f=state.fields[i]
if f.DeclaringType==t and not f.IsStatic then
log('FIELD '..tostring(f))
if state.typeindex==1 and state.event then
local v=f:GetValue(state.event)
if v==nil then log('VALUE '..f.Name..'=nil')
elseif f.FieldType.IsPrimitive or f.FieldType.IsEnum or f.FieldType.FullName=='System.String' then log('VALUE '..f.Name..'='..tostring(v))
else log('VALUE_TYPE '..f.Name..' '..v:GetType().FullName)end
end
end
end
state.index=state.index+8
if state.index>=state.fields.Length then
state.typeindex=state.typeindex+1;state.methods=nil;state.fields=nil;state.index=0
state.step=state.typeindex>2 and 3 or 2
end
return
end
if state.step==3 then
local page=CS.RPG.Client.GlobalVars.s_UIManager:GetPageByName('GridFightPreparationPage')
local obj=page and page.LuaTable
if type(obj)=='table'then
local names={'_on_start_battle_click','_enter_battle','_check_enter_battle_by_reason'}
for _,name in ipairs(names)do
local fn=obj[name]
if type(fn)=='function'then
log('LUA_FUNCTION '..name)
for i=1,24 do
local key,val=debug.getupvalue(fn,i);if not key then break end
log('LUA_UPVALUE '..name..' '..i..' '..key..' '..type(val))
end
end
end
else log('NO preparation page')end
state.done=true;state.module=nil;state.session=nil;state.event=nil;log('END')
end
end
local ok,e=pcall(capture)
if not ok then _G.__gacCwTeaBreakRuntime2={done=true};CS.UnityEngine.Debug.Log('[GAC_CW_TEA_RUNTIME2] ERROR '..tostring(e))end
end