Decompiled source of WeedKillerAdjusterFixed v1.0.0

WeedKillerAdjuster.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using OniroDev.Patches;
using Unity.Collections;
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("WeedKillerAdjuster")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("WeedKiller Adjuster - Ported to v81")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("WeedKillerAdjuster")]
[assembly: AssemblyTitle("WeedKillerAdjuster")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[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 OniroDev
{
	[BepInPlugin("OniroDev.WeedKillerAdjuster", "WeedKillerAdjuster", "2.0.0")]
	public class WeedKillerAdjusterBase : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("OniroDev.WeedKillerAdjuster");

		public static WeedKillerAdjusterBase Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			WeedKillerAdjusterLogger.Initialize("OniroDev.WeedKillerAdjuster");
			WeedKillerAdjusterLogger.Log("WeedKillerAdjuster starting up (OniroDev.WeedKillerAdjuster)");
			new WeedKillerConfig(((BaseUnityPlugin)this).Config);
			WeedKillerAdjusterLogger.Log("Applying patches...");
			_harmony.PatchAll(typeof(WeedKillerPatch));
			_harmony.PatchAll(typeof(WeedKillerConfig));
			WeedKillerAdjusterLogger.Log("Patches applied successfully.");
		}
	}
	internal static class PluginInfo
	{
		internal const string PLUGIN_GUID = "OniroDev.WeedKillerAdjuster";

		internal const string PLUGIN_NAME = "WeedKillerAdjuster";

		internal const string PLUGIN_VERSION = "2.0.0";
	}
	public static class WeedKillerAdjusterLogger
	{
		private static ManualLogSource _logSource;

		public static void Initialize(string pluginGUID)
		{
			_logSource = Logger.CreateLogSource(pluginGUID);
		}

		public static void Log(object message)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogInfo(message);
			}
		}

		public static void LogWarning(object message)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogWarning(message);
			}
		}

		public static void LogError(object message)
		{
			ManualLogSource logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogError(message);
			}
		}
	}
	public class WeedKillerConfig
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		public static ConfigEntry<float> weedKillRate;

		public static ConfigEntry<float> weedKillTank;

		public static ConfigEntry<bool> usesBattery;

		private static WeedKillerConfig _default;

		private static WeedKillerConfig _synced;

		private float _killRate;

		private float _killTank;

		private bool _battery;

		public static bool IsSynced { get; private set; }

		private static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

		private static bool IsHost => NetworkManager.Singleton.IsHost;

		private static bool IsClient => NetworkManager.Singleton.IsClient;

		public WeedKillerConfig(ConfigFile configFile)
		{
			configFile.SaveOnConfigSet = false;
			weedKillRate = configFile.Bind<float>("Weed Killer Settings", "Vain Shroud Kill Rate", 1f, "Multiplier for kill rate of Vain Shrouds. Set to 7 to kill them 7x faster than normal.");
			weedKillTank = configFile.Bind<float>("Weed Killer Settings", "Weed Killer Base Fuel Tank", 1f, "Multiplier for fuel tank capacity. Set to 7 for 7x more spray fuel.");
			usesBattery = configFile.Bind<bool>("Weed Killer Settings", "Use Battery Charges", false, "When true, the weed killer uses battery charges and can be recharged on the ship. When enabled, the Fuel Tank multiplier is ignored.");
			ClearOrphanedEntries(configFile);
			configFile.Save();
			configFile.SaveOnConfigSet = true;
			_default = this;
			_synced = this;
			SnapshotFromConfig();
			WeedKillerAdjusterLogger.Log($"Config loaded — killRate={weedKillRate.Value}, killTank={weedKillTank.Value}, battery={usesBattery.Value}");
		}

		private void SnapshotFromConfig()
		{
			_killRate = weedKillRate.Value;
			_killTank = weedKillTank.Value;
			_battery = usesBattery.Value;
		}

		private static byte[] Serialize(WeedKillerConfig cfg)
		{
			byte[] array = new byte[9];
			Buffer.BlockCopy(BitConverter.GetBytes(cfg._killRate), 0, array, 0, 4);
			Buffer.BlockCopy(BitConverter.GetBytes(cfg._killTank), 0, array, 4, 4);
			array[8] = (byte)(cfg._battery ? 1 : 0);
			return array;
		}

		private static WeedKillerConfig Deserialize(byte[] data)
		{
			return new WeedKillerConfig
			{
				_killRate = BitConverter.ToSingle(data, 0),
				_killTank = BitConverter.ToSingle(data, 4),
				_battery = (data[8] != 0)
			};
		}

		private WeedKillerConfig()
		{
		}

		private static void ApplySynced(WeedKillerConfig cfg)
		{
			weedKillRate.Value = cfg._killRate;
			weedKillTank.Value = cfg._killTank;
			usesBattery.Value = cfg._battery;
			_synced = cfg;
			IsSynced = true;
			WeedKillerAdjusterLogger.Log("Config synced from host.");
		}

		private static void RevertSync()
		{
			if (_default != null)
			{
				weedKillRate.Value = _default._killRate;
				weedKillTank.Value = _default._killTank;
				usesBattery.Value = _default._battery;
				_synced = _default;
				IsSynced = false;
				WeedKillerAdjusterLogger.Log("Config reverted to local defaults.");
			}
		}

		public static void RequestSync()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1);
			try
			{
				MessageManager.SendNamedMessage("OniroDev.WeedKillerAdjuster_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				return;
			}
			WeedKillerAdjusterLogger.Log($"Config sync request from client {clientId}");
			byte[] array = Serialize(_default);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + 4, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				MessageManager.SendNamedMessage("OniroDev.WeedKillerAdjuster_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(4))
			{
				WeedKillerAdjusterLogger.LogError("Config sync error: could not read length.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				WeedKillerAdjusterLogger.LogError("Config sync error: could not read payload.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			try
			{
				ApplySynced(Deserialize(data));
			}
			catch (Exception arg)
			{
				WeedKillerAdjusterLogger.LogError($"Config sync deserialization failed: {arg}");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_0060: 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_006b: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (IsHost)
			{
				CustomMessagingManager messageManager = MessageManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messageManager.RegisterNamedMessageHandler("OniroDev.WeedKillerAdjuster_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				IsSynced = true;
				return;
			}
			IsSynced = false;
			CustomMessagingManager messageManager2 = MessageManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("OniroDev.WeedKillerAdjuster_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			RevertSync();
		}

		private static void ClearOrphanedEntries(ConfigFile configFile)
		{
			if (AccessTools.Property(typeof(ConfigFile), "OrphanedEntries")?.GetValue(configFile) is Dictionary<ConfigDefinition, string> dictionary)
			{
				dictionary.Clear();
			}
		}
	}
}
namespace OniroDev.Patches
{
	public class WeedKillerPatch
	{
		private static readonly FieldRef<SprayPaintItem, float> _sprayCanTankRef = AccessTools.FieldRefAccess<SprayPaintItem, float>("sprayCanTank");

		private static readonly FieldRef<SprayPaintItem, float> _killWeedSpeedRef = TryGetKillWeedSpeedRef();

		private static readonly FieldRef<SprayPaintItem, bool> _isSprayingRef = AccessTools.FieldRefAccess<SprayPaintItem, bool>("isSpraying");

		private static float _tempCanTank;

		private static FieldRef<SprayPaintItem, float> TryGetKillWeedSpeedRef()
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(SprayPaintItem), "killWeedSpeed");
			if (fieldInfo == null)
			{
				WeedKillerAdjusterLogger.LogWarning("SprayPaintItem.killWeedSpeed not found in this game version. weedKillRate multiplier will be applied to drain rate instead.");
				return null;
			}
			return AccessTools.FieldRefAccess<SprayPaintItem, float>(fieldInfo);
		}

		[HarmonyPatch(typeof(SprayPaintItem), "Start")]
		[HarmonyPostfix]
		public static void WeedKillerKillRatePatch(SprayPaintItem __instance)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			if (_killWeedSpeedRef != null)
			{
				float num = _killWeedSpeedRef.Invoke(__instance) * WeedKillerConfig.weedKillRate.Value;
				_killWeedSpeedRef.Invoke(__instance) = num;
				WeedKillerAdjusterLogger.Log($"killWeedSpeed scaled to {num} (x{WeedKillerConfig.weedKillRate.Value})");
			}
			if (__instance.isWeedKillerSprayBottle && WeedKillerConfig.usesBattery.Value)
			{
				((GrabbableObject)__instance).insertedBattery = new Battery(false, _sprayCanTankRef.Invoke(__instance));
				((GrabbableObject)__instance).itemProperties.requiresBattery = true;
				WeedKillerAdjusterLogger.Log("Weed killer battery mode enabled.");
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "ChargeBatteries")]
		[HarmonyPrefix]
		private static void WeedKillerChargeBatteries(GrabbableObject __instance)
		{
			SprayPaintItem val = (SprayPaintItem)(object)((__instance is SprayPaintItem) ? __instance : null);
			if (val != null && val.isWeedKillerSprayBottle && WeedKillerConfig.usesBattery.Value)
			{
				_sprayCanTankRef.Invoke(val) = ((GrabbableObject)val).insertedBattery.charge;
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem), "LateUpdate")]
		[HarmonyPrefix]
		private static void PreWeedKillerLateUpdate(SprayPaintItem __instance)
		{
			_tempCanTank = _sprayCanTankRef.Invoke(__instance);
		}

		[HarmonyPatch(typeof(SprayPaintItem), "LateUpdate")]
		[HarmonyPostfix]
		private static void PostWeedKillerLateUpdate(SprayPaintItem __instance)
		{
			if (__instance.isWeedKillerSprayBottle)
			{
				bool flag = _isSprayingRef.Invoke(__instance);
				if (((GrabbableObject)__instance).isHeld && flag)
				{
					float num = ((_killWeedSpeedRef != null) ? 1f : WeedKillerConfig.weedKillRate.Value);
					float num2 = Mathf.Max(_tempCanTank - Time.deltaTime / (15f * WeedKillerConfig.weedKillTank.Value * num), 0f);
					_sprayCanTankRef.Invoke(__instance) = num2;
				}
				if (WeedKillerConfig.usesBattery.Value)
				{
					((GrabbableObject)__instance).insertedBattery.charge = _sprayCanTankRef.Invoke(__instance);
				}
			}
		}
	}
}