using 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 <>9__1_2; public static ConsoleOptionsFetcher <>9__1_1; internal void b__1_0(ConsoleEventArgs args) { if (ProcessRaceCommand(args.FullLine, out var output)) { args.Context.AddString(output); } } internal List b__1_1() { List list = new List(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 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 list = new List(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 = "[HeadElfPlus] Erro: Ative 'devcommands' e 'debugmode' primeiro."; return true; } string[] array = text.TrimStart('/').Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length < 2) { output = "Uso: race [NomeJogador]"; 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 = "Raça '" + targetRace + "' inválida."; 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 = "Iniciando mudança de raça para " + text2 + "!"; 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 = "Comando de raça enviado para " + val.m_playerName + "!"; } else { output = "Jogador '" + targetPlayerName + "' offline."; } } return true; } } [HarmonyPatch] internal static class KeyPatch { [CompilerGenerated] private sealed class d__3 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Player player; public string race; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(prefab2, ((Component)player).transform.position, ((Component)player).transform.rotation); } MessageHud.instance.ShowMessage((MessageType)2, "Seu corpo se sente livre finalmente...", 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(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 KeyMapping = new Dictionary(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 enumerable)) { return true; } if (name.Equals("Limiar do Humano", StringComparison.OrdinalIgnoreCase)) { List list = new List(); 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, "Você retornou à sua essência Humana...", 0, (Sprite)null, false); return false; } if (KeyMapping.TryGetValue(name, out var value)) { if (enumerable.Contains(name, StringComparer.OrdinalIgnoreCase)) { return true; } List list2 = new List(); 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(d__3))] private static IEnumerator DoTransformationRitual(Player player, string race) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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, "O vínculo ancestral foi quebrado...", 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(); 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(); 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(); if ((Object)(object)boneScaler == (Object)null) { boneScaler = ((Component)__instance).gameObject.AddComponent(); } 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(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(((Component)obj).gameObject, helmet); ZNetView.m_forceDisableInit = false; ((Object)val3).name = "RaceVisual_Hack_" + race; Component[] componentsInChildren = val3.GetComponentsInChildren(); 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(); 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("HeadElfPlus_SyncConfig", (Action)RPC_ReceiveConfig); ZRoutedRpc.instance.Register("HeadElfPlus_SyncRace", (Action)RPC_ReceiveSyncRace); ZRoutedRpc.instance.Register("HeadElfPlus_ForceUpdateVisuals", (Action)RPC_ReceiveForceRace); ZRoutedRpc.instance.Register("HeadElfPlus_RequestRaceChange", (Action)RPC_RequestRaceChange); ZRoutedRpc.instance.Register("HeadElfPlus_CommandRaceChange", (Action)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 list = new List(); 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(); 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(); 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 list = new List(); if (KeyPatch.f_uniques?.GetValue(Player.m_localPlayer) is IEnumerable 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 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 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(); 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 ElfSkin; internal static ConfigEntry ElfHeight; internal static ConfigEntry ElfItemColor; internal static ConfigEntry ElfItemPos; internal static ConfigEntry ElfItemRot; internal static ConfigEntry ElfItemScale; internal static ConfigEntry OrcSkin; internal static ConfigEntry OrcHeight; internal static ConfigEntry OrcItemColor; internal static ConfigEntry OrcItemPos; internal static ConfigEntry OrcItemRot; internal static ConfigEntry OrcItemScale; internal static ConfigEntry OrcItemPosFem; internal static ConfigEntry OrcItemRotFem; internal static ConfigEntry OrcItemScaleFem; internal static ConfigEntry OrcBoneSpineScale; internal static ConfigEntry OrcBoneNeckScale; internal static ConfigEntry OrcBoneHeadScale; internal static ConfigEntry OrcBoneLegsScale; internal static ConfigEntry DrowSkin; internal static ConfigEntry DrowHeight; internal static ConfigEntry DrowItemColor; internal static ConfigEntry DrowItemPos; internal static ConfigEntry DrowItemRot; internal static ConfigEntry DrowItemScale; internal static ConfigEntry DwarfSkin; internal static ConfigEntry DwarfHeight; internal static ConfigEntry DwarfVisualOffset; internal static ConfigEntry DwarfBoneSpineScale; internal static ConfigEntry DwarfBoneNeckScale; internal static ConfigEntry DwarfBoneHeadScale; internal static ConfigEntry DwarfBoneLegsScale; internal static ConfigEntry HalflingSkin; internal static ConfigEntry HalflingHeight; internal static ConfigEntry HalflingItemColor; internal static ConfigEntry HalflingItemPos; internal static ConfigEntry HalflingItemRot; internal static ConfigEntry HalflingItemScale; internal static ConfigEntry HighElfSkin; internal static ConfigEntry HighElfHeight; internal static ConfigEntry HighElfItemColor; internal static ConfigEntry HighElfItemPos; internal static ConfigEntry HighElfItemRot; internal static ConfigEntry HighElfItemScale; internal static ConfigEntry 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("1. Elf", "SkinColor", "#8080CC", ""); ElfItemColor = config.Bind("1. Elf", "ItemColor", "#7e4df192", ""); ElfItemPos = config.Bind("1. Elf", "ItemPosition", "0, -0.02, -0.04", ""); ElfItemRot = config.Bind("1. Elf", "ItemRotation", "10, 0, 0", ""); ElfItemScale = config.Bind("1. Elf", "ItemScale", "0.55, 0.55, 0.55", ""); ElfHeight = config.Bind("1. Elf", "HeightScale", "0.95, 1, 0.95", ""); OrcSkin = config.Bind("2. Half-Orc", "SkinColor", "#6B8E23", ""); OrcItemColor = config.Bind("2. Half-Orc", "ItemColor", "vanilla", ""); OrcItemPos = config.Bind("2. Half-Orc", "ItemPosition_Male", "0, 0.02, 0.045", ""); OrcItemRot = config.Bind("2. Half-Orc", "ItemRotation_Male", "24, 0, 0", ""); OrcItemScale = config.Bind("2. Half-Orc", "ItemScale_Male", "0.7, 0.7, 0.75", ""); OrcItemPosFem = config.Bind("2. Half-Orc", "ItemPosition_Female", "0, 0.015, 0.05", ""); OrcItemRotFem = config.Bind("2. Half-Orc", "ItemRotation_Female", "25, 0, 0", ""); OrcItemScaleFem = config.Bind("2. Half-Orc", "ItemScale_Female", "0.6, 0.65, 0.6", ""); OrcHeight = config.Bind("2. Half-Orc", "HeightScale", "1, 1, 1", ""); OrcBoneSpineScale = config.Bind("2. Half-Orc", "BoneSpineScale", "1.3, 1, 1.3", "Escala do osso Spine (Peito e Ombros)"); OrcBoneNeckScale = config.Bind("2. Half-Orc", "BoneNeckScale", "0.83, 1, 0.83", "Escala do osso Neck (Pescoço e Cabeça)"); OrcBoneHeadScale = config.Bind("2. Half-Orc", "BoneHeadScale", "1, 1, 1", "Escala do osso Head (Cabeça)"); OrcBoneLegsScale = config.Bind("2. Half-Orc", "BoneLegsScale", "1.15, 1, 1.15", "Escala dos ossos da Perna"); DrowSkin = config.Bind("4. Drow", "SkinColor", "#312626", ""); DrowItemColor = config.Bind("4. Drow", "ItemColor", "#312626", ""); DrowItemPos = config.Bind("4. Drow", "ItemPosition", "0, -0.02, -0.04", ""); DrowItemRot = config.Bind("4. Drow", "ItemRotation", "10, 0, 0", ""); DrowItemScale = config.Bind("4. Drow", "ItemScale", "0.6, 0.55, 0.6", ""); DrowHeight = config.Bind("4. Drow", "HeightScale", "0.95, 1, 0.95", ""); DwarfSkin = config.Bind("5. Dwarf", "SkinColor", "vanilla", ""); DwarfHeight = config.Bind("5. Dwarf", "HeightScale", "0.85, 0.85, 0.85", ""); DwarfVisualOffset = config.Bind("5. Dwarf", "VisualOffset", "0", ""); DwarfBoneSpineScale = config.Bind("5. Dwarf", "BoneSpineScale", "1.4, 1, 1.4", "Escala do osso Spine (Peito e Ombros)"); DwarfBoneNeckScale = config.Bind("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("5. Dwarf", "BoneHeadScale", "1.1, 1.1, 1.1", "Escala do osso Head (Cabeça)"); DwarfBoneLegsScale = config.Bind("5. Dwarf", "BoneLegsScale", "1.2, 1, 1.2", "Escala dos ossos da Perna"); HalflingSkin = config.Bind("6. Halfling", "SkinColor", "#eedf9c", ""); HalflingItemColor = config.Bind("6. Halfling", "ItemColor", "#bb9903", ""); HalflingItemPos = config.Bind("6. Halfling", "ItemPosition", "0, 0, -0.02", ""); HalflingItemRot = config.Bind("6. Halfling", "ItemRotation", "-35, 0, 0", ""); HalflingItemScale = config.Bind("6. Halfling", "ItemScale", "0.7, 0.6, 0.4", ""); HalflingHeight = config.Bind("6. Halfling", "HeightScale", "0.8, 0.8, 0.8", ""); HighElfSkin = config.Bind("7. High-Elf", "SkinColor", "#f7f6f6", ""); HighElfItemColor = config.Bind("7. High-Elf", "ItemColor", "#ffc5e9", ""); HighElfItemPos = config.Bind("7. High-Elf", "ItemPosition", "0, -0.02, -0.04", ""); HighElfItemRot = config.Bind("7. High-Elf", "ItemRotation", "10, 0, 0", ""); HighElfItemScale = config.Bind("7. High-Elf", "ItemScale", "0.55, 0.55, 0.55", ""); HighElfHeight = config.Bind("7. High-Elf", "HeightScale", "0.95, 1, 0.95", ""); ChildHeight = config.Bind("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 }); } } } } }