Decompiled source of VehicleJump v1.0.0

Zichen-VehicleJump-1.0.0.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Zichen-VehicleJump")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1a60eed8779fb0fe09b431111fff1ba26d82e689")]
[assembly: AssemblyProduct("Zichen-VehicleJump")]
[assembly: AssemblyTitle("Zichen-VehicleJump")]
[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 Zichen_VehicleJump
{
	[BepInPlugin("zichen.vehiclejump", "VehicleJump", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "zichen.vehiclejump";

		public const string PluginName = "VehicleJump";

		public const string PluginVersion = "1.0.0";

		internal static Plugin Instance;

		private static ConfigEntry<bool> _cfgModEnabled;

		private static ConfigEntry<int> _cfgJumpForce;

		private static ConfigEntry<float> _cfgJumpCooldown;

		private static ConfigEntry<float> _cfgTumbleProtectDuration;

		private static ConfigEntry<bool> _cfgContinuousJump;

		internal static float _jumpCooldownTimer;

		internal static float _tumbleProtectTimer;

		internal static ItemVehicle _pendingVehicle;

		internal static int _pendingFrame = -1;

		internal const byte JumpEventCode = 151;

		private bool _eventRegistered;

		internal static readonly CompatibilityState Compat = new CompatibilityState();

		internal static FieldRef<ItemVehicle, bool> f_localPlayerIsMounted;

		internal static FieldRef<ItemVehicle, bool> f_isAnyWheelGrounded;

		internal static FieldRef<ItemVehicle, float> f_currentFallGravity;

		internal static FieldRef<ItemVehicle, float> f_accumulatedFallVelocity;

		internal static FieldRef<ItemVehicle, float> f_currentCustomGravitySpeed;

		internal static FieldRef<ItemVehicle, float> f_fallGravityStartHeight;

		internal static FieldRef<ItemVehicle, float> f_seatSlowdownRate;

		internal static FieldRef<ItemVehicle, float> f_seatVelocityDrag;

		internal static FieldRef<ItemVehicle, PhotonView> f_photonView;

		public static float JumpForce => _cfgJumpForce.Value;

		public static float JumpCooldown => _cfgJumpCooldown.Value;

		public static float TumbleProtectDuration => _cfgTumbleProtectDuration.Value;

		public static bool ContinuousJump => _cfgContinuousJump.Value;

		public static bool IsStaticModEnabled()
		{
			if (_cfgModEnabled != null)
			{
				return _cfgModEnabled.Value;
			}
			return false;
		}

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Instance = this;
			DetachFromManager();
			ResetConfigIfVersionChanged();
			BindConfig();
			InitFieldAccessors();
			RunCompatibilityCheck();
			Harmony harmony = new Harmony("zichen.vehiclejump");
			InstallPatches(harmony);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VehicleJump v1.0.0 loaded.");
			if (!Compat.HasIssues)
			{
				return;
			}
			((BaseUnityPlugin)this).Logger.LogWarning((object)("兼容性问题: " + string.Join(", ", Compat.AffectedFeatures)));
			foreach (string detailLog in Compat.DetailLogs)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("  " + detailLog));
			}
		}

		private void Update()
		{
			if (IsStaticModEnabled())
			{
				float deltaTime = Time.deltaTime;
				if (_jumpCooldownTimer > 0f)
				{
					_jumpCooldownTimer -= deltaTime;
				}
				if (_tumbleProtectTimer > 0f)
				{
					_tumbleProtectTimer -= deltaTime;
				}
				if (_eventRegistered && !PhotonNetwork.IsConnected)
				{
					_eventRegistered = false;
				}
				if (!_eventRegistered && PhotonNetwork.IsConnected)
				{
					PhotonNetwork.NetworkingClient.EventReceived += OnJumpEvent;
					_eventRegistered = true;
				}
			}
		}

		private void OnDestroy()
		{
			if (_eventRegistered && PhotonNetwork.IsConnected)
			{
				PhotonNetwork.NetworkingClient.EventReceived -= OnJumpEvent;
			}
		}

		private void OnJumpEvent(EventData photonEvent)
		{
			if (!IsStaticModEnabled() || !SemiFunc.IsMasterClientOrSingleplayer() || !Compat.CanForce || photonEvent.Code != 151 || !(photonEvent.CustomData is object[] array))
			{
				return;
			}
			PhotonView val = PhotonView.Find((int)array[0]);
			if (!((Object)(object)val == (Object)null))
			{
				ItemVehicle component = ((Component)val).GetComponent<ItemVehicle>();
				if (!((Object)(object)component == (Object)null))
				{
					ApplyJumpForce(component);
				}
			}
		}

		internal static void ApplyJumpForce(ItemVehicle vehicle)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			Rigidbody rb = vehicle.rb;
			if (Object.op_Implicit((Object)(object)rb))
			{
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(0f, rb.velocity.y, 0f);
				rb.AddForce(Vector3.up * JumpForce - val, (ForceMode)2);
				_tumbleProtectTimer = TumbleProtectDuration;
				if (f_currentFallGravity != null)
				{
					f_currentFallGravity.Invoke(vehicle) = 0f;
				}
				if (f_accumulatedFallVelocity != null)
				{
					f_accumulatedFallVelocity.Invoke(vehicle) = 0f;
				}
				if (f_currentCustomGravitySpeed != null)
				{
					f_currentCustomGravitySpeed.Invoke(vehicle) = 0f;
				}
				if (f_fallGravityStartHeight != null)
				{
					f_fallGravityStartHeight.Invoke(vehicle) = ((Component)vehicle).transform.position.y;
				}
			}
		}

		private static void InitFieldAccessors()
		{
			f_localPlayerIsMounted = TryField<ItemVehicle, bool>("localPlayerIsMounted", "跳跃输入");
			f_isAnyWheelGrounded = TryField<ItemVehicle, bool>("isAnyWheelGrounded", "跳跃输入");
			f_currentFallGravity = TryField<ItemVehicle, float>("currentFallGravity", "跳跃施力");
			f_accumulatedFallVelocity = TryField<ItemVehicle, float>("accumulatedFallVelocity", "跳跃施力");
			f_currentCustomGravitySpeed = TryField<ItemVehicle, float>("currentCustomGravitySpeed", "跳跃施力");
			f_fallGravityStartHeight = TryField<ItemVehicle, float>("fallGravityStartHeight", "跳跃施力");
			f_seatSlowdownRate = TryField<ItemVehicle, float>("seatSlowdownRate", "跳跃施力");
			f_seatVelocityDrag = TryField<ItemVehicle, float>("seatVelocityDrag", "跳跃施力");
			f_photonView = TryField<ItemVehicle, PhotonView>("photonView", "跳跃施力");
		}

		private static FieldRef<T, F> TryField<T, F>(string name, string feature) where T : class
		{
			try
			{
				if (typeof(T).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null)
				{
					Compat.MarkFailed(feature, "字段 " + typeof(T).Name + "." + name + " 不存在");
					return null;
				}
				return AccessTools.FieldRefAccess<T, F>(name);
			}
			catch (Exception ex)
			{
				Compat.MarkFailed(feature, "无法访问 " + typeof(T).Name + "." + name + ": " + ex.Message);
				return null;
			}
		}

		private static void RunCompatibilityCheck()
		{
			CheckMethod(typeof(ItemVehicle), "Update", Type.EmptyTypes, "跳跃输入");
			CheckMethod(typeof(ItemVehicle), "FixedUpdateActive", Type.EmptyTypes, "跳跃施力");
			CheckMethod(typeof(ItemVehicle), "TumbleVehicle", new Type[1] { typeof(float) }, "翻车保护");
		}

		private static void CheckMethod(Type type, string name, Type[] args, string feature)
		{
			if (type.GetMethod(name, AccessTools.all, null, args, null) == null)
			{
				Compat.MarkFailed(feature, "方法 " + type.Name + "." + name + " 不存在");
			}
		}

		private void InstallPatches(Harmony harmony)
		{
			SafePatch(harmony, typeof(Patch_Update), "跳跃输入");
			SafePatch(harmony, typeof(Patch_FixedUpdateActive), "跳跃施力");
			SafePatch(harmony, typeof(Patch_TumbleVehicle), "翻车保护");
		}

		private void SafePatch(Harmony harmony, Type patchType, string feature)
		{
			try
			{
				harmony.CreateClassProcessor(patchType).Patch();
			}
			catch (Exception ex)
			{
				Compat.MarkFailed(feature, "补丁失败: " + ex.Message);
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[VehicleJump] " + patchType.Name + " 失败: " + ex.Message));
			}
		}

		private void BindConfig()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组名称", "车辆跳跃", new ConfigDescription("", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Browsable = false
				}
			}));
			((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组版本号", "1.0.0", new ConfigDescription("", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Browsable = false
				}
			}));
			_cfgModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "模组启用", true, "关闭后整个模组全部功能彻底失效");
			_cfgContinuousJump = ((BaseUnityPlugin)this).Config.Bind<bool>("B.跳跃设置", "连续跳跃", false, "开启后可在空中无限跳跃");
			_cfgJumpForce = ((BaseUnityPlugin)this).Config.Bind<int>("B.跳跃设置", "跳跃力", 25, new ConfigDescription("跳跃后的向上速度(m/s),不受车辆质量影响,值越大跳越高", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_cfgJumpCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("B.跳跃设置", "跳跃冷却", 0.1f, new ConfigDescription("两次跳跃之间的最小间隔(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			_cfgTumbleProtectDuration = ((BaseUnityPlugin)this).Config.Bind<float>("B.跳跃设置", "翻车保护时间", 0.1f, new ConfigDescription("跳跃后免翻车保护的持续时间(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
		}

		private void ResetConfigIfVersionChanged()
		{
			try
			{
				string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
				string text = ReadConfigPluginVersion(configFilePath);
				if (!string.IsNullOrWhiteSpace(text) && !(text == "1.0.0"))
				{
					((BaseUnityPlugin)this).Config.Clear();
					if (File.Exists(configFilePath))
					{
						File.Delete(configFilePath);
					}
					((BaseUnityPlugin)this).Config.Reload();
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Config version changed. Old config was reset to defaults.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to reset config by version: " + ex.Message));
			}
		}

		private static string ReadConfigPluginVersion(string configPath)
		{
			if (!File.Exists(configPath))
			{
				return null;
			}
			Match match = Regex.Match(File.ReadAllText(configPath), "(?m)^模组版本号\\s*=\\s*(.+?)\\s*$");
			if (!match.Success)
			{
				return null;
			}
			return match.Groups[1].Value.Trim();
		}

		private void DetachFromManager()
		{
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}
	}
	internal class CompatibilityState
	{
		private readonly HashSet<string> _failed = new HashSet<string>();

		private readonly List<string> _logs = new List<string>();

		public bool HasIssues => _failed.Count > 0;

		public HashSet<string> AffectedFeatures => _failed;

		public List<string> DetailLogs => _logs;

		public bool CanInput => !_failed.Contains("跳跃输入");

		public bool CanForce => !_failed.Contains("跳跃施力");

		public bool CanTumbleProtect => !_failed.Contains("翻车保护");

		public void MarkFailed(string feature, string detail)
		{
			_failed.Add(feature);
			_logs.Add("[" + feature + "] " + detail);
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "Update")]
	internal static class Patch_Update
	{
		private static void Postfix(ItemVehicle __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			if (!Plugin.IsStaticModEnabled() || !Plugin.Compat.CanInput)
			{
				return;
			}
			FieldRef<ItemVehicle, bool> f_localPlayerIsMounted = Plugin.f_localPlayerIsMounted;
			if (f_localPlayerIsMounted == null || !f_localPlayerIsMounted.Invoke(__instance) || (int)__instance.currentState != 1 || Plugin._jumpCooldownTimer > 0f || !SemiFunc.InputDown((InputKey)1))
			{
				return;
			}
			if (!Plugin.ContinuousJump)
			{
				FieldRef<ItemVehicle, bool> f_isAnyWheelGrounded = Plugin.f_isAnyWheelGrounded;
				if (f_isAnyWheelGrounded == null || !f_isAnyWheelGrounded.Invoke(__instance))
				{
					return;
				}
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				Plugin._pendingVehicle = __instance;
				Plugin._pendingFrame = Time.frameCount;
			}
			else if (PhotonNetwork.IsConnected)
			{
				PhotonView val = ((Plugin.f_photonView != null) ? Plugin.f_photonView.Invoke(__instance) : ((Component)__instance).GetComponent<PhotonView>());
				if ((Object)(object)val != (Object)null)
				{
					object[] array = new object[1] { val.ViewID };
					PhotonNetwork.RaiseEvent((byte)151, (object)array, new RaiseEventOptions
					{
						Receivers = (ReceiverGroup)2
					}, SendOptions.SendReliable);
				}
				Plugin._jumpCooldownTimer = Plugin.JumpCooldown;
			}
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "FixedUpdateActive")]
	internal static class Patch_FixedUpdateActive
	{
		private static void Postfix(ItemVehicle __instance)
		{
			if (!Plugin.IsStaticModEnabled() || !Plugin.Compat.CanForce)
			{
				return;
			}
			if ((Object)(object)Plugin._pendingVehicle == (Object)(object)__instance)
			{
				if (Time.frameCount - Plugin._pendingFrame > 10)
				{
					Plugin._pendingVehicle = null;
					return;
				}
				Plugin._pendingVehicle = null;
				Plugin.ApplyJumpForce(__instance);
				Plugin._jumpCooldownTimer = Plugin.JumpCooldown;
			}
			if (Plugin._tumbleProtectTimer > 0f)
			{
				if (Plugin.f_seatSlowdownRate != null)
				{
					Plugin.f_seatSlowdownRate.Invoke(__instance) = 0f;
				}
				if (Plugin.f_seatVelocityDrag != null)
				{
					Plugin.f_seatVelocityDrag.Invoke(__instance) = 0f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "TumbleVehicle", new Type[] { typeof(float) })]
	internal static class Patch_TumbleVehicle
	{
		private static bool Prefix()
		{
			if (!Plugin.IsStaticModEnabled())
			{
				return true;
			}
			if (!Plugin.Compat.CanTumbleProtect)
			{
				return true;
			}
			return Plugin._tumbleProtectTimer <= 0f;
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;

		public Action<ConfigEntryBase> CustomDrawer;

		public bool? ReadOnly;

		public bool? Browsable;
	}
}