@@ -20,6 +20,8 @@ You should have received a copy of the license along with this
2020using System . Text ;
2121using System . Threading ;
2222using System . Threading . Tasks ;
23+ using System . Windows ;
24+ using System . Windows . Forms ;
2325using System . Windows . Media ;
2426using Clio . Utilities ;
2527using ff14bot ;
@@ -34,6 +36,8 @@ You should have received a copy of the license along with this
3436using LlamaLibrary . RemoteAgents ;
3537using LlamaLibrary . Settings ;
3638using Newtonsoft . Json ;
39+ using LogLevel = LlamaLibrary . Logging . LogLevel ;
40+ using MessageBox = System . Windows . MessageBox ;
3741using PatchManager = LlamaLibrary . Hooks . PatchManager ;
3842
3943// ReSharper disable InconsistentNaming
@@ -86,7 +90,13 @@ private static int GameVersion
8690
8791 private static string OffsetFile { get ; } = Path . Combine ( JsonSettings . SettingsPath , $ "LL_Offsets_{ GameVersion } .json") ;
8892
89- public static LLogger Logger { get ; } = new ( "LLOffsetManager" , Colors . RosyBrown ) ;
93+ private static string VtableFile = Path . Combine ( JsonSettings . SettingsPath , $ "Vtables_{ ActiveRegion } _{ Core . CurrentGameVer } .json") ;
94+
95+ private static bool VtableFileExists => File . Exists ( VtableFile ) ;
96+
97+ private static Dictionary < IntPtr , int > VtableMap = new Dictionary < IntPtr , int > ( ) ;
98+
99+ public static LLogger Logger { get ; } = new ( "LLOffsetManager" , Colors . RosyBrown , LogLevel . Debug ) ;
90100
91101 /// <summary>
92102 /// Active record for the current game region.
@@ -305,6 +315,31 @@ private static List<Type> GetTypes(Assembly assembly)
305315
306316 internal static void SetPostOffsets ( )
307317 {
318+ if ( ! VtableFileExists )
319+ {
320+ if ( GeneralFunctions . DalamudDetected ( ) )
321+ {
322+ Logger . Error ( "Dalamud detected, Run RB once per patch without Dalamud enabled to generate vtable file." ) ;
323+ if ( DataManager . CurrentLanguage == Language . Chn )
324+ {
325+ MessageBox . Show ( "检测到Dalamud,请在没有Dalamud的情况下运行RB一次以生成vtable文件。" , "错误" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
326+ }
327+ else
328+ {
329+ MessageBox . Show ( "Dalamud detected, Run RB once per patch without Dalamud to generate vtable file." , "Error" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
330+ }
331+ }
332+ else
333+ {
334+ Logger . Information ( "Generating vtable file..." ) ;
335+ GenerateVtableFile ( ) ;
336+ Logger . Information ( "Done generating vtable file." ) ;
337+ }
338+ }
339+
340+ LoadVtableFile ( ) ;
341+
342+
308343 var newStopwatch = Stopwatch . StartNew ( ) ;
309344 var vtables = new Dictionary < IntPtr , int > ( ) ;
310345 var pointers = AgentModule . AgentVtables ;
@@ -343,7 +378,16 @@ internal static void SetPostOffsets()
343378 }
344379 else
345380 {
346- Logger . Error ( $ "\t Found one { myType . Name } { test : X} but no agent") ;
381+ var relative = Core . Memory . GetRelative ( test ) ;
382+ if ( VtableMap . TryGetValue ( relative , out var id ) )
383+ {
384+ names . Add ( myType . Name ) ;
385+ Logger . Debug ( $ "\t Trying to add { myType . Name } { AgentModule . TryAddAgent ( id , myType ) } ") ;
386+ continue ;
387+ }
388+
389+
390+ Logger . Error ( $ "\t Found one { myType . Name } { test : X} ({ Core . Memory . GetRelative ( test ) : X} ) but no agent") ;
347391 }
348392 }
349393
@@ -425,7 +469,15 @@ public static void RegisterAgent(IAgent iagent)
425469 }
426470 else
427471 {
428- Logger . Error ( $ "\t Found one { iagent . RegisteredVtable : X} but no agent") ;
472+ var relative = Core . Memory . GetRelative ( iagent . RegisteredVtable ) ;
473+ if ( VtableMap . TryGetValue ( relative , out var id ) )
474+ {
475+ Logger . Information ( $ "\t Trying to add { iagent . GetType ( ) } { AgentModule . TryAddAgent ( id , iagent . GetType ( ) ) } ") ;
476+ return ;
477+ }
478+
479+
480+ Logger . Error ( $ "\t Found one { iagent . GetType ( ) . Name } { iagent . RegisteredVtable : X} ({ Core . Memory . GetRelative ( iagent . RegisteredVtable ) : X} ) but no agent") ;
429481 }
430482 }
431483
@@ -716,6 +768,12 @@ public static void SetOffsetClassesAndAgents()
716768 }
717769 else
718770 {
771+ var relative = Core . Memory . GetRelative ( test ) ;
772+ if ( VtableMap . TryGetValue ( relative , out var id ) )
773+ {
774+ Logger . WriteLog ( Colors . BlueViolet , $ "\t Trying to add { MyType . Name } { AgentModule . TryAddAgent ( id , MyType ) } ") ;
775+ continue ;
776+ }
719777 Logger . WriteLog ( Colors . BlueViolet , $ "\t Found one { MyType . Name } { test : X} but no agent") ;
720778 }
721779 }
@@ -861,4 +919,58 @@ public static Dictionary<string, string> LLDict(Assembly assembly, ClientRegion
861919
862920 return results ;
863921 }
864- }
922+
923+ //Generate vtable file
924+ public static void GenerateVtableFile ( )
925+ {
926+ if ( GeneralFunctions . DalamudDetected ( ) )
927+ {
928+ Logger . Error ( "Dalamud detected, Run RB once without Dalamud to generate vtable file." ) ;
929+ if ( DataManager . CurrentLanguage == Language . Chn )
930+ {
931+ MessageBox . Show ( "检测到Dalamud,请在没有Dalamud的情况下运行RB一次以生成vtable文件。" , "错误" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
932+ }
933+ else
934+ {
935+ MessageBox . Show ( "Dalamud detected, Run RB once without Dalamud to generate vtable file." , "Error" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
936+ }
937+
938+ return ;
939+ }
940+
941+ Dictionary < long , int > vtableDict = new ( ) ;
942+ foreach ( var agentVtable in ff14bot . Managers . AgentModule . AgentVtables )
943+ {
944+ var id = ff14bot . Managers . AgentModule . FindAgentIdByVtable ( agentVtable ) ;
945+ var offset = Core . Memory . GetRelative ( agentVtable ) ;
946+ vtableDict . TryAdd ( offset . ToInt64 ( ) , id ) ;
947+ }
948+
949+ System . IO . File . WriteAllText ( VtableFile , Newtonsoft . Json . JsonConvert . SerializeObject ( vtableDict ) ) ;
950+ }
951+
952+ //Load vtable file
953+ public static void LoadVtableFile ( )
954+ {
955+ if ( ! VtableFileExists )
956+ {
957+ Logger . Error ( "Vtable file does not exist, please generate it first." ) ;
958+ return ;
959+ }
960+
961+ if ( VtableMap . Count != 0 )
962+ {
963+
964+ return ;
965+ }
966+
967+ var fileContent = System . IO . File . ReadAllText ( VtableFile ) ;
968+ var mapTemp = Newtonsoft . Json . JsonConvert . DeserializeObject < Dictionary < long , int > > ( fileContent ) ?? new Dictionary < long , int > ( ) ;
969+ foreach ( var kvp in mapTemp )
970+ {
971+ VtableMap . Add ( new IntPtr ( kvp . Key ) , kvp . Value ) ;
972+ }
973+
974+ Logger . Information ( $ "Loaded { VtableMap . Count } vtables from file.") ;
975+ }
976+ }
0 commit comments