Decompiled source of MidasTouchSamples v1.0.0

plugins/MidasTouchSamples/MidasTouchSamples.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MidasTouchSamples")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MidasTouchSamples")]
[assembly: AssemblyTitle("MidasTouchSamples")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
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 MidasTouchSamples
{
	internal static class HunterSampleValueSync
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnReceiveSyncValueMessage;
		}

		private const string SyncMessageName = "MidasTouchSamples.SyncValue";

		private static bool _handlersRegistered;

		private static readonly Dictionary<ulong, int> PendingValues = new Dictionary<ulong, int>();

		internal static void ResetState()
		{
			PendingValues.Clear();
			_handlersRegistered = false;
		}

		internal static void EnsureHandlersRegistered()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null && !_handlersRegistered)
			{
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				object obj = <>O.<0>__OnReceiveSyncValueMessage;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnReceiveSyncValueMessage;
					<>O.<0>__OnReceiveSyncValueMessage = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("MidasTouchSamples.SyncValue", (HandleNamedMessageDelegate)obj);
				_handlersRegistered = true;
				Plugin.LogVerbose("Handler de synchronisation HunterSamples enregistré.");
			}
		}

		internal static void SyncToClients(GrabbableObject grabbableObject, int value)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)grabbableObject == (Object)null || (Object)(object)((NetworkBehaviour)grabbableObject).NetworkObject == (Object)null)
			{
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			EnsureHandlersRegistered();
			ulong networkObjectId = ((NetworkBehaviour)grabbableObject).NetworkObject.NetworkObjectId;
			FastBufferWriter val = default(FastBufferWriter);
			try
			{
				val = new FastBufferWriter(12, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref value, default(ForPrimitives));
				foreach (ulong connectedClientsId in singleton.ConnectedClientsIds)
				{
					if (connectedClientsId != singleton.LocalClientId)
					{
						singleton.CustomMessagingManager.SendNamedMessage("MidasTouchSamples.SyncValue", connectedClientsId, val, (NetworkDelivery)3);
					}
				}
				Plugin.LogVerbose($"Sync envoyée pour objectId={networkObjectId} | value={value}");
			}
			catch (Exception ex)
			{
				Plugin.LogError("Erreur SyncToClients: " + ex);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void OnReceiveSyncValueMessage(ulong senderClientId, 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ulong num = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
				int num2 = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num2, default(ForPrimitives));
				Plugin.LogVerbose($"Sync reçue depuis {senderClientId} pour objectId={num} => {num2}");
				if (!TryApplyValueToSpawnedObject(num, num2))
				{
					PendingValues[num] = num2;
					Plugin.LogVerbose($"Objet {num} indisponible côté client, sync mise en attente.");
				}
			}
			catch (Exception ex)
			{
				Plugin.LogError("Erreur OnReceiveSyncValueMessage: " + ex);
			}
		}

		internal static void TryApplyPendingValue(GrabbableObject grabbableObject)
		{
			if (!((Object)(object)grabbableObject == (Object)null) && !((Object)(object)((NetworkBehaviour)grabbableObject).NetworkObject == (Object)null))
			{
				ulong networkObjectId = ((NetworkBehaviour)grabbableObject).NetworkObject.NetworkObjectId;
				if (PendingValues.TryGetValue(networkObjectId, out var value))
				{
					Plugin.ApplyValue(grabbableObject, value);
					PendingValues.Remove(networkObjectId);
					Plugin.LogVerbose($"Valeur en attente appliquée à objectId={networkObjectId} => {value}");
				}
			}
		}

		private static bool TryApplyValueToSpawnedObject(ulong objectId, int value)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.SpawnManager == null)
			{
				return false;
			}
			if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(objectId, out var value2))
			{
				return false;
			}
			if ((Object)(object)value2 == (Object)null)
			{
				return false;
			}
			GrabbableObject component = ((Component)value2).GetComponent<GrabbableObject>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			Plugin.ApplyValue(component, value);
			return true;
		}
	}
	[BepInPlugin("lc.mod.midastouchsamples", "MidasTouchSamples", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "lc.mod.midastouchsamples";

		public const string ModName = "MidasTouchSamples";

		public const string ModVersion = "1.0.0";

		internal static Plugin Instance;

		internal static Harmony Harmony;

		internal static ConfigEntry<bool> EnableVerboseLogs;

		internal static ConfigEntry<bool> EnableCompatibility;

		private static Assembly _moreShipUpgradesAssembly;

		private static Type _monsterSampleType;

		private static Type _midasTouchType;

		private static MethodInfo _increaseScrapValueIntegerMethod;

		private static bool _reflectionInitialized;

		private static bool _runtimePatchInstalled;

		internal static readonly HashSet<ulong> ProcessedObjects = new HashSet<ulong>();

		private void Awake()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			Instance = this;
			EnableVerboseLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableVerboseLogs", true, "Active les logs détaillés.");
			EnableCompatibility = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "EnableCompatibility", true, "Applique Midas Touch aux samples générés par Hunter.");
			InitializeReflection();
			Harmony = new Harmony("lc.mod.midastouchsamples");
			Harmony.PatchAll();
			InstallRuntimePatch();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MidasTouchSamples chargé.");
		}

		internal static void ResetRuntimeState()
		{
			ProcessedObjects.Clear();
			HunterSampleValueSync.ResetState();
			LogVerbose("Etat runtime réinitialisé.");
		}

		private static void InitializeReflection()
		{
			if (_reflectionInitialized)
			{
				return;
			}
			_reflectionInitialized = true;
			try
			{
				_monsterSampleType = FindTypeInLoadedAssemblies("MoreShipUpgrades.UpgradeComponents.Items.MonsterSample");
				_midasTouchType = FindTypeInLoadedAssemblies("MoreShipUpgrades.UpgradeComponents.TierUpgrades.Ship.MidasTouch");
				if (_monsterSampleType == null)
				{
					LogWarning("Type MonsterSample introuvable.");
				}
				else
				{
					_moreShipUpgradesAssembly = _monsterSampleType.Assembly;
					LogInfo("Type MonsterSample trouvé : " + _monsterSampleType.FullName);
				}
				if (_midasTouchType == null)
				{
					LogWarning("Type MidasTouch introuvable.");
					return;
				}
				LogInfo("Type MidasTouch trouvé : " + _midasTouchType.FullName);
				_increaseScrapValueIntegerMethod = _midasTouchType.GetMethod("IncreaseScrapValueInteger", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (_increaseScrapValueIntegerMethod != null)
				{
					LogInfo("Méthode MidasTouch.IncreaseScrapValueInteger trouvée.");
				}
				else
				{
					LogWarning("Méthode MidasTouch.IncreaseScrapValueInteger introuvable.");
				}
			}
			catch (Exception ex)
			{
				LogError("Erreur InitializeReflection: " + ex);
			}
		}

		private static void InstallRuntimePatch()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			if (_runtimePatchInstalled || Harmony == null)
			{
				return;
			}
			_runtimePatchInstalled = true;
			try
			{
				if (_monsterSampleType == null)
				{
					LogWarning("Patch runtime non installé : MonsterSample introuvable.");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(_monsterSampleType, "Start", (Type[])null, (Type[])null);
				MethodInfo method = typeof(Plugin).GetMethod("MonsterSampleStartPostfix", BindingFlags.Static | BindingFlags.NonPublic);
				if (methodInfo == null)
				{
					LogWarning("Patch runtime non installé : MonsterSample.Start introuvable.");
					return;
				}
				if (method == null)
				{
					LogWarning("Patch runtime non installé : postfix introuvable.");
					return;
				}
				Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				LogInfo("Patch installé sur MonsterSample.Start()");
			}
			catch (Exception ex)
			{
				LogError("Erreur lors de l'installation du patch runtime: " + ex);
			}
		}

		private static void MonsterSampleStartPostfix(object __instance)
		{
			try
			{
				if (!EnableCompatibility.Value || __instance == null)
				{
					return;
				}
				Component val = (Component)((__instance is Component) ? __instance : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				GrabbableObject component = val.GetComponent<GrabbableObject>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.itemProperties == (Object)null)
				{
					return;
				}
				NetworkObject networkObject = ((NetworkBehaviour)component).NetworkObject;
				if ((Object)(object)networkObject == (Object)null)
				{
					LogVerbose("MonsterSample sans NetworkObject ignoré.");
					return;
				}
				ulong networkObjectId = networkObject.NetworkObjectId;
				string itemName = component.itemProperties.itemName;
				int scrapValue = component.scrapValue;
				LogVerbose($"MonsterSample détecté | item='{itemName}' | objectId={networkObjectId} | scrap actuel={scrapValue} | inShip={component.isInShipRoom}");
				if (IsHostOrServer())
				{
					if (ProcessedObjects.Contains(networkObjectId))
					{
						return;
					}
					ProcessedObjects.Add(networkObjectId);
					if (component.isInShipRoom && scrapValue > 0)
					{
						HunterSampleValueSync.SyncToClients(component, scrapValue);
						LogInfo($"Host: sample déjà sauvegardé conservé pour '{itemName}' => {scrapValue}");
						return;
					}
					if (scrapValue <= 0)
					{
						LogVerbose("Host: sample '" + itemName + "' ignoré car scrapValue <= 0.");
						return;
					}
					int num = ApplyMidasTouchIfNeeded(scrapValue, itemName);
					if (num != scrapValue)
					{
						ApplyValue(component, num);
						if ((Object)(object)RoundManager.Instance != (Object)null)
						{
							RoundManager instance = RoundManager.Instance;
							instance.totalScrapValueInLevel += (float)(num - scrapValue);
						}
						LogInfo($"Host: sample '{itemName}' ajusté => {num} (base {scrapValue})");
					}
					else
					{
						LogVerbose($"Host: sample '{itemName}' inchangé => {scrapValue}");
					}
					HunterSampleValueSync.SyncToClients(component, num);
				}
				else if (IsClientOnly())
				{
					HunterSampleValueSync.TryApplyPendingValue(component);
				}
			}
			catch (Exception ex)
			{
				LogError("Erreur dans MonsterSampleStartPostfix: " + ex);
			}
		}

		internal static int ApplyMidasTouchIfNeeded(int baseValue, string itemName)
		{
			if (!EnableCompatibility.Value)
			{
				return baseValue;
			}
			if (_increaseScrapValueIntegerMethod == null)
			{
				LogVerbose($"MidasTouch indisponible pour '{itemName}', valeur conservée = {baseValue}");
				return baseValue;
			}
			try
			{
				object obj = _increaseScrapValueIntegerMethod.Invoke(null, new object[1] { baseValue });
				if (obj is int num)
				{
					LogVerbose($"MidasTouch appliqué à '{itemName}' : {baseValue} => {num}");
					return num;
				}
				if (int.TryParse(obj?.ToString(), out var result))
				{
					LogVerbose($"MidasTouch appliqué à '{itemName}' : {baseValue} => {result}");
					return result;
				}
			}
			catch (Exception ex)
			{
				LogError("Erreur ApplyMidasTouchIfNeeded: " + ex);
			}
			return baseValue;
		}

		internal static void ApplyValue(GrabbableObject grabbableObject, int value)
		{
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return;
			}
			try
			{
				grabbableObject.SetScrapValue(value);
				if (grabbableObject.scrapValue != value)
				{
					grabbableObject.scrapValue = value;
				}
				if ((Object)(object)grabbableObject.itemProperties != (Object)null)
				{
					grabbableObject.itemProperties.creditsWorth = value;
				}
				LogVerbose(string.Format("Valeur appliquée à '{0}' => {1}", grabbableObject.itemProperties?.itemName ?? "<unknown>", value));
			}
			catch (Exception ex)
			{
				LogError("Erreur ApplyValue: " + ex);
			}
		}

		internal static bool IsHostOrServer()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return false;
			}
			return NetworkManager.Singleton.IsServer;
		}

		internal static bool IsClientOnly()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return false;
			}
			if (NetworkManager.Singleton.IsClient)
			{
				return !NetworkManager.Singleton.IsServer;
			}
			return false;
		}

		internal static Type FindTypeInLoadedAssemblies(string fullName)
		{
			if (string.IsNullOrWhiteSpace(fullName))
			{
				return null;
			}
			Type type = Type.GetType(fullName);
			if (type != null)
			{
				return type;
			}
			type = AccessTools.TypeByName(fullName);
			if (type != null)
			{
				return type;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly == null))
				{
					type = assembly.GetType(fullName, throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
			}
			return null;
		}

		internal static void LogInfo(string message)
		{
			Plugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
			}
		}

		internal static void LogWarning(string message)
		{
			Plugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
			}
		}

		internal static void LogError(string message)
		{
			Plugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)message);
			}
		}

		internal static void LogVerbose(string message)
		{
			if ((Object)(object)Instance != (Object)null && EnableVerboseLogs.Value)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix()
		{
			Plugin.ResetRuntimeState();
			HunterSampleValueSync.EnsureHandlersRegistered();
			Plugin.LogVerbose("Initialisation réseau terminée.");
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal static class GameNetworkManagerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void StartPostfix()
		{
			HunterSampleValueSync.EnsureHandlersRegistered();
		}
	}
}