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 Vanity v1.19.0
Vanity.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using Service; using Splatform; using TMPro; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Vanity")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c5e6e2433be6a7db0a404b26b1a7110b95d072dc")] [assembly: AssemblyProduct("Vanity")] [assembly: AssemblyTitle("Vanity")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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.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] [Microsoft.CodeAnalysis.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] [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 Service { public class Watcher { private static readonly Dictionary<string, byte[]> hashes = new Dictionary<string, byte[]>(); private static byte[] GetHash(string path) { using MD5 mD = MD5.Create(); using FileStream inputStream = File.OpenRead(path); return mD.ComputeHash(inputStream); } public static void Setup(string folder, string pattern, Action action) { Action action2 = action; FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(folder, pattern); fileSystemWatcher.Changed += delegate(object s, FileSystemEventArgs e) { byte[] hash = GetHash(e.FullPath); if (!hashes.ContainsKey(e.FullPath) || !hashes[e.FullPath].SequenceEqual(hash)) { hashes[e.FullPath] = hash; action2(); } }; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } public static void Setup(string file, Action action) { string fileName = Path.GetFileName(file); Setup(Paths.ConfigPath, fileName, action); } public static void Setup(ConfigFile config, ManualLogSource logger) { ConfigFile config2 = config; ManualLogSource logger2 = logger; string configFilePath = config2.ConfigFilePath; string directoryName = Path.GetDirectoryName(configFilePath); string fileName = Path.GetFileName(configFilePath); Setup(directoryName, fileName, delegate { if (!File.Exists(config2.ConfigFilePath)) { return; } try { logger2.LogDebug((object)"ReadConfigValues called"); config2.Reload(); } catch { logger2.LogError((object)("There was an issue loading your " + config2.ConfigFilePath)); logger2.LogError((object)"Please check your config entries for spelling and format!"); } }); } } } namespace Vanity { [HarmonyPatch(typeof(Player), "LateUpdate")] public class ColorCycle { private const float TickLength = 0.02f; private static int Ticks; private static int SecondsToTicks(float value) { return (int)(value / 0.02f); } private static Color GetColor(Color[] colors) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (colors.Length < 2) { return colors[0]; } int num = SecondsToTicks(VanityManager.ColorDuration); if (num == 0) { return colors[0]; } float num2 = (float)(Ticks % (num * colors.Length)) / (float)num; int num3 = (int)Math.Floor(num2); Color val = colors[num3]; int num4 = (int)Math.Ceiling(num2); if (num4 >= colors.Length) { num4 = 0; } Color val2 = colors[num4]; float num5 = num2 - (float)Math.Truncate(num2); return Color.Lerp(val, val2, num5); } private static void UpdateSkinColor(Player obj) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Color color = GetColor(VanityManager.GetSkinColors(obj)); VanityManager.SkinColor = color; ((Humanoid)obj).m_visEquipment.SetSkinColor(Vector3.zero); } private static void UpdateHairColor(Player obj) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Color color = GetColor(VanityManager.GetHairColors(obj)); VanityManager.HairColor = color; ((Humanoid)obj).m_visEquipment.SetHairColor(Vector3.zero); } private static void Postfix(Player __instance) { if (Helper.IsLocalPlayer(__instance)) { Ticks++; int num = SecondsToTicks(VanityManager.ColorUpdateInterval); if (Ticks % num == 0) { UpdateSkinColor(__instance); UpdateHairColor(__instance); } } } } public class ChangeEquipment : MonoBehaviour { [CompilerGenerated] private static class <>O { public static ConsoleEvent <0>__SetIntervalValue; public static ConsoleEvent <1>__SetDurationValue; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<string, bool> <>9__6_0; public static Func<string, bool> <>9__7_0; public static Func<string, bool> <>9__7_1; public static Func<int, List<string>> <>9__13_0; public static Func<int, List<string>> <>9__13_1; public static Func<int, List<string>> <>9__14_1; public static Func<int, List<string>> <>9__15_0; public static Func<int, List<string>> <>9__15_1; public static ConsoleOptionsFetcher <>9__16_1; public static ConsoleEvent <>9__17_0; public static ConsoleEvent <>9__17_1; public static ConsoleEvent <>9__17_2; public static ConsoleEvent <>9__17_3; public static ConsoleEvent <>9__17_4; public static ConsoleOptionsFetcher <>9__17_5; public static ConsoleEvent <>9__17_6; public static ConsoleOptionsFetcher <>9__17_7; public static ConsoleEvent <>9__17_8; public static ConsoleOptionsFetcher <>9__17_9; public static ConsoleEvent <>9__17_10; public static ConsoleOptionsFetcher <>9__17_11; public static ConsoleEvent <>9__17_12; public static ConsoleOptionsFetcher <>9__17_13; internal bool <AddPlayerId>b__6_0(string s) { return s.StartsWith("player=", StringComparison.OrdinalIgnoreCase); } internal bool <Parse>b__7_0(string s) { return s.StartsWith("player=", StringComparison.OrdinalIgnoreCase); } internal bool <Parse>b__7_1(string s) { return !s.StartsWith("player=", StringComparison.OrdinalIgnoreCase); } internal List<string> <RegisterGearAutoComplete>b__13_0(int index) { return index switch { 0 => ObjectData.Items, 1 => ObjectData.Items, 2 => CommandWrapper.Info("Item variant (number)."), _ => new List<string>(1) { "player" }, }; } internal List<string> <RegisterGearAutoComplete>b__13_1(int index) { if (index != 0) { return null; } return Helper.Players(); } internal List<string> <RegisterAutoComplete>b__14_1(int index) { if (index != 0) { return null; } return Helper.Players(); } internal List<string> <RegisterColorAutoComplete>b__15_0(int index) { return CommandWrapper.Info("Color (r,g,b)"); } internal List<string> <RegisterColorAutoComplete>b__15_1(int index) { if (index != 0) { return null; } return Helper.Players(); } internal List<string> <CreateCommand>b__16_1() { return ObjectData.Items; } internal void <AddChangeEquipment>b__17_0(ConsoleEventArgs args) { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { VisEquipment component = ((Component)Player.m_localPlayer).GetComponent<VisEquipment>(); if (!((Object)(object)component == (Object)null)) { args.Context.AddString("Helmet: " + component.m_helmetItem); args.Context.AddString("Shoulder: " + component.m_shoulderItem); args.Context.AddString("Chest: " + component.m_chestItem); args.Context.AddString("Leg: " + component.m_legItem); args.Context.AddString("Utility: " + component.m_utilityItem); args.Context.AddString("Left hand: " + component.m_leftItem); args.Context.AddString("Right hand: " + component.m_rightItem); args.Context.AddString("Left back: " + component.m_leftBackItem); args.Context.AddString("Right back: " + component.m_rightBackItem); args.Context.AddString("Hair: " + component.m_hairItem); args.Context.AddString("Beard: " + component.m_beardItem); args.Context.AddString("Skin: " + ((Vector3)(ref component.m_skinColor)).ToString("F2")); args.Context.AddString("Hair color: " + ((Vector3)(ref component.m_hairColor)).ToString("F2")); } } } internal void <AddChangeEquipment>b__17_1(ConsoleEventArgs args) { string[] args2 = AddPlayerId(args); if (Vanity.ConfigSync.IsSourceOfTruth) { Parse(args2, out string id); VanityEntry entry = GetEntry(id); Set(entry, (VisSlot)2, ""); Set(entry, (VisSlot)3, ""); Set(entry, (VisSlot)9, ""); Set(entry, (VisSlot)4, ""); Set(entry, (VisSlot)10, ""); Set(entry, (VisSlot)0, ""); Set(entry, (VisSlot)1, ""); Set(entry, (VisSlot)6, ""); Set(entry, (VisSlot)6, ""); Set(entry, (VisSlot)5, ""); Set(entry, (VisSlot)7, ""); Set(entry, (VisSlot)8, ""); Set(entry, (VisSlot)8, ""); SetColor(entry, (VisSlot)10, ""); SetColor(entry, (VisSlot)5, ""); VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } internal void <AddChangeEquipment>b__17_2(ConsoleEventArgs args) { SetColorValue((VisSlot)5, args); } internal void <AddChangeEquipment>b__17_3(ConsoleEventArgs args) { SetColorValue((VisSlot)10, args); } internal void <AddChangeEquipment>b__17_4(ConsoleEventArgs args) { SetVisualValue((VisSlot)9, args); } internal List<string> <AddChangeEquipment>b__17_5() { return ObjectData.Beards; } internal void <AddChangeEquipment>b__17_6(ConsoleEventArgs args) { SetVisualValue((VisSlot)10, args); } internal List<string> <AddChangeEquipment>b__17_7() { return ObjectData.Hairs; } internal void <AddChangeEquipment>b__17_8(ConsoleEventArgs args) { string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); if (array.Length < 2) { return; } VanityEntry entry = GetEntry(id); if (entry.gear.TryGetValue(array[1], out string value)) { UndoCommands.Push(array[0] + " " + array[1] + " " + value); } else { UndoCommands.Push(array[0] + " " + array[1]); } if (Vanity.ConfigSync.IsSourceOfTruth) { if (array.Length == 2) { entry.gear.Remove(array[1]); } else { entry.gear[args[1]] = string.Join(" ", array.Skip(2)); } VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } internal List<string> <AddChangeEquipment>b__17_9() { return ObjectData.Items; } internal void <AddChangeEquipment>b__17_10(ConsoleEventArgs args) { string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); VanityEntry entry = GetEntry(id); if (entry.crafted.TryGetValue(array[1], out string value)) { UndoCommands.Push(array[0] + " " + array[1] + " " + value); } else { UndoCommands.Push(array[0] + " " + array[1]); } if (Vanity.ConfigSync.IsSourceOfTruth) { entry.crafted[array[1]] = string.Join(" ", array.Skip(2)); VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } internal List<string> <AddChangeEquipment>b__17_11() { return ObjectData.Items; } internal void <AddChangeEquipment>b__17_12(ConsoleEventArgs args) { if (UndoCommands.Count == 0) { args.Context.AddString("Nothing to undo."); return; } string text = UndoCommands.Pop(); args.Context.TryRunCommand(text, false, false); if (UndoCommands.Count > 0) { UndoCommands.Pop(); } } internal List<string> <AddChangeEquipment>b__17_13() { return ObjectData.Items; } } private static readonly Stack<string> UndoCommands = new Stack<string>(); private static string Get(VanityEntry entry, VisSlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown return (int)slot switch { 2 => entry.leftBack, 3 => entry.rightBack, 9 => entry.beard, 4 => entry.chest, 10 => entry.hair, 0 => entry.leftHand, 1 => entry.rightHand, 6 => entry.helmet, 5 => entry.legs, 7 => entry.shoulder, 8 => entry.utility, _ => throw new NotImplementedException(), }; } private static string GetColor(VanityEntry entry, VisSlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)slot != 5) { if ((int)slot == 10) { return entry.hairColor; } throw new NotImplementedException(); } return entry.skinColor; } private static void Set(VanityEntry entry, VisSlot slot, string value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown switch ((int)slot) { case 2: entry.leftBack = value; break; case 3: entry.rightBack = value; break; case 9: entry.beard = value; break; case 4: entry.chest = value; break; case 10: entry.hair = value; break; case 0: entry.leftHand = value; break; case 1: entry.rightHand = value; break; case 6: entry.helmet = value; break; case 5: entry.legs = value; break; case 7: entry.shoulder = value; break; case 8: entry.utility = value; break; default: throw new NotImplementedException(); } } private static void SetColor(VanityEntry entry, VisSlot slot, string value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)slot != 5) { if ((int)slot == 10) { entry.hairColor = value; } } else { entry.skinColor = value; } } private static VanityEntry GetEntry(string id) { VanityEntry vanityEntry = new VanityEntry(); if (VanityData.Data.TryGetValue(id, out VanityEntry value)) { vanityEntry = value; } else { VanityData.Data[id] = vanityEntry; } return vanityEntry; } private static string[] AddPlayerId(ConsoleEventArgs args) { if (string.IsNullOrEmpty(args.Args.FirstOrDefault((string s) => s.StartsWith("player=", StringComparison.OrdinalIgnoreCase)))) { return args.Args.Append("player=" + Helper.GetPlayerID()).ToArray(); } return args.Args; } private static string[] Parse(string[] args, out string id) { id = ""; string text = args.FirstOrDefault((string s) => s.StartsWith("player=", StringComparison.OrdinalIgnoreCase)); if (text == null) { return args; } string[] array = text.Split(new char[1] { '=' }); string[] result = args.Where((string s) => !s.StartsWith("player=", StringComparison.OrdinalIgnoreCase)).ToArray(); if (array.Length < 2) { throw new InvalidOperationException("Missing player id"); } if (long.TryParse(array[1], out var result2)) { id = result2.ToString(); return result; } id = Helper.GetPlayerID(array[1]); return result; } private static void SetVisualValue(VisSlot slot, ConsoleEventArgs args) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); string value = string.Join(" ", array.Skip(1)); VanityEntry entry = GetEntry(id); string text = Get(entry, slot); UndoCommands.Push(array[0] + " " + text); if (Vanity.ConfigSync.IsSourceOfTruth) { Set(entry, slot, value); VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } private static void SetColorValue(VisSlot slot, ConsoleEventArgs args) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); string value = string.Join(" ", array.Skip(1)).Replace(", ", ","); VanityEntry entry = GetEntry(id); string color = GetColor(entry, slot); UndoCommands.Push(array[0] + " " + color); if (Vanity.ConfigSync.IsSourceOfTruth) { SetColor(entry, slot, value); VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } private static void SetDurationValue(ConsoleEventArgs args) { string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); float value = Helper.TryFloat(string.Join(" ", array.Skip(1))); VanityEntry entry = GetEntry(id); Stack<string> undoCommands = UndoCommands; string obj = array[0]; float? colorDuration = entry.colorDuration; undoCommands.Push(obj + " " + colorDuration); if (Vanity.ConfigSync.IsSourceOfTruth) { entry.colorDuration = value; VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } private static void SetIntervalValue(ConsoleEventArgs args) { string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); float value = Helper.TryFloat(string.Join(" ", array.Skip(1))); VanityEntry entry = GetEntry(id); Stack<string> undoCommands = UndoCommands; string obj = array[0]; float? updateInterval = entry.updateInterval; undoCommands.Push(obj + " " + updateInterval); if (Vanity.ConfigSync.IsSourceOfTruth) { entry.updateInterval = value; VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } } private static string SlotToString(VisSlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown return (int)slot switch { 2 => "back_left", 3 => "back_right", 9 => "beard", 4 => "chest", 10 => "hair", 0 => "left", 1 => "right", 6 => "helmet", 5 => "legs", 7 => "shoulder", 8 => "utility", _ => throw new NotImplementedException(), }; } private static void RegisterGearAutoComplete(string name) { CommandWrapper.Register(name, (int index) => index switch { 0 => ObjectData.Items, 1 => ObjectData.Items, 2 => CommandWrapper.Info("Item variant (number)."), _ => new List<string>(1) { "player" }, }, new Dictionary<string, Func<int, List<string>>> { { "player", (int index) => (index != 0) ? null : Helper.Players() } }); } private static void RegisterAutoComplete(string name, bool variant = true) { CommandWrapper.Register(name, delegate(int index) { if (index == 0) { return ObjectData.Items; } return (index == 1 && variant) ? CommandWrapper.Info("Item variant (number).") : new List<string>(1) { "player" }; }, new Dictionary<string, Func<int, List<string>>> { { "player", (int index) => (index != 0) ? null : Helper.Players() } }); } private static void RegisterColorAutoComplete(string name) { CommandWrapper.Register(name, (int index) => CommandWrapper.Info("Color (r,g,b)"), new Dictionary<string, Func<int, List<string>>> { { "player", (int index) => (index != 0) ? null : Helper.Players() } }); } private static void CreateCommand(VisSlot slot) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown RegisterAutoComplete("wear_" + SlotToString(slot)); string text = "wear_" + SlotToString(slot); ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SetVisualValue(slot, args); }; object obj = <>c.<>9__16_1; if (obj == null) { ConsoleOptionsFetcher val2 = () => ObjectData.Items; <>c.<>9__16_1 = val2; obj = (object)val2; } new ConsoleCommand(text, "[item name] [variant = 0] - Changes visual equipment.", val, false, false, false, false, false, (ConsoleOptionsFetcher)obj, false, false, false); } public static void AddChangeEquipment() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //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_0249: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Expected O, but got Unknown //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Expected O, but got Unknown object obj = <>c.<>9__17_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { VisEquipment component = ((Component)Player.m_localPlayer).GetComponent<VisEquipment>(); if (!((Object)(object)component == (Object)null)) { args.Context.AddString("Helmet: " + component.m_helmetItem); args.Context.AddString("Shoulder: " + component.m_shoulderItem); args.Context.AddString("Chest: " + component.m_chestItem); args.Context.AddString("Leg: " + component.m_legItem); args.Context.AddString("Utility: " + component.m_utilityItem); args.Context.AddString("Left hand: " + component.m_leftItem); args.Context.AddString("Right hand: " + component.m_rightItem); args.Context.AddString("Left back: " + component.m_leftBackItem); args.Context.AddString("Right back: " + component.m_rightBackItem); args.Context.AddString("Hair: " + component.m_hairItem); args.Context.AddString("Beard: " + component.m_beardItem); args.Context.AddString("Skin: " + ((Vector3)(ref component.m_skinColor)).ToString("F2")); args.Context.AddString("Hair color: " + ((Vector3)(ref component.m_hairColor)).ToString("F2")); } } }; <>c.<>9__17_0 = val; obj = (object)val; } new ConsoleCommand("wear_info", "Prints information about visual equipment.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__17_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { string[] args4 = AddPlayerId(args); if (Vanity.ConfigSync.IsSourceOfTruth) { Parse(args4, out string id3); VanityEntry entry3 = GetEntry(id3); Set(entry3, (VisSlot)2, ""); Set(entry3, (VisSlot)3, ""); Set(entry3, (VisSlot)9, ""); Set(entry3, (VisSlot)4, ""); Set(entry3, (VisSlot)10, ""); Set(entry3, (VisSlot)0, ""); Set(entry3, (VisSlot)1, ""); Set(entry3, (VisSlot)6, ""); Set(entry3, (VisSlot)6, ""); Set(entry3, (VisSlot)5, ""); Set(entry3, (VisSlot)7, ""); Set(entry3, (VisSlot)8, ""); Set(entry3, (VisSlot)8, ""); SetColor(entry3, (VisSlot)10, ""); SetColor(entry3, (VisSlot)5, ""); VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args4); } }; <>c.<>9__17_1 = val2; obj2 = (object)val2; } new ConsoleCommand("wear_reset", "Resets visual equipment.", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); RegisterColorAutoComplete("wear_skin_color"); object obj3 = <>c.<>9__17_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { SetColorValue((VisSlot)5, args); }; <>c.<>9__17_2 = val3; obj3 = (object)val3; } new ConsoleCommand("wear_skin_color", "[r1,g1,b1] [r2,g2,b2] ... - Changes skin color. Automatically cycles between multiple values.", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); RegisterColorAutoComplete("wear_hair_color"); object obj4 = <>c.<>9__17_3; if (obj4 == null) { ConsoleEvent val4 = delegate(ConsoleEventArgs args) { SetColorValue((VisSlot)10, args); }; <>c.<>9__17_3 = val4; obj4 = (object)val4; } new ConsoleCommand("wear_hair_color", "[r1,g1,b1] [r2,g2,b2] ... - Changes hair color. Automatically cycles between multiple values.", (ConsoleEvent)obj4, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); RegisterAutoComplete("wear_beard", variant: false); object obj5 = <>c.<>9__17_4; if (obj5 == null) { ConsoleEvent val5 = delegate(ConsoleEventArgs args) { SetVisualValue((VisSlot)9, args); }; <>c.<>9__17_4 = val5; obj5 = (object)val5; } object obj6 = <>c.<>9__17_5; if (obj6 == null) { ConsoleOptionsFetcher val6 = () => ObjectData.Beards; <>c.<>9__17_5 = val6; obj6 = (object)val6; } new ConsoleCommand("wear_beard", "[name] - Changes beard.", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)obj6, false, false, false); RegisterAutoComplete("wear_hair", variant: false); object obj7 = <>c.<>9__17_6; if (obj7 == null) { ConsoleEvent val7 = delegate(ConsoleEventArgs args) { SetVisualValue((VisSlot)10, args); }; <>c.<>9__17_6 = val7; obj7 = (object)val7; } object obj8 = <>c.<>9__17_7; if (obj8 == null) { ConsoleOptionsFetcher val8 = () => ObjectData.Hairs; <>c.<>9__17_7 = val8; obj8 = (object)val8; } new ConsoleCommand("wear_hair", "[name] - Changes hair.", (ConsoleEvent)obj7, false, false, false, false, false, (ConsoleOptionsFetcher)obj8, false, false, false); RegisterGearAutoComplete("wear_gear"); object obj9 = <>c.<>9__17_8; if (obj9 == null) { ConsoleEvent val9 = delegate(ConsoleEventArgs args) { string[] args3 = AddPlayerId(args); string id2; string[] array2 = Parse(args3, out id2); if (array2.Length >= 2) { VanityEntry entry2 = GetEntry(id2); if (entry2.gear.TryGetValue(array2[1], out string value2)) { UndoCommands.Push(array2[0] + " " + array2[1] + " " + value2); } else { UndoCommands.Push(array2[0] + " " + array2[1]); } if (Vanity.ConfigSync.IsSourceOfTruth) { if (array2.Length == 2) { entry2.gear.Remove(array2[1]); } else { entry2.gear[args[1]] = string.Join(" ", array2.Skip(2)); } VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args3); } } }; <>c.<>9__17_8 = val9; obj9 = (object)val9; } object obj10 = <>c.<>9__17_9; if (obj10 == null) { ConsoleOptionsFetcher val10 = () => ObjectData.Items; <>c.<>9__17_9 = val10; obj10 = (object)val10; } new ConsoleCommand("wear_gear", "[item name] [visual name] [variant = 0] - Changes visual of a specific gear.", (ConsoleEvent)obj9, false, false, false, false, false, (ConsoleOptionsFetcher)obj10, false, false, false); RegisterGearAutoComplete("wear_crafted"); object obj11 = <>c.<>9__17_10; if (obj11 == null) { ConsoleEvent val11 = delegate(ConsoleEventArgs args) { string[] args2 = AddPlayerId(args); string id; string[] array = Parse(args2, out id); VanityEntry entry = GetEntry(id); if (entry.crafted.TryGetValue(array[1], out string value)) { UndoCommands.Push(array[0] + " " + array[1] + " " + value); } else { UndoCommands.Push(array[0] + " " + array[1]); } if (Vanity.ConfigSync.IsSourceOfTruth) { entry.crafted[array[1]] = string.Join(" ", array.Skip(2)); VanityData.ToFile(); } else { ServerExecution.Send((IEnumerable<string>)args2); } }; <>c.<>9__17_10 = val11; obj11 = (object)val11; } object obj12 = <>c.<>9__17_11; if (obj12 == null) { ConsoleOptionsFetcher val12 = () => ObjectData.Items; <>c.<>9__17_11 = val12; obj12 = (object)val12; } new ConsoleCommand("wear_crafted", "[item name] [visual name] [variant = 0] - Changes visual of a specific gear.", (ConsoleEvent)obj11, false, false, false, false, false, (ConsoleOptionsFetcher)obj12, false, false, false); object obj13 = <>c.<>9__17_12; if (obj13 == null) { ConsoleEvent val13 = delegate(ConsoleEventArgs args) { if (UndoCommands.Count == 0) { args.Context.AddString("Nothing to undo."); } else { string text = UndoCommands.Pop(); args.Context.TryRunCommand(text, false, false); if (UndoCommands.Count > 0) { UndoCommands.Pop(); } } }; <>c.<>9__17_12 = val13; obj13 = (object)val13; } object obj14 = <>c.<>9__17_13; if (obj14 == null) { ConsoleOptionsFetcher val14 = () => ObjectData.Items; <>c.<>9__17_13 = val14; obj14 = (object)val14; } new ConsoleCommand("wear_undo", "Reverts wear commands.", (ConsoleEvent)obj13, false, false, false, false, false, (ConsoleOptionsFetcher)obj14, false, false, false); CreateCommand((VisSlot)2); CreateCommand((VisSlot)3); CreateCommand((VisSlot)4); CreateCommand((VisSlot)0); CreateCommand((VisSlot)1); CreateCommand((VisSlot)6); CreateCommand((VisSlot)5); CreateCommand((VisSlot)7); CreateCommand((VisSlot)8); object obj15 = <>O.<0>__SetIntervalValue; if (obj15 == null) { ConsoleEvent val15 = SetIntervalValue; <>O.<0>__SetIntervalValue = val15; obj15 = (object)val15; } new ConsoleCommand("wear_color_interval", "Sets the color update interval.", (ConsoleEvent)obj15, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj16 = <>O.<1>__SetDurationValue; if (obj16 == null) { ConsoleEvent val16 = SetDurationValue; <>O.<1>__SetDurationValue = val16; obj16 = (object)val16; } new ConsoleCommand("wear_color_duration", "Sets the color duration.", (ConsoleEvent)obj16, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public static class CommandWrapper { public static Assembly ServerDevcommands = null; private const string GUID = "server_devcommands"; private static readonly BindingFlags PublicBinding = BindingFlags.Static | BindingFlags.Public; public static void Init() { if (Chainloader.PluginInfos.TryGetValue("server_devcommands", out var value)) { ServerDevcommands = ((object)value.Instance).GetType().Assembly; } } private static Type Type() { return ServerDevcommands.GetType("ServerDevcommands.AutoComplete"); } private static Type InfoType() { return ServerDevcommands.GetType("ServerDevcommands.ParameterInfo"); } private static MethodInfo GetMethod(Type type, string name, Type[] types) { return type.GetMethod(name, PublicBinding, null, CallingConventions.Standard, types, null); } public static void Register(string command, Func<int, int, List<string>> action) { if (!(ServerDevcommands == null)) { GetMethod(Type(), "Register", new Type[2] { typeof(string), typeof(Func<int, int, List<string>>) }).Invoke(null, new object[2] { command, action }); } } public static void Register(string command, Func<int, List<string>> action) { if (!(ServerDevcommands == null)) { GetMethod(Type(), "Register", new Type[2] { typeof(string), typeof(Func<int, List<string>>) }).Invoke(null, new object[2] { command, action }); } } public static void Register(string command, Func<int, List<string>> action, Dictionary<string, Func<int, List<string>>> named) { if (!(ServerDevcommands == null)) { GetMethod(Type(), "Register", new Type[3] { typeof(string), typeof(Func<int, List<string>>), typeof(Dictionary<string, Func<int, List<string>>>) }).Invoke(null, new object[3] { command, action, named }); } } public static List<string> Info(string value) { if (ServerDevcommands == null) { return new List<string>(); } return GetMethod(InfoType(), "Create", new Type[1] { typeof(string) }).Invoke(null, new object[1] { value }) as List<string>; } public static List<string> XZ(string name, string description, int index) { if (ServerDevcommands == null) { return new List<string>(); } return GetMethod(InfoType(), "XZ", new Type[3] { typeof(string), typeof(string), typeof(int) }).Invoke(null, new object[3] { name, description, index }) as List<string>; } public static List<string> Flag(string name, string description) { if (ServerDevcommands == null) { return new List<string>(); } return GetMethod(InfoType(), "Flag", new Type[2] { typeof(string), typeof(string) }).Invoke(null, new object[2] { name, description }) as List<string>; } public static List<string> ObjectIds() { if (ServerDevcommands == null) { return new List<string>(); } return InfoType().GetProperty("ObjectIds", PublicBinding).GetValue(null) as List<string>; } public static List<string> LocationIds() { if (ServerDevcommands == null) { return new List<string>(); } return InfoType().GetProperty("LocationIds", PublicBinding).GetValue(null) as List<string>; } public static void RegisterEmpty(string command) { if (!(ServerDevcommands == null)) { MethodInfo? method = Type().GetMethod("RegisterEmpty", PublicBinding); object[] parameters = new string[1] { command }; method.Invoke(null, parameters); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public class ObjectDB_Awake { private static void Postfix(ObjectDB __instance) { ObjectData.Beards = (from item in __instance.GetAllItems((ItemType)10, "Beard") select ((Object)item).name).ToList(); ObjectData.Hairs = (from item in __instance.GetAllItems((ItemType)10, "Hair") select ((Object)item).name).ToList(); ObjectData.Items = __instance.m_items.Select((GameObject item) => ((Object)item).name).ToList(); } } public class ObjectData { public static List<string> Beards = new List<string>(); public static List<string> Hairs = new List<string>(); public static List<string> Items = new List<string>(); } public class VanityEntry { [DefaultValue("")] public string name = ""; [DefaultValue("")] public string player = ""; [DefaultValue("")] public string group = ""; [DefaultValue("")] public string helmet = ""; [DefaultValue("")] public string chest = ""; [DefaultValue("")] public string shoulder = ""; [DefaultValue("")] public string legs = ""; [DefaultValue("")] public string utility = ""; [DefaultValue("")] public string leftHand = ""; [DefaultValue("")] public string rightHand = ""; [DefaultValue("")] public string leftBack = ""; [DefaultValue("")] public string rightBack = ""; [DefaultValue("")] public string beard = ""; [DefaultValue("")] public string hair = ""; [DefaultValue("")] public string skinColor = ""; [DefaultValue("")] public string hairColor = ""; [DefaultValue(null)] public float? updateInterval; [DefaultValue(null)] public float? colorDuration; public Dictionary<string, string> gear = new Dictionary<string, string>(); public Dictionary<string, string> crafted = new Dictionary<string, string>(); } public class VanityInfo { public Dictionary<string, Tuple<string, int>> gear = new Dictionary<string, Tuple<string, int>>(); public Tuple<string, int>? helmet; public Tuple<string, int>? chest; public Tuple<string, int>? legs; public Tuple<string, int>? shoulder; public Tuple<string, int>? utility; public Tuple<string, int>? leftHand; public Tuple<string, int>? rightHand; public Tuple<string, int>? leftBack; public Tuple<string, int>? rightBack; public Tuple<string, int>? beard; public Tuple<string, int>? hair; public string skinColor = ""; public string hairColor = ""; public float? updateInterval; public float? colorDuration; } public class VanityData { public static Dictionary<string, VanityEntry> Data = new Dictionary<string, VanityEntry>(); public static Dictionary<string, string> PlayerIds = new Dictionary<string, string>(); public static string FileName = "vanity.yaml"; public static string FilePath = Path.Combine(Paths.ConfigPath, FileName); public static void CreateFile() { if (!File.Exists(FilePath)) { File.WriteAllText(FilePath, ""); } } public static void ToFile() { if (Vanity.ConfigSync.IsSourceOfTruth) { string contents = Serializer().Serialize((object)Data); File.WriteAllText(FilePath, contents); } } public static void FromFile() { if (Vanity.ConfigSync.IsSourceOfTruth) { Vanity.VanityValue.Value = File.ReadAllText(FilePath); } } public static void FromValue(string value) { Data = Deserialize<Dictionary<string, VanityEntry>>(value, "Data") ?? new Dictionary<string, VanityEntry>(); PlayerIds.Clear(); foreach (KeyValuePair<string, VanityEntry> datum in Data) { if (!string.IsNullOrEmpty(datum.Value.name)) { PlayerIds[datum.Value.name] = datum.Key; } } VanityManager.Load(); Vanity.Log.LogInfo((object)$"Reloading {Data.Count} vanity data."); } public static void SetupWatcher() { Watcher.Setup(FileName, FromFile); } public static IDeserializer Deserializer() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown return ((BuilderSkeleton<DeserializerBuilder>)(object)((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance)).WithTypeConverter((IYamlTypeConverter)(object)new FloatConverter()).Build(); } public static IDeserializer DeserializerUnSafe() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown return ((BuilderSkeleton<DeserializerBuilder>)(object)((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance)).WithTypeConverter((IYamlTypeConverter)(object)new FloatConverter()).IgnoreUnmatchedProperties().Build(); } public static ISerializer Serializer() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown return ((BuilderSkeleton<SerializerBuilder>)(object)((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).DisableAliases().ConfigureDefaultValuesHandling((DefaultValuesHandling)2)).WithTypeConverter((IYamlTypeConverter)(object)new FloatConverter()).Build(); } public static T Deserialize<T>(string raw, string fileName) where T : new() { try { return Deserializer().Deserialize<T>(raw); } catch (Exception ex) { Vanity.Log.LogError((object)(fileName + ": " + ex.Message)); try { return DeserializerUnSafe().Deserialize<T>(raw); } catch (Exception) { return new T(); } } } public static Dictionary<long, T> Read<T>(string pattern) { Dictionary<long, T> dictionary = new Dictionary<long, T>(); string[] files = Directory.GetFiles(Paths.ConfigPath, pattern); foreach (string text in files) { Dictionary<long, T> dictionary2 = Deserialize<Dictionary<long, T>>(File.ReadAllText(text), text); if (dictionary2 == null) { continue; } foreach (KeyValuePair<long, T> item in dictionary2) { dictionary[item.Key] = item.Value; } } return dictionary; } private static bool UpdateName(string id, string name) { if (Data.TryGetValue(id, out VanityEntry value)) { if (value.name == name) { return false; } value.name = name; return true; } Data[id] = new VanityEntry { name = name }; return true; } private static bool UpdateNetworkId(string id, string networkId) { if (Data.TryGetValue(id, out VanityEntry value)) { if (value.player == networkId) { return false; } value.player = networkId; return true; } Data[id] = new VanityEntry { player = networkId }; return true; } public static void UpdatePlayerIds() { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) ZDOMan instance = ZDOMan.instance; if (instance == null || !Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { return; } bool flag = false; flag |= UpdateName("Everyone", "Everyone"); if (!ZNet.instance.IsDedicated()) { flag |= UpdateName(Game.instance.GetPlayerProfile().GetPlayerID().ToString(), Game.instance.GetPlayerProfile().GetName()); flag |= UpdateNetworkId(Game.instance.GetPlayerProfile().GetPlayerID().ToString(), Helper.GetNetworkId()); } foreach (ZDOPeer peer in instance.m_peers) { ZDO zDO = instance.GetZDO(peer.m_peer.m_characterID); if (zDO == null) { return; } long @long = zDO.GetLong(ZDOVars.s_playerID, 0L); string @string = zDO.GetString(ZDOVars.s_playerName, ""); if (@long != 0L && !(@string == "")) { flag |= UpdateName(@long.ToString(), @string); flag |= UpdateNetworkId(@long.ToString(), peer.m_peer.m_rpc.GetSocket().GetHostName()); } } if (flag) { ToFile(); } } } public class FloatConverter : IYamlTypeConverter { public bool Accepts(Type type) { return type == typeof(float); } public object ReadYaml(IParser parser, Type type) { return ReadYaml(parser, type, null); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) float num = float.Parse(((Scalar)parser.Current).Value, NumberStyles.Float, CultureInfo.InvariantCulture); parser.MoveNext(); return num; } public void WriteYaml(IEmitter emitter, object value, Type type) { WriteYaml(emitter, value, type, null); } public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown emitter.Emit((ParsingEvent)new Scalar(((float)value).ToString("0.###", CultureInfo.InvariantCulture))); } } public class VanityManager { public static VanityInfo Info = new VanityInfo(); public static Dictionary<string, Dictionary<string, Tuple<string, int>>> Crafted = new Dictionary<string, Dictionary<string, Tuple<string, int>>>(); public static Color? SkinColor; public static Color? HairColor; public static float ColorUpdateInterval => Info.updateInterval.GetValueOrDefault(0.1f); public static float ColorDuration => Info.colorDuration.GetValueOrDefault(1f); public static void Load() { Info = new VanityInfo(); LoadCrafted(); string playerID = Helper.GetPlayerID(); string networkId = Helper.GetNetworkId(); Load(Info, "Everyone"); Load(Info, "0"); Load(Info, networkId); Load(Info, playerID); if (Object.op_Implicit((Object)(object)Game.instance) && Game.instance.m_shuttingDown) { return; } if (Object.op_Implicit((Object)(object)FejdStartup.m_instance) && Object.op_Implicit((Object)(object)FejdStartup.m_instance.m_playerInstance)) { Player component = FejdStartup.m_instance.m_playerInstance.GetComponent<Player>(); if (component != null) { ((Humanoid)component).SetupEquipment(); } } if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Humanoid)Player.m_localPlayer).SetupEquipment(); } } private static void LoadCrafted() { Crafted = new Dictionary<string, Dictionary<string, Tuple<string, int>>>(); foreach (KeyValuePair<string, VanityEntry> datum in VanityData.Data) { if (!Crafted.ContainsKey(datum.Key)) { Crafted[datum.Key] = new Dictionary<string, Tuple<string, int>>(); } foreach (KeyValuePair<string, string> item in datum.Value.crafted) { Crafted[datum.Key][item.Key] = Helper.Parse(item.Value); } } } private static void Load(VanityInfo info, string id) { if (!VanityData.Data.TryGetValue(id, out VanityEntry value)) { return; } if (!string.IsNullOrEmpty(value.group)) { string[] array = Helper.ParseGroups(value.group); foreach (string id2 in array) { Load(info, id2); } } if (!string.IsNullOrEmpty(value.beard)) { info.beard = Helper.Parse(value.beard); } if (!string.IsNullOrEmpty(value.chest)) { info.chest = Helper.Parse(value.chest); } if (value.colorDuration.HasValue) { info.colorDuration = value.colorDuration; } if (!string.IsNullOrEmpty(value.hair)) { info.hair = Helper.Parse(value.hair); } if (!string.IsNullOrEmpty(value.hairColor)) { info.hairColor = value.hairColor; } if (!string.IsNullOrEmpty(value.helmet)) { info.helmet = Helper.Parse(value.helmet); } if (!string.IsNullOrEmpty(value.leftBack)) { info.leftBack = Helper.Parse(value.leftBack); } if (!string.IsNullOrEmpty(value.leftHand)) { info.leftHand = Helper.Parse(value.leftHand); } if (!string.IsNullOrEmpty(value.legs)) { info.legs = Helper.Parse(value.legs); } if (!string.IsNullOrEmpty(value.rightBack)) { info.rightBack = Helper.Parse(value.rightBack); } if (!string.IsNullOrEmpty(value.rightHand)) { info.rightHand = Helper.Parse(value.rightHand); } if (!string.IsNullOrEmpty(value.shoulder)) { info.shoulder = Helper.Parse(value.shoulder); } if (!string.IsNullOrEmpty(value.skinColor)) { info.skinColor = value.skinColor; } if (value.updateInterval.HasValue) { info.updateInterval = value.updateInterval; } if (!string.IsNullOrEmpty(value.utility)) { info.utility = Helper.Parse(value.utility); } foreach (KeyValuePair<string, string> item in value.gear) { info.gear[item.Key] = Helper.Parse(item.Value); } } public static Tuple<string, int>? GetVisualBySlot(VisSlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown return (int)slot switch { 2 => Info.leftBack, 3 => Info.rightBack, 9 => Info.beard, 4 => Info.chest, 10 => Info.hair, 0 => Info.leftHand, 1 => Info.rightHand, 6 => Info.helmet, 5 => Info.legs, 7 => Info.shoulder, 8 => Info.utility, _ => null, }; } public static Color[] GetSkinColors(Player obj) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return Helper.ParseColors(Info.skinColor, obj.m_skinColor); } public static Color[] GetHairColors(Player obj) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return Helper.ParseColors(Info.hairColor, obj.m_hairColor); } private static ItemData? GetEquipment(Player player, VisSlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown return (ItemData?)((int)slot switch { 2 => ((Humanoid)player).m_leftItem, 3 => ((Humanoid)player).m_rightItem, 9 => null, 4 => ((Humanoid)player).m_chestItem, 10 => null, 0 => ((Humanoid)player).m_leftItem, 1 => ((Humanoid)player).m_rightItem, 6 => ((Humanoid)player).m_helmetItem, 5 => ((Humanoid)player).m_legItem, 7 => ((Humanoid)player).m_shoulderItem, 8 => ((Humanoid)player).m_utilityItem, _ => throw new NotImplementedException(), }); } public static void OverrideItem(VisEquipment vis, VisSlot slot, ref string name, ref int variant) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsLocalPlayer(vis)) { ItemData equipment = GetEquipment(((Component)vis).GetComponent<Player>(), slot); Tuple<string, int> visualBySlot = GetVisualBySlot(slot); Dictionary<string, Tuple<string, int>> value; Tuple<string, int> value2; Tuple<string, int> value3; if (visualBySlot != null) { name = visualBySlot.Item1; variant = visualBySlot.Item2; } else if (equipment != null && Crafted.TryGetValue(equipment.m_crafterID.ToString(), out value) && value.TryGetValue(name, out value2)) { name = value2.Item1; variant = value2.Item2; } else if (Info.gear.TryGetValue(name, out value3)) { name = value3.Item1; variant = value3.Item2; } } } private static VisSlot? GetSlot(ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected I4, but got Unknown ItemType itemType = item.m_shared.m_itemType; return (itemType - 3) switch { 0 => (VisSlot)1, 1 => (VisSlot)0, 4 => (VisSlot)4, 3 => (VisSlot)6, 8 => (VisSlot)5, 2 => (VisSlot)0, 16 => (VisSlot)1, 14 => (VisSlot)7, 12 => (VisSlot)1, 11 => (VisSlot)1, 15 => (VisSlot)8, _ => null, }; } public static void OverrideItem(ItemData item, ref string name, ref int variant) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) VisSlot? slot = GetSlot(item); if (slot.HasValue) { Tuple<string, int> visualBySlot = GetVisualBySlot(slot.Value); Dictionary<string, Tuple<string, int>> value; Tuple<string, int> value2; Tuple<string, int> value3; if (visualBySlot != null) { name = visualBySlot.Item1; variant = visualBySlot.Item2; } else if (Crafted.TryGetValue(item.m_crafterID.ToString(), out value) && Object.op_Implicit((Object)(object)item.m_dropPrefab) && value.TryGetValue(((Object)item.m_dropPrefab).name, out value2)) { name = value2.Item1; variant = value2.Item2; } else if (Object.op_Implicit((Object)(object)item.m_dropPrefab) && Info.gear.TryGetValue(((Object)item.m_dropPrefab).name, out value3)) { name = value3.Item1; variant = value3.Item2; } } } public static void OverrideItem(VisEquipment vis, VisSlot slot, ref string name) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) int variant = 0; OverrideItem(vis, slot, ref name, ref variant); } public static void OverrideSkinColor(VisEquipment vis, ref Vector3 color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsLocalPlayer(vis) && SkinColor.HasValue) { color.x = SkinColor.Value.r; color.y = SkinColor.Value.g; color.z = SkinColor.Value.b; } } public static void OverrideHairColor(VisEquipment vis, ref Vector3 color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsLocalPlayer(vis) && HairColor.HasValue) { color.x = HairColor.Value.r; color.y = HairColor.Value.g; color.z = HairColor.Value.b; } } } public static class Helper { public static List<string> Players() { return (from s in VanityData.PlayerIds.Keys select s.Replace(" ", "_") into s orderby s select s).ToList(); } private static string Normalize(string name) { return name.ToLower().Replace(" ", "_"); } public static string GetPlayerID(string name) { string name2 = name; name2 = name2.ToLower().Replace(" ", "_"); Dictionary<string, string> dictionary = VanityData.PlayerIds.ToDictionary<KeyValuePair<string, string>, string, string>((KeyValuePair<string, string> kvp) => Normalize(kvp.Key), (KeyValuePair<string, string> kvp) => kvp.Value); if (dictionary.TryGetValue(name2, out var value)) { return value; } string text = dictionary.Keys.FirstOrDefault((string s) => s.StartsWith(name2, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(text)) { return dictionary[text]; } text = dictionary.Keys.FirstOrDefault((string s) => s.Contains(name2)); if (!string.IsNullOrEmpty(text)) { return dictionary[text]; } throw new InvalidOperationException("Unable to find the player."); } public static bool IsLocalPlayer(VisEquipment obj) { if (Object.op_Implicit((Object)(object)obj) && obj.m_isPlayer) { return IsLocalPlayer(((Component)obj).GetComponent<Player>()); } return false; } public static bool IsLocalPlayer(Player obj) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)obj)) { if (!((Object)(object)obj == (Object)(object)Player.m_localPlayer)) { return ((Character)obj).GetZDOID() == ZDOID.None; } return true; } return false; } public static bool IsTrophy(ItemData item) { if (item != null) { return Name(item).ToLower().Contains("trophy"); } return false; } public static string Name(ItemData item) { object obj; if (item == null) { obj = null; } else { GameObject dropPrefab = item.m_dropPrefab; obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } if (obj == null) { obj = ""; } return (string)obj; } public static float TryFloat(string arg, float defaultValue = 1f) { if (!float.TryParse(arg, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return defaultValue; } return result; } public static float TryFloat(string[] args, int index, float defaultValue = 1f) { if (index >= args.Length) { return defaultValue; } return TryFloat(args[index], defaultValue); } public static int TryInt(string arg, int defaultValue = 1) { if (!int.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return defaultValue; } return result; } public static int TryInt(string[] args, int index, int defaultValue = 1) { if (index >= args.Length) { return defaultValue; } return TryInt(args[index], defaultValue); } public static Tuple<string, int> Parse(string value) { char[] separator = new char[2] { ',', ' ' }; string[] array = value.Split(separator, StringSplitOptions.RemoveEmptyEntries).ToArray(); string item = array[0]; int item2 = TryInt(array, 1, 0); return new Tuple<string, int>(item, item2); } public static string[] ParseGroups(string value) { char[] separator = new char[2] { ',', ' ' }; return value.Split(separator, StringSplitOptions.RemoveEmptyEntries).ToArray(); } public static Color ParseColor(string value, Color baseColor) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) string[] args = value.Split(new char[1] { ',' }); Color val = baseColor; val.r = TryFloat(args, 0, val.r); val.g = TryFloat(args, 1, val.g); val.b = TryFloat(args, 2, val.b); return val; } public static Color[] ParseColors(string value, Vector3 baseColor) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) string[] source = value.Split(new char[1] { ' ' }); Color color = new Color(baseColor.x, baseColor.y, baseColor.z); return source.Select((string value) => ParseColor(value, color)).ToArray(); } public static string GetPlayerID() { Player localPlayer = Player.m_localPlayer; return ((localPlayer != null) ? localPlayer.GetPlayerID().ToString() : null) ?? CharacterPreview.Id; } public static string GetNetworkId() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) IDistributionPlatform distributionPlatform = PlatformManager.DistributionPlatform; object obj; if (distributionPlatform == null) { obj = null; } else { ILocalUser localUser = distributionPlatform.LocalUser; if (localUser == null) { obj = null; } else { PlatformUserID platformUserID = ((IUser)localUser).PlatformUserID; obj = ((object)(PlatformUserID)(ref platformUserID)).ToString(); } } if (obj == null) { obj = "0"; } return (string)obj; } } [HarmonyPatch(typeof(FejdStartup), "SetupCharacterPreview")] public class CharacterPreview { public static string Id = ""; private static void Prefix(PlayerProfile profile) { if (profile == null) { Id = ""; } else { Id = profile.m_playerID.ToString(); } VanityManager.Load(); } } [HarmonyPatch(typeof(Player), "Awake")] public class LoadVanity { private static void Postfix() { VanityManager.Load(); } } [HarmonyPatch] public class IconPatches { private static Sprite? OverrideItem(ItemData item) { string name = ""; int variant = 0; VanityManager.OverrideItem(item, ref name, ref variant); if (name == "") { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name); ItemData val = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData); if (val == null || val.m_shared.m_icons == null || val.m_shared.m_icons.Length <= variant) { return null; } return val.m_shared.m_icons[variant]; } [HarmonyPatch(typeof(ItemData), "GetIcon")] [HarmonyPostfix] [HarmonyPriority(0)] private static Sprite GetIcon(Sprite result, ItemData __instance) { return OverrideItem(__instance) ?? result; } [HarmonyPatch(typeof(InventoryGui), "SetupUpgradeItem")] [HarmonyPostfix] [HarmonyPriority(0)] private static void SetupUpgradeItem(InventoryGui __instance, Recipe recipe, ItemData item) { if (item == null) { item = recipe.m_item.m_itemData; } __instance.m_upgradeItemIcon.sprite = OverrideItem(item) ?? __instance.m_upgradeItemIcon.sprite; } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] [HarmonyPostfix] [HarmonyPriority(0)] private static void UpdateRecipe(InventoryGui __instance) { ItemData itemData = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).ItemData; if (itemData != null) { __instance.m_recipeIcon.sprite = OverrideItem(itemData) ?? __instance.m_recipeIcon.sprite; } } } [HarmonyPatch(typeof(Terminal), "AddString", new Type[] { typeof(string) })] public class RedirectOutput { public static ZRpc? Target; private static void Postfix(string text) { if (ZNet.m_isServer && Target != null) { ZNet.instance.RemotePrint(Target, text); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public class ServerExecution { public static string RPC_Command = "VANITY_Command"; public static void Send(string command) { ZRpc serverRPC = ZNet.instance.GetServerRPC(); ((Terminal)Console.instance).AddString("Sending command: " + command); if (serverRPC != null) { string rPC_Command = RPC_Command; object[] array = new string[1] { command }; serverRPC.Invoke(rPC_Command, array); } } public static void Send(IEnumerable<string> args) { Send(string.Join(" ", args)); } public static void Send(ConsoleEventArgs args) { Send((IEnumerable<string>)args.Args); } private static bool IsAllowed(ZRpc rpc) { ZNet instance = ZNet.instance; if (!((Behaviour)instance).enabled) { return false; } if (rpc != null && !instance.ListContainsId(instance.m_adminList, rpc.GetSocket().GetHostName())) { ((Terminal)Console.instance).AddString("Unauthorized to set vanity."); return false; } return true; } private static void RPC_Do_Command(ZRpc rpc, string command) { RedirectOutput.Target = rpc; if (IsAllowed(rpc)) { ((Terminal)Console.instance).TryRunCommand(command, false, false); } RedirectOutput.Target = null; } private static void Postfix(ZNet __instance, ZRpc rpc) { if (__instance.IsServer()) { rpc.Register<string>(RPC_Command, (Action<ZRpc, string>)RPC_Do_Command); } } } [HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")] public class SetupVisEquipment { private static void Prefix(Humanoid __instance) { SetEquipment.IsHidden = __instance.m_hiddenLeftItem != null || __instance.m_hiddenRightItem != null; } } [HarmonyPatch(typeof(VisEquipment))] [HarmonyPriority(200)] public class SetEquipment { public static bool IsHidden; [HarmonyPatch("SetRightItem")] [HarmonyPrefix] private static void SetRightItem(VisEquipment __instance, ref string name) { if (!IsHidden) { VanityManager.OverrideItem(__instance, (VisSlot)1, ref name); } } [HarmonyPatch("SetLeftItem")] [HarmonyPrefix] private static void SetLeftItem(VisEquipment __instance, ref string name, ref int variant) { if (!IsHidden) { VanityManager.OverrideItem(__instance, (VisSlot)0, ref name, ref variant); } } [HarmonyPatch("SetRightBackItem")] [HarmonyPrefix] private static void SetRightBackItem(VisEquipment __instance, ref string name) { if (IsHidden) { VanityManager.OverrideItem(__instance, (VisSlot)1, ref name); } VanityManager.OverrideItem(__instance, (VisSlot)3, ref name); } [HarmonyPatch("SetLeftBackItem")] [HarmonyPrefix] private static void SetLeftBackItem(VisEquipment __instance, ref string name, ref int variant) { if (IsHidden) { VanityManager.OverrideItem(__instance, (VisSlot)0, ref name, ref variant); } VanityManager.OverrideItem(__instance, (VisSlot)2, ref name, ref variant); } [HarmonyPatch("SetChestItem")] [HarmonyPrefix] private static void SetChestItem(VisEquipment __instance, ref string name) { VanityManager.OverrideItem(__instance, (VisSlot)4, ref name); } [HarmonyPatch("SetLegItem")] [HarmonyPrefix] private static void SetLegItem(VisEquipment __instance, ref string name) { VanityManager.OverrideItem(__instance, (VisSlot)5, ref name); } [HarmonyPatch("SetHelmetItem")] [HarmonyPrefix] private static void SetHelmetItem(VisEquipment __instance, ref string name) { VanityManager.OverrideItem(__instance, (VisSlot)6, ref name); } [HarmonyPatch("SetShoulderItem")] [HarmonyPrefix] private static void SetShoulderItem(VisEquipment __instance, ref string name, ref int variant) { VanityManager.OverrideItem(__instance, (VisSlot)7, ref name, ref variant); } [HarmonyPatch("SetUtilityItem")] [HarmonyPrefix] private static void SetUtilityItem(VisEquipment __instance, ref string name) { VanityManager.OverrideItem(__instance, (VisSlot)8, ref name); } [HarmonyPatch("SetBeardItem")] [HarmonyPrefix] private static void SetBeardItem(VisEquipment __instance, ref string name) { VanityManager.OverrideItem(__instance, (VisSlot)9, ref name); } [HarmonyPatch("SetHairItem")] [HarmonyPrefix] private static void SetHairItem(VisEquipment __instance, ref string name) { VanityManager.OverrideItem(__instance, (VisSlot)10, ref name); } [HarmonyPatch("SetSkinColor")] [HarmonyPrefix] private static void SetSkinColor(VisEquipment __instance, ref Vector3 color) { VanityManager.OverrideSkinColor(__instance, ref color); } [HarmonyPatch("SetHairColor")] [HarmonyPrefix] private static void SetHairColor(VisEquipment __instance, ref Vector3 color) { VanityManager.OverrideHairColor(__instance, ref color); } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) })] public class Tooltip { private static string Postfix(string result, ItemData item, bool crafting) { if (item == null) { return result; } if (crafting) { return result; } string name = ""; int variant = 0; VanityManager.OverrideItem(item, ref name, ref variant); if (variant != 0) { name = name + " " + variant; } if (name != "") { return result + "\nStyle: <color=orange>" + name + "</color>"; } return result; } } [BepInPlugin("vanity", "Vanity", "1.19")] public class Vanity : BaseUnityPlugin { public const string GUID = "vanity"; public const string NAME = "Vanity"; public const string VERSION = "1.19"; public static ManualLogSource Log; public static CustomSyncedValue<string> VanityValue; public static ConfigSync ConfigSync = new ConfigSync("vanity") { DisplayName = "Vanity", CurrentVersion = "1.19", MinimumRequiredVersion = "1.19", IsLocked = true }; private float timer; public void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; VanityValue = new CustomSyncedValue<string>(ConfigSync, "vanity_data"); VanityValue.ValueChanged += delegate { VanityData.FromValue(VanityValue.Value); }; new Harmony("vanity").PatchAll(); VanityData.CreateFile(); VanityData.SetupWatcher(); VanityData.FromFile(); } public void Start() { CommandWrapper.Init(); } public void LateUpdate() { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { timer -= Time.deltaTime; if (timer <= 0f) { timer = 10f; VanityData.UpdatePlayerIds(); } } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] public class SetCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<int, List<string>> <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleOptionsFetcher <>9__0_2; internal List<string> <Postfix>b__0_0(int index) { if (index == 0) { return Helper.Players(); } return null; } internal void <Postfix>b__0_1(ConsoleEventArgs args) { string text = ""; text = ((args.Length <= 1) ? Helper.GetPlayerID() : Helper.GetPlayerID(string.Join(" ", args.Args.Skip(1)))); args.Context.AddString(text.ToString()); GUIUtility.systemCopyBuffer = text.ToString(); } internal List<string> <Postfix>b__0_2() { return Helper.Players(); } } private static void Postfix() { //IL_004c: 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_0057: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown ChangeEquipment.AddChangeEquipment(); CommandWrapper.Register("playerid", (int index) => (index == 0) ? Helper.Players() : null); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { string text = ""; text = ((args.Length <= 1) ? Helper.GetPlayerID() : Helper.GetPlayerID(string.Join(" ", args.Args.Skip(1)))); args.Context.AddString(text.ToString()); GUIUtility.systemCopyBuffer = text.ToString(); }; <>c.<>9__0_1 = val; obj = (object)val; } object obj2 = <>c.<>9__0_2; if (obj2 == null) { ConsoleOptionsFetcher val2 = () => Helper.Players(); <>c.<>9__0_2 = val2; obj2 = (object)val2; } new ConsoleCommand("playerid", "[name] - Copies the player id to the clipboard.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false); } } [HarmonyPatch(typeof(ZNet), "Awake")] public class DisableServerSync { private static void Finalizer(ZNet __instance) { if (!__instance.IsDedicated() && __instance.IsServer()) { Vanity.Log.LogInfo((object)"Self hosting detected, disabling server sync."); AccessTools.Field(typeof(ConfigSync), "isServer").SetValue(null, false); } } } } namespace ServerSync { [PublicAPI] public abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] public class SyncedConfigEntry<T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; base..ctor(); } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } public abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] public sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] public class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = configSyncs.First(); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); }).ToList(); List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>(); public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ZPlayFabSocket, ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; ((ZPlayFabSocket)this)..ctor(); } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPriority(800)] [HarmonyPrefix] private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (!__instance.IsServer()) { return; } BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket"); object? value = fieldInfo.GetValue(val); ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null); if (val2 != null) { typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId); } fieldInfo.SetValue(val, bufferingSocket); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = bufferingSocket; } [HarmonyPostfix] private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary<Assembly, BufferingSocket> __state2 = __state; ZNetPeer peer; if (__instance2.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance2).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc2.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List<PackageEntry> entries = new List<PackageEntry>(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc2.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package)); } SendBufferedData(); } } } private class PackageEntry { public string section = null; public string key = null; public Type type = null; public object? value; } [HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")] private static class PreventSavingServerInfo { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, ref string __result) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase)) { return true; } __result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType); return false; } } [HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")] private static class PreventConfigRereadChangingValues { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, string value) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null) { return true; } try { ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType); } catch (Exception ex) { Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}"); } return false; } } private class InvalidDeserializationTypeException : Exception { public string expected = null; public string received = null; public string field = ""; } public static bool ProcessingServerUpdate; public readonly string Name; public string? DisplayName; public string? CurrentVersion; public string? MinimumRequiredVersion; public bool ModRequired = false; private bool? forceConfigLocking; private bool isSourceOfTruth = true; private static readonly HashSet<ConfigSync> configSyncs; private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>(); private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>(); private static bool isServer; private static bool lockExempt; private OwnConfigEntryBase? lockedConfig = null; private const byte PARTIAL_CONFIGS = 1; private const byte FRAGMENTED_CONFIG = 2; private const byte COMPRESSED_CONFIG = 4; private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>(); private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>(); private static long packageCounter; public bool IsLocked { get { bool? flag = forceConfigLocking; bool num; if (!flag.HasValue) { if (lockedConfig == null) { goto IL_0052; } num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0; } else { num = flag.GetValueOrDefault(); } if (!num) { goto IL_0052; } int result = ((!lockExempt) ? 1 : 0); goto IL_0053; IL_0053: return (byte)result != 0; IL_0052: result = 0; goto IL_0053; } set { forceConfigLocking = value; } } public bool IsAdmin => lockExempt || isSourceOfTruth; public bool IsSourceOfTruth { get { return isSourceOfTruth; } private set { if (value != isSourceOfTruth) { isSourceOfTruth = value; this.SourceOfTruthChanged?.Invoke(value); } } } public bool InitialSyncDone { get; private set; } = false; public event Action<bool>? SourceOfTruthChanged; private event Action? lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet<ConfigSync>(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry) { ConfigEntry<T> configEntry2 = configEntry; OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2); SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry<T>(configEntry2); AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1] { new ConfigurationManagerAttributes() }.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray()); configEntry2.SettingChanged += delegate { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry<T>(lockingConfig); lockingConfig.SettingChanged += delegate { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry<T>)lockedConfig; } internal void AddCustomValue(CustomSyncedValueBase customValue) { CustomSyncedValueBase customValue2 = customValue; if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue2.Identifier)) { throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)"); } allCustomValues.Add(customValue2); allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority)); customValue2.ValueChanged += delegate { if (!ProcessingServerUpdate) { Broadcast(ZRoutedRpc.Everybody, customValue2); } }; } private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package) { lockedConfigChanged += serverLockedSettingChanged; IsSourceOfTruth = false; if (HandleConfigSyncRPC(0L, package, clientUpdate: false)) { InitialSyncDone = true; } } private void RPC_FromOtherClientConfigSync(long sender, ZPackage package) { HandleConfigSyncRPC(sender, package, clientUpdate: true); } private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown try { if (isServer && IsLocked) { ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc; object obj; if (currentRpc == null) { obj = null; } else { ISocket socket = currentRpc.GetSocket(); obj = ((socket != null) ? socket.GetHostName() : null); } string text = (string)obj; if (text != null) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text })))) { return false; } } } cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv) { if (kv.Key < DateTimeOffset.Now.Ticks) { configValueCache.Remove(kv.Value); return true; } return false; }); byte b = package.ReadByte(); if ((b & 2u) != 0) { long num = package.ReadLong(); string text2 = sender.ToString() + num; if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value)) { value = new SortedDictionary<int, byte[]>(); configValueCache[text2] = value; cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2)); } int key = package.ReadInt(); int num2 = package.ReadInt(); value.Add(key, package.ReadByteArray()); if (value.Count < num2) { return false; } configValueCache.Remove(text2); package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray()); b = package.ReadByte(); } ProcessingServerUpdate = true; if ((b & 4u) != 0) { byte[] buffer = package.ReadByteArray(); MemoryStream stream = new MemoryStream(buffer); MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) { deflateStream.CopyTo(memoryStream); } package = new ZPackage(memoryStream.ToArray()); b = package.ReadByte(); } if ((b & 1) == 0) { resetConfigsFromServer(); } ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package); ConfigFile val2 = null; bool saveOnConfigSet = false; foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues) { if (!isServer && configValue.Key.LocalBaseValue == null) { configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue; } if (val2 == null) { val2 = configValue.Key.BaseConfig.ConfigFile; saveOnConfigSet = val2.SaveOnConfigSet; val2.SaveOnConfigSet = false; } configValue.Key.BaseConfig.BoxedValue = configValue.Value; } if (val2 != null) { val2.SaveOnConfigSet = saveOnConfigSet; } foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues) { if (!isServer) {