using HarmonyLib; using System; using System.Reflection; using UnityEngine; namespace CustomCosmeticLoader.Patches { [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; // If this is a networked game, ONLY apply to my marble and not anyone else happening to use our SkinToHijack if (NetworkManager.IsMultiplayer) { MarbleController controller = __instance.GetComponentInParent(); if (!controller.isMyClientMarble()) return; } Shared.ApplyCustomTexture(__instance.currentMarble); } } [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; FieldInfo mbcField = typeof(MarbleHolder).GetField("mbc", BindingFlags.NonPublic | BindingFlags.Instance); MarbleController controller = mbcField.GetValue(__instance) as MarbleController; if (controller == null) 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; } } }