Decompiled source of DiscountSync v1.0.1

DiscountSync.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using DiscountSync.Manager;
using DiscountSync.Patches;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DiscountSync")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Discounts on items are saved after restarting the game")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DiscountSync")]
[assembly: AssemblyTitle("DiscountSync")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
namespace DiscountSync
{
	public static class CheckModVersion
	{
		private const string RequiredModVersion = "1.0.0";

		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		[HarmonyPrefix]
		public static void CheckApproving(ConnectionApprovalRequest request, ref ConnectionApprovalResponse response)
		{
			//IL_0007: 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)
			try
			{
				string @string = Encoding.UTF8.GetString(request.Payload);
				string[] array = @string.Split(',');
				string text = ((array.Length > 1) ? array[1] : null);
				if (text != "1.0.0")
				{
					response.Approved = false;
					response.Pending = false;
					response.Reason = "Mod version mismatch. Please install the correct version of the mod.";
					NetworkManager.Singleton.DisconnectClient(request.ClientNetworkId, response.Reason);
					Plugin.Instance.SendLog("info", "Client rejected: Mod version mismatch (Client: " + (text ?? "unknown") + ", Required: 1.0.0)", null);
				}
				else
				{
					Plugin.Instance.SendLog("info", "Client approved: Mod version matches.", null);
					response.Approved = true;
				}
			}
			catch (Exception ex)
			{
				Plugin.Instance.SendLog("error", "Something went wrong: " + ex.Message, null);
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SetConnectionDataBeforeConnecting")]
		[HarmonyPostfix]
		public static void AddModVersionToConnectionData()
		{
			try
			{
				NetworkManager.Singleton.NetworkConfig.ConnectionData = Encoding.UTF8.GetBytes(string.Format("{0},{1}", GameNetworkManager.Instance.gameVersionNum, "1.0.0"));
			}
			catch (Exception ex)
			{
				Plugin.Instance.SendLog("error", "Something went wrong: " + ex.Message, null);
			}
		}
	}
	[BepInPlugin("DiscountSync", "DiscountSync", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public GameObject dsNetManagerPrefab;

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			Instance = this;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin DiscountSync is loaded!");
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "discountsyncnet");
			AssetBundle val = AssetBundle.LoadFromFile(text);
			dsNetManagerPrefab = val.LoadAsset<GameObject>("Assets/DiscountsSync/DS_NetworkManager.prefab");
			dsNetManagerPrefab.AddComponent<DiscountsManager>();
			Harmony val2 = new Harmony("DiscountSync");
			Harmony.CreateAndPatchAll(typeof(CheckModVersion), (string)null);
			Harmony.CreateAndPatchAll(typeof(Terminal), (string)null);
			Harmony.CreateAndPatchAll(typeof(GameNetworkManagerPatcher), (string)null);
			Harmony.CreateAndPatchAll(typeof(StartOfRoundPatcher), (string)null);
			val2.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony patches patched!");
		}

		public void SendLog(string type, string text, [CanBeNull] Exception err)
		{
			if (!(type == "info"))
			{
				if (type == "error")
				{
					((BaseUnityPlugin)this).Logger.LogError((object)(text ?? ""));
					if (err != null)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)err);
					}
				}
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)(text ?? ""));
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "DiscountSync";

		public const string PLUGIN_NAME = "DiscountSync";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace DiscountSync.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatcher
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void AddToPrefabs(ref GameNetworkManager __instance)
		{
			((Component)__instance).GetComponent<NetworkManager>().AddNetworkPrefab(Plugin.Instance.dsNetManagerPrefab);
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatcher
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsHost)
			{
				GameObject val = Object.Instantiate<GameObject>(Plugin.Instance.dsNetManagerPrefab);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatcher
	{
		private static readonly string SavePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		private static bool IsFirstRun = true;

		[HarmonyPatch("InitializeItemSalesPercentages")]
		[HarmonyPostfix]
		private static void InitializeItemSalesPercentagesPostfix(Terminal __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsHost)
			{
				int[] array = LoadItemSalesPercentages();
				if (array != null && array.Length != 0)
				{
					__instance.itemSalesPercentages = array;
					Plugin.Instance.SendLog("info", "Discounts have been successfully restored.", null);
				}
			}
		}

		[HarmonyPatch("SetItemSales")]
		[HarmonyPrefix]
		private static void CheckFirstRun(Terminal __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsHost)
			{
				if (__instance.itemSalesPercentages == null || __instance.itemSalesPercentages.Length == 0)
				{
					IsFirstRun = true;
				}
				else
				{
					IsFirstRun = false;
				}
			}
		}

		[HarmonyPatch("SetItemSales")]
		[HarmonyPostfix]
		private static void SaveItemSales(Terminal __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null)
			{
				return;
			}
			if (singleton.IsHost)
			{
				if (IsFirstRun)
				{
					Plugin.Instance.SendLog("info", "This is the first save load today, so the discounts in the file will not be overwritten.", null);
				}
				else
				{
					SaveItemSalesPercentages(__instance.itemSalesPercentages);
				}
			}
			else
			{
				Plugin.Instance.SendLog("info", "Requesting discounts from the host...", null);
				DiscountsManager.Instance.RequestGetDiscountsServerRpc();
			}
		}

		private static void SaveItemSalesPercentages(int[] percentages)
		{
			try
			{
				string path = Path.Combine(SavePath, GameNetworkManager.Instance.currentSaveFileName + "_SaveSales.dat");
				string contents = string.Join(",", percentages);
				File.WriteAllText(path, contents);
				Plugin.Instance.SendLog("info", "Current discounts have been saved in the file.", null);
			}
			catch (Exception err)
			{
				Plugin.Instance.SendLog("error", "Failed to save itemSalesPercentages", err);
			}
		}

		private static int[] LoadItemSalesPercentages()
		{
			string path = Path.Combine(SavePath, GameNetworkManager.Instance.currentSaveFileName + "_SaveSales.dat");
			try
			{
				if (!File.Exists(path))
				{
					Plugin.Instance.SendLog("info", "File " + GameNetworkManager.Instance.currentSaveFileName + "_SaveSales.dat not found, returning default percentages.", null);
					return new int[0];
				}
				string text = File.ReadAllText(path);
				int[] result = text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
				Plugin.Instance.SendLog("info", "Loaded itemSalesPercentages", null);
				return result;
			}
			catch (Exception err)
			{
				Plugin.Instance.SendLog("error", "Failed to load itemSalesPercentages", err);
				return new int[0];
			}
		}
	}
}
namespace DiscountSync.Manager
{
	internal class DiscountsManager : NetworkBehaviour
	{
		public static DiscountsManager Instance;

		private void Awake()
		{
			Instance = this;
		}

		[ServerRpc(RequireOwnership = false)]
		public void RequestGetDiscountsServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4104995895u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4104995895u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			Plugin.Instance.SendLog("info", "[ServerRpc] Client requested discounts", null);
			Terminal val3 = Object.FindObjectOfType<Terminal>();
			if ((Object)(object)val3 != (Object)null)
			{
				int[] itemSalesPercentages = val3.itemSalesPercentages;
				if (itemSalesPercentages != null && itemSalesPercentages.Length != 0)
				{
					RequestGetDiscountsClientRpc(itemSalesPercentages);
					Plugin.Instance.SendLog("info", "[ServerRpc] Discounts sent to client", null);
				}
				else
				{
					Plugin.Instance.SendLog("error", "[ServerRpc] Discounts array or host terminal not found", null);
				}
			}
		}

		[ClientRpc]
		public void RequestGetDiscountsClientRpc(int[] discounts)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1557665797u, val, (RpcDelivery)0);
				bool flag = discounts != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<int>(discounts, default(ForPrimitives));
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1557665797u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				Terminal val3 = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val3 != (Object)null)
				{
					val3.itemSalesPercentages = discounts;
					Plugin.Instance.SendLog("info", "[Client] Discounts successfully updated from the host", null);
				}
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_DiscountsManager()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(4104995895u, new RpcReceiveHandler(__rpc_handler_4104995895));
			NetworkManager.__rpc_func_table.Add(1557665797u, new RpcReceiveHandler(__rpc_handler_1557665797));
		}

		private static void __rpc_handler_4104995895(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((DiscountsManager)(object)target).RequestGetDiscountsServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1557665797(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				int[] discounts = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref discounts, default(ForPrimitives));
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((DiscountsManager)(object)target).RequestGetDiscountsClientRpc(discounts);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "DiscountsManager";
		}
	}
}