Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChuxiaFixes v1.0.7
ChuxiaFixes.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ChuxiaFixes.Patches; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Patches; using Steamworks; using TMPro; 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: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("chuxiaaaa")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("\r\n\t\tA collection of Fixes for the vanilla game.(including LateJoin, Player Name, and various bug fixes.)\r\n\t")] [assembly: AssemblyFileVersion("1.0.7.0")] [assembly: AssemblyInformationalVersion("1.0.7+881f9d684486953c9b05e0588379e7b35063f190")] [assembly: AssemblyProduct("ChuxiaFixes")] [assembly: AssemblyTitle("ChuxiaFixes")] [assembly: AssemblyMetadata("RepositoryUrl", "__PROJECT_URL__")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.7.0")] [module: UnverifiableCode] [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; } } } [BepInPlugin("ChuxiaFixes", "ChuxiaFixes", "1.0.7")] public class Plugin : BaseUnityPlugin { public static ManualLogSource Log; public static ConfigEntry<bool> FixPlayerName_Enable { get; set; } public static ConfigEntry<float> FixPlayerName_WorkInterval { get; set; } public static ConfigEntry<bool> General_DisableFontWarn { get; set; } public static ConfigEntry<bool> General_DisableNetworkAnalyzer { get; set; } public static ConfigEntry<bool> General_FixDeathBoxes { get; set; } public static ConfigEntry<bool> General_FixGiftBox { get; set; } public static ConfigEntry<bool> General_FixNetworkObject { get; set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; General_DisableFontWarn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableFontWarn", true, "Disable unknow font warning messages in the console."); General_DisableNetworkAnalyzer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableNetworkAnalyzer", true, "Disable the built-in network analyzer that cause performance issues."); General_FixNetworkObject = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FixNetworkObject", true, "Fixed the issue where NetworkObject's cached parent was not set correctly."); General_FixDeathBoxes = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FixDeathBoxes", true, "Fixed the issue where names and avatars were displayed incorrectly in spectator mode."); General_FixGiftBox = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FixGiftBox", true, "Fixed the bug with the gift box in late joining"); FixPlayerName_Enable = ((BaseUnityPlugin)this).Config.Bind<bool>("FixPlayerName", "Enable", true, "Fixed incorrect or unknown player names."); FixPlayerName_WorkInterval = ((BaseUnityPlugin)this).Config.Bind<float>("FixPlayerName", "WorkInterval", 30f, "Interval (in seconds) between each attempt to fix player names."); Harmony.CreateAndPatchAll(typeof(FixPlayerName_Patches), (string)null); Harmony.CreateAndPatchAll(typeof(FixPlayerName_Patches.UpdateMapTargetPostfixPatch), (string)null); Harmony.CreateAndPatchAll(typeof(General_Patches), (string)null); if (General_DisableNetworkAnalyzer.Value) { Harmony.CreateAndPatchAll(typeof(NetworkAnalyzer_Patches), (string)null); } Log.LogInfo((object)"Plugin ChuxiaFixes is loaded!"); } } internal static class LCMPluginInfo { public const string PLUGIN_GUID = "ChuxiaFixes"; public const string PLUGIN_NAME = "ChuxiaFixes"; public const string PLUGIN_VERSION = "1.0.7"; } namespace ChuxiaFixes.Patches { [HarmonyPatch] [HarmonyWrapSafe] public static class NetworkAnalyzer_Patches { public static bool hasPatch { get; set; } public static MethodBase TargetMethod() { Type type = Type.GetType("Unity.Netcode.NetworkMetrics, Unity.Netcode.Runtime"); ConstructorInfo[] constructors = type.GetConstructors(); int num = 0; if (num < constructors.Length) { return constructors[num]; } return null; } private static void Postfix(object __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown if (hasPatch) { return; } hasPatch = true; Harmony val = new Harmony("ChuxiaFixes.NetworkAnalyzer_Patches"); foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(__instance.GetType())) { if (declaredMethod.ReturnType == typeof(void)) { val.Patch((MethodBase)declaredMethod, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(NetworkAnalyzer_Patches), "EmptyMethodTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } } } public static IEnumerable<CodeInstruction> EmptyMethodTranspiler(IEnumerable<CodeInstruction> instructions) { yield return new CodeInstruction(OpCodes.Ret, (object)null); } } } namespace Patches { [HarmonyWrapSafe] public static class FixPlayerName_Patches { [HarmonyPatch] [HarmonyWrapSafe] public static class UpdateMapTargetPostfixPatch { private static ManualCameraRenderer manualCamera; private static bool Prepare() { return Plugin.FixPlayerName_Enable.Value; } private static MethodBase TargetMethod() { Type type = AccessTools.Inner(typeof(ManualCameraRenderer), "<updateMapTarget>d__74"); return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null); } [HarmonyPostfix] public static void Postfix(object __instance, ref bool __result) { if (__result) { return; } if ((Object)(object)manualCamera == (Object)null) { FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "<>4__this"); if (fieldInfo == null) { return; } object? value = fieldInfo.GetValue(__instance); manualCamera = (ManualCameraRenderer)((value is ManualCameraRenderer) ? value : null); } if ((Object)(object)manualCamera != (Object)null && (Object)(object)manualCamera.targetedPlayer != (Object)null && ((TMP_Text)StartOfRound.Instance.mapScreenPlayerName).text != manualCamera.targetedPlayer.playerUsername) { ((TMP_Text)StartOfRound.Instance.mapScreenPlayerName).text = manualCamera.targetedPlayer.playerUsername; } } } private static Coroutine? _fixCoroutine; private static bool _isRegistered; private static readonly WaitForSeconds _workInterval = new WaitForSeconds(Plugin.FixPlayerName_WorkInterval.Value); [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] [HarmonyPostfix] public static void OpenQuickMenu(QuickMenuManager __instance) { if (__instance.NonHostPlayerSlotsEnabled()) { PlayerName_Refresh(); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyMemberJoined")] public static void SteamMatchmaking_OnLobbyMemberJoinedPostfix() { PlayerName_Refresh(); } private static bool PlayerName_Refresh() { if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)StartOfRound.Instance == (Object)null) { return false; } if (GameNetworkManager.Instance.disableSteam) { return false; } if (!Plugin.FixPlayerName_Enable.Value) { return false; } ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(RefreshPlayerNames()); return true; } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "SendNewPlayerValuesClientRpc")] public static void SendNewPlayerValuesClientRpc() { PlayerName_Refresh(); } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")] public static void OnPlayerConnectedClientRpc() { PlayerName_Refresh(); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void ConnectClientToPlayerObjectPostfix(PlayerControllerB __instance) { if (!GameNetworkManager.Instance.disableSteam && Plugin.FixPlayerName_Enable.Value) { StopFixCoroutine((MonoBehaviour)(object)__instance); _fixCoroutine = ((MonoBehaviour)__instance).StartCoroutine(FixPlayerNamesRoutine()); } } [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "OnLocalDisconnect")] public static void OnLocalDisconnect() { StopFixCoroutine(); } private static void StopFixCoroutine(MonoBehaviour behaviour = null) { if (_fixCoroutine != null) { MonoBehaviour val = (MonoBehaviour)(((object)behaviour) ?? ((object)StartOfRound.Instance?.localPlayerController)); if (val != null) { val.StopCoroutine(_fixCoroutine); } if (_isRegistered) { SteamFriends.OnPersonaStateChange -= OnPersonaStateChange; _isRegistered = false; } _fixCoroutine = null; } } private static IEnumerator FixPlayerNamesRoutine() { if (!_isRegistered) { SteamFriends.OnPersonaStateChange += OnPersonaStateChange; _isRegistered = true; } while ((Object)(object)StartOfRound.Instance?.localPlayerController != (Object)null) { yield return _workInterval; yield return RefreshPlayerNames(); } StopFixCoroutine(); } private static IEnumerator RefreshPlayerNames() { StartOfRound instance = StartOfRound.Instance; if (instance?.allPlayerScripts == null) { yield break; } QuickMenuManager quickMenu = Object.FindObjectOfType<QuickMenuManager>(); if ((Object)(object)quickMenu == (Object)null) { yield break; } PlayerControllerB[] players = instance.allPlayerScripts; for (int i = 0; i < players.Length; i++) { PlayerControllerB player = players[i]; PlayerListSlot slot = quickMenu.playerListSlots[i]; if (slot == null || (Object)(object)slot.slotContainer == (Object)null) { continue; } GameObject container = slot.slotContainer; if (!player.isPlayerControlled && !player.isPlayerDead) { if (container.activeSelf) { container.SetActive(false); } continue; } if (!container.activeSelf) { container.SetActive(true); } yield return UpdatePlayerName(player, slot); } } private static IEnumerator UpdatePlayerName(PlayerControllerB player, PlayerListSlot slot) { try { Friend friend = new Friend(SteamId.op_Implicit(player.playerSteamId)); string steamName = ((Friend)(ref friend)).Name; if (steamName == "[unknown]") { SteamFriends.RequestUserInformation(SteamId.op_Implicit(player.playerSteamId), true); yield break; } if (player.playerUsername != steamName) { player.playerUsername = steamName; ((TMP_Text)player.usernameBillboardText).text = steamName; } if (((TMP_Text)slot.usernameHeader).text != steamName) { ((TMP_Text)slot.usernameHeader).text = steamName; slot.playerSteamId = player.playerSteamId; } } catch (Exception ex) { Exception ex2 = ex; Plugin.Log.LogError((object)$"[FixPlayerName] UpdatePlayerName:{ex2}"); } } private static void OnPersonaStateChange(Friend friend) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) try { StartOfRound instance = StartOfRound.Instance; if (instance?.allPlayerScripts == null) { return; } QuickMenuManager val = Object.FindObjectOfType<QuickMenuManager>(); if ((Object)(object)val == (Object)null) { return; } PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; for (int i = 0; i < allPlayerScripts.Length; i++) { PlayerControllerB val2 = allPlayerScripts[i]; if ((val2.isPlayerControlled || val2.isPlayerDead) && val2.playerSteamId == friend.Id.Value) { if (((Friend)(ref friend)).Name != val2.playerUsername || ((TMP_Text)val2.usernameBillboardText).text != ((Friend)(ref friend)).Name) { val2.playerUsername = ((Friend)(ref friend)).Name; ((TMP_Text)val2.usernameBillboardText).text = ((Friend)(ref friend)).Name; } PlayerListSlot val3 = val.playerListSlots[i]; ((TMP_Text)val3.usernameHeader).text = ((Friend)(ref friend)).Name; if (!val3.slotContainer.activeSelf) { val3.slotContainer.SetActive(true); } break; } } } catch (Exception arg) { Plugin.Log.LogError((object)$"[FixPlayerName] OnPersonaStateChange:{arg}"); } } } [HarmonyWrapSafe] public static class General_Patches { [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void warningsDisabled(ref bool __result) { if (Plugin.General_DisableFontWarn.Value) { __result = true; } } [HarmonyPrefix] [HarmonyPatch(typeof(NetworkObject), "GetCachedParent")] public static void GetCachedParent(NetworkObject __instance) { if (Plugin.General_FixNetworkObject.Value && (Object)(object)__instance.m_CachedParent == (Object)null) { __instance.SetCachedParent(((Component)__instance).transform.parent); } } [HarmonyPostfix] [HarmonyPatch(typeof(SceneEventData), "AddSpawnedNetworkObjects")] public static void AddSpawnedNetworkObjects(SceneEventData __instance) { if (!Plugin.General_FixGiftBox.Value || __instance?.m_NetworkObjectsSync == null) { return; } for (int num = __instance.m_NetworkObjectsSync.Count - 1; num >= 0; num--) { NetworkObject val = __instance.m_NetworkObjectsSync[num]; if (!((Object)(object)val == (Object)null)) { GrabbableObject componentInChildren = ((Component)val).GetComponentInChildren<GrabbableObject>(); GiftBoxItem val2 = (GiftBoxItem)(object)((componentInChildren is GiftBoxItem) ? componentInChildren : null); if (val2 != null && val2.hasUsedGift) { Plugin.Log.LogInfo((object)$"[GiftBox] Remove {((Object)val).GetInstanceID()}"); __instance.m_NetworkObjectsSync.RemoveAt(num); Object.Destroy((Object)(object)((Component)val).gameObject); } } } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")] private static void ResetHUDManager() { if (Plugin.General_FixDeathBoxes.Value) { HUDManager instance = HUDManager.Instance; if (!((Object)(object)instance == (Object)null)) { instance.spectatingPlayerBoxes = new Dictionary<Animator, PlayerControllerB>(); instance.boxesAdded = 0; } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }