11using System ;
2- using System . Collections ;
32using System . IO ;
43using System . Linq ;
54using System . Reflection ;
1110using HarmonyLib ;
1211using MelonLoader ;
1312using UIExpansionKit . API ;
14- using UnhollowerBaseLib ;
1513using UnhollowerRuntimeLib ;
1614using UnityEngine ;
1715using UnityEngine . Networking ;
2018using ImageDownloaderClosure = ImageDownloader . __c__DisplayClass11_0 ;
2119using Object = UnityEngine . Object ;
2220
23- [ assembly: MelonInfo ( typeof ( FavCatMod ) , "FavCat Unchained " , "1.1.15~unchained " , "knah & xAstroBoy " , "https://github.com/xAstroBoy /VRCMods-Unchained " ) ]
21+ [ assembly: MelonInfo ( typeof ( FavCatMod ) , "FavCat" , "1.1.16 " , "knah" , "https://github.com/knah /VRCMods" ) ]
2422[ assembly: MelonGame ( "VRChat" , "VRChat" ) ]
2523
2624namespace FavCat
@@ -35,32 +33,11 @@ internal partial class FavCatMod : MelonMod
3533 internal PlayersModule ? PlayerModule ;
3634
3735 internal static PageUserInfo PageUserInfo ;
38- private static readonly Func < VRCUiManager > ourGetUiManager ;
39-
40- static FavCatMod ( )
41- {
42- ourGetUiManager = ( Func < VRCUiManager > ) Delegate . CreateDelegate ( typeof ( Func < VRCUiManager > ) , typeof ( VRCUiManager )
43- . GetProperties ( BindingFlags . Static | BindingFlags . Public | BindingFlags . DeclaredOnly )
44- . First ( it => it . PropertyType == typeof ( VRCUiManager ) ) . GetMethod ) ;
45- }
46-
47- internal static VRCUiManager GetUiManager ( ) => ourGetUiManager ( ) ;
48-
49- private static void DoAfterUiManagerInit ( Action code )
50- {
51- MelonCoroutines . Start ( OnUiManagerInitCoro ( code ) ) ;
52- }
53-
54- private static IEnumerator OnUiManagerInitCoro ( Action code )
55- {
56- while ( GetUiManager ( ) == null )
57- yield return null ;
58- code ( ) ;
59- }
60-
36+
6137 public override void OnApplicationStart ( )
6238 {
6339 Instance = this ;
40+ if ( ! CheckWasSuccessful || ! MustStayTrue || MustStayFalse ) return ;
6441
6542 Directory . CreateDirectory ( "./UserData/FavCatImport" ) ;
6643
@@ -164,6 +141,7 @@ public class ApiSnifferPatch
164141 private delegate void ImageDownloaderOnDoneDelegate ( IntPtr thisPtr , IntPtr asyncOperationPtr , IntPtr methodInfo ) ;
165142
166143 private static ApiPopulateDelegate ourOriginalApiPopulate = ( _ , _ , _ , _ ) => 0 ;
144+ private static ApiPopulateDelegate ourOriginalApiPopulateTokens = ( _ , _ , _ , _ ) => 0 ;
167145 private static ImageDownloaderOnDoneDelegate ourOriginalOnDone = ( _ , _ , _ ) => { } ;
168146
169147 private static readonly Type ImageDownloaderClosureType ;
@@ -183,24 +161,18 @@ static ApiSnifferPatch()
183161
184162 public static void DoPatch ( )
185163 {
186- unsafe
187- {
188- var originalMethodPointer = * ( IntPtr * ) ( IntPtr ) UnhollowerUtils
189- . GetIl2CppMethodInfoPointerFieldForGeneratedMethod (
190- typeof ( ApiModel ) . GetMethods ( ) . Single ( it =>
191- it . Name == nameof ( ApiModel . SetApiFieldsFromJson ) && it . GetParameters ( ) . Length == 2 && it . GetParameters ( ) [ 0 ] . ParameterType . GenericTypeArguments [ 1 ] == typeof ( Il2CppSystem . Object ) ) )
192- . GetValue ( null ) ;
193- MelonUtils. NativeHookAttach ( ( IntPtr ) ( & originalMethodPointer ) , typeof ( ApiSnifferPatch ) . GetMethod ( nameof ( ApiSnifferStatic ) ) ! . MethodHandle . GetFunctionPointer ( ) ) ;
194- ourOriginalApiPopulate = Marshal . GetDelegateForFunctionPointer < ApiPopulateDelegate > ( originalMethodPointer ) ;
195- }
196-
197- unsafe
198- {
199- var originalMethodPointer = * ( IntPtr * ) ( IntPtr ) UnhollowerUtils . GetIl2CppMethodInfoPointerFieldForGeneratedMethod ( ImageDownloaderClosureType . GetMethod ( nameof ( ImageDownloaderClosure . _DownloadImageInternal_b__0 ) ) ) . GetValue ( null ) ;
200- MelonUtils. NativeHookAttach ( ( IntPtr ) ( & originalMethodPointer ) , typeof ( ApiSnifferPatch ) . GetMethod ( nameof ( ImageSnifferPatch ) ) ! . MethodHandle . GetFunctionPointer ( ) ) ;
201- ourOriginalOnDone = Marshal . GetDelegateForFunctionPointer < ImageDownloaderOnDoneDelegate > ( originalMethodPointer ) ;
202- }
164+ NativePatchUtils . NativePatch ( typeof ( ApiModel ) . GetMethods ( ) . Single ( it =>
165+ it . Name == nameof ( ApiModel . SetApiFieldsFromJson ) && it . GetParameters ( ) . Length == 2 && it . GetParameters ( ) [ 0 ] . ParameterType . GenericTypeArguments [ 1 ] == typeof ( Il2CppSystem . Object ) ) ,
166+ out ourOriginalApiPopulate , ApiSnifferStatic ) ;
167+
168+ NativePatchUtils . NativePatch ( typeof ( ApiModel ) . GetMethods ( ) . Single ( it =>
169+ it . Name == nameof ( ApiModel . SetApiFieldsFromJson ) && it . GetParameters ( ) . Length == 2 && it . GetParameters ( ) [ 0 ] . ParameterType . GenericTypeArguments [ 1 ] != typeof ( Il2CppSystem . Object ) ) ,
170+ out ourOriginalApiPopulateTokens , ApiSnifferStaticTokens ) ;
171+
172+ NativePatchUtils . NativePatch ( ImageDownloaderClosureType . GetMethod ( nameof ( ImageDownloaderClosure
173+ . _DownloadImageInternal_b__0 ) ) ! , out ourOriginalOnDone , ImageSnifferPatch ) ;
203174 }
175+
204176 private static readonly object [ ] EmptyObjectArray = new object [ 0 ] ;
205177
206178 public static void ImageSnifferPatch ( IntPtr instancePtr , IntPtr asyncOperationPtr , IntPtr methodInfo )
@@ -238,10 +210,26 @@ public static byte ApiSnifferStatic(IntPtr @this, IntPtr dictionary, IntPtr some
238210 {
239211 var result = ourOriginalApiPopulate ( @this , dictionary , someRef , methodInfo ) ;
240212
213+ ApiSnifferBody ( @this ) ;
214+
215+ return result ;
216+ }
217+
218+ public static byte ApiSnifferStaticTokens ( IntPtr @this , IntPtr dictionary , IntPtr someRef , IntPtr methodInfo )
219+ {
220+ var result = ourOriginalApiPopulateTokens ( @this , dictionary , someRef , methodInfo ) ;
221+
222+ ApiSnifferBody ( @this ) ;
223+
224+ return result ;
225+ }
226+
227+ private static void ApiSnifferBody ( IntPtr @this )
228+ {
241229 try
242230 {
243231 var apiModel = new ApiModel ( @this ) ;
244- if ( ! apiModel . Populated ) return result ;
232+ if ( ! apiModel . Populated ) return ;
245233
246234 var maybeUser = apiModel . TryCast < APIUser > ( ) ;
247235 if ( maybeUser != null ) FavCatMod . Database ? . UpdateStoredPlayer ( maybeUser ) ;
@@ -252,8 +240,6 @@ public static byte ApiSnifferStatic(IntPtr @this, IntPtr dictionary, IntPtr some
252240 {
253241 MelonLogger . Error ( $ "Exception in API sniffer patch: { ex } ") ;
254242 }
255-
256- return result ;
257243 }
258244 }
259245}
0 commit comments