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);
}
}