Decompiled source of ShipyardCodes v1.0.1

ShipyardCodes.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using NANDBrewShipDataParser;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ShipyardCodes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ShipyardCodes")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("978194b6-286b-44cb-bbbe-99b78b3c90bc")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ShipyardCodes
{
	[BepInPlugin("pr0skynesis.shipyardcodes", "ShipyardCodes", "1.0.1")]
	public class ShipyardCodesMain : BaseUnityPlugin
	{
		public const string pluginGuid = "pr0skynesis.shipyardcodes";

		public const string pluginName = "ShipyardCodes";

		public const string pluginVersion = "1.0.1";

		public static ConfigEntry<string> code1;

		public static ConfigEntry<string> code2;

		public static ConfigEntry<string> code3;

		public static ConfigEntry<string> code4;

		public static ConfigEntry<string> code5;

		public static ConfigEntry<string> code6;

		public static ConfigEntry<string> code7;

		public static ConfigEntry<string> code8;

		public static ConfigEntry<string> code9;

		public static ConfigEntry<string> code10;

		private static AssetBundle bundle;

		private static string assetPath;

		public static GameObject shipyardCodes;

		private void Start()
		{
			assetPath = Paths.PluginPath + "\\ShipyardCodes\\shipyardCodes";
			bundle = AssetBundle.LoadFromFile(assetPath);
			if ((Object)(object)bundle == (Object)null)
			{
				assetPath = Paths.PluginPath + "\\Pr0SkyNesis-ShipyardCodes-1.0.1\\shipyardCodes";
				bundle = AssetBundle.LoadFromFile(assetPath);
				if ((Object)(object)bundle == (Object)null)
				{
					Debug.LogError((object)"ShipyardCodes: Bundle not loaded! Did you place it in the correct folder?");
				}
			}
		}

		public void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Expected O, but got Unknown
			SceneManager.sceneLoaded += SceneLoaded;
			Harmony val = new Harmony("pr0skynesis.shipyardcodes");
			MethodInfo methodInfo = AccessTools.Method(typeof(ShipyardUI), "ShowUI", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ShipyardCodesPatches), "ShowUI_Patch", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(ShipyardUI), "HideUI", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(ShipyardCodesPatches), "HideUI_Patch", (Type[])null, (Type[])null);
			code1 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code1", "", "Previously saved code");
			code2 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code2", "", "Previously saved code");
			code3 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code3", "", "Previously saved code");
			code4 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code4", "", "Previously saved code");
			code5 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code5", "", "Previously saved code");
			code6 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code6", "", "Previously saved code");
			code7 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code7", "", "Previously saved code");
			code8 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code8", "", "Previously saved code");
			code9 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code9", "", "Previously saved code");
			code10 = ((BaseUnityPlugin)this).Config.Bind<string>("A) Last Saved Codes", "code10", "", "Previously saved code");
			val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void SceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			if (((Scene)(ref scene)).name == "the ocean")
			{
				SetupThings();
			}
		}

		private static void SetupThings()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bundle != (Object)null)
			{
				string text = "Assets/ShipyardCodes/shipyardCodes.prefab";
				shipyardCodes = bundle.LoadAsset<GameObject>(text);
				Transform transform = ((Component)Object.FindObjectOfType<ShipyardUI>()).transform;
				AddButtonComponents();
				shipyardCodes = Object.Instantiate<GameObject>(shipyardCodes, transform);
				if (!Chainloader.PluginInfos.ContainsKey("com.nandbrew.nandtweaks"))
				{
					shipyardCodes.transform.GetChild(0).localPosition = new Vector3(1.5f, 0f, 0f);
				}
				shipyardCodes.SetActive(false);
			}
			else
			{
				Debug.LogError((object)"ShipyardCodes: Bundle not loaded correctly");
			}
		}

		private static void AddButtonComponents()
		{
			GameObject gameObject = ((Component)shipyardCodes.transform.GetChild(0)).gameObject;
			GameObject gameObject2 = ((Component)shipyardCodes.transform.GetChild(1).GetChild(0)).gameObject;
			GameObject gameObject3 = ((Component)shipyardCodes.transform.GetChild(1).GetChild(1)).gameObject;
			GameObject gameObject4 = ((Component)shipyardCodes.transform.GetChild(1).GetChild(2)).gameObject;
			GameObject gameObject5 = ((Component)shipyardCodes.transform.GetChild(1).GetChild(3)).gameObject;
			gameObject.AddComponent<OpenCloseButton>();
			gameObject2.AddComponent<SaveCodeButton>();
			gameObject3.AddComponent<LoadCodeButton>();
			gameObject4.AddComponent<AllowAllSailsButton>();
			gameObject5.AddComponent<AllowAllPartsButton>();
			((Component)shipyardCodes.transform.GetChild(1)).gameObject.SetActive(false);
			OpenCloseButton.uiOpen = false;
		}
	}
	public class ShipyardCodesPatches
	{
		private static bool uiOpen;

		[HarmonyPostfix]
		public static void ShowUI_Patch()
		{
			ShipyardCodesMain.shipyardCodes.SetActive(true);
			uiOpen = true;
		}

		[HarmonyPostfix]
		public static void HideUI_Patch()
		{
			if (uiOpen)
			{
				ShipyardCodesMain.shipyardCodes.SetActive(false);
				uiOpen = false;
			}
		}
	}
	public class ManageCodes
	{
		public static bool allowAllSails = true;

		public static bool allowAllParts = true;

		public static void SaveCode()
		{
			GameObject currentBoat = GameState.currentShipyard.GetCurrentBoat();
			SaveBoatCustomizationData data = currentBoat.GetComponent<SaveableBoatCustomization>().GetData();
			string text = ShareableConfigUtility.CreateShipConfig(data, currentBoat, compressPartOptions: true);
			SaveToConfig(text);
			CopyToClipboard(text);
			Debug.LogWarning((object)("ShipyardCodes: " + text));
		}

		public static void LoadCode()
		{
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			string text = PasteFromClipboard();
			if (!text.StartsWith("@D") && !text.StartsWith("@S") && !text.StartsWith("@C") && !text.StartsWith("@B") && !text.StartsWith("@J") && !text.StartsWith("@K") && !text.StartsWith("D") && !text.StartsWith("S") && !text.StartsWith("C") && !text.StartsWith("B") && !text.StartsWith("J") && !text.StartsWith("K"))
			{
				NotificationUi.instance.ShowNotification("No code found in the clipboard");
				return;
			}
			Shipyard currentShipyard = GameState.currentShipyard;
			GameObject currentBoat = currentShipyard.GetCurrentBoat();
			BoatRefs component = currentBoat.GetComponent<BoatRefs>();
			BoatCustomParts component2 = currentBoat.GetComponent<BoatCustomParts>();
			SaveBoatCustomizationData data = ShareableConfigUtility.ParseShipConfig(text, currentBoat, includeOptional: true);
			Mast[] masts = component.masts;
			text = text.TrimStart(new char[1] { '@' });
			if (ShareableConfigUtility.boatIndexes[text.First().ToString()] != currentBoat.GetComponent<SaveableObject>().sceneIndex)
			{
				NotificationUi.instance.ShowNotification("Code is for another boat!");
				return;
			}
			Mast[] array = masts;
			foreach (Mast val in array)
			{
				if (!Object.op_Implicit((Object)(object)val) || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				foreach (GameObject sail in val.sails)
				{
					Sail component3 = sail.GetComponent<Sail>();
					currentShipyard.AddRefund(new ShipyardRefund(component3.sailName, Mathf.RoundToInt(component3.GetSailPrice() * currentShipyard.GetCurrencyRate() * 0.5f)));
				}
				val.RemoveAllSails();
			}
			for (int k = 0; k < component2.availableParts.Count; k++)
			{
				if (allowAllParts || component2.availableParts[k].category != 1)
				{
					int num = data.partActiveOptions[k] - component2.availableParts[k].activeOption;
					currentShipyard.partsInstaller.ChangeOrderedOption(k, num);
				}
			}
			for (int l = 0; l < masts.Length; l++)
			{
				int i;
				for (i = 0; i < data.sails.Count; i++)
				{
					if (data.sails[i].mastIndex == l)
					{
						GameObject val2 = (GameObject)((!allowAllSails) ? ((object)((IEnumerable<GameObject>)currentShipyard.sailPrefabs).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => go.GetComponent<Sail>()?.prefabIndex == data.sails[i].prefabIndex))) : ((object)PrefabsDirectory.instance.sails[data.sails[i].prefabIndex]));
						if ((Object)(object)val2 != (Object)null)
						{
							currentShipyard.sailInstaller.SelectMast(masts[l]);
							currentShipyard.AddNewSail(val2);
							Sail val3 = ((Component)masts[l]).GetComponentsInChildren<Sail>().Last();
							float num2 = data.sails[i].installHeight - val3.GetCurrentInstallHeight();
							val3.ChangeInstallHeight(num2);
							currentShipyard.sailInstaller.MoveHeldSail(0f);
						}
					}
				}
			}
		}

		public static void CopyToClipboard(string text)
		{
			GUIUtility.systemCopyBuffer = text;
		}

		public static string PasteFromClipboard()
		{
			return GUIUtility.systemCopyBuffer;
		}

		public static void SaveToConfig(string code)
		{
			for (int i = 0; i < 10; i++)
			{
				int num = 9 - i;
				if (num != 0)
				{
					SetConfigCode(num, GetConfigCode(num - 1));
				}
				else
				{
					SetConfigCode(num, code);
				}
			}
		}

		private static void SetConfigCode(int i, string code)
		{
			switch (i)
			{
			case 0:
				ShipyardCodesMain.code1.Value = code;
				break;
			case 1:
				ShipyardCodesMain.code2.Value = code;
				break;
			case 2:
				ShipyardCodesMain.code3.Value = code;
				break;
			case 3:
				ShipyardCodesMain.code4.Value = code;
				break;
			case 4:
				ShipyardCodesMain.code5.Value = code;
				break;
			case 5:
				ShipyardCodesMain.code6.Value = code;
				break;
			case 6:
				ShipyardCodesMain.code7.Value = code;
				break;
			case 7:
				ShipyardCodesMain.code8.Value = code;
				break;
			case 8:
				ShipyardCodesMain.code9.Value = code;
				break;
			case 9:
				ShipyardCodesMain.code10.Value = code;
				break;
			}
		}

		private static string GetConfigCode(int i)
		{
			return i switch
			{
				0 => ShipyardCodesMain.code1.Value, 
				1 => ShipyardCodesMain.code2.Value, 
				2 => ShipyardCodesMain.code3.Value, 
				3 => ShipyardCodesMain.code4.Value, 
				4 => ShipyardCodesMain.code5.Value, 
				5 => ShipyardCodesMain.code6.Value, 
				6 => ShipyardCodesMain.code7.Value, 
				7 => ShipyardCodesMain.code8.Value, 
				8 => ShipyardCodesMain.code9.Value, 
				9 => ShipyardCodesMain.code10.Value, 
				_ => null, 
			};
		}
	}
	public class OpenCloseButton : GoPointerButton
	{
		public static bool uiOpen;

		public override void OnActivate()
		{
			if (uiOpen)
			{
				uiOpen = !uiOpen;
				((Component)ShipyardCodesMain.shipyardCodes.transform.GetChild(1)).gameObject.SetActive(false);
			}
			else
			{
				uiOpen = !uiOpen;
				((Component)ShipyardCodesMain.shipyardCodes.transform.GetChild(1)).gameObject.SetActive(true);
			}
		}
	}
	public class SaveCodeButton : GoPointerButton
	{
		public override void OnActivate()
		{
			ManageCodes.SaveCode();
		}
	}
	public class LoadCodeButton : GoPointerButton
	{
		public override void OnActivate()
		{
			ManageCodes.LoadCode();
		}
	}
	public class AllowAllSailsButton : GoPointerButton
	{
		public static TextMesh allowAllSailsStatusText;

		public override void OnActivate()
		{
			if (ManageCodes.allowAllSails)
			{
				ManageCodes.allowAllSails = false;
				((Component)((Component)this).transform.parent.GetChild(4).GetChild(0)).gameObject.GetComponent<TextMesh>().text = "No";
			}
			else
			{
				ManageCodes.allowAllSails = true;
				((Component)((Component)this).transform.parent.GetChild(4).GetChild(0)).gameObject.GetComponent<TextMesh>().text = "Yes";
			}
		}
	}
	public class AllowAllPartsButton : GoPointerButton
	{
		public TextMesh allowAllPartsStatusText;

		public override void OnActivate()
		{
			if (ManageCodes.allowAllParts)
			{
				ManageCodes.allowAllParts = false;
				((Component)((Component)this).transform.parent.GetChild(4).GetChild(1)).gameObject.GetComponent<TextMesh>().text = "No";
			}
			else
			{
				ManageCodes.allowAllParts = true;
				((Component)((Component)this).transform.parent.GetChild(4).GetChild(1)).gameObject.GetComponent<TextMesh>().text = "Yes";
			}
		}
	}
}
namespace NANDBrewShipDataParser
{
	internal class ShareableConfigUtility
	{
		public static readonly Dictionary<int, string> boatNames = new Dictionary<int, string>
		{
			{ 10, "D" },
			{ 20, "S" },
			{ 40, "C" },
			{ 50, "B" },
			{ 80, "J" },
			{ 90, "K" }
		};

		public static readonly Dictionary<string, int> boatIndexes = new Dictionary<string, int>
		{
			{ "D", 10 },
			{ "S", 20 },
			{ "C", 40 },
			{ "B", 50 },
			{ "J", 80 },
			{ "K", 90 }
		};

		private static readonly char modIndicator = '@';

		private static readonly char opener = '(';

		private static readonly string chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

		public static string CreateShipConfig(SaveBoatCustomizationData data, GameObject boat, bool compressPartOptions)
		{
			int sceneIndex = boat.GetComponent<SaveableObject>().sceneIndex;
			string text = "";
			char c;
			if (data.masts.Length == 64)
			{
				string text2 = text;
				c = modIndicator;
				text = text2 + c;
			}
			text += boatNames[sceneIndex];
			int num = 0;
			while (num < data.partActiveOptions.Count)
			{
				int num2 = data.partActiveOptions[num];
				if (compressPartOptions)
				{
					int i;
					for (i = num + 1; i < data.partActiveOptions.Count && data.partActiveOptions[i] == data.partActiveOptions[num]; i++)
					{
						if (num2 + 16 >= chars.Length)
						{
							break;
						}
						num2 += 16;
					}
					text += IntToBase64(num2, isLong: false);
					num = i;
				}
				else
				{
					text += num2;
					num++;
				}
			}
			string text3 = text;
			c = opener;
			text = text3 + c;
			foreach (SaveSailData sail in data.sails)
			{
				int prefabIndex = sail.prefabIndex;
				int mastIndex = sail.mastIndex;
				int value = Mathf.RoundToInt(sail.installHeight * 100f);
				text += IntToBase64(prefabIndex, isLong: true);
				text += IntToBase64(mastIndex, isLong: false);
				text += IntToBase64(value, isLong: true);
			}
			return text;
		}

		private static string IntToBase64(int value, bool isLong)
		{
			if (isLong)
			{
				int index = value % chars.Length;
				int index2 = (int)Mathf.Floor((float)(value / chars.Length));
				string text = "";
				text += chars[index2];
				return text + chars[index];
			}
			return chars[value].ToString();
		}

		private static int Base64ToInt(string value)
		{
			int num = 0;
			if (value.Length == 2)
			{
				num += chars.IndexOf(value[0]) * chars.Length;
				num += chars.IndexOf(value[1]);
			}
			else if (value.Length == 1)
			{
				num += chars.IndexOf(value[0]);
			}
			return num;
		}

		public static SaveBoatCustomizationData ParseShipConfig(string shipConfig, GameObject boat, bool includeOptional)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Expected O, but got Unknown
			BoatRefs component = boat.GetComponent<BoatRefs>();
			SaveBoatCustomizationData val = new SaveBoatCustomizationData();
			if (shipConfig.IndexOf(modIndicator) == 0 && component.masts.Length != 64)
			{
				NotificationUi.instance.ShowNotification("This code was saved\nwith the ShipyardExpansion mod.\nOnly vanilla parts will be loaded.");
			}
			List<BoatPart> availableParts = boat.GetComponent<BoatCustomParts>().availableParts;
			shipConfig = shipConfig.TrimStart(new char[1] { modIndicator });
			if (boatIndexes[shipConfig.First().ToString()] != boat.GetComponent<SaveableObject>().sceneIndex)
			{
				return null;
			}
			shipConfig = shipConfig.Substring(1);
			string[] source = shipConfig.Split(new char[1] { opener });
			string text = source.First();
			for (int i = 0; i < text.Length && i < availableParts.Count; i++)
			{
				int num = Base64ToInt(text[i].ToString());
				int item = num % 16;
				int num2 = (int)Mathf.Floor((float)(num / 16)) + 1;
				for (int j = 0; j < num2; j++)
				{
					if (!includeOptional && availableParts[i].category == 1)
					{
						val.partActiveOptions.Add(availableParts[i].activeOption);
					}
					else
					{
						val.partActiveOptions.Add(item);
					}
				}
			}
			string text2 = "";
			foreach (int partActiveOption in val.partActiveOptions)
			{
				text2 += partActiveOption;
			}
			string text3 = source.Last();
			while (text3.Length >= 5)
			{
				int num3 = Base64ToInt(text3.Substring(2, 1));
				if (num3 < component.masts.Length && (Object)(object)component.masts[num3] != (Object)null)
				{
					val.sails.Add(new SaveSailData
					{
						prefabIndex = Base64ToInt(text3.Substring(0, 2)),
						mastIndex = num3,
						installHeight = (float)Base64ToInt(text3.Substring(3, 2)) / 100f
					});
				}
				text3 = text3.Substring(5);
			}
			return val;
		}
	}
}