Decompiled source of SpongePEAKCore v1.0.0

plugins/com.sponge.peakcore.dll

Decompiled 8 hours 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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SpongePEAK.Core.Logging;
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("sponge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) sponge")]
[assembly: AssemblyDescription("Pure library tier: logging, config, reflection and patching helpers. Registers no BepInEx plugin.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ddcbf023fcb4c2065ad9b038910633cd4a3a93b0")]
[assembly: AssemblyProduct("SpongePEAKCore")]
[assembly: AssemblyTitle("com.sponge.peakcore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 SpongePEAK.Core.Reflection
{
	public static class ReflectionCache
	{
		private const BindingFlags AllInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags AllStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Dictionary<(Type, string), FieldInfo> Fields = new Dictionary<(Type, string), FieldInfo>();

		private static readonly Dictionary<(Type, string), PropertyInfo> Properties = new Dictionary<(Type, string), PropertyInfo>();

		private static readonly Dictionary<(Type, string), MethodInfo> Methods = new Dictionary<(Type, string), MethodInfo>();

		public static FieldInfo Field(Type type, string name)
		{
			if (type == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			(Type, string) key = (type, name);
			if (Fields.TryGetValue(key, out var value))
			{
				return value;
			}
			FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			Fields[key] = field;
			return field;
		}

		public static PropertyInfo Property(Type type, string name)
		{
			if (type == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			(Type, string) key = (type, name);
			if (Properties.TryGetValue(key, out var value))
			{
				return value;
			}
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			Properties[key] = property;
			return property;
		}

		public static MethodInfo Method(Type type, string name)
		{
			if (type == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			(Type, string) key = (type, name);
			if (Methods.TryGetValue(key, out var value))
			{
				return value;
			}
			MethodInfo methodInfo;
			try
			{
				methodInfo = type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			catch (AmbiguousMatchException)
			{
				methodInfo = null;
			}
			Methods[key] = methodInfo;
			return methodInfo;
		}

		public static T GetField<T>(object instance, string name, T fallback = default(T))
		{
			if (instance == null)
			{
				return fallback;
			}
			FieldInfo fieldInfo = Field(instance.GetType(), name);
			if (fieldInfo == null)
			{
				return fallback;
			}
			try
			{
				return (fieldInfo.GetValue(instance) is T val) ? val : fallback;
			}
			catch
			{
				return fallback;
			}
		}

		public static bool SetField(object instance, string name, object value)
		{
			if (instance == null)
			{
				return false;
			}
			FieldInfo fieldInfo = Field(instance.GetType(), name);
			if (fieldInfo == null)
			{
				return false;
			}
			try
			{
				fieldInfo.SetValue(instance, value);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public static void Clear()
		{
			Fields.Clear();
			Properties.Clear();
			Methods.Clear();
		}
	}
}
namespace SpongePEAK.Core.Patching
{
	public sealed class PatchHost : IDisposable
	{
		private readonly ModLog _log;

		private Harmony _harmony;

		public string Id { get; }

		public int FailureCount { get; private set; }

		public Harmony Harmony
		{
			get
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				//IL_001d: Expected O, but got Unknown
				Harmony obj = _harmony;
				if (obj == null)
				{
					Harmony val = new Harmony(Id);
					Harmony val2 = val;
					_harmony = val;
					obj = val2;
				}
				return obj;
			}
		}

		public PatchHost(string id, ModLog log)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("Patch host id must not be empty.", "id");
			}
			Id = id;
			_log = log;
		}

		public bool PatchAll(Assembly assembly)
		{
			if (assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}
			try
			{
				Harmony.PatchAll(assembly);
				_log?.Debug("Applied patches from " + assembly.GetName().Name + ".");
				return true;
			}
			catch (Exception ex)
			{
				FailureCount++;
				_log?.Exception("Failed to apply patches from " + assembly.GetName().Name, ex);
				return false;
			}
		}

		public bool PatchMethod(MethodBase target, MethodInfo prefix = null, MethodInfo postfix = null, MethodInfo transpiler = null, MethodInfo finalizer = null)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (target == null)
			{
				FailureCount++;
				_log?.Warning("Cannot patch a null method.");
				return false;
			}
			try
			{
				_harmony.Patch(target, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(prefix), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(postfix), (transpiler == null) ? ((HarmonyMethod)null) : new HarmonyMethod(transpiler), (finalizer == null) ? ((HarmonyMethod)null) : new HarmonyMethod(finalizer), (HarmonyMethod)null);
				_log?.Debug("Patched " + target.DeclaringType?.Name + "." + target.Name + ".");
				return true;
			}
			catch (Exception ex)
			{
				FailureCount++;
				_log?.Exception("Failed to patch " + target.DeclaringType?.Name + "." + target.Name, ex);
				return false;
			}
		}

		public bool PatchType(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			try
			{
				Harmony.CreateClassProcessor(type).Patch();
				_log?.Debug("Applied patches from " + type.Name + ".");
				return true;
			}
			catch (Exception ex)
			{
				FailureCount++;
				_log?.Exception("Failed to apply patches from " + type.Name, ex);
				return false;
			}
		}

		public void UnpatchAll()
		{
			if (_harmony == null)
			{
				return;
			}
			try
			{
				_harmony.UnpatchSelf();
				_log?.Debug("Removed all patches.");
			}
			catch (Exception ex)
			{
				_log?.Exception("Failed to unpatch", ex);
			}
		}

		public void Dispose()
		{
			UnpatchAll();
		}
	}
}
namespace SpongePEAK.Core.Logging
{
	public sealed class ModLog
	{
		private readonly string _prefix;

		private ManualLogSource _sink;

		public bool IsAttached => _sink != null;

		public ModLog(string prefix)
		{
			_prefix = (string.IsNullOrEmpty(prefix) ? "SpongePEAK" : prefix);
		}

		public void Attach(ManualLogSource sink)
		{
			_sink = sink;
		}

		public void Debug(object message)
		{
			Write((LogLevel)32, message);
		}

		public void Info(object message)
		{
			Write((LogLevel)16, message);
		}

		public void Message(object message)
		{
			Write((LogLevel)8, message);
		}

		public void Warning(object message)
		{
			Write((LogLevel)4, message);
		}

		public void Error(object message)
		{
			Write((LogLevel)2, message);
		}

		public void Fatal(object message)
		{
			Write((LogLevel)1, message);
		}

		public void Exception(string context, Exception ex)
		{
			Write((LogLevel)2, $"{context}: {ex}");
		}

		private void Write(LogLevel level, object message)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource sink = _sink;
			if (sink == null)
			{
				return;
			}
			try
			{
				sink.Log(level, (object)$"[{_prefix}] {message}");
			}
			catch
			{
			}
		}
	}
}
namespace SpongePEAK.Core.Game
{
	public static class GameState
	{
		public static Character LocalCharacter => Character.localCharacter;

		public static bool InRun => (Object)(object)Character.localCharacter != (Object)null;

		public static List<Character> AllCharacters => Character.AllCharacters ?? new List<Character>();

		public static List<Character> AllBots => Character.AllBotCharacters ?? new List<Character>();

		public static int PlayerCount
		{
			get
			{
				List<Character> allCharacters = Character.AllCharacters;
				if (allCharacters == null)
				{
					return 0;
				}
				int num = 0;
				for (int i = 0; i < allCharacters.Count; i++)
				{
					Character val = allCharacters[i];
					if ((Object)(object)val != (Object)null && !val.isBot)
					{
						num++;
					}
				}
				return num;
			}
		}

		public static List<Character> AllPlayers()
		{
			List<Character> list = new List<Character>();
			List<Character> allCharacters = Character.AllCharacters;
			if (allCharacters == null)
			{
				return list;
			}
			for (int i = 0; i < allCharacters.Count; i++)
			{
				Character val = allCharacters[i];
				if ((Object)(object)val != (Object)null && !val.isBot)
				{
					list.Add(val);
				}
			}
			return list;
		}
	}
}
namespace SpongePEAK.Core.Config
{
	public sealed class FeatureToggle
	{
		private readonly ConfigEntry<bool> _entry;

		public string Name { get; }

		public bool Enabled => _entry?.Value ?? false;

		public bool Applied { get; private set; }

		public event Action<bool> Changed
		{
			add
			{
				if (_entry != null)
				{
					_entry.SettingChanged += delegate
					{
						value(_entry.Value);
					};
				}
			}
			remove
			{
			}
		}

		public void MarkApplied(bool applied)
		{
			Applied = applied;
		}

		public FeatureToggle(ConfigFile config, string section, string name, bool defaultValue, string description)
		{
			if (config == null)
			{
				throw new ArgumentNullException("config");
			}
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentException("Feature name must not be empty.", "name");
			}
			Name = name;
			_entry = config.Bind<bool>(section, name, defaultValue, description);
		}

		public override string ToString()
		{
			return Name + "=" + (Enabled ? "on" : "off");
		}
	}
}