/// <summary> /// Replaces a method with another one /// </summary> /// <param name="sourceType">Original type</param> /// <param name="sourceMethod">Original method name</param> /// <param name="destinationType">New type</param> /// <param name="destinationMethod">New method name</param> void ReplaceMethod(Type sourceType, string sourceMethod, BindingFlags sourceBinding, Type destinationType, string destinationMethod, BindingFlags?destinationBinding = null, Type[] types = null) { ParameterInfo[] sourceParameters; ParameterInfo[] destinationParameters; MethodInfo methodtoreplace = null; if (types == null) { methodtoreplace = sourceType.GetMethod(sourceMethod, sourceBinding); } else { methodtoreplace = sourceType.GetMethod(sourceMethod, types); } var methodtoinject = destinationType.GetMethod(destinationMethod, destinationBinding ?? sourceBinding); MyDebug.AssertRelease(methodtoreplace != null); if (methodtoreplace != null && methodtoinject != null) { sourceParameters = methodtoreplace.GetParameters(); destinationParameters = methodtoinject.GetParameters(); MyDebug.AssertDebug(sourceParameters.Length == destinationParameters.Length); bool valid = true; // Verify signatures for (var x = 0; x < Math.Min(destinationParameters.Length, sourceParameters.Length); x++) { MyDebug.AssertDebug(destinationParameters[x].ParameterType == sourceParameters[x].ParameterType); if (destinationParameters[x].ParameterType != sourceParameters[x].ParameterType) { valid = false; } } if (sourceParameters.Length != destinationParameters.Length || !valid) { methodtoreplace = null; } } if (methodtoreplace != null && methodtoinject != null) { MethodUtil.ReplaceMethod(methodtoreplace, methodtoinject); } else { MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, sourceMethod)); } }
public static bool ReplaceMethod(MethodInfo methodtoreplace, MethodInfo methodtoinject, Type[] types = null) { ParameterInfo[] sourceParameters; ParameterInfo[] destinationParameters; MyDebug.AssertRelease(methodtoreplace != null); if (methodtoreplace != null && methodtoinject != null) { sourceParameters = methodtoreplace.GetParameters(); destinationParameters = methodtoinject.GetParameters(); MyDebug.AssertDebug(sourceParameters.Length == destinationParameters.Length); bool valid = true; // Verify signatures for (var x = 0; x < Math.Min(destinationParameters.Length, sourceParameters.Length); x++) { MyDebug.AssertDebug(destinationParameters[x].ParameterType == sourceParameters[x].ParameterType); if (destinationParameters[x].ParameterType != sourceParameters[x].ParameterType) { valid = false; } } if (sourceParameters.Length != destinationParameters.Length || !valid) { methodtoreplace = null; } } if (methodtoreplace != null && methodtoinject != null) { MethodUtil.ReplaceMethod(methodtoreplace, methodtoinject); return(true); } else { return(false); } }
private void SetupReflection() { if (m_compile && m_type == WorkshopType.Mod) { #if SE if (_scriptManager == null) { _scriptManager = new MyScriptManager(); } #else if (_scriptManager == null) { _scriptManager = new MyModManager(); } #endif if (_compileMethod == null) { var compileMethod = _scriptManager.GetType().GetMethod("LoadScripts", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null #if SE , new[] { typeof(string), typeof(MyModContext) } #else , new[] { typeof(MyModContext) } #endif , null); MyDebug.AssertDebug(compileMethod != null); if (compileMethod != null) { _compileMethod = Delegate.CreateDelegate(typeof(LoadScripts), _scriptManager, compileMethod, false) as LoadScripts; } if (_compileMethod == null) { MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, "LoadScripts")); } } } var publishMethod = typeof(MyWorkshop).GetMethod("PublishItemBlocking", BindingFlags.Static | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(string), typeof(string), typeof(string), m_modId.GetType(), typeof(MyPublishedFileVisibility), typeof(string[]), typeof(HashSet <string>), typeof(HashSet <string>), #if SE typeof(uint[]), typeof(MyWorkshopItem[]).MakeByRefType() #endif }, null); MyDebug.AssertDebug(publishMethod != null); if (publishMethod != null) { _publishMethod = Delegate.CreateDelegate(typeof(PublishItemBlocking), publishMethod, false) as PublishItemBlocking; } if (_publishMethod == null) { MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, "PublishItemBlocking")); } if (_globalIgnoredExtensions == null) { _globalIgnoredExtensions = (HashSet <string>) typeof(MyWorkshop).GetField("m_ignoredExecutableExtensions", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); } if (_previewFileNames == null) { _previewFileNames = (string[])typeof(MyWorkshop).GetField("m_previewFileNames", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); } if (_previewFileNames == null) { _previewFileNames = new string[] { "thumb.png", "thumb.jpg" } } ; #if !SE try { if (__refget_m_publishSuccess == null) { __refget_m_publishSuccess = MethodUtil.create_refgetter <MyWorkshop, bool>("m_publishSuccess", BindingFlags.NonPublic | BindingFlags.Static); } } catch (Exception ex) { MySandboxGame.Log.WriteLineAndConsole(string.Format(Constants.ERROR_Reflection, "m_publishSuccess")); MySandboxGame.Log.WriteLine(ex.Message); } #endif }