Decompiled source of AlwaysMist v0.0.11

AlwaysMist.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AlwaysMist.EX;
using AlwaysMist.Proxy;
using BepInEx;
using BepInEx.Configuration;
using BepInExUtils;
using BepInExUtils.EX;
using BepInExUtils.Proxy;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TeamCherry.SharedUtils;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("AlwaysMist")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+224021322e614031609bca642f5c316f1d2b9f9d")]
[assembly: AssemblyProduct("AlwaysMist")]
[assembly: AssemblyTitle("AlwaysMist")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AlwaysMist
{
	public class AlwaysMistController : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <OnSceneLoadedDelay>d__49 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public AlwaysMistController <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				AlwaysMistController alwaysMistController = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					alwaysMistController.EnterMazeHandle();
					ConfigEntry<bool> trueAlwaysMist = Main.TrueAlwaysMist;
					if (trueAlwaysMist != null && trueAlwaysMist.Value)
					{
						if (alwaysMistController.IsOutsideMaze)
						{
							alwaysMistController.EnterSceneName = alwaysMistController.CurrentSceneName;
							alwaysMistController.ChangeAllTransitionScene();
						}
						else
						{
							string currentSceneName = alwaysMistController.CurrentSceneName;
							if (!(currentSceneName == "Dust_Maze_09_entrance"))
							{
								if (currentSceneName == "Dust_Maze_Last_Hall")
								{
									Utils.Logger.Debug((object)("TargetSceneName: " + alwaysMistController.TargetSceneName));
									Utils.Logger.Debug((object)("TargetExitDoorDir: " + alwaysMistController.TargetExitDoorDir));
									if (!string.IsNullOrEmpty(alwaysMistController.TargetSceneName))
									{
										alwaysMistController.FixExitTransition();
									}
								}
							}
							else
							{
								Utils.Logger.Debug((object)("EnterSceneName: " + alwaysMistController.EnterSceneName));
								Utils.Logger.Debug((object)("EnterDoorName: " + alwaysMistController.EnterDoorName));
								string targetEntryDoorDir = alwaysMistController.TargetEntryDoorDir;
								if (!(targetEntryDoorDir == "left"))
								{
									if (targetEntryDoorDir == "right")
									{
										alwaysMistController.ChangeTransitionScene("left1", alwaysMistController.EnterSceneName, alwaysMistController.EnterDoorName);
									}
								}
								else
								{
									alwaysMistController.ChangeTransitionScene("right1", alwaysMistController.EnterSceneName, alwaysMistController.EnterDoorName);
								}
							}
						}
					}
					else
					{
						string currentSceneName = alwaysMistController.CurrentSceneName;
						if ((currentSceneName == "Shadow_04" || currentSceneName == "Dust_05") ? true : false)
						{
							alwaysMistController.EnterSceneName = alwaysMistController.CurrentSceneName;
							alwaysMistController.ChangeTransitionScene("left1");
						}
					}
					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 string ChangeScene = "Shadow_04";

		private const string ChangeScene2 = "Dust_05";

		public const string LeftTransitionPoint = "left1";

		public const string RightTransitionPoint = "right1";

		public const string MazeEntranceSceneName = "Dust_Maze_09_entrance";

		public const string MazeExitSceneName = "Dust_Maze_Last_Hall";

		public const string MazeRestSceneName = "Dust_Maze_crossing";

		public readonly Dictionary<TransitionPoint, string> ChangedTransitionPoint = new Dictionary<TransitionPoint, string>();

		public readonly Dictionary<int, AlwaysMistData> SaveDatas = new Dictionary<int, AlwaysMistData>();

		private Scene _currentScene;

		private static readonly string[] SceneNames = new string[8] { "Dust_Maze_01", "Dust_Maze_02", "Dust_Maze_03", "Dust_Maze_04", "Dust_Maze_05", "Dust_Maze_06", "Dust_Maze_07", "Dust_Maze_08" };

		public string CurrentSceneName { get; private set; } = "";


		public string TargetSceneName
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.TargetSceneName;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.TargetSceneName = value;
			}
		}

		public string TargetEntryDoorDir
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.TargetEntryDoorDir;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.TargetEntryDoorDir = value;
			}
		}

		public string TargetExitDoorDir
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.TargetExitDoorDir;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.TargetExitDoorDir = value;
			}
		}

		public string TargetExitDoorName
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.TargetExitDoorName;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.TargetExitDoorName = value;
			}
		}

		public string EnterSceneName
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.EnterSceneName;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.EnterSceneName = value;
			}
		}

		public string EnterDoorName
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.EnterDoorName;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.EnterDoorName = value;
			}
		}

		public bool IsEnteredMaze
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.IsEnteredMaze;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.IsEnteredMaze = value;
			}
		}

		public bool IsOutsideMaze
		{
			get
			{
				if (!IsEnteredMaze && CurrentSceneName != "Dust_Maze_Last_Hall" && CurrentSceneName != "Dust_Maze_crossing")
				{
					return !SceneNames.Contains(CurrentSceneName);
				}
				return false;
			}
		}

		public int LastRandomValue
		{
			get
			{
				GetSaveData(out AlwaysMistData data);
				return data.LastRandomValue;
			}
			set
			{
				GetSaveData(out AlwaysMistData data);
				data.LastRandomValue = value;
			}
		}

		public static AlwaysMistController? Instance { get; private set; }

		public void GetSaveData(out AlwaysMistData data)
		{
			GameManager instance = GameManager.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				data = new AlwaysMistData();
				return;
			}
			if (!SaveDatas.ContainsKey(instance.profileID))
			{
				SaveDatas.Add(instance.profileID, new AlwaysMistData());
			}
			data = SaveDatas[instance.profileID];
		}

		private void Awake()
		{
			Instance = this;
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0029: 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)
			Utils.Logger.Debug((object)("OnSceneLoaded: " + ((Scene)(ref scene)).name));
			CurrentSceneName = ((Scene)(ref scene)).name;
			_currentScene = scene;
			TurnOnRestBench();
			((MonoBehaviour)this).StartCoroutine(OnSceneLoadedDelay());
		}

		[IteratorStateMachine(typeof(<OnSceneLoadedDelay>d__49))]
		private IEnumerator OnSceneLoadedDelay()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnSceneLoadedDelay>d__49(0)
			{
				<>4__this = this
			};
		}

		private void TurnOnRestBench()
		{
			if (CurrentSceneName != "Dust_Maze_09_entrance")
			{
				return;
			}
			ConfigEntry<bool> restBenchInMist = Main.RestBenchInMist;
			if (restBenchInMist == null || !restBenchInMist.Value)
			{
				restBenchInMist = Main.TrueAlwaysMist;
				if (restBenchInMist == null || !restBenchInMist.Value)
				{
					return;
				}
			}
			RestBench[] array = Object.FindObjectsByType<RestBench>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			Utils.Logger.Debug((object)$"Find RestBenchs: {array}");
			RestBench[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				GameObject gameObject = ((Component)array2[i]).gameObject;
				if (!(gameObject.tag != "RespawnPoint"))
				{
					Utils.Logger.Debug((object)$"Got RestBench: {gameObject}");
					if (Object.op_Implicit((Object)(object)gameObject) && !gameObject.activeSelf)
					{
						gameObject.SetActive(true);
					}
				}
			}
		}

		private void EnterMazeHandle()
		{
			if (CurrentSceneName == "Dust_Maze_09_entrance")
			{
				IsEnteredMaze = true;
			}
			else if (IsEnteredMaze && !SceneNames.Contains(CurrentSceneName) && !(CurrentSceneName == "Dust_Maze_09_entrance") && !(CurrentSceneName == "Dust_Maze_Last_Hall") && !(CurrentSceneName == "Dust_Maze_crossing"))
			{
				IsEnteredMaze = false;
				LastRandomValue = -1;
				TargetSceneName = "";
				TargetEntryDoorDir = "";
				TargetExitDoorDir = "";
			}
		}

		private void ChangeTransitionScene(string doorName, string changeScene = "Dust_Maze_09_entrance", string? exitDoorName = null)
		{
			string doorName2 = doorName;
			TransitionPoint val = ((IEnumerable<TransitionPoint>)TransitionPoint.TransitionPoints).FirstOrDefault((Func<TransitionPoint, bool>)((TransitionPoint door) => ((Component)door).gameObject.scene == _currentScene && ((Object)((Component)door).gameObject).name == doorName2));
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			string targetScene = val.targetScene;
			Utils.Logger.Info((object)("Target Scene: " + targetScene));
			if (targetScene != changeScene)
			{
				Utils.Logger.Info((object)("Change target scene to: " + changeScene));
				val.SetTargetScene(changeScene);
			}
			if (!string.IsNullOrEmpty(exitDoorName) && val.entryPoint != exitDoorName)
			{
				val.SetTargetDoor(exitDoorName);
			}
			ConfigEntry<bool> resetMazeSaveData = Main.ResetMazeSaveData;
			if (resetMazeSaveData == null || !resetMazeSaveData.Value)
			{
				resetMazeSaveData = Main.TrueAlwaysMist;
				if (resetMazeSaveData == null || !resetMazeSaveData.Value)
				{
					return;
				}
			}
			MazeController.ResetSaveData();
		}

		private void FixExitTransition()
		{
			TransitionPoint val = ((IEnumerable<TransitionPoint>)TransitionPoint.TransitionPoints).FirstOrDefault((Func<TransitionPoint, bool>)((TransitionPoint door) => ((Component)door).gameObject.scene == _currentScene && door.targetScene == TargetSceneName));
			if (Object.op_Implicit((Object)(object)val))
			{
				val.SetTargetDoor(TargetExitDoorName);
			}
		}

		private void ChangeAllTransitionScene()
		{
			List<TransitionPoint> list = TransitionPoint.TransitionPoints.Where((TransitionPoint door) => ((Component)door).gameObject.scene == _currentScene).ToList();
			if (list.Count < 1)
			{
				return;
			}
			foreach (TransitionPoint item in list)
			{
				string targetScene = item.targetScene;
				Utils.Logger.Info((object)("Target Scene: " + targetScene));
				if ((!(targetScene == "Dust_Maze_09_entrance") && !(targetScene == "Dust_Maze_Last_Hall")) || 1 == 0)
				{
					Utils.Logger.Info((object)"Change target scene to: Dust_Maze_09_entrance");
					item.SetTargetScene("Dust_Maze_09_entrance");
					if (!ChangedTransitionPoint.ContainsKey(item))
					{
						ChangedTransitionPoint.Add(item, targetScene);
					}
				}
			}
			ConfigEntry<bool> resetMazeSaveData = Main.ResetMazeSaveData;
			if (resetMazeSaveData == null || !resetMazeSaveData.Value)
			{
				resetMazeSaveData = Main.TrueAlwaysMist;
				if (resetMazeSaveData == null || !resetMazeSaveData.Value)
				{
					return;
				}
			}
			MazeController.ResetSaveData();
		}
	}
	[Serializable]
	[JsonObject]
	public class AlwaysMistData
	{
		public string TargetSceneName = "";

		public string TargetEntryDoorDir = "";

		public string TargetExitDoorDir = "";

		public string TargetExitDoorName = "";

		public string EnterSceneName = "";

		public string EnterDoorName = "";

		public bool IsEnteredMaze;

		public int LastRandomValue = -1;
	}
	[BepInPlugin("io.github.ykysnk.AlwaysMist", "Always Mist", "0.0.11")]
	public class Main : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("io.github.ykysnk.AlwaysMist");

		internal static ConfigEntry<bool>? ResetMazeSaveData;

		internal static ConfigEntry<bool>? RandomNeededCorrectDoors;

		internal static ConfigEntry<int>? MaxRandomNeededCorrectDoors;

		internal static ConfigEntry<int>? MinRandomNeededCorrectDoors;

		internal static ConfigEntry<bool>? TrueAlwaysMist;

		internal static ConfigEntry<bool>? RestBenchInMist;

		private const string SectionOptions = "Options";

		private void Awake()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			Utils.Logger.Info((object)"Plugin Always Mist loaded, version 0.0.11");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			ResetMazeSaveData = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ResetMazeSaveData", false, "Always reset maze save data when enter even you're not death.");
			RandomNeededCorrectDoors = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "RandomNeededCorrectDoors", false, "Random the correct doors needed when enter every single times.");
			MaxRandomNeededCorrectDoors = ((BaseUnityPlugin)this).Config.Bind<int>("Options", "MaxRandomNeededCorrectDoors", 10, new ConfigDescription("The max value of random the correct doors needed", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 100), Array.Empty<object>()));
			MinRandomNeededCorrectDoors = ((BaseUnityPlugin)this).Config.Bind<int>("Options", "MinRandomNeededCorrectDoors", 2, new ConfigDescription("The min value of random the correct doors needed", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 100), Array.Empty<object>()));
			TrueAlwaysMist = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "TrueAlwaysMist", false, "Always enter mist maze first");
			RestBenchInMist = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "RestBenchInMist", false, "Turn on rest bench in mist maze");
			GameObject val = new GameObject("AlwaysMistController");
			val.AddComponent<AlwaysMistController>();
			Object.DontDestroyOnLoad((Object)val);
		}
	}
	public static class Utils
	{
		internal const string Guid = "io.github.ykysnk.AlwaysMist";

		internal const string Name = "Always Mist";

		internal const string FolderName = "AlwaysMist";

		internal const string Version = "0.0.11";

		private static Logger? _logger;

		public static Logger Logger
		{
			get
			{
				//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)
				//IL_0019: Expected O, but got Unknown
				object obj = _logger;
				if (obj == null)
				{
					Logger val = new Logger("Always Mist");
					_logger = val;
					obj = (object)val;
				}
				return (Logger)obj;
			}
		}

		public static string? GetDoorDir(string doorName)
		{
			if (doorName.StartsWith("left"))
			{
				return "left";
			}
			if (doorName.StartsWith("right"))
			{
				return "right";
			}
			if (doorName.StartsWith("top"))
			{
				return "top";
			}
			if (!doorName.StartsWith("bot"))
			{
				return null;
			}
			return "bot";
		}

		public static string? GetDoorDirMatch(string doorName)
		{
			string doorDir = GetDoorDir(doorName);
			if (doorDir == null)
			{
				return null;
			}
			return doorDir switch
			{
				"left" => "right", 
				"right" => "left", 
				"top" => "bot", 
				"bot" => "top", 
				_ => null, 
			};
		}

		public static string? GetEntryDoorDir(string doorName)
		{
			string doorDir = GetDoorDir(doorName);
			if (doorDir == null)
			{
				return null;
			}
			return doorDir switch
			{
				"left" => "left", 
				"right" => "right", 
				"top" => "left", 
				"bot" => "right", 
				_ => null, 
			};
		}
	}
}
namespace AlwaysMist.Proxy
{
	public class MazeControllerEntryMatchProxy : ClassProxy
	{
		public MazeControllerEntryMatchProxy()
			: base("MazeController+EntryMatch")
		{
		}

		public MazeControllerEntryMatchProxy(object obj)
			: base(obj, "MazeController+EntryMatch")
		{
		}

		public TraverseEX<string> EntryScene()
		{
			return new TraverseEX<string>(Traverse.Create(base.Instance).Field<string>("EntryScene"));
		}

		public TraverseEX<string> EntryDoorDir()
		{
			return new TraverseEX<string>(Traverse.Create(base.Instance).Field<string>("EntryDoorDir"));
		}

		public TraverseEX<string> ExitDoorDir()
		{
			return new TraverseEX<string>(Traverse.Create(base.Instance).Field<string>("ExitDoorDir"));
		}

		public TraverseEX<MinMaxFloat> FogRotationRange()
		{
			return new TraverseEX<MinMaxFloat>(Traverse.Create(base.Instance).Field<MinMaxFloat>("FogRotationRange"));
		}

		public object? GetObject()
		{
			return base.Instance;
		}
	}
}
namespace AlwaysMist.Patch
{
	[HarmonyPatch(typeof(DesktopPlatform))]
	internal class DesktopPlatformPatches
	{
		private const string SaveFileName = "saveData{0}.json";

		private const string SaveFileBackupName = "saveData{0}.json.bak";

		private const string SaveFileNewName = "saveData{0}.json.new";

		[HarmonyPatch("WriteSaveSlot")]
		[HarmonyPostfix]
		private static void WriteSaveSlot(DesktopPlatform __instance, int slotIndex, byte[] bytes, Action<bool> callback)
		{
			Utils.Logger.Debug((object)$"DesktopPlatform.WriteSaveSlot: {slotIndex}");
			AlwaysMistController instance = AlwaysMistController.Instance;
			if (!Object.op_Implicit((Object)(object)instance) || !instance.SaveDatas.TryGetValue(slotIndex, out AlwaysMistData data))
			{
				return;
			}
			string savePath = __instance.GetSavePath();
			string filePath = Path.Combine(savePath, $"saveData{slotIndex}.json");
			string newFilePath = Path.Combine(savePath, $"saveData{slotIndex}.json.new");
			string backupFilePath = Path.Combine(savePath, $"saveData{slotIndex}.json.bak");
			CoreLoop.InvokeNext((Action)delegate
			{
				SaveDataUtility.SerializeToJsonAsync<AlwaysMistData>(data, (Action<bool, string>)delegate(bool success, string result)
				{
					if (!success)
					{
						return;
					}
					try
					{
						File.WriteAllText(newFilePath, result);
					}
					catch (Exception ex)
					{
						Utils.Logger.Error((object)ex);
					}
					try
					{
						if (File.Exists(filePath))
						{
							File.Replace(newFilePath, filePath, backupFilePath);
						}
						else
						{
							File.Move(newFilePath, filePath);
						}
					}
					catch (Exception ex2)
					{
						Utils.Logger.Error((object)ex2);
					}
				});
			});
		}

		[HarmonyPatch("ReadSaveSlot")]
		[HarmonyPostfix]
		private static void ReadSaveSlot(DesktopPlatform __instance, int slotIndex, Action<byte[]> callback)
		{
			Utils.Logger.Debug((object)$"DesktopPlatform.ReadSaveSlot: {slotIndex}");
			AlwaysMistController controller = AlwaysMistController.Instance;
			if (!Object.op_Implicit((Object)(object)controller))
			{
				return;
			}
			string path = Path.Combine(__instance.GetSavePath(), $"saveData{slotIndex}.json");
			string saveJson = "";
			try
			{
				if (File.Exists(path))
				{
					saveJson = File.ReadAllText(path);
				}
			}
			catch (Exception ex)
			{
				Utils.Logger.Error((object)ex);
			}
			if (!string.IsNullOrEmpty(saveJson))
			{
				CoreLoop.InvokeSafe((Action)delegate
				{
					controller.SaveDatas[slotIndex] = SaveDataUtility.DeserializeSaveData<AlwaysMistData>(saveJson);
				});
			}
		}
	}
	[HarmonyPatch(typeof(MazeController))]
	internal class MazeControllerPatches
	{
		[HarmonyPatch("Activate")]
		[HarmonyPrefix]
		private static void Activate(MazeController __instance)
		{
			MazeController __instance2 = __instance;
			if (__instance2.isActive().V)
			{
				return;
			}
			AlwaysMistController instance = AlwaysMistController.Instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return;
			}
			ConfigEntry<bool> randomNeededCorrectDoors = Main.RandomNeededCorrectDoors;
			if (randomNeededCorrectDoors == null || !randomNeededCorrectDoors.Value)
			{
				randomNeededCorrectDoors = Main.TrueAlwaysMist;
				if (randomNeededCorrectDoors == null || !randomNeededCorrectDoors.Value)
				{
					goto IL_00c3;
				}
			}
			if (instance.LastRandomValue < 0)
			{
				instance.LastRandomValue = Random.Range(ConfigEntryEX<int>.op_Implicit(ConfigEntryEX.Value<int>(Main.MinRandomNeededCorrectDoors)), ConfigEntryEX<int>.op_Implicit(ConfigEntryEX.Value<int>(Main.MaxRandomNeededCorrectDoors)));
			}
			__instance2.neededCorrectDoors().V = instance.LastRandomValue;
			__instance2.restScenePoint().V = (int)Math.Round((float)instance.LastRandomValue / 2f);
			goto IL_00c3;
			IL_00c3:
			if (instance.CurrentSceneName == "Dust_Maze_Last_Hall" && !string.IsNullOrEmpty(instance.TargetSceneName))
			{
				__instance2.exitSceneName().V = instance.TargetSceneName;
			}
			if (instance.CurrentSceneName != "Dust_Maze_09_entrance")
			{
				return;
			}
			randomNeededCorrectDoors = Main.TrueAlwaysMist;
			if (randomNeededCorrectDoors != null && randomNeededCorrectDoors.Value && !string.IsNullOrEmpty(instance.TargetEntryDoorDir) && !(instance.TargetEntryDoorDir == "left"))
			{
				TransitionPoint val = ((IEnumerable<TransitionPoint>)TransitionPoint.TransitionPoints).FirstOrDefault((Func<TransitionPoint, bool>)((TransitionPoint door) => ((Component)door).gameObject.scene == ((Component)__instance2).gameObject.scene && ((Object)((Component)door).gameObject).name == "right1"));
				if (Object.op_Implicit((Object)(object)val))
				{
					PlayerData instance2 = PlayerData.instance;
					Utils.Logger.Debug((object)("playerData.PreviousMazeTargetDoor: " + instance2.PreviousMazeTargetDoor));
					__instance2.entryDoors().V.Clear();
					__instance2.entryDoors().V.Add(val);
				}
			}
		}

		[HarmonyPatch("GetExitMatch")]
		[HarmonyPrefix]
		private static bool GetExitMatch(MazeController __instance, ref object __result)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			AlwaysMistController instance = AlwaysMistController.Instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return true;
			}
			ConfigEntry<bool> trueAlwaysMist = Main.TrueAlwaysMist;
			if (trueAlwaysMist == null || !trueAlwaysMist.Value)
			{
				return true;
			}
			if (string.IsNullOrEmpty(instance.TargetSceneName))
			{
				return true;
			}
			if (!instance.IsEnteredMaze)
			{
				return true;
			}
			Utils.Logger.Debug((object)"Create Entry Match");
			MazeControllerEntryMatchProxy mazeControllerEntryMatchProxy = new MazeControllerEntryMatchProxy();
			mazeControllerEntryMatchProxy.EntryScene().V = instance.EnterSceneName;
			mazeControllerEntryMatchProxy.EntryDoorDir().V = instance.TargetEntryDoorDir;
			mazeControllerEntryMatchProxy.ExitDoorDir().V = ((instance.CurrentSceneName == "Dust_Maze_Last_Hall") ? instance.TargetExitDoorName : instance.TargetExitDoorDir);
			TraverseEX<MinMaxFloat> val = mazeControllerEntryMatchProxy.FogRotationRange();
			string targetEntryDoorDir = instance.TargetEntryDoorDir;
			MinMaxFloat v = ((targetEntryDoorDir == "left") ? new MinMaxFloat(0f, 0f) : ((!(targetEntryDoorDir == "right")) ? new MinMaxFloat(0f, 0f) : new MinMaxFloat(0f, 3.1416f)));
			val.V = v;
			object @object = mazeControllerEntryMatchProxy.GetObject();
			Utils.Logger.Debug((object)$"Create Entry Match is {@object}");
			if (@object == null)
			{
				return true;
			}
			__result = @object;
			return false;
		}

		[HarmonyPatch("SubscribeDoorEntered")]
		[HarmonyPrefix]
		private static bool SubscribeDoorEntered(MazeController __instance, TransitionPoint door)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			TransitionPoint door2 = door;
			MazeController __instance2 = __instance;
			AlwaysMistController controller = AlwaysMistController.Instance;
			if (!Object.op_Implicit((Object)(object)controller))
			{
				return true;
			}
			ConfigEntry<bool> trueAlwaysMist = Main.TrueAlwaysMist;
			if (trueAlwaysMist == null || !trueAlwaysMist.Value)
			{
				return true;
			}
			door2.OnBeforeTransition += (BeforeTransitionEvent)delegate
			{
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_018d: Unknown result type (might be due to invalid IL or missing references)
				PlayerData instance = PlayerData.instance;
				string name = ((Object)door2).name;
				if (!__instance2.isCapScene().V)
				{
					if (door2.targetScene == TraverseEX<string>.op_Implicit(__instance2.restSceneName()))
					{
						instance.EnteredMazeRestScene = true;
						instance.CorrectMazeDoorsEntered = TraverseEX<int>.op_Implicit(__instance2.neededCorrectDoors()) - TraverseEX<int>.op_Implicit(__instance2.restScenePoint());
						instance.IncorrectMazeDoorsEntered = 0;
					}
					else if (instance.PreviousMazeTargetDoor != name)
					{
						if (__instance2.correctDoors().V.Contains(door2))
						{
							instance.CorrectMazeDoorsEntered++;
							instance.IncorrectMazeDoorsEntered = 0;
						}
						else
						{
							instance.CorrectMazeDoorsEntered = 0;
							instance.IncorrectMazeDoorsEntered++;
							instance.EnteredMazeRestScene = false;
							bool flag = string.IsNullOrEmpty(controller.TargetEntryDoorDir) || controller.TargetEntryDoorDir == "left";
							if (instance.IncorrectMazeDoorsEntered >= TraverseEX<int>.op_Implicit(__instance2.allowedIncorrectDoors()) && name.StartsWith(flag ? "right" : "left"))
							{
								door2.SetTargetScene("Dust_Maze_09_entrance");
								door2.entryPoint = (flag ? "left1" : "right1");
							}
						}
					}
				}
				instance.PreviousMazeTargetDoor = door2.entryPoint;
				Scene scene = ((Component)door2).gameObject.scene;
				instance.PreviousMazeScene = ((Scene)(ref scene)).name;
				instance.PreviousMazeDoor = name;
			};
			return false;
		}
	}
	[HarmonyPatch(typeof(TransitionPoint))]
	internal static class TransitionPointPatches
	{
		[HarmonyPatch("DoSceneTransition")]
		[HarmonyPrefix]
		private static void DoSceneTransition(TransitionPoint __instance, bool doFade)
		{
			ConfigEntry<bool> trueAlwaysMist = Main.TrueAlwaysMist;
			if (trueAlwaysMist != null && trueAlwaysMist.Value)
			{
				AlwaysMistController instance = AlwaysMistController.Instance;
				if (Object.op_Implicit((Object)(object)instance) && instance.IsOutsideMaze && instance.ChangedTransitionPoint.TryGetValue(__instance, out string value))
				{
					instance.TargetSceneName = value;
					instance.TargetEntryDoorDir = Utils.GetEntryDoorDir(((Object)__instance).name) ?? Utils.GetDoorDirMatch(__instance.entryPoint) ?? "left";
					instance.TargetExitDoorDir = Utils.GetDoorDir(__instance.entryPoint) ?? "right";
					instance.TargetExitDoorName = __instance.entryPoint;
					instance.EnterDoorName = ((Object)__instance).name;
					Utils.Logger.Debug((object)("controller.TargetSceneName: " + instance.TargetSceneName));
					Utils.Logger.Debug((object)("controller.TargetEntryDoorDir: " + instance.TargetEntryDoorDir));
					Utils.Logger.Debug((object)("controller.TargetExitDoorDir: " + instance.TargetExitDoorDir));
					Utils.Logger.Debug((object)("controller.TargetExitDoorName: " + instance.TargetExitDoorName));
					Utils.Logger.Debug((object)("controller.EnterDoorName: " + instance.EnterDoorName));
					string targetEntryDoorDir = instance.TargetEntryDoorDir;
					string targetDoor = ((targetEntryDoorDir == "left") ? "right1" : ((!(targetEntryDoorDir == "right")) ? "right1" : "left1"));
					__instance.SetTargetDoor(targetDoor);
				}
			}
		}
	}
}
namespace AlwaysMist.EX
{
	public static class DesktopPlatformEX
	{
		public static TraverseEX<string> saveDirPath(this DesktopPlatform instance)
		{
			return new TraverseEX<string>(Traverse.Create((object)instance).Field<string>("saveDirPath"));
		}

		public static string GetSavePath(this DesktopPlatform instance)
		{
			string text = Path.Combine(TraverseEX<string>.op_Implicit(instance.saveDirPath()), "AlwaysMist");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			return text;
		}
	}
	public static class MazeControllerEX
	{
		public static TraverseEX<bool> isCapScene(this MazeController instance)
		{
			return new TraverseEX<bool>(Traverse.Create((object)instance).Field<bool>("isCapScene"));
		}

		public static TraverseEX<List<TransitionPoint>> entryDoors(this MazeController instance)
		{
			return new TraverseEX<List<TransitionPoint>>(Traverse.Create((object)instance).Field<List<TransitionPoint>>("entryDoors"));
		}

		public static TraverseEX<string[]> sceneNames(this MazeController instance)
		{
			return new TraverseEX<string[]>(Traverse.Create((object)instance).Field<string[]>("sceneNames"));
		}

		public static TraverseEX<int> neededCorrectDoors(this MazeController instance)
		{
			return new TraverseEX<int>(Traverse.Create((object)instance).Field<int>("neededCorrectDoors"));
		}

		public static TraverseEX<int> allowedIncorrectDoors(this MazeController instance)
		{
			return new TraverseEX<int>(Traverse.Create((object)instance).Field<int>("allowedIncorrectDoors"));
		}

		public static TraverseEX<int> restScenePoint(this MazeController instance)
		{
			return new TraverseEX<int>(Traverse.Create((object)instance).Field<int>("restScenePoint"));
		}

		public static TraverseEX<string> restSceneName(this MazeController instance)
		{
			return new TraverseEX<string>(Traverse.Create((object)instance).Field<string>("restSceneName"));
		}

		public static TraverseEX<string> exitSceneName(this MazeController instance)
		{
			return new TraverseEX<string>(Traverse.Create((object)instance).Field<string>("exitSceneName"));
		}

		public static TraverseEX<object[]> entryMatchExit(this MazeController instance)
		{
			return new TraverseEX<object[]>(Traverse.Create((object)instance).Field<object[]>("entryMatchExit"));
		}

		public static TraverseEX<bool> isActive(this MazeController instance)
		{
			return new TraverseEX<bool>(Traverse.Create((object)instance).Field<bool>("isActive"));
		}

		public static TraverseEX<List<TransitionPoint>> correctDoors(this MazeController instance)
		{
			return new TraverseEX<List<TransitionPoint>>(Traverse.Create((object)instance).Field<List<TransitionPoint>>("correctDoors"));
		}
	}
}