using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SemiHands; using SemiHands.Patches; 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("SemiHandsFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("SemiHandsFix")] [assembly: AssemblyTitle("SemiHandsFix")] [assembly: AssemblyVersion("0.1.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 SemiHandsFix { [HarmonyPatch(typeof(FlashlightController), "Update")] internal static class FlashlightVisibilityPatch { private struct HideState { internal bool WasForced; internal bool OriginalValue; } [HarmonyPrefix] [HarmonyPriority(0)] private static void ForceVanillaHideWhileFistsAreActive(FlashlightController __instance, ref bool ___hideFlashlight, out HideState __state) { __state = default(HideState); if (IsInFistsMode(__instance)) { __state.WasForced = true; __state.OriginalValue = ___hideFlashlight; ___hideFlashlight = true; } } [HarmonyPostfix] [HarmonyPriority(800)] private static void RestoreVanillaHideState(ref bool ___hideFlashlight, HideState __state) { if (__state.WasForced) { ___hideFlashlight = __state.OriginalValue; } } [HarmonyFinalizer] private static Exception RestoreVanillaHideStateAfterException(Exception __exception, ref bool ___hideFlashlight, HideState __state) { RestoreVanillaHideState(ref ___hideFlashlight, __state); return __exception; } private static bool IsInFistsMode(FlashlightController flashlight) { if ((Object)(object)flashlight == (Object)null || (Object)(object)flashlight.PlayerAvatar == (Object)null) { return false; } PlayerFightController instance = PlayerFightController.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.PlayerAvatar == (Object)(object)flashlight.PlayerAvatar) { return instance.IsInFistsMode; } instance = ((Component)flashlight.PlayerAvatar).GetComponent(); if ((Object)(object)instance != (Object)null) { return instance.IsInFistsMode; } return false; } } [HarmonyPatch(typeof(PlayerAvatarRightArm_UpdateTranspiler), "CheckR")] internal static class RightArmNullGuardPatch { [HarmonyPrefix] private static bool ReturnFalseForMissingAvatar(PlayerAvatar avatar, ref bool __result) { if ((Object)(object)avatar != (Object)null) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(PlayerAvatarLeftArm_UpdateTranspiler), "CheckL")] internal static class LeftArmNullGuardPatch { [HarmonyPrefix] private static bool ReturnFalseForMissingAvatar(PlayerAvatar avatar, ref bool __result) { if ((Object)(object)avatar != (Object)null) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(FlashlightController_UpdateTranspiler), "Check")] internal static class FlashlightNullGuardPatch { [HarmonyPrefix] private static bool ReturnFalseForMissingAvatar(FlashlightController __instance, ref bool __result) { if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.PlayerAvatar != (Object)null) { return true; } __result = false; return false; } } [BepInPlugin("mathe.semihandsfix", "SemiHands Fix", "0.1.0")] [BepInDependency("NoteBoxz.SemiHands", "0.1.1")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "mathe.semihandsfix"; public const string PluginName = "SemiHands Fix"; public const string PluginVersion = "0.1.0"; public const string SemiHandsGuid = "NoteBoxz.SemiHands"; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; if (!ValidateTargets(out var error)) { ((BaseUnityPlugin)this).Logger.LogError((object)("SemiHands Fix is disabled because the installed SemiHands DLL does not match the expected methods: " + error)); return; } _harmony = new Harmony("mathe.semihandsfix"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"SemiHands Fix 0.1.0 loaded. SemiHands null-avatar guards and fists-mode flashlight hiding are active."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Log = null; } private static bool ValidateTargets(out string error) { if (!IsExpectedBooleanMethod(AccessTools.Method(typeof(PlayerAvatarRightArm_UpdateTranspiler), "CheckR", new Type[1] { typeof(PlayerAvatar) }, (Type[])null), typeof(PlayerAvatar))) { error = "PlayerAvatarRightArm_UpdateTranspiler.CheckR(PlayerAvatar) was not found as a bool method."; return false; } if (!IsExpectedBooleanMethod(AccessTools.Method(typeof(PlayerAvatarLeftArm_UpdateTranspiler), "CheckL", new Type[1] { typeof(PlayerAvatar) }, (Type[])null), typeof(PlayerAvatar))) { error = "PlayerAvatarLeftArm_UpdateTranspiler.CheckL(PlayerAvatar) was not found as a bool method."; return false; } if (!IsExpectedBooleanMethod(AccessTools.Method(typeof(FlashlightController_UpdateTranspiler), "Check", new Type[1] { typeof(FlashlightController) }, (Type[])null), typeof(FlashlightController))) { error = "FlashlightController_UpdateTranspiler.Check(FlashlightController) was not found as a bool method."; return false; } MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(FlashlightController), "Update", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo.ReturnType != typeof(void) || methodInfo.GetParameters().Length != 0) { error = "FlashlightController.Update() was not found as a parameterless void method."; return false; } FieldInfo fieldInfo = AccessTools.Field(typeof(FlashlightController), "hideFlashlight"); if (fieldInfo == null || fieldInfo.FieldType != typeof(bool)) { error = "FlashlightController.hideFlashlight was not found as a bool field."; return false; } PropertyInfo propertyInfo = AccessTools.Property(typeof(PlayerFightController), "IsInFistsMode"); if (propertyInfo == null || propertyInfo.PropertyType != typeof(bool) || propertyInfo.GetMethod == null) { error = "PlayerFightController.IsInFistsMode was not found as a readable bool property."; return false; } error = null; return true; } private static bool IsExpectedBooleanMethod(MethodInfo method, Type parameterType) { if (method == null || method.ReturnType != typeof(bool)) { return false; } ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1) { return parameters[0].ParameterType == parameterType; } return false; } } }