Decompiled source of SaveTheWindows v1.1.0

SaveTheWindows.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SaveTheWindows")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace SaveTheWindows;

[BepInPlugin("starfi5h.plugin.SaveTheWindows", "SaveTheWindows", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	public const string GUID = "starfi5h.plugin.SaveTheWindows";

	public const string NAME = "SaveTheWindows";

	public const string VERSION = "1.1.0";

	public static ManualLogSource Log;

	public static ConfigFile ConfigFile;

	public static ConfigEntry<string> SubFolder;

	private static Harmony harmony;

	public void Awake()
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigFile = ((BaseUnityPlugin)this).Config;
		ConfigEntry<bool> obj = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Enable Save Window Position", true, "启用窗口位置保存");
		ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Enable Drag Window Offset", true, "允许窗口部分超出边框");
		ConfigEntry<bool> val2 = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Enable Save Subfolder", true, "允许存档子文件夹功能");
		SubFolder = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "Save Subfolder", "", "Name of the current subfolder\n当前存档子文件夹名称(空字串=原位置)");
		harmony = new Harmony("starfi5h.plugin.SaveTheWindows");
		if (obj.Value)
		{
			harmony.PatchAll(typeof(SaveWindow_Patch));
		}
		if (val.Value)
		{
			harmony.PatchAll(typeof(UIWindowDragOffset_Patch));
		}
		if (val2.Value)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Save subfolder enable. Name:" + SubFolder.Value));
			harmony.PatchAll(typeof(SaveFolder_Patch));
		}
	}
}
public class SaveFolder_Patch
{
	private static string subfolder = "";

	private static GameObject group;

	private static UIComboBox subfolderComboBox;

	[HarmonyPostfix]
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static void GetGameSaveSubfolder(ref string __result)
	{
		if (!string.IsNullOrEmpty(subfolder))
		{
			__result = __result + "/" + subfolder + "/";
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIMainMenu), "_OnOpen")]
	public static void Init()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected O, but got Unknown
		if ((Object)(object)group != (Object)null)
		{
			return;
		}
		try
		{
			GameObject gameObject = ((Component)((Component)UIRoot.instance.optionWindow.resolutionComp).transform).gameObject;
			group = new GameObject("Subfolder_Group");
			GameObject val = Object.Instantiate<GameObject>(gameObject, group.transform, false);
			((Object)val).name = "Subfolder ComboBox";
			val.transform.localPosition = new Vector3(0f, 0f, 0f);
			Transform val2 = val.transform.Find("Dropdown List ScrollBox/Mask/Content Panel/");
			for (int num = val2.childCount - 1; num >= 0; num--)
			{
				if (((Object)val2.GetChild(num)).name == "Item Button(Clone)")
				{
					Object.Destroy((Object)(object)((Component)val2.GetChild(num)).gameObject);
				}
			}
			subfolderComboBox = val.GetComponentInChildren<UIComboBox>();
			((UnityEventBase)subfolderComboBox.onItemIndexChange).RemoveAllListeners();
			subfolderComboBox.DropDownCount = 25;
			subfolderComboBox.itemIndex = 0;
			RefreshComboBoxList();
			((UnityEvent)subfolderComboBox.onItemIndexChange).AddListener(new UnityAction(OnComboBoxIndexChange));
			SetGameSaveSubfolder(Plugin.SubFolder.Value);
			Plugin.Log.LogDebug((object)"UI Subfolder init");
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)"Error when creating subfolder UI!");
			Plugin.Log.LogWarning((object)ex);
		}
	}

	[HarmonyPrefix]
	[HarmonyPriority(600)]
	[HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen")]
	private static void SetSubfolderGroupPosition(UILoadGameWindow __instance)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//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_0074: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)group == (Object)null)
		{
			Init();
		}
		try
		{
			group.transform.SetParent(((Component)__instance.showButton).transform.parent);
			group.transform.localPosition = ((Component)__instance.showButton).transform.localPosition + new Vector3(0f, -45f, 0f);
			group.transform.localScale = Vector3.one;
			RefreshComboBoxList();
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)ex);
		}
	}

	[HarmonyPrefix]
	[HarmonyPriority(600)]
	[HarmonyPatch(typeof(UISaveGameWindow), "_OnOpen")]
	private static void SetSubfolderGroupPosition(UISaveGameWindow __instance)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//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_0074: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)group == (Object)null)
		{
			Init();
		}
		try
		{
			group.transform.SetParent(((Component)__instance.showButton).transform.parent);
			group.transform.localPosition = ((Component)__instance.showButton).transform.localPosition + new Vector3(0f, -45f, 0f);
			group.transform.localScale = Vector3.one;
			RefreshComboBoxList();
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)ex);
		}
	}

	public static void OnDestroy()
	{
		Object.Destroy((Object)(object)group);
	}

	public static void SetGameSaveSubfolder(string folderName)
	{
		if (subfolder != folderName)
		{
			Plugin.Log.LogDebug((object)("SetGameSaveSubfolder " + folderName));
			Plugin.SubFolder.Value = (subfolder = folderName);
			if ((Object)(object)UIRoot.instance != (Object)null)
			{
				if (((ManualBehaviour)UIRoot.instance.loadGameWindow).active)
				{
					UIRoot.instance.loadGameWindow.RefreshList();
				}
				if (((ManualBehaviour)UIRoot.instance.saveGameWindow).active)
				{
					UIRoot.instance.saveGameWindow.RefreshList();
				}
			}
		}
		if (!string.IsNullOrEmpty(subfolder) && !Directory.Exists(GameConfig.gameSaveFolder))
		{
			Plugin.Log.LogInfo((object)("CreateDirectory " + GameConfig.gameSaveFolder));
			Directory.CreateDirectory(GameConfig.gameSaveFolder);
		}
	}

	public static void OnComboBoxIndexChange()
	{
		if (subfolderComboBox.itemIndex >= 0 && subfolderComboBox.itemIndex < subfolderComboBox.Items.Count)
		{
			SetGameSaveSubfolder(subfolderComboBox.Items[subfolderComboBox.itemIndex]);
		}
		else
		{
			SetGameSaveSubfolder("");
		}
	}

	private static void RefreshComboBoxList()
	{
		subfolderComboBox.Items.Clear();
		subfolderComboBox.ItemsData.Clear();
		bool flag = false;
		List<string> list = new List<string>(Directory.EnumerateDirectories(GameConfig.gameSavePath));
		list.Insert(0, "");
		for (int i = 0; i < list.Count; i++)
		{
			string fileName = Path.GetFileName(list[i]);
			subfolderComboBox.Items.Add(fileName);
			subfolderComboBox.ItemsData.Add(i);
			if (fileName == subfolder)
			{
				subfolderComboBox.itemIndex = i;
				flag = true;
			}
		}
		if (!flag)
		{
			subfolderComboBox.itemIndex = 0;
		}
	}
}
public class SaveWindow_Patch
{
	private static readonly List<UIWindowDrag> _windows = new List<UIWindowDrag>();

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIRoot), "OpenGameUI")]
	public static void OpenGameUI()
	{
		CollectWindows();
		LoadWindowPos();
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(GameMain), "End")]
	public static void OnGameEnd()
	{
		SaveWindowPos();
	}

	private static void CollectWindows()
	{
		Transform val = ((Component)UIRoot.instance.overlayCanvas).transform.Find("In Game/Windows");
		if ((Object)(object)val != (Object)null)
		{
			_windows.Clear();
			((Component)val).GetComponentsInChildren<UIWindowDrag>(true, _windows);
			Plugin.Log.LogInfo((object)$"Collect {_windows.Count} windows");
		}
		else
		{
			Plugin.Log.LogWarning((object)"Can't find In Game/Windows");
		}
	}

	private static void LoadWindowPos()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		foreach (UIWindowDrag window in _windows)
		{
			if (!((Object)(object)window?.dragTrans == (Object)null))
			{
				string name = ((Object)window).name;
				RectTransform dragTrans = window.dragTrans;
				Vector2 value = Plugin.ConfigFile.Bind<Vector2>("Window Position", name, Vector2.zero, (ConfigDescription)null).Value;
				if (!(value == Vector2.zero))
				{
					dragTrans.anchoredPosition = value;
				}
			}
		}
	}

	private static void SaveWindowPos()
	{
		//IL_003a: 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_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		Vector2 value = default(Vector2);
		foreach (UIWindowDrag window in _windows)
		{
			if (!((Object)(object)window?.dragTrans == (Object)null))
			{
				string name = ((Object)window).name;
				RectTransform dragTrans = window.dragTrans;
				((Vector2)(ref value))..ctor((float)Mathf.RoundToInt(dragTrans.anchoredPosition.x), (float)Mathf.RoundToInt(dragTrans.anchoredPosition.y));
				Plugin.ConfigFile.Bind<Vector2>("Window Position", name, Vector2.zero, (ConfigDescription)null).Value = value;
			}
		}
	}
}
public class UIWindowDragOffset_Patch
{
	[HarmonyTranspiler]
	[HarmonyPatch(typeof(UIWindowDrag), "Update")]
	public static IEnumerable<CodeInstruction> UIWindowDrag_Update_Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		//IL_0002: 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)
		//IL_0036: Expected O, but got Unknown
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Expected O, but got Unknown
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		try
		{
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "WorldToScreenPoint"), (string)null)
			}).RemoveInstruction().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UIWindowDragOffset_Patch), "WorldToScreenPoint_Min", (Type[])null, (Type[])null))
			})
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "WorldToScreenPoint"), (string)null)
				})
				.RemoveInstruction()
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UIWindowDragOffset_Patch), "WorldToScreenPoint_Max", (Type[])null, (Type[])null))
				})
				.InstructionEnumeration();
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)"Transpiler UIWindowDrag.Update error");
			Plugin.Log.LogError((object)ex);
			return instructions;
		}
	}

	private static Vector2 WorldToScreenPoint_Min(Vector3 worldPos, UIWindowDrag window)
	{
		//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_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_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)
		//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)
		Vector2 val = UIRoot.WorldToScreenPoint(worldPos);
		Rect rect = window.refTrans.rect;
		float num = ((Rect)(ref rect)).width * 3f / 4f;
		rect = window.refTrans.rect;
		return val + new Vector2(num, ((Rect)(ref rect)).height - 60f);
	}

	private static Vector2 WorldToScreenPoint_Max(Vector3 worldPos, UIWindowDrag window)
	{
		//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_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_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)
		//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)
		Vector2 val = UIRoot.WorldToScreenPoint(worldPos);
		Rect rect = window.refTrans.rect;
		float num = ((Rect)(ref rect)).width * 3f / 4f;
		rect = window.refTrans.rect;
		return val - new Vector2(num, ((Rect)(ref rect)).height - 60f);
	}
}