Decompiled source of BuildSharing v1.0.0

BepInEx/plugins/BuildSharing.dll

Decompiled 2 days ago
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<SharingButtons>())?.CopyGridToClipboard();
	}

	private static void StaticPasteCode()
	{
		(_active ?? Object.FindObjectOfType<SharingButtons>())?.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<EquippedUpgrade> list = new List<EquippedUpgrade>();
		HexMap hexMap = equipSlots.HexMap;
		Dictionary<UpgradeInstance, List<(int, int)>> dictionary = new Dictionary<UpgradeInstance, List<(int, int)>>();
		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<UpgradeInstance, List<(int, int)>> 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<EquippedUpgrade> 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<int, List<EquippedUpgrade>> dictionary = (from up in upgrades
			group up by up.ID).ToDictionary((IGrouping<int, EquippedUpgrade> g) => g.Key, (IGrouping<int, EquippedUpgrade> g) => g.ToList());
		Dictionary<int, List<UpgradeInstance>> availableUpgradeInstances = GetAvailableUpgradeInstances();
		foreach (KeyValuePair<int, List<EquippedUpgrade>> item in dictionary)
		{
			int key = item.Key;
			List<EquippedUpgrade> value = item.Value;
			if (!availableUpgradeInstances.ContainsKey(key))
			{
				continue;
			}
			List<UpgradeInstance> list = availableUpgradeInstances[key];
			List<UpgradeInstance> list2 = new List<UpgradeInstance>();
			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<int, List<UpgradeInstance>> 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<int, List<UpgradeInstance>> dictionary = new Dictionary<int, List<UpgradeInstance>>();
		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<UpgradeInstance>();
			}
			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<UpgradeInstance>();
			}
			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<SharingButtons>();
			if ((Object)(object)sharingButtons == (Object)null)
			{
				sharingButtons = ((Component)window).gameObject.AddComponent<SharingButtons>();
			}
			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<EquippedUpgrade> Upgrades;

	public EquippedUpgrades(int gearID)
	{
		GearID = gearID;
		Upgrades = new List<EquippedUpgrade>();
	}

	public EquippedUpgrades(int gearID, List<EquippedUpgrade> 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<EquippedUpgrade>();
		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<byte> list = new List<byte>();
		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)
		{
		}
	}
}