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 HeadElfPlus v1.0.0
HeadElfPlus.dll
Decompiled 4 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HeadElfPlus.src.Config; using HeadElfPlus.src.Patches; using Microsoft.CodeAnalysis; 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("HeadElfPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HeadElfPlus")] [assembly: AssemblyTitle("HeadElfPlus")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 HeadElfPlus { [BepInPlugin("HeadElfPlus.Mod", "HeadElfPlus", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "HeadElfPlus.Mod"; public const string Name = "HeadElfPlus"; public const string Version = "1.0.0"; public static Plugin Instance; public static ManualLogSource MLogger; private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Instance = this; MLogger = ((BaseUnityPlugin)this).Logger; ModConfig.Init(); new Harmony("HeadElfPlus.Mod").PatchAll(); } } } namespace HeadElfPlus.src.Patches { [HarmonyPatch] internal static class ChatPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; public static Func<ZNetPeer, string> <>9__1_2; public static ConsoleOptionsFetcher <>9__1_1; internal void <AddRaceCommand>b__1_0(ConsoleEventArgs args) { if (ProcessRaceCommand(args.FullLine, out var output)) { args.Context.AddString(output); } } internal List<string> <AddRaceCommand>b__1_1() { List<string> list = new List<string>(ValidRaces); if ((Object)(object)ZNet.instance != (Object)null) { list.AddRange(from p in ZNet.instance.GetPeers() select p.m_playerName); } if ((Object)(object)Player.m_localPlayer != (Object)null) { list.Add(Player.m_localPlayer.GetPlayerName()); } return list; } internal string <AddRaceCommand>b__1_2(ZNetPeer p) { return p.m_playerName; } } private static readonly string[] ValidRaces = new string[8] { "Elf", "High-Elf", "Half-Orc", "Drow", "Dwarf", "Halfling", "Child", "Human" }; [HarmonyPatch(typeof(Terminal), "InitTerminal")] [HarmonyPostfix] private static void AddRaceCommand() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (ProcessRaceCommand(args.FullLine, out var output)) { args.Context.AddString(output); } }; <>c.<>9__1_0 = val; obj = (object)val; } object obj2 = <>c.<>9__1_1; if (obj2 == null) { ConsoleOptionsFetcher val2 = delegate { List<string> list = new List<string>(ValidRaces); if ((Object)(object)ZNet.instance != (Object)null) { list.AddRange(from p in ZNet.instance.GetPeers() select p.m_playerName); } if ((Object)(object)Player.m_localPlayer != (Object)null) { list.Add(Player.m_localPlayer.GetPlayerName()); } return list; }; <>c.<>9__1_1 = val2; obj2 = (object)val2; } new ConsoleCommand("race", "[Race] [PlayerName]", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)obj2, true, false, false); } internal static bool ProcessRaceCommand(string text, out string output) { output = ""; if (!(bool)AccessTools.Field(typeof(Terminal), "m_cheat").GetValue(null) || !Player.m_debugMode) { output = "<color=red>[HeadElfPlus] Erro: Ative 'devcommands' e 'debugmode' primeiro.</color>"; return true; } string[] array = text.TrimStart('/').Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length < 2) { output = "<color=yellow>Uso: race <Raça> [NomeJogador]</color>"; return true; } string targetRace = array[1]; string targetPlayerName = ((array.Length > 2) ? string.Join(" ", array.Skip(2)) : null); string text2 = ValidRaces.FirstOrDefault((string r) => r.ToLower() == targetRace.ToLower()); if (text2 == null) { output = "<color=red>Raça '" + targetRace + "' inválida.</color>"; return true; } if ((string.IsNullOrEmpty(targetPlayerName) || ((Object)(object)Player.m_localPlayer != (Object)null && targetPlayerName.ToLower() == Player.m_localPlayer.GetPlayerName().ToLower())) && (Object)(object)Player.m_localPlayer != (Object)null) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "HeadElfPlus_CommandRaceChange", new object[1] { text2 }); output = "<color=green>Iniciando mudança de raça para " + text2 + "!</color>"; return true; } if ((Object)(object)ZNet.instance != (Object)null) { ZNetPeer val = ZNet.instance.GetPeers().Find((ZNetPeer p) => p.m_playerName.ToLower() == targetPlayerName.ToLower()); if (val != null) { ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "HeadElfPlus_CommandRaceChange", new object[1] { text2 }); output = "<color=green>Comando de raça enviado para " + val.m_playerName + "!</color>"; } else { output = "<color=red>Jogador '" + targetPlayerName + "' offline.</color>"; } } return true; } } [HarmonyPatch] internal static class KeyPatch { [CompilerGenerated] private sealed class <DoTransformationRitual>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Player player; public string race; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DoTransformationRitual>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; GameObject prefab2 = ZNetScene.instance.GetPrefab("fx_shaman_protect"); if ((Object)(object)prefab2 != (Object)null) { Object.Instantiate<GameObject>(prefab2, ((Component)player).transform.position, ((Component)player).transform.rotation); } MessageHud.instance.ShowMessage((MessageType)2, "<i><b><color=#00FFFF>Seu corpo se sente livre finalmente...</color></b></i>", 0, (Sprite)null, false); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; } case 1: { <>1__state = -1; GameObject prefab = ZNetScene.instance.GetPrefab("vfx_ghost_death"); if ((Object)(object)prefab != (Object)null) { Object.Instantiate<GameObject>(prefab, ((Component)player).transform.position, ((Component)player).transform.rotation); } RaceManager.RequestRaceChange(race); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static readonly FieldInfo f_uniques = AccessTools.Field(typeof(Player), "m_uniques"); internal static readonly Dictionary<string, string> KeyMapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "Limiar do elfo", "Elf" }, { "Limiar da Criança", "Child" }, { "Limiar do High-Elf", "High-Elf" }, { "Limiar do Meio-Orc", "Half-Orc" }, { "Limiar do Drow", "Drow" }, { "Limiar do Dwarf", "Dwarf" }, { "Limiar do Halfling", "Halfling" } }; [HarmonyPatch(typeof(Player), "AddUniqueKey")] [HarmonyPrefix] private static bool Prefix_AddUniqueKey(Player __instance, string name) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (!(f_uniques?.GetValue(__instance) is IEnumerable<string> enumerable)) { return true; } if (name.Equals("Limiar do Humano", StringComparison.OrdinalIgnoreCase)) { List<string> list = new List<string>(); foreach (string item in enumerable) { if (item.StartsWith("Limiar do", StringComparison.OrdinalIgnoreCase) || item.StartsWith("Limiar da", StringComparison.OrdinalIgnoreCase)) { list.Add(item); } } foreach (string item2 in list) { ((Humanoid)__instance).RemoveUniqueKey(item2); } RaceManager.RequestRaceChange("Human"); MessageHud.instance.ShowMessage((MessageType)2, "<i><b><color=#FFFFFF>Você retornou à sua essência Humana...</color></b></i>", 0, (Sprite)null, false); return false; } if (KeyMapping.TryGetValue(name, out var value)) { if (enumerable.Contains<string>(name, StringComparer.OrdinalIgnoreCase)) { return true; } List<string> list2 = new List<string>(); foreach (string item3 in enumerable) { if ((item3.StartsWith("Limiar do", StringComparison.OrdinalIgnoreCase) || item3.StartsWith("Limiar da", StringComparison.OrdinalIgnoreCase)) && !item3.Equals(name, StringComparison.OrdinalIgnoreCase)) { list2.Add(item3); } } foreach (string item4 in list2) { ((Humanoid)__instance).RemoveUniqueKey(item4); } ((MonoBehaviour)__instance).StartCoroutine(DoTransformationRitual(__instance, value)); return true; } return true; } [IteratorStateMachine(typeof(<DoTransformationRitual>d__3))] private static IEnumerator DoTransformationRitual(Player player, string race) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DoTransformationRitual>d__3(0) { player = player, race = race }; } [HarmonyPatch(typeof(Player), "RemoveUniqueKey")] [HarmonyPrefix] private static void Prefix_RemoveUniqueKey(Player __instance, string name) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (name.StartsWith("Limiar do", StringComparison.OrdinalIgnoreCase) || name.StartsWith("Limiar da", StringComparison.OrdinalIgnoreCase))) { RaceManager.RequestRaceChange("Human"); MessageHud.instance.ShowMessage((MessageType)2, "<i><b><color=#ff4444>O vínculo ancestral foi quebrado...</color></b></i>", 0, (Sprite)null, false); } } } public class BoneScaler : MonoBehaviour { private Transform spine; private Transform neck; private Transform head; private Transform leftLeg; private Transform rightLeg; private VisEquipment visEq; public string race = "human"; public Vector3 spineScale = Vector3.one; public Vector3 neckScale = Vector3.one; public Vector3 headScale = Vector3.one; public Vector3 legsScale = Vector3.one; private Transform FindBone(Transform root, string name) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (((Object)root).name == name) { return root; } foreach (Transform item in root) { Transform root2 = item; Transform val = FindBone(root2, name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void Start() { visEq = ((Component)this).GetComponent<VisEquipment>(); spine = FindBone(((Component)this).transform, "Spine"); neck = FindBone(((Component)this).transform, "Neck"); head = FindBone(((Component)this).transform, "Head"); leftLeg = FindBone(((Component)this).transform, "LeftUpLeg") ?? FindBone(((Component)this).transform, "LeftUpperLeg") ?? FindBone(((Component)this).transform, "LeftLeg"); rightLeg = FindBone(((Component)this).transform, "RightUpLeg") ?? FindBone(((Component)this).transform, "RightUpperLeg") ?? FindBone(((Component)this).transform, "RightLeg"); } private void LateUpdate() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spine != (Object)null) { spine.localScale = spineScale; } if ((Object)(object)neck != (Object)null) { neck.localScale = neckScale; } if ((Object)(object)head != (Object)null) { head.localScale = headScale; } if ((Object)(object)leftLeg != (Object)null) { leftLeg.localScale = legsScale; } if ((Object)(object)rightLeg != (Object)null) { rightLeg.localScale = legsScale; } if ((Object)(object)visEq != (Object)null && (Object)(object)visEq.m_helmet != (Object)null && ((Object)(object)head == (Object)null || (Object)(object)visEq.m_helmet.parent != (Object)(object)head)) { visEq.m_helmet.localScale = headScale; } } } [HarmonyPatch(typeof(VisEquipment), "UpdateVisuals")] internal static class RacePatch { private static readonly FieldInfo f_mVisual = AccessTools.Field(typeof(VisEquipment), "m_visual"); private static readonly FieldInfo f_modelIndex = AccessTools.Field(typeof(VisEquipment), "m_modelIndex"); [HarmonyPostfix] private static void Postfix_UpdateVisuals(VisEquipment __instance) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } string @string = component.GetZDO().GetString("PlayerRace", "Human"); try { ModConfig.RaceSettings settings = GetSettings(@string); if (settings != null) { ((Component)__instance).transform.localScale = ModConfig.ParseVector3(settings.Height, Vector3.one); object? obj = f_mVisual?.GetValue(__instance); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val != null) { val.transform.localPosition = new Vector3(0f, ModConfig.ParseFloat(settings.VisualOffset, 0f), 0f); } } else { ((Component)__instance).transform.localScale = Vector3.one; object? obj2 = f_mVisual?.GetValue(__instance); GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val2 != null) { val2.transform.localPosition = Vector3.zero; } } Color color; bool overrideSkin = ModConfig.TryParseHex(settings?.SkinColor, out color); ApplySkinColors(__instance, @string, overrideSkin, color); BoneScaler boneScaler = ((Component)__instance).GetComponent<BoneScaler>(); if ((Object)(object)boneScaler == (Object)null) { boneScaler = ((Component)__instance).gameObject.AddComponent<BoneScaler>(); } boneScaler.race = @string.ToLower(); boneScaler.spineScale = ModConfig.ParseVector3(settings?.BoneSpineScale, Vector3.one); boneScaler.neckScale = ModConfig.ParseVector3(settings?.BoneNeckScale, Vector3.one); boneScaler.headScale = ModConfig.ParseVector3(settings?.BoneHeadScale, Vector3.one); boneScaler.legsScale = ModConfig.ParseVector3(settings?.BoneLegsScale, Vector3.one); if ((Object)(object)ObjectDB.instance != (Object)null) { ApplyRaceItems(__instance, @string, settings); } } catch (Exception arg) { Plugin.MLogger.LogError((object)$"Erro no RacePatch: {arg}"); } } private static ModConfig.RaceSettings GetSettings(string race) { return race.ToLower() switch { "elf" => ModConfig.Elf, "high-elf" => ModConfig.HighElf, "half-orc" => ModConfig.HalfOrc, "drow" => ModConfig.Drow, "dwarf" => ModConfig.Dwarf, "halfling" => ModConfig.Halfling, "child" => ModConfig.Child, _ => null, }; } private static void ApplySkinColors(VisEquipment vis, string race, bool overrideSkin, Color skinColor) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) string text = race.ToLower(); bool flag = text == "elf" || text == "high-elf"; if (!overrideSkin && !flag) { return; } object? obj = AccessTools.Field(typeof(VisEquipment), "m_bodyModel")?.GetValue(vis); SkinnedMeshRenderer val = (SkinnedMeshRenderer)((obj is SkinnedMeshRenderer) ? obj : null); Renderer[] componentsInChildren = ((Component)vis).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).transform).name.StartsWith("RaceVisual_Hack")) { continue; } string text2 = ((Object)((Component)val2).gameObject).name.ToLower(); bool flag2 = text2.Contains("hair") || text2.Contains("beard") || text2.Contains("attachment"); Material[] materials = val2.materials; bool flag3 = false; for (int j = 0; j < materials.Length; j++) { Material val3 = materials[j]; if ((Object)(object)val3 == (Object)null) { continue; } if (flag2 || ((Object)(object)val2 == (Object)(object)val && j == 1)) { if (flag && val3.HasProperty("_SkinColor")) { val3.SetColor("_SkinColor", Color.white); flag3 = true; } } else if (overrideSkin && val3.HasProperty("_SkinColor")) { val3.SetColor("_SkinColor", skinColor); flag3 = true; } } if (flag3) { val2.materials = materials; } } } private static void ApplyRaceItems(VisEquipment vis, string race, ModConfig.RaceSettings s) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) Transform helmet = vis.m_helmet; if ((Object)(object)helmet == (Object)null) { return; } foreach (Transform item in helmet) { Transform val = item; if (((Object)val).name.StartsWith("RaceVisual_Hack") && ((Object)val).name != "RaceVisual_Hack_" + race) { Object.Destroy((Object)(object)((Component)val).gameObject); } } string text = race.ToLower(); switch (text) { case "dwarf": return; case "child": return; } if (s == null) { return; } Transform val2 = helmet.Find("RaceVisual_Hack_" + race); if ((Object)(object)val2 == (Object)null) { string text2 = "TrophyGoblin"; if (text == "half-orc") { text2 = "HelmetBerserkerUndead"; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text2); if ((Object)(object)itemPrefab != (Object)null) { Transform obj = itemPrefab.transform.Find("attach") ?? itemPrefab.transform.Find("Visual") ?? itemPrefab.transform; ZNetView.m_forceDisableInit = true; GameObject val3 = Object.Instantiate<GameObject>(((Component)obj).gameObject, helmet); ZNetView.m_forceDisableInit = false; ((Object)val3).name = "RaceVisual_Hack_" + race; Component[] componentsInChildren = val3.GetComponentsInChildren<Component>(); foreach (Component val4 in componentsInChildren) { if ((val4 is Collider || val4 is Rigidbody || val4 is ItemDrop || val4 is ZNetView) ? true : false) { Object.DestroyImmediate((Object)(object)val4); } } val2 = val3.transform; } } if (!((Object)(object)val2 != (Object)null)) { return; } bool flag = f_modelIndex != null && (int)f_modelIndex.GetValue(vis) == 1; Vector3 localPosition; Vector3 localEulerAngles; Vector3 localScale; if (text == "half-orc" && flag && !string.IsNullOrEmpty(s.ItemPosFem)) { localPosition = ModConfig.ParseVector3(s.ItemPosFem, Vector3.zero); localEulerAngles = ModConfig.ParseVector3(s.ItemRotFem, Vector3.zero); localScale = ModConfig.ParseVector3(s.ItemScaleFem, Vector3.one); } else { localPosition = ModConfig.ParseVector3(s.ItemPos, Vector3.zero); localEulerAngles = ModConfig.ParseVector3(s.ItemRot, Vector3.zero); localScale = ModConfig.ParseVector3(s.ItemScale, Vector3.one); } val2.localPosition = localPosition; val2.localEulerAngles = localEulerAngles; val2.localScale = localScale; if (!ModConfig.TryParseHex(s.ItemColor, out var color)) { return; } Renderer[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Renderer>(); for (int i = 0; i < componentsInChildren2.Length; i++) { Material[] materials = componentsInChildren2[i].materials; foreach (Material val5 in materials) { if ((Object)(object)val5 != (Object)null && val5.HasProperty("_Color")) { val5.SetColor("_Color", color); } } } } } [HarmonyPatch] internal static class ServerSyncPatch { private static bool isServerConfigForced; internal static bool IsClientLockedByServer() { if ((Object)(object)ZNet.instance != (Object)null && isServerConfigForced) { return !ZNet.instance.IsServer(); } return false; } [HarmonyPatch(typeof(ZNet), "Awake")] [HarmonyPostfix] private static void Postfix_ZNet_Awake(ZNet __instance) { ZRoutedRpc.instance.Register<string>("HeadElfPlus_SyncConfig", (Action<long, string>)RPC_ReceiveConfig); ZRoutedRpc.instance.Register<string, string>("HeadElfPlus_SyncRace", (Action<long, string, string>)RPC_ReceiveSyncRace); ZRoutedRpc.instance.Register<string>("HeadElfPlus_ForceUpdateVisuals", (Action<long, string>)RPC_ReceiveForceRace); ZRoutedRpc.instance.Register<string>("HeadElfPlus_RequestRaceChange", (Action<long, string>)RPC_RequestRaceChange); ZRoutedRpc.instance.Register<string>("HeadElfPlus_CommandRaceChange", (Action<long, string>)RPC_CommandRaceChange); isServerConfigForced = false; ModConfig.UpdateMemoryValuesFromLocal(); } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPostfix] private static void Postfix_RPC_PeerInfo(ZNet __instance, ZRpc rpc) { if (!__instance.IsServer()) { return; } ZNetPeer val = __instance.GetPeers().Find((ZNetPeer p) => p.m_rpc == rpc); if (val != null) { List<string> list = new List<string>(); ModConfig.RaceSettings[] array = new ModConfig.RaceSettings[7] { ModConfig.Elf, ModConfig.HalfOrc, ModConfig.Drow, ModConfig.Dwarf, ModConfig.Halfling, ModConfig.HighElf, ModConfig.Child }; foreach (ModConfig.RaceSettings raceSettings in array) { list.Add(raceSettings.SkinColor ?? ""); list.Add(raceSettings.Height ?? ""); list.Add(raceSettings.ItemColor ?? ""); list.Add(raceSettings.ItemPos ?? ""); list.Add(raceSettings.ItemRot ?? ""); list.Add(raceSettings.ItemScale ?? ""); list.Add(raceSettings.ItemPosFem ?? ""); list.Add(raceSettings.ItemRotFem ?? ""); list.Add(raceSettings.ItemScaleFem ?? ""); list.Add(raceSettings.VisualOffset ?? ""); list.Add(raceSettings.BoneSpineScale ?? ""); list.Add(raceSettings.BoneNeckScale ?? ""); list.Add(raceSettings.BoneHeadScale ?? ""); list.Add(raceSettings.BoneLegsScale ?? ""); } string text = string.Join("|", list); ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "HeadElfPlus_SyncConfig", new object[1] { text }); } } private static void RPC_ReceiveConfig(long sender, string packed) { if (ZNet.instance.IsServer()) { return; } string[] array = packed.Split('|'); if (array.Length >= 98) { int num = 0; ModConfig.RaceSettings[] array2 = new ModConfig.RaceSettings[7] { ModConfig.Elf, ModConfig.HalfOrc, ModConfig.Drow, ModConfig.Dwarf, ModConfig.Halfling, ModConfig.HighElf, ModConfig.Child }; foreach (ModConfig.RaceSettings obj in array2) { obj.SkinColor = array[num++]; obj.Height = array[num++]; obj.ItemColor = array[num++]; obj.ItemPos = array[num++]; obj.ItemRot = array[num++]; obj.ItemScale = array[num++]; obj.ItemPosFem = array[num++]; obj.ItemRotFem = array[num++]; obj.ItemScaleFem = array[num++]; obj.VisualOffset = array[num++]; obj.BoneSpineScale = array[num++]; obj.BoneNeckScale = array[num++]; obj.BoneHeadScale = array[num++]; obj.BoneLegsScale = array[num++]; } isServerConfigForced = true; ModConfig.UpdatePlayerVisuals(); } } private static void RPC_ReceiveSyncRace(long sender, string userId, string race) { foreach (Player allPlayer in Player.GetAllPlayers()) { ZNetView component = ((Component)allPlayer).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null && (component.GetZDO().GetOwner().ToString() == userId || ((Object)(object)allPlayer == (Object)(object)Player.m_localPlayer && ZNet.GetUID().ToString() == userId))) { component.GetZDO().Set("PlayerRace", race); if ((Object)(object)allPlayer == (Object)(object)Player.m_localPlayer) { allPlayer.m_customData["PlayerRace"] = race; } } } ModConfig.UpdatePlayerVisuals(); } private static void RPC_ReceiveForceRace(long sender, string rId) { if ((Object)(object)Player.m_localPlayer != (Object)null) { Player.m_localPlayer.m_customData["PlayerRace"] = rId; ZNetView component = ((Component)Player.m_localPlayer).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null) { component.GetZDO().Set("PlayerRace", rId); } } ModConfig.UpdatePlayerVisuals(); } private static void RPC_RequestRaceChange(long sender, string raceName) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer != null) { RaceManager.SetRace(peer.m_uid.ToString(), raceName, peer.m_playerName); } } } private static void RPC_CommandRaceChange(long sender, string race) { if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } List<string> list = new List<string>(); if (KeyPatch.f_uniques?.GetValue(Player.m_localPlayer) is IEnumerable<string> enumerable) { foreach (string item in enumerable) { if (item.StartsWith("Limiar do", StringComparison.OrdinalIgnoreCase) || item.StartsWith("Limiar da", StringComparison.OrdinalIgnoreCase)) { list.Add(item); } } } foreach (string item2 in list) { ((Humanoid)Player.m_localPlayer).RemoveUniqueKey(item2); } if (race.ToLower() == "human") { return; } string text = ""; foreach (KeyValuePair<string, string> item3 in KeyPatch.KeyMapping) { if (item3.Value.Equals(race, StringComparison.OrdinalIgnoreCase)) { text = item3.Key; break; } } if (!string.IsNullOrEmpty(text)) { ((Humanoid)Player.m_localPlayer).AddUniqueKey(text); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class PlayerSpawnPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } try { string text = "Human"; if (__instance.m_customData.TryGetValue("PlayerRace", out var value) && !string.IsNullOrEmpty(value) && value != "Human") { text = value; } else if (KeyPatch.f_uniques?.GetValue(__instance) is IEnumerable<string> enumerable) { foreach (string item in enumerable) { if (KeyPatch.KeyMapping.TryGetValue(item, out var value2)) { text = value2; __instance.m_customData["PlayerRace"] = text; break; } } } if (text != "Human") { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null) { component.GetZDO().Set("PlayerRace", text); } } ModConfig.UpdatePlayerVisuals(); } catch (Exception arg) { Plugin.MLogger.LogError((object)$"Erro no PlayerSpawnPatch: {arg}"); } } } } namespace HeadElfPlus.src.Config { internal static class ModConfig { internal class RaceSettings { public string SkinColor = "#FFFFFF"; public string ItemColor = "#FFFFFF"; public string ItemPos = "0,0,0"; public string ItemRot = "0,0,0"; public string ItemScale = "1,1,1"; public string ItemPosFem = ""; public string ItemRotFem = ""; public string ItemScaleFem = ""; public string Height = "1,1,1"; public string VisualOffset = "0"; public string BoneSpineScale = "1,1,1"; public string BoneNeckScale = "1,1,1"; public string BoneHeadScale = "1,1,1"; public string BoneLegsScale = "1,1,1"; } internal static ConfigEntry<string> ElfSkin; internal static ConfigEntry<string> ElfHeight; internal static ConfigEntry<string> ElfItemColor; internal static ConfigEntry<string> ElfItemPos; internal static ConfigEntry<string> ElfItemRot; internal static ConfigEntry<string> ElfItemScale; internal static ConfigEntry<string> OrcSkin; internal static ConfigEntry<string> OrcHeight; internal static ConfigEntry<string> OrcItemColor; internal static ConfigEntry<string> OrcItemPos; internal static ConfigEntry<string> OrcItemRot; internal static ConfigEntry<string> OrcItemScale; internal static ConfigEntry<string> OrcItemPosFem; internal static ConfigEntry<string> OrcItemRotFem; internal static ConfigEntry<string> OrcItemScaleFem; internal static ConfigEntry<string> OrcBoneSpineScale; internal static ConfigEntry<string> OrcBoneNeckScale; internal static ConfigEntry<string> OrcBoneHeadScale; internal static ConfigEntry<string> OrcBoneLegsScale; internal static ConfigEntry<string> DrowSkin; internal static ConfigEntry<string> DrowHeight; internal static ConfigEntry<string> DrowItemColor; internal static ConfigEntry<string> DrowItemPos; internal static ConfigEntry<string> DrowItemRot; internal static ConfigEntry<string> DrowItemScale; internal static ConfigEntry<string> DwarfSkin; internal static ConfigEntry<string> DwarfHeight; internal static ConfigEntry<string> DwarfVisualOffset; internal static ConfigEntry<string> DwarfBoneSpineScale; internal static ConfigEntry<string> DwarfBoneNeckScale; internal static ConfigEntry<string> DwarfBoneHeadScale; internal static ConfigEntry<string> DwarfBoneLegsScale; internal static ConfigEntry<string> HalflingSkin; internal static ConfigEntry<string> HalflingHeight; internal static ConfigEntry<string> HalflingItemColor; internal static ConfigEntry<string> HalflingItemPos; internal static ConfigEntry<string> HalflingItemRot; internal static ConfigEntry<string> HalflingItemScale; internal static ConfigEntry<string> HighElfSkin; internal static ConfigEntry<string> HighElfHeight; internal static ConfigEntry<string> HighElfItemColor; internal static ConfigEntry<string> HighElfItemPos; internal static ConfigEntry<string> HighElfItemRot; internal static ConfigEntry<string> HighElfItemScale; internal static ConfigEntry<string> ChildHeight; internal static RaceSettings Elf = new RaceSettings(); internal static RaceSettings HalfOrc = new RaceSettings(); internal static RaceSettings Drow = new RaceSettings(); internal static RaceSettings Dwarf = new RaceSettings(); internal static RaceSettings Halfling = new RaceSettings(); internal static RaceSettings HighElf = new RaceSettings(); internal static RaceSettings Child = new RaceSettings(); internal static void Init() { ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config; ElfSkin = config.Bind<string>("1. Elf", "SkinColor", "#8080CC", ""); ElfItemColor = config.Bind<string>("1. Elf", "ItemColor", "#7e4df192", ""); ElfItemPos = config.Bind<string>("1. Elf", "ItemPosition", "0, -0.02, -0.04", ""); ElfItemRot = config.Bind<string>("1. Elf", "ItemRotation", "10, 0, 0", ""); ElfItemScale = config.Bind<string>("1. Elf", "ItemScale", "0.55, 0.55, 0.55", ""); ElfHeight = config.Bind<string>("1. Elf", "HeightScale", "0.95, 1, 0.95", ""); OrcSkin = config.Bind<string>("2. Half-Orc", "SkinColor", "#6B8E23", ""); OrcItemColor = config.Bind<string>("2. Half-Orc", "ItemColor", "vanilla", ""); OrcItemPos = config.Bind<string>("2. Half-Orc", "ItemPosition_Male", "0, 0.02, 0.045", ""); OrcItemRot = config.Bind<string>("2. Half-Orc", "ItemRotation_Male", "24, 0, 0", ""); OrcItemScale = config.Bind<string>("2. Half-Orc", "ItemScale_Male", "0.7, 0.7, 0.75", ""); OrcItemPosFem = config.Bind<string>("2. Half-Orc", "ItemPosition_Female", "0, 0.015, 0.05", ""); OrcItemRotFem = config.Bind<string>("2. Half-Orc", "ItemRotation_Female", "25, 0, 0", ""); OrcItemScaleFem = config.Bind<string>("2. Half-Orc", "ItemScale_Female", "0.6, 0.65, 0.6", ""); OrcHeight = config.Bind<string>("2. Half-Orc", "HeightScale", "1, 1, 1", ""); OrcBoneSpineScale = config.Bind<string>("2. Half-Orc", "BoneSpineScale", "1.3, 1, 1.3", "Escala do osso Spine (Peito e Ombros)"); OrcBoneNeckScale = config.Bind<string>("2. Half-Orc", "BoneNeckScale", "0.83, 1, 0.83", "Escala do osso Neck (Pescoço e Cabeça)"); OrcBoneHeadScale = config.Bind<string>("2. Half-Orc", "BoneHeadScale", "1, 1, 1", "Escala do osso Head (Cabeça)"); OrcBoneLegsScale = config.Bind<string>("2. Half-Orc", "BoneLegsScale", "1.15, 1, 1.15", "Escala dos ossos da Perna"); DrowSkin = config.Bind<string>("4. Drow", "SkinColor", "#312626", ""); DrowItemColor = config.Bind<string>("4. Drow", "ItemColor", "#312626", ""); DrowItemPos = config.Bind<string>("4. Drow", "ItemPosition", "0, -0.02, -0.04", ""); DrowItemRot = config.Bind<string>("4. Drow", "ItemRotation", "10, 0, 0", ""); DrowItemScale = config.Bind<string>("4. Drow", "ItemScale", "0.6, 0.55, 0.6", ""); DrowHeight = config.Bind<string>("4. Drow", "HeightScale", "0.95, 1, 0.95", ""); DwarfSkin = config.Bind<string>("5. Dwarf", "SkinColor", "vanilla", ""); DwarfHeight = config.Bind<string>("5. Dwarf", "HeightScale", "0.85, 0.85, 0.85", ""); DwarfVisualOffset = config.Bind<string>("5. Dwarf", "VisualOffset", "0", ""); DwarfBoneSpineScale = config.Bind<string>("5. Dwarf", "BoneSpineScale", "1.4, 1, 1.4", "Escala do osso Spine (Peito e Ombros)"); DwarfBoneNeckScale = config.Bind<string>("5. Dwarf", "BoneNeckScale", "0.85, 0.85, 0.85", "Escala do osso Neck (Pescoço e Cabeça). Use o inverso do Spine para anular estiramento da cabeça."); DwarfBoneHeadScale = config.Bind<string>("5. Dwarf", "BoneHeadScale", "1.1, 1.1, 1.1", "Escala do osso Head (Cabeça)"); DwarfBoneLegsScale = config.Bind<string>("5. Dwarf", "BoneLegsScale", "1.2, 1, 1.2", "Escala dos ossos da Perna"); HalflingSkin = config.Bind<string>("6. Halfling", "SkinColor", "#eedf9c", ""); HalflingItemColor = config.Bind<string>("6. Halfling", "ItemColor", "#bb9903", ""); HalflingItemPos = config.Bind<string>("6. Halfling", "ItemPosition", "0, 0, -0.02", ""); HalflingItemRot = config.Bind<string>("6. Halfling", "ItemRotation", "-35, 0, 0", ""); HalflingItemScale = config.Bind<string>("6. Halfling", "ItemScale", "0.7, 0.6, 0.4", ""); HalflingHeight = config.Bind<string>("6. Halfling", "HeightScale", "0.8, 0.8, 0.8", ""); HighElfSkin = config.Bind<string>("7. High-Elf", "SkinColor", "#f7f6f6", ""); HighElfItemColor = config.Bind<string>("7. High-Elf", "ItemColor", "#ffc5e9", ""); HighElfItemPos = config.Bind<string>("7. High-Elf", "ItemPosition", "0, -0.02, -0.04", ""); HighElfItemRot = config.Bind<string>("7. High-Elf", "ItemRotation", "10, 0, 0", ""); HighElfItemScale = config.Bind<string>("7. High-Elf", "ItemScale", "0.55, 0.55, 0.55", ""); HighElfHeight = config.Bind<string>("7. High-Elf", "HeightScale", "0.95, 1, 0.95", ""); ChildHeight = config.Bind<string>("8. Child", "HeightScale", "0.75, 0.75, 0.75", ""); UpdateMemoryValuesFromLocal(); ((BaseUnityPlugin)Plugin.Instance).Config.ConfigReloaded += delegate { UpdateMemoryValuesFromLocal(); UpdatePlayerVisuals(); }; SetupWatcher(); } private static void SetupWatcher() { string configFilePath = ((BaseUnityPlugin)Plugin.Instance).Config.ConfigFilePath; FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath)); fileSystemWatcher.Changed += delegate { if (!ServerSyncPatch.IsClientLockedByServer()) { ((BaseUnityPlugin)Plugin.Instance).Config.Reload(); } }; fileSystemWatcher.EnableRaisingEvents = true; } internal static void UpdateMemoryValuesFromLocal() { if (!ServerSyncPatch.IsClientLockedByServer()) { Elf.SkinColor = ElfSkin.Value; Elf.Height = ElfHeight.Value; Elf.ItemColor = ElfItemColor.Value; Elf.ItemPos = ElfItemPos.Value; Elf.ItemRot = ElfItemRot.Value; Elf.ItemScale = ElfItemScale.Value; HalfOrc.SkinColor = OrcSkin.Value; HalfOrc.Height = OrcHeight.Value; HalfOrc.ItemColor = OrcItemColor.Value; HalfOrc.ItemPos = OrcItemPos.Value; HalfOrc.ItemRot = OrcItemRot.Value; HalfOrc.ItemScale = OrcItemScale.Value; HalfOrc.ItemPosFem = OrcItemPosFem.Value; HalfOrc.ItemRotFem = OrcItemRotFem.Value; HalfOrc.ItemScaleFem = OrcItemScaleFem.Value; HalfOrc.BoneSpineScale = OrcBoneSpineScale.Value; HalfOrc.BoneNeckScale = OrcBoneNeckScale.Value; HalfOrc.BoneHeadScale = OrcBoneHeadScale.Value; HalfOrc.BoneLegsScale = OrcBoneLegsScale.Value; Drow.SkinColor = DrowSkin.Value; Drow.Height = DrowHeight.Value; Drow.ItemColor = DrowItemColor.Value; Drow.ItemPos = DrowItemPos.Value; Drow.ItemRot = DrowItemRot.Value; Drow.ItemScale = DrowItemScale.Value; Dwarf.SkinColor = DwarfSkin.Value; Dwarf.Height = DwarfHeight.Value; Dwarf.VisualOffset = DwarfVisualOffset.Value; Dwarf.BoneSpineScale = DwarfBoneSpineScale.Value; Dwarf.BoneNeckScale = DwarfBoneNeckScale.Value; Dwarf.BoneHeadScale = DwarfBoneHeadScale.Value; Dwarf.BoneLegsScale = DwarfBoneLegsScale.Value; Halfling.SkinColor = HalflingSkin.Value; Halfling.Height = HalflingHeight.Value; Halfling.ItemColor = HalflingItemColor.Value; Halfling.ItemPos = HalflingItemPos.Value; Halfling.ItemRot = HalflingItemRot.Value; Halfling.ItemScale = HalflingItemScale.Value; HighElf.SkinColor = HighElfSkin.Value; HighElf.Height = HighElfHeight.Value; HighElf.ItemColor = HighElfItemColor.Value; HighElf.ItemPos = HighElfItemPos.Value; HighElf.ItemRot = HighElfItemRot.Value; HighElf.ItemScale = HighElfItemScale.Value; Child.Height = ChildHeight.Value; } } internal static void UpdatePlayerVisuals() { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { object? obj = AccessTools.Field(typeof(Humanoid), "m_visEquipment")?.GetValue(Player.m_localPlayer); VisEquipment val = (VisEquipment)((obj is VisEquipment) ? obj : null); if (val != null) { AccessTools.Method(typeof(VisEquipment), "UpdateVisuals", (Type[])null, (Type[])null)?.Invoke(val, null); } } } internal static bool TryParseHex(string hex, out Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) color = Color.white; if (string.IsNullOrWhiteSpace(hex) || hex.Trim().ToLower() == "vanilla") { return false; } if (!hex.StartsWith("#")) { hex = "#" + hex; } return ColorUtility.TryParseHtmlString(hex, ref color); } internal static Vector3 ParseVector3(string val, Vector3 def) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(val)) { return def; } string[] array = val.Split(','); if (array.Length != 3) { return def; } float result; float num = (float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out result) ? result : def.x); float result2; float num2 = (float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result2) ? result2 : def.y); float result3; float num3 = (float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out result3) ? result3 : def.z); return new Vector3(num, num2, num3); } internal static float ParseFloat(string val, float def) { if (string.IsNullOrWhiteSpace(val)) { return def; } if (!float.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return def; } return result; } } internal static class RaceManager { public static void SetRace(string userId, string race, string playerName) { if (!((Object)(object)ZNet.instance == (Object)null)) { if (ZNet.instance.IsServer()) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "HeadElfPlus_SyncRace", new object[2] { userId, race }); } else { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "HeadElfPlus_RequestRaceChange", new object[1] { race }); } } } public static void RequestRaceChange(string raceName) { if (!((Object)(object)ZNet.instance == (Object)null)) { if (ZNet.instance.IsServer()) { string userId = ZNet.GetUID().ToString(); Player localPlayer = Player.m_localPlayer; SetRace(userId, raceName, ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "Server"); } else { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "HeadElfPlus_RequestRaceChange", new object[1] { raceName }); } } } } }