Decompiled source of ChaosTricks PEAK TwitchIntegration v1.0.0

ChaosTricks_PEAK_plugins/EventsIO.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using EventsIO.Interfaces;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("EventIO")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BFT")]
[assembly: AssemblyProduct("EventIO")]
[assembly: AssemblyCopyright("Copyright ©  2020")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ab7abff2-5203-43d0-88ed-aebd4b6a130c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace EventsIO
{
	public class EventsData : IEventsData
	{
		public string Username { get; set; }

		public string Cost { get; set; }

		public string EventID { get; set; }

		public string Lang { get; set; }

		public string ExtraInfo { get; set; }

		public override string ToString()
		{
			return "EventsData: " + Username + " " + Cost + " " + EventID + " " + Lang + " " + ExtraInfo;
		}
	}
	public class EventsDataEncoder : IEventsDataEncoder, IEventsDataEncoderParams
	{
		internal static readonly string clientAppSep = "&";

		internal static readonly char clientAppSepChar = '&';

		internal static readonly string clientAppEqual = "=";

		internal static readonly char clientAppEqualChar = '=';

		protected static readonly Dictionary<string, string> symbolCodes = new Dictionary<string, string>
		{
			{ clientAppSep, "%encode_amp%" },
			{ clientAppEqual, "%encode_equal%" }
		};

		string IEventsDataEncoderParams.ClientAppSep => clientAppSep;

		char IEventsDataEncoderParams.ClientAppSepChar => clientAppSepChar;

		string IEventsDataEncoderParams.ClientAppEqual => clientAppEqual;

		char IEventsDataEncoderParams.ClientAppEqualChar => clientAppEqualChar;

		public virtual string Encode(string s)
		{
			foreach (KeyValuePair<string, string> symbolCode in symbolCodes)
			{
				s = s?.Replace(symbolCode.Key, symbolCode.Value);
			}
			return s;
		}

		public virtual string Decode(string s)
		{
			foreach (KeyValuePair<string, string> symbolCode in symbolCodes)
			{
				s = s?.Replace(symbolCode.Value, symbolCode.Key);
			}
			return s;
		}
	}
	public class EventsDataParser : IEventsDataParser
	{
		protected readonly Action<string> log;

		protected readonly IEventsDataEncoder encoder;

		protected readonly IEventsDataEncoderParams encoderParams;

		public bool isLogInfoError = true;

		public bool isLogSkipEmpty;

		public EventsDataParser(Action<string> log = null)
		{
			this.log = log;
			encoderParams = (IEventsDataEncoderParams)(encoder = new EventsDataEncoder());
		}

		protected virtual void ParserLog(string s)
		{
			log?.Invoke(s);
		}

		public virtual IEventsData ParseEvent(string data)
		{
			EventsData eventsData = new EventsData();
			string[] array = data.Split(new char[1] { encoderParams.ClientAppSepChar }, StringSplitOptions.RemoveEmptyEntries);
			if (array == null)
			{
				if (isLogInfoError)
				{
					ParserLog("get event info error. Wrong args.");
				}
				return eventsData;
			}
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(new char[1] { encoderParams.ClientAppEqualChar }, StringSplitOptions.RemoveEmptyEntries);
				if (array3.Length != 2)
				{
					if (isLogSkipEmpty)
					{
						ParserLog("skip empty item: " + text);
					}
					continue;
				}
				string text2 = encoder.Decode(array3[0]);
				string text3 = encoder.Decode(array3[1]);
				switch (text2.ToLowerInvariant())
				{
				case "username":
					eventsData.Username = text3;
					break;
				case "eventid":
					eventsData.EventID = text3;
					break;
				case "cost":
					eventsData.Cost = text3;
					break;
				case "lang":
					eventsData.Lang = text3;
					break;
				case "extrainfo":
					eventsData.ExtraInfo = text3;
					break;
				}
			}
			return eventsData;
		}
	}
	public class EventsGenerator : IEventsGenerator
	{
		protected internal enum FieldNames
		{
			UserName,
			EventID,
			Cost,
			Lang,
			ExtraInfo
		}

		protected EventsData data;

		protected readonly IEventsDataEncoder encoder;

		protected readonly IEventsDataEncoderParams encoderParams;

		public EventsGenerator()
		{
			data = new EventsData();
			encoderParams = (IEventsDataEncoderParams)(encoder = new EventsDataEncoder());
		}

		public virtual void SetCost(string s)
		{
			data.Cost = encoder.Encode(s);
		}

		public virtual void SetEventID(string s)
		{
			data.EventID = encoder.Encode(s);
		}

		public virtual void SetLang(string s)
		{
			data.Lang = encoder.Encode(s);
		}

		public virtual void SetUsername(string s)
		{
			data.Username = encoder.Encode(s);
		}

		public virtual void SetExtraInfo(string s)
		{
			data.ExtraInfo = encoder.Encode(s);
		}

		public virtual string Generate()
		{
			Dictionary<FieldNames, string> obj = new Dictionary<FieldNames, string>
			{
				{
					FieldNames.UserName,
					data.Username
				},
				{
					FieldNames.Cost,
					data.Cost
				},
				{
					FieldNames.EventID,
					data.EventID
				},
				{
					FieldNames.Lang,
					data.Lang
				},
				{
					FieldNames.ExtraInfo,
					data.ExtraInfo
				}
			};
			StringBuilder stringBuilder = new StringBuilder(obj.Count);
			string clientAppSep = encoderParams.ClientAppSep;
			string clientAppEqual = encoderParams.ClientAppEqual;
			bool flag = true;
			foreach (KeyValuePair<FieldNames, string> item in obj)
			{
				if (flag)
				{
					stringBuilder.Append($"{item.Key}{clientAppEqual}{item.Value}");
					flag = false;
					continue;
				}
				stringBuilder.Append($"{clientAppSep}{item.Key}{clientAppEqual}{item.Value}");
			}
			data = new EventsData();
			return stringBuilder.ToString();
		}
	}
	public class EventsReaderOnKey : EventsReader, IEventsReaderOnKey, IEventsReader
	{
		protected readonly Action<IEventsData> processEvent;

		protected readonly IEventsDataParser parser;

		public EventsReaderOnKey(Action<IEventsData> processEvent, IEventsDataParser parser, Action<string> log = null, Action<string> logError = null)
			: base(log, logError)
		{
			this.processEvent = processEvent;
			this.parser = parser;
		}

		protected virtual void ProcessOnKey(string[] events)
		{
			if (events == null || events.Length == 0)
			{
				return;
			}
			foreach (IEventsData item in events.Select((string item) => parser?.ParseEvent(item)))
			{
				try
				{
					ReaderLog($"StartProcessOnKey {item}");
					processEvent?.Invoke(item);
				}
				catch (Exception arg)
				{
					ReaderLogError($"StartProcessOnKey error: {arg}");
				}
			}
		}

		public virtual void ProcessAllOnKey(string[] events)
		{
			try
			{
				ProcessOnKey(events);
			}
			catch (Exception arg)
			{
				ReaderLogError($"ProcessAllOnKey error: {arg}");
			}
		}

		public virtual void ReadAndProcessAllOnKey(string path, bool isClearFile = true)
		{
			ProcessAllOnKey(ReadAll(path, isClearFile));
		}
	}
	public class EventsReaderOnFrame : EventsReader, IEventsReaderOnFrame, IEventsReader
	{
		protected bool isFirstRun = true;

		protected readonly float delay;

		protected float delayCounter;

		protected float initDelay;

		protected float initCounter;

		protected readonly float checkPeriod;

		protected float periodCounter;

		protected readonly Action<IEventsData> processEvent;

		protected readonly IEventsDataParser parser;

		protected IEnumerator<IEventsData> eventsData;

		protected readonly string path;

		private bool isDelayEveryProcessing;

		public bool IsDelayEveryProcessing
		{
			get
			{
				return isDelayEveryProcessing;
			}
			set
			{
				isDelayEveryProcessing = value;
			}
		}

		protected virtual void StartProcessOnFrame()
		{
			while (eventsData.MoveNext())
			{
				try
				{
					ReaderLog($"StartProcessOnFrame {eventsData.Current}");
					processEvent?.Invoke(eventsData.Current);
				}
				catch (Exception arg)
				{
					ReaderLogError($"StartProcessOnFrame error: {arg}");
				}
			}
			eventsData = null;
		}

		protected virtual void StartProcessWithDelayOnFrame()
		{
			if (eventsData.MoveNext())
			{
				try
				{
					ReaderLog($"StartProcessWithDelayOnFrame {eventsData.Current}");
					processEvent?.Invoke(eventsData.Current);
					return;
				}
				catch (Exception arg)
				{
					ReaderLogError($"StartProcessWithDelayOnFrame error: {arg}");
					return;
				}
			}
			isFirstRun = false;
			eventsData = null;
			ReaderLog("StartProcessWithDelayOnFrame end");
		}

		public EventsReaderOnFrame(string path, Action<IEventsData> processEvent, IEventsDataParser parser, Action<string> log = null, Action<string> errorLog = null, float checkPeriod = 2f, float delay = 1f, float initDelay = 0.5f)
			: base(log, errorLog)
		{
			this.processEvent = processEvent;
			this.parser = parser;
			this.delay = delay;
			this.initDelay = initDelay;
			this.path = path;
			this.checkPeriod = checkPeriod;
		}

		public virtual void SetEventsToProcess(string[] events)
		{
			try
			{
				if (events == null || events.Length == 0)
				{
					eventsData = null;
					return;
				}
				ReaderLog($"SetEventsToProcess read {events.Length} events");
				eventsData = events.Select((string item) => parser?.ParseEvent(item))?.GetEnumerator();
			}
			catch (Exception arg)
			{
				ReaderLogError($"SetEventsToProcess error: {arg}");
			}
		}

		public virtual bool IsProcessEnd()
		{
			return eventsData == null;
		}

		public virtual void ProcessAllWithDelayOnFrame(float dt)
		{
			if (IsProcessEnd())
			{
				return;
			}
			try
			{
				if (isDelayEveryProcessing || isFirstRun)
				{
					if (initDelay != 0f)
					{
						initCounter += dt;
						if (initCounter >= initDelay)
						{
							initCounter = 0f;
							initDelay = 0f;
							StartProcessWithDelayOnFrame();
						}
					}
					else
					{
						delayCounter += dt;
						if (delayCounter >= delay)
						{
							delayCounter = 0f;
							StartProcessWithDelayOnFrame();
						}
					}
				}
				else
				{
					StartProcessOnFrame();
				}
			}
			catch (Exception arg)
			{
				ReaderLogError($"ProcessAllWithDelay error: {arg}");
			}
		}

		public virtual void ReadAndProcessAllWithDelayOnFrame(float dt)
		{
			if (IsProcessEnd())
			{
				periodCounter += dt;
				if (periodCounter >= checkPeriod)
				{
					periodCounter = 0f;
					string[] eventsToProcess = ReadAll(path);
					SetEventsToProcess(eventsToProcess);
				}
			}
			ProcessAllWithDelayOnFrame(dt);
		}
	}
	public class EventsReader : IEventsReader
	{
		protected readonly Action<string> log;

		protected readonly Action<string> logError;

		public EventsReader(Action<string> log = null, Action<string> logError = null)
		{
			this.log = log;
			this.logError = logError;
		}

		protected virtual void ReaderLog(string s)
		{
			log?.Invoke(s);
		}

		protected virtual void ReaderLogError(string s)
		{
			logError?.Invoke(s);
		}

		public virtual string[] ReadAllUnsafe(string path, bool isClearFile = true)
		{
			using FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
			using StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8);
			char[] separator = new char[2] { '\r', '\n' };
			string[] array = streamReader.ReadToEnd().Split(separator, StringSplitOptions.RemoveEmptyEntries);
			if (isClearFile && array != null && array.Length >= 1)
			{
				fileStream.SetLength(0L);
			}
			return array;
		}

		public virtual string[] ReadAll(string path, bool isClearFile = true)
		{
			try
			{
				return ReadAllUnsafe(path, isClearFile);
			}
			catch (FileNotFoundException)
			{
			}
			catch (DirectoryNotFoundException)
			{
			}
			catch (Exception arg)
			{
				ReaderLogError($"read event error: {arg}");
			}
			return null;
		}
	}
}
namespace EventsIO.Interfaces
{
	public interface IEventsData
	{
		string Username { get; }

		string Cost { get; }

		string EventID { get; }

		string Lang { get; }

		string ExtraInfo { get; }
	}
	public interface IEventsDataEncoderParams
	{
		string ClientAppSep { get; }

		char ClientAppSepChar { get; }

		string ClientAppEqual { get; }

		char ClientAppEqualChar { get; }
	}
	public interface IEventsDataEncoder
	{
		string Encode(string s);

		string Decode(string s);
	}
	public interface IEventsDataParser
	{
		IEventsData ParseEvent(string s);
	}
	public interface IEventsGenerator
	{
		void SetUsername(string s);

		void SetEventID(string s);

		void SetCost(string s);

		void SetLang(string s);

		void SetExtraInfo(string s);

		string Generate();
	}
	public interface IEventsReaderOnKey : IEventsReader
	{
		void ProcessAllOnKey(string[] events);

		void ReadAndProcessAllOnKey(string path, bool isClearFile = true);
	}
	public interface IEventsReaderOnFrame : IEventsReader
	{
		void SetEventsToProcess(string[] events);

		bool IsProcessEnd();

		void ProcessAllWithDelayOnFrame(float dt);

		void ReadAndProcessAllWithDelayOnFrame(float dt);
	}
	public interface IEventsReader
	{
		string[] ReadAll(string path, bool isClearFile = true);
	}
}

ChaosTricks_PEAK_plugins/InteractiveMod.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using EventsIO;
using EventsIO.Interfaces;
using HarmonyLib;
using ModHelper;
using ModHelper.Interfaces;
using ModHelperUnity;
using ModHelperUnity.Interfaces;
using ModHelperUnity.UtilityGUI;
using Newtonsoft.Json;
using Photon.Pun;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using WebSocketIO;
using Zorro.Core;
using Zorro.Core.CLI;
using Zorro.Settings;
using peak_bepinex;
using peak_bepinex.Commands.Interfaces;
using peak_bepinex.Patchers;
using peak_bepinex.Services;
using peak_bepinex.Wrappers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("peak_bepinex")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BFT LLC")]
[assembly: AssemblyProduct("ChaosTricksMod")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("BFT")]
[assembly: ComVisible(false)]
[assembly: Guid("F3976D04-F3F2-42D1-A5AD-9FEA4196A17F")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace peak_standalone.Commands
{
	internal class CustomRevive : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "revive_player";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			bool dead = localCharacter.data.dead;
			if (localCharacter.data.fullyPassedOut && !dead)
			{
				((MonoBehaviourPun)localCharacter).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[2]
				{
					Character.localCharacter.Head,
					true
				});
			}
			else if (dead)
			{
				PlayerGhost ghost = localCharacter.Ghost;
				Vector3 val = ((!((Object)(object)ghost != (Object)null)) ? Character.localCharacter.Head : (ghost.m_target.Center + Vector3.up * 5f));
				((MonoBehaviourPun)localCharacter).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[2] { val, true });
			}
			else
			{
				((HelperLog)Utils.logger).LogWarning((object)"player is alive, skip revive");
			}
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
}
namespace peak_bepinex
{
	[BepInPlugin("bft.chaostricks", "Chaos Tricks", "1.0.0")]
	internal class BepInExPlugin : BaseUnityPlugin
	{
		public const string GUID = "bft.chaostricks";

		public const string NAME = "Chaos Tricks";

		private GameObject hookObj;

		private bool isPatched;

		public void Awake()
		{
			try
			{
				UtilitySettings.BaseFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			catch (Exception arg)
			{
				((HelperLog)Utils.logger).LogError((object)string.Format("{0} v{1} error: {2}", "Chaos Tricks", "1.0.0", arg));
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			try
			{
				((HelperLog)Utils.logger).Log((object)("OnSceneLoaded triggered: " + ((Scene)(ref scene)).name));
				if (!isPatched)
				{
					((HelperLog)Utils.logger).LogInfo((object)"Background task: trying to create mod instance");
					hookObj = new GameObject();
					Object.DontDestroyOnLoad((Object)(object)hookObj);
					hookObj.AddComponent<InteractiveMod>();
					hookObj.SetActive(true);
					isPatched = true;
					SceneManager.sceneLoaded -= OnSceneLoaded;
				}
			}
			catch (Exception arg)
			{
				((HelperLog)Utils.logger).LogError((object)string.Format("{0} v{1} OnSceneLoaded error: {2}", "Chaos Tricks", "1.0.0", arg));
			}
		}
	}
	public static class GameUtils
	{
		public struct Coords
		{
			public Vector3 pos;

			public Quaternion rot;
		}

		public static IEnumerable<Character> Players => Character.AllCharacters;

		public static IEnumerable<Character> AlivePlayers => Character.AllCharacters.Where((Character p) => (Object)(object)p.data != (Object)null && !p.data.dead);

		public static void RunGameConsoleCommand(string cmd)
		{
			((HelperLog)Utils.logger).LogInfo((object)("try to run in-game command: " + cmd));
			ConsoleHandler.ProcessCommand(cmd);
		}

		public static void ApplyForceToPlayer(Character ch, in Vector3 dir)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			List<Bodypart> partList = ch.refs.ragdoll.partList;
			if (partList == null || partList.Count == 0)
			{
				((HelperLog)Utils.logger).LogWarning((object)"ApplyForceToPlayer empty body parts");
				return;
			}
			foreach (Bodypart item in partList)
			{
				Traverse.Create((object)item).Field<Rigidbody>("rig").Value.AddForce(dir, (ForceMode)1);
			}
		}

		public static void ApplyForceToLocalPlayer(in Vector3 dir)
		{
			ApplyForceToPlayer(Character.localCharacter, in dir);
		}

		public static Vector3 GetLocalPlayerForwardOffset(float offsetForward = 1f, float offsetHeight = 0.5f)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)Character.localCharacter).transform;
			Vector3 position = transform.position;
			Vector3 forward = transform.forward;
			return position + ((Vector3)(ref forward)).normalized * offsetForward + new Vector3(0f, offsetHeight, 0f);
		}

		public static ref Vector3 GetLocalPlayerForwardWay()
		{
			return ref Character.localCharacter.data.lookDirection_Flat;
		}

		public static ref Vector3 GetLocalPlayerRightWay()
		{
			return ref Character.localCharacter.data.lookDirection_Right;
		}

		public static ref Vector3 GetLocalPlayerUpWay()
		{
			return ref Character.localCharacter.data.lookDirection_Up;
		}

		public static void TeleportPlayer(Character player, in Vector3 pos)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			StopClimbing(player);
			((MonoBehaviourPun)player).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { pos, true });
		}

		public static void StopClimbing(Character player)
		{
			try
			{
				player.refs.climbing.CancelHandle(false);
			}
			catch (Exception arg)
			{
				((HelperLog)Utils.logger).LogError((object)$"CancelHandle error: {arg}");
			}
			try
			{
				Traverse.Create((object)player.refs.climbing).Field<PhotonView>("view").Value.RPC("StopClimbingRpc", (RpcTarget)0, new object[1] { 0f });
			}
			catch (Exception arg2)
			{
				((HelperLog)Utils.logger).LogError((object)$"StopClimbingRpc error: {arg2}");
			}
			try
			{
				Traverse.Create((object)player.refs.vineClimbing).Field<PhotonView>("view").Value.RPC("StopVineClimbingRpc", (RpcTarget)0, Array.Empty<object>());
			}
			catch (Exception arg3)
			{
				((HelperLog)Utils.logger).LogError((object)$"StopVineClimbingRpc error: {arg3}");
			}
			try
			{
				Traverse.Create((object)player.refs.ropeHandling).Field<PhotonView>("view").Value.RPC("StopRopeClimbingRpc", (RpcTarget)0, Array.Empty<object>());
			}
			catch (Exception arg4)
			{
				((HelperLog)Utils.logger).LogError((object)$"StopRopeClimbingRpc error: {arg4}");
			}
		}

		public static STATUSTYPE NameToPlayerStatusType(string name)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.TryParse<STATUSTYPE>(name, ignoreCase: true, out STATUSTYPE result))
			{
				return result;
			}
			((HelperLog)Utils.logger).LogError((object)("NameToStatusType got unknown status " + name + ", used default Crab."));
			return (STATUSTYPE)4;
		}

		public static Bodypart GetCharacterBodypart(BodypartType part)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return Character.localCharacter.refs.ragdoll.partDict[part];
		}

		public static T GetClosestObject<T>(Vector3 pos, Func<T, bool> filter, bool needLog = true) where T : MonoBehaviour
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			T[] array = Object.FindObjectsOfType<T>();
			int num = array.Length;
			if (needLog)
			{
				((HelperLog)Utils.logger).LogInfo((object)$"GetClosestObject found {num}");
			}
			if (num == 0)
			{
				return default(T);
			}
			if (filter != null)
			{
				array = array.Where(filter).ToArray();
				num = array.Length;
				if (needLog)
				{
					((HelperLog)Utils.logger).LogInfo((object)$"GetClosestObject filtered size {num}");
				}
			}
			switch (num)
			{
			case 0:
				return default(T);
			case 1:
				return array[0];
			default:
			{
				T val = array[0];
				Vector3 val2 = pos - ((Component)(object)val).transform.position;
				float num2 = ((Vector3)(ref val2)).sqrMagnitude;
				for (int i = 1; i < num; i++)
				{
					T val3 = array[i];
					val2 = pos - ((Component)(object)val3).transform.position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num2)
					{
						val = val3;
						num2 = sqrMagnitude;
					}
				}
				return val;
			}
			}
		}
	}
	public sealed class InteractiveMod : MonoBehaviour
	{
		public static InteractiveMod inst;

		internal const string MOD_VERSION = "1.0.0";

		private readonly ServiceProvider serviceProvider = ServiceProvider.inst;

		private readonly BufferedLogger logger = Utils.logger;

		private ScheduleManager systemScheduleManager;

		private ScheduleManager scheduleManager;

		private EventEmitter eventEmitter;

		private WebSocketEventsReader<SettingsData> eventsReader;

		private IEventsDataParser eventsParser;

		private ICommandManager commandManager;

		private IComponentTypedNotify notifyManager;

		private UtilityConsole console;

		private Dictionary<string, IInternalStandaloneCommand> commands;

		private TranslationService translationService;

		private LimitedLogWrapper limitedLogger;

		private LimitedLogWrapper limitedSceneLogger;

		private bool readyToActivateEvents;

		private readonly List<IForceEnd> forceEndEvents = new List<IForceEnd>();

		public void Awake()
		{
			inst = this;
			Utils.LogClearBySize();
			limitedLogger = new LimitedLogWrapper(100, (IDebugLogger)(object)Utils.logger);
			limitedSceneLogger = new LimitedLogWrapper(50, (IDebugLogger)(object)Utils.logger);
			((HelperLog)logger).LogInfo((object)"InteractiveMod Awake");
			((HelperLog)logger).LogInfo((object)"mod version 1.0.0");
			FlushLog();
			MainPatcher.InitPatch();
		}

		public void Start()
		{
			((HelperLog)logger).LogInfo((object)"InteractiveMod Start");
			try
			{
				UtilityJson.RegisterCustomGenerator((Func<IJsonUtil>)(() => (IJsonUtil)(object)new JsonParser()));
				((HelperLog)logger).LogInfo((object)"init mod services");
				InitServices();
				((HelperLog)logger).LogInfo((object)"init mod readers");
				InitReaders();
				((HelperLog)logger).LogInfo((object)"init mod commands");
				InitCommands(needValidate: false);
				((HelperLog)logger).LogInfo((object)"mod initiation ends");
			}
			catch (Exception arg)
			{
				((HelperLog)logger).LogError((object)$"mod initiation error: {arg}");
			}
			FlushLog();
		}

		public void OnDestroy()
		{
			((HelperLog)logger).LogInfo((object)"InteractiveMod OnDestroy");
			FlushLog();
			SceneManager.sceneLoaded -= SceneLoaded;
		}

		private void FlushLog()
		{
			logger.Flush(true);
		}

		private void InitServices()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			eventEmitter = new EventEmitter();
			serviceProvider.RegisterEventEmitter(eventEmitter);
			systemScheduleManager = new ScheduleManager((ILogger)(object)logger, 0);
			serviceProvider.RegisterSystemScheduleManager(systemScheduleManager);
			systemScheduleManager.NewPeriodicTask(new PeriodicTaskData
			{
				periodicAction = FlushLog,
				finishAction = FlushLog,
				periodInSec = 5f
			}, false);
			scheduleManager = new ScheduleManager((ILogger)(object)logger, 0);
			serviceProvider.RegisterScheduleManager(scheduleManager);
			translationService = new TranslationService();
			translationService.LoadData();
			if (notifyManager == null)
			{
				notifyManager = (IComponentTypedNotify)(object)((Component)this).gameObject.AddComponent<TypedNotifyOnGUI>();
			}
			notifyManager.ForcePostInit(Utils.modFolder, (IDebugLogger)(object)Utils.logger, (Func<string, byte[]>)null);
			SceneManager.sceneLoaded += SceneLoaded;
		}

		private void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			string name = ((Scene)(ref scene)).name;
			((HelperLog)Utils.logger).LogInfo((object)("scene loaded: " + name));
			readyToActivateEvents = name != "Title" && name != "Airport";
		}

		private void InitReaders()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			console = new UtilityConsole((IDebugLogger)(object)logger, (List<string>)null);
			eventsParser = (IEventsDataParser)new EventsDataParser((Action<string>)((HelperLog)logger).LogWarning);
			eventsReader = new WebSocketEventsReader<SettingsData>((Action<IEventsData>)ProcessEvent, eventsParser, (Action<string>)((HelperLog)logger).LogInfo, (Action<string>)((HelperLog)logger).LogInfo, 0.5f, 1f, 0.5f, true);
			eventsReader.InitDefaultSocket(Utils.modFolder, "chaostricks_peak", 13715, "127.0.0.1");
			Action<string> defaultOnConfig = eventsReader.SocketHandler.OnConfigMessage;
			eventsReader.SocketHandler.OnConfigMessage = delegate(string s)
			{
				defaultOnConfig?.Invoke(s);
				SettingsManager.QueueUpdateSettings(eventsReader.Settings);
			};
			eventsReader.OpenSocket(true);
		}

		public void InitCommands(bool needValidate)
		{
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			forceEndEvents.Clear();
			Type type = typeof(IInternalStandaloneCommand);
			IEnumerable<Type> enumerable = from p in Assembly.GetExecutingAssembly().GetTypes()
				where type.IsAssignableFrom(p) && p.IsClass && !p.IsAbstract
				select p;
			((HelperLog)logger).LogInfo((object)$"found {enumerable.Count()} commands");
			commands = new Dictionary<string, IInternalStandaloneCommand>();
			foreach (Type item2 in enumerable)
			{
				IInternalStandaloneCommand internalStandaloneCommand = Activator.CreateInstance(item2) as IInternalStandaloneCommand;
				if (internalStandaloneCommand != null)
				{
					console.RegisterCommand((IConsoleCommand)internalStandaloneCommand);
					if (commands.ContainsKey(((IConsoleCommand)internalStandaloneCommand).Id))
					{
						((HelperLog)logger).LogWarning((object)("repeated id command " + ((IConsoleCommand)internalStandaloneCommand).Id + ". The command will replace existed."));
					}
					commands[((IConsoleCommand)internalStandaloneCommand).Id] = internalStandaloneCommand;
					if (internalStandaloneCommand is IForceEnd item)
					{
						forceEndEvents.Add(item);
					}
					((HelperLog)logger).LogInfo((object)("init command '" + ((IConsoleCommand)internalStandaloneCommand).Id + "' complete"));
				}
				else
				{
					((HelperLog)logger).LogError((object)("init command '" + ((IConsoleCommand)internalStandaloneCommand).Id + "' failed"));
				}
			}
			((HelperLog)logger).LogInfo((object)$"found {commands.Count} commands and {forceEndEvents.Count} timers");
			((HelperLog)logger).LogInfo((object)"init HelperCommandManager");
			commandManager = (ICommandManager)new HelperCommandManagerFormatted((IDebugLogger)(object)logger);
			commandManager.InitFromFile(Utils.GetRelativeModFilePath("commands.data"));
			int num = commandManager.GetCommands().Length;
			((HelperLog)logger).LogInfo((object)$"found {num} events");
			if (!needValidate)
			{
				return;
			}
			((HelperLog)logger).LogInfo((object)"validate commands");
			string[] array = commandManager.GetCommands();
			foreach (string text in array)
			{
				if (!console.IsValidCommandLine(text?.Trim()))
				{
					((HelperLog)logger).LogError((object)("Command line '" + text + "' invalid"));
				}
			}
			((HelperLog)logger).LogInfo((object)"init HelperCommandManager ends");
		}

		private void ProcessEvent(IEventsData data)
		{
			string eventID = data.EventID;
			if (string.IsNullOrEmpty(eventID))
			{
				((HelperLog)logger).LogError((object)"ProcessEvent eventID is null or empty");
				return;
			}
			((HelperLog)logger).LogInfo((object)("Try to execute event: '" + eventID + "'"));
			string text = commandManager.GetCommandData(eventID, true)?.Trim();
			try
			{
				((HelperLog)logger).LogInfo((object)("Command: " + text));
				if (console.RunCommand(text, data, (Action<string>)null))
				{
					((HelperLog)logger).LogInfo((object)("Event '" + data.EventID + "' executing is completed"));
					if (notifyManager != null)
					{
						notifyManager.AddNotifyToQueue(data, translationService.translation, (Func<string, string>)null, true);
					}
				}
				else
				{
					((HelperDebugLog)logger).LogDebugError((object)("Event '" + data.EventID + "' executing is failed"));
				}
			}
			catch (Exception arg)
			{
				((HelperLog)logger).LogError((object)$"ProcessCommands '{data.EventID}' unexpected error: {arg}");
			}
		}

		private void CancelEvents()
		{
			try
			{
				((HelperLog)Utils.logger).LogInfo((object)"CancelEvents triggered");
				foreach (IForceEnd forceEndEvent in forceEndEvents)
				{
					try
					{
						forceEndEvent.ForceEnd();
					}
					catch (Exception arg)
					{
						((HelperLog)Utils.logger).LogError((object)$"CancelEvents force end for {((IConsoleCommand)forceEndEvent).Id} error: {arg}");
					}
				}
				if (notifyManager != null)
				{
					notifyManager.ClearNotifyQueue();
					notifyManager.StopCurrentNotify();
				}
			}
			catch (Exception arg2)
			{
				((HelperLog)Utils.logger).LogError((object)$"CancelEvents {arg2}");
			}
		}

		public void Update()
		{
			try
			{
				float deltaTime = Time.deltaTime;
				systemScheduleManager.OnUpdate(deltaTime);
				SettingsManager.OnUpdate();
				scheduleManager.OnUpdate(deltaTime);
				if (readyToActivateEvents)
				{
					eventEmitter.TriggerOnUpdateEvent(this, deltaTime);
					((EventsReaderOnFrame)eventsReader).ReadAndProcessAllWithDelayOnFrame(deltaTime);
				}
			}
			catch (Exception arg)
			{
				limitedLogger.LogError($"OnUpdate error: {arg}");
			}
		}

		public void ReinitMod()
		{
			try
			{
				((HelperLog)logger).LogInfo((object)"ReinitMod starts");
				FlushLog();
				CancelEvents();
				InitCommands(needValidate: false);
				notifyManager.ForcePostInit(Utils.modFolder, (IDebugLogger)(object)Utils.logger, (Func<string, byte[]>)null);
				((HelperLog)logger).LogInfo((object)"ReinitMod ends");
			}
			catch (Exception arg)
			{
				((HelperLog)logger).LogError((object)$"ReinitMod error: {arg}");
			}
			FlushLog();
		}
	}
	internal sealed class JsonParser : IJsonUtil
	{
		public T FromFile<T>(string path) where T : class
		{
			using StreamReader streamReader = new StreamReader(path);
			return FromString<T>(streamReader.ReadToEnd());
		}

		public T FromString<T>(string s) where T : class
		{
			return JsonConvert.DeserializeObject<T>(s);
		}
	}
	public static class Utils
	{
		public static readonly Random rnd = new Random(Guid.NewGuid().GetHashCode());

		public static readonly string modFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		private const string LOG_FNAME = "latest_log.txt";

		private static readonly string logPath = Path.Combine(modFolder, "latest_log.txt");

		public static readonly BufferedLogger logger = new BufferedLogger(modFolder, "latest_log.txt", false, 50);

		public static void LogClearBySize()
		{
			try
			{
				FileInfo fileInfo = new FileInfo(logPath);
				if (fileInfo.Exists && fileInfo.Length > 200000)
				{
					((HelperLog)logger).LogClear();
				}
			}
			catch (Exception arg)
			{
				Debug.Log((object)$"LogClearBySize error: {arg}");
			}
		}

		public static string GetRelativeModFilePath(string fname)
		{
			return Path.Combine(modFolder, fname);
		}

		public static List<T> Shuffle<T>(IEnumerable<T> list)
		{
			if (list == null)
			{
				return new List<T>();
			}
			int num = list.Count();
			if (num <= 1)
			{
				return new List<T>(list);
			}
			List<T> list2 = new List<T>(list);
			for (int i = 0; i < num; i++)
			{
				T value = list2[i];
				int index = rnd.Next(num);
				list2[i] = list2[index];
				list2[index] = value;
			}
			return list2;
		}

		public static List<T> ShuffleForceRandom<T>(IEnumerable<T> list)
		{
			if (list == null)
			{
				return new List<T>();
			}
			int num = list.Count();
			if (num <= 1)
			{
				return new List<T>(list);
			}
			T[] array = new T[num];
			T[] array2 = list.ToArray();
			List<int> list2 = new List<int>(Enumerable.Range(0, num));
			for (int i = 0; i < num; i++)
			{
				List<int> list3 = new List<int>(list2);
				list3.Remove(i);
				if (list3.Count == 0)
				{
					break;
				}
				int num2 = list3[rnd.Next(list3.Count)];
				array[i] = array2[num2];
				list2.Remove(num2);
			}
			if (list2.Count == 1)
			{
				int num3 = num - 1;
				int num4 = rnd.Next(num3);
				array[num3] = array[num4];
				array[num4] = array2[num3];
			}
			return array.ToList();
		}
	}
}
namespace peak_bepinex.Wrappers
{
	public class CommandArgsReaderWrapper
	{
		private readonly IEnumerator<string> args;

		private readonly CommandArgsReader reader;

		public CommandArgsReaderWrapper(IEnumerable<string> args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			this.args = args?.GetEnumerator();
			reader = new CommandArgsReader((ILogger)(object)Utils.logger);
		}

		public int ReadInt(int defaultValue = 0)
		{
			return reader.ReadInt(args, defaultValue);
		}

		public float ReadFloat(float defaultValue = 0f)
		{
			return reader.ReadFloat(args, defaultValue);
		}

		public string ReadString(string defaultValue = "")
		{
			return reader.ReadString(args, defaultValue);
		}

		public string ReadSpacedString(string defaultValue = "")
		{
			return ParseItemPath(reader.ReadString(args, defaultValue));
		}

		public string ReadAllAsSingleString(string separator = " ", string defaultValue = "")
		{
			if (args == null)
			{
				return defaultValue;
			}
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = true;
			while (args.MoveNext())
			{
				if (!flag && !string.IsNullOrEmpty(separator))
				{
					stringBuilder.Append(separator);
				}
				flag = false;
				stringBuilder.Append(args.Current);
			}
			string text = stringBuilder.ToString();
			if (!string.IsNullOrEmpty(text))
			{
				return text;
			}
			return defaultValue;
		}

		public string[] ParseList(string s, string separator = "|")
		{
			if (string.IsNullOrEmpty(s))
			{
				return null;
			}
			return (from item in s.Split(new string[1] { separator }, StringSplitOptions.None)
				select item.Trim() into item
				where !string.IsNullOrWhiteSpace(item)
				select item).ToArray();
		}

		public static string ParseItemPath(string path)
		{
			return path?.Replace("_", " ");
		}

		public bool ReadBool(bool defaultValue = false)
		{
			return reader.ReadBool(args, defaultValue);
		}
	}
	public class LimitedLogWrapper : IDebugLogger, ILoggerWithConsole, ILogger
	{
		private readonly IDebugLogger logger;

		private int messagesLimit;

		public LimitedLogWrapper(int messagesLimit, IDebugLogger logger)
		{
			this.logger = logger;
			this.messagesLimit = messagesLimit;
		}

		public void Log(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILogger)logger).Log(obj);
			}
		}

		public void LogClear()
		{
			((ILogger)logger).LogClear();
		}

		public void LogDebugInfo(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				logger.LogDebugInfo(obj);
			}
		}

		public void LogDebugWarning(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				logger.LogDebugWarning(obj);
			}
		}

		public void LogDebugError(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				logger.LogDebugError(obj);
			}
		}

		public void LogInfo(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILogger)logger).LogInfo(obj);
			}
		}

		public void LogInfoConsoleOnly(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILoggerWithConsole)logger).LogInfoConsoleOnly(obj);
			}
		}

		public void LogInfoFileOnly(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILoggerWithConsole)logger).LogInfoFileOnly(obj);
			}
		}

		public void LogWarning(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILogger)logger).LogWarning(obj);
			}
		}

		public void LogWarningConsoleOnly(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILoggerWithConsole)logger).LogWarningConsoleOnly(obj);
			}
		}

		public void LogWarningFileOnly(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILoggerWithConsole)logger).LogWarningFileOnly(obj);
			}
		}

		public void LogError(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILogger)logger).LogError(obj);
			}
		}

		public void LogErrorConsoleOnly(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILoggerWithConsole)logger).LogErrorConsoleOnly(obj);
			}
		}

		public void LogErrorFileOnly(object obj)
		{
			if (messagesLimit > 0)
			{
				messagesLimit--;
				((ILoggerWithConsole)logger).LogErrorFileOnly(obj);
			}
		}

		public void UpdateLimit(int limit)
		{
			messagesLimit = limit;
		}
	}
}
namespace peak_bepinex.Patchers
{
	public static class MainPatcher
	{
		private static bool isPatched;

		public static void InitPatch()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (isPatched)
			{
				return;
			}
			isPatched = true;
			try
			{
				((HelperLog)Utils.logger).Log((object)"MainPatcher init");
				new Harmony("com.Loki.patch").PatchAll(Assembly.GetExecutingAssembly());
			}
			catch (Exception arg)
			{
				((HelperLog)Utils.logger).LogError((object)$"MainPatcher error: {arg}");
			}
		}
	}
}
namespace peak_bepinex.Services
{
	public class ChaosModNetwork : MonoBehaviour
	{
		public struct DataSource
		{
			public int playerID;

			public string eventID;

			public string username;

			public string lang;
		}

		private static ChaosModNetwork inst;

		private PhotonView photonView;

		private static Queue<DataSource> commandQueue;

		private static readonly HashSet<string> shouldBeRunFromHost = new HashSet<string>();

		private void Awake()
		{
			inst = this;
			photonView = ((Component)this).GetComponent<PhotonView>();
			commandQueue = new Queue<DataSource>();
		}

		[PunRPC]
		private void ActivateEventOtherRPC(string eventID)
		{
			((HelperLog)Utils.logger).LogInfo((object)("ChaosModNetwork->ActivateEventOtherRPC triggered for " + eventID));
		}

		[PunRPC]
		private void ActivateClientEventRPC(int playerID, string eventID, string lang, string username)
		{
			((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->ActivateClientEventRPC triggered for {playerID} {eventID}");
			if (commandQueue == null)
			{
				((HelperLog)Utils.logger).LogError((object)"ChaosModNetwork->ActivateClientEventRPC an attempt to store events before initiating");
				return;
			}
			commandQueue.Enqueue(new DataSource
			{
				eventID = eventID,
				playerID = playerID,
				lang = lang,
				username = username
			});
		}

		public static void RequestEventOther(string eventID)
		{
			((HelperLog)Utils.logger).LogInfo((object)("ChaosModNetwork->RequestEventOther triggered for " + eventID));
			try
			{
				inst.photonView.RPC("ActivateEventOtherRPC", (RpcTarget)1, new object[1] { eventID });
			}
			catch (Exception arg)
			{
				((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->RequestEventOther error: {arg}");
			}
		}

		public static void RequestClientEventRPC(int userID, string eventID, string lang, string username)
		{
			((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->RequestClientEventRPC triggered for {userID} {eventID}");
			try
			{
				inst.photonView.RPC("ActivateClientEventRPC", (RpcTarget)2, new object[4] { userID, eventID, lang, username });
			}
			catch (Exception arg)
			{
				((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->RequestClientEventRPC error: {arg}");
			}
		}

		public static bool NeedRunFromHost(string eventID)
		{
			return shouldBeRunFromHost.Contains(eventID);
		}

		public static void ProcessNetworkEvents(ICommandManager cm, Dictionary<string, IInternalStandaloneCommand> commands)
		{
			while (commandQueue.Count > 0)
			{
				try
				{
					DataSource dataSource = commandQueue.Dequeue();
					((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->ProcessEvents event id {dataSource.eventID} for {dataSource.playerID}");
				}
				catch (Exception arg)
				{
					((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->ProcessEvents: {arg}");
				}
			}
		}

		public static void RequestNotifyOtherRPC(string eventID, string lang, string username)
		{
			if (eventID.StartsWith("all_") || eventID.StartsWith("spawn_"))
			{
				try
				{
					inst.photonView.RPC("NotifyOtherRPC", (RpcTarget)1, new object[3] { eventID, lang, username });
				}
				catch (Exception arg)
				{
					((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->RequestActivateNotifyRPC error: {arg}");
				}
				((HelperLog)Utils.logger).LogInfo((object)("ChaosModNetwork->RequestActivateNotifyRPC triggered for " + eventID));
			}
		}

		[PunRPC]
		private void NotifyOtherRPC(string eventID, string lang, string username)
		{
			((HelperLog)Utils.logger).LogInfo((object)("ChaosModNetwork->ActivateNotifyRPC triggered for " + eventID));
		}
	}
	public sealed class EventEmitter
	{
		private enum Event
		{
			OnUpdate,
			OnConfigChangedThreadSafe
		}

		private class EmitterAction
		{
			public string id;

			public Action<object, object> action;
		}

		private readonly ILogger logger = (ILogger)(object)new LimitedLogWrapper(100, (IDebugLogger)(object)Utils.logger);

		private readonly Dictionary<Event, List<EmitterAction>> eventHandlers;

		public EventEmitter()
		{
			eventHandlers = new Dictionary<Event, List<EmitterAction>>();
			foreach (Event item in Enum.GetValues(typeof(Event)).OfType<Event>())
			{
				eventHandlers[item] = new List<EmitterAction>();
			}
		}

		private void ReplaceOrAddHandler(Event key, string id, Action<object, object> handler)
		{
			if (id != null)
			{
				eventHandlers[key].RemoveAll((EmitterAction action) => action.id == id);
			}
			eventHandlers[key].Add(new EmitterAction
			{
				action = handler,
				id = id
			});
		}

		private void TriggerEvent(Event key, object sender, object data)
		{
			try
			{
				if (!eventHandlers.TryGetValue(key, out var value))
				{
					return;
				}
				foreach (EmitterAction item in value)
				{
					try
					{
						item.action(sender, data);
					}
					catch (Exception arg)
					{
						logger.LogError((object)$"EventEmitter->TriggerEvent inner {key} error: {arg}");
					}
				}
			}
			catch (Exception arg2)
			{
				logger.LogError((object)$"EventEmitter->TriggerEvent {key} error: {arg2}");
			}
		}

		public void ReplaceOrAddOnUpdateHandler(string id, Action<object, float> handler)
		{
			ReplaceOrAddHandler(Event.OnUpdate, id, delegate(object sender, object data)
			{
				handler(sender, (float)data);
			});
		}

		public void TriggerOnUpdateEvent(object sender, float dtInSec)
		{
			TriggerEvent(Event.OnUpdate, sender, dtInSec);
		}

		public void ReplaceOrAddOnConfigChanged_ThreadSafeHandler(string id, Action<object, SettingsData> handler)
		{
			ReplaceOrAddHandler(Event.OnConfigChangedThreadSafe, id, delegate(object sender, object settings)
			{
				handler(sender, (SettingsData)settings);
			});
		}

		public void TriggerOnConfigChangedEvent_ThreadSafe(object sender, SettingsData settings)
		{
			TriggerEvent(Event.OnConfigChangedThreadSafe, sender, settings);
		}
	}
	public sealed class ServiceProvider
	{
		public static readonly ServiceProvider inst = new ServiceProvider();

		public ScheduleManager systemScheduleManager;

		public ScheduleManager scheduleManager;

		public EventEmitter eventEmitter;

		public void RegisterSystemScheduleManager(ScheduleManager systemScheduleManager)
		{
			this.systemScheduleManager = systemScheduleManager;
		}

		public void RegisterScheduleManager(ScheduleManager scheduleManager)
		{
			this.scheduleManager = scheduleManager;
		}

		public void RegisterEventEmitter(EventEmitter eventEmitter)
		{
			this.eventEmitter = eventEmitter;
		}
	}
	public sealed class SettingsData
	{
	}
	public static class SettingsManager
	{
		private static SettingsData newData;

		public static SettingsData Data { get; private set; } = new SettingsData();


		public static void QueueUpdateSettings(SettingsData data)
		{
			newData = data;
		}

		public static void OnUpdate()
		{
			if (newData != null)
			{
				Data = newData;
				ServiceProvider.inst.eventEmitter.TriggerOnConfigChangedEvent_ThreadSafe(null, newData);
				newData = null;
			}
		}
	}
	public class TranslationService
	{
		public readonly ITranslation translation;

		public TranslationService()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			translation = (ITranslation)new HelperLanguagesFormatted((IDebugLogger)(object)Utils.logger);
		}

		public void LoadData()
		{
			translation.InitFromFile(Utils.GetRelativeModFilePath("langs.data"));
		}
	}
}
namespace peak_bepinex.Commands
{
	internal class AddBonusStamina : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "add_bonus_stamina";

		public bool Execute(IEnumerable<string> args)
		{
			float num = new CommandArgsReaderWrapper(args).ReadFloat();
			Character.localCharacter.AddExtraStamina(num);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class AddStamina : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "add_stamina";

		public bool Execute(IEnumerable<string> args)
		{
			float num = new CommandArgsReaderWrapper(args).ReadFloat();
			Character.localCharacter.AddStamina(num);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class DamageOnMouseClick : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "damage_on_mouse_click";

		public bool IsActive { get; private set; }

		private string PeriodicId => Id + "_period";

		public bool Execute(IEnumerable<string> args)
		{
			//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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float damage = commandArgsReaderWrapper.ReadFloat();
			IsActive = true;
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					ServiceProvider.inst.scheduleManager.RemovePeriodicTask(PeriodicId);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			ServiceProvider.inst.scheduleManager.NewPeriodicTask(new PeriodicTaskData
			{
				id = PeriodicId,
				periodInSec = 0f,
				periodicAction = delegate
				{
					if (IsActive)
					{
						Character localCharacter = Character.localCharacter;
						if (localCharacter.input.usePrimaryWasPressed || localCharacter.input.useSecondaryWasPressed)
						{
							localCharacter.refs.afflictions.AddStatus((STATUSTYPE)0, damage, false);
						}
					}
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class DamageOnJump : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "damage_on_jump";

		public bool IsActive { get; private set; }

		private string PeriodicId => Id + "_period";

		public bool Execute(IEnumerable<string> args)
		{
			//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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float damage = commandArgsReaderWrapper.ReadFloat();
			IsActive = true;
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					ServiceProvider.inst.scheduleManager.RemovePeriodicTask(PeriodicId);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			ServiceProvider.inst.scheduleManager.NewPeriodicTask(new PeriodicTaskData
			{
				id = PeriodicId,
				periodInSec = 0f,
				periodicAction = delegate
				{
					if (IsActive)
					{
						Character localCharacter = Character.localCharacter;
						if (localCharacter.input.jumpWasPressed)
						{
							localCharacter.refs.afflictions.AddStatus((STATUSTYPE)0, damage, false);
						}
					}
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class SlipperyPlayer : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "slippery_player";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			Dictionary<BodypartType, Bodypart> partDict = localCharacter.refs.ragdoll.partDict;
			Rigidbody rig = partDict[(BodypartType)16].Rig;
			Rigidbody rig2 = partDict[(BodypartType)13].Rig;
			Rigidbody rig3 = partDict[(BodypartType)0].Rig;
			Rigidbody rig4 = partDict[(BodypartType)4].Rig;
			localCharacter.RPCA_Fall(2f);
			Vector3 val = (localCharacter.data.lookDirection_Flat + Vector3.up) * 200f;
			rig.AddForce(val, (ForceMode)1);
			rig2.AddForce(val, (ForceMode)1);
			rig3.AddForce(Vector3.up * 1500f, (ForceMode)1);
			rig4.AddForce(localCharacter.data.lookDirection_Flat * -300f, (ForceMode)1);
			Vector3 pos = localCharacter.Center;
			PlaySound(in pos);
			return true;
		}

		private void PlaySound(in Vector3 pos)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			SlipperyJellyfish val = Object.FindFirstObjectByType<SlipperyJellyfish>();
			if (!((Object)(object)val == (Object)null) && val.slipSFX != null)
			{
				for (int i = 0; i < val.slipSFX.Length; i++)
				{
					val.slipSFX[i].Play(pos);
				}
			}
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class LockCamera : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "lock_camera";

		public bool IsActive { get; private set; }

		private string PeriodicId => Id + "_period";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			float durationInSec = new CommandArgsReaderWrapper(args).ReadFloat();
			IsActive = true;
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					Character.localCharacter.data.usingBackpackWheel = false;
					ServiceProvider.inst.scheduleManager.RemovePeriodicTask(PeriodicId);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			ServiceProvider.inst.scheduleManager.NewPeriodicTask(new PeriodicTaskData
			{
				id = PeriodicId,
				periodInSec = 0.005f,
				periodicAction = delegate
				{
					if (IsActive)
					{
						Character.localCharacter.data.usingBackpackWheel = true;
					}
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class RandomizeOutfitPeriodically : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "randomize_outfit_periodically";

		public bool IsActive { get; private set; }

		private string PeriodicId => Id + "_period";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float periodInSec = commandArgsReaderWrapper.ReadFloat();
			IsActive = true;
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					ServiceProvider.inst.scheduleManager.RemovePeriodicTask(PeriodicId);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			ServiceProvider.inst.scheduleManager.NewPeriodicTask(new PeriodicTaskData
			{
				id = PeriodicId,
				periodInSec = periodInSec,
				periodicAction = delegate
				{
					CharacterCustomization customization = Character.localCharacter.refs.customization;
					customization.SetRandomEyes();
					customization.SetRandomMouth();
					customization.SetRandomAccessory();
					customization.SetRandomOutfit();
					customization.SetRandomHat();
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class RandomizeColorPeriodically : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "randomize_color_periodically";

		public bool IsActive { get; private set; }

		private string PeriodicId => Id + "_period";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float periodInSec = commandArgsReaderWrapper.ReadFloat();
			IsActive = true;
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					ServiceProvider.inst.scheduleManager.RemovePeriodicTask(PeriodicId);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			ServiceProvider.inst.scheduleManager.NewPeriodicTask(new PeriodicTaskData
			{
				id = PeriodicId,
				periodInSec = periodInSec,
				periodicAction = delegate
				{
					Character.localCharacter.refs.customization.SetRandomSkinColor();
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class RemoveTicks : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "remove_ticks";

		public bool Execute(IEnumerable<string> args)
		{
			Bugfix[] array = Object.FindObjectsOfType<Bugfix>();
			((HelperLog)Utils.logger).LogInfo((object)$"Found ticks: {array?.Length}");
			if (array == null || array.Length == 0)
			{
				return false;
			}
			Character ch = Character.localCharacter;
			array = array.Where((Bugfix tick) => (Object)(object)Traverse.Create((object)tick).Field<Character>("targetCharacter").Value == (Object)(object)ch).ToArray();
			((HelperLog)Utils.logger).LogInfo((object)$"Filtered ticks: {array.Length}");
			Bugfix[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				Traverse.Create((object)array2[i]).Field<PhotonView>("photonView").Value.RPC("RPCA_Remove", (RpcTarget)0, Array.Empty<object>());
			}
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ClearPlayerStatus : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "clear_status";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			STATUSTYPE val = GameUtils.NameToPlayerStatusType(new CommandArgsReaderWrapper(args).ReadString());
			Character.localCharacter.refs.afflictions.SetStatus(val, 0f);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ClearPlayerStatuses : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "clear_statuses";

		public bool Execute(IEnumerable<string> args)
		{
			Character.localCharacter.refs.afflictions.ClearAllStatus(false);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ApplyForceToPlayer_UpWay : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "apply_force_to_player_up";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float num = commandArgsReaderWrapper.ReadFloat(1000f);
			int num2 = commandArgsReaderWrapper.ReadInt(1);
			Vector3 dir = GameUtils.GetLocalPlayerUpWay() * (float)num2 * num;
			GameUtils.ApplyForceToLocalPlayer(in dir);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ApplyForceToPlayer_ForwardWay : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "apply_force_to_player_forward";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float num = commandArgsReaderWrapper.ReadFloat(1000f);
			int num2 = commandArgsReaderWrapper.ReadInt(1);
			Vector3 dir = GameUtils.GetLocalPlayerForwardWay() * (float)num2 * num;
			GameUtils.ApplyForceToLocalPlayer(in dir);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ApplyForceToPlayer_RightWay : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "apply_force_to_player_right";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float num = commandArgsReaderWrapper.ReadFloat(1000f);
			int num2 = commandArgsReaderWrapper.ReadInt(1);
			Vector3 dir = GameUtils.GetLocalPlayerRightWay() * (float)num2 * num;
			GameUtils.ApplyForceToLocalPlayer(in dir);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ApplyForceToPlayer : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "apply_force_to_player";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float num = commandArgsReaderWrapper.ReadFloat();
			float num2 = commandArgsReaderWrapper.ReadFloat();
			float num3 = commandArgsReaderWrapper.ReadFloat();
			Vector3 dir = new Vector3(num, num2, num3);
			GameUtils.ApplyForceToLocalPlayer(in dir);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ChangeWind : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "change_wind";

		public bool Execute(IEnumerable<string> args)
		{
			string text = new CommandArgsReaderWrapper(args).ReadString();
			if (!(text == "start"))
			{
				if (text == "stop")
				{
					SetWindStatus(enable: false);
					return true;
				}
				((HelperLog)Utils.logger).LogWarning((object)"undefined wind status. Will use 'start'.");
				SetWindStatus(enable: true);
				return true;
			}
			SetWindStatus(enable: true);
			return true;
		}

		private void SetWindStatus(bool enable)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			WindChillZone val = Object.FindFirstObjectByType<WindChillZone>();
			if ((Object)(object)val == (Object)null)
			{
				((HelperLog)Utils.logger).LogWarning((object)"Can't find wind manager");
				return;
			}
			Traverse obj = Traverse.Create((object)val);
			Vector3 randomDirection = GetRandomDirection();
			obj.Method("RPCA_ToggleWind", new object[2] { enable, randomDirection }).GetValue();
		}

		private Vector3 GetRandomDirection()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			int randomSign = MathUtility.GetRandomSign();
			float num = Random.Range(0.25f, 0.5f);
			Vector3 val = Vector3.Lerp(Vector3.left * (float)randomSign, Vector3.forward, num);
			return ((Vector3)(ref val)).normalized;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class AddPlayerStatus : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "add_status";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			string name = commandArgsReaderWrapper.ReadString();
			float num = commandArgsReaderWrapper.ReadFloat();
			STATUSTYPE val = GameUtils.NameToPlayerStatusType(name);
			Character.localCharacter.refs.afflictions.AddStatus(val, num, false);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class RandomizeCustomization : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "randomize_cosmetics";

		public bool Execute(IEnumerable<string> args)
		{
			Character.localCharacter.refs.customization.RandomizeCosmetics();
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class PlayEmote : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "play_emote";

		public bool Execute(IEnumerable<string> args)
		{
			string text = new CommandArgsReaderWrapper(args).ReadString();
			((HelperLog)Utils.logger).LogInfo((object)("try to play emote '" + text + "'"));
			if (text == "random")
			{
				text = GetRandomEmote();
				((HelperLog)Utils.logger).LogInfo((object)("random selected '" + text + "'"));
			}
			Traverse.Create((object)Character.localCharacter.refs.animations).Method("PlayEmote", new object[1] { text }).GetValue();
			return true;
		}

		private string GetRandomEmote()
		{
			return UtilityRandom.GetRandomItemFromList<string>((IList<string>)new string[8] { "A_Scout_Emote_Salute", "A_Scout_Emote_Dance1", "A_Scout_Emote_CrossedArms", "A_Scout_Emote_Shrug", "A_Scout_Emote_Flex", "A_Scout_Emote_Nono", "A_Scout_Emote_Think", "A_Scout_Emote_ThumbsUp" });
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class DropBackpack : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "drop_backpack";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			float num = new CommandArgsReaderWrapper(args).ReadFloat();
			Transform transform = ((Component)GameUtils.GetCharacterBodypart((BodypartType)0)).transform;
			Vector3 val = transform.position + transform.forward * num;
			((MonoBehaviourPun)Character.localCharacter).photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2]
			{
				(byte)3,
				val
			});
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class AddTick : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "add_tick";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			int num = new CommandArgsReaderWrapper(args).ReadInt(1);
			int viewID = ((MonoBehaviourPun)Character.localCharacter).photonView.ViewID;
			for (int i = 0; i < num; i++)
			{
				PhotonNetwork.Instantiate("BugfixOnYou", Vector3.zero, Quaternion.identity, (byte)0, (object[])null).GetComponent<PhotonView>().RPC("AttachBug", (RpcTarget)0, new object[1] { viewID });
			}
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class DropRandomInvetoryItem : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "drop_random_inventory_item";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			float num = new CommandArgsReaderWrapper(args).ReadFloat(0.6f);
			Character ch = Character.localCharacter;
			List<ItemSlot> list = (from i in Enumerable.Range(0, 3)
				select ch.player.GetItemSlot((byte)i) into slot
				where slot != null && !slot.IsEmpty()
				select slot).ToList();
			if (list.Count == 0)
			{
				((HelperLog)Utils.logger).LogInfo((object)"Inventory items not found.");
				return true;
			}
			byte itemSlotID = UtilityRandom.GetRandomItemFromList<ItemSlot>((IList<ItemSlot>)list).itemSlotID;
			((HelperLog)Utils.logger).LogInfo((object)$"target slot: {itemSlotID}");
			Optionable<byte> currentSelectedSlot = ch.refs.items.currentSelectedSlot;
			if (currentSelectedSlot.IsSome && currentSelectedSlot.Value == itemSlotID)
			{
				DropItemInHands.DropItem(0.2f);
			}
			Transform transform = ((Component)GameUtils.GetCharacterBodypart((BodypartType)0)).transform;
			Vector3 val = transform.position + transform.forward * num;
			((MonoBehaviourPun)ch).photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { itemSlotID, val });
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class DropInvetoryItems : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "drop_inventory_items";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float num = commandArgsReaderWrapper.ReadFloat(0.6f);
			float num2 = commandArgsReaderWrapper.ReadFloat(0.5f);
			DropItemInHands.DropItem(0.2f);
			Character localCharacter = Character.localCharacter;
			Transform transform = ((Component)GameUtils.GetCharacterBodypart((BodypartType)0)).transform;
			Vector3 val = transform.position + transform.forward * num;
			for (int i = 0; i <= 2; i++)
			{
				((MonoBehaviourPun)localCharacter).photonView.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2]
				{
					(byte)i,
					val
				});
				val += Vector3.up * num2;
			}
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class DropItemInHands : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "drop_item_in_hands";

		public bool Execute(IEnumerable<string> args)
		{
			return DropItem(new CommandArgsReaderWrapper(args).ReadFloat());
		}

		public static bool DropItem(float throwPower)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			CharacterItems items = localCharacter.refs.items;
			if (items.currentSelectedSlot.IsNone || (Object)(object)localCharacter.data.currentItem == (Object)null)
			{
				((HelperLog)Utils.logger).LogWarning((object)"DropItemInHands can't drop an item. Hands slot is empty.");
				return false;
			}
			byte value = items.currentSelectedSlot.Value;
			ItemSlot itemSlot = localCharacter.player.GetItemSlot(value);
			((MonoBehaviourPun)localCharacter).photonView.RPC("DropItemRpc", (RpcTarget)0, new object[6]
			{
				throwPower,
				value,
				((Component)localCharacter.data.currentItem).transform.position + Vector3.down * 0.2f,
				localCharacter.data.currentItem.rig.linearVelocity,
				((Component)localCharacter.data.currentItem).transform.rotation,
				itemSlot.data
			});
			items.throwChargeLevel = 0f;
			items.EquipSlot(Optionable<byte>.None);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class GravityPower : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		private bool isInitiated;

		private float defaultPower;

		public string Id => "gravity_power";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float num = commandArgsReaderWrapper.ReadFloat();
			CharacterMovement movement = Character.localCharacter.refs.movement;
			if (!isInitiated)
			{
				isInitiated = true;
				defaultPower = movement.maxGravity;
			}
			bool num2 = movement.maxGravity != num;
			movement.maxGravity = num;
			IsActive = true;
			TimerTaskData val = new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					Character localCharacter = Character.localCharacter;
					localCharacter.refs.movement.maxGravity = defaultPower;
					localCharacter.data.sinceGrounded = 0f;
					localCharacter.data.sinceJump = 0f;
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			};
			if (num2)
			{
				ServiceProvider.inst.scheduleManager.NewTimerTask(val, false);
			}
			else
			{
				ServiceProvider.inst.scheduleManager.AppendTimerTask(val, false);
			}
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class LockStatus : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "lock_status";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			float durationInSec = new CommandArgsReaderWrapper(args).ReadFloat();
			IsActive = true;
			ReflectionUtility.SetInternalProperty((object)Character.localCharacter, "statusesLocked", (object)true);
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					ReflectionUtility.SetInternalProperty((object)Character.localCharacter, "statusesLocked", (object)false);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class SpeedBonus : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		private string oldActivationKey;

		public string Id => "speed_bonus";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float modifierMove = commandArgsReaderWrapper.ReadFloat();
			float modifierClimb = commandArgsReaderWrapper.ReadFloat();
			float modifierRope = commandArgsReaderWrapper.ReadFloat();
			float modifierVine = commandArgsReaderWrapper.ReadFloat();
			string text = commandArgsReaderWrapper.ReadString();
			TimerTaskData val = new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					SetModifiers(Character.localCharacter, 0f - modifierMove, 0f - modifierClimb, 0f - modifierRope, 0f - modifierVine);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			};
			if (!IsActive || text != oldActivationKey)
			{
				IsActive = true;
				oldActivationKey = text;
				SetModifiers(Character.localCharacter, modifierMove, modifierClimb, modifierRope, modifierVine);
				ServiceProvider.inst.scheduleManager.NewTimerTask(val, true);
			}
			else
			{
				ServiceProvider.inst.scheduleManager.AppendTimerTask(val, true);
			}
			return true;
		}

		private void SetModifiers(Character ch, float modifierMove, float modifierClimb, float modifierRope, float modifierVine)
		{
			CharacterMovement movement = ch.refs.movement;
			movement.movementModifier += modifierMove;
			CharacterClimbing climbing = ch.refs.climbing;
			climbing.climbSpeedMod += modifierClimb;
			CharacterRopeHandling ropeHandling = ch.refs.ropeHandling;
			ropeHandling.climbSpeedMod += modifierRope;
			CharacterVineClimbing vineClimbing = ch.refs.vineClimbing;
			vineClimbing.climbSpeedMod += modifierVine;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class JumpPower : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		private bool isInitiated;

		private float defaultJumpGravity;

		public string Id => "jump_power";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat();
			float num = commandArgsReaderWrapper.ReadFloat();
			CharacterMovement movement = Character.localCharacter.refs.movement;
			if (!isInitiated)
			{
				isInitiated = true;
				defaultJumpGravity = movement.jumpGravity;
			}
			bool num2 = movement.jumpGravity != num;
			movement.jumpGravity = num;
			IsActive = true;
			TimerTaskData val = new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					Character.localCharacter.refs.movement.jumpGravity = defaultJumpGravity;
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			};
			if (num2)
			{
				ServiceProvider.inst.scheduleManager.NewTimerTask(val, false);
			}
			else
			{
				ServiceProvider.inst.scheduleManager.AppendTimerTask(val, false);
			}
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class InfiniteStamina : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		public string Id => "infinite_stamina";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			float durationInSec = new CommandArgsReaderWrapper(args).ReadFloat();
			IsActive = true;
			Character.localCharacter.data.currentStamina = 1f;
			Traverse.Create((object)Character.localCharacter).Property("infiniteStam", (object[])null).SetValue((object)true);
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					Traverse.Create((object)Character.localCharacter).Property("infiniteStam", (object[])null).SetValue((object)false);
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			return true;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal abstract class MouseInvertBase : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		protected OffOnMode oldMouseMode;

		protected bool needStoreOldSettings = true;

		public abstract string Id { get; }

		public bool IsActive { get; private set; }

		protected abstract OffOnSetting SettingObject { get; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			float durationInSec = new CommandArgsReaderWrapper(args).ReadFloat(30f);
			OffOnSetting settingObject = SettingObject;
			if (needStoreOldSettings)
			{
				oldMouseMode = ((EnumSetting<OffOnMode>)(object)settingObject).Value;
				needStoreOldSettings = false;
			}
			ReflectionUtility.SetInternalProperty((object)settingObject, "Value", (object)Inverted(oldMouseMode));
			IsActive = true;
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					IsActive = false;
					ReflectionUtility.SetInternalProperty((object)SettingObject, "Value", (object)oldMouseMode);
					needStoreOldSettings = true;
				}
			}, true);
			return true;
		}

		private static OffOnMode Inverted(OffOnMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)mode == 1)
			{
				return (OffOnMode)0;
			}
			return (OffOnMode)1;
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ChangeMouseSens : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		private float oldMouseSens;

		private float oldConstrollerSens;

		private float lastMouseCommandSens;

		private bool needStoreOldSettings = true;

		public string Id => "change_mouse_move_sens";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//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)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			float durationInSec = commandArgsReaderWrapper.ReadFloat(30f);
			float num = commandArgsReaderWrapper.ReadFloat(2.5f);
			float num2 = commandArgsReaderWrapper.ReadFloat(2.5f);
			FloatSetting mouseSetting = GetMouseSetting();
			FloatSetting controllerSetting = GetControllerSetting();
			if (needStoreOldSettings)
			{
				oldMouseSens = mouseSetting.Value;
				oldConstrollerSens = controllerSetting.Value;
				needStoreOldSettings = false;
			}
			ReflectionUtility.SetInternalProperty((object)mouseSetting, "Value", (object)num);
			ReflectionUtility.SetInternalProperty((object)controllerSetting, "Value", (object)num2);
			TimerTaskData val = new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					ReflectionUtility.SetInternalProperty((object)GetMouseSetting(), "Value", (object)oldMouseSens);
					ReflectionUtility.SetInternalProperty((object)GetControllerSetting(), "Value", (object)oldConstrollerSens);
					needStoreOldSettings = true;
				}
			};
			if (lastMouseCommandSens != num)
			{
				if (IsActive)
				{
					((HelperLog)Utils.logger).LogInfo((object)"ChangeMouseSens reset timer");
				}
				ServiceProvider.inst.scheduleManager.NewTimerTask(val, false);
			}
			else
			{
				ServiceProvider.inst.scheduleManager.AppendTimerTask(val, true);
			}
			IsActive = true;
			lastMouseCommandSens = num;
			return true;
		}

		private FloatSetting GetMouseSetting()
		{
			return (FloatSetting)(object)GameHandler.Instance.SettingsHandler.GetSetting<MouseSensitivitySetting>();
		}

		private FloatSetting GetControllerSetting()
		{
			return (FloatSetting)(object)GameHandler.Instance.SettingsHandler.GetSetting<ControllerSensitivitySetting>();
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class MouseInvertY : MouseInvertBase
	{
		public override string Id => "mouse_invert_y";

		protected override OffOnSetting SettingObject => (OffOnSetting)(object)GameHandler.Instance.SettingsHandler.GetSetting<InvertYSetting>();
	}
	internal class MouseInvertX : MouseInvertBase
	{
		public override string Id => "mouse_invert_x";

		protected override OffOnSetting SettingObject => (OffOnSetting)(object)GameHandler.Instance.SettingsHandler.GetSetting<InvertXSetting>();
	}
	internal class RunGameConsoleCommand : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "console_cmd";

		public bool Execute(IEnumerable<string> args)
		{
			GameUtils.RunGameConsoleCommand(new CommandArgsReaderWrapper(args).ReadAllAsSingleString());
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class GiveItem : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "give_item";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			CommandArgsReaderWrapper commandArgsReaderWrapper = new CommandArgsReaderWrapper(args);
			string s = commandArgsReaderWrapper.ReadAllAsSingleString();
			string[] array = commandArgsReaderWrapper.ParseList(s);
			if (array == null || array.Length == 0)
			{
				((HelperLog)Utils.logger).LogWarning((object)"GiveItem found empty item list");
			}
			if (!PhotonNetwork.IsConnected)
			{
				return false;
			}
			Character localCharacter = Character.localCharacter;
			string randomItemFromList = UtilityRandom.GetRandomItemFromList<string>((IList<string>)array);
			PhotonNetwork.Instantiate("0_Items/" + randomItemFromList, localCharacter.Head + Vector3.up, Quaternion.identity, (byte)0, (object[])null).GetComponent<Item>().RequestPickup(((Component)localCharacter).GetComponent<PhotonView>());
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class ShufflePlayerMovement : IInternalStandaloneCommand, IConsoleCommand, IForceEnd
	{
		private readonly string[] ways = new string[4] { "up", "down", "left", "right" };

		public string Id => "shuffle_player_movement";

		public bool IsActive { get; private set; }

		public bool Execute(IEnumerable<string> args)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			float durationInSec = new CommandArgsReaderWrapper(args).ReadFloat();
			ServiceProvider.inst.scheduleManager.AppendTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = durationInSec,
				finishAction = delegate
				{
					IsActive = false;
					RestoreInput();
					((HelperLog)Utils.logger).LogInfo((object)(Id + " ends"));
				}
			}, false);
			if (ShuffleBinds())
			{
				IsActive = true;
				return true;
			}
			return false;
		}

		private bool ShuffleBinds()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			InputAction action_move = CharacterInput.action_move;
			List<InputBinding>[] array = new List<InputBinding>[4];
			foreach (InputBinding item in ((IEnumerable<InputBinding>)(object)action_move.bindings).Where((InputBinding b) => ways.Contains(((InputBinding)(ref b)).name)))
			{
				InputBinding bind = item;
				if (ways[0] == ((InputBinding)(ref bind)).name)
				{
					AddBind(array, 0, in bind);
				}
				else if (ways[1] == ((InputBinding)(ref bind)).name)
				{
					AddBind(array, 1, in bind);
				}
				else if (ways[2] == ((InputBinding)(ref bind)).name)
				{
					AddBind(array, 2, in bind);
				}
				else if (ways[3] == ((InputBinding)(ref bind)).name)
				{
					AddBind(array, 3, in bind);
				}
			}
			SwapBinds(action_move, array[0], array[1]);
			SwapBinds(action_move, array[2], array[3]);
			return true;
		}

		private void AddBind(List<InputBinding>[] bindings, int index, in InputBinding bind)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (bindings[index] == null)
			{
				bindings[index] = new List<InputBinding> { bind };
			}
			else
			{
				bindings[index].Add(bind);
			}
		}

		private void SwapBinds(InputAction action, List<InputBinding> bindList1, List<InputBinding> bindList2)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if (bindList1 == null || bindList2 == null)
			{
				((HelperLog)Utils.logger).LogError((object)"SwapBinds got null bind list");
				return;
			}
			for (int i = 0; i < bindList1.Count && i < bindList2.Count; i++)
			{
				InputBinding val = bindList1[i];
				InputBinding val2 = bindList2[i];
				((HelperLog)Utils.logger).LogInfo((object)("rebind " + ((InputBinding)(ref val)).name + " from " + ((InputBinding)(ref val)).path + " to " + ((InputBinding)(ref val2)).path));
				((HelperLog)Utils.logger).LogInfo((object)("rebind " + ((InputBinding)(ref val2)).name + " from " + ((InputBinding)(ref val2)).path + " to " + ((InputBinding)(ref val)).path));
				((InputBinding)(ref val)).overridePath = ((InputBinding)(ref val2)).path;
				((InputBinding)(ref val2)).overridePath = ((InputBinding)(ref val)).path;
				InputActionRebindingExtensions.ApplyBindingOverride(action, val);
				InputActionRebindingExtensions.ApplyBindingOverride(action, val2);
			}
		}

		private void RestoreInput()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			InputAction action_move = CharacterInput.action_move;
			InputBinding[] array = ((IEnumerable<InputBinding>)(object)action_move.bindings).Where((InputBinding b) => ways.Contains(((InputBinding)(ref b)).name)).ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				InputBinding val = array[i];
				((InputBinding)(ref val)).overridePath = null;
				((HelperLog)Utils.logger).LogInfo((object)("reset bind " + ((InputBinding)(ref val)).name + " to " + ((InputBinding)(ref val)).path));
				InputActionRebindingExtensions.ApplyBindingOverride(action_move, val);
			}
		}

		public void ForceEnd()
		{
			ServiceProvider.inst.scheduleManager.FinishImmediatlyTimerTask(Id);
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class TeleportAllPlayersToShrine : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "teleport_all_to_shrine";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			if (ServiceProvider.inst.scheduleManager.IsTaskExists(Id))
			{
				((HelperLog)Utils.logger).LogWarning((object)(Id + " spams too much. Old teleport is not finished"));
				return true;
			}
			Character ch = Character.localCharacter;
			RespawnChest closestObject = GameUtils.GetClosestObject<RespawnChest>(ch.Center, (Func<RespawnChest, bool>)((RespawnChest obj) => obj.IsInteractible(ch)), needLog: true);
			if ((Object)(object)closestObject == (Object)null)
			{
				((HelperLog)Utils.logger).LogWarning((object)(Id + " can't find not used Shrine. Skip teleporting."));
				return false;
			}
			Vector3 val = ((Luggage)closestObject).Center();
			Vector3 forward = ((Component)closestObject).transform.forward;
			Vector3 shrinePos = val + ((Vector3)(ref forward)).normalized * 2f;
			ServiceProvider.inst.scheduleManager.NewTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = 1f,
				finishAction = delegate
				{
					Character[] array = GameUtils.AlivePlayers.ToArray();
					for (int i = 0; i < array.Length; i++)
					{
						GameUtils.TeleportPlayer(array[i], in shrinePos);
					}
				}
			}, false);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class TeleportToRandomPlayer : IInternalStandaloneCommand, IConsoleCommand
	{
		[CompilerGenerated]
		private sealed class <TeleportPosFinder>d__6 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public int triggerCount;

			public Character target;

			public TeleportToRandomPlayer <>4__this;

			private List<Vector3> <posList>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TeleportPosFinder>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<posList>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0049: 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)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//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_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TeleportToRandomPlayer teleportToRandomPlayer = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<posList>5__2 = new List<Vector3>();
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (triggerCount > 0)
				{
					int num2 = triggerCount - 1;
					triggerCount = num2;
					Vector3 val = target.Center + Vector3.up * (target.data.currentHeadHeight + 1.5f);
					<posList>5__2.Add(val);
					if (triggerCount % 10 == 0)
					{
						((HelperLog)Utils.logger).LogInfo((object)$"found pos {val}");
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (<posList>5__2.Count == 0)
				{
					((HelperLog)Utils.logger).LogError((object)"positions is not found");
					teleportToRandomPlayer.teleportEnds = true;
					return false;
				}
				Vector3 pos = <posList>5__2.Aggregate((Vector3 max, Vector3 next) => (!(next.y > max.y)) ? max : next);
				((HelperLog)Utils.logger).LogInfo((object)$"selected pos {pos}");
				GameUtils.TeleportPlayer(Character.localCharacter, in pos);
				teleportToRandomPlayer.teleportEnds = true;
				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 const float DELAY = 0.5f;

		private DateTime lastTriggerTime = DateTime.MinValue;

		private bool teleportEnds = true;

		public string Id => "teleport_to_random_player";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			if (!teleportEnds && (DateTime.Now - lastTriggerTime).TotalSeconds < 1.5)
			{
				((HelperLog)Utils.logger).LogWarning((object)(Id + " spams too much. Old teleport is not finished"));
				return true;
			}
			teleportEnds = false;
			lastTriggerTime = DateTime.Now;
			ServiceProvider.inst.scheduleManager.NewTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = 0.5f,
				finishAction = delegate
				{
					//IL_0099: Unknown result type (might be due to invalid IL or missing references)
					Character[] source = GameUtils.AlivePlayers.ToArray();
					Character ch = Character.localCharacter;
					Character[] array = source.Where((Character p) => (Object)(object)p != (Object)(object)ch).ToArray();
					if (array.Length == 0)
					{
						((HelperLog)Utils.logger).LogWarning((object)(Id + " can't apply teleport, other players doesn't found"));
						teleportEnds = true;
					}
					else
					{
						Character randomItemFromList = UtilityRandom.GetRandomItemFromList<Character>((IList<Character>)array);
						((HelperLog)Utils.logger).LogInfo((object)$"{Id} found otherPlayers {array.Length}, target {randomItemFromList.characterName}, base pos {ch.data.groundPos}");
						((MonoBehaviour)ch).StartCoroutine(TeleportPosFinder(randomItemFromList, 60));
					}
				}
			}, false);
			return true;
		}

		[IteratorStateMachine(typeof(<TeleportPosFinder>d__6))]
		private IEnumerator TeleportPosFinder(Character target, int triggerCount)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TeleportPosFinder>d__6(0)
			{
				<>4__this = this,
				target = target,
				triggerCount = triggerCount
			};
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
	internal class TeleportShufflePlayers : IInternalStandaloneCommand, IConsoleCommand
	{
		public string Id => "teleport_shuffle_players";

		public bool Execute(IEnumerable<string> args)
		{
			//IL_003d: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			if (ServiceProvider.inst.scheduleManager.IsTaskExists(Id))
			{
				((HelperLog)Utils.logger).LogWarning((object)(Id + " spams too much. Old teleport is not finished"));
				return true;
			}
			ServiceProvider.inst.scheduleManager.NewTimerTask(new TimerTaskData
			{
				id = Id,
				durationInSec = 1f,
				finishAction = delegate
				{
					//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
					List<Character> list = GameUtils.AlivePlayers.ToList();
					if (list.Count <= 1)
					{
						((HelperLog)Utils.logger).LogWarning((object)(Id + " can't apply teleport, other players doesn't found"));
					}
					else
					{
						List<Vector3> list2 = Utils.ShuffleForceRandom(list.Select((Character p) => p.Center));
						((HelperLog)Utils.logger).LogInfo((object)$"{Id} found {list.Count} players and {list2.Count} positions");
						if (list2.Count != list.Count)
						{
							((HelperLog)Utils.logger).LogError((object)(Id + " wrong arr sizes"));
						}
						else
						{
							for (int i = 0; i < list.Count; i++)
							{
								Character player = list[i];
								Vector3 pos = list2[i];
								GameUtils.TeleportPlayer(player, in pos);
							}
						}
					}
				}
			}, false);
			return true;
		}

		public bool IsValidCommandArgs(IEnumerable<string> args)
		{
			throw new NotImplementedException();
		}
	}
}
namespace peak_bepinex.Commands.Interfaces
{
	public interface INetworkCommand : IConsoleCommand
	{
	}
	public interface IInternalStandaloneCommand : IConsoleCommand
	{
	}
	public interface IInternalStandaloneCommandWithData : IInternalStandaloneCommand, IConsoleCommand, IConsoleCommandWithData
	{
	}
	public interface IForceEnd : IInternalStand

ChaosTricks_PEAK_plugins/ModHelper.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using EventsIO;
using EventsIO.Interfaces;
using ModHelper.Interfaces;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ModHelper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BFT")]
[assembly: AssemblyProduct("ModHelper")]
[assembly: AssemblyCopyright("Copyright ©  2020")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8d858f35-342c-4916-8e50-2b2cfd18640d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ModHelper
{
	public class CommandArgsValidator
	{
		private readonly ILogger logger;

		public CommandArgsValidator(ILogger logger)
		{
			this.logger = logger;
		}

		public bool IsZeroArgs(IEnumerable<string> args)
		{
			int num = args?.Count() ?? 0;
			if (num != 0)
			{
				logger?.LogWarning($"CommandArgsValidator wrong args count {num} (must be 0)");
				return false;
			}
			return true;
		}

		public bool IsZeroArgs(IEnumerator<string> args)
		{
			if (args == null || !args.MoveNext())
			{
				return true;
			}
			logger?.LogWarning("CommandArgsValidator wrong args count (more than needed)");
			return false;
		}

		private bool IsInvalidArgsCount(IEnumerator<string> args)
		{
			if (args != null)
			{
				return !args.MoveNext();
			}
			return true;
		}

		public bool IsValidInt(IEnumerator<string> args, int minValue, int maxValue, bool isSkippable = false)
		{
			if (IsInvalidArgsCount(args))
			{
				if (isSkippable)
				{
					return true;
				}
				logger?.LogWarning("CommandArgsValidator wrong args count");
				return false;
			}
			try
			{
				int num = int.Parse(args.Current);
				if (num < minValue || num > maxValue)
				{
					string obj = $"CommandArgsValidator wrong integer value {num} (must be in range from {minValue} to {maxValue})";
					logger?.LogWarning(obj);
					return false;
				}
			}
			catch (Exception arg)
			{
				logger?.LogWarning($"CommandArgsValidator can't parse integer value from '{args.Current}', {arg}");
				return false;
			}
			return true;
		}

		public bool IsValidFloat(IEnumerator<string> args, float minValue, float maxValue, bool isSkippable = false)
		{
			if (IsInvalidArgsCount(args))
			{
				if (isSkippable)
				{
					return true;
				}
				logger?.LogWarning("CommandArgsValidator wrong args count");
				return false;
			}
			try
			{
				float num = float.Parse(args.Current, CultureInfo.InvariantCulture.NumberFormat);
				if (num < minValue || num > maxValue)
				{
					string obj = $"CommandArgsValidator wrong float value {num} (must be in range from {minValue} to {maxValue})";
					logger?.LogWarning(obj);
					return false;
				}
			}
			catch (Exception arg)
			{
				logger?.LogWarning($"CommandArgsValidator can't parse float value from '{args.Current}', {arg}");
			}
			return true;
		}

		public bool IsValidString(IEnumerator<string> args, Func<string, bool> validator, bool isSkippable = false)
		{
			if (IsInvalidArgsCount(args))
			{
				if (isSkippable)
				{
					return true;
				}
				logger?.LogWarning("CommandArgsValidator wrong args count");
				return false;
			}
			if (validator == null || validator(args.Current))
			{
				return true;
			}
			logger?.LogWarning("CommandArgsValidator wrong string value " + args.Current);
			return false;
		}

		public bool IsValidBool(IEnumerator<string> args, bool isSkippable = false)
		{
			if (IsInvalidArgsCount(args))
			{
				if (isSkippable)
				{
					return true;
				}
				logger?.LogWarning("CommandArgsValidator wrong args count");
				return false;
			}
			try
			{
				bool.Parse(args.Current.ToLower());
			}
			catch (Exception arg)
			{
				logger?.LogWarning($"CommandArgsValidator can't parse bool value from '{args.Current}', {arg}");
				return false;
			}
			return true;
		}
	}
	public class PeriodicTaskData
	{
		public string id;

		public float periodInSec;

		internal float periodCalculatedInSec;

		public int triggerTimes;

		public bool isInfiniteRepeates = true;

		public Action periodicAction;

		public Action finishAction;

		public override string ToString()
		{
			return "id=" + id + ", " + $"period={periodInSec}s, " + $"calc_period={periodCalculatedInSec}s, " + $"triggerTimes={triggerTimes}, " + $"isInfiniteRepeates={isInfiniteRepeates}";
		}
	}
	public class TimerTaskData
	{
		public string id;

		public float durationInSec;

		public Action finishAction;

		public override string ToString()
		{
			return $"id={id}, duration={durationInSec}s";
		}
	}
	public class BufferedLogger : HelperDebugLog, IDisposable
	{
		protected readonly Queue<string> queue;

		protected readonly int bufferRecordsCount;

		private bool isDisposed;

		public BufferedLogger(string folderPath = null, string logFileName = null, bool isDebug = false, int bufferRecordsCount = 10)
			: base(folderPath, logFileName, isDebug)
		{
			this.bufferRecordsCount = bufferRecordsCount;
			queue = new Queue<string>();
		}

		public virtual void Flush(bool isNeedClearQueue = false)
		{
			if (queue.Count != 0)
			{
				WriteToFile(string.Join("\n", queue.ToArray()));
				if (isNeedClearQueue)
				{
					queue.Clear();
				}
			}
		}

		public override void Log(object obj)
		{
			if (obj != null && isLogFile)
			{
				queue.Enqueue($"{LogTime} {obj}");
				if (queue.Count >= bufferRecordsCount)
				{
					Flush(isNeedClearQueue: true);
				}
			}
		}

		protected virtual void Dispose(bool isDisposing)
		{
			if (!isDisposed)
			{
				isDisposed = true;
				if (queue.Count > 0)
				{
					Flush();
				}
			}
		}

		public void Dispose()
		{
			Dispose(isDisposing: true);
			GC.SuppressFinalize(this);
		}

		~BufferedLogger()
		{
			Dispose(isDisposing: false);
		}
	}
	public static class HelperGroups
	{
		public static Dictionary<string, List<string>> GenerateNewEmptyGroupsDict()
		{
			return new Dictionary<string, List<string>>(StringComparer.InvariantCultureIgnoreCase);
		}

		private static bool SafeApplyValidator(Func<string, bool> groupItemValidator, string itemName, ILogger logger = null)
		{
			try
			{
				return groupItemValidator?.Invoke(itemName) ?? true;
			}
			catch (Exception arg)
			{
				logger?.LogError($"RandomGroup.SafeApplyValidator unexpected error: {arg}");
			}
			return false;
		}

		public static void InitGroupsFromFiles(string dataDir, Dictionary<string, List<string>> groups, string groupsPrefix, Func<string, bool> groupItemValidator = null, IDebugLogger logger = null)
		{
			try
			{
				if (string.IsNullOrEmpty(groupsPrefix))
				{
					logger?.LogError("RandomGroup error: wrong groupsPrefix " + groupsPrefix);
					return;
				}
				string[] files = Directory.GetFiles(dataDir);
				foreach (string path in files)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					if (fileNameWithoutExtension.StartsWith(groupsPrefix))
					{
						groups[fileNameWithoutExtension] = GetItemsFromFile(path, logger);
					}
				}
				foreach (KeyValuePair<string, List<string>> group in groups)
				{
					logger?.LogDebugInfo("RandomGroup validate list " + group.Key + ":");
					List<string> list = new List<string>();
					foreach (string item in group.Value)
					{
						if (!SafeApplyValidator(groupItemValidator, item, logger))
						{
							logger?.LogWarning("invalid name " + item);
							list.Add(item);
						}
					}
					if (list.Count > 0)
					{
						foreach (string item2 in list)
						{
							group.Value.Remove(item2);
						}
						logger?.LogWarning("list " + group.Key + " is invalid");
					}
					else
					{
						logger?.LogDebugInfo("list " + group.Key + " is valid");
					}
				}
			}
			catch (Exception arg)
			{
				logger?.LogError($"RandomGroup.InitGroupsFromFiles unexpected error: {arg}");
			}
		}

		public static Dictionary<string, List<string>> GenerateGroupsFromFiles(string dataDir, string groupsPrefix, Func<string, bool> groupItemValidator = null, IDebugLogger logger = null)
		{
			Dictionary<string, List<string>> dictionary = GenerateNewEmptyGroupsDict();
			InitGroupsFromFiles(dataDir, dictionary, groupsPrefix, groupItemValidator, logger);
			return dictionary;
		}

		public static List<string> GetItemsFromFile(string path, IDebugLogger logger = null)
		{
			try
			{
				List<string> list = new HelperJson(logger).FromFile<List<string>>(path);
				if (list == null)
				{
					list = new List<string>();
				}
				logger?.LogInfo($"Items from file {path}: found {list.Count}");
				foreach (string item in list)
				{
					logger?.LogDebugInfo("value " + item);
				}
				return list;
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperGroups.GetItemsFromFile unexpected error: {arg}");
			}
			return new List<string>();
		}

		public static bool IsValidGroupName(Dictionary<string, List<string>> dict, string name)
		{
			return dict?.ContainsKey(name) ?? false;
		}

		public static void PrintGroups(Dictionary<string, List<string>> dict, ILogger logger, string groupsName = "default_name")
		{
			if (logger == null)
			{
				return;
			}
			if (dict == null || dict.Count == 0)
			{
				logger?.LogWarning("No groups found for " + groupsName);
				return;
			}
			logger?.LogInfo("---------------Groups " + groupsName + " list---------------");
			foreach (KeyValuePair<string, List<string>> item in dict)
			{
				logger?.LogInfo(item.Key ?? "");
			}
			logger?.LogInfo("---------------Groups " + groupsName + " list end---------------");
		}
	}
	public class HelperJson : IJsonUtil
	{
		private class ContainerObjAndInt
		{
			public object valueObj;

			public int valueInt;
		}

		private class ContainerStringAndInt
		{
			public string valueString;

			public int valueInt;
		}

		private ILogger logger;

		private const char startClass = '{';

		private const char endClass = '}';

		private const char startArray = '[';

		private const char endArray = ']';

		private const char isHasNextField = ',';

		private const char special = '\\';

		private const char startString = '"';

		private const char nameValueSeparator = ':';

		private char[] ignoreChars = new char[9] { ' ', '\n', '\r', '\t', '\b', '\f', '\0', '{', '[' };

		private string logMsgBaseError = "HelperJson error:";

		private string logMsgBase = "HelperJson:";

		private bool isVerboseDebugLog;

		private void VerboseDebugLog(string s)
		{
			if (isVerboseDebugLog)
			{
				logger?.LogInfo("[DEBUG] " + s);
			}
		}

		public HelperJson(IDebugLogger logger = null, bool isVerboseDebugLog = false)
		{
			this.logger = logger;
			this.isVerboseDebugLog = isVerboseDebugLog;
		}

		public T FromFile<T>(string path) where T : class
		{
			string s;
			using (StreamReader streamReader = new StreamReader(path))
			{
				s = streamReader.ReadToEnd();
			}
			return FromString<T>(s);
		}

		public T FromString<T>(string s) where T : class
		{
			return GetFromString(typeof(T), s, 0).valueObj as T;
		}

		private char GetSpecialChar(char c)
		{
			if (c != '"')
			{
				return c;
			}
			return c;
		}

		private void SetFieldClass<T, R>(T instance, string fieldName, R fieldValue) where T : class where R : class
		{
			Type type = instance.GetType();
			VerboseDebugLog("type=" + type.Name + ", field=" + fieldName);
			type.GetField(fieldName).SetValue(instance, fieldValue);
		}

		private ContainerStringAndInt ParseNextStringValue(string s, int index, bool isSkipSep = true)
		{
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			int i;
			for (i = index; i < s.Length; i++)
			{
				char c = s[i];
				VerboseDebugLog($"{logMsgBase} ParseNextStringValue for process {c}");
				if (!flag)
				{
					i = SkipIgnoredChars(s, i, isSkipHasNextField: false, isSkipSep);
					if (i >= s.Length)
					{
						logger?.Log(logMsgBaseError + " class field value parsing internal issue. Set default value.");
						break;
					}
					c = s[i];
					if (c == '"')
					{
						flag = true;
						VerboseDebugLog(logMsgBase + " ParseNextStringValue is startString case");
						continue;
					}
					if (c == ']' || c == '}')
					{
						break;
					}
					if (c == ',' || c == ':')
					{
						i = SkipIgnoredChars(s, i, isSkipHasNextField: true, isSkipSep);
						break;
					}
				}
				else if (c == '\\')
				{
					VerboseDebugLog(logMsgBase + " ParseNextStringValue is special case");
					i++;
					if (i >= s.Length)
					{
						logger?.Log(logMsgBaseError + " class field value parsing internal issue with special symbols. Set default value.");
						break;
					}
					c = GetSpecialChar(s[i]);
					if (c != '"')
					{
						stringBuilder.Append('\\');
					}
				}
				else if (c == '"')
				{
					VerboseDebugLog(logMsgBase + " ParseNextStringValue is startString end case");
					i = SkipIgnoredChars(s, ++i, isSkipHasNextField: true, isSkipSep);
					break;
				}
				VerboseDebugLog($"{logMsgBase} ParseNextStringValue append {c}");
				stringBuilder.Append(c);
			}
			string text = stringBuilder.ToString();
			VerboseDebugLog($"{logMsgBase} ParseNextStringValue {text}, end at index {i}");
			return new ContainerStringAndInt
			{
				valueString = text,
				valueInt = i
			};
		}

		private ContainerStringAndInt GetNextFieldName(string s, int index)
		{
			VerboseDebugLog(logMsgBase + " GetNextFieldName");
			return ParseNextStringValue(s, index, isSkipSep: false);
		}

		private ContainerObjAndInt GetNextValue(Type valueType, string s, int index, bool isSkipSep)
		{
			VerboseDebugLog(logMsgBase + " GetNextValue");
			int num = SkipIgnoredChars(s, index, isSkipHasNextField: true, isSkipSep);
			if (num >= s.Length)
			{
				logger?.LogError(logMsgBaseError + " class parsing internal issue at value type " + valueType.Name + ". Set default value.");
			}
			if (valueType.IsPrimitive)
			{
				ContainerStringAndInt containerStringAndInt = ParseNextStringValue(s, num, isSkipSep);
				try
				{
					TypeCode typeCode = Type.GetTypeCode(valueType);
					object valueObj;
					if ((uint)(typeCode - 5) <= 10u)
					{
						if (double.TryParse(containerStringAndInt.valueString, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
						{
							valueObj = Convert.ChangeType(result, valueType);
						}
						else
						{
							valueObj = Activator.CreateInstance(valueType);
							logger?.Log(logMsgBaseError + " incorrect convert, use default.");
							logger?.Log("Read value: " + containerStringAndInt.valueString + ", type: " + valueType.Name);
						}
					}
					else
					{
						valueObj = Convert.ChangeType(containerStringAndInt.valueString, valueType);
					}
					return new ContainerObjAndInt
					{
						valueObj = valueObj,
						valueInt = containerStringAndInt.valueInt
					};
				}
				catch (Exception arg)
				{
					logger?.Log($"{logMsgBaseError} incorrect format, use default. Msg: {arg}");
					logger?.Log("read value: " + containerStringAndInt.valueString + ", type: " + valueType.Name);
					return new ContainerObjAndInt
					{
						valueObj = Activator.CreateInstance(valueType),
						valueInt = containerStringAndInt.valueInt
					};
				}
			}
			if (valueType.IsAssignableFrom(typeof(string)))
			{
				ContainerStringAndInt containerStringAndInt2 = ParseNextStringValue(s, num, isSkipSep);
				return new ContainerObjAndInt
				{
					valueObj = containerStringAndInt2.valueString,
					valueInt = containerStringAndInt2.valueInt
				};
			}
			ContainerObjAndInt fromString = GetFromString(valueType, s, num);
			return new ContainerObjAndInt
			{
				valueObj = fromString.valueObj,
				valueInt = fromString.valueInt
			};
		}

		private int SkipIgnoredChars(string s, int index, bool isSkipHasNextField = false, bool isSkipSep = false)
		{
			for (int i = index; i < s.Length; i++)
			{
				if (ignoreChars.Contains(s[i]))
				{
					VerboseDebugLog($"skip char '{s[i]}'");
					continue;
				}
				if (isSkipHasNextField && s[i] == ',')
				{
					VerboseDebugLog($"skip char '{s[i]}'");
					continue;
				}
				if (isSkipSep && s[i] == ':')
				{
					VerboseDebugLog($"skip char '{s[i]}'");
					continue;
				}
				return i;
			}
			return s.Length;
		}

		private ContainerObjAndInt ParseIListByItemType(Type itemType, string s, int index)
		{
			if (!(Activator.CreateInstance(typeof(List<>).MakeGenericType(itemType)) is IList list))
			{
				logger?.LogError(logMsgBaseError + " can't create IList for item type " + itemType.Name);
				return new ContainerObjAndInt
				{
					valueObj = null,
					valueInt = s.Length
				};
			}
			do
			{
				ContainerObjAndInt nextValue = GetNextValue(itemType, s, index, isSkipSep: true);
				object valueObj = nextValue.valueObj;
				index = nextValue.valueInt;
				list.Add(valueObj);
				index = SkipIgnoredChars(s, index, isSkipHasNextField: true, isSkipSep: true);
			}
			while (index < s.Length && s[index] != ']' && s[index] != '}');
			return new ContainerObjAndInt
			{
				valueObj = list,
				valueInt = index + 1
			};
		}

		private ContainerObjAndInt ParseIList(Type resultType, string s, int index)
		{
			Type itemType = (resultType.IsGenericType ? resultType.GetGenericArguments()[0] : resultType.GetElementType());
			return ParseIListByItemType(itemType, s, index);
		}

		private ContainerObjAndInt ParseArray(Type resultType, string s, int index)
		{
			Type elementType = resultType.GetElementType();
			ContainerObjAndInt containerObjAndInt = ParseIListByItemType(elementType, s, index);
			Array array;
			if (containerObjAndInt.valueObj is IList list)
			{
				array = Array.CreateInstance(elementType, list.Count);
				for (int i = 0; i < array.Length; i++)
				{
					array.SetValue(list[i], i);
				}
			}
			else
			{
				logger?.Log(logMsgBaseError + " create empty Array");
				array = Array.CreateInstance(elementType, 0);
			}
			return new ContainerObjAndInt
			{
				valueObj = array,
				valueInt = containerObjAndInt.valueInt
			};
		}

		private ContainerObjAndInt ParseIDictionary(Type dictType, string s, int index)
		{
			Type[] genericArguments = dictType.GetGenericArguments();
			if (genericArguments.Length != 2)
			{
				logger?.Log(logMsgBaseError + " can't create IDictionary, invalid args");
			}
			if (dictType.IsGenericType)
			{
				if (!dictType.IsGenericTypeDefinition)
				{
					dictType = dictType.GetGenericTypeDefinition();
				}
				dictType = dictType.MakeGenericType(genericArguments);
			}
			if (!(Activator.CreateInstance(dictType) is IDictionary dictionary))
			{
				string name = dictType.GetType().Name;
				logger?.Log(logMsgBaseError + " can't create IDictionary " + name + " for item type " + genericArguments[0].Name + ", " + genericArguments[1].Name);
				return new ContainerObjAndInt
				{
					valueObj = null,
					valueInt = s.Length
				};
			}
			Type valueType = genericArguments[0];
			Type valueType2 = genericArguments[1];
			do
			{
				ContainerObjAndInt nextValue = GetNextValue(valueType, s, index, isSkipSep: false);
				index = nextValue.valueInt;
				ContainerObjAndInt nextValue2 = GetNextValue(valueType2, s, index, isSkipSep: true);
				index = nextValue2.valueInt;
				dictionary.Add(nextValue.valueObj, nextValue2.valueObj);
				VerboseDebugLog($"{logMsgBase} dict add key {nextValue.valueObj}");
				index = SkipIgnoredChars(s, index, isSkipHasNextField: true, isSkipSep: true);
			}
			while (index < s.Length && s[index] != '}' && s[index] != ']');
			return new ContainerObjAndInt
			{
				valueObj = dictionary,
				valueInt = index + 1
			};
		}

		private bool IsTypeOf(Type targetType, Type sourceType, int argsCount)
		{
			if (sourceType.IsAssignableFrom(targetType))
			{
				VerboseDebugLog(logMsgBase + " is " + targetType.Name);
				return true;
			}
			Type[] types = sourceType.Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (!type.IsClass)
				{
					continue;
				}
				Type[] interfaces = type.GetInterfaces();
				foreach (Type type2 in interfaces)
				{
					if (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == targetType && sourceType.GetGenericArguments().Length == argsCount)
					{
						VerboseDebugLog(logMsgBase + " is " + targetType.Name + " assembly interface");
						return true;
					}
				}
			}
			return false;
		}

		private ContainerObjAndInt GetFromString(Type resultType, string s, int index)
		{
			try
			{
				VerboseDebugLog(logMsgBase + " GetFromString");
				if (resultType.IsArray)
				{
					VerboseDebugLog(logMsgBase + " is array");
					return ParseArray(resultType, s, index);
				}
				if (resultType.IsAssignableFrom(typeof(IList)) || IsTypeOf(typeof(IList<>), resultType, 1))
				{
					return ParseIList(resultType, s, index);
				}
				if (resultType.IsAssignableFrom(typeof(IDictionary)) || IsTypeOf(typeof(IDictionary<, >), resultType, 2))
				{
					return ParseIDictionary(resultType, s, index);
				}
				if (resultType.IsGenericType && !resultType.IsGenericTypeDefinition)
				{
					Type[] genericArguments = resultType.GetGenericArguments();
					resultType = resultType.GetGenericTypeDefinition();
					resultType = resultType.MakeGenericType(genericArguments);
				}
				object obj = Activator.CreateInstance(resultType);
				int num = index;
				while (num < s.Length && s[num] != ']' && s[num] != '}')
				{
					ContainerStringAndInt nextFieldName = GetNextFieldName(s, num);
					string valueString = nextFieldName.valueString;
					if (string.IsNullOrEmpty(valueString?.Trim()))
					{
						VerboseDebugLog(logMsgBase + " IsNullOrWhiteSpace field " + valueString + ", class type " + resultType.Name);
						num = GetNextValue(typeof(string), s, num, isSkipSep: true).valueInt;
						continue;
					}
					num = nextFieldName.valueInt;
					FieldInfo field = resultType.GetField(valueString);
					VerboseDebugLog(logMsgBase + " field " + valueString + ", class type " + resultType.Name);
					if (isVerboseDebugLog)
					{
						FieldInfo[] fields = resultType.GetFields();
						VerboseDebugLog(logMsgBase + " fields in class: ");
						FieldInfo[] array = fields;
						foreach (FieldInfo fieldInfo in array)
						{
							VerboseDebugLog(fieldInfo.Name);
						}
					}
					if ((object)field == null)
					{
						logger?.LogWarning(logMsgBaseError + " can't find field " + valueString + " for type " + resultType.Name + ". Try to skip.");
						num = GetNextValue(typeof(string), s, num, isSkipSep: true).valueInt;
					}
					else
					{
						ContainerObjAndInt nextValue = GetNextValue(field.FieldType, s, num, isSkipSep: true);
						object valueObj = nextValue.valueObj;
						num = nextValue.valueInt;
						SetFieldClass(obj, valueString, valueObj);
					}
				}
				num = SkipIgnoredChars(s, num + 1, isSkipHasNextField: true, isSkipSep: true);
				return new ContainerObjAndInt
				{
					valueObj = obj,
					valueInt = num
				};
			}
			catch (Exception arg)
			{
				logger?.LogError($"{logMsgBaseError} {arg}");
			}
			return new ContainerObjAndInt
			{
				valueObj = null,
				valueInt = s.Length
			};
		}
	}
	public class HelperDebugLog : HelperLog, IDebugLogger, ILoggerWithConsole, ILogger
	{
		protected bool isDebug;

		public HelperDebugLog(string folderPath = null, string logFileName = null, bool isDebug = false)
			: base(folderPath, logFileName)
		{
			this.isDebug = isDebug;
		}

		public virtual void LogDebugInfo(object obj)
		{
			if (isDebug)
			{
				LogInfo($"[DEBUG] {obj}");
			}
		}

		public virtual void LogDebugWarning(object obj)
		{
			if (isDebug)
			{
				LogWarning($"[DEBUG] {obj}");
			}
		}

		public virtual void LogDebugError(object obj)
		{
			if (isDebug)
			{
				LogError($"[DEBUG] {obj}");
			}
		}
	}
	public class ScheduleManager
	{
		protected ILogger logger;

		protected Dictionary<string, TimerTaskData> timerTasks = new Dictionary<string, TimerTaskData>();

		protected Dictionary<string, PeriodicTaskData> periodicTasks = new Dictionary<string, PeriodicTaskData>();

		protected List<TimerTaskData> timerTasksNoId = new List<TimerTaskData>();

		protected List<PeriodicTaskData> periodicTasksNoId = new List<PeriodicTaskData>();

		protected int onUpdateErrorLimit = 10;

		public ScheduleManager(ILogger logger = null, int onUpdateErrorLimit = 0)
		{
			this.logger = logger;
			this.onUpdateErrorLimit = onUpdateErrorLimit;
		}

		public void NewTimerTask(TimerTaskData task, bool triggerFinishIfExists = false)
		{
			if (task == null)
			{
				logger?.LogInfo($"ScheduleManager new timer task null error. Details info: {task}");
				return;
			}
			if (task.id == null)
			{
				NewTimerTaskWithOutId(task);
				return;
			}
			if (triggerFinishIfExists && timerTasks.ContainsKey(task.id))
			{
				SafeRunAction(timerTasks[task.id].finishAction);
			}
			timerTasks[task.id] = task;
			logger?.LogInfo($"ScheduleManager new timer task {task}");
		}

		public void NewPeriodicTask(PeriodicTaskData task, bool triggerFinishIfExists = false)
		{
			if (task == null)
			{
				logger?.LogInfo($"ScheduleManager new periodic task null error. Details info: {task}");
				return;
			}
			task.periodCalculatedInSec = task.periodInSec;
			if (task.id == null)
			{
				NewPeriodicTaskWithOutId(task);
				return;
			}
			if (triggerFinishIfExists && periodicTasks.ContainsKey(task.id))
			{
				SafeRunAction(periodicTasks[task.id].finishAction);
			}
			periodicTasks[task.id] = task;
			logger?.LogInfo($"ScheduleManager new periodic task {task}");
		}

		public void AppendPeriodicTask(PeriodicTaskData task, bool isReplaceAction = false)
		{
			if (task.id == null || !periodicTasks.ContainsKey(task.id))
			{
				NewPeriodicTask(task);
				return;
			}
			logger?.LogInfo($"ScheduleManager append periodic task {task}");
			PeriodicTaskData periodicTaskData = periodicTasks[task.id];
			periodicTaskData.triggerTimes += task.triggerTimes;
			if (isReplaceAction)
			{
				periodicTaskData.finishAction = task.finishAction;
			}
		}

		protected void NewTimerTaskWithOutId(TimerTaskData task)
		{
			if (task == null)
			{
				logger?.LogWarning($"ScheduleManager new timer no id task null error. Details info: {task}");
				return;
			}
			timerTasksNoId.Add(task);
			logger?.LogInfo($"ScheduleManager new timer no id task {task}");
		}

		protected void NewPeriodicTaskWithOutId(PeriodicTaskData task)
		{
			if (task == null)
			{
				logger?.LogWarning($"ScheduleManager new periodic no id task null error. Details info: {task}");
				return;
			}
			periodicTasksNoId.Add(task);
			logger?.LogInfo($"ScheduleManager new periodic no id task {task}");
		}

		public void AppendTimerTask(TimerTaskData task, bool isReplaceAction = true)
		{
			if (!timerTasks.ContainsKey(task.id))
			{
				NewTimerTask(task);
				return;
			}
			logger?.LogInfo($"ScheduleManager append timer task {task}");
			TimerTaskData timerTaskData = timerTasks[task.id];
			timerTasks[task.id] = task;
			task.durationInSec += timerTaskData.durationInSec;
			if (!isReplaceAction)
			{
				task.finishAction = timerTaskData.finishAction;
			}
		}

		public bool IsTaskExists(string id)
		{
			if (!periodicTasks.ContainsKey(id))
			{
				return timerTasks.ContainsKey(id);
			}
			return true;
		}

		public void RemoveTimerTask(string id)
		{
			if (timerTasks.Remove(id))
			{
				logger?.LogInfo("ScheduleManager remove timer task " + id);
			}
		}

		public void RemovePeriodicTask(string id)
		{
			if (periodicTasks.Remove(id))
			{
				logger?.LogInfo("ScheduleManager remove periodic task " + id);
			}
		}

		public void RemoveAllTasks(string id)
		{
			logger?.LogInfo("ScheduleManager RemoveAllTasks with id " + id);
			RemoveTimerTask(id);
			RemovePeriodicTask(id);
		}

		public void RemoveAllTasks(bool isSuppressLog = false)
		{
			timerTasks.Clear();
			periodicTasks.Clear();
			timerTasksNoId.Clear();
			periodicTasksNoId.Clear();
			if (!isSuppressLog && logger != null)
			{
				logger.LogInfo("ScheduleManager RemoveAllTasks");
			}
		}

		protected List<TimerTaskData> ProcessTimersList(ICollection<TimerTaskData> list, float dtInSec)
		{
			List<TimerTaskData> list2 = new List<TimerTaskData>();
			foreach (TimerTaskData item in list)
			{
				item.durationInSec -= dtInSec;
				if (item.durationInSec <= 0f)
				{
					SafeRunAction(item.finishAction);
					list2.Add(item);
					logger?.LogInfo("ScheduleManager triggered finish action timer task " + item.id);
				}
			}
			return list2;
		}

		protected List<PeriodicTaskData> ProcessPeriodicList(ICollection<PeriodicTaskData> list, float dtInSec)
		{
			List<PeriodicTaskData> list2 = new List<PeriodicTaskData>();
			foreach (PeriodicTaskData item in list)
			{
				item.periodCalculatedInSec -= dtInSec;
				if (!(item.periodCalculatedInSec <= 0f))
				{
					continue;
				}
				if (item.isInfiniteRepeates || item.triggerTimes > 0)
				{
					SafeRunAction(item.periodicAction);
					item.periodCalculatedInSec = item.periodInSec;
					if (item.triggerTimes == 1)
					{
						logger?.LogInfo("ScheduleManager triggered action periodic task " + item.id);
					}
				}
				if (!item.isInfiniteRepeates)
				{
					item.triggerTimes--;
					if (item.triggerTimes <= 0)
					{
						SafeRunAction(item.finishAction);
						list2.Add(item);
						logger?.LogInfo("ScheduleManager triggered finish action periodic task " + item.id);
					}
				}
			}
			return list2;
		}

		public void OnUpdate(float dtInSec)
		{
			try
			{
				foreach (TimerTaskData item in ProcessTimersList(timerTasks.Values, dtInSec))
				{
					timerTasks.Remove(item.id);
					logger?.LogInfo($"ScheduleManager OnUpdate finished timer task {item}");
				}
				foreach (PeriodicTaskData item2 in ProcessPeriodicList(periodicTasks.Values, dtInSec))
				{
					periodicTasks.Remove(item2.id);
					logger?.LogInfo($"ScheduleManager OnUpdate finished periodic task {item2}");
				}
				foreach (TimerTaskData item3 in ProcessTimersList(timerTasksNoId, dtInSec))
				{
					timerTasksNoId.Remove(item3);
					logger?.LogInfo($"ScheduleManager OnUpdate finished timer no id task {item3}");
				}
				foreach (PeriodicTaskData item4 in ProcessPeriodicList(periodicTasksNoId, dtInSec))
				{
					periodicTasksNoId.Remove(item4);
					logger?.LogInfo($"ScheduleManager OnUpdate finished periodic no id task {item4}");
				}
			}
			catch (Exception arg)
			{
				if (onUpdateErrorLimit > 0)
				{
					logger?.LogError($"ScheduleManager unexpected onUpdate error: {arg}");
					onUpdateErrorLimit--;
				}
			}
		}

		public void FinishImmediatlyTimerTask(string id)
		{
			if (timerTasks.ContainsKey(id))
			{
				SafeRunAction(timerTasks[id].finishAction);
				timerTasks.Remove(id);
				logger?.LogInfo("ScheduleManager finish and remove timer task " + id);
			}
		}

		public float GetTimerTaskDurationInSec(string id)
		{
			if (!timerTasks.ContainsKey(id))
			{
				return -1f;
			}
			return timerTasks[id].durationInSec;
		}

		public void FinishImmediatlyPeriodicTask(string id)
		{
			if (periodicTasks.ContainsKey(id))
			{
				SafeRunAction(periodicTasks[id].finishAction);
				periodicTasks.Remove(id);
				logger?.LogInfo("ScheduleManager finish and remove periodic task " + id);
			}
		}

		public void FinishAllImmediatly(string id)
		{
			FinishImmediatlyTimerTask(id);
			FinishImmediatlyPeriodicTask(id);
		}

		public void FinishAllImmediatly()
		{
			foreach (TimerTaskData value in timerTasks.Values)
			{
				SafeRunAction(value.finishAction);
			}
			foreach (PeriodicTaskData value2 in periodicTasks.Values)
			{
				SafeRunAction(value2.finishAction);
			}
			foreach (TimerTaskData item in timerTasksNoId)
			{
				SafeRunAction(item.finishAction);
			}
			foreach (PeriodicTaskData item2 in periodicTasksNoId)
			{
				SafeRunAction(item2.finishAction);
			}
			RemoveAllTasks();
		}

		protected void SafeRunAction(Action action)
		{
			if (action == null)
			{
				return;
			}
			try
			{
				action();
			}
			catch (Exception arg)
			{
				logger?.LogError($"SafeRunAction error: {arg}");
			}
		}
	}
	public class UtilityConsole
	{
		private readonly Dictionary<string, IConsoleCommand> consoleCommandsDict;

		private readonly IDebugLogger logger;

		private readonly List<string> ignoreValidationCommands;

		public bool isLogCheckCommand = true;

		public bool isLogCheckCommandParameters = true;

		public int logCheckCommandParametersMaxLength = 40;

		public bool isLogProcessCommand = true;

		public bool isLogProcessCommandParameters = true;

		public int logProcessCommandParametersMaxLength = 40;

		public UtilityConsole(IDebugLogger logger = null, List<string> ignoreValidationCommands = null)
		{
			consoleCommandsDict = new Dictionary<string, IConsoleCommand>();
			this.logger = logger;
			this.ignoreValidationCommands = ignoreValidationCommands;
		}

		public void RegisterCommand(IConsoleCommand command)
		{
			if (string.IsNullOrEmpty(command?.Id))
			{
				logger?.LogWarning("UtilityConsole.RegisterCommand: invalid console command");
			}
			else
			{
				consoleCommandsDict[command.Id] = command;
			}
		}

		public static string[] ParseCommandLine(string commandLine)
		{
			return commandLine.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
		}

		public static string[] ParseArgs(string command)
		{
			return command.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
		}

		private string GetCmdName(string cmd)
		{
			string[] array = cmd.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length != 0)
			{
				return array[0];
			}
			return "";
		}

		private void LogCommand(string funcPrefix, string cmd, bool isLog, bool isLogParams, int maxLen)
		{
			if (logger == null || !isLog)
			{
				return;
			}
			if (string.IsNullOrEmpty(cmd))
			{
				logger.LogWarning(funcPrefix + " null or empty");
			}
			else if (isLogParams)
			{
				if (cmd.Length > maxLen)
				{
					string text = cmd.Substring(0, maxLen);
					logger.Log(funcPrefix + " " + text + "...");
				}
				else
				{
					logger.Log(funcPrefix + " " + cmd);
				}
			}
			else
			{
				logger.Log(funcPrefix + " " + GetCmdName(cmd));
			}
		}

		public bool IsValidCommandLine(string commandLine)
		{
			try
			{
				if (string.IsNullOrEmpty(commandLine))
				{
					logger?.LogDebugError("UtilityConsole.IsValidCommandLine: invalid command line");
					return false;
				}
				string[] array = ParseCommandLine(commandLine);
				if (array == null || array.Length < 1)
				{
					logger?.LogDebugError("UtilityConsole.IsValidCommandLine: invalid commands count");
					return false;
				}
				bool flag = true;
				string[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					string text = array2[i]?.Trim();
					LogCommand("UtilityConsole.IsValidCommandLine: check command", text, isLogCheckCommand, isLogCheckCommandParameters, logCheckCommandParametersMaxLength);
					string[] array3 = ParseArgs(text);
					if (array3 == null || array3.Length < 1)
					{
						logger?.LogDebugError("UtilityConsole.IsValidCommandLine: invalid commands count");
						flag = false;
						continue;
					}
					string text2 = array3[0];
					List<string> list = ignoreValidationCommands;
					if (list != null && list.Contains(text2))
					{
						logger?.LogDebugInfo("UtilityConsole.IsValidCommandLine: validation is ignored for this command");
					}
					else if (consoleCommandsDict.ContainsKey(text2))
					{
						bool flag2 = consoleCommandsDict[text2].IsValidCommandArgs(array3.Skip(1));
						if (!flag2)
						{
							logger?.LogDebugError("UtilityConsole.IsValidCommandLine: command with id " + text2 + " is invalid");
						}
						flag = flag && flag2;
					}
					else
					{
						logger?.LogDebugError("UtilityConsole.IsValidCommandLine: can't find custom command with id " + text2);
						flag = false;
					}
				}
				return flag;
			}
			catch (Exception arg)
			{
				logger?.LogDebugError(string.Format("{0} error: {1}", "UtilityConsole.IsValidCommandLine:", arg));
				return false;
			}
		}

		public bool RunCommand(string commandLine, IEventsData data, Action<string> onCustomCommandNotFound = null)
		{
			try
			{
				string[] array = ParseCommandLine(commandLine);
				foreach (string text in array)
				{
					LogCommand("UtilityConsole.RunCommand: process command", text, isLogProcessCommand, isLogProcessCommandParameters, logProcessCommandParametersMaxLength);
					string[] array2 = ParseArgs(text);
					string key = array2[0];
					if (consoleCommandsDict.ContainsKey(key))
					{
						try
						{
							if (consoleCommandsDict[key] is IConsoleCommandWithData consoleCommandWithData)
							{
								consoleCommandWithData.Execute(array2.Skip(1), data);
							}
							else
							{
								consoleCommandsDict[key].Execute(array2.Skip(1));
							}
						}
						catch (Exception arg)
						{
							logger?.LogError(string.Format("{0} execute command error {1}", "UtilityConsole.RunCommand:", arg));
						}
					}
					else if (onCustomCommandNotFound != null)
					{
						onCustomCommandNotFound(text);
					}
					else
					{
						logger?.LogError("UtilityConsole.RunCommand: execute command not found error");
					}
				}
			}
			catch (Exception arg2)
			{
				logger?.LogError(string.Format("{0} error {1}", "UtilityConsole.RunCommand:", arg2));
				return false;
			}
			return true;
		}
	}
	public class CommandArgsReader
	{
		private readonly ILogger logger;

		public CommandArgsReader(ILogger logger)
		{
			this.logger = logger;
		}

		public int ReadInt(IEnumerator<string> args, int defaultValue = 0)
		{
			if (args == null || !args.MoveNext())
			{
				return defaultValue;
			}
			try
			{
				return int.Parse(args.Current);
			}
			catch (Exception arg)
			{
				logger?.LogWarning($"CommandArgsReader: {arg}");
				return defaultValue;
			}
		}

		public float ReadFloat(IEnumerator<string> args, float defaultValue = 0f)
		{
			if (args == null || !args.MoveNext())
			{
				return defaultValue;
			}
			try
			{
				return float.Parse(args.Current, CultureInfo.InvariantCulture.NumberFormat);
			}
			catch (Exception arg)
			{
				logger?.LogWarning($"CommandArgsReader: {arg}");
				return defaultValue;
			}
		}

		public string ReadString(IEnumerator<string> args, string defaultValue = "")
		{
			if (args != null && args.MoveNext())
			{
				return args.Current;
			}
			return defaultValue;
		}

		public bool ReadBool(IEnumerator<string> args, bool defaultValue = false)
		{
			if (args == null || !args.MoveNext())
			{
				return defaultValue;
			}
			try
			{
				return bool.Parse(args.Current.ToLower());
			}
			catch (Exception arg)
			{
				logger?.LogWarning($"CommandArgsReader: {arg}");
				return defaultValue;
			}
		}
	}
	public static class UtilityRandom
	{
		private static readonly Random rnd = new Random(Guid.NewGuid().GetHashCode());

		public static T GetRandomItemFromList<T>(IList<T> list)
		{
			if (list != null && list.Count > 0)
			{
				return list[rnd.Next(list.Count)];
			}
			return default(T);
		}
	}
	public class HelperCommandManagerFormatted : ICommandManager
	{
		private Dictionary<string, string> commandsDict;

		private readonly IDebugLogger logger;

		private readonly string errorString = string.Empty;

		public int logCommandMaxLength = 50;

		public bool isUseLogCommandLimit = true;

		public HelperCommandManagerFormatted(IDebugLogger logger)
		{
			this.logger = logger;
		}

		public virtual void InitFromFile(string path)
		{
			try
			{
				Dictionary<string, string> dictionary = UtilityJson.Generate(logger).FromFile<Dictionary<string, string>>(path);
				commandsDict = new Dictionary<string, string>(dictionary, StringComparer.OrdinalIgnoreCase);
				CheckLoadedDict();
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperCommandManagerFormatted InitFromFile load: {arg}");
				commandsDict = null;
			}
		}

		public virtual void InitFromString(string data)
		{
			try
			{
				Dictionary<string, string> dictionary = UtilityJson.Generate(logger).FromString<Dictionary<string, string>>(data);
				commandsDict = new Dictionary<string, string>(dictionary, StringComparer.OrdinalIgnoreCase);
				CheckLoadedDict();
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperCommandManagerFormatted InitFromString load: {arg}");
				commandsDict = null;
			}
		}

		protected virtual void CheckLoadedDict()
		{
			if (commandsDict == null)
			{
				logger?.LogWarning("HelperCommandManagerFormatted: commandsDict null");
				return;
			}
			logger?.LogInfo($"HelperCommandManagerFormatted: found commands {commandsDict.Count}");
			foreach (KeyValuePair<string, string> item in commandsDict)
			{
				logger?.LogDebugInfo("command: key=" + item.Key + ", value=" + GetSubstringCmd(item.Value));
			}
		}

		protected virtual string GetSubstringCmd(string cmd)
		{
			if (isUseLogCommandLimit && cmd != null)
			{
				if (cmd.Length > logCommandMaxLength)
				{
					return cmd.Substring(0, logCommandMaxLength) + "...";
				}
				return cmd;
			}
			return cmd;
		}

		public virtual string GetCommandData(string eventKey, bool isLogError = false)
		{
			if (commandsDict == null)
			{
				logger?.LogWarning("HelperCommandManagerFormatted GetCommandData: commandsDict null");
				return "";
			}
			try
			{
				eventKey = eventKey.Trim();
				string text = commandsDict[eventKey];
				if (text != null)
				{
					return text;
				}
				throw new NullReferenceException();
			}
			catch (Exception arg)
			{
				if (isLogError)
				{
					logger?.LogError($"HelperCommandManagerFormatted key {eventKey}, error: {arg}");
				}
				return errorString;
			}
		}

		public virtual string[] GetCommands()
		{
			if (commandsDict == null)
			{
				logger?.LogWarning("HelperCommandManagerFormatted GetCommands: commandsDict null");
				return new string[0];
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, string> item in commandsDict)
			{
				list.Add(item.Value);
			}
			return list.ToArray();
		}
	}
	public class HelperDictManager : IDictManager
	{
		private readonly ILogger logger;

		private readonly IEventsDataEncoder encoder;

		private readonly IEventsDataEncoderParams encoderParams;

		public HelperDictManager(ILogger logger = null)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			this.logger = logger;
			encoderParams = (IEventsDataEncoderParams)(object)(encoder = (IEventsDataEncoder)new EventsDataEncoder());
		}

		public Dictionary<string, string> ParseDict(string data)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			try
			{
				string[] array = data.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
				if (array == null)
				{
					logger?.LogError("HelperDictManager error, wrong args. Source: " + data);
					return dictionary;
				}
				string[] array2 = array;
				foreach (string text in array2)
				{
					string[] array3 = text.Split(new char[1] { encoderParams.ClientAppSepChar }, StringSplitOptions.RemoveEmptyEntries);
					if (array3.Length != 2)
					{
						logger?.LogWarning("HelperDictManager, invalid item: " + text);
						continue;
					}
					string text2 = array3[0];
					string text3 = array3[1];
					if (text3 == null || text2 == null)
					{
						logger?.LogWarning("HelperDictManager, invalid key/val: " + text2 + "/" + text3);
						continue;
					}
					string key = encoder.Decode(text2).Trim();
					string value = encoder.Decode(text3).Trim();
					dictionary.Add(key, value);
				}
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperDictManager error: {arg}");
			}
			return dictionary;
		}
	}
	public class HelperCommandManager : ICommandManager
	{
		private readonly Dictionary<string, string> commandsDict;

		private readonly IDebugLogger logger;

		private readonly string errorString = string.Empty;

		public HelperCommandManager(IDebugLogger logger, string commandsDir, string commandsFname = "commands.data")
		{
			this.logger = logger;
			try
			{
				string path = Path.Combine(commandsDir, commandsFname);
				IDictManager dictManager = new HelperDictManager();
				using StreamReader streamReader = new StreamReader(path);
				string data = streamReader.ReadToEnd();
				Dictionary<string, string> dictionary = dictManager.ParseDict(data);
				commandsDict = new Dictionary<string, string>(dictionary, StringComparer.OrdinalIgnoreCase);
				logger?.LogInfo($"HelperCommandManager: found commands {commandsDict.Count}");
				foreach (KeyValuePair<string, string> item in commandsDict)
				{
					logger?.LogDebugInfo("command: key=" + item.Key + ", value=" + item.Value);
				}
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperCommandManager load: {arg}");
				commandsDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			}
		}

		public string GetCommandData(string eventKey, bool isLogError = false)
		{
			try
			{
				eventKey = eventKey.Trim();
				string text = commandsDict[eventKey];
				if (text != null)
				{
					return text;
				}
				throw new NullReferenceException();
			}
			catch (Exception arg)
			{
				if (isLogError)
				{
					logger?.LogError($"HelperCommandManager key {eventKey}: {arg}");
				}
				return errorString;
			}
		}

		public string[] GetCommands()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, string> item in commandsDict)
			{
				list.Add(item.Value);
			}
			return list.ToArray();
		}

		public virtual void InitFromFile(string path)
		{
			throw new NotImplementedException();
		}

		public virtual void InitFromString(string data)
		{
			throw new NotImplementedException();
		}
	}
	public class HelperEventManager<CustomEvent> : IEventManager<CustomEvent> where CustomEvent : class, IEvent
	{
		private readonly Dictionary<string, CustomEvent> eventsDict;

		private readonly IDebugLogger logger;

		public HelperEventManager(IDebugLogger logger)
		{
			this.logger = logger;
			eventsDict = new Dictionary<string, CustomEvent>(StringComparer.OrdinalIgnoreCase);
			try
			{
				Type type = typeof(CustomEvent);
				IEnumerable<Type> enumerable = from p in AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly s)
					{
						try
						{
							return s.GetTypes();
						}
						catch (Exception)
						{
							return new Type[0];
						}
					})
					where p.IsClass && !p.IsAbstract && !p.IsInterface && type.IsAssignableFrom(p)
					select p;
				logger?.LogInfo($"HelperEventManager: found {enumerable.Count()} events");
				foreach (Type item in enumerable)
				{
					CustomEvent val = Activator.CreateInstance(item) as CustomEvent;
					if (val != null)
					{
						eventsDict.Add(val.Id, val);
						logger?.LogDebugInfo("init event '" + val.Id + "' complete");
					}
					else
					{
						logger?.LogWarning("init event '" + val.Id + "' failed");
					}
				}
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperEventManager error: {arg}");
			}
		}

		public HelperEventManager(IDebugLogger logger, IEventManager<IEvent> manager)
		{
			this.logger = logger;
			eventsDict = new Dictionary<string, CustomEvent>(StringComparer.OrdinalIgnoreCase);
			string name = typeof(CustomEvent).Name;
			try
			{
				foreach (IEvent item in manager.GetEventsCollection())
				{
					if (item is CustomEvent val)
					{
						eventsDict.Add(val.Id, val);
						logger?.LogDebugInfo("init event '" + val.Id + "' as '" + name + "' complete");
					}
				}
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperEventManager: {arg}");
			}
		}

		public IEnumerable<CustomEvent> GetEventsCollection()
		{
			if (eventsDict == null)
			{
				return new List<CustomEvent>();
			}
			return eventsDict.Values;
		}

		public CustomEvent GetEvent(string eventID, bool isLogError = false)
		{
			try
			{
				eventID = eventID.Trim();
				CustomEvent val = eventsDict[eventID];
				if (val != null)
				{
					return val;
				}
				throw new NullReferenceException();
			}
			catch (Exception arg)
			{
				if (isLogError)
				{
					logger?.LogError($"HelperCommandManager key {eventID}: {arg}");
				}
				return null;
			}
		}
	}
	public class HelperLanguagesFormatted : ITranslation
	{
		protected Dictionary<string, Text> transDict;

		protected readonly IDebugLogger logger;

		protected readonly string errorString = "trans_error";

		public bool isLogOnlyEnItems;

		public bool isSuppressLogItems = true;

		public HelperLanguagesFormatted(IDebugLogger logger)
		{
			this.logger = logger;
		}

		public virtual void InitFromFile(string path)
		{
			try
			{
				Dictionary<string, Text> dictionary = UtilityJson.Generate(logger).FromFile<Dictionary<string, Text>>(path);
				transDict = new Dictionary<string, Text>(dictionary, StringComparer.OrdinalIgnoreCase);
				CheckLoadedDict();
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperLanguagesFormatted InitFromFile load: {arg}");
				transDict = null;
			}
		}

		public virtual void InitFromString(string data)
		{
			try
			{
				Dictionary<string, Text> dictionary = UtilityJson.Generate(logger).FromString<Dictionary<string, Text>>(data);
				transDict = new Dictionary<string, Text>(dictionary, StringComparer.OrdinalIgnoreCase);
				CheckLoadedDict();
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperLanguagesFormatted InitFromString load: {arg}");
				transDict = null;
			}
		}

		protected virtual void CheckLoadedDict()
		{
			if (transDict == null)
			{
				logger?.LogWarning("HelperLanguagesFormatted: transDict null");
				return;
			}
			logger?.LogInfo($"HelperLanguagesFormatted: found translates {transDict.Count}");
			if (isSuppressLogItems || logger == null)
			{
				return;
			}
			foreach (KeyValuePair<string, Text> item in transDict)
			{
				if (isLogOnlyEnItems)
				{
					logger.LogDebugInfo("key=" + item.Key + ", en=" + item.Value.en);
					continue;
				}
				logger.LogDebugInfo("key=" + item.Key + ", ru=" + item.Value.ru + ", en=" + item.Value.en);
			}
		}

		public virtual string GetTrans(string key, Languages lang)
		{
			return GetTrans(key, lang.ToString());
		}

		public virtual string GetTrans(string key, string lang)
		{
			if (transDict == null)
			{
				logger?.LogWarning("HelperLanguagesFormatted transDict is null");
				return errorString;
			}
			try
			{
				key = key.Trim();
				lang = lang.Trim();
				return transDict[key].GetTrans(lang);
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperLanguagesFormatted key {key} lang {lang}, error: {arg}");
				return errorString;
			}
		}
	}
	public class HelperLog : ILoggerWithConsole, ILogger
	{
		protected readonly string path;

		protected const string baseLogName = "interactive_mod_log.txt";

		public bool isLogConsole = true;

		public bool isLogFile = true;

		public ConsoleColor infoColor = ConsoleColor.White;

		public ConsoleColor warningColor = ConsoleColor.Yellow;

		public ConsoleColor errorColor = ConsoleColor.Red;

		protected virtual string LogTime => DateTime.Now.ToString("h:mm:ss:fff");

		public HelperLog(string logDir)
			: this(logDir, "interactive_mod_log.txt")
		{
		}

		public HelperLog(string logDir, string logFname)
		{
			if (logDir == "" || Directory.Exists(logDir))
			{
				path = Path.Combine(logDir, logFname);
			}
		}

		protected virtual void WriteToFile(string s)
		{
			if (path != null)
			{
				using (StreamWriter streamWriter = new StreamWriter(path, append: true, Encoding.UTF8))
				{
					streamWriter.WriteLine(s);
				}
			}
		}

		public virtual void Log(object obj)
		{
			if (isLogFile)
			{
				WriteToFile($"{LogTime} {obj}");
			}
		}

		public virtual void LogConsole(string text, string prefix, ConsoleColor prefixColor)
		{
			Console.ForegroundColor = prefixColor;
			Console.Write(LogTime + " " + prefix + " ");
			Console.ResetColor();
			Console.WriteLine(text);
		}

		protected virtual void LogWithConsole(object obj, string prefix, ConsoleColor color)
		{
			Log($"{prefix} {obj}");
			if (isLogConsole)
			{
				LogConsole(obj.ToString(), prefix, color);
			}
		}

		public virtual void LogInfo(object obj)
		{
			LogWithConsole(obj, "[INFO]", infoColor);
		}

		public virtual void LogWarning(object obj)
		{
			LogWithConsole(obj, "[WARNING]", warningColor);
		}

		public virtual void LogError(object obj)
		{
			LogWithConsole(obj, "[ERROR]", errorColor);
		}

		public virtual void LogInfoConsoleOnly(object obj)
		{
			if (isLogConsole)
			{
				LogConsole(obj.ToString(), "[INFO]", infoColor);
			}
		}

		public virtual void LogWarningConsoleOnly(object obj)
		{
			if (isLogConsole)
			{
				LogConsole(obj.ToString(), "[WARNING]", warningColor);
			}
		}

		public virtual void LogErrorConsoleOnly(object obj)
		{
			if (isLogConsole)
			{
				LogConsole(obj.ToString(), "[ERROR]", errorColor);
			}
		}

		public virtual void LogInfoFileOnly(object obj)
		{
			Log($"[INFO] {obj}");
		}

		public virtual void LogWarningFileOnly(object obj)
		{
			Log($"[WARNING] {obj}");
		}

		public virtual void LogErrorFileOnly(object obj)
		{
			Log($"[ERROR] {obj}");
		}

		public virtual void LogClear()
		{
			if (path != null)
			{
				using (new StreamWriter(path))
				{
				}
			}
		}
	}
	public class HelperParse : IParseManager
	{
		private readonly ILogger logger;

		public HelperParse(ILogger logger = null)
		{
			this.logger = logger;
		}

		public Type GetEnumUnderlyingType(Type type)
		{
			if (!type.IsEnum)
			{
				return type;
			}
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (fields != null && fields.Length >= 1)
			{
				return fields[0].FieldType;
			}
			return type;
		}

		public bool TryParseEnum<TEnum>(string arg, out TEnum result, TEnum defaultValue = default(TEnum))
		{
			Type typeFromHandle = typeof(TEnum);
			try
			{
				Type enumUnderlyingType = GetEnumUnderlyingType(typeFromHandle);
				if ((object)enumUnderlyingType == typeof(int))
				{
					if (int.TryParse(arg, out var result2) && Enum.IsDefined(typeFromHandle, result2))
					{
						result = (TEnum)Enum.ToObject(typeFromHandle, result2);
						return true;
					}
					logger?.LogWarning("TryParseEnum can't parse int from " + arg + " for enum " + typeFromHandle.Name);
				}
				else if ((object)enumUnderlyingType == typeof(sbyte))
				{
					if (sbyte.TryParse(arg, out var result3) && Enum.IsDefined(typeFromHandle, result3))
					{
						result = (TEnum)Enum.ToObject(typeFromHandle, result3);
						return true;
					}
					logger?.LogWarning("TryParseEnum can't parse sbyte from " + arg + " for enum " + typeFromHandle.Name);
				}
				else
				{
					foreach (TEnum value in Enum.GetValues(typeFromHandle))
					{
						if (Enum.GetName(typeFromHandle, value).Equals(arg, StringComparison.OrdinalIgnoreCase))
						{
							result = value;
							return true;
						}
					}
					logger?.LogWarning("TryParseEnum can't find item by direct name " + arg + " for enum " + typeFromHandle.Name);
				}
			}
			catch (Exception arg2)
			{
				logger?.LogError($"TryParseEnum error happened when process {arg} for enum {typeFromHandle.Name}: {arg2}");
			}
			result = defaultValue;
			return false;
		}

		public bool TryParseBool(string arg, out bool result, bool defaultValue = false)
		{
			if (bool.TryParse(arg, out result))
			{
				return true;
			}
			if (int.TryParse(arg, out var result2))
			{
				result = result2 != 0;
				return true;
			}
			logger?.LogWarning($"TryParseBool error happened when process {arg}. Will be used default {defaultValue}");
			result = defaultValue;
			return false;
		}
	}
	public class UtilityJson
	{
		private static Func<IJsonUtil> customGenerator;

		public static IJsonUtil Generate(IDebugLogger logger)
		{
			if (customGenerator == null)
			{
				return new HelperJson(logger, File.Exists(".mod_json_debug"));
			}
			return customGenerator();
		}

		public static void RegisterCustomGenerator(Func<IJsonUtil> generator)
		{
			customGenerator = generator;
		}
	}
	public class UtilitySettings
	{
		public static string CommandUpdateSettingsID => "command_update_parameters";

		public static string BaseFolder { get; set; } = "ChaosTricks_InteractiveModData";


		public static string SettingsFileName => "settings.txt";

		public static string SettingsPath => Path.Combine(BaseFolder, SettingsFileName);

		public static T LoadSettings<T>(IDebugLogger logger) where T : class
		{
			string text = string.Empty;
			try
			{
				text = SettingsPath;
				T result = UtilityJson.Generate(logger).FromFile<T>(text);
				logger?.LogInfo("settings loaded");
				return result;
			}
			catch (FileNotFoundException)
			{
				logger?.LogWarning("can't load settings. File not found at " + text + ". Using standard.");
			}
			catch (Exception arg)
			{
				logger?.LogError($"can't load settings. Using standard. \n{arg}");
			}
			T result2 = null;
			try
			{
				result2 = Activator.CreateInstance<T>();
				return result2;
			}
			catch (Exception arg2)
			{
				logger?.LogError($"can't create default data class. \n{arg2}");
			}
			return result2;
		}
	}
	public enum Languages
	{
		ru,
		en
	}
	public class Text
	{
		public string ru;

		public string en;

		public Text(string ru, string en)
		{
			this.ru = ru;
			this.en = en;
		}

		public Text()
		{
		}

		public string GetTrans(Languages lang)
		{
			if (lang != Languages.en)
			{
				return ru;
			}
			return en;
		}

		public string GetTrans(string lang)
		{
			if (GetLangFromAppLang(lang) != Languages.en)
			{
				return ru;
			}
			return en;
		}

		private Languages GetLangFromAppLang(string lang)
		{
			lang = lang?.Trim()?.ToLower();
			switch (lang)
			{
			default:
				return Languages.en;
			case "ru":
			case "russian":
			case "rus":
			case "русский":
			case "ру":
			case "рус":
				return Languages.ru;
			}
		}
	}
	public class HelperLanguages : ITranslation
	{
		private readonly Dictionary<string, Text> transDict;

		private readonly ILogger logger;

		private readonly string errorString = "trans_error";

		public HelperLanguages(ILogger logger, string langsDir, string langsFname = "langs.data")
		{
			this.logger = logger;
			try
			{
				string path = Path.Combine(langsDir, langsFname);
				IDictManager dictManager = new HelperDictManager(logger);
				using (StreamReader streamReader = new StreamReader(path))
				{
					string data = streamReader.ReadToEnd();
					Dictionary<string, string> source = dictManager.ParseDict(data);
					transDict = GetTransDict(source);
				}
				logger?.LogInfo($"HelperLanguages: found translates {transDict.Count}");
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperLanguages load: {arg}");
				transDict = new Dictionary<string, Text>(StringComparer.OrdinalIgnoreCase);
			}
		}

		protected Dictionary<string, Text> GetTransDict(Dictionary<string, string> source)
		{
			Dictionary<string, Text> dictionary = new Dictionary<string, Text>(StringComparer.OrdinalIgnoreCase);
			foreach (KeyValuePair<string, string> item in source)
			{
				string[] array = item.Value.Split(new string[1] { "%lang%" }, StringSplitOptions.RemoveEmptyEntries);
				if (array == null || array.Length != 2)
				{
					logger?.LogError("HelperLanguages parse item: " + item.Key);
					continue;
				}
				string ru = array[0];
				string en = array[1];
				dictionary.Add(item.Key, new Text(ru, en));
			}
			return dictionary;
		}

		public string GetTrans(string key, Languages lang)
		{
			return GetTrans(key, lang.ToString());
		}

		public string GetTrans(string key, string lang)
		{
			try
			{
				key = key.Trim();
				lang = lang.Trim();
				return transDict[key].GetTrans(lang);
			}
			catch (Exception arg)
			{
				logger?.LogError($"HelperLanguages key {key} lang {lang}: {arg}");
				return errorString;
			}
		}

		public virtual void InitFromFile(string path)
		{
			throw new NotImplementedException();
		}

		public void InitFromString(string data)
		{
			throw new NotImplementedException();
		}
	}
}
namespace ModHelper.Interfaces
{
	public interface ICommandTargets
	{
		bool IsAllPlayers { get; }
	}
	public interface IConsoleCommandWithData : IConsoleCommand
	{
		bool Execute(IEnumerable<string> args, IEventsData data);
	}
	public interface IConsoleCommand
	{
		string Id { get; }

		bool Execute(IEnumerable<string> args);

		bool IsValidCommandArgs(IEnumerable<string> args);
	}
	public interface IDebugLogger : ILoggerWithConsole, ILogger
	{
		void LogDebugInfo(object obj);

		void LogDebugWarning(object obj);

		void LogDebugError(object obj);
	}
	public interface ILoggerWithConsole : ILogger
	{
		void LogInfoConsoleOnly(object obj);

		void LogWarningConsoleOnly(object obj);

		void LogErrorConsoleOnly(object obj);

		void LogInfoFileOnly(object obj);

		void LogWarningFileOnly(object obj);

		void LogErrorFileOnly(object obj);
	}
	public interface ICommandNotify
	{
		string ProcessMsg(string msg);
	}
	public interface ICommand
	{
		string Id { get; }
	}
	public interface IDictionaryItem<T>
	{
		string Key { get; }

		T Value { get; }
	}
	public interface IJsonUtil
	{
		T FromFile<T>(string path) where T : class;

		T FromString<T>(string s) where T : class;
	}
	public interface IDictManager
	{
		Dictionary<string, string> ParseDict(string data);
	}
	public interface ICommandManager
	{
		string GetCommandData(string eventKey, bool isLogError = false);

		string[] GetCommands();

		void InitFromString(string data);

		void InitFromFile(string path);
	}
	public interface IEventManager<CustomEvent>
	{
		CustomEvent GetEvent(string eventID, bool isLogError = false);

		IEnumerable<CustomEvent> GetEventsCollection();
	}
	public interface IEventWithData : IEvent
	{
		bool Execute(IEventsData data);
	}
	public interface IEvent
	{
		string Id { get; }

		bool Execute();
	}
	public interface ILogger
	{
		void Log(object obj);

		void LogInfo(object obj);

		void LogWarning(object obj);

		void LogError(object obj);

		void LogClear();
	}
	public interface ITranslation
	{
		string GetTrans(string key, Languages lang);

		string GetTrans(string key, string lang);

		void InitFromString(string data);

		void InitFromFile(string path);
	}
	public interface IParseManager
	{
		bool TryParseEnum<TEnum>(string arg, out TEnum result, TEnum defaultValue = default(TEnum));

		bool TryParseBool(string arg, out bool result, bool defaultValue = false);
	}
}

ChaosTricks_PEAK_plugins/ModHelperUnity.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using EventsIO.Interfaces;
using ModHelper;
using ModHelper.Interfaces;
using ModHelperUnity;
using ModHelperUnity.Data;
using ModHelperUnity.Interfaces;
using ModHelperUnity.UtilityGUI;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ModHelperUnity")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BFT")]
[assembly: AssemblyProduct("ModHelperUnity")]
[assembly: AssemblyCopyright("Copyright ©  2020")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4afa0e1e-341b-4554-97c1-0c38ad74f246")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Doorstop
{
	internal class Entrypoint
	{
		public static void Start()
		{
			Preloader.Main();
		}
	}
}
namespace ModHelperUnity
{
	public abstract class TypedNotifyBase : MonoBehaviour, IComponentTypedNotify
	{
		private bool isDisposed;

		private Queue<TypedNotifyMessage> messages;

		private bool isInitiated;

		private bool isMessageProcessed;

		private float delayAfterNotify;

		private bool isShowAnimationStageFinished;

		private bool isShowMessageStageFinished;

		private bool isHideAnimationStageFinished;

		protected int logLimit;

		protected IDebugLogger logger;

		protected Dictionary<string, Texture2D> messageTextures = new Dictionary<string, Texture2D>();

		protected readonly Dictionary<string, IPostProcessText> postProcessEvents = new Dictionary<string, IPostProcessText>();

		public TypedNotifySettings Settings { get; protected set; }

		protected TypedNotifyMessage CurrentMessage { get; private set; }

		protected TypedNotifyParameters CurrentNotifyParameters { get; private set; }

		protected virtual void Log(object obj)
		{
			IDebugLogger obj2 = logger;
			if (obj2 != null)
			{
				((ILogger)obj2).LogInfo((object)$"TypedNotifyBase: {obj}");
			}
		}

		protected virtual void LimitedLogError(object obj)
		{
			if (logLimit > 0 && logger != null)
			{
				((ILogger)logger).LogError((object)$"TypedNotifyBase: {obj}");
				logLimit--;
			}
		}

		protected virtual Texture2D GetMessageTexture(string type)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (!messageTextures.ContainsKey(type))
			{
				return new Texture2D(2, 2);
			}
			return messageTextures[type];
		}

		protected void LoadFadeSettings(string settingsFilePath, Func<string, byte[]> customFileReader = null)
		{
			try
			{
				if (customFileReader == null)
				{
					Settings = UtilityJson.Generate(logger).FromFile<TypedNotifySettings>(settingsFilePath);
				}
				else
				{
					byte[] bytes = customFileReader(settingsFilePath);
					string @string = Encoding.UTF8.GetString(bytes);
					Settings = UtilityJson.Generate(logger).FromString<TypedNotifySettings>(@string);
				}
			}
			catch (Exception arg)
			{
				Log($"LoadFadeSettings error: {arg}");
			}
			if (Settings == null)
			{
				Settings = new TypedNotifySettings();
			}
		}

		protected Texture2D LoadImage(string imageFilePath, Func<string, byte[]> customFileReader = null)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			try
			{
				Texture2D val = UtilityUI.LoadImage(imageFilePath, customFileReader);
				Log($"LoadImage {imageFilePath}: width {((Texture)val).width}, height {((Texture)val).height}");
				return val;
			}
			catch (Exception arg)
			{
				Log($"LoadImage {imageFilePath} error: {arg}");
				return new Texture2D(2, 2, (TextureFormat)4, false);
			}
		}

		protected void LoadResources(string folderPath, Func<string, byte[]> customFileReader = null)
		{
			Log("LoadResources");
			string text = "notify_settings.data";
			string settingsFilePath = ((folderPath == null) ? text : Path.Combine(folderPath, text));
			LoadFadeSettings(settingsFilePath, customFileReader);
			ClearMessageTextures();
			if (Settings.notifyParameters != null)
			{
				TypedNotifyParameters[] notifyParameters = Settings.notifyParameters;
				foreach (TypedNotifyParameters typedNotifyParameters in notifyParameters)
				{
					Log(typedNotifyParameters.ToString());
					string imageFilePath = ((folderPath == null) ? typedNotifyParameters.imageFileName : Path.Combine(folderPath, typedNotifyParameters.imageFileName));
					Texture2D val = LoadImage(imageFilePath, customFileReader);
					messageTextures[typedNotifyParameters.type] = val;
					((Texture)val).filterMode = (FilterMode)2;
					((Texture)val).anisoLevel = 16;
				}
			}
		}

		public virtual void PostInit(string folderPath, IDebugLogger logger = null, Func<string, byte[]> customFileReader = null)
		{
			if (!isInitiated)
			{
				ForcePostInit(folderPath, logger, customFileReader);
			}
			Log("post init completed");
		}

		public virtual void ForcePostInit(string folderPath, IDebugLogger logger = null, Func<string, byte[]> customFileReader = null)
		{
			this.logger = logger;
			try
			{
				messages = new Queue<TypedNotifyMessage>();
				CurrentMessage = null;
				CurrentNotifyParameters = new TypedNotifyParameters();
				logLimit = 10;
				isInitiated = true;
				LoadResources(folderPath, customFileReader);
			}
			catch (Exception arg)
			{
				Log($"ForcePostInit error: {arg}");
			}
			Log("force init");
		}

		protected virtual string ProcessCustomTemplates(string message, IEventsData eventData, ITranslation translation)
		{
			try
			{
				return Regex.Replace(message, "%template_.+?%", (Match s) => translation.GetTrans(s.Value, eventData.Lang));
			}
			catch (Exception arg)
			{
				Log($"ProcessCustomTemplates error: {arg}");
				return message;
			}
		}

		protected virtual string GenerateMessage(IEventsData eventData, ITranslation translation)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			TypedNotifyParameters typedNotifyParameters = GetTypedNotifyParameters(eventData);
			string trans = translation.GetTrans(eventData.EventID, eventData.Lang);
			string message = typedNotifyParameters.messageTemplate.Replace("%name%", UtilityUI.GetColoredText(eventData.Username, typedNotifyParameters.nicknameTextColor)).Replace("%message%", UtilityUI.GetColoredText(trans, typedNotifyParameters.messageTextColor));
			return ProcessCustomTemplates(message, eventData, translation);
		}

		public virtual TypedNotifyParameters GetTypedNotifyParameters(string type)
		{
			TypedNotifyParameters[] notifyParameters = Settings.notifyParameters;
			if (notifyParameters == null || notifyParameters.Length == 0)
			{
				Log("warning, notify types empty (use default)");
				return new TypedNotifyParameters();
			}
			TypedNotifyParameters[] array = notifyParameters;
			foreach (TypedNotifyParameters typedNotifyParameters in array)
			{
				if (typedNotifyParameters.type == type)
				{
					return typedNotifyParameters;
				}
			}
			return notifyParameters[0];
		}

		public virtual TypedNotifyParameters GetTypedNotifyParameters(IEventsData eventData)
		{
			TypedNotifyParameters[] notifyParameters = Settings.notifyParameters;
			if (notifyParameters == null || notifyParameters.Length == 0)
			{
				Log("warning, notify types empty (use default)");
				return new TypedNotifyParameters();
			}
			TypedNotifyParameters[] array = notifyParameters;
			foreach (TypedNotifyParameters typedNotifyParameters in array)
			{
				string[] events = typedNotifyParameters.events;
				if (events != null && events.Contains(eventData.EventID))
				{
					return typedNotifyParameters;
				}
			}
			return notifyParameters[0];
		}

		public virtual void AddNotifyToQueue(IEventsData eventData, ITranslation translation, Func<string, string> converter = null, bool applyUpperCase = true)
		{
			if (eventData == null)
			{
				Log("warning, eventData is null");
			}
			if (translation == null)
			{
				Log("warning, translation is null");
			}
			TypedNotifyParameters typedNotifyParameters = GetTypedNotifyParameters(eventData);
			string text = GenerateMessage(eventData, translation);
			if (converter != null)
			{
				text = converter(text);
			}
			text = PostProcessEvent(text, eventData.EventID, eventData.Lang);
			AddNotifyToQueue(new TypedNotifyMessage(applyUpperCase ? text.ToUpperInvariant() : text, typedNotifyParameters.type, typedNotifyParameters.showMessageDuration, typedNotifyParameters.showFadeAnimationDuration, typedNotifyParameters.hideFadeAnimationDuration));
		}

		public virtual void AddNotifyToQueue(string message, string type)
		{
			TypedNotifyParameters typedNotifyParameters = GetTypedNotifyParameters(type);
			AddNotifyToQueue(new TypedNotifyMessage(message, type, typedNotifyParameters.showMessageDuration, typedNotifyParameters.showFadeAnimationDuration, typedNotifyParameters.hideFadeAnimationDuration));
		}

		public virtual void AddNotifyToQueue(TypedNotifyMessage notifyMessage)
		{
			if (!isInitiated)
			{
				Log("error, attempt to use the manager before init completed");
				return;
			}
			if (notifyMessage == null)
			{
				Log("error, message is null");
				return;
			}
			messages.Enqueue(notifyMessage);
			Log("add new notify message: " + notifyMessage.message);
		}

		public virtual void ClearNotifyQueue()
		{
			if (isInitiated)
			{
				messages.Clear();
			}
		}

		public virtual void StopCurrentNotify()
		{
			CurrentMessage = null;
			isShowAnimationStageFinished = true;
			isShowMessageStageFinished = true;
			isHideAnimationStageFinished = true;
			isMessageProcessed = false;
		}

		protected virtual void Update()
		{
			try
			{
				if (!isInitiated)
				{
					return;
				}
				if (CurrentMessage == null)
				{
					if (delayAfterNotify > 0f)
					{
						delayAfterNotify -= Time.deltaTime;
					}
					else if (messages.Count > 0)
					{
						CurrentMessage = messages.Peek();
						CurrentNotifyParameters = GetTypedNotifyParameters(CurrentMessage.messageType);
						delayAfterNotify = CurrentNotifyParameters.delayAfterNotify;
						StartShowAnimation();
					}
					return;
				}
				if (!isShowAnimationStageFinished)
				{
					UpdateProcessShowAnimation();
				}
				else if (!isShowMessageStageFinished)
				{
					UpdateProcessNoAnimationStage();
				}
				else if (!isHideAnimationStageFinished)
				{
					UpdateProcessHideAnimation();
				}
				if (isMessageProcessed)
				{
					messages.Dequeue();
					CurrentMessage = null;
					isMessageProcessed = false;
				}
			}
			catch (Exception obj)
			{
				LimitedLogError(obj);
			}
		}

		protected virtual void UpdateProcessShowAnimation()
		{
			if (CurrentMessage.showFadeAnimationDuration > 0f)
			{
				CurrentMessage.showFadeAnimationDuration -= Time.deltaTime;
			}
			else
			{
				FinishShowAnimation();
			}
		}

		protected virtual void UpdateProcessNoAnimationStage()
		{
			if (CurrentMessage.showMessageDuration > 0f)
			{
				CurrentMessage.showMessageDuration -= Time.deltaTime;
			}
			else
			{
				StartHideAnimation();
			}
		}

		protected virtual void UpdateProcessHideAnimation()
		{
			if (CurrentMessage.hideFadeAnimationDuration > 0f)
			{
				CurrentMessage.hideFadeAnimationDuration -= Time.deltaTime;
			}
			else
			{
				FinishHideAnimation();
			}
		}

		protected virtual void Start()
		{
		}

		protected virtual void Awake()
		{
		}

		protected virtual void OnGUI()
		{
		}

		protected virtual void StartShowAnimation()
		{
			isShowAnimationStageFinished = false;
			Log("start show animation");
		}

		protected virtual void FinishShowAnimation()
		{
			isShowAnimationStageFinished = true;
			isShowMessageStageFinished = false;
			Log("finish show animation");
		}

		protected virtual void StartHideAnimation()
		{
			isHideAnimationStageFinished = false;
			isShowMessageStageFinished = true;
			Log("start hide animation");
		}

		protected virtual void FinishHideAnimation()
		{
			isHideAnimationStageFinished = true;
			isMessageProcessed = true;
			Log("finish hide animation");
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void ClearMessageTextures()
		{
			if (messageTextures == null)
			{
				return;
			}
			foreach (Texture2D value in messageTextures.Values)
			{
				((Object)value).hideFlags = (HideFlags)61;
				Object.Destroy((Object)(object)value);
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!isDisposed)
			{
				ClearMessageTextures();
				messageTextures = null;
				isDisposed = true;
			}
		}

		~TypedNotifyBase()
		{
			try
			{
				Dispose(disposing: false);
			}
			finally
			{
				((object)this).Finalize();
			}
		}

		public void RegisterPostProcessEvent(string key, IPostProcessText e)
		{
			if (string.IsNullOrEmpty(key) || e == null)
			{
				IDebugLogger obj = logger;
				if (obj != null)
				{
					((ILogger)obj).LogError((object)("TypedNotifyOnGUI RegisterPostProcessEvent invalid arg error for key '" + key + "'"));
				}
			}
			else
			{
				postProcessEvents[key] = e;
			}
		}

		protected string PostProcessEvent(string text, string eventKey, string langKey)
		{
			if (string.IsNullOrEmpty(eventKey) || text == null)
			{
				IDebugLogger obj = logger;
				if (obj != null)
				{
					((ILogger)obj).LogWarning((object)("TypedNotifyOnGUI PostProcessEvent invalid arg error for key '" + eventKey + "', text " + text));
				}
				return text;
			}
			if (!postProcessEvents.TryGetValue(eventKey, out var value))
			{
				return text;
			}
			return value.PostProcessText(text, langKey);
		}
	}
	public static class UtilityUI
	{
		public static int StandardScreenWidth => 2560;

		public static int StandardScreenHeight => 1440;

		public static string GetColoredText(string text, Color32 color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string text2 = ColorUtility.ToHtmlStringRGBA(Color32.op_Implicit(color));
			return "<color=#" + text2 + ">" + text + "</color>";
		}

		public static Texture2D LoadImage(string imageFilePath, Func<string, byte[]> customFileReader = null)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0025: Expected O, but got Unknown
			byte[] array = ((customFileReader == null) ? File.ReadAllBytes(imageFilePath) : customFileReader(imageFilePath));
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, array);
			return val;
		}

		public static float CalcScreenFactor(int baseScreenSize, int currentScreenSize)
		{
			if (baseScreenSize != currentScreenSize)
			{
				return (float)currentScreenSize / (float)baseScreenSize;
			}
			return 1f;
		}
	}
	public class MathUtility
	{
		public static bool RandomBool()
		{
			return Random.value > 0.5f;
		}

		public static int GetRandomSign()
		{
			if (!RandomBool())
			{
				return 1;
			}
			return -1;
		}

		public static Vector3 GetRandomPointOnCircle(float radius = 1f)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			return Vector2.op_Implicit(((Vector2)(ref insideUnitCircle)).normalized * radius);
		}

		public static Vector3 GetRandomPointOnCircleInForward(Vector3 forward, float radiusMin, float radiusMax, float minAngleInDeg = -90f, float maxAngleInDeg = 90f)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = forward;
			val.y = 0f;
			val = ((Vector3)(ref val)).normalized;
			if (minAngleInDeg > maxAngleInDeg)
			{
				float num = minAngleInDeg;
				minAngleInDeg = maxAngleInDeg;
				maxAngleInDeg = num;
			}
			float num2 = Random.Range(minAngleInDeg, maxAngleInDeg);
			if (radiusMin < 0f)
			{
				radiusMin = 0f;
			}
			if (radiusMax < 0f)
			{
				radiusMax = 1f;
			}
			if (radiusMin > radiusMax)
			{
				float num3 = radiusMin;
				radiusMin = radiusMax;
				radiusMax = num3;
			}
			float num4 = Random.Range(radiusMin, radiusMax);
			Vector3 result = default(Vector3);
			float num5 = (float)Math.PI / 180f * num2;
			float num6 = Mathf.Atan2(val.z, val.x);
			num5 += num6;
			result.x = num4 * Mathf.Cos(num5);
			result.z = num4 * Mathf.Sin(num5);
			return result;
		}

		public static Vector3 FindRandomSpawnPointNearPosition(Vector3 pos, float minDistance, float maxDistance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (maxDistance < 0f)
			{
				maxDistance = 10f;
			}
			if (minDistance < 0f || minDistance > maxDistance)
			{
				minDistance = 0f;
			}
			Vector3 result = default(Vector3);
			float num = Random.Range(-(float)Math.PI, (float)Math.PI);
			float num2 = Random.Range(minDistance, maxDistance);
			result.x = Mathf.Floor(pos.x + num2 * Mathf.Cos(num));
			result.z = Mathf.Floor(pos.z + num2 * Mathf.Sin(num));
			result.y = pos.y;
			return result;
		}

		public static Vector3 FindRandomSpawnPointNearPositionFixY(Vector3 pos, float minDistance, float maxDistance, float yFixOffset, LayerMask mask)
		{
			//IL_0000: 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)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = FindRandomSpawnPointNearPosition(pos, minDistance, maxDistance);
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(pos + Vector3.up * 10f, Vector3.down, ref val, 10f, LayerMask.op_Implicit(mask)))
			{
				result = ((RaycastHit)(ref val)).point;
				result.y += yFixOffset;
			}
			return result;
		}

		public static Vector3 GetRandomVector(Vector3 randomRangeMin, Vector3 randomRangeMax)
		{
			//IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(randomRangeMin.x, randomRangeMax.x);
			float num2 = Random.Range(randomRangeMin.y, randomRangeMax.y);
			float num3 = Random.Range(randomRangeMin.z, randomRangeMax.z);
			return new Vector3(num, num2, num3);
		}

		public static void LookAt(Transform obj, Transform target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = target.position - obj.position;
			obj.rotation = Quaternion.LookRotation(val);
		}
	}
	public static class Loader
	{
		private const string ASSEMBLY_NAME = "InteractiveMod";

		private const string CLASS_MOD = "InteractiveMod";

		private static ILogger logger;

		private static GameObject hookObj;

		static Loader()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			logger = (ILogger)new HelperLog(UtilitySettings.BaseFolder, "loader_log.txt");
			logger.LogClear();
		}

		public static async Task StartInitTask(Type type, int delayInMs)
		{
			int counter = 0;
			do
			{
				await Task.Delay(delayInMs);
				if ((Object)(object)hookObj == (Object)null)
				{
					logger.LogInfo((object)"Background task: trying to create mod instance");
					hookObj = new GameObject();
					Object.DontDestroyOnLoad((Object)(object)hookObj);
					hookObj.AddComponent(type);
					hookObj.SetActive(true);
				}
				int num = counter + 1;
				counter = num;
			}
			while (counter <= 10 && (!((Object)(object)hookObj != (Object)null) || counter <= 2));
			logger.LogInfo((object)"Background task closed");
		}

		public static void HotReload(int delayInMs = 1000)
		{
			if ((Object)(object)hookObj != (Object)null)
			{
				hookObj.SetActive(false);
				GameObject obj = hookObj;
				hookObj = null;
				Object.DestroyImmediate((Object)(object)obj);
			}
			LoadAssembly(delayInMs);
		}

		public static void LoadAssembly(int delayInMs = 5000)
		{
			logger.LogInfo((object)"load mod assembly");
			string text = Path.Combine(Preloader.GetAssemblyModFolderFullPath(), "InteractiveMod.dll");
			logger.LogInfo((object)("load mod assembly at " + text));
			byte[] rawAssembly;
			using (MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(text)))
			{
				rawAssembly = memoryStream.ToArray();
			}
			Assembly assembly = AppDomain.CurrentDomain.Load(rawAssembly);
			CancellationToken token = new CancellationTokenSource().Token;
			if (!string.Equals(assembly.GetName().Name, "InteractiveMod", StringComparison.OrdinalIgnoreCase))
			{
				logger.LogError((object)"wrong assembly mod name");
				return;
			}
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				bool num = string.Equals(type.Name, "InteractiveMod", StringComparison.OrdinalIgnoreCase);
				Type typeFromHandle = typeof(MonoBehaviour);
				if (!num || (!type.IsAssignableFrom(typeFromHandle) && !type.IsSubclassOf(typeFromHandle)))
				{
					continue;
				}
				logger.LogInfo((object)"Found valid type in Loader class");
				Task.Factory.StartNew((Func<Task>)async delegate
				{
					try
					{
						await StartInitTask(type, delayInMs);
					}
					catch (Exception arg)
					{
						logger.LogError((object)$"LoadAssembly task error {arg}");
					}
				}, token, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
				return;
			}
			logger.LogError((object)"init failed");
		}

		public static void Init()
		{
			logger.LogInfo((object)"Loader triggered");
			try
			{
				LoadAssembly();
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"ModHelperUnity.Init {arg}");
			}
		}
	}
	public class Patcher
	{
		private readonly ILogger logger = (ILogger)new HelperLog(UtilitySettings.BaseFolder, "patcher_log.txt");

		private bool isPatched;

		internal void ExecutePatch()
		{
			try
			{
				logger.LogClear();
				logger.LogInfo((object)$"Patcher v{Assembly.GetExecutingAssembly().GetName().Version}");
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Patcher unexpected error: {arg}");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			try
			{
				logger.Log((object)("OnSceneLoaded triggered: " + ((Scene)(ref scene)).name));
				if (!isPatched)
				{
					Loader.Init();
					isPatched = true;
					SceneManager.sceneLoaded -= OnSceneLoaded;
				}
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Patcher unexpected error: {arg}");
			}
		}
	}
	public static class Preloader
	{
		private static string baseFolderFullPath;

		private static readonly ILogger logger = (ILogger)new HelperLog(UtilitySettings.BaseFolder, "preloader_log.txt");

		public static string GetAssemblyModFolderFullPath()
		{
			return baseFolderFullPath;
		}

		public static void Main()
		{
			logger.LogClear();
			logger.LogInfo((object)"Preloader main");
			baseFolderFullPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			logger.LogInfo((object)("base path: " + baseFolderFullPath));
			AppDomain.CurrentDomain.AssemblyResolve += ModAssemblyResolve;
			new Patcher().ExecutePatch();
		}

		private static Assembly ModAssemblyResolve(object sender, ResolveEventArgs args)
		{
			try
			{
				string text = Path.Combine(GetAssemblyModFolderFullPath(), new AssemblyName(args.Name).Name + ".dll");
				logger.LogInfo((object)text);
				if (File.Exists(text))
				{
					return Assembly.LoadFrom(text);
				}
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"error: {arg}");
			}
			return null;
		}
	}
}
namespace ModHelperUnity.UtilityGUI
{
	public class TypedNotifyOnGUI : TypedNotifyBase
	{
		private float currentAlpha;

		private float targetAlpha;

		protected Dictionary<string, Font> fonts;

		public override void ForcePostInit(string folderPath, IDebugLogger logger = null, Func<string, byte[]> customFileReader = null)
		{
			base.ForcePostInit(folderPath, logger, customFileReader);
			try
			{
				fonts = new Dictionary<string, Font>();
				TypedNotifyParameters[] notifyParameters = base.Settings.notifyParameters;
				foreach (TypedNotifyParameters typedNotifyParameters in notifyParameters)
				{
					try
					{
						string fontPath = typedNotifyParameters.fontPath;
						if (!fonts.ContainsKey(fontPath))
						{
							Font val = Resources.Load<Font>(fontPath);
							if ((Object)(object)val != (Object)null)
							{
								fonts.Add(fontPath, val);
							}
						}
					}
					catch (Exception arg)
					{
						if (logger != null)
						{
							((ILogger)logger).LogError((object)$"TypedNotifyOnGUI loading font: {arg}");
						}
					}
				}
			}
			catch (Exception arg2)
			{
				if (logger != null)
				{
					((ILogger)logger).LogError((object)$"TypedNotifyOnGUI PostInit: {arg2}");
				}
			}
		}

		protected Font GetFont(string path, int size)
		{
			try
			{
				if (fonts.ContainsKey(path))
				{
					return fonts[path];
				}
				string key = $"{path}_{size}";
				if (fonts.ContainsKey(key))
				{
					return fonts[key];
				}
				Font val = Font.CreateDynamicFontFromOSFont(path, size);
				if ((Object)(object)val != (Object)null)
				{
					fonts.Add(key, val);
				}
				return val;
			}
			catch (Exception arg)
			{
				IDebugLogger obj = logger;
				if (obj != null)
				{
					((ILogger)obj).LogError((object)$"TypedNotifyOnGUI finding font: {arg}");
				}
			}
			return null;
		}

		protected virtual void SetupAlpha(float baseDuration)
		{
			if (!Mathf.Approximately(currentAlpha, targetAlpha))
			{
				currentAlpha = Mathf.MoveTowards(currentAlpha, targetAlpha, Time.deltaTime / baseDuration);
			}
		}

		protected override void UpdateProcessShowAnimation()
		{
			SetupAlpha(base.CurrentNotifyParameters.showFadeAnimationDuration);
			base.UpdateProcessShowAnimation();
		}

		protected override void UpdateProcessNoAnimationStage()
		{
			SetupAlpha(base.CurrentNotifyParameters.showMessageDuration);
			base.UpdateProcessNoAnimationStage();
		}

		protected override void UpdateProcessHideAnimation()
		{
			SetupAlpha(base.CurrentNotifyParameters.hideFadeAnimationDuration);
			base.UpdateProcessHideAnimation();
		}

		protected override void StartShowAnimation()
		{
			base.StartShowAnimation();
			targetAlpha = 1f;
		}

		protected override void StartHideAnimation()
		{
			base.StartHideAnimation();
			targetAlpha = 0f;
		}

		protected string GetFadedText(string text)
		{
			string text2 = ((int)(255f * currentAlpha)).ToString("X2");
			return text.Replace("FF>", text2 + ">");
		}

		protected override void OnGUI()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			base.OnGUI();
			TypedNotifyParameters currentNotifyParameters = base.CurrentNotifyParameters;
			if (!base.Settings.isDisableNotify && base.CurrentMessage != null && currentNotifyParameters != null && !currentNotifyParameters.isDisable)
			{
				Matrix4x4 matrix = GUI.matrix;
				Color color = GUI.color;
				color.a = currentAlpha;
				GUI.color = color;
				Texture2D messageTexture = GetMessageTexture(base.CurrentMessage.messageType);
				float num = UtilityUI.CalcScreenFactor(UtilityUI.StandardScreenWidth, Screen.width);
				float num2 = UtilityUI.CalcScreenFactor(UtilityUI.StandardScreenHeight, Screen.height);
				float num3 = (float)((Texture)messageTexture).width * num;
				float num4 = (float)((Texture)messageTexture).height * num2;
				Rect val = default(Rect);
				((Rect)(ref val)).x = ((float)Screen.width - num3) * (0.5f + currentNotifyParameters.notifyHorizontalOffset);
				((Rect)(ref val)).y = ((float)Screen.height - num4) * (0.5f + currentNotifyParameters.notifyVerticalOffset);
				((Rect)(ref val)).width = num3;
				((Rect)(ref val)).height = num4;
				Rect val2 = val;
				float num5 = Math.Min(num, num2);
				float num6 = Math.Max(num, num2);
				int num7 = (int)((float)currentNotifyParameters.fontSize * num5);
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = num7,
					alignment = (TextAnchor)4,
					richText = true,
					fixedWidth = num3,
					fixedHeight = num4
				};
				Font font = GetFont(currentNotifyParameters.fontPath, num7);
				if ((Object)(object)font != (Object)null)
				{
					val3.font = font;
				}
				val3.padding.top = (int)((float)currentNotifyParameters.textPadding.top * num6);
				val3.padding.bottom = (int)((float)currentNotifyParameters.textPadding.bottom * num6);
				val3.padding.left = (int)((float)currentNotifyParameters.textPadding.left * num6);
				val3.padding.right = (int)((float)currentNotifyParameters.textPadding.right * num6);
				val3.normal.textColor = color;
				GUI.DrawTexture(val2, (Texture)(object)messageTexture);
				GUI.Label(val2, GetFadedText(base.CurrentMessage.message), val3);
				GUI.matrix = matrix;
			}
		}
	}
	public class TypedNotifySettings
	{
		public bool isDisableNotify;

		public TypedNotifyParameters[] notifyParameters = new TypedNotifyParameters[0];

		public override string ToString()
		{
			if (notifyParameters == null)
			{
				return "TypedNotifySettings: not found notifyParameters";
			}
			string text = $"isDisableNotify={isDisableNotify}";
			TypedNotifyParameters[] array = notifyParameters;
			for (int i = 0; i < array.Length; i++)
			{
				_ = array[i];
				text = string.Join(Environment.NewLine, text, "notifyParameters:", notifyParameters.ToString());
			}
			return text;
		}
	}
}
namespace ModHelperUnity.Interfaces
{
	public interface IComponentTypedNotify
	{
		void AddNotifyToQueue(string message, string type);

		void AddNotifyToQueue(IEventsData eventData, ITranslation translation, Func<string, string> converter = null, bool applyUpperCase = true);

		void ClearNotifyQueue();

		void StopCurrentNotify();

		void PostInit(string folderPath, IDebugLogger logger = null, Func<string, byte[]> customFileReader = null);

		void ForcePostInit(string folderPath, IDebugLogger logger = null, Func<string, byte[]> customFileReader = null);

		void RegisterPostProcessEvent(string key, IPostProcessText e);
	}
	public interface IPostProcessText
	{
		string PostProcessText(string text, string langKey);
	}
	public interface ISoundManager
	{
		void PlaySound(string path, int volume = 50);

		void StopSound();
	}
	public interface IDictionaryItemJson<T>
	{
		string Key { get; }

		T Value { get; }
	}
}
namespace ModHelperUnity.Data
{
	public class TypedNotifyParameters
	{
		public bool isDisable;

		public string imageFileName = string.Empty;

		public string type = "default";

		public string messageTemplate = "%name% %message%";

		public string fontPath = "";

		public float showMessageDuration = 5f;

		public float showFadeAnimationDuration = 1f;

		public float hideFadeAnimationDuration = 1f;

		public float delayAfterNotify = 1f;

		public float notifyHorizontalOffset;

		public float notifyVerticalOffset = -0.45f;

		public int fontSize = 19;

		public Padding textPadding = new Padding
		{
			bottom = 20,
			top = 20,
			left = 24,
			right = 24
		};

		public Color32 nicknameTextColor = new Color32((byte)65, (byte)160, (byte)94, byte.MaxValue);

		public Color32 messageTextColor = new Color32((byte)65, (byte)160, (byte)94, byte.MaxValue);

		public string[] events = new string[0];

		public override string ToString()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			return string.Join(Environment.NewLine, "imageFileName: " + imageFileName, "type: " + type, $"showMessageDuration: {showMessageDuration}", $"showFadeAnimationDuration: {showFadeAnimationDuration}", $"hideFadeAnimationDuration: {hideFadeAnimationDuration}", $"delayAfterNotify: {delayAfterNotify}", $"notifyHorizontalOffset: {notifyHorizontalOffset}", $"notifyVerticalOffset: {notifyVerticalOffset}", $"textPadding: {textPadding}", $"fontSize: {fontSize}", $"isDisable: {isDisable}", $"nicknameTextColor: {nicknameTextColor}", $"messageTextColor: {messageTextColor}", "events: " + string.Join(Environment.NewLine, events), "fontPath: " + fontPath);
		}
	}
	public class Padding
	{
		public int left;

		public int right;

		public int top;

		public int bottom;

		public Padding()
		{
		}

		public Padding(int left, int right, int top, int bottom)
		{
			this.left = left;
			this.right = right;
			this.top = top;
			this.bottom = bottom;
		}

		public RectOffset GetRect()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return new RectOffset(left, right, top, bottom);
		}

		public override string ToString()
		{
			return $"left: {left}, right: {right}, top: {top}, bottom: {bottom}";
		}
	}
	public class TypedNotifyMessage
	{
		public readonly string message;

		public readonly string messageType;

		public float showMessageDuration;

		public float showFadeAnimationDuration;

		public float hideFadeAnimationDuration;

		public TypedNotifyMessage(string message, string messageType, float showMessageDuration, float showFadeAnimationDuration, float hideFadeAnimationDuration)
		{
			this.message = (string.IsNullOrEmpty(message?.Trim()) ? string.Empty : message);
			this.messageType = messageType;
			this.showMessageDuration = showMessageDuration;
			this.showFadeAnimationDuration = showFadeAnimationDuration;
			this.hideFadeAnimationDuration = hideFadeAnimationDuration;
		}
	}
	public class NotifyMessage
	{
		private readonly string msg;

		private float durationInSec;

		public NotifyMessage(string msg, float durationInSec)
		{
			this.msg = (string.IsNullOrEmpty(msg?.Trim()) ? string.Empty : msg);
			this.durationInSec = durationInSec;
		}

		public string GetMessage()
		{
			return msg;
		}

		public bool IsFinished()
		{
			return durationInSec <= 0f;
		}

		public void OnFrame(float dtInSec)
		{
			if (!IsFinished())
			{
				durationInSec -= dtInSec;
			}
		}
	}
}

ChaosTricks_PEAK_plugins/WebSocketIO.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using EventsIO;
using EventsIO.Interfaces;
using ModHelper;
using ModHelper.Interfaces;
using WebSocketIO.Data;
using WebSocketSharp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("WebSocketIO")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BFT")]
[assembly: AssemblyProduct("WebSocketIO")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("27b98c5b-ac6a-4518-ae12-3c9957b291e4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace WebSocketIO
{
	public class ChaosWebSocketHandler
	{
		public const string TypeEventMessage = "event";

		public const string TypeConfigMessage = "config";

		public bool isEnableDebugLog = true;

		public bool isEnableDebugLogOnClose;

		public bool isEnableDebugLogOnOpen;

		public bool isEnableDebugLogOnCloseValidConnect = true;

		protected bool isNeedLogOnCloseValidConnect;

		protected ILogger logger;

		public Action<string, string> OnCustomMessage { get; set; }

		public Action<string> OnEventMessage { get; set; }

		public Action<string> OnConfigMessage { get; set; }

		public Action OnWebSocketOpen { get; set; }

		public Action<CloseEventArgs> OnWebSocketClose { get; set; }

		public Action<ErrorEventArgs> OnWebSocketError { get; set; }

		public ChaosWebSocketHandler(ILogger logger = null)
		{
			this.logger = logger;
		}

		protected void DebugWebSocketLog(string s)
		{
			if (isEnableDebugLog && logger != null)
			{
				logger.LogInfo((object)("[DEBUG] ChaosTricks WebSocketHandler: " + s));
			}
		}

		protected void DebugWebSocketLogError(string s)
		{
			if (isEnableDebugLog && logger != null)
			{
				logger.LogError((object)("[DEBUG] ChaosTricks WebSocketHandler: " + s));
			}
		}

		public void OnOpen()
		{
			if (isEnableDebugLogOnOpen)
			{
				DebugWebSocketLog("OnOpen");
			}
			try
			{
				if (isEnableDebugLogOnCloseValidConnect)
				{
					isNeedLogOnCloseValidConnect = true;
				}
				OnWebSocketOpen?.Invoke();
			}
			catch (Exception arg)
			{
				if (isEnableDebugLogOnOpen)
				{
					DebugWebSocketLogError($"OnOpen {arg}");
				}
			}
		}

		public void OnClose(CloseEventArgs e)
		{
			if (isEnableDebugLogOnClose)
			{
				DebugWebSocketLog("OnClose " + e.Reason);
			}
			try
			{
				OnWebSocketClose?.Invoke(e);
			}
			catch (Exception arg)
			{
				if (isEnableDebugLogOnClose)
				{
					DebugWebSocketLogError($"OnClose {arg}");
				}
				else if (isEnableDebugLogOnCloseValidConnect && isNeedLogOnCloseValidConnect)
				{
					isNeedLogOnCloseValidConnect = false;
					DebugWebSocketLogError($"OnClose {arg}");
				}
			}
		}

		public void OnError(ErrorEventArgs e)
		{
			DebugWebSocketLogError("Error " + e.Message);
			try
			{
				OnWebSocketError?.Invoke(e);
			}
			catch (Exception arg)
			{
				DebugWebSocketLogError($"OnError inner error {arg}");
			}
		}

		public WebSocketMessage ParseWebSocketMessage(string data)
		{
			try
			{
				return UtilityJson.Generate((IDebugLogger)null).FromString<WebSocketMessage>(data) ?? new WebSocketMessage();
			}
			catch (Exception arg)
			{
				DebugWebSocketLogError($"ParseWebSocketMessage {arg}");
				return new WebSocketMessage();
			}
		}

		public void OnMessage(MessageEventArgs e)
		{
			if (!e.IsText)
			{
				return;
			}
			try
			{
				WebSocketMessage webSocketMessage = ParseWebSocketMessage(e.Data);
				string type = webSocketMessage.type;
				string data = webSocketMessage.data;
				if (!(type == "config"))
				{
					if (type == "event")
					{
						DebugWebSocketLog("OnMessage - event");
						OnEventMessage?.Invoke(data);
					}
					else
					{
						DebugWebSocketLog("OnMessage - custom msg");
						OnCustomMessage?.Invoke(type, data);
					}
				}
				else
				{
					DebugWebSocketLog("OnMessage - config");
					OnConfigMessage?.Invoke(data);
				}
			}
			catch (Exception arg)
			{
				DebugWebSocketLogError($"OnMessage {arg}");
			}
		}
	}
	public class WebSocketEventsReader<T> : EventsReaderOnFrame, IDisposable where T : class
	{
		protected object locker = new object();

		protected List<string> eventListFromSocket = new List<string>();

		protected bool isDisposed;

		protected bool isSocketMessageProcessing;

		public bool isAutoRequestSettingsOnOpen = true;

		public bool isAutoConnectOnRead = true;

		public const int DEFAULT_PORT = 13715;

		public float autoConnectOnReadPeriod = 8f;

		protected float autoConnectOnReadPeriodTicks;

		protected bool isNeedLogOnClose;

		protected bool logOnConnectionError;

		public virtual ChaosWebSocketHandler SocketHandler { get; set; }

		public virtual WebSocket Socket { get; set; }

		public virtual T Settings { get; protected set; }

		public Action<MessageEventArgs> OnMessage { get; set; }

		public Action OnOpen { get; set; }

		public Action<CloseEventArgs> OnCloseOnlyAfterConnect { get; set; }

		public Action<ErrorEventArgs> OnErrorOnlyAfterConnect { get; set; }

		public Action<CloseEventArgs> OnClose { get; set; }

		public Action<ErrorEventArgs> OnError { get; set; }

		public WebSocketEventsReader(Action<IEventsData> processEvent, IEventsDataParser parser, Action<string> log = null, Action<string> errorLog = null, float checkPeriod = 2f, float delay = 1f, float initDelay = 0.5f, bool logOnConnectionError = false)
			: base("", processEvent, parser, log, errorLog, checkPeriod, delay, initDelay)
		{
			this.logOnConnectionError = logOnConnectionError;
		}

		public virtual int GetPortFromSettingsOrDefault(string settingsDir)
		{
			try
			{
				string path = Path.Combine(settingsDir, "ChaosWebSocketConfig.txt");
				if (File.Exists(path))
				{
					return int.Parse(File.ReadAllLines(path)[0]);
				}
			}
			catch (Exception arg)
			{
				((EventsReader)this).ReaderLogError($"GetPortFromSettingsOrDefault error: {arg}. (will be used {13715})");
			}
			return 13715;
		}

		public virtual T ParseSettings(string data)
		{
			try
			{
				T result = UtilityJson.Generate((IDebugLogger)null).FromString<T>(data);
				((EventsReader)this).ReaderLog("settings parsing completed: " + data);
				return result;
			}
			catch (Exception arg)
			{
				((EventsReader)this).ReaderLogError($"error: {arg}.\nCan't parse settings. Using standard.");
			}
			T result2 = null;
			try
			{
				result2 = Activator.CreateInstance<T>();
				return result2;
			}
			catch (Exception arg2)
			{
				((EventsReader)this).ReaderLogError($"error: {arg2}.\nCan't create default data class.");
				return result2;
			}
		}

		public virtual void OpenSocket(bool isLogOnError = true)
		{
			WebSocket socket = Socket;
			try
			{
				if (socket != null && !socket.IsAlive)
				{
					((EventsReader)this).ReaderLog("try to open socket connection");
					socket.ConnectAsync();
				}
			}
			catch (Exception arg)
			{
				if (isLogOnError)
				{
					((EventsReader)this).ReaderLogError($"OpenSocket error: {arg}");
				}
				try
				{
					socket.Close();
				}
				catch (Exception)
				{
				}
			}
		}

		public virtual void CloseSocket()
		{
			try
			{
				WebSocket socket = Socket;
				if (socket != null)
				{
					socket.Close();
				}
			}
			catch (Exception arg)
			{
				((EventsReader)this).ReaderLogError($"CloseSocket error: {arg}");
			}
		}

		public virtual void RequestSettings()
		{
			try
			{
				WebSocket socket = Socket;
				if (socket != null)
				{
					socket.Send(new WebSocketMessage("config", "").ToString());
				}
			}
			catch (Exception arg)
			{
				((EventsReader)this).ReaderLogError($"RequestSettings error: {arg}");
			}
		}

		public virtual void InitDefaultSocket(string settingsDir, string room, int port, string ip = "127.0.0.1")
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			WebSocket val = new WebSocket($"ws://{ip}:{port}/{room}", Array.Empty<string>());
			ChaosWebSocketHandler socketHandler = new ChaosWebSocketHandler
			{
				OnEventMessage = delegate(string data)
				{
					isSocketMessageProcessing = true;
					lock (locker)
					{
						eventListFromSocket.Add(data);
					}
					isSocketMessageProcessing = false;
				},
				OnConfigMessage = delegate(string data)
				{
					Settings = ParseSettings(data);
				},
				OnWebSocketOpen = delegate
				{
					isNeedLogOnClose = true;
					((EventsReader)this).ReaderLog("ChaosTricks connected");
					if (isAutoRequestSettingsOnOpen)
					{
						RequestSettings();
					}
					try
					{
						OnOpen?.Invoke();
					}
					catch (Exception arg6)
					{
						((EventsReader)this).ReaderLogError($"ChaosTricks custom OnOpen error: {arg6}");
					}
				},
				OnWebSocketClose = delegate(CloseEventArgs e)
				{
					if (isNeedLogOnClose)
					{
						isNeedLogOnClose = false;
						((EventsReader)this).ReaderLog($"ChaosTricks disconnected {e.Reason} {e.Code}");
						try
						{
							OnCloseOnlyAfterConnect?.Invoke(e);
						}
						catch (Exception arg4)
						{
							((EventsReader)this).ReaderLogError($"ChaosTricks custom OnClose after success connection error: {arg4}");
						}
					}
					try
					{
						OnClose?.Invoke(e);
					}
					catch (Exception arg5)
					{
						((EventsReader)this).ReaderLogError($"ChaosTricks custom OnClose error: {arg5}");
					}
				},
				OnWebSocketError = delegate(ErrorEventArgs e)
				{
					if (isNeedLogOnClose)
					{
						((EventsReader)this).ReaderLog($"ChaosTricks ws error {e.Message} {e.Exception}");
						try
						{
							OnErrorOnlyAfterConnect?.Invoke(e);
						}
						catch (Exception arg2)
						{
							((EventsReader)this).ReaderLogError($"ChaosTricks custom OnError after success connection error: {arg2}");
						}
					}
					try
					{
						OnError?.Invoke(e);
					}
					catch (Exception arg3)
					{
						((EventsReader)this).ReaderLogError($"ChaosTricks custom OnError error: {arg3}");
					}
				}
			};
			val.OnMessage += delegate(object sender, MessageEventArgs e)
			{
				socketHandler.OnMessage(e);
				try
				{
					OnMessage?.Invoke(e);
				}
				catch (Exception arg)
				{
					((EventsReader)this).ReaderLogError($"ChaosTricks custom OnMessage error: {arg}");
				}
			};
			val.OnOpen += delegate
			{
				socketHandler.OnOpen();
			};
			val.OnClose += delegate(object sender, CloseEventArgs e)
			{
				socketHandler.OnClose(e);
			};
			val.OnError += delegate(object sender, ErrorEventArgs e)
			{
				socketHandler.OnError(e);
			};
			if (!File.Exists(Path.Combine(settingsDir ?? "", ".debug_websocket")))
			{
				val.Log.Level = (LogLevel)10;
			}
			SocketHandler = socketHandler;
			Socket = val;
			SetSocketForConnectLimit(val, int.MaxValue);
		}

		public void SetSocketForConnectLimit(WebSocket ws, int max)
		{
			FieldInfo field = ((object)ws).GetType().GetField("_maxRetryCountForConnect", BindingFlags.Static | BindingFlags.NonPublic);
			if (field == null)
			{
				((EventsReader)this).ReaderLogError("FixSocketLimit error, maxRetryField is null");
			}
			else
			{
				field.SetValue(ws, max);
			}
		}

		public override string[] ReadAll(string path, bool isClearFile = true)
		{
			string[] result = null;
			if (!isSocketMessageProcessing)
			{
				lock (locker)
				{
					if (eventListFromSocket.Count > 0)
					{
						result = eventListFromSocket.ToArray();
						eventListFromSocket.Clear();
					}
				}
			}
			return result;
		}

		public override void ReadAndProcessAllWithDelayOnFrame(float dt)
		{
			if (isAutoConnectOnRead)
			{
				autoConnectOnReadPeriodTicks += dt;
				if (autoConnectOnReadPeriodTicks > autoConnectOnReadPeriod)
				{
					autoConnectOnReadPeriodTicks = 0f;
					OpenSocket(logOnConnectionError);
				}
			}
			((EventsReaderOnFrame)this).ReadAndProcessAllWithDelayOnFrame(dt);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!isDisposed)
			{
				isDisposed = true;
				if (disposing)
				{
					((IDisposable)Socket)?.Dispose();
				}
			}
		}

		~WebSocketEventsReader()
		{
			try
			{
				Dispose(disposing: false);
			}
			finally
			{
				((object)this).Finalize();
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
}
namespace WebSocketIO.Interfaces
{
	public interface IChaosWebSocket
	{
		void Start();

		void Stop();
	}
}
namespace WebSocketIO.Data
{
	public class WebSocketMessage
	{
		public string type = "";

		public string data = "";

		public WebSocketMessage()
		{
		}

		public WebSocketMessage(string type, string data)
		{
			this.type = type;
			this.data = data;
		}

		public override string ToString()
		{
			string text = data.Replace("\"", "\\\"");
			return "{\"type\":\"" + type + "\", \"data\":\"" + text + "\"}";
		}
	}
}