Decompiled source of CrossplayStutterFix v1.1.0

CrossplayStutterFix.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Rombusz")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Reduces PEAK character lifecycle hitches caused by initialization races and repeated diagnostic exceptions.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("CrossplayStutterFix")]
[assembly: AssemblyTitle("CrossplayStutterFix")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 CrossplayStutterFix
{
	[BepInPlugin("Rombusz.CrossplayStutterFix", "CrossplayStutterFix", "1.1.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "Rombusz.CrossplayStutterFix";

		public const string Name = "CrossplayStutterFix";

		public const string Version = "1.1.0";

		private Harmony? _harmony;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("Rombusz.CrossplayStutterFix");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogMessage((object)"Plugin CrossplayStutterFix 1.1.0 is loaded!");
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(CharacterData))]
	internal static class CharacterDataRegistryPatch
	{
		private static readonly FieldRef<CharacterData, PhotonView> View = AccessTools.FieldRefAccess<CharacterData, PhotonView>("m_photonView");

		private static readonly FieldRef<Dictionary<Player, CharacterData>> Instances = AccessTools.StaticFieldRefAccess<Dictionary<Player, CharacterData>>(AccessTools.Field(typeof(CharacterData), "m_instances"));

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void RegisterNewestCharacter(CharacterData __instance)
		{
			PhotonView val = View.Invoke(__instance);
			Dictionary<Player, CharacterData> dictionary = Instances.Invoke();
			if (((val != null) ? val.Owner : null) != null && dictionary != null)
			{
				dictionary[val.Owner] = __instance;
				VoiceDataInitializationPatch.AllowCommunication(__instance);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnDestroy")]
		private static bool RemoveOnlyCurrentCharacter(CharacterData __instance)
		{
			PhotonView val = View.Invoke(__instance);
			Dictionary<Player, CharacterData> dictionary = Instances.Invoke();
			if (((val != null) ? val.Owner : null) != null && dictionary != null && dictionary.TryGetValue(val.Owner, out var value) && value == __instance)
			{
				dictionary.Remove(val.Owner);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(CharacterVoiceHandler))]
	internal static class VoiceDataInitializationPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("CheckCommunicationWithUser")]
		private static bool InitializePlayer(Player p)
		{
			CharacterData data = default(CharacterData);
			if (p != null && CharacterData.TryGetPlayerData(p, ref data))
			{
				AllowCommunication(data);
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("CheckCommunicationWithCharacter")]
		private static bool InitializeCharacter(Character c)
		{
			if ((Object)(object)c != (Object)null)
			{
				InitializePlayer(((MonoBehaviourPun)c).photonView.Controller);
			}
			return false;
		}

		internal static void AllowCommunication(CharacterData data)
		{
			data.canCommunicateWith = true;
			data.isMuted = false;
		}
	}
	[HarmonyPatch(typeof(Character), "WarpPlayer")]
	internal static class CharacterWarpPatch
	{
		private static readonly MethodInfo LogError = AccessTools.Method(typeof(Debug), "LogError", new Type[1] { typeof(object) }, (Type[])null);

		private static readonly MethodInfo StopAnyClimbing = AccessTools.Method(typeof(CharacterClimbing), "StopAnyClimbing", (Type[])null, (Type[])null);

		private static readonly MethodInfo StopClimbingWhenReady = AccessTools.Method(typeof(CharacterWarpPatch), "StopClimbingIfInitialized", (Type[])null, (Type[])null);

		private static readonly FieldRef<CharacterClimbing, Character> ClimbingCharacter = AccessTools.FieldRefAccess<CharacterClimbing, Character>("character");

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> RepairEarlyWarpAndRemoveErrorStack(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, StopAnyClimbing))
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = StopClimbingWhenReady;
				}
				else if (CodeInstructionExtensions.Calls(instruction, LogError))
				{
					instruction.opcode = OpCodes.Pop;
					instruction.operand = null;
				}
				yield return instruction;
			}
		}

		private static void StopClimbingIfInitialized(CharacterClimbing climbing)
		{
			if ((Object)(object)climbing != (Object)null && (Object)(object)ClimbingCharacter.Invoke(climbing) != (Object)null)
			{
				climbing.StopAnyClimbing();
			}
		}
	}
	[HarmonyPatch(typeof(AnimatedMouth), "Start")]
	internal static class MalformedGhostMouthPatch
	{
		[HarmonyPrefix]
		private static bool DisableIfAudioSourceIsMissing(AnimatedMouth __instance)
		{
			if (!__instance.isGhost || (Object)(object)__instance.audioSource != (Object)null)
			{
				return true;
			}
			((Behaviour)__instance).enabled = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Dynamite), "TestLightWick")]
	internal static class DynamiteProximityPatch
	{
		private static Character? _readyCharacter;

		[HarmonyPrefix]
		private static bool RunWhenLocalCharacterIsUsable()
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return false;
			}
			if ((Object)(object)localCharacter == (Object)(object)_readyCharacter)
			{
				return true;
			}
			if (localCharacter.refs != null && (Object)(object)localCharacter.refs.ragdoll != (Object)null && localCharacter.refs.ragdoll.partDict.TryGetValue((BodypartType)2, out var value) && (Object)(object)value != (Object)null && (Object)(object)value.transform != (Object)null)
			{
				_readyCharacter = localCharacter;
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_Fall")]
	internal static class FallDiagnosticPatch
	{
		private static readonly MethodInfo Log = AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(object) }, (Type[])null);

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> RemoveRepeatedFallLog(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, Log))
				{
					instruction.opcode = OpCodes.Pop;
					instruction.operand = null;
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterStats), "Record")]
	internal static class ReviveTimelineDiagnosticPatch
	{
		private static readonly MethodInfo LogError = AccessTools.Method(typeof(Debug), "LogError", new Type[1] { typeof(object) }, (Type[])null);

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> RemoveReviveErrorStack(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, LogError))
				{
					instruction.opcode = OpCodes.Pop;
					instruction.operand = null;
				}
				yield return instruction;
			}
		}
	}
}