using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("NoteBoxz.BetterServerRpcErrorLog")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.3.0")]
[assembly: AssemblyInformationalVersion("0.0.3+7e368df0bc7f1de3dc94dd2f6bb0dd9af1d26bce")]
[assembly: AssemblyProduct("BetterServerRpcErrorLog")]
[assembly: AssemblyTitle("NoteBoxz.BetterServerRpcErrorLog")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BetterServerRpcErrorLog
{
[BepInPlugin("NoteBoxz.BetterServerRpcErrorLog", "BetterServerRpcErrorLog", "0.0.3")]
public class BetterServerRpcErrorLog : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <PatchDynamicCoroutine>d__24 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private Task <patchingTask>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PatchDynamicCoroutine>d__24(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<patchingTask>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<patchingTask>5__1 = Task.Run(delegate
{
List<Assembly> list = AppDomain.CurrentDomain.GetAssemblies().ToList();
int count = list.Count;
int num = 0;
foreach (Assembly item in list)
{
try
{
ScanAssemblyToPatch(item);
num++;
if (num % 5 == 0 || num == count)
{
Logger.LogMessage((object)($"Patching progress: {num}/{count} assemblies processed " + $"{ServerRpcCount} ServerRpc methods patched, {RpcHandlerCount} RPC handlers patched"));
}
}
catch (Exception ex)
{
Logger.LogError((object)("Error scanning assembly " + item.FullName + ": " + ex.Message));
}
}
Logger.LogInfo((object)($"Dynamic patching complete. Processed {count} assemblies. " + $"Patched {ServerRpcCount} ServerRpc methods and {RpcHandlerCount} RPC handlers."));
});
break;
case 1:
<>1__state = -1;
break;
}
if (!<patchingTask>5__1.IsCompleted)
{
<>2__current = null;
<>1__state = 1;
return true;
}
if (<patchingTask>5__1.Exception != null)
{
Logger.LogError((object)$"Error during async patching: {<patchingTask>5__1.Exception}");
}
Object.Destroy((Object)(object)((Component)SharedCoroutineStarter.Instance).gameObject);
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static Harmony Harmony;
public static ManualLogSource Logger { get; private set; }
public static ConfigEntry<bool> LogAssemblyScanning { get; private set; }
public static ConfigEntry<bool> RemoveFirstLineOfStackTrace { get; private set; }
public static int ServerRpcCount { get; private set; }
public static int RpcHandlerCount { get; private set; }
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
Harmony = new Harmony("NoteBoxz.BetterServerRpcErrorLog");
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Active, waiting for game to start before dynamic patching...");
LogAssemblyScanning = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LogAssemblyScanning", false, "Enable/disable logging of assembly scanning progress");
RemoveFirstLineOfStackTrace = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RemoveFirstLineOfStackTrace", true, "Enable/disable removing the first line of the stack trace in the error log. This first line is usually from the mod itself and not the actual error.");
Patch();
}
public static void Patch()
{
Logger.LogDebug((object)"Patching...");
Harmony.PatchAll(Assembly.GetExecutingAssembly());
Logger.LogDebug((object)"Patching complete!");
}
public static void PatchDynamic()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
Logger.LogInfo((object)"Dynamic patching...");
ServerRpcCount = 0;
GameObject val = new GameObject("SharedCoroutineStarter");
Object.DontDestroyOnLoad((Object)(object)val);
SharedCoroutineStarter.Instance = val.AddComponent<SharedCoroutineStarter>();
((MonoBehaviour)SharedCoroutineStarter.Instance).StartCoroutine(PatchDynamicCoroutine());
}
[IteratorStateMachine(typeof(<PatchDynamicCoroutine>d__24))]
private static IEnumerator PatchDynamicCoroutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PatchDynamicCoroutine>d__24(0);
}
public static void ScanAssemblyToPatch(Assembly assembly)
{
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02cd: Expected O, but got Unknown
//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
//IL_04c1: Expected O, but got Unknown
//IL_036b: Unknown result type (might be due to invalid IL or missing references)
//IL_0379: Expected O, but got Unknown
List<MethodInfo> list = new List<MethodInfo>();
List<MethodInfo> list2 = new List<MethodInfo>();
List<string> list3 = new List<string>();
if (LogAssemblyScanning.Value)
{
Logger.LogMessage((object)("----Scanning assembly " + assembly.GetName().Name + " for patch methods----"));
}
try
{
Type[] array;
try
{
array = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
int num = ex.Types.Count((Type t) => t == null);
if (LogAssemblyScanning.Value)
{
Logger.LogWarning((object)("Some types in assembly " + assembly.GetName().Name + " couldn't be loaded: " + ex.Message));
Logger.LogWarning((object)$"Failed to load {num} types from {ex.Types.Length} total types");
}
array = ex.Types.Where((Type t) => t != null).ToArray();
}
Type[] array2 = array;
foreach (Type type in array2)
{
try
{
list.AddRange(from m in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
where m.Name.EndsWith("ServerRpc")
select m);
IEnumerable<MethodInfo> enumerable = from m in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
where m.Name.StartsWith("__rpc_handler_") && IsRpcHandlerSignatureMatch(m)
select m;
foreach (MethodInfo item in enumerable)
{
if (ContainsOwnershipCheckAndErrorLog(item))
{
list2.Add(item);
if (LogAssemblyScanning.Value)
{
Logger.LogInfo((object)("Found RPC handler with ownership check: " + GetUniqueMethodSignature(item)));
}
}
}
}
catch (Exception ex2)
{
Logger.LogError((object)("Error accessing methods for type " + type.Name + ": " + ex2.Message));
}
}
foreach (MethodInfo item2 in list)
{
try
{
string uniqueMethodSignature = GetUniqueMethodSignature(item2);
if (list3.Contains(uniqueMethodSignature))
{
if (LogAssemblyScanning.Value)
{
Logger.LogWarning((object)("Already patched " + uniqueMethodSignature + ", skipping"));
}
continue;
}
ServerRpcAttribute val = (ServerRpcAttribute)item2.GetCustomAttribute(typeof(ServerRpcAttribute));
if (val == null)
{
if (LogAssemblyScanning.Value)
{
Logger.LogWarning((object)("No ServerRpcAttribute found for " + uniqueMethodSignature + " despite ending with 'ServerRpc', skipping"));
}
continue;
}
if (!val.RequireOwnership)
{
if (LogAssemblyScanning.Value)
{
Logger.LogInfo((object)("ServerRpcAttribute found for " + uniqueMethodSignature + " but RequireOwnership is false, skipping"));
}
continue;
}
try
{
Harmony.Patch((MethodBase)item2, new HarmonyMethod(typeof(BetterServerRpcErrorLog).GetMethod("ServerRpcPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
ServerRpcCount++;
if (LogAssemblyScanning.Value)
{
Logger.LogInfo((object)("Successfully patched ServerRpc " + uniqueMethodSignature));
}
}
catch (Exception ex3)
{
Logger.LogError((object)("Failed to patch " + uniqueMethodSignature + ": " + ex3.Message));
}
list3.Add(uniqueMethodSignature);
}
catch (Exception ex4)
{
Logger.LogError((object)("Error processing patch method " + item2.Name + ": " + ex4.Message));
}
}
foreach (MethodInfo item3 in list2)
{
try
{
string uniqueMethodSignature2 = GetUniqueMethodSignature(item3);
if (list3.Contains(uniqueMethodSignature2))
{
if (LogAssemblyScanning.Value)
{
Logger.LogWarning((object)("Already patched RPC handler " + uniqueMethodSignature2 + ", skipping"));
}
continue;
}
try
{
Harmony.Patch((MethodBase)item3, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BetterServerRpcErrorLog).GetMethod("RpcHandlerTranspiler", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null);
RpcHandlerCount++;
if (LogAssemblyScanning.Value)
{
Logger.LogInfo((object)("Successfully patched RPC handler " + uniqueMethodSignature2));
}
}
catch (Exception ex5)
{
Logger.LogError((object)("Failed to patch RPC handler " + uniqueMethodSignature2 + ": " + ex5.Message));
}
list3.Add(uniqueMethodSignature2);
}
catch (Exception ex6)
{
Logger.LogError((object)("Error processing RPC handler " + item3.Name + ": " + ex6.Message));
}
}
}
catch (Exception ex7)
{
Logger.LogError((object)("Error getting types from assembly " + assembly.GetName().Name + ": " + ex7.Message));
}
}
private static bool IsRpcHandlerSignatureMatch(MethodInfo method)
{
ParameterInfo[] parameters = method.GetParameters();
return parameters.Length == 3 && parameters[0].ParameterType == typeof(NetworkBehaviour) && parameters[1].ParameterType.Name == "FastBufferReader" && parameters[2].ParameterType.Name == "__RpcParams";
}
private static bool ContainsOwnershipCheckAndErrorLog(MethodInfo method)
{
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
try
{
MethodBody methodBody = method.GetMethodBody();
if (methodBody == null)
{
return false;
}
string location = method.Module.Assembly.Location;
if (string.IsNullOrEmpty(location))
{
return false;
}
AssemblyDefinition val = AssemblyDefinition.ReadAssembly(location);
try
{
MethodDefinition val2 = FindMethodDefinition(val, method);
if (val2 == null)
{
return false;
}
Enumerator<Instruction> enumerator = val2.Body.Instructions.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
Instruction current = enumerator.Current;
if (current.OpCode == OpCodes.Ldstr && current.Operand is string text && text == "Only the owner can invoke a ServerRpc that requires ownership!")
{
return true;
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
}
finally
{
((IDisposable)val)?.Dispose();
}
return false;
}
catch (Exception ex)
{
Logger.LogError((object)("Error analyzing method " + method.Name + ": " + ex.Message));
return false;
}
}
private static MethodDefinition? FindMethodDefinition(AssemblyDefinition assembly, MethodInfo method)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Enumerator<ModuleDefinition> enumerator = assembly.Modules.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
ModuleDefinition current = enumerator.Current;
TypeDefinition type = current.GetType(method.DeclaringType.FullName);
if (type == null)
{
continue;
}
Enumerator<MethodDefinition> enumerator2 = type.Methods.GetEnumerator();
try
{
while (enumerator2.MoveNext())
{
MethodDefinition current2 = enumerator2.Current;
if (!(((MemberReference)current2).Name == method.Name) || ((MethodReference)current2).Parameters.Count != method.GetParameters().Length)
{
continue;
}
bool flag = true;
for (int i = 0; i < ((MethodReference)current2).Parameters.Count; i++)
{
if (((MemberReference)((ParameterReference)((MethodReference)current2).Parameters[i]).ParameterType).Name != method.GetParameters()[i].ParameterType.Name)
{
flag = false;
break;
}
}
if (flag)
{
return current2;
}
}
}
finally
{
((IDisposable)enumerator2).Dispose();
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
return null;
}
private static IEnumerable<CodeInstruction> RpcHandlerTranspiler(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod)
{
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Expected O, but got Unknown
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Expected O, but got Unknown
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
bool flag = false;
for (int i = 0; i < list.Count - 2; i++)
{
if (list[i].opcode == OpCodes.Ldstr && list[i].operand is string text && text == "Only the owner can invoke a ServerRpc that requires ownership!" && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand is MethodInfo methodInfo && methodInfo.Name == "LogError" && methodInfo.DeclaringType.Name == "Debug")
{
flag = true;
list.Insert(i, new CodeInstruction(OpCodes.Ldarg_0, (object)null));
list.Insert(i + 1, new CodeInstruction(OpCodes.Ldarg_2, (object)null));
list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)typeof(BetterServerRpcErrorLog).GetMethod("LogDetailedRpcHandlerError", BindingFlags.Static | BindingFlags.NonPublic)));
list[i + 3] = new CodeInstruction(OpCodes.Nop, (object)null);
list[i + 4] = new CodeInstruction(OpCodes.Nop, (object)null);
break;
}
}
if (!flag)
{
Logger.LogWarning((object)("RPC handler transpiler couldn't find the error log in " + __originalMethod.Name));
}
return list;
}
private static void LogDetailedRpcHandlerError(NetworkBehaviour target, __RpcParams rpcParams)
{
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
try
{
NetworkManager networkManager = target.NetworkManager;
if (networkManager == null)
{
return;
}
string text = Environment.StackTrace;
if (RemoveFirstLineOfStackTrace.Value)
{
string[] array = text.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<int> indicesToRemove = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i].Contains("BetterServerRpcErrorLog.LogDetailedRpcHandlerError") || array[i].Contains("RpcHandlerTranspiler"))
{
indicesToRemove.Add(i);
}
}
if (indicesToRemove.Count > 0)
{
text = string.Join(Environment.NewLine, array.Where((string line, int index) => !indicesToRemove.Contains(index)));
}
}
Logger.LogError((object)("[RPC Handler] Only the owner can invoke a ServerRpc that requires ownership!" + $"\nCalled by client {rpcParams.Server.Receive.SenderClientId}, but owner is {target.OwnerClientId}" + "\nObject: " + ((Object)target).name + " (" + ((object)target).GetType().Name + ")\n" + text));
}
catch (Exception ex)
{
Logger.LogError((object)("Error in LogDetailedRpcHandlerError: " + ex.Message));
}
}
private static void ServerRpcPrefix(MethodBase __originalMethod, NetworkBehaviour __instance)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Invalid comparison between Unknown and I4
try
{
NetworkManager networkManager = __instance.NetworkManager;
if (networkManager == null || !networkManager.IsListening || (int)__instance.__rpc_exec_stage == 1 || (!networkManager.IsClient && !networkManager.IsHost) || __instance.OwnerClientId == networkManager.LocalClientId)
{
return;
}
string empty = string.Empty;
string text = Environment.StackTrace;
if (RemoveFirstLineOfStackTrace.Value)
{
string[] array = text.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int indexToRemove = -1;
for (int i = 0; i < array.Length; i++)
{
if (array[i].Contains("BetterServerRpcErrorLog.ServerRpcPrefix") || array[i].Contains("ServerRpcPrefix"))
{
indexToRemove = i;
break;
}
}
if (indexToRemove >= 0 && array.Length > indexToRemove + 1)
{
text = string.Join(Environment.NewLine, array.Where((string line, int index) => index != indexToRemove));
}
}
Logger.LogError((object)($"stage({((object)(__RpcExecStage)(ref __instance.__rpc_exec_stage)).ToString()}) Non-owner called ServerRpc that requires ownership: {GetUniqueMethodSignature(__originalMethod)}" + $"\nCalled by client {networkManager.LocalClientId}, but owner is {__instance.OwnerClientId}\n" + text));
}
catch (Exception ex)
{
Logger.LogError((object)$"Error in ServerRpcPrefix for {GetUniqueMethodSignature(__originalMethod)}: {ex.Message}");
}
}
private static object GetUniqueMethodSignature(MethodBase method)
{
string arg = string.Join(", ", from p in method.GetParameters()
select p.ParameterType.Name);
string text = $"{method.DeclaringType}.{method.Name}({arg})";
if (method.IsGenericMethod)
{
string text2 = string.Join(", ", from t in method.GetGenericArguments()
select t.Name);
text = text + "<" + text2 + ">";
}
return text;
}
private static string GetUniqueMethodSignature(MethodInfo method)
{
string arg = string.Join(", ", from p in method.GetParameters()
select p.ParameterType.Name);
string text = $"{method.DeclaringType}.{method.Name}({arg})";
if (method.IsGenericMethod)
{
string text2 = string.Join(", ", from t in method.GetGenericArguments()
select t.Name);
text = text + "<" + text2 + ">";
}
return text;
}
}
public class SharedCoroutineStarter : MonoBehaviour
{
public static SharedCoroutineStarter Instance;
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "NoteBoxz.BetterServerRpcErrorLog";
public const string PLUGIN_NAME = "BetterServerRpcErrorLog";
public const string PLUGIN_VERSION = "0.0.3";
}
}
namespace BetterServerRpcErrorLog.Patches
{
[HarmonyPatch(typeof(InitializeGame))]
internal class InitPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void Postfix()
{
BetterServerRpcErrorLog.PatchDynamic();
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}