using HarmonyLib; using Parse.Common.Internal; using System; using System.Reflection; using UnityEngine; namespace CustomCosmeticLoader.Patches { internal static class MarbleHolderValues { private static FieldInfo _mbcField = typeof(MarbleHolder).GetField("mbc", BindingFlags.NonPublic | BindingFlags.Instance); public static FieldInfo MbcField { get { return _mbcField; } } } [HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.SetMarble))] internal class MarbleHolderSetMarblePatch { static void Postfix(MarbleHolder __instance, Cosmetic marbleObject) { if (!Config.enabled) return; if (marbleObject.Id != Config.skinNameToHijack && Config.skinNameToHijack != "*") return; if (!Config.inCosmeticMenu && __instance == CosmeticPanel.cosmHolder) return; Texture2D skin = null; if (NetworkManager.IsMultiplayer) { MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController; if (controller == null) return; if (!controller.isMyClientMarble()) { if (!Config.otherPlayers.ContainsKey(controller.nickname)) return; skin = Config.skins[Config.otherPlayers[controller.nickname]]; } } Shared.ApplyCustomTexture(__instance.currentMarble, skin); } } [HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.CheckSet))] internal class MarbleHolderCheckSetPatch { static void Postfix(MarbleHolder __instance, Cosmetic.Set cs) { if (!Config.enabled) return; if (!NetworkManager.IsMultiplayer) return; MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController; if (controller == null) return; Debug.Log("========= MarbleHolder.CheckSet with nickname " + controller.nickname); if (!controller.isMyClientMarble()) { if (!Config.otherPlayers.ContainsKey(controller.nickname)) return; } // Don't hijack the soccer ball or zombie skins if (cs.skin == "SoccerBall_V4" || cs.skin == "Zombie") return; __instance.SetMarble(Shared.SkinToHijack); __instance.CosmeticSet.skin = cs.skin; } } }