The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of ChaosTricks PEAK TwitchIntegration v1.1.0
ChaosTricks_PEAK_plugins/EventsIO.dll
Decompiled a month agousing 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 a month ago
The result has been truncated due to the large size, download it to view full contents!
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 BepInEx; using EventsIO; using EventsIO.Interfaces; using HarmonyLib; using ModHelper; using ModHelper.Interfaces; using ModHelper.Wrappers; using ModHelperUnity.Interfaces; using ModHelperUnity.TypedNotify; using ModHelperUnity.Utilities; 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.Base; using peak_bepinex.Commands.Interfaces; using peak_bepinex.Patchers; using peak_bepinex.Services; [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.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.1.0.0")] namespace peak_standalone.Commands { internal class CustomRevive : SyncLocalCommand, 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.1.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 { SettingsUtils.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.1.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.1.0", arg)); } } } internal static class CustomNotifyOnGUI { private static bool showNotify; private static Texture2D rectTexture; private static string notifyText; private static string prefixText; internal static void ShowNotify(bool show) { showNotify = show; } internal static void SetNotifyText(string prefix, string text) { prefixText = prefix; notifyText = text; } internal static void OnGUI() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0138: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_0021: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (showNotify) { if ((Object)(object)rectTexture == (Object)null) { rectTexture = new Texture2D(1, 1); rectTexture.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.7f)); rectTexture.Apply(); } float val = HelperUI.CalcScreenFactor(HelperUI.StandardScreenWidth, Screen.width); float val2 = HelperUI.CalcScreenFactor(HelperUI.StandardScreenHeight, Screen.height); float num = Math.Min(val, val2); float num2 = Math.Max(val, val2); int num3 = (int)(14f * num2); int num4 = (int)(7f * num2); int num5 = (int)(10f * num2); int fontSize = (int)(20f * num); GUIStyle val3 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, padding = new RectOffset(num3, num3, num4, num5), fontSize = fontSize, wordWrap = false }; val3.normal.background = rectTexture; string text = "<b><color=#c11fff>" + prefixText + "</color> " + notifyText + "</b>"; GUIContent val4 = new GUIContent(text); Vector2 val5 = val3.CalcSize(val4); GUI.Label(new Rect((float)Screen.width - val5.x, 0f, val5.x, val5.y), text, val3); } } } public static class GameUtils { 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 Character GetCharacterByNetworkID(int id) { foreach (Character player in Players) { if (!((Object)(object)player == (Object)null) && !((Object)(object)((MonoBehaviourPun)player).photonView == (Object)null) && ((MonoBehaviourPun)player).photonView.ViewID == id) { return player; } } return null; } 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 sealed class InteractiveMod : MonoBehaviour { public static InteractiveMod inst; internal const string MOD_VERSION = "1.1.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 CommandConsole console; private Dictionary<string, IInternalStandaloneCommand> commands; private TranslationService translationService; private LimitedLogWrapper limitedLogger; private LimitedLogWrapper limitedSceneLogger; private Language lastUsedLang = (Language)(-1); private bool readyToActivateEvents; private readonly List<IForceEnd> forceEndEvents = new List<IForceEnd>(); public void Awake() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown inst = this; ((HelperLog)logger).ClearLogBySize(200000, (Action<string>)Debug.LogError); 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.1.0"); FlushLog(); MainPatcher.InitPatch(); } public void Start() { ((HelperLog)logger).LogInfo((object)"InteractiveMod Start"); try { JsonUtils.RegisterCustomGenerator((Func<IJsonUtils>)(() => (IJsonUtils)(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(); serviceProvider.RegisterTranslationService(translationService); 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)); bool flag = name == "Airport"; readyToActivateEvents = !flag && name != "Title"; CustomNotifyOnGUI.ShowNotify(flag); } 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 CommandConsole((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) { if (string.IsNullOrEmpty(data.EventID)) { ((HelperLog)logger).LogError((object)"ProcessEvent eventID is null or empty"); return; } if (!PhotonNetwork.IsMasterClient) { int viewID = ((MonoBehaviourPun)Character.localCharacter).photonView.ViewID; ChaosModNetwork.RequestEventRPC((RpcTarget)2, new ChaosModNetwork.DataSource(viewID, data)); return; } ActivateEventLocally(data); if (GameUtils.Players.Count() <= 1) { return; } string text = commandManager.GetCommandData(data.EventID, true)?.Trim(); if (string.IsNullOrEmpty(text)) { ((HelperLog)Utils.logger).LogWarning((object)"ProcessEvent can't find commands"); return; } string[] eventCommands = CommandConsole.ParseCommandLine(text); if (ChaosModNetwork.AnyCommandRequiresNetworkSync(eventCommands, commands)) { ChaosModNetwork.ApplyCommandsHostEffects(eventCommands, -42, commands); ChaosModNetwork.RequestEventRPC((RpcTarget)1, new ChaosModNetwork.DataSource(-42, data)); } } private void ActivateEventLocally(IEventsData data) { string eventID = data.EventID; if (string.IsNullOrEmpty(eventID)) { ((HelperLog)logger).LogError((object)"ActivateEventLocally 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)$"ActivateEventLocally '{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); UpdateWarningText(); if (readyToActivateEvents) { eventEmitter.TriggerOnUpdateEvent(this, deltaTime); ((EventsReaderOnFrame)eventsReader).ReadAndProcessAllWithDelayOnFrame(deltaTime); ChaosModNetwork.ProcessNetworkEvents(commandManager, commands, ActivateEventLocally); } } catch (Exception arg) { limitedLogger.LogError((object)$"OnUpdate error: {arg}"); } } private void UpdateWarningText() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected I4, but got Unknown if (lastUsedLang != LocalizedText.CURRENT_LANGUAGE) { lastUsedLang = LocalizedText.CURRENT_LANGUAGE; Language val = lastUsedLang; string text; switch (val - 3) { case 5: text = "uk"; break; case 4: text = "ru"; break; case 1: case 2: text = "es"; break; case 0: text = "ge"; break; case 8: text = "ja"; break; case 9: text = "ko"; break; default: text = "en"; break; } string trans = ServiceProvider.inst.translationService.translation.GetTrans("airplane_warning", text); ((HelperLog)Utils.logger).LogInfo((object)("got lang: " + text + ", warning text: " + trans)); CustomNotifyOnGUI.SetNotifyText("Chaos Tricks", trans); } } public void OnGUI() { CustomNotifyOnGUI.OnGUI(); } 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 : IJsonUtils { 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); public static readonly BufferedLogger logger = new BufferedLogger(modFolder, "latest_log.txt", false, 50); public static string GetRelativeModFilePath(string fname) { return Path.Combine(modFolder, fname); } } } namespace peak_bepinex.Services { internal static class ArgsReaderFactory { public static CommandArgsReader NewReader(IEnumerable<string> args) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown return new CommandArgsReader(args, (ILogger)(object)Utils.logger); } } public class ChaosModNetwork : MonoBehaviour { public struct DataSource { public int playerID; public string eventID; public string username; public string lang; public DataSource(int playerID, IEventsData e) { this.playerID = playerID; eventID = e.EventID; username = e.Username; lang = e.Lang; } public object[] ToNetworkArray() { return new object[4] { playerID, eventID, lang, username }; } public EventsData ToEventData() { //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_0011: 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_002a: Expected O, but got Unknown return new EventsData { Username = username, EventID = eventID, Lang = lang }; } } private static readonly Queue<DataSource> commandQueue = new Queue<DataSource>(); public const int ANY_PLAYER_ID = -42; [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 { playerID = playerID, eventID = eventID, lang = lang, username = username }); } public static void RequestEventRPC(RpcTarget rpcTarget, DataSource data) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) ((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->RequestEventRPC triggered for {data.playerID} {data.eventID}"); try { ((MonoBehaviourPun)Character.localCharacter).photonView.RPC("ActivateClientEventRPC", rpcTarget, data.ToNetworkArray()); } catch (Exception arg) { ((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->RequestEventRPC error: {arg}"); } } public static void ProcessNetworkEvents(ICommandManager cm, Dictionary<string, IInternalStandaloneCommand> commands, Action<IEventsData> activateEventLocally) { while (commandQueue.Count > 0) { try { if (PhotonNetwork.IsMasterClient) { ProcessNetworkEvents_OnHostSide(cm, commands, activateEventLocally); } else { ProcessNetworkEvents_OnClientSide(activateEventLocally); } } catch (Exception arg) { ((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->ProcessNetworkEvents (host {PhotonNetwork.IsMasterClient}): {arg}"); } } } private static void ProcessNetworkEvents_OnHostSide(ICommandManager cm, Dictionary<string, IInternalStandaloneCommand> commands, Action<IEventsData> activateEventLocally) { DataSource dataSource = commandQueue.Dequeue(); ((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->ProcessNetworkEvents_OnHostSide event id {dataSource.eventID} for {dataSource.playerID}"); if (dataSource.playerID == -42) { ((HelperLog)Utils.logger).LogError((object)"ChaosModNetwork->ProcessNetworkEvents_OnHostSide should not get here any player ID"); return; } string text = cm.GetCommandData(dataSource.eventID, true)?.Trim(); if (string.IsNullOrEmpty(text)) { ((HelperLog)Utils.logger).LogWarning((object)"ChaosModNetwork->ProcessNetworkEvents_OnHostSide can't find commands"); return; } string[] eventCommands = CommandConsole.ParseCommandLine(text); if (AnyCommandRequiresNetworkSync(eventCommands, commands)) { activateEventLocally((IEventsData)(object)dataSource.ToEventData()); ApplyCommandsHostEffects(eventCommands, -42, commands); DataSource data = dataSource; data.playerID = -42; RequestEventRPC((RpcTarget)1, data); } else { ApplyCommandsHostEffects(eventCommands, dataSource.playerID, commands); RequestEventRPC((RpcTarget)1, dataSource); } } public static bool AnyCommandRequiresNetworkSync(string[] eventCommands, Dictionary<string, IInternalStandaloneCommand> commands) { for (int i = 0; i < eventCommands.Length; i++) { string key = CommandConsole.ParseArgs(eventCommands[i])[0]; try { if (commands[key] is INetworkSyncCommand networkSyncCommand && networkSyncCommand.NeedSendToOthers()) { return true; } } catch (Exception arg) { ((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->AnyCommandRequiresNetworkSync: {arg}"); return false; } } return false; } public static void ApplyCommandsHostEffects(string[] eventCommands, int playerID, Dictionary<string, IInternalStandaloneCommand> commands) { Character[] array; if (playerID == -42) { array = GameUtils.Players.Where((Character ch) => (Object)(object)ch != (Object)null && (Object)(object)ch != (Object)(object)Character.localCharacter).ToArray(); } else { Character characterByNetworkID = GameUtils.GetCharacterByNetworkID(playerID); if ((Object)(object)characterByNetworkID == (Object)null) { ((HelperLog)Utils.logger).LogError((object)"ChaosModNetwork->ApplyCommandsHostEffect: null target"); return; } array = (Character[])(object)new Character[1] { characterByNetworkID }; } Character[] array2 = array; foreach (Character val in array2) { foreach (string text in eventCommands) { string[] array3 = CommandConsole.ParseArgs(text); string key = array3[0]; try { if (commands[key] is IHostNetworkCommand hostNetworkCommand) { hostNetworkCommand.ExecuteHostAction(array3.Skip(1), val); } } catch (Exception ex) { ((HelperLog)Utils.logger).LogError((object)$"ChaosModNetwork->ApplyCommandsHostEffect cmd {text}, target {((Object)val).name}, id {((MonoBehaviourPun)val).photonView.ViewID}: {ex}"); } } } } private static void ProcessNetworkEvents_OnClientSide(Action<IEventsData> activateEventLocally) { DataSource dataSource = commandQueue.Dequeue(); if (dataSource.playerID == -42 || dataSource.playerID == ((MonoBehaviourPun)Character.localCharacter).photonView.ViewID) { ((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->ProcessNetworkEvents_OnClientSide event id {dataSource.eventID} for {dataSource.playerID}"); activateEventLocally((IEventsData)(object)dataSource.ToEventData()); } else { ((HelperLog)Utils.logger).LogInfo((object)$"ChaosModNetwork->ProcessNetworkEvents_OnClientSide event id {dataSource.eventID} for other player {dataSource.playerID}. Skipped."); } } } 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)new LimitedLogWrapper(100, (IDebugLogger)(object)Utils.logger); private readonly Dictionary<Event, List<EmitterAction>> eventHandlers; public EventEmitter() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown 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 TranslationService translationService; 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 void RegisterTranslationService(TranslationService translationService) { this.translationService = translationService; } } public sealed class SettingsData { public bool applySpawnItemsToAll; public bool applyEffectsToAll = true; } 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, Data); 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.Patchers { [HarmonyPatch(typeof(Character), "Awake")] public class CharacterPatcher { public static void Postfix(Character __instance) { if ((Object)(object)((Component)__instance).GetComponent<ChaosModNetwork>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<ChaosModNetwork>(); } } } 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.Commands { internal class AddBonusStamina : SyncLocalCommand, IInternalStandaloneCommand, IConsoleCommand { public string Id => "add_bonus_stamina"; public bool Execute(IEnumerable<string> args) { float num = ArgsReaderFactory.NewReader(args).ReadFloat(0f); Character.localCharacter.AddExtraStamina(num); return true; } public bool IsValidCommandArgs(IEnumerable<string> args) { throw new NotImplementedException(); } } internal class AddStamina : SyncLocalCommand, IInternalStandaloneCommand, IConsoleCommand { public string Id => "add_stamina"; public bool Execute(IEnumerable<string> args) { float num = ArgsReaderFactory.NewReader(args).ReadFloat(0f); Character.localCharacter.AddStamina(num); return true; } public bool IsValidCommandArgs(IEnumerable<string> args) { throw new NotImplementedException(); } } internal class DamageOnMouseClick : SyncLocalCommand, 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 CommandArgsReader val = ArgsReaderFactory.NewReader(args); float durationInSec = val.ReadFloat(0f); float damage = val.ReadFloat(0f); 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 : SyncLocalCommand, 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 CommandArgsReader val = ArgsReaderFactory.NewReader(args); float durationInSec = val.ReadFloat(0f); float damage = val.ReadFloat(0f); 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 : SyncLocalCommand, 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 : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(args).ReadFloat(0f); 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 : SyncLocalCommand, 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 CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float durationInSec = obj.ReadFloat(0f); float periodInSec = obj.ReadFloat(0f); 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 : SyncLocalCommand, 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 CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float durationInSec = obj.ReadFloat(0f); float periodInSec = obj.ReadFloat(0f); 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 : SyncLocalCommand, 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 : SyncLocalCommand, 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(ArgsReaderFactory.NewReader(args).ReadString("")); Character.localCharacter.refs.afflictions.SetStatus(val, 0f); return true; } public bool IsValidCommandArgs(IEnumerable<string> args) { throw new NotImplementedException(); } } internal class ClearPlayerStatuses : SyncLocalCommand, 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 : SyncLocalCommand, 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) CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float num = obj.ReadFloat(1000f); int num2 = obj.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 : SyncLocalCommand, 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) CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float num = obj.ReadFloat(1000f); int num2 = obj.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 : SyncLocalCommand, 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) CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float num = obj.ReadFloat(1000f); int num2 = obj.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 : SyncLocalCommand, 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) CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float num = obj.ReadFloat(0f); float num2 = obj.ReadFloat(0f); float num3 = obj.ReadFloat(0f); 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 = ArgsReaderFactory.NewReader(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 = UnityMathUtils.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 : SyncLocalCommand, 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) CommandArgsReader obj = ArgsReaderFactory.NewReader(args); string name = obj.ReadString(""); float num = obj.ReadFloat(0f); 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 : SyncLocalCommand, 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 : SyncLocalCommand, IInternalStandaloneCommand, IConsoleCommand { public string Id => "play_emote"; public bool Execute(IEnumerable<string> args) { string text = ArgsReaderFactory.NewReader(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 RandomUtils.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 : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(args).ReadFloat(0f); 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 : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(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 : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(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 = RandomUtils.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 : SyncLocalCommand, 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) CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float num = obj.ReadFloat(0.6f); float num2 = obj.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 : SyncLocalCommand, IInternalStandaloneCommand, IConsoleCommand { public string Id => "drop_item_in_hands"; public bool Execute(IEnumerable<string> args) { return DropItem(ArgsReaderFactory.NewReader(args).ReadFloat(0f)); } 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 : SyncLocalCommand, 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 CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float durationInSec = obj.ReadFloat(0f); float num = obj.ReadFloat(0f); 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 : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(args).ReadFloat(0f); 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 : SyncLocalCommand, 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 CommandArgsReader val = ArgsReaderFactory.NewReader(args); float durationInSec = val.ReadFloat(0f); float modifierMove = val.ReadFloat(0f); float modifierClimb = val.ReadFloat(0f); float modifierRope = val.ReadFloat(0f); float modifierVine = val.ReadFloat(0f); string text = val.ReadString(""); TimerTaskData val2 = 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(val2, true); } else { ServiceProvider.inst.scheduleManager.AppendTimerTask(val2, 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 : SyncLocalCommand, 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 CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float durationInSec = obj.ReadFloat(0f); float num = obj.ReadFloat(0f); 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 : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(args).ReadFloat(0f); 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 class ChangeMouseSens : SyncLocalCommand, 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 CommandArgsReader obj = ArgsReaderFactory.NewReader(args); float durationInSec = obj.ReadFloat(30f); float num = obj.ReadFloat(2.5f); float num2 = obj.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(ArgsReaderFactory.NewReader(args).ReadAllAsSingleString(" ", "")); return true; } public bool IsValidCommandArgs(IEnumerable<string> args) { throw new NotImplementedException(); } } internal class GiveItem : IInternalStandaloneCommand, IConsoleCommand, IHostNetworkCommand, INetworkSyncCommand { public string Id => "give_item"; public bool Execute(IEnumerable<string> args) { return ExecuteHostAction(args, Character.localCharacter); } public bool ExecuteHostAction(IEnumerable<string> args, Character targetCharacter) { //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) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsConnected) { return false; } if (!PhotonNetwork.IsMasterClient) { return true; } CommandArgsReader obj = ArgsReaderFactory.NewReader(args); string text = obj.ReadAllAsSingleString(" ", ""); string[] array = obj.ParseList(text, "|"); if (array == null || array.Length == 0) { ((HelperLog)Utils.logger).LogWarning((object)"GiveItem found empty item list"); } string randomItemFromList = RandomUtils.GetRandomItemFromList<string>((IList<string>)array); PhotonNetwork.Instantiate("0_Items/" + randomItemFromList, targetCharacter.Head + Vector3.up, Quaternion.identity, (byte)0, (object[])null).GetComponent<Item>().RequestPickup(((Component)targetCharacter).GetComponent<PhotonView>()); return true; } public bool IsValidCommandArgs(IEnumerable<string> args) { throw new NotImplementedException(); } public bool NeedSendToOthers() { return SettingsManager.Data.applySpawnItemsToAll; } } internal class ShufflePlayerMovement : SyncLocalCommand, 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 = ArgsReaderFactory.NewReader(args).ReadFloat(0f); 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, IHostNetworkCommand { public string Id => "teleport_all_to_shrine"; public bool Execute(IEnumerable<string> args) { return ExecuteHostAction(args, Character.localCharacter); } public bool ExecuteHostAction(IEnumerable<string> args, Character targetCharacter) { //IL_004f: 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_00a9: 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_00b1: 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) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown if (!PhotonNetwork.IsMasterClient) { return true; } if (ServiceProvider.inst.scheduleManager.IsTaskExists(Id)) { ((HelperLog)Utils.logger).LogWarning((object)(Id + " spams too much. Old teleport is not finished")); return true; } RespawnChest closestObject = GameObjectUtils.GetClosestObject<RespawnChest>(targetCharacter.Center, (Func<RespawnChest, bool>)((RespawnChest obj) => obj.IsInteractible(targetCharacter)), (Action<string>)((HelperLog)Utils.logger).LogInfo); 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, IHostNetworkCommand { [CompilerGenerated] private sealed class <TeleportPosFinder>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int triggerCount; public Character target; public TeleportToRandomPlayer <>4__this; public Character originalPlayer; 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__7(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(originalPlayer, 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) { return ExecuteHostAction(args, Character.localCharacter); } public bool ExecuteHostAction(IEnumerable<string> args, Character originalPlayer) { //IL_0080: 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) //IL_0091: 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_00b4: Expected O, but got Unknown if (!PhotonNetwork.IsMasterClient) { return true; } 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_00a9: Unknown result type (might be due to invalid IL or missing references) Character[] source = GameUtils.AlivePlayers.ToArray(); Character ch = originalPlayer; 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 = RandomUtils.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(originalPlayer, randomItemFromList, 60)); } } }, false); return true; } [IteratorStateMachine(typeof(<TeleportPosFinder>d__7))] private IEnumerator TeleportPosFinder(Character originalPlayer, Character target, int triggerCount) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TeleportPosFinder>d__7(0) { <>4__this = this, originalPlayer = originalPlayer, target = target, triggerCount = triggerCount }; } public bool IsValidCommandArgs(IEnumerable<string> args) { throw new NotImplementedException(); } } internal class TeleportShufflePlayers : IInternalStandaloneCommand, IConsoleCommand, IHostNetworkCommand { public string Id => "teleport_shuffle_players"; public bool Execute(IEnumerable<string> args) { return ExecuteHostAction(args, null); } public bool ExecuteHostAction(IEnumerable<string> args, Character targetCharacter) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown if (!PhotonNetwork.IsMasterClient) { return true; } 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) {
ChaosTricks_PEAK_plugins/ModHelper.dll
Decompiled a month agousing 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.Runtime.Versioning; 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: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [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 : IJsonUtils { 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 && 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 (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 CommandConsole { 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 CommandConsole(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; private readonly IEnumerator<string> args; public CommandArgsReader(IEnumerable<string> argsSource, ILogger logger) { args = argsSource.GetEnumerator(); this.logger = logger; } public int ReadInt(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(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(string defaultValue = "") { if (args != null && args.MoveNext()) { return args.Current; } return defaultValue; } public bool ReadBool(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 string ReadSpacedString(string defaultValue = "") { return ParseItemPath(ReadString(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 static class RandomUtils { 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 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(); } } 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 = JsonUtils.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 = JsonUtils.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 = JsonUtils.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 = JsonUtils.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 ClearLog(Action<string> onError) { if (path == null) { return; } try { using (new StreamWriter(path)) { } } catch (Exception arg) { onError?.Invoke($"ClearLog error: {arg}"); } } public virtual void ClearLogBySize(int fileSizeInBytes, Action<string> onError) { try { FileInfo fileInfo = new FileInfo(path); if (fileInfo.Exists && fileInfo.Length > fileSizeInBytes) { ClearLog(onError); } } catch (Exception arg) { onError?.Invoke($"ClearLogBySize error: {arg}"); } } } 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 (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 (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 JsonUtils { private static Func<IJsonUtils> customGenerator; public static IJsonUtils Generate(IDebugLogger logger) { if (customGenerator == null) { return new HelperJson(logger, File.Exists(".mod_json_debug")); } return customGenerator(); } public static void RegisterCustomGenerator(Func<IJsonUtils> generator) { customGenerator = generator; } } public class SettingsUtils { 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 = JsonUtils.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.Wrappers { 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--; logger.Log(obj); } } 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--; logger.LogInfo(obj); } } public void LogInfoConsoleOnly(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogInfoConsoleOnly(obj); } } public void LogInfoFileOnly(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogInfoFileOnly(obj); } } public void LogWarning(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogWarning(obj); } } public void LogWarningConsoleOnly(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogWarningConsoleOnly(obj); } } public void LogWarningFileOnly(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogWarningFileOnly(obj); } } public void LogError(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogError(obj); } } public void LogErrorConsoleOnly(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogErrorConsoleOnly(obj); } } public void LogErrorFileOnly(object obj) { if (messagesLimit > 0) { messagesLimit--; logger.LogErrorFileOnly(obj); } } public void UpdateLimit(int limit) { messagesLimit = limit; } public void ClearLog(Action<string> onError) { logger.ClearLog(onError); } public void ClearLogBySize(int fileSizeInBytes, Action<string> onError) { logger.ClearLogBySize(fileSizeInBytes, onError); } } } 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 IJsonUtils { 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 ClearLog(Action<string> onError); void ClearLogBySize(int fileSizeInBytes, Action<string> onError); } 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 a month agousing 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.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using EventsIO.Interfaces; using ModHelper; using ModHelper.Interfaces; using ModHelperUnity.Data; using ModHelperUnity.Interfaces; using ModHelperUnity.Utilities; using UnityEngine; [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 ModHelperUnity.Utilities { public static class CoroutineUtils { [CompilerGenerated] private sealed class <ActionCoroutine>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delayInSec; public Action action; public Action<string> log; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ActionCoroutine>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (delayInSec == 0f) { <>2__current = null; <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(delayInSec); <>1__state = 2; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } try { action(); } catch (Exception arg) { log?.Invoke($"ActionCoroutine for {delayInSec} error: {arg}"); } 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(); } } [CompilerGenerated] private sealed class <ActionCoroutineInFrames>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int delayInFrames; public Action action; public Action<string> log; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ActionCoroutineInFrames>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (delayInFrames > 0) { int num = delayInFrames - 1; delayInFrames = num; <>2__current = null; <>1__state = 1; return true; } try { action(); } catch (Exception arg) { log?.Invoke($"ActionCoroutineInFrames for {delayInFrames} error: {arg}"); } 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(); } } [CompilerGenerated] private sealed class <WhileCoroutine>d__5 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float repeatDelayInSec; public Func<bool> action; public Action<string> log; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WhileCoroutine>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; bool flag; try { flag = action(); } catch (Exception arg) { log?.Invoke($"ActionCoroutine for {repeatDelayInSec} error: {arg}"); flag = false; } if (!flag) { return false; } } else { <>1__state = -1; } <>2__current = (object)new WaitForSeconds(repeatDelayInSec); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void StartCoroutine(MonoBehaviour script, float delayInSec, Action action, Action<string> log = null) { if ((Object)(object)script == (Object)null) { return; } if (action == null) { log?.Invoke("StartCoroutine got null action"); return; } if (delayInSec < 0f) { delayInSec = 0f; log?.Invoke($"StartCoroutine got invalid delay {delayInSec}"); } script.StartCoroutine(ActionCoroutine(delayInSec, action)); } [IteratorStateMachine(typeof(<ActionCoroutine>d__1))] private static IEnumerator ActionCoroutine(float delayInSec, Action action, Action<string> log = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ActionCoroutine>d__1(0) { delayInSec = delayInSec, action = action, log = log }; } public static void StartCoroutineInFrames(MonoBehaviour script, int delayInFrames, Action action, Action<string> log = null) { if ((Object)(object)script == (Object)null) { return; } if (action == null) { log?.Invoke("StartCoroutineInFrames got null action"); return; } if (delayInFrames <= 0) { log?.Invoke($"StartCoroutineInFrames got invalid delay in frames {delayInFrames}. Replaced to 1."); delayInFrames = 1; } script.StartCoroutine(ActionCoroutineInFrames(delayInFrames, action)); } [IteratorStateMachine(typeof(<ActionCoroutineInFrames>d__3))] private static IEnumerator ActionCoroutineInFrames(int delayInFrames, Action action, Action<string> log = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ActionCoroutineInFrames>d__3(0) { delayInFrames = delayInFrames, action = action, log = log }; } public static void StartCoroutineWhile(MonoBehaviour script, float repeatDelayInSec, Func<bool> action, Action<string> log = null) { if ((Object)(object)script == (Object)null) { return; } if (action == null) { log?.Invoke("StartCoroutine got null action"); return; } if (repeatDelayInSec < 0f) { repeatDelayInSec = 0f; log?.Invoke($"StartCoroutine got invalid delay {repeatDelayInSec}"); } script.StartCoroutine(WhileCoroutine(repeatDelayInSec, action)); } [IteratorStateMachine(typeof(<WhileCoroutine>d__5))] private static IEnumerator WhileCoroutine(float repeatDelayInSec, Func<bool> action, Action<string> log = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WhileCoroutine>d__5(0) { repeatDelayInSec = repeatDelayInSec, action = action, log = log }; } } public static class GameObjectUtils { public static T GetClosestObject<T>(Vector3 pos, Func<T, bool> filter, Action<string> log) where T : MonoBehaviour { //IL_0080: 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) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) T[] array = Object.FindObjectsOfType<T>(); int num = array.Length; log?.Invoke($"GetClosestObject found {num}"); if (num == 0) { return default(T); } if (filter != null) { array = array.Where(filter).ToArray(); num = array.Length; log?.Invoke($"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 static void DebugFindAndPrintAllObjects<T>(Action<string> log) where T : MonoBehaviour { T[] array = Resources.FindObjectsOfTypeAll<T>(); StringBuilder stringBuilder = new StringBuilder("--- Found object list (names) ---\n"); T[] array2 = array; foreach (T val in array2) { stringBuilder.AppendLine(((Object)(object)val).name ?? ""); } log?.Invoke(stringBuilder.ToString()); } public static void DebugLoadAndPrintAllObjects<T>(string resourcePath, bool replaceSpaces, Action<string> log) where T : MonoBehaviour { T[] array = Resources.LoadAll<T>(resourcePath); StringBuilder stringBuilder = new StringBuilder("\n--- Loaded object list (path) ---\n"); T[] array2 = array; foreach (T val in array2) { string value = (replaceSpaces ? ((Object)(object)val).name.Replace(" ", "_") : ((Object)(object)val).name); stringBuilder.AppendLine(value); } log?.Invoke(stringBuilder.ToString()); } } public static class HelperUI { 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 UnityMathUtils { public static bool GetRandomBool() { return Random.value > 0.5f; } public static int GetRandomSign() { if (!GetRandomBool()) { 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); } } } 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.TypedNotify { 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 = JsonUtils.Generate(logger).FromFile<TypedNotifySettings>(settingsFilePath); } else { byte[] bytes = customFileReader(settingsFilePath); string @string = Encoding.UTF8.GetString(bytes); Settings = JsonUtils.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 = HelperUI.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%", HelperUI.GetColoredText(eventData.Username, typedNotifyParameters.nicknameTextColor)).Replace("%message%", HelperUI.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 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 = HelperUI.CalcScreenFactor(HelperUI.StandardScreenWidth, Screen.width); float num2 = HelperUI.CalcScreenFactor(HelperUI.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.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 a month agousing 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 JsonUtils.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 = JsonUtils.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 + "\"}"; } } }