Decompiled source of Stop Time v0.2.3

plugins/A2.StopTime.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using A2.StopTime.Commands;
using A2.StopTime.Reflection;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Stop Time")]
[assembly: AssemblyDescription("Allows you to break the laws of the universe and stop the flow of time.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Stop Time")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7a21f3ee-a897-0940-f735-5e60a11c218f")]
[assembly: AssemblyFileVersion("0.2.3.0")]
[assembly: AssemblyVersion("0.2.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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;
		}
	}
}
internal static class PluginInfo
{
	public const string PluginGUID = "A2.StopTime";

	public const string PluginName = "Stop Time";

	public const string PluginDescription = "Allows you to break the laws of the universe and stop the flow of time.";

	public const string PluginSemanticVersion = "0.2.3";

	public const string PluginFullVersion = "0.2.3.0";
}
namespace A2.StopTime
{
	[BepInPlugin("A2.StopTime", "Stop Time", "0.2.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static EventHandler <0>__OnIsTimeStoppedChanged;

			public static CoroutineHandler <1>__ServerReceiveTimeStop;

			public static CoroutineHandler <2>__ClientReceiveTimeStop;

			public static CoroutineHandler <3>__ServerReceiveTimeResume;

			public static CoroutineHandler <4>__ClientReceiveTimeResume;
		}

		private static readonly Func<ZNet, List<ZNetPeer>> get_ZNet_m_peers = ReflectionCompiler<ZNet>.CompileFieldGetter<List<ZNetPeer>>("m_peers");

		private static readonly Func<ZNetPeer, bool> get_ZNetPeer_m_server = ReflectionCompiler<ZNetPeer>.CompileFieldGetter<bool>("m_server");

		private static readonly Func<ZNetPeer, ISocket> get_ZNetPeer_m_socket = ReflectionCompiler<ZNetPeer>.CompileFieldGetter<ISocket>("m_socket");

		private static readonly Func<ZNetPeer, ZRpc> get_ZNetPeer_m_rpc = ReflectionCompiler<ZNetPeer>.CompileFieldGetter<ZRpc>("m_rpc");

		private static readonly Harmony _harmony = new Harmony("A2.StopTime");

		private static ConfigEntry<bool>? IsTimeStopped_ConfigEntry;

		internal static bool CommandUsed = false;

		private static CustomRPC? TimeStopRPC;

		private static CustomRPC? TimeResumeRPC;

		internal static bool IsTimeStopped
		{
			get
			{
				if (IsTimeStopped_ConfigEntry == null)
				{
					return false;
				}
				return IsTimeStopped_ConfigEntry.Value;
			}
			set
			{
				if (IsTimeStopped_ConfigEntry != null)
				{
					IsTimeStopped_ConfigEntry.Value = value;
				}
			}
		}

		public void Awake()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			IsTimeStopped_ConfigEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("Stop time", "StopTime", false, new ConfigDescription("Stops the flow of time.", (AcceptableValueBase)null, new object[1] { val }));
			IsTimeStopped_ConfigEntry.SettingChanged += OnIsTimeStoppedChanged;
			NetworkManager instance = NetworkManager.Instance;
			object obj = <>O.<1>__ServerReceiveTimeStop;
			if (obj == null)
			{
				CoroutineHandler val2 = ServerReceiveTimeStop;
				<>O.<1>__ServerReceiveTimeStop = val2;
				obj = (object)val2;
			}
			object obj2 = <>O.<2>__ClientReceiveTimeStop;
			if (obj2 == null)
			{
				CoroutineHandler val3 = ClientReceiveTimeStop;
				<>O.<2>__ClientReceiveTimeStop = val3;
				obj2 = (object)val3;
			}
			TimeStopRPC = instance.AddRPC("TimeStopRPC", (CoroutineHandler)obj, (CoroutineHandler)obj2);
			NetworkManager instance2 = NetworkManager.Instance;
			object obj3 = <>O.<3>__ServerReceiveTimeResume;
			if (obj3 == null)
			{
				CoroutineHandler val4 = ServerReceiveTimeResume;
				<>O.<3>__ServerReceiveTimeResume = val4;
				obj3 = (object)val4;
			}
			object obj4 = <>O.<4>__ClientReceiveTimeResume;
			if (obj4 == null)
			{
				CoroutineHandler val5 = ClientReceiveTimeResume;
				<>O.<4>__ClientReceiveTimeResume = val5;
				obj4 = (object)val5;
			}
			TimeResumeRPC = instance2.AddRPC("TimeResumeRPC", (CoroutineHandler)obj3, (CoroutineHandler)obj4);
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new TimeStopCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new TimeResumeCommand());
			_harmony.PatchAll();
		}

		internal static void TimeStopRPCSendPackage(List<ZNetPeer> peers)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (TimeStopRPC != null)
			{
				TimeStopRPC.SendPackage(peers, new ZPackage());
			}
		}

		internal static void TimeResumeRPCSendPackage(List<ZNetPeer> peers)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (TimeResumeRPC != null)
			{
				TimeResumeRPC.SendPackage(peers, new ZPackage());
			}
		}

		private static IEnumerator ServerReceiveTimeStop(long sender, ZPackage package)
		{
			Console.instance.Print("Time stop command received from client.");
			yield return null;
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			if (!ZNet.instance.IsAdmin(get_ZNetPeer_m_socket(peer).GetHostName()))
			{
				ZNet.instance.RemotePrint(get_ZNetPeer_m_rpc(peer), "You are not admin");
			}
			else
			{
				IsTimeStopped = true;
			}
			yield return null;
		}

		private static IEnumerator ServerReceiveTimeResume(long sender, ZPackage package)
		{
			Console.instance.Print("Time resume command received from client.");
			yield return null;
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			if (!ZNet.instance.IsAdmin(get_ZNetPeer_m_socket(peer).GetHostName()))
			{
				ZNet.instance.RemotePrint(get_ZNetPeer_m_rpc(peer), "You are not admin");
			}
			else
			{
				IsTimeStopped = false;
			}
			yield return null;
		}

		private static IEnumerator ClientReceiveTimeStop(long sender, ZPackage package)
		{
			Console.instance.Print("Time stop command received from server.");
			yield return null;
			CommandUsed = true;
			IsTimeStopped = true;
			yield return null;
		}

		private static IEnumerator ClientReceiveTimeResume(long sender, ZPackage package)
		{
			Console.instance.Print("Time resume command received from server.");
			yield return null;
			CommandUsed = true;
			IsTimeStopped = false;
			yield return null;
		}

		private static void OnIsTimeStoppedChanged(object sender, EventArgs args)
		{
			if (IsTimeStopped)
			{
				Console.instance.Print("Time stopped.");
			}
			else
			{
				Console.instance.Print("Time resumed.");
			}
			if (CommandUsed)
			{
				CommandUsed = false;
			}
			else if (ZNet.instance.IsServer())
			{
				List<ZNetPeer> list = (from x in get_ZNet_m_peers(ZNet.instance)
					where !get_ZNetPeer_m_server(x)
					select x).ToList();
				if (IsTimeStopped)
				{
					Console.instance.Print($"Sending timestop command to clients. Targets: {list.Count}");
					TimeStopRPCSendPackage(list);
				}
				else
				{
					Console.instance.Print($"Sending timeresume command to clients. Targets: {list.Count}");
					TimeResumeRPCSendPackage(list);
				}
			}
			else
			{
				List<ZNetPeer> list2 = (from x in get_ZNet_m_peers(ZNet.instance)
					where get_ZNetPeer_m_server(x)
					select x).ToList();
				if (IsTimeStopped)
				{
					Console.instance.Print($"Sending timestop command to server. Targets: {list2.Count}");
					TimeStopRPCSendPackage(list2);
				}
				else
				{
					Console.instance.Print($"Sending timeresume command to server. Targets: {list2.Count}");
					TimeResumeRPCSendPackage(list2);
				}
			}
		}

		public void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}
	}
}
namespace A2.StopTime.Reflection
{
	internal static class ReflectionCompiler<TInstance>
	{
		public static Func<TInstance, TField> CompileFieldGetter<TField>(string fieldName)
		{
			if (fieldName == null)
			{
				throw new ArgumentNullException("fieldName");
			}
			FieldInfo field = typeof(TInstance).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new ArgumentException("Field " + fieldName + " does not exist.");
			ParameterExpression parameterExpression = Expression.Parameter(typeof(TInstance), string.Empty);
			MemberExpression memberExpression = Expression.Field(parameterExpression, field);
			Expression body = memberExpression;
			if (!typeof(TInstance).IsValueType)
			{
				ConstantExpression right = Expression.Constant(null, typeof(TInstance));
				BinaryExpression test = Expression.Equal(parameterExpression, right);
				DefaultExpression ifTrue = Expression.Default(typeof(TField));
				body = Expression.Condition(test, ifTrue, memberExpression);
			}
			return Expression.Lambda<Func<TInstance, TField>>(body, new ParameterExpression[1] { parameterExpression }).Compile();
		}
	}
}
namespace A2.StopTime.Patches
{
	public static class ZNetPatch
	{
		[HarmonyPatch(typeof(ZNet), "UpdateNetTime")]
		public static class InputText
		{
			public static bool Prefix(ZNet __instance, float dt)
			{
				return !Plugin.IsTimeStopped;
			}
		}
	}
}
namespace A2.StopTime.Commands
{
	public class TimeResumeCommand : ConsoleCommand
	{
		private static readonly Func<ZNet, List<ZNetPeer>> get_ZNet_m_peers = ReflectionCompiler<ZNet>.CompileFieldGetter<List<ZNetPeer>>("m_peers");

		private static readonly Func<ZNetPeer, bool> get_ZNetPeer_m_server = ReflectionCompiler<ZNetPeer>.CompileFieldGetter<bool>("m_server");

		public override string Name => "timeresume";

		public override string Help => "Resumes the flow of time.";

		public override bool IsCheat => true;

		public override bool IsNetwork => true;

		public override bool IsSecret => false;

		public override bool OnlyServer => false;

		public override void Run(string[] args)
		{
			if (!SynchronizationManager.Instance.PlayerIsAdmin)
			{
				Console.instance.Print("You must be an admin to use this command.");
				return;
			}
			Plugin.CommandUsed = true;
			if (ZNet.instance.IsServer())
			{
				List<ZNetPeer> list = (from x in get_ZNet_m_peers(ZNet.instance)
					where !get_ZNetPeer_m_server(x)
					select x).ToList();
				Console.instance.Print($"Sending timeresume command to clients. Targets: {list.Count}");
				Plugin.TimeResumeRPCSendPackage(list);
				Plugin.IsTimeStopped = false;
			}
			else
			{
				List<ZNetPeer> list2 = (from x in get_ZNet_m_peers(ZNet.instance)
					where get_ZNetPeer_m_server(x)
					select x).ToList();
				Console.instance.Print($"Sending timeresume command to server. Targets: {list2.Count}");
				Plugin.TimeResumeRPCSendPackage(list2);
			}
		}
	}
	internal class TimeStopCommand : ConsoleCommand
	{
		private static readonly Func<ZNet, List<ZNetPeer>> get_ZNet_m_peers = ReflectionCompiler<ZNet>.CompileFieldGetter<List<ZNetPeer>>("m_peers");

		private static readonly Func<ZNetPeer, bool> get_ZNetPeer_m_server = ReflectionCompiler<ZNetPeer>.CompileFieldGetter<bool>("m_server");

		public override string Name => "timestop";

		public override string Help => "Stops the flow of time.";

		public override bool IsCheat => true;

		public override bool IsNetwork => true;

		public override bool IsSecret => false;

		public override bool OnlyServer => false;

		public override void Run(string[] args)
		{
			if (!SynchronizationManager.Instance.PlayerIsAdmin)
			{
				Console.instance.Print("You must be an admin to use this command.");
				return;
			}
			Plugin.CommandUsed = true;
			if (ZNet.instance.IsServer())
			{
				List<ZNetPeer> list = (from x in get_ZNet_m_peers(ZNet.instance)
					where !get_ZNetPeer_m_server(x)
					select x).ToList();
				Console.instance.Print($"Sending timestop command to clients. Targets: {list.Count}");
				Plugin.TimeStopRPCSendPackage(list);
				Plugin.IsTimeStopped = true;
			}
			else
			{
				List<ZNetPeer> list2 = (from x in get_ZNet_m_peers(ZNet.instance)
					where get_ZNetPeer_m_server(x)
					select x).ToList();
				Console.instance.Print($"Sending timestop command to server. Targets: {list2.Count}");
				Plugin.TimeStopRPCSendPackage(list2);
			}
		}
	}
}