Decompiled source of Permanent Moons v1.0.1

PermanentMoons.dll

Decompiled a year ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Permanent Moons")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Permanent Moons")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("aacbef64-ab41-4446-ac10-1b7d30e07acd")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(TimeOfDay))]
internal class TimeOfDayPatch
{
	[HarmonyPatch("SetNewProfitQuota")]
	[HarmonyPrefix]
	private static void SetNewProfitQuota()
	{
		if (Plugin.IsServer() && Plugin.Instance.unlockedMoons.Count != 0)
		{
			Plugin.Instance.quotaNum++;
			if (Plugin.Instance.quotaReset.Value > 0 && Plugin.Instance.quotaReset.Value <= Plugin.Instance.quotaNum)
			{
				Plugin.ResetMoons();
			}
		}
	}
}
[HarmonyPatch(typeof(GameNetworkManager))]
internal class GameNetworkManagerPatch
{
	[HarmonyPatch("Disconnect")]
	[HarmonyPostfix]
	private static void Disconnect()
	{
		Plugin.Instance.unlockedMoons.Clear();
		Plugin.Instance.originalPrices.Clear();
		Plugin.Instance.quotaNum = 0;
		Plugin.UnregisterMessages();
	}

	[HarmonyPatch("SaveGameValues")]
	[HarmonyPostfix]
	private static void SaveGameValues()
	{
		if (!Plugin.IsServer())
		{
			return;
		}
		try
		{
			Plugin.SetSave();
		}
		catch (Exception arg)
		{
			Plugin.Instance.logger.LogError((object)$"Failed to save unlocked moons: {arg}");
		}
	}

	[HarmonyPatch("ResetSavedGameValues")]
	[HarmonyPostfix]
	private static void ResetSavedGameValues()
	{
		if (Plugin.IsServer())
		{
			Plugin.ResetMoons();
		}
	}
}
[HarmonyPatch(typeof(Terminal))]
internal class TerminalPatch
{
	private static string currentMoon;

	private static int currentCredits;

	[HarmonyPatch("Start")]
	[HarmonyPostfix]
	private static void Start(ref Terminal __instance)
	{
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		Plugin.RegisterMessages();
		Plugin.Instance.terminal = __instance;
		if (Plugin.IsServer())
		{
			Dictionary<string, object> save = Plugin.GetSave();
			if (save.ContainsKey("UnlockedMoons"))
			{
				Plugin.Instance.unlockedMoons = (List<string>)save["UnlockedMoons"];
			}
			if (save.ContainsKey("OriginalMoonPrices"))
			{
				Plugin.Instance.originalPrices = (Dictionary<string, int>)save["OriginalMoonPrices"];
			}
			if (save.ContainsKey("MoonQuotaNum"))
			{
				Plugin.Instance.quotaNum = (int)save["MoonQuotaNum"];
			}
			if (Plugin.Instance.unlockedMoons.Count == 0)
			{
				Plugin.Instance.quotaNum = 0;
			}
			Plugin.SyncData();
		}
		else
		{
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("PM_RetrieveData", 0uL, new FastBufferWriter(0, (Allocator)2, -1), (NetworkDelivery)3);
		}
	}

	[HarmonyPatch("LoadNewNodeIfAffordable")]
	[HarmonyPrefix]
	private static void LoadNewNodeIfAffordable_Before(TerminalNode node)
	{
		SelectableLevel[] moonsCatalogueList = Plugin.Instance.terminal.moonsCatalogueList;
		foreach (SelectableLevel val in moonsCatalogueList)
		{
			if (val.levelID == node.buyRerouteToMoon)
			{
				currentMoon = val.PlanetName;
				currentCredits = Plugin.Instance.terminal.groupCredits;
				break;
			}
		}
	}

	[HarmonyPatch("LoadNewNodeIfAffordable")]
	[HarmonyPostfix]
	private static void LoadNewNodeIfAffordable_After()
	{
		if (currentCredits != Plugin.Instance.terminal.groupCredits)
		{
			string text = currentMoon.ToLower();
			if (!Plugin.Instance.unlockedMoons.Contains(text))
			{
				Plugin.Instance.unlockedMoons.Add(text);
			}
			if (!Plugin.Instance.originalPrices.ContainsKey(text))
			{
				Plugin.Instance.originalPrices.Add(text, currentCredits - Plugin.Instance.terminal.groupCredits);
			}
			Plugin.SyncData();
			currentMoon = null;
			currentCredits = 0;
		}
	}
}
[BepInPlugin("BULLETBOT.PermanentMoons", "Permanent Moons", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
	private const string modGUID = "BULLETBOT.PermanentMoons";

	private const string modName = "Permanent Moons";

	private const string modVer = "1.0.1";

	private readonly Harmony harmony = new Harmony("BULLETBOT.PermanentMoons");

	public static Plugin Instance;

	public Terminal terminal;

	internal ManualLogSource logger;

	public ConfigEntry<int> quotaReset;

	public List<string> unlockedMoons = new List<string>();

	public Dictionary<string, int> originalPrices = new Dictionary<string, int>();

	public int quotaNum;

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		logger = Logger.CreateLogSource("Permanent Moons");
		harmony.PatchAll();
		logger.LogInfo((object)"Permanent Moons has been initialized!");
		quotaReset = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Quota Reset", 1, "This makes it so that every x quota, the permanent moons reset. (set to 0 for no reset)");
	}

	public static Dictionary<string, object> GetSave()
	{
		Dictionary<string, object> dictionary = new Dictionary<string, object>();
		if (ES3.KeyExists("UnlockedMoons", GameNetworkManager.Instance.currentSaveFileName))
		{
			dictionary.Add("UnlockedMoons", ES3.Load<List<string>>("UnlockedMoons", GameNetworkManager.Instance.currentSaveFileName));
		}
		if (ES3.KeyExists("OriginalMoonPrices", GameNetworkManager.Instance.currentSaveFileName))
		{
			dictionary.Add("OriginalMoonPrices", ES3.Load<Dictionary<string, int>>("OriginalMoonPrices", GameNetworkManager.Instance.currentSaveFileName));
		}
		if (ES3.KeyExists("MoonQuotaNum", GameNetworkManager.Instance.currentSaveFileName))
		{
			dictionary.Add("MoonQuotaNum", ES3.Load<int>("MoonQuotaNum", GameNetworkManager.Instance.currentSaveFileName));
		}
		return dictionary;
	}

	public static void SetSave()
	{
		if (Instance.unlockedMoons.Count != 0)
		{
			ES3.Save<List<string>>("UnlockedMoons", Instance.unlockedMoons, GameNetworkManager.Instance.currentSaveFileName);
		}
		else if (ES3.KeyExists("UnlockedMoons", GameNetworkManager.Instance.currentSaveFileName))
		{
			ES3.DeleteKey("UnlockedMoons", GameNetworkManager.Instance.currentSaveFileName);
		}
		if (Instance.originalPrices.Count != 0)
		{
			ES3.Save<Dictionary<string, int>>("OriginalMoonPrices", Instance.originalPrices, GameNetworkManager.Instance.currentSaveFileName);
		}
		else if (ES3.KeyExists("OriginalMoonPrices", GameNetworkManager.Instance.currentSaveFileName))
		{
			ES3.DeleteKey("OriginalMoonPrices", GameNetworkManager.Instance.currentSaveFileName);
		}
		ES3.Save<int>("MoonQuotaNum", Instance.quotaNum, GameNetworkManager.Instance.currentSaveFileName);
	}

	public static void ResetMoons()
	{
		Instance.unlockedMoons.Clear();
		Instance.quotaNum = 0;
		SetSave();
		SyncData();
	}

	public static bool IsServerAndSenderIsClient(ulong senderId)
	{
		if (IsServer())
		{
			return senderId != 0;
		}
		return false;
	}

	public static bool IsServer()
	{
		return NetworkManager.Singleton.IsServer;
	}

	public static void RegisterMessages()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("PM_SyncData", new HandleNamedMessageDelegate(SyncDataHandler));
		NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("PM_RetrieveData", new HandleNamedMessageDelegate(RetrieveDataHandler));
	}

	public static void UnregisterMessages()
	{
		NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("PM_SyncData");
		NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("PM_RetrieveData");
	}

	private static void SyncDataHandler(ulong senderId, FastBufferReader reader)
	{
		//IL_0006: 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)
		byte[] bytes = default(byte[]);
		((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref bytes, default(ForPrimitives));
		if (IsServerAndSenderIsClient(senderId))
		{
			SyncData(bytes);
			return;
		}
		Dictionary<string, object> dictionary = Deserialize(bytes);
		Instance.quotaNum = (int)dictionary["MoonQuotaNum"];
		List<string> list = (dictionary.ContainsKey("UnlockedMoons") ? ((List<string>)dictionary["UnlockedMoons"]) : new List<string>());
		Instance.unlockedMoons = list;
		Dictionary<string, int> dictionary2 = (dictionary.ContainsKey("OriginalMoonPrices") ? ((Dictionary<string, int>)dictionary["OriginalMoonPrices"]) : new Dictionary<string, int>());
		Instance.originalPrices = dictionary2;
		List<TerminalKeyword> list2 = Instance.terminal.terminalNodes.allKeywords.ToList();
		CompatibleNoun[] compatibleNouns = list2.Find((TerminalKeyword keyword) => keyword.word == "route").compatibleNouns;
		foreach (CompatibleNoun val in compatibleNouns)
		{
			string word = val.noun.word.ToLower();
			if (Instance.originalPrices.Keys.ToList().Exists((string str) => str.Contains(word)) && val.result.itemCost > 0)
			{
				foreach (string item in Instance.originalPrices.Keys.ToList())
				{
					if (item.Contains(word) && val.result.itemCost != Instance.originalPrices[item])
					{
						Instance.originalPrices[item] = val.result.itemCost;
					}
				}
			}
			int itemCost = val.result.itemCost;
			if (Instance.unlockedMoons.Exists((string str) => str.Contains(word)))
			{
				itemCost = 0;
			}
			else if (Instance.originalPrices.Keys.ToList().Exists((string str) => str.Contains(word)) && val.result.itemCost <= 0)
			{
				foreach (string key in Instance.originalPrices.Keys)
				{
					if (key.Contains(word))
					{
						itemCost = Instance.originalPrices[key];
					}
				}
			}
			val.result.itemCost = itemCost;
			CompatibleNoun[] terminalOptions = val.result.terminalOptions;
			foreach (CompatibleNoun val2 in terminalOptions)
			{
				if (val2.noun.word.ToLower() == "confirm")
				{
					val2.result.itemCost = itemCost;
				}
			}
		}
		Instance.terminal.terminalNodes.allKeywords = list2.ToArray();
	}

	public static void SyncData(byte[] bytes = null)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		if (bytes == null)
		{
			bytes = Serialize();
		}
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize<byte>(bytes, -1, 0), (Allocator)2, -1);
		CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
		FastBufferWriter val2 = val;
		try
		{
			((FastBufferWriter)(ref val)).WriteValueSafe<byte>(bytes, default(ForPrimitives));
			if (IsServer())
			{
				customMessagingManager.SendNamedMessageToAll("PM_SyncData", val, (NetworkDelivery)3);
			}
			else
			{
				customMessagingManager.SendNamedMessage("PM_SyncData", 0uL, val, (NetworkDelivery)3);
			}
		}
		finally
		{
			((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
		}
	}

	private static void RetrieveDataHandler(ulong senderId, FastBufferReader reader)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		byte[] array = default(byte[]);
		if (IsServerAndSenderIsClient(senderId))
		{
			array = Serialize();
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize<byte>(array, -1, 0), (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(array, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("PM_RetrieveData", senderId, val, (NetworkDelivery)3);
				return;
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}
		((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref array, default(ForPrimitives));
		SyncData(array);
	}

	private static byte[] Serialize()
	{
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write(Instance.quotaNum);
		binaryWriter.Write(Instance.unlockedMoons.Count);
		foreach (string unlockedMoon in Instance.unlockedMoons)
		{
			binaryWriter.Write(unlockedMoon);
		}
		binaryWriter.Write(Instance.originalPrices.Count);
		foreach (KeyValuePair<string, int> originalPrice in Instance.originalPrices)
		{
			binaryWriter.Write(originalPrice.Key);
			binaryWriter.Write(originalPrice.Value);
		}
		return memoryStream.ToArray();
	}

	public static Dictionary<string, object> Deserialize(byte[] bytes)
	{
		Dictionary<string, object> dictionary = new Dictionary<string, object>();
		using MemoryStream input = new MemoryStream(bytes);
		using BinaryReader binaryReader = new BinaryReader(input);
		dictionary.Add("MoonQuotaNum", binaryReader.ReadInt32());
		int num = binaryReader.ReadInt32();
		for (int i = 0; i < num; i++)
		{
			if (!dictionary.ContainsKey("UnlockedMoons"))
			{
				dictionary.Add("UnlockedMoons", new List<string>());
			}
			((List<string>)dictionary["UnlockedMoons"]).Add(binaryReader.ReadString());
		}
		int num2 = binaryReader.ReadInt32();
		for (int j = 0; j < num2; j++)
		{
			if (!dictionary.ContainsKey("OriginalMoonPrices"))
			{
				dictionary.Add("OriginalMoonPrices", new Dictionary<string, int>());
			}
			((Dictionary<string, int>)dictionary["OriginalMoonPrices"]).Add(binaryReader.ReadString(), binaryReader.ReadInt32());
		}
		return dictionary;
	}
}