Decompiled source of GoldbergLocalCoop v1.0.0

plugins/RoR2LocalCoop.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("RoR2LocalCoop")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RoR2LocalCoop")]
[assembly: AssemblyTitle("RoR2LocalCoop")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RoR2LocalCoop
{
	[BepInPlugin("com.splitux.ror2localcoop", "RoR2LocalCoop", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.splitux.ror2localcoop";

		public const string PluginName = "RoR2LocalCoop";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static HashSet<ulong> AllowedSteamIds;

		static Plugin()
		{
			AllowedSteamIds = new HashSet<ulong>();
			for (ulong num = 1uL; num <= 10; num++)
			{
				AllowedSteamIds.Add(76561198000000000L + num);
			}
		}

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"RoR2LocalCoop v1.0.0 loading...");
			_harmony = new Harmony("com.splitux.ror2localcoop");
			try
			{
				ApplyPatches();
				Log.LogInfo((object)"RoR2LocalCoop loaded successfully!");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to apply patches: {arg}");
			}
		}

		private void ApplyPatches()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Expected O, but got Unknown
			Type type = FindType("RoR2.Networking.ServerAuthManager");
			if (type != null)
			{
				Log.LogInfo((object)("Found ServerAuthManager: " + type.FullName));
				MethodInfo method = type.GetMethod("FindConnectionForSteamID", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					MethodInfo method2 = typeof(NetworkPatches).GetMethod("FindConnectionForSteamID_Postfix", BindingFlags.Static | BindingFlags.Public);
					_harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Patched FindConnectionForSteamID: " + method.DeclaringType.Name + "." + method.Name));
				}
				else
				{
					Log.LogWarning((object)"FindConnectionForSteamID not found in ServerAuthManager");
					ListMethods(type, "Find");
				}
			}
			else
			{
				Log.LogWarning((object)"ServerAuthManager not found");
			}
			Type type2 = FindType("RoR2.Networking.NetworkManagerSystemSteam");
			if (type2 != null)
			{
				Log.LogInfo((object)("Found NetworkManagerSystemSteam: " + type2.FullName));
				MethodInfo method3 = type2.GetMethod("OnSteamServerP2PIncomingConnection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method3 != null)
				{
					MethodInfo method4 = typeof(NetworkPatches).GetMethod("OnSteamServerP2PIncomingConnection_Postfix", BindingFlags.Static | BindingFlags.Public);
					_harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)"Patched OnSteamServerP2PIncomingConnection");
				}
				else
				{
					Log.LogWarning((object)"OnSteamServerP2PIncomingConnection not found");
				}
				MethodInfo method5 = type2.GetMethod("OnSteamClientP2PIncomingConnection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method5 != null)
				{
					MethodInfo method6 = typeof(NetworkPatches).GetMethod("OnSteamClientP2PIncomingConnection_Postfix", BindingFlags.Static | BindingFlags.Public);
					_harmony.Patch((MethodBase)method5, (HarmonyMethod)null, new HarmonyMethod(method6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)"Patched OnSteamClientP2PIncomingConnection");
				}
				MethodInfo method7 = type2.GetMethod("OnSteamServerP2PData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method7 != null)
				{
					MethodInfo method8 = typeof(NetworkPatches).GetMethod("OnSteamServerP2PData_Prefix", BindingFlags.Static | BindingFlags.Public);
					_harmony.Patch((MethodBase)method7, new HarmonyMethod(method8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)"Patched OnSteamServerP2PData");
				}
				else
				{
					Log.LogWarning((object)"OnSteamServerP2PData not found");
				}
				MethodInfo method9 = type2.GetMethod("OnP2PData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method9 != null)
				{
					MethodInfo method10 = typeof(NetworkPatches).GetMethod("OnP2PData_Prefix", BindingFlags.Static | BindingFlags.Public);
					_harmony.Patch((MethodBase)method9, new HarmonyMethod(method10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)"Patched OnP2PData");
				}
			}
			else
			{
				Log.LogWarning((object)"NetworkManagerSystemSteam not found");
			}
		}

		private void ListMethods(Type type, string filter)
		{
			Log.LogDebug((object)("Methods in " + type.Name + " containing '" + filter + "':"));
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name.Contains(filter))
				{
					string text = string.Join(", ", Array.ConvertAll(methodInfo.GetParameters(), (ParameterInfo p) => p.ParameterType.Name + " " + p.Name));
					Log.LogDebug((object)("  " + methodInfo.Name + "(" + text + ") -> " + methodInfo.ReturnType.Name));
				}
			}
		}

		public static void AllowSteamId(ulong steamId)
		{
			if (AllowedSteamIds.Add(steamId))
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)$"Allowing Steam ID: {steamId}");
				}
			}
		}

		internal static Type FindType(string typeName)
		{
			bool flag = typeName.Contains(".");
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(typeName, throwOnError: false, ignoreCase: true);
					if (type != null)
					{
						return type;
					}
					if (flag)
					{
						continue;
					}
					Type[] types = assembly.GetTypes();
					foreach (Type type2 in types)
					{
						if (type2.Name == typeName)
						{
							return type2;
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class NetworkPatches
	{
		private static HashSet<ulong> _connectionAttempted = new HashSet<ulong>();

		private static Type _platformIdType;

		private static ConstructorInfo _platformIdCtor;

		private static bool _platformIdTypeInitialized;

		private static object CreatePlatformId(ulong steamId)
		{
			if (!_platformIdTypeInitialized)
			{
				_platformIdTypeInitialized = true;
				_platformIdType = Plugin.FindType("RoR2.PlatformID");
				if (_platformIdType != null)
				{
					ConstructorInfo[] constructors = _platformIdType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (ConstructorInfo constructorInfo in constructors)
					{
						ParameterInfo[] parameters = constructorInfo.GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ulong))
						{
							_platformIdCtor = constructorInfo;
							ManualLogSource log = Plugin.Log;
							if (log != null)
							{
								log.LogInfo((object)"Found PlatformID(ulong) constructor");
							}
							break;
						}
					}
					if (_platformIdCtor == null)
					{
						ManualLogSource log2 = Plugin.Log;
						if (log2 != null)
						{
							log2.LogWarning((object)"PlatformID(ulong) constructor not found, will use field injection");
						}
					}
				}
				else
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogError((object)"Could not find RoR2.PlatformID type");
					}
				}
			}
			if (_platformIdType == null)
			{
				return null;
			}
			if (_platformIdCtor != null)
			{
				try
				{
					object result = _platformIdCtor.Invoke(new object[1] { steamId });
					ManualLogSource log4 = Plugin.Log;
					if (log4 != null)
					{
						log4.LogDebug((object)$"Created PlatformID via constructor for {steamId}");
					}
					return result;
				}
				catch (Exception ex)
				{
					ManualLogSource log5 = Plugin.Log;
					if (log5 != null)
					{
						log5.LogWarning((object)("Constructor failed: " + ex.Message + ", falling back to fields"));
					}
				}
			}
			object obj = Activator.CreateInstance(_platformIdType);
			FieldInfo field = _platformIdType.GetField("ID", BindingFlags.Instance | BindingFlags.Public);
			FieldInfo field2 = _platformIdType.GetField("ID2", BindingFlags.Instance | BindingFlags.Public);
			FieldInfo field3 = _platformIdType.GetField("stringID", BindingFlags.Instance | BindingFlags.Public);
			if (field != null)
			{
				field.SetValue(obj, steamId);
				ManualLogSource log6 = Plugin.Log;
				if (log6 != null)
				{
					log6.LogDebug((object)$"Set ID field to {steamId}");
				}
			}
			if (field2 != null)
			{
				field2.SetValue(obj, steamId);
				ManualLogSource log7 = Plugin.Log;
				if (log7 != null)
				{
					log7.LogDebug((object)$"Set ID2 field to {steamId}");
				}
			}
			if (field3 != null)
			{
				field3.SetValue(obj, string.Empty);
			}
			ManualLogSource log8 = Plugin.Log;
			if (log8 != null)
			{
				log8.LogDebug((object)$"Created PlatformID via fields for {steamId}, type is {obj?.GetType().FullName}");
			}
			return obj;
		}

		private static object GetSteamworksInstance(object networkManager)
		{
			Type type = networkManager.GetType();
			object obj = type.GetField("serverSteamworks", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(networkManager);
			if (obj != null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogDebug((object)"Got steamworks from serverSteamworks field");
				}
				return obj;
			}
			Type type2 = Plugin.FindType("Facepunch.Steamworks.Server");
			if (type2 != null)
			{
				obj = type2.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
				if (obj != null)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogDebug((object)"Got steamworks from Server.Instance");
					}
					return obj;
				}
			}
			Type type3 = Plugin.FindType("Facepunch.Steamworks.Client");
			if (type3 != null)
			{
				obj = type3.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
				if (obj != null)
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogDebug((object)"Got steamworks from Client.Instance");
					}
					return obj;
				}
			}
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogWarning((object)"Could not get any steamworks instance");
			}
			return null;
		}

		private static void CreateConnectionForSteamId(ulong steamId, object networkManager)
		{
			if (_connectionAttempted.Contains(steamId))
			{
				return;
			}
			_connectionAttempted.Add(steamId);
			try
			{
				object steamworksInstance = GetSteamworksInstance(networkManager);
				if (steamworksInstance == null)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogError((object)"Cannot create connection: no steamworks instance");
					}
					return;
				}
				object obj = CreatePlatformId(steamId);
				if (obj == null)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogError((object)"Cannot create connection: failed to create PlatformID");
					}
					return;
				}
				MethodInfo method = networkManager.GetType().GetMethod("CreateServerP2PConnectionWithPeer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogWarning((object)"CreateServerP2PConnectionWithPeer method not found");
					}
					return;
				}
				method.Invoke(networkManager, new object[2] { steamworksInstance, obj });
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)$"Created server P2P connection for {steamId}");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log5 = Plugin.Log;
				if (log5 != null)
				{
					log5.LogError((object)$"Error creating connection for {steamId}: {arg}");
				}
			}
		}

		public static void FindConnectionForSteamID_Postfix(object steamId, ref object __result)
		{
			if (__result != null)
			{
				return;
			}
			ulong num = ExtractSteamId(steamId);
			if (num == 0)
			{
				return;
			}
			Plugin.AllowSteamId(num);
			if (Plugin.AllowedSteamIds.Contains(num))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)$"FindConnectionForSteamID: No connection for allowed ID {num}");
				}
			}
		}

		public static void OnSteamServerP2PIncomingConnection_Postfix(ulong senderSteamId, ref bool __result, object __instance)
		{
			Plugin.AllowSteamId(senderSteamId);
			if (!__result && Plugin.AllowedSteamIds.Contains(senderSteamId))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Force-accepting P2P server connection from {senderSteamId}");
				}
				__result = true;
				CreateConnectionForSteamId(senderSteamId, __instance);
			}
		}

		public static void OnSteamClientP2PIncomingConnection_Postfix(ulong senderSteamId, ref bool __result, object __instance)
		{
			Plugin.AllowSteamId(senderSteamId);
			if (!__result && Plugin.AllowedSteamIds.Contains(senderSteamId))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Force-accepting P2P client connection from {senderSteamId}");
				}
				__result = true;
				CreateConnectionForSteamId(senderSteamId, __instance);
			}
		}

		public static void OnSteamServerP2PData_Prefix(ulong senderSteamId, object __instance)
		{
			Plugin.AllowSteamId(senderSteamId);
			CreateConnectionForSteamId(senderSteamId, __instance);
		}

		public static void OnP2PData_Prefix(object senderSteamId)
		{
			ulong num = ExtractSteamId(senderSteamId);
			if (num != 0)
			{
				Plugin.AllowSteamId(num);
			}
		}

		private static ulong ExtractSteamId(object steamIdObj)
		{
			if (steamIdObj == null)
			{
				return 0uL;
			}
			try
			{
				if (steamIdObj is ulong result)
				{
					return result;
				}
				Type type = steamIdObj.GetType();
				FieldInfo field = type.GetField("ID", BindingFlags.Instance | BindingFlags.Public);
				if (field != null && field.GetValue(steamIdObj) is ulong num && num != 0)
				{
					return num;
				}
				FieldInfo field2 = type.GetField("Value");
				if (field2 != null)
				{
					return (ulong)field2.GetValue(steamIdObj);
				}
				PropertyInfo property = type.GetProperty("Value");
				if (property != null)
				{
					return (ulong)property.GetValue(steamIdObj);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogDebug((object)("Could not extract Steam ID: " + ex.Message));
				}
			}
			return 0uL;
		}
	}
}