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";
}
}
}