using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Sparroh.UI; using UnityEngine; [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("BuildSharing")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BuildSharing")] [assembly: AssemblyTitle("BuildSharing")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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; } } } public class SharingButtons : MonoBehaviour { public GearDetailsWindow window; private ModuleEquipSlots equipSlots; private static bool _barRegistered; private static SharingButtons _active; private static string Clipboard_GetText() { return GUIUtility.systemCopyBuffer; } private static void Clipboard_SetText(string text) { GUIUtility.systemCopyBuffer = text; } private void OnEnable() { _active = this; RegisterBar(); } private void OnDisable() { if ((Object)(object)_active == (Object)(object)this) { _active = null; } } private void Update() { GearActionBar.Tick(); if ((Object)(object)window == (Object)null && (Object)(object)Menu.Instance != (Object)null && Menu.Instance.IsOpen && (Object)(object)Menu.Instance.WindowSystem != (Object)null) { ref GearDetailsWindow reference = ref window; Window top = Menu.Instance.WindowSystem.GetTop(); reference = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null); } if (GearActionBar.IsGearMenuOpen()) { _active = this; RegisterBar(); } } private void RegisterBar() { if (!_barRegistered) { GearActionBar.Register("copy_grid", "Copy Grid", 50, (Action)StaticCopyGrid, (UIButtonStyle)1); GearActionBar.Register("paste_code", "Paste Code", 60, (Action)StaticPasteCode, (UIButtonStyle)0); GearActionBar.SetSlotVisible("copy_grid", true); GearActionBar.SetSlotVisible("paste_code", true); _barRegistered = true; } } private static void StaticCopyGrid() { (_active ?? Object.FindObjectOfType())?.CopyGridToClipboard(); } private static void StaticPasteCode() { (_active ?? Object.FindObjectOfType())?.PasteCodeFromClipboard(); } private void CopyGridToClipboard() { ResolveWindow(); if (!((Object)(object)window == (Object)null) && window.UpgradablePrefab != null) { EnsureEquipSlots(); if (!((Object)(object)equipSlots == (Object)null)) { Clipboard_SetText(GetCurrentEquippedUpgrades().ToString()); } } } private void PasteCodeFromClipboard() { ResolveWindow(); if ((Object)(object)window == (Object)null || window.UpgradablePrefab == null) { return; } EnsureEquipSlots(); if (!((Object)(object)equipSlots == (Object)null)) { string text = Clipboard_GetText(); if (!string.IsNullOrEmpty(text)) { EquippedUpgrades equippedUpgrades = new EquippedUpgrades(text); ApplyUpgradesToGrid(equippedUpgrades.Upgrades); } } } private void ResolveWindow() { if (!((Object)(object)window != (Object)null) && (Object)(object)Menu.Instance != (Object)null && Menu.Instance.IsOpen && (Object)(object)Menu.Instance.WindowSystem != (Object)null) { ref GearDetailsWindow reference = ref window; Window top = Menu.Instance.WindowSystem.GetTop(); reference = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null); } } private void EnsureEquipSlots() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown if ((Object)(object)equipSlots == (Object)null && (Object)(object)window != (Object)null) { equipSlots = (ModuleEquipSlots)(typeof(GearDetailsWindow).GetField("equipSlots", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(window)); } if ((Object)(object)window != (Object)null) { equipSlots = (ModuleEquipSlots)(typeof(GearDetailsWindow).GetField("equipSlots", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(window)); } } private EquippedUpgrades GetCurrentEquippedUpgrades() { //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_0049: 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_00f8: 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_007d: 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) int iD = window.UpgradablePrefab.Info.ID; List list = new List(); HexMap hexMap = equipSlots.HexMap; Dictionary> dictionary = new Dictionary>(); for (int i = 0; i < hexMap.Height; i++) { for (int j = 0; j < hexMap.Width; j++) { Node val = hexMap[j, i]; if (val.enabled && val.upgrade != null) { if (!dictionary.ContainsKey(val.upgrade)) { dictionary[val.upgrade] = new List<(int, int)>(); } dictionary[val.upgrade].Add((j, i)); } } } foreach (KeyValuePair> item in dictionary) { UpgradeInstance key = item.Key; List<(int, int)> value = item.Value; byte rotation = key.GetRotation(window.UpgradablePrefab); int iD2 = key.Upgrade.ID.ID; int num = int.MaxValue; int num2 = int.MaxValue; foreach (var item2 in value) { if (item2.Item1 < num || (item2.Item1 == num && item2.Item2 < num2)) { (num, num2) = item2; } } list.Add(new EquippedUpgrade(num, num2, rotation, iD2)); } return new EquippedUpgrades(iD, list); } private void ApplyUpgradesToGrid(List upgrades) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) HexMap hexMap = equipSlots.HexMap; for (int i = 0; i < hexMap.Height; i++) { for (int j = 0; j < hexMap.Width; j++) { Node val = hexMap[j, i]; if (val.upgrade != null) { equipSlots.Unequip(window.UpgradablePrefab, val.upgrade); } } } Dictionary> dictionary = (from up in upgrades group up by up.ID).ToDictionary((IGrouping g) => g.Key, (IGrouping g) => g.ToList()); Dictionary> availableUpgradeInstances = GetAvailableUpgradeInstances(); foreach (KeyValuePair> item in dictionary) { int key = item.Key; List value = item.Value; if (!availableUpgradeInstances.ContainsKey(key)) { continue; } List list = availableUpgradeInstances[key]; List list2 = new List(); foreach (EquippedUpgrade item2 in value) { if (list.Count > 0) { UpgradeInstance val2 = list[0]; list.RemoveAt(0); EquipUpgrade(item2, val2, !list2.Contains(val2)); list2.Add(val2); continue; } break; } } } private Dictionary> GetAvailableUpgradeInstances() { //IL_0028: 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) Dictionary> dictionary = new Dictionary>(); IUpgradable upgradablePrefab = window.UpgradablePrefab; UpgradeEnumerator val = default(UpgradeEnumerator); ((UpgradeEnumerator)(ref val))..ctor(upgradablePrefab); while (((UpgradeEnumerator)(ref val)).MoveNext()) { int iD = ((UpgradeEnumerator)(ref val)).Upgrade.Upgrade.ID.ID; if (!dictionary.ContainsKey(iD)) { dictionary[iD] = new List(); } dictionary[iD].Add(((UpgradeEnumerator)(ref val)).Upgrade); } ((UpgradeEnumerator)(ref val))..ctor((IUpgradable)(object)Global.Instance); while (((UpgradeEnumerator)(ref val)).MoveNext()) { int iD2 = ((UpgradeEnumerator)(ref val)).Upgrade.Upgrade.ID.ID; if (!dictionary.ContainsKey(iD2)) { dictionary[iD2] = new List(); } dictionary[iD2].Add(((UpgradeEnumerator)(ref val)).Upgrade); } return dictionary; } private void EquipUpgrade(EquippedUpgrade up, UpgradeInstance upgrade, bool checkOffset = true) { HexMap modifiedMap = upgrade.GetPattern(false).GetModifiedMap((int)up.Rotation, (HexMap)null); int num = int.MaxValue; int num2 = int.MaxValue; for (int i = 0; i < modifiedMap.Height; i++) { for (int j = 0; j < modifiedMap.Width; j++) { if (modifiedMap[j, i].enabled && (j < num || (j == num && i < num2))) { num = j; num2 = i; } } } if (num == int.MaxValue) { num = 0; } if (num2 == int.MaxValue) { num2 = 0; } int num3 = up.X - num; int num4 = up.Y - num2; int num5 = int.MaxValue; int num6 = int.MinValue; int num7 = int.MaxValue; int num8 = int.MinValue; for (int k = 0; k < modifiedMap.Height; k++) { for (int l = 0; l < modifiedMap.Width; l++) { if (modifiedMap[l, k].enabled) { int num9 = num3 + l; int num10 = num4 + k; if (num9 < num5) { num5 = num9; } if (num9 > num6) { num6 = num9; } if (num10 < num7) { num7 = num10; } if (num10 > num8) { num8 = num10; } } } } int num11 = 0; int num12 = 0; if (num5 < 0) { num11 = -num5; } if (num6 >= equipSlots.Width) { num11 -= Mathf.Max(0, num6 - equipSlots.Width + 1); } if (num7 < 0) { num12 = -num7; } if (num8 >= equipSlots.Height) { num12 -= Mathf.Max(0, num8 - equipSlots.Height + 1); } num3 += num11; num4 += num12; equipSlots.Unequip(window.UpgradablePrefab, upgrade); bool flag = equipSlots.Unequip(window.UpgradablePrefab, upgrade); bool flag2 = equipSlots.EquipModule(window.UpgradablePrefab, upgrade, num3, num4, up.Rotation, true, false); if (!(flag2 || flag)) { equipSlots.Unequip(window.UpgradablePrefab, upgrade); flag = equipSlots.Unequip(window.UpgradablePrefab, upgrade); flag2 = equipSlots.EquipModule(window.UpgradablePrefab, upgrade, num3, num4 - 1, up.Rotation, true, false); if (flag2 || flag) { num4--; } } if (!(checkOffset && flag2)) { return; } (int, int)? actualUpgradePosition = GetActualUpgradePosition(upgrade); if (actualUpgradePosition.HasValue) { int item = actualUpgradePosition.Value.Item1; int item2 = actualUpgradePosition.Value.Item2; int num13 = up.X - item; int num14 = up.Y - item2; if (num13 != 0 || num14 != 0) { equipSlots.Unequip(window.UpgradablePrefab, upgrade); equipSlots.EquipModule(window.UpgradablePrefab, upgrade, num3 + num13, num4 + num14, up.Rotation, true, false); } } } private (int, int)? GetActualUpgradePosition(UpgradeInstance upgrade) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) HexMap hexMap = equipSlots.HexMap; int? num = null; int? num2 = null; for (int i = 0; i < hexMap.Height; i++) { for (int j = 0; j < hexMap.Width; j++) { Node val = hexMap[j, i]; if (val.enabled && val.upgrade == upgrade && (!num.HasValue || j < num || (j == num && i < num2))) { num = j; num2 = i; } } } if (num.HasValue) { return (num.Value, num2.Value); } return null; } } [HarmonyPatch(typeof(GearDetailsWindow), "Awake")] public static class GearDetailsWindow_Awake_Patch { [HarmonyPostfix] private static void Postfix(GearDetailsWindow __instance) { EnsureSharingButtons(__instance); } internal static void EnsureSharingButtons(GearDetailsWindow window) { if (!((Object)(object)window == (Object)null)) { SharingButtons sharingButtons = ((Component)window).GetComponent(); if ((Object)(object)sharingButtons == (Object)null) { sharingButtons = ((Component)window).gameObject.AddComponent(); } sharingButtons.window = window; } } } [HarmonyPatch(typeof(GearDetailsWindow), "OnOpen")] public static class GearDetailsWindow_OnOpen_Patch { [HarmonyPostfix] private static void Postfix(GearDetailsWindow __instance) { GearDetailsWindow_Awake_Patch.EnsureSharingButtons(__instance); } } [BepInPlugin("sparroh.buildsharing", "BuildSharing", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [MycoMod(/*Could not decode attribute arguments.*/)] public class BuildSharingPlugin : BaseUnityPlugin { public const string PluginGUID = "sparroh.buildsharing"; public const string PluginName = "BuildSharing"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Logger; public static BuildSharingPlugin Instance; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; Instance = this; new Harmony("sparroh.buildsharing").PatchAll(); Logger.LogInfo((object)"BuildSharing v1.0.0 loaded successfully."); } } public class EquippedUpgrades { public int GearID; public List Upgrades; public EquippedUpgrades(int gearID) { GearID = gearID; Upgrades = new List(); } public EquippedUpgrades(int gearID, List upgrades) { GearID = gearID; Upgrades = upgrades; } public EquippedUpgrades(string code) { if (string.IsNullOrEmpty(code)) { throw new ArgumentException("Code cannot be null or empty", "code"); } using MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(code)); using BinaryReader binaryReader = new BinaryReader(memoryStream); GearID = 0; Upgrades = new List(); while (memoryStream.Position < memoryStream.Length) { byte[] array = binaryReader.ReadBytes(2); Array.Reverse((Array)array); short num = BitConverter.ToInt16(array, 0); byte[] array2 = binaryReader.ReadBytes(4); Array.Reverse((Array)array2); int id = BitConverter.ToInt32(array2, 0); int x = (num >> 6) & 7; int y = (num >> 3) & 7; byte rotation = (byte)(num & 7); Upgrades.Add(new EquippedUpgrade(x, y, rotation, id)); } } public void Add(EquippedUpgrade upgrade) { Upgrades.Add(upgrade); } public override string ToString() { List list = new List(); foreach (EquippedUpgrade upgrade in Upgrades) { short value = IPAddress.HostToNetworkOrder((short)((upgrade.X << 6) | (upgrade.Y << 3) | upgrade.Rotation)); list.AddRange(BitConverter.GetBytes(value)); int value2 = IPAddress.HostToNetworkOrder(upgrade.ID); list.AddRange(BitConverter.GetBytes(value2)); } return Convert.ToBase64String(list.ToArray()).TrimEnd(new char[1] { '=' }); } } public class EquippedUpgrade { public int X; public int Y; public byte Rotation; public int ID; public EquippedUpgrade(int x, int y, byte rotation, int id) { X = x; Y = y; Rotation = rotation; ID = id; } } namespace BuildSharing { public static class MyPluginInfo { public const string PLUGIN_GUID = "BuildSharing"; public const string PLUGIN_NAME = "BuildSharing"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }