Decompiled source of CWAPI v1.1.0

BepInEx/plugins/HungryMuttis.CWAPI.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MyceliumNetworking;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HungryMuttis.CWAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+3140be56eeff42df12df43269919097e7e0a269f")]
[assembly: AssemblyProduct("CWAPI")]
[assembly: AssemblyTitle("HungryMuttis.CWAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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.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 CWAPI
{
	public class ConfigSection
	{
		public ConfigFile Config { get; }

		private string Name { get; }

		public ConfigSection(ConfigFile config, string name)
		{
			Config = config;
			Name = name;
			base..ctor();
		}

		public ConfigEntry<T> Bind<T>(string key, T defaultValue, ConfigDescription? configDescription = null)
		{
			return Config.Bind<T>(Name, key, defaultValue, configDescription);
		}

		public ConfigEntry<T> Bind<T>(string key, T defaultValue, string? description = null)
		{
			return Config.Bind<T>(Name, key, defaultValue, description);
		}
	}
	[ContentWarningPlugin("HungryMuttis.CWAPI", "1.1.0", false)]
	[BepInPlugin("HungryMuttis.CWAPI", "CWAPI", "1.1.0")]
	public class CWAPI : BaseUnityPlugin
	{
	}
	public interface IFeature
	{
		string FeatureName { get; }

		bool Enabled { get; }

		bool Required { get; }

		void CreateRequiredConfig(ConfigSection section);

		void CreateConfig(ConfigSection section);

		void Initialize();
	}
	public abstract class Feature<T> : IFeature where T : Feature<T>
	{
		private ManualLogSource? _logger;

		private ConfigEntry<bool>? _enabled;

		public static T Instance { get; private set; }

		public bool Enabled => _enabled?.Value ?? Required;

		internal ManualLogSource Logger => _logger ?? (_logger = new ManualLogSource(LogSource, FeatureName));

		public abstract ManualLogSource LogSource { get; }

		public virtual bool Required { get; }

		public abstract string FeatureName { get; }

		public abstract string FeatureDescription { get; }

		public Feature()
		{
			Instance = (T)this;
		}

		public void CreateRequiredConfig(ConfigSection section)
		{
			if (!Required)
			{
				_enabled = section.Bind("Enabled", defaultValue: true, "Enables feature: " + FeatureDescription);
			}
		}

		public virtual void CreateConfig(ConfigSection section)
		{
		}

		public abstract void Initialize();

		public static void Debug(object data)
		{
			Instance.Logger.LogDebug(data);
		}

		public static void Message(object data)
		{
			Instance.Logger.LogMessage(data);
		}

		public static void Info(object data)
		{
			Instance.Logger.LogInfo(data);
		}

		public static void Warning(object data)
		{
			Instance.Logger.LogWarning(data);
		}

		public static void Error(object data)
		{
			Instance.Logger.LogError(data);
		}

		public static void Fatal(object data)
		{
			Instance.Logger.LogFatal(data);
		}
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	public class FeatureAttribute : Attribute
	{
		public bool Required { get; }

		public FeatureAttribute(bool required = false)
		{
			Required = required;
			base..ctor();
		}
	}
	public class FeatureManager
	{
		private readonly List<IFeature> Features = new List<IFeature>();

		private readonly ManualLogSource Logger;

		private readonly ConfigFile Config;

		public FeatureManager(ManualLogSource logger, ConfigFile configs)
		{
			Logger = new ManualLogSource(logger, "FeatureManager");
			Config = configs;
			RegisterFeaturesFromAssembly(Assembly.GetCallingAssembly());
		}

		public void RegisterFeaturesFromAssembly(Assembly assembly)
		{
			Logger.LogDebug("Scanning for features...");
			Type baseType = typeof(Feature<>);
			assembly.GetTypes().Where(delegate(Type t)
			{
				if (!t.IsClass || t.IsAbstract || t.GetCustomAttribute<FeatureAttribute>() == null)
				{
					return false;
				}
				Type baseType2 = t.BaseType;
				while (baseType2 != null)
				{
					if (baseType2.IsGenericType && baseType2.GetGenericTypeDefinition() == baseType)
					{
						return true;
					}
					baseType2 = baseType2.BaseType;
				}
				return false;
			}).ToList()
				.ForEach(delegate(Type t)
				{
					if (Activator.CreateInstance(t) is IFeature feature)
					{
						Features.Add(feature);
						Logger.LogDebug("Discovered and registered feature: " + feature.FeatureName);
					}
				});
		}

		public bool InitializeFeatures(bool handleExceptions = false)
		{
			return Features.All(delegate(IFeature f)
			{
				try
				{
					ConfigSection section = new ConfigSection(Config, f.FeatureName);
					f.CreateRequiredConfig(section);
					f.CreateConfig(section);
					if (f.Enabled)
					{
						if (f.Required)
						{
							Logger.LogInfo("Feature '" + f.FeatureName + "' is required. Initializing...");
						}
						else
						{
							Logger.LogInfo("Feature '" + f.FeatureName + "' is enabled. Initializing...");
						}
						f.Initialize();
					}
					else
					{
						Logger.LogInfo("Feature '" + f.FeatureName + "' is disabled.");
					}
					return true;
				}
				catch (Exception arg)
				{
					Logger.LogError($"There was an error loading feature '{f.FeatureName}'. Exception: {arg}");
					if (!handleExceptions)
					{
						throw;
					}
					return false;
				}
			});
		}
	}
	public class HarmonyPatcher
	{
		private readonly Harmony harmony = new Harmony(id);

		private readonly ManualLogSource Logger = new ManualLogSource(logger, "HarmonyPatcher");

		public Type? OriginalType { get; set; }

		public Type? PatchType { get; set; }

		public HarmonyPatcher(string id, ManualLogSource logger)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown


		public bool Patch(string originalMethodName, Type[]? originalMethodParameters = null, string? prefix = null, string? postfix = null, string? transpiler = null)
		{
			if (OriginalType == null || PatchType == null)
			{
				Logger.LogError("OriginalType or PatchType is null");
				return false;
			}
			return Patch(OriginalType, originalMethodName, originalMethodParameters, (prefix == null) ? null : new(Type, string)?((PatchType, prefix)), (postfix == null) ? null : new(Type, string)?((PatchType, postfix)), (transpiler == null) ? null : new(Type, string)?((PatchType, transpiler)));
		}

		public bool Patch(Type originalType, string originalMethodName, Type[]? originalMethodParameters = null, string? prefix = null, string? postfix = null, string? transpiler = null)
		{
			if (PatchType == null)
			{
				Logger.LogError("PatchType is null");
				return false;
			}
			return Patch(originalType, originalMethodName, originalMethodParameters, (prefix == null) ? null : new(Type, string)?((PatchType, prefix)), (postfix == null) ? null : new(Type, string)?((PatchType, postfix)), (transpiler == null) ? null : new(Type, string)?((PatchType, transpiler)));
		}

		public bool Patch(string originalMethodName, Type[]? originalMethodParameters = null, (Type type, string methodName)? prefix = null, (Type type, string methodName)? postfix = null, (Type type, string methodName)? transpiler = null)
		{
			if (OriginalType == null)
			{
				Logger.LogError("OriginalType is null");
				return false;
			}
			return Patch(OriginalType, originalMethodName, originalMethodParameters, prefix, postfix, transpiler);
		}

		public bool Patch(Type originalType, string originalMethodName, Type[]? originalMethodParameters = null, (Type type, string methodName)? prefix = null, (Type type, string methodName)? postfix = null, (Type type, string methodName)? transpiler = null)
		{
			MethodInfo methodInfo = FindMethod(originalType, originalMethodName, originalMethodParameters);
			if (methodInfo == null)
			{
				return false;
			}
			HarmonyMethod val = null;
			if (prefix.HasValue)
			{
				val = GetHarmonyMethod(prefix.Value.type, prefix.Value.methodName);
				if (val == null)
				{
					return false;
				}
			}
			HarmonyMethod val2 = null;
			if (postfix.HasValue)
			{
				val2 = GetHarmonyMethod(postfix.Value.type, postfix.Value.methodName);
				if (val2 == null)
				{
					return false;
				}
			}
			HarmonyMethod val3 = null;
			if (transpiler.HasValue)
			{
				val3 = GetHarmonyMethod(transpiler.Value.type, transpiler.Value.methodName);
				if (val3 == null)
				{
					return false;
				}
			}
			return Patch(methodInfo, val, val2, val3);
		}

		public bool Patch(MethodInfo? original, HarmonyMethod? prefix = null, HarmonyMethod? postfix = null, HarmonyMethod? transpiler = null)
		{
			if (original == null)
			{
				Logger.LogError("The original method to patch cannot be null.");
				return false;
			}
			try
			{
				harmony.Patch((MethodBase)original, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null);
				return true;
			}
			catch (Exception arg)
			{
				Logger.LogError($"Failed to patch {original.DeclaringType?.Name}.{original.Name}. Exception: {arg}");
				return false;
			}
		}

		public void ChangeInfo(int depth = 1)
		{
			PatchType = new StackTrace().GetFrame(depth).GetMethod().DeclaringType;
		}

		public void ChangeInfo(Type originalType)
		{
			OriginalType = originalType;
		}

		public bool SaveInfo(string assembly = "Assembly-CSharp", string @namespace = "", bool fixName = true, int depth = 1)
		{
			PatchType = new StackTrace().GetFrame(depth).GetMethod().DeclaringType;
			string text = PatchType.Name;
			if (fixName)
			{
				int num = text.LastIndexOf("Patch");
				if (num != -1)
				{
					text = text.Remove(num, 5);
				}
			}
			if (!string.IsNullOrEmpty(@namespace))
			{
				text = (@namespace.EndsWith('.') ? @namespace : (@namespace + ".")) + text;
			}
			OriginalType = Type.GetType(text + ", " + assembly);
			return OriginalType != null;
		}

		public void SaveInfo(Type originalType, int depth = 1)
		{
			SaveInfo(originalType, new StackTrace().GetFrame(depth).GetMethod().DeclaringType);
		}

		public void SaveInfo(Type originalType, Type patchType)
		{
			OriginalType = originalType;
			PatchType = patchType;
		}

		public MethodInfo? FindMethod(Type type, string methodName, Type[]? parameters = null)
		{
			MethodInfo methodInfo = ((parameters == null) ? AccessTools.Method(type, methodName, (Type[])null, (Type[])null) : AccessTools.Method(type, methodName, parameters, (Type[])null));
			if (methodInfo == null)
			{
				Logger.LogError("Failed to find " + type.Name + "." + methodName);
			}
			return methodInfo;
		}

		public HarmonyMethod? GetHarmonyMethod(Type type, string methodName)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			MethodInfo methodInfo = FindMethod(type, methodName);
			if (!(methodInfo == null))
			{
				return new HarmonyMethod(methodInfo);
			}
			return null;
		}

		public void UnpatchAll()
		{
			harmony.UnpatchSelf();
		}
	}
	public class ManualLogSource
	{
		private ManualLogSource Logger { get; }

		public string Prefix { get; }

		internal ManualLogSource(ManualLogSource logger, string name)
		{
			Logger = logger;
			Prefix = "[" + name + "] ";
		}

		public void LogDebug(object data)
		{
			Logger.LogDebug((object)(Prefix + data));
		}

		public void LogInfo(object data)
		{
			Logger.LogInfo((object)(Prefix + data));
		}

		public void LogMessage(object data)
		{
			Logger.LogMessage((object)(Prefix + data));
		}

		public void LogWarning(object data)
		{
			Logger.LogWarning((object)(Prefix + data));
		}

		public void LogError(object data)
		{
			Logger.LogError((object)(Prefix + data));
		}

		public void LogFatal(object data)
		{
			Logger.LogFatal((object)(Prefix + data));
		}
	}
	public abstract class NetworkComponent<THandler, TParent> : MonoBehaviour where THandler : NetworkComponent<THandler, TParent> where TParent : MonoBehaviour
	{
		private ManualLogSource? _logger;

		protected abstract ManualLogSource LogSource { get; }

		protected ManualLogSource Logger => _logger ?? (_logger = new ManualLogSource(LogSource, ((object)this).GetType().Name));

		protected abstract uint MOD_ID { get; }

		protected TParent ParentComponent { get; private set; }

		protected int ViewId { get; private set; }

		protected virtual void Awake()
		{
			ParentComponent = ((Component)this).GetComponent<TParent>();
			if ((Object)(object)ParentComponent == (Object)null)
			{
				Logger.LogError("Could not find the required component of type '" + typeof(TParent).Name + "'. Destroying self");
				Object.Destroy((Object)(object)this);
				return;
			}
			PhotonView componentInParent = ((Component)this).GetComponentInParent<PhotonView>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				Logger.LogError("Could not find the required component 'PhotonView'. Destroying self");
				Object.Destroy((Object)(object)this);
			}
			else
			{
				ViewId = componentInParent.ViewID;
				MyceliumNetwork.RegisterNetworkObject((object)this, MOD_ID, ViewId);
				SuccessfulAwake();
			}
		}

		protected virtual void SuccessfulAwake()
		{
		}

		protected virtual void OnDestroy()
		{
			if (ViewId != 0)
			{
				MyceliumNetwork.DeregisterNetworkObject((object)this, MOD_ID, ViewId);
			}
		}

		protected static bool SendMasked(TParent mask, string methodName, ReliableType reliable, params object[] parameters)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			THandler component = ((Component)(object)mask).GetComponent<THandler>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)("[" + typeof(THandler).Name + "] Target '" + typeof(TParent).Name + "' does not have a handler"));
				return false;
			}
			MyceliumNetwork.RPCMasked(component.MOD_ID, methodName, reliable, component.ViewId, parameters);
			return true;
		}

		protected static bool SendTargetMasked(TParent mask, string methodName, CSteamID target, ReliableType reliable, params object[] parameters)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			THandler component = ((Component)(object)mask).GetComponent<THandler>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)("[" + typeof(THandler).Name + "] Target player does not have a handler"));
				return false;
			}
			MyceliumNetwork.RPCTargetMasked(component.MOD_ID, methodName, target, reliable, component.ViewId, parameters);
			return true;
		}

		protected static bool Send(TParent mask, string methodName, ReliableType reliable, params object[] parameters)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return SendMasked(mask, methodName, reliable, parameters);
		}

		protected static bool Send(TParent mask, string methodName, CSteamID target, ReliableType reliable, params object[] parameters)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return SendTargetMasked(mask, methodName, target, reliable, parameters);
		}
	}
	public abstract class SingletonNetworkComponent<THandler> : MonoBehaviour where THandler : SingletonNetworkComponent<THandler>
	{
		private ManualLogSource? _logger;

		protected abstract ManualLogSource LogSource { get; }

		protected ManualLogSource Logger => _logger ?? (_logger = new ManualLogSource(LogSource, ((object)this).GetType().Name));

		protected abstract uint MOD_ID { get; }

		public static SingletonNetworkComponent<THandler>? Instance { get; private set; }

		public static THandler? TypedInstance => Instance as THandler;

		protected virtual void Awake()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance != (Object)null)
			{
				Logger.LogWarning("This singleton already exists. Destroying self");
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			((Component)this).transform.SetParent((Transform)null);
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			GameObject gameObject = ((Component)this).gameObject;
			((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x34);
			Instance = this;
			MyceliumNetwork.RegisterNetworkObject((object)this, MOD_ID, 0);
			SuccessfulAwake();
		}

		protected virtual void SuccessfulAwake()
		{
		}

		protected virtual void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
				MyceliumNetwork.DeregisterNetworkObject((object)this, MOD_ID, 0);
			}
		}

		protected static bool Send(string methodName, ReliableType reliable, params object[] parameters)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			MyceliumNetwork.RPC((Instance ?? throw new InvalidOperationException("[" + typeof(THandler).Name + "] Not initialized. Cannot send")).MOD_ID, methodName, reliable, parameters);
			return true;
		}

		protected static bool SendTarget(string methodName, CSteamID target, ReliableType reliable, params object[] parameters)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			MyceliumNetwork.RPCTarget((Instance ?? throw new InvalidOperationException("[" + typeof(THandler).Name + "] Not initialized. Cannot send")).MOD_ID, methodName, target, reliable, parameters);
			return true;
		}

		protected static bool Send(string methodName, CSteamID target, ReliableType reliable, params object[] parameters)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return SendTarget(methodName, target, reliable, parameters);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HungryMuttis.CWAPI";

		public const string PLUGIN_NAME = "CWAPI";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace CWAPI.Extensions
{
	public static class PlayerExtensions
	{
		public static bool TryGetSteamID(this Player player, out CSteamID steamId)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			steamId = CSteamID.Nil;
			if (player != null)
			{
				PlayerRefs refs = player.refs;
				bool? obj;
				if (refs == null)
				{
					obj = null;
				}
				else
				{
					PhotonView view = refs.view;
					if (view == null)
					{
						obj = null;
					}
					else
					{
						Player owner = view.Owner;
						obj = ((owner == null) ? null : ((Dictionary<object, object>)(object)owner.CustomProperties)?.ContainsKey((object)"SteamID"));
					}
				}
				bool? flag = obj;
				if (flag.GetValueOrDefault())
				{
					if (!ulong.TryParse(player.refs.view.Owner.CustomProperties[(object)"SteamID"] as string, out var result))
					{
						return false;
					}
					steamId = new CSteamID(result);
					return true;
				}
			}
			return false;
		}
	}
}