Decompiled source of EasyHarvest v10.0.0

plugins/EasyHarvest/EasyHarvest.dll

Decompiled 5 days 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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("EasyHarvest")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EasyHarvest")]
[assembly: AssemblyTitle("EasyHarvest")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 EasyHarvest
{
	[BepInPlugin("easyharvest.client.only", "EasyHarvest", "1.0.0")]
	public class EasyHarvestPlugin : BaseUnityPlugin
	{
		public const string Guid = "easyharvest.client.only";

		public const string PluginName = "EasyHarvest";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> CritEnabled;

		internal static ConfigEntry<float> CritMultiplier;

		internal static ConfigEntry<bool> CritPickaxeOnly;

		internal static ConfigEntry<bool> SpeedEnabled;

		internal static ConfigEntry<float> SpeedMultiplier;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			CritEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Mining Crit", "Enabled", true, "挖矿伤害加成开关。作用对象是矿石(MineRock5 / MineRock)。");
			CritMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Mining Crit", "DamageMultiplier", 1.5f, new ConfigDescription("每次挖矿的伤害倍率:1.5 = 原版 1.5 倍。\n直接乘在伤害数值上,与站位、角度、是否站在矿石上方都无关。\n(岩石本身对锄击有弱点加成,所以最终数字会比面板更高,这是正常的。)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			CritPickaxeOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Mining Crit", "PickaxeOnly", false, "只对「带锄击伤害的命中」生效(true)/对所有打矿石的伤害都生效(false,默认)。\n矿石对大多数伤害类型免疫,所以保持 false 也不会误伤别的玩法。");
			SpeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Pickaxe Swing Speed", "Enabled", true, "镐子挥击速度开关。只影响你手持镐子攻击时自己的动画速度。");
			SpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Pickaxe Swing Speed", "SpeedMultiplier", 1.3f, new ConfigDescription("镐子挥击速度倍率:1.3 = 挥击快 30%。\n原版镐子一次挥击约 1.4 秒,1.3 倍后约 1.08 秒。\n调太高动画会显得发飘,建议 1.2 - 1.6。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()));
			Log.LogInfo((object)"EasyHarvest 1.0.0 开始挂载 Harmony 补丁……");
			SwingSpeed.Init();
			ApplyPatches();
			VerifyPatches();
		}

		private void ApplyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			harmony = new Harmony("easyharvest.client.only");
			Type[] array = new Type[3]
			{
				typeof(MineRock5DamagePatch),
				typeof(MineRockDamagePatch),
				typeof(HumanoidUpdateAttackPatch)
			};
			int num = 0;
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
					Log.LogInfo((object)("  已挂载补丁类:" + type.Name));
					num++;
				}
				catch (Exception ex)
				{
					Log.LogError((object)("  挂载失败 " + type.Name + ":" + ex.Message));
				}
			}
			Log.LogInfo((object)$"Harmony 补丁挂载完成:{num}/{array.Length} 成功。");
		}

		private void VerifyPatches()
		{
			List<MethodBase> list = new List<MethodBase>();
			MethodBase methodBase = AccessTools.Method(typeof(MineRock5), "Damage", (Type[])null, (Type[])null);
			if (methodBase != null)
			{
				list.Add(methodBase);
			}
			methodBase = AccessTools.Method(typeof(MineRock), "Damage", (Type[])null, (Type[])null);
			if (methodBase != null)
			{
				list.Add(methodBase);
			}
			methodBase = AccessTools.Method(typeof(Humanoid), "UpdateAttack", (Type[])null, (Type[])null);
			if (methodBase != null)
			{
				list.Add(methodBase);
			}
			Log.LogInfo((object)"---- 补丁挂载自检 ----");
			foreach (MethodBase item in list)
			{
				Patches patchInfo = Harmony.GetPatchInfo(item);
				int num = ((patchInfo != null && patchInfo.Prefixes != null) ? patchInfo.Prefixes.Count : 0);
				int num2 = ((patchInfo != null && patchInfo.Postfixes != null) ? patchInfo.Postfixes.Count : 0);
				string text = ((num + num2 > 0) ? "OK" : "!! 未挂上 !!");
				Log.LogInfo((object)$"  {item.DeclaringType.Name}.{item.Name}()  prefix={num} postfix={num2}  {text}");
			}
			Log.LogInfo((object)"-----------------------");
		}

		private void OnDestroy()
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class MiningCrit
	{
		private static readonly ConditionalWeakTable<HitData, object> Handled = new ConditionalWeakTable<HitData, object>();

		private static int appliedCount;

		internal static int AppliedCount => appliedCount;

		internal static void TryBoost(HitData hit, string source)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			try
			{
				if (hit == null || !EasyHarvestPlugin.CritEnabled.Value)
				{
					return;
				}
				float value = EasyHarvestPlugin.CritMultiplier.Value;
				if (!(value <= 1f) && (!EasyHarvestPlugin.CritPickaxeOnly.Value || hit.m_damage.m_pickaxe > 0f || (int)hit.m_skill == 12) && !Handled.TryGetValue(hit, out var _))
				{
					Handled.Add(hit, null);
					float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
					((DamageTypes)(ref hit.m_damage)).Modify(value);
					float totalDamage2 = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
					appliedCount++;
					if (appliedCount <= 5)
					{
						EasyHarvestPlugin.Log.LogInfo((object)$"[{source}] 挖矿伤害 {totalDamage:0.#} -> {totalDamage2:0.#}(x{value})");
					}
					else if (appliedCount == 6)
					{
						EasyHarvestPlugin.Log.LogInfo((object)"(后续同类日志省略,功能已在正常工作)");
					}
				}
			}
			catch (Exception ex)
			{
				EasyHarvestPlugin.Log.LogError((object)("挖矿伤害加成失败(普通挖矿不受影响):" + ex));
			}
		}
	}
	internal static class SwingSpeed
	{
		private static FieldInfo animatorField;

		private static FieldInfo zanimField;

		private static MethodInfo zanimSetSpeed;

		private static FieldInfo skillTypeField;

		private static readonly ConditionalWeakTable<Character, object> Touched = new ConditionalWeakTable<Character, object>();

		internal static void Init()
		{
			try
			{
				animatorField = AccessTools.Field(typeof(Character), "m_animator");
				zanimField = AccessTools.Field(typeof(Character), "m_zanim");
				if (zanimField != null)
				{
					zanimSetSpeed = AccessTools.Method(zanimField.FieldType, "SetSpeed", new Type[1] { typeof(float) }, (Type[])null);
				}
				skillTypeField = AccessTools.Field(typeof(SharedData), "m_skillType");
				EasyHarvestPlugin.Log.LogInfo((object)$"挥击速度依赖检查: m_animator={animatorField != null}  m_zanim={zanimField != null}  SetSpeed={zanimSetSpeed != null}  m_skillType={skillTypeField != null}");
			}
			catch (Exception ex)
			{
				EasyHarvestPlugin.Log.LogError((object)("挥击速度初始化失败:" + ex));
			}
		}

		internal static void Update(Humanoid humanoid)
		{
			try
			{
				if ((Object)(object)humanoid == (Object)null)
				{
					return;
				}
				float num = 1f;
				if (EasyHarvestPlugin.SpeedEnabled.Value && ((Character)humanoid).InAttack() && IsPickaxeInHand(humanoid))
				{
					num = Mathf.Max(1f, EasyHarvestPlugin.SpeedMultiplier.Value);
				}
				object value2;
				if (num > 1f)
				{
					SetSpeed((Character)(object)humanoid, num);
					if (!Touched.TryGetValue((Character)(object)humanoid, out var _))
					{
						Touched.Add((Character)(object)humanoid, null);
					}
				}
				else if (Touched.TryGetValue((Character)(object)humanoid, out value2))
				{
					SetSpeed((Character)(object)humanoid, 1f);
					Touched.Remove((Character)(object)humanoid);
				}
			}
			catch (Exception ex)
			{
				EasyHarvestPlugin.Log.LogError((object)("挥击速度调整失败(普通攻击不受影响):" + ex));
			}
		}

		private static bool IsPickaxeInHand(Humanoid humanoid)
		{
			if (skillTypeField == null)
			{
				return false;
			}
			ItemData currentWeapon = humanoid.GetCurrentWeapon();
			if (currentWeapon == null || currentWeapon.m_shared == null)
			{
				return false;
			}
			object value = skillTypeField.GetValue(currentWeapon.m_shared);
			if (value != null)
			{
				return value.ToString() == "Pickaxes";
			}
			return false;
		}

		private static void SetSpeed(Character character, float speed)
		{
			if (zanimField != null && zanimSetSpeed != null)
			{
				object value = zanimField.GetValue(character);
				if (value != null)
				{
					zanimSetSpeed.Invoke(value, new object[1] { speed });
					return;
				}
			}
			if (animatorField != null)
			{
				object? value2 = animatorField.GetValue(character);
				Animator val = (Animator)((value2 is Animator) ? value2 : null);
				if ((Object)(object)val != (Object)null)
				{
					val.speed = speed;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MineRock5), "Damage")]
	internal static class MineRock5DamagePatch
	{
		[HarmonyPrefix]
		private static void Prefix(HitData hit)
		{
			MiningCrit.TryBoost(hit, "MineRock5");
		}
	}
	[HarmonyPatch(typeof(MineRock), "Damage")]
	internal static class MineRockDamagePatch
	{
		[HarmonyPrefix]
		private static void Prefix(HitData hit)
		{
			MiningCrit.TryBoost(hit, "MineRock");
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UpdateAttack")]
	internal static class HumanoidUpdateAttackPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Humanoid __instance)
		{
			SwingSpeed.Update(__instance);
		}
	}
}