using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EWP; using GUIFramework; using HarmonyLib; using Microsoft.CodeAnalysis; using ServerDevcommands; using Service; using Splatform; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [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("ServerDevcommands")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1134af287ad1bc884b9022df8102aab51dff1d99")] [assembly: AssemblyProduct("ServerDevcommands")] [assembly: AssemblyTitle("ServerDevcommands")] [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 PlayerInfo { public string Name; public Vector3 Pos; public Quaternion Rot; public string HostId; public long PeerId; public ZDOID ZDOID; public PlayerInfo(ZNetPeer peer) { //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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) HostId = peer.m_rpc.GetSocket().GetHostName(); Name = peer.m_playerName; Pos = peer.m_refPos; ZDOID = peer.m_characterID; PeerId = ((ZDOID)(ref ZDOID)).UserID; ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO != null) { Pos = zDO.m_position; Rot = zDO.GetRotation(); } } public PlayerInfo(PlayerInfo info) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) HostId = ((object)(PlatformUserID)(ref info.m_userInfo.m_id)).ToString(); Name = info.m_name; Pos = info.m_position; ZDOID = info.m_characterID; PeerId = ((ZDOID)(ref ZDOID)).UserID; ZDO zDO = ZDOMan.instance.GetZDO(info.m_characterID); if (zDO != null) { Pos = zDO.m_position; Rot = zDO.GetRotation(); } } public PlayerInfo(Player player) { //IL_001f: 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_0041: 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) //IL_0052: 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) HostId = "self"; Name = player.GetPlayerName(); ZDOID = ((Character)player).GetZDOID(); PeerId = ((ZDOID)(ref ZDOID)).UserID; Pos = ((Component)player).transform.position; Rot = ((Component)player).transform.rotation; } public static List FindPlayers(string[] args) { //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) List list = (ZNet.instance.IsServer() ? (from peer in ZNet.instance.GetPeers() select new PlayerInfo(peer)).ToList() : ZNet.instance.m_players.Select((PlayerInfo player) => new PlayerInfo(player)).ToList()); if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && list.All((PlayerInfo p) => p.ZDOID != ((Character)Player.m_localPlayer).GetZDOID())) { list.Add(new PlayerInfo(Player.m_localPlayer)); } Dictionary dictionary = new Dictionary(); foreach (string text in args) { switch (text) { case "*": case "all": return list; case "others": { List list2 = new List(); list2.AddRange(list.Where(delegate(PlayerInfo p) { //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) //IL_001b: 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_0034: Unknown result type (might be due to invalid IL or missing references) ZDOID zDOID = p.ZDOID; Player localPlayer = Player.m_localPlayer; ZDOID? val = ((localPlayer != null) ? new ZDOID?(((Character)localPlayer).GetZDOID()) : null); return !val.HasValue || zDOID != val.GetValueOrDefault(); })); return list2; } } string text2 = text.ToLowerInvariant(); foreach (PlayerInfo item in list) { string text3 = item.Name.ToLowerInvariant(); if (item.HostId == text) { dictionary[item.ZDOID] = item; } else if (text3 == text2) { dictionary[item.ZDOID] = item; } else if (text2[0] == '*' && text2[text2.Length - 1] == '*' && text3.Contains(text2.Substring(1, text2.Length - 2))) { dictionary[item.ZDOID] = item; } else if (text2[0] == '*' && item.Name.EndsWith(text2.Substring(1), StringComparison.OrdinalIgnoreCase)) { dictionary[item.ZDOID] = item; } else if (text2[text2.Length - 1] == '*' && item.Name.StartsWith(text2.Substring(0, text2.Length - 1), StringComparison.OrdinalIgnoreCase)) { dictionary[item.ZDOID] = item; } } } Dictionary.ValueCollection values = dictionary.Values; List list3 = new List(values.Count); list3.AddRange(values); if (list3.Count == 0) { throw new InvalidOperationException("No target player found with id/name '" + string.Join(",", args) + "'."); } return list3; } } public class Hovered { public ZNetView Obj; public int Index; public Hovered(ZNetView obj, int index) { Obj = obj; Index = index; base..ctor(); } } public static class Selector { private static KeyValuePair RaftParent = ZDO.GetHashZDOID("MBParent"); public static bool IsValid(ZNetView view) { if (Object.op_Implicit((Object)(object)view)) { return IsValid(view.GetZDO()); } return false; } public static bool IsValid(ZDO zdo) { if (zdo != null) { return zdo.IsValid(); } return false; } public static ZNetView? GetHovered(float range, string[] included, string[] excluded) { return GetHovered(range, included, new HashSet(), excluded); } public static ZNetView? GetHovered(float range, string[] included, HashSet types, string[] excluded) { return GetHovered(Player.m_localPlayer, range, included, types, excluded)?.Obj; } public static int GetPrefabFromHit(RaycastHit hit) { return ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent().GetZDO().GetPrefab(); } public static Hovered? GetHovered(Player obj, float maxDistance, string[] included, string[] excluded, bool allowOtherPlayers = false) { return GetHovered(obj, maxDistance, included, new HashSet(), excluded, allowOtherPlayers); } public static Hovered? GetHovered(Player obj, float maxDistance, string[] included, HashSet types, string[] excluded, bool allowOtherPlayers = false) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) allowOtherPlayers |= included.Contains("Player"); HashSet allPrefabs = GetAllPrefabs(included); if (included.Length != 0 && allPrefabs.Count == 0) { throw new InvalidOperationException("No valid prefabs found."); } HashSet allPrefabs2 = GetAllPrefabs(excluded); float num = Math.Max(maxDistance + 5f, 50f); int mask = LayerMask.GetMask(new string[11] { "item", "piece", "piece_nonsolid", "Default", "static_solid", "Default_small", "character", "character_net", "terrain", "vehicle", "character_trigger" }); RaycastHit[] array = Physics.RaycastAll(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, num, mask); Array.Sort(array, (RaycastHit x, RaycastHit y) => ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance)); RaycastHit[] array2 = array; MineRock5 val2 = default(MineRock5); MineRock val3 = default(MineRock); for (int i = 0; i < array2.Length; i++) { RaycastHit val = array2[i]; if (Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)obj).m_eye.position) >= maxDistance) { continue; } ZNetView componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent(); if (!IsValid(componentInParent) || (allPrefabs.Count > 0 && !allPrefabs.Contains(componentInParent.GetZDO().GetPrefab())) || allPrefabs2.Contains(componentInParent.GetZDO().GetPrefab()) || Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponent())) { continue; } Player componentInChildren = ((Component)componentInParent).GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)(object)obj || (!allowOtherPlayers && Object.op_Implicit((Object)(object)componentInChildren)) || (types.Count > 0 && !ComponentInfo.HasComponent(componentInParent, types))) { continue; } int index = -1; if (((Component)componentInParent).TryGetComponent(ref val2)) { index = val2.GetAreaIndex(((RaycastHit)(ref val)).collider); } if (((Component)componentInParent).TryGetComponent(ref val3)) { index = val3.GetAreaIndex(((RaycastHit)(ref val)).collider); } Room componentInParent2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent(); if (Object.op_Implicit((Object)(object)componentInParent2)) { Transform transform = ((Component)componentInParent).transform; for (int j = 0; j < transform.childCount; j++) { if ((Object)(object)((Component)transform.GetChild(j)).gameObject == (Object)(object)((Component)componentInParent2).gameObject) { index = j; break; } } } return new Hovered(componentInParent, index); } return null; } private static float GetX(float x, float y, float angle) { return Mathf.Cos(angle) * x - Mathf.Sin(angle) * y; } private static float GetY(float x, float y, float angle) { return Mathf.Sin(angle) * x + Mathf.Cos(angle) * y; } public static bool Within(Vector3 position, Vector3 center, float angle, Range width, Range depth, float height) { //IL_0000: 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) //IL_000d: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) float x = position.x - center.x; float y = position.z - center.z; float x2 = GetX(x, y, angle); float y2 = GetY(x, y, angle); if (!WithinHeight(position, center, height)) { return false; } return Helper.Within(width, depth, Mathf.Abs(x2), Mathf.Abs(y2)); } public static bool Within(Vector3 position, Vector3 center, Range radius, float height) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) if (!WithinHeight(position, center, height)) { return false; } return Helper.Within(radius, Utils.DistanceXZ(position, center)); } private static bool WithinHeight(Vector3 position, Vector3 center, float height) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) float y = center.y; float y2 = position.y; if (Helper.IsZero(height)) { return Mathf.Abs(y2 - y) <= 1000f; } float num = Mathf.Min(y, y + height); float num2 = Mathf.Max(y, y + height); if (y2 >= num) { return y2 <= num2; } return false; } private static bool IsIncluded(string id, string name) { if (id.StartsWith("*", StringComparison.Ordinal) && id.EndsWith("*", StringComparison.Ordinal)) { return name.Contains(id.Substring(1, id.Length - 3)); } if (id.StartsWith("*", StringComparison.Ordinal)) { return name.EndsWith(id.Substring(1), StringComparison.Ordinal); } if (id.EndsWith("*", StringComparison.Ordinal)) { return name.StartsWith(id.Substring(0, id.Length - 2), StringComparison.Ordinal); } return id == name; } public static HashSet GetPrefabs(string[] ids) { if (ids.Length == 0) { return GetSafePrefabs(""); } HashSet hashSet = new HashSet(); foreach (string id in ids) { hashSet.UnionWith(GetSafePrefabs(id)); } return hashSet; } public static HashSet GetAllPrefabs(string[] ids) { if (ids.Length == 0) { return new HashSet(); } HashSet hashSet = new HashSet(); foreach (string id in ids) { hashSet.UnionWith(GetAllPrefabs(id)); } return hashSet; } private static HashSet GetSafePrefabs(string id) { string id2 = id; id2 = id2.ToLower(); IEnumerable source = ZNetScene.instance.m_namedPrefabs.Values; if (id2 != "player") { source = source.Where((GameObject prefab) => ((Object)prefab).name != "Player"); } source = ((id2 == "*" || id2 == "") ? source.Where((GameObject prefab) => !((Object)prefab).name.StartsWith("_", StringComparison.Ordinal)) : ((!id2.Contains("*")) ? source.Where((GameObject prefab) => ((Object)prefab).name.ToLower() == id2) : source.Where((GameObject prefab) => IsIncluded(id2, ((Object)prefab).name.ToLower())))); HashSet hashSet = new HashSet(); foreach (int item in source.Select((GameObject prefab) => StringExtensionMethods.GetStableHashCode(((Object)prefab).name))) { hashSet.Add(item); } return hashSet; } private static HashSet GetAllPrefabs(string id) { string id2 = id; id2 = id2.ToLower(); IEnumerable source = ZNetScene.instance.m_namedPrefabs.Values; if (!(id2 == "*") && !(id2 == "")) { source = ((!id2.Contains("*")) ? source.Where((GameObject prefab) => ((Object)prefab).name.ToLower() == id2) : source.Where((GameObject prefab) => IsIncluded(id2, ((Object)prefab).name.ToLower()))); } HashSet hashSet = new HashSet(); foreach (int item in source.Select((GameObject prefab) => StringExtensionMethods.GetStableHashCode(((Object)prefab).name))) { hashSet.Add(item); } return hashSet; } public static ZNetView[] GetNearby(string[] included, HashSet types, string[] excluded, Vector3 center, Range radius, float height) { //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) Range radius2 = radius; HashSet prefabs = GetPrefabs(included); if (included.Length != 0 && prefabs.Count == 0) { throw new InvalidOperationException("No valid prefabs found."); } HashSet allPrefabs = GetAllPrefabs(excluded); return GetNearby(prefabs, types, allPrefabs, checker); bool checker(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Within(pos, center, radius2, height); } } public static ZNetView[] GetNearby(string[] included, HashSet types, string[] excluded, Vector3 center, float angle, Range width, Range depth, float height) { //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) Range width2 = width; Range depth2 = depth; HashSet prefabs = GetPrefabs(included); if (included.Length != 0 && prefabs.Count == 0) { throw new InvalidOperationException("No valid prefabs found."); } HashSet allPrefabs = GetAllPrefabs(excluded); return GetNearby(prefabs, types, allPrefabs, checker); bool checker(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Within(pos, center, angle, width2, depth2, height); } } public static ZNetView[] GetNearby(HashSet included, HashSet types, HashSet excluded, Func checker) { HashSet included2 = included; HashSet excluded2 = excluded; Func checker2 = checker; _ = ZNetScene.instance; IEnumerable source = ZNetScene.instance.m_instances.Values.Where(IsValid); if (included2.Count > 0) { source = source.Where((ZNetView view) => included2.Contains(view.GetZDO().GetPrefab())); } if (excluded2.Count > 0) { source = source.Where((ZNetView view) => !excluded2.Contains(view.GetZDO().GetPrefab())); } source = source.Where((ZNetView view) => checker2(view.GetZDO().GetPosition())); if (types.Count > 0) { source = ComponentInfo.HaveComponent(source, types); } ZNetView[] array = source.ToArray(); if (array.Length == 0) { throw new InvalidOperationException("Nothing is nearby."); } return array; } public static ZNetView[] GetConnectedRaft(ZNetView baseView, HashSet included, HashSet excluded) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) HashSet included2 = included; HashSet excluded2 = excluded; ZDOID id = baseView.GetZDO().GetZDOID(RaftParent); IEnumerable source = ZNetScene.instance.m_instances.Values.Where(IsValid); if (included2.Count > 0) { source = source.Where((ZNetView view) => included2.Contains(view.GetZDO().GetPrefab())); } if (excluded2.Count > 0) { source = source.Where((ZNetView view) => !excluded2.Contains(view.GetZDO().GetPrefab())); } source = source.Where((ZNetView view) => view.GetZDO().m_uid == id || view.GetZDO().GetZDOID(RaftParent) == id); List list = new List(); list.AddRange(source); return list.ToArray(); } public static ZNetView[] GetConnected(ZNetView baseView, string[] take, string[] include, string[] exclude) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) HashSet allPrefabs = GetAllPrefabs(take); HashSet allPrefabs2 = GetAllPrefabs(include); HashSet allPrefabs3 = GetAllPrefabs(exclude); if (baseView.GetZDO().GetZDOID(RaftParent) != ZDOID.None) { return GetConnectedRaft(baseView, allPrefabs2, allPrefabs3); } WearNTear item = ((Component)baseView).GetComponent() ?? throw new InvalidOperationException("Connected doesn't work for this object."); List list = new List(); int prefab = baseView.GetZDO().GetPrefab(); if (allPrefabs.Contains(prefab)) { list.Add(baseView); } else if (allPrefabs.Count == 0 && !allPrefabs3.Contains(prefab) && (allPrefabs2.Count == 0 || allPrefabs2.Contains(prefab))) { list.Add(baseView); } HashSet hashSet = new HashSet { baseView }; Queue queue = new Queue(); queue.Enqueue(item); while (queue.Count > 0) { WearNTear val = queue.Dequeue(); if (val.m_colliders == null) { val.SetupColliders(); } foreach (BoundData bound in val.m_bounds) { int num = Physics.OverlapBoxNonAlloc(bound.m_pos, bound.m_size, WearNTear.s_tempColliders, bound.m_rot, WearNTear.s_rayMask); for (int i = 0; i < num; i++) { Collider val2 = WearNTear.s_tempColliders[i]; if (val2.isTrigger || (Object)(object)val2.attachedRigidbody != (Object)null || val.m_colliders.Contains(val2)) { continue; } WearNTear componentInParent = ((Component)val2).GetComponentInParent(); if (!Object.op_Implicit((Object)(object)componentInParent) || !IsValid(componentInParent.m_nview) || hashSet.Contains(componentInParent.m_nview)) { continue; } hashSet.Add(componentInParent.m_nview); prefab = componentInParent.m_nview.GetZDO().GetPrefab(); if (allPrefabs.Contains(prefab)) { list.Add(componentInParent.m_nview); } if ((allPrefabs2.Count <= 0 || allPrefabs2.Contains(prefab)) && !allPrefabs3.Contains(prefab)) { if (allPrefabs.Count == 0) { list.Add(componentInParent.m_nview); } queue.Enqueue(componentInParent); } } } } return list.ToArray(); } public static ZNetView[] GetConnected(ZNetView baseView, string[] included, string[] excluded) { return GetConnected(baseView, Array.Empty(), included, excluded); } } } namespace EWP { public static class Api { public const string GUID = "expand_world_prefabs"; private static bool isSetup; private static MethodInfo? registerGroupHandlerMethod; private static void SetupIfNeeded() { if (!isSetup) { isSetup = true; if (Chainloader.PluginInfos.TryGetValue("expand_world_prefabs", out var value)) { Setup(((object)value.Instance).GetType().Assembly); } } } private static void Setup(Assembly assembly) { if (!(assembly == null)) { Type type = assembly.GetType("ExpandWorld.Prefab.Api"); if (!(type == null)) { registerGroupHandlerMethod = AccessTools.Method(type, "RegisterGroupHandler", new Type[2] { typeof(string), typeof(Func) }, (Type[])null); } } } public static void RegisterGroupHandler(string key, Func handler) { SetupIfNeeded(); registerGroupHandlerMethod?.Invoke(null, new object[2] { key, handler }); } } } namespace ServerDevcommands { public class AddStatusCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index) { return index switch { 0 => ParameterInfo.StatusEffects, 1 => ParameterInfo.Create("Effect duration in seconds."), 2 => ParameterInfo.Create("Effect intensity."), _ => ParameterInfo.None, }; } internal void <.ctor>b__0_1(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing status name"); Player player = Helper.GetPlayer(); int stableHashCode = StringExtensionMethods.GetStableHashCode(args[1]); ((Character)player).GetSEMan().AddStatusEffect(stableHashCode, true, 0, 0f); StatusEffect statusEffect = ((Character)player).GetSEMan().GetStatusEffect(stableHashCode); if ((Object)(object)statusEffect == (Object)null) { return; } float ttl = default(float); if (args.TryParameterFloat(2, ref ttl)) { statusEffect.m_ttl = ttl; } float num = default(float); if (!args.TryParameterFloat(3, ref num)) { return; } SE_Shield val = (SE_Shield)(object)((statusEffect is SE_Shield) ? statusEffect : null); if (val != null) { val.m_absorbDamage = num; } SE_Burning val2 = (SE_Burning)(object)((statusEffect is SE_Burning) ? statusEffect : null); if (val2 != null) { if (args[1] == "Burning") { val2.m_fireDamageLeft = 0f; val2.AddFireDamage(num); } else { val2.m_spiritDamageLeft = 0f; val2.AddSpiritDamage(num); } } SE_Poison val3 = (SE_Poison)(object)((statusEffect is SE_Poison) ? statusEffect : null); if (val3 != null) { val3.m_damageLeft = num; val3.m_damagePerHit = num / statusEffect.m_ttl * val3.m_damageInterval; } } } public AddStatusCommand() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("addstatus", (int index) => index switch { 0 => ParameterInfo.StatusEffects, 1 => ParameterInfo.Create("Effect duration in seconds."), 2 => ParameterInfo.Create("Effect intensity."), _ => ParameterInfo.None, }); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing status name"); Player player = Helper.GetPlayer(); int stableHashCode = StringExtensionMethods.GetStableHashCode(args[1]); ((Character)player).GetSEMan().AddStatusEffect(stableHashCode, true, 0, 0f); StatusEffect statusEffect = ((Character)player).GetSEMan().GetStatusEffect(stableHashCode); if (!((Object)(object)statusEffect == (Object)null)) { float ttl = default(float); if (args.TryParameterFloat(2, ref ttl)) { statusEffect.m_ttl = ttl; } float num = default(float); if (args.TryParameterFloat(3, ref num)) { SE_Shield val2 = (SE_Shield)(object)((statusEffect is SE_Shield) ? statusEffect : null); if (val2 != null) { val2.m_absorbDamage = num; } SE_Burning val3 = (SE_Burning)(object)((statusEffect is SE_Burning) ? statusEffect : null); if (val3 != null) { if (args[1] == "Burning") { val3.m_fireDamageLeft = 0f; val3.AddFireDamage(num); } else { val3.m_spiritDamageLeft = 0f; val3.AddSpiritDamage(num); } } SE_Poison val4 = (SE_Poison)(object)((statusEffect is SE_Poison) ? statusEffect : null); if (val4 != null) { val4.m_damageLeft = num; val4.m_damagePerHit = num / statusEffect.m_ttl * val4.m_damageInterval; } } } }; <>c.<>9__0_1 = val; obj = (object)val; } Helper.Command("addstatus", "[name] [duration] [intensity] - Adds a status effect.", (ConsoleEvent)obj); } } public class AliasCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func <>9__1_2; public static ConsoleEvent <>9__1_0; public static Func> <>9__1_1; internal void b__0_0(ConsoleEventArgs args) { } internal void <.ctor>b__1_0(ConsoleEventArgs args) { if (args.Length < 2) { args.Context.AddString(string.Join("\n", Settings.AliasKeys.Select((string key) => key + " -> " + Settings.GetAliasValue(key)))); } else if (args.Length < 3) { Settings.RemoveAlias(args[1]); if (Terminal.commands.ContainsKey(args[1])) { Terminal.commands.Remove(args[1]); } args.Context.updateCommandList(); AliasManager.ToBeSaved = true; } else { string value = string.Join(" ", args.Args.Skip(2)); Settings.AddAlias(args[1], value); AddCommand(args[1], value); args.Context.updateCommandList(); AliasManager.ToBeSaved = true; } } internal string <.ctor>b__1_2(string key) { return key + " -> " + Settings.GetAliasValue(key); } internal List <.ctor>b__1_1(int index, int subIndex) { if (index == 0) { return ParameterInfo.Create("Name of the alias."); } return ParameterInfo.None; } } public static void AddCommand(string key, string value) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown string text = Aliasing.Plain(value); string key2 = text.Split(new char[1] { ' ' }).First(); if (Terminal.commands.TryGetValue(key2, out var value2)) { new ConsoleCommand(key, text, value2.action, value2.IsCheat, value2.IsNetwork, value2.OnlyServer, value2.IsSecret, value2.AllowInDevBuild, value2.m_tabOptionsFetcher, false, false, false); return; } object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate { }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand(key, text, (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } public AliasCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length < 2) { args.Context.AddString(string.Join("\n", Settings.AliasKeys.Select((string key) => key + " -> " + Settings.GetAliasValue(key)))); } else if (args.Length < 3) { Settings.RemoveAlias(args[1]); if (Terminal.commands.ContainsKey(args[1])) { Terminal.commands.Remove(args[1]); } args.Context.updateCommandList(); AliasManager.ToBeSaved = true; } else { string value = string.Join(" ", args.Args.Skip(2)); Settings.AddAlias(args[1], value); AddCommand(args[1], value); args.Context.updateCommandList(); AliasManager.ToBeSaved = true; } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("alias", "[name] [command] - Sets a command alias.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("alias", (int index, int subIndex) => (index == 0) ? ParameterInfo.Create("Name of the alias.") : ParameterInfo.None); AutoComplete.Offsets["alias"] = 1; } } [HarmonyPatch] public class BindCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleOptionsFetcher <>9__0_1; public static Func> <>9__0_2; public static Func> <>9__0_7; public static ConsoleEvent <>9__0_3; public static Func> <>9__0_4; public static ConsoleEvent <>9__0_5; public static ConsoleEvent <>9__0_6; internal void <.ctor>b__0_0(ConsoleEventArgs args) { if (args.Length >= 2) { BindManager.AddBind(args[1], string.Join(" ", args.Args.Skip(2))); } } internal List <.ctor>b__0_1() { return ParameterInfo.KeyCodes; } internal List <.ctor>b__0_2(int index, int subIndex) { if (index == 0 && subIndex == 0) { return ParameterInfo.KeyCodes; } if (index == 0 && subIndex == 1) { return ParameterInfo.KeyCodesWithNegative; } return ParameterInfo.None; } internal List <.ctor>b__0_7(int index) { return ParameterInfo.KeyCodesWithNegative; } internal void <.ctor>b__0_3(ConsoleEventArgs args) { if (args.Length >= 2) { BindManager.RemoveBind(args[1]); } } internal List <.ctor>b__0_4(int index) { if (index == 0) { return ParameterInfo.KeyCodes; } return ParameterInfo.None; } internal void <.ctor>b__0_5(ConsoleEventArgs args) { BindManager.PrintBinds(args.Context); } internal void <.ctor>b__0_6(ConsoleEventArgs args) { BindManager.ClearBinds(); } } public BindCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length >= 2) { BindManager.AddBind(args[1], string.Join(" ", args.Args.Skip(2))); } }; <>c.<>9__0_0 = val; obj = (object)val; } object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleOptionsFetcher val2 = () => ParameterInfo.KeyCodes; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("bind", "[keycode,modifier1,modifier2,...] [command] [parameters] - Binds a key (with modifier keys) to a command.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false); AutoComplete.Register("bind", delegate(int index, int subIndex) { if (index == 0 && subIndex == 0) { return ParameterInfo.KeyCodes; } return (index == 0 && subIndex == 1) ? ParameterInfo.KeyCodesWithNegative : ParameterInfo.None; }, new Dictionary>> { { "keys", (int index) => ParameterInfo.KeyCodesWithNegative } }); AutoComplete.Offsets["bind"] = 1; object obj3 = <>c.<>9__0_3; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { if (args.Length >= 2) { BindManager.RemoveBind(args[1]); } }; <>c.<>9__0_3 = val3; obj3 = (object)val3; } new ConsoleCommand("unbind", "[keycode] - Clears binds from a key.", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("unbind", (int index) => (index == 0) ? ParameterInfo.KeyCodes : ParameterInfo.None); object obj4 = <>c.<>9__0_5; if (obj4 == null) { ConsoleEvent val4 = delegate(ConsoleEventArgs args) { BindManager.PrintBinds(args.Context); }; <>c.<>9__0_5 = val4; obj4 = (object)val4; } new ConsoleCommand("printbinds", "Prints all key binds.", (ConsoleEvent)obj4, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.RegisterEmpty("printbinds"); object obj5 = <>c.<>9__0_6; if (obj5 == null) { ConsoleEvent val5 = delegate { BindManager.ClearBinds(); }; <>c.<>9__0_6 = val5; obj5 = (object)val5; } new ConsoleCommand("resetbinds", "Removes all custom key binds.", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.RegisterEmpty("resetbinds"); } [HarmonyPatch(typeof(Chat), "Update")] [HarmonyTranspiler] private static IEnumerable DisableDefaultBindExecution(IEnumerable instructions) { //IL_0002: 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_0034: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(Chat), "m_wasFocused"), (string)null) }).Advance(4).Insert((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Pop, (object)null), new CodeInstruction(OpCodes.Ldc_I4_1, (object)null) }) .InstructionEnumeration(); } [HarmonyPatch(typeof(Chat), "Update")] [HarmonyPostfix] private static void ExecuteBestBinds(Chat __instance) { if (((TMP_InputField)((Terminal)__instance).m_input).isFocused || (Object.op_Implicit((Object)(object)Console.instance) && ((Component)((Terminal)Console.instance).m_chatWindow).gameObject.activeInHierarchy)) { return; } foreach (CommandBind bestKeyCommand in BindManager.GetBestKeyCommands()) { bestKeyCommand.Executed = true; if (!bestKeyCommand.WasExecuted && !(bestKeyCommand.Command == "")) { ((Terminal)__instance).TryRunCommand(bestKeyCommand.Command, true, true); } } foreach (CommandBind offBind in BindManager.GetOffBinds()) { offBind.WasExecuted = false; if (!(offBind.OffCommand == "")) { ((Terminal)__instance).TryRunCommand(offBind.OffCommand, true, true); } } } public static void SetMode(string mode) { BindManager.SetMode(mode); } } public class BroadcastCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__2_0; public static Func> <>9__2_1; public static Func> <>9__2_4; public static Func> <>9__2_5; public static Func> <>9__2_6; public static Func> <>9__2_7; public static ConsoleEvent <>9__2_2; public static Func> <>9__2_3; public static Func> <>9__2_8; public static Func> <>9__2_9; public static Func> <>9__2_10; public static Func> <>9__2_11; internal void <.ctor>b__2_0(ConsoleEventArgs args) { //IL_002f: 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) Helper.ArgsCheck(args, 2, "Missing the center/side parameter."); Helper.ArgsCheck(args, 3, "Missing the message"); MessageType val = (MessageType)((args[2] == "side") ? 1 : 2); string text = string.Join(" ", args.Args.Skip(2)); MessageHud.instance.MessageAll(val, text); } internal List <.ctor>b__2_1(int index) { if (index == 0) { return Types; } return Modifiers; } internal List <.ctor>b__2_4(int index) { return ParameterInfo.Create("Bolds the text."); } internal List <.ctor>b__2_5(int index) { return ParameterInfo.Create("Italics the text."); } internal List <.ctor>b__2_6(int index) { return ParameterInfo.Colors; } internal List <.ctor>b__2_7(int index) { return ParameterInfo.Create("Size in pixels."); } internal void <.ctor>b__2_2(ConsoleEventArgs args) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected I4, but got Unknown Helper.ArgsCheck(args, 2, "Missing the player parameter."); Helper.ArgsCheck(args, 3, "Missing the center/side parameter."); Helper.ArgsCheck(args, 4, "Missing the message"); List list = PlayerInfo.FindPlayers(Parse.Split(args[1])); if (list.Count == 0) { throw new Exception("Player " + args[1] + " not found."); } MessageType val = (MessageType)((args[3] == "side") ? 1 : 2); string text = string.Join(" ", args.Args.Skip(3)); foreach (PlayerInfo item in list) { ZRoutedRpc.instance.InvokeRoutedRPC(item.PeerId, "ShowMessage", new object[2] { (int)val, text }); } } internal List <.ctor>b__2_3(int index) { return index switch { 0 => ParameterInfo.PlayerNames, 1 => Types, _ => Modifiers, }; } internal List <.ctor>b__2_8(int index) { return ParameterInfo.Create("Bolds the text."); } internal List <.ctor>b__2_9(int index) { return ParameterInfo.Create("Italics the text."); } internal List <.ctor>b__2_10(int index) { return ParameterInfo.Colors; } internal List <.ctor>b__2_11(int index) { return ParameterInfo.Create("Size in pixels."); } } private static readonly List Types = new List(2) { "center", "side" }; private static readonly List Modifiers = new List(4) { "c.<>9__2_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_002f: 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) Helper.ArgsCheck(args, 2, "Missing the center/side parameter."); Helper.ArgsCheck(args, 3, "Missing the message"); MessageType val4 = (MessageType)((args[2] == "side") ? 1 : 2); string text2 = string.Join(" ", args.Args.Skip(2)); MessageHud.instance.MessageAll(val4, text2); }; <>c.<>9__2_0 = val; obj = (object)val; } Helper.Command("broadcast", "[center/side] [message] - Broadcasts a message.", (ConsoleEvent)obj); AutoComplete.Register("broadcast", (int index) => (index == 0) ? Types : Modifiers, new Dictionary>> { { " ParameterInfo.Create("Bolds the text.") }, { " ParameterInfo.Create("Italics the text.") }, { " ParameterInfo.Colors }, { " ParameterInfo.Create("Size in pixels.") } }); object obj2 = <>c.<>9__2_2; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected I4, but got Unknown Helper.ArgsCheck(args, 2, "Missing the player parameter."); Helper.ArgsCheck(args, 3, "Missing the center/side parameter."); Helper.ArgsCheck(args, 4, "Missing the message"); List list = PlayerInfo.FindPlayers(Parse.Split(args[1])); if (list.Count == 0) { throw new Exception("Player " + args[1] + " not found."); } MessageType val3 = (MessageType)((args[3] == "side") ? 1 : 2); string text = string.Join(" ", args.Args.Skip(3)); foreach (PlayerInfo item in list) { ZRoutedRpc.instance.InvokeRoutedRPC(item.PeerId, "ShowMessage", new object[2] { (int)val3, text }); } }; <>c.<>9__2_2 = val2; obj2 = (object)val2; } Helper.Command("message", "[player] [center/side] [message] - Sends a message to a player.", (ConsoleEvent)obj2); AutoComplete.Register("message", (int index) => index switch { 0 => ParameterInfo.PlayerNames, 1 => Types, _ => Modifiers, }, new Dictionary>> { { " ParameterInfo.Create("Bolds the text.") }, { " ParameterInfo.Create("Italics the text.") }, { " ParameterInfo.Colors }, { " ParameterInfo.Create("Size in pixels.") } }); } } public class CalmCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index) { if (index == 0) { return ParameterInfo.Create("Radius", "a positive integer"); } return ParameterInfo.None; } internal void <.ctor>b__0_1(ConsoleEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Helper.GetPlayer()).transform.position; float num = args.TryParameterFloat(1, 20f); int num2 = 0; foreach (BaseAI instance in BaseAI.Instances) { BaseAI val = instance; if (Vector3.Distance(position, ((Component)val).transform.position) <= num && (val.IsAlerted() || val.IsAggravated() || val.HaveTarget())) { val.m_nview.ClaimOwnership(); val.SetAggravated(false, (AggravatedReason)1); val.SetAlerted(false); val.SetTargetInfo(ZDOID.None); MonsterAI val2 = (MonsterAI)(object)((val is MonsterAI) ? val : null); if (val2 != null) { val2.m_targetCreature = null; val2.m_targetStatic = null; } AnimalAI val3 = (AnimalAI)(object)((val is AnimalAI) ? val : null); if (val3 != null) { val3.m_target = null; } num2++; } } Helper.AddMessage(args.Context, $"Calmed {num2} creatures."); } } public CalmCommand() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("calm", (int index) => (index == 0) ? ParameterInfo.Create("Radius", "a positive integer") : ParameterInfo.None); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Helper.GetPlayer()).transform.position; float num = args.TryParameterFloat(1, 20f); int num2 = 0; foreach (BaseAI instance in BaseAI.Instances) { BaseAI val2 = instance; if (Vector3.Distance(position, ((Component)val2).transform.position) <= num && (val2.IsAlerted() || val2.IsAggravated() || val2.HaveTarget())) { val2.m_nview.ClaimOwnership(); val2.SetAggravated(false, (AggravatedReason)1); val2.SetAlerted(false); val2.SetTargetInfo(ZDOID.None); MonsterAI val3 = (MonsterAI)(object)((val2 is MonsterAI) ? val2 : null); if (val3 != null) { val3.m_targetCreature = null; val3.m_targetStatic = null; } AnimalAI val4 = (AnimalAI)(object)((val2 is AnimalAI) ? val2 : null); if (val4 != null) { val4.m_target = null; } num2++; } } Helper.AddMessage(args.Context, $"Calmed {num2} creatures."); }; <>c.<>9__0_1 = val; obj = (object)val; } Helper.Command("calm", "[radius=20] - Calms creatures within given meters.", (ConsoleEvent)obj); } } public class ConfigCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__1_0; public static ConsoleOptionsFetcher <>9__1_1; internal List b__0_0(int index) { if (index == 0) { return Settings.Options; } return ParameterInfo.Create("Value"); } internal void <.ctor>b__1_0(ConsoleEventArgs args) { if (args.Length >= 2) { if (args.Length == 2) { Settings.UpdateValue(args.Context, args[1], ""); } else { Settings.UpdateValue(args.Context, args[1], string.Join(" ", args.Args.Skip(2))); } } } internal List <.ctor>b__1_1() { return Settings.Options; } } private void RegisterAutoComplete(string command) { AutoComplete.Register(command, (int index) => (index == 0) ? Settings.Options : ParameterInfo.Create("Value")); } public ConfigCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length >= 2) { if (args.Length == 2) { Settings.UpdateValue(args.Context, args[1], ""); } else { Settings.UpdateValue(args.Context, args[1], string.Join(" ", args.Args.Skip(2))); } } }; <>c.<>9__1_0 = val; obj = (object)val; } object obj2 = <>c.<>9__1_1; if (obj2 == null) { ConsoleOptionsFetcher val2 = () => Settings.Options; <>c.<>9__1_1 = val2; obj2 = (object)val2; } new ConsoleCommand("dev_config", "[key] [value] - Toggles or sets config value.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false); RegisterAutoComplete("dev_config"); } } public static class DefaultAutoComplete { public static void Register() { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown AutoComplete.RegisterEmpty("aggravate"); AutoComplete.RegisterEmpty("challenge"); AutoComplete.RegisterEmpty("cheers"); AutoComplete.RegisterEmpty("clear"); AutoComplete.Register("fov ", (int index) => (index == 0) ? ParameterInfo.Create("Amount", "a positive number") : ParameterInfo.None); AutoComplete.RegisterEmpty("hidebetatext"); AutoComplete.Register("help ", (int index) => index switch { 0 => ParameterInfo.Create("Page", "number"), 1 => ParameterInfo.Create("Page size", "a positive integer (default is 5)"), _ => ParameterInfo.None, }); AutoComplete.RegisterEmpty("info"); AutoComplete.Register("lodbias", (int index) => (index == 0) ? ParameterInfo.Create("Amount", "a positive number") : ParameterInfo.None); AutoComplete.RegisterEmpty("nonono"); AutoComplete.RegisterEmpty("opterrain"); AutoComplete.RegisterEmpty("point"); AutoComplete.RegisterEmpty("ping"); ConsoleOptionsFetcher originalFetcher = Terminal.commands["raiseskill"].m_tabOptionsFetcher; Terminal.commands["raiseskill"].m_tabOptionsFetcher = new ConsoleOptionsFetcher(newFetcher); AutoComplete.Register("raiseskill", delegate(int index) { ConsoleOptionsFetcher tabOptionsFetcher = Terminal.commands["raiseskill"].m_tabOptionsFetcher; return index switch { 0 => tabOptionsFetcher.Invoke(), 1 => ParameterInfo.Create("Amount of skill levels gained or lost (if negative)."), _ => ParameterInfo.None, }; }); AutoComplete.RegisterEmpty("resetsharedmap"); AutoComplete.RegisterEmpty("resetspawn"); AutoComplete.RegisterEmpty("respawn"); AutoComplete.Register("s", (int index) => ParameterInfo.Create("Message")); AutoComplete.Register("say", (int index) => ParameterInfo.Create("Message")); AutoComplete.RegisterEmpty("restartparty"); AutoComplete.RegisterEmpty("sit"); AutoComplete.RegisterEmpty("thumbsup"); AutoComplete.RegisterEmpty("tutorialreset"); AutoComplete.RegisterEmpty("tutorialtoggle"); AutoComplete.RegisterEmpty("wave"); AutoComplete.Register("W", (int index) => (index == 0) ? ParameterInfo.PlayerNames : ParameterInfo.Create("Message")); AutoComplete.RegisterAdmin("ban"); AutoComplete.RegisterEmpty("banned"); AutoComplete.RegisterAdmin("kick"); AutoComplete.RegisterEmpty("save"); AutoComplete.RegisterAdmin("unban"); AutoComplete.Register("beard", (int index) => (index == 0) ? ParameterInfo.Beards : ParameterInfo.None); AutoComplete.RegisterEmpty("clearstatus"); AutoComplete.RegisterEmpty("dpsdebug"); AutoComplete.RegisterEmpty("exploremap"); AutoComplete.Register("ffsmooth", (int index) => (index == 0) ? ParameterInfo.Create("0 = normal, 1 = add smooth movement") : ParameterInfo.None); AutoComplete.RegisterEmpty("fly"); AutoComplete.RegisterEmpty("freefly"); AutoComplete.Register("forcedelete", (int index) => index switch { 0 => ParameterInfo.Create("Radius", "in meters (from 0.0 to 50.0, default is 5.0)."), 1 => ParameterInfo.ObjectIds, _ => ParameterInfo.None, }); AutoComplete.RegisterEmpty("gc"); AutoComplete.RegisterEmpty("ghost"); AutoComplete.RegisterEmpty("god"); AutoComplete.Register("hair", (int index) => (index == 0) ? ParameterInfo.Hairs : ParameterInfo.None); AutoComplete.RegisterEmpty("heal"); AutoComplete.Register("itemset", (int index) => index switch { 0 => Terminal.commands["itemset"].m_tabOptionsFetcher.Invoke(), 1 => new List(2) { "keep", "clear" }, _ => ParameterInfo.None, }); AutoComplete.RegisterEmpty("killenemycreatures"); AutoComplete.RegisterEmpty("killtame"); AutoComplete.RegisterEmpty("listkeys"); if (Terminal.commands.TryGetValue("listkeys", out var value)) { value.RemoteCommand = false; } AutoComplete.Register("location", (int index) => index switch { 0 => ParameterInfo.LocationIds, 1 => new List(1) { "SAVE" }, _ => ParameterInfo.None, }); AutoComplete.Register("maxfps", (int index) => (index == 0) ? ParameterInfo.Create("Amount", "a positive integer") : ParameterInfo.None); AutoComplete.Register("model", (int index) => (index == 0) ? ParameterInfo.Create("0 = male, 1 = female") : ParameterInfo.None); AutoComplete.RegisterEmpty("nocost"); AutoComplete.RegisterEmpty("noportals"); AutoComplete.Register("players", (int index) => (index == 0) ? ParameterInfo.Create("Amount", "a positive integer (0 disables the override)") : ParameterInfo.None); AutoComplete.RegisterEmpty("printcreatures"); AutoComplete.RegisterEmpty("printseeds"); AutoComplete.RegisterEmpty("printlocations"); AutoComplete.RegisterEmpty("puke"); AutoComplete.RegisterEmpty("removebirds"); AutoComplete.RegisterEmpty("removedrops"); AutoComplete.RegisterEmpty("removefish"); AutoComplete.Register("recall ", (int index) => (index == 0) ? ParameterInfo.PlayerNames : ParameterInfo.None); AutoComplete.RegisterEmpty("resetcharacter"); AutoComplete.RegisterEmpty("resetenv"); AutoComplete.RegisterEmpty("resetwind"); AutoComplete.Register("removekey", (int index) => (index == 0) ? ParameterInfo.GlobalKeys : ParameterInfo.None); AutoComplete.Register("setkey", (int index) => (index == 0) ? ParameterInfo.GlobalKeys : ParameterInfo.None); AutoComplete.RegisterDefault("setpower"); AutoComplete.Register("spawn", delegate(int index) { switch (index) { case 0: return ParameterInfo.ObjectIds; case 1: return ParameterInfo.Create("Amount", "a positive integer (default 1)"); case 2: return ParameterInfo.Create("Level", "a positive integer (default 1)"); default: if (index == 2) { return ParameterInfo.Create("p to automatically pick up items. e to automatically equip items."); } return ParameterInfo.None; } }); AutoComplete.RegisterEmpty("tame"); AutoComplete.Register("test", (int index) => (index == 0) ? new List(1) { "oldcomfort" } : ParameterInfo.None); AutoComplete.RegisterDefault("resetskill"); AutoComplete.RegisterEmpty("time"); AutoComplete.Register("timescale", (int index) => index switch { 0 => ParameterInfo.Create("Multiplier", "sets how fast the time goes (from 0.0 to 3.0). Value 0 can be used to pause the game."), 1 => ParameterInfo.Create("Transition duration", "causes the change to be applied gradually over time (seconds). Default value 0 applies the change instantly."), _ => ParameterInfo.None, }); AutoComplete.Register("tod", (int index) => (index == 0) ? ParameterInfo.Create("Time", "overrides the time of the day (from 0.0 to 1.0, with 0.5 being the mid day). Value -1 removes the override.") : ParameterInfo.None); List newFetcher() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) List list = originalFetcher.Invoke(); SkillType val = (SkillType)999; if (!list.Contains(((object)(SkillType)(ref val)).ToString())) { val = (SkillType)999; list.Add(((object)(SkillType)(ref val)).ToString()); } return list; } } } public class DevcommandsCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__4_0; internal void <.ctor>b__4_0(ConsoleEventArgs args) { if (Terminal.m_cheat) { Set(args.Context, value: false); return; } if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { Set(args.Context, value: true); return; } args.Context.AddString("Authenticating for devcommands..."); Admin.ManualCheck(); } } public static void Set(Terminal terminal, bool value) { terminal.AddString("Devcommands: " + value); Set(value); } public static void EnableAutoFeatures() { if (!Terminal.m_cheat) { return; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && ((Character)localPlayer).m_nview.IsValid()) { if (Settings.AutoGodMode && Settings.IsEnabled(PermissionHash.God, localValue: true)) { localPlayer.SetGodMode(true); } if (Settings.AutoGhostMode && Settings.IsEnabled(PermissionHash.Ghost, localValue: true)) { localPlayer.SetGhostMode(true); } if (Settings.AutoFly && Settings.IsEnabled(PermissionHash.Fly, localValue: true)) { localPlayer.m_debugFly = true; ((Character)localPlayer).m_nview.GetZDO().Set(ZDOVars.s_debugFly, true); } if (Settings.AutoNoCost && Settings.IsEnabled(PermissionHash.NoCost, localValue: true)) { localPlayer.m_noPlacementCost = true; } if (Settings.AutoDebugMode) { Player.m_debugMode = true; } } if (Object.op_Implicit((Object)(object)EnvMan.instance)) { if (Settings.AutoTod != "" && PermissionApi.IsCommandAllowed("tod")) { EnvMan.instance.m_debugTimeOfDay = true; EnvMan.instance.m_debugTime = Mathf.Clamp01(Parse.Float(Settings.AutoTod)); } if (Settings.AutoEnv != "" && PermissionApi.IsCommandAllowed("env")) { EnvMan.instance.m_debugEnv = Settings.AutoEnv; } } } public static void DisableAutoFeatures() { if (Terminal.m_cheat) { return; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && ((Character)localPlayer).m_nview.IsValid()) { if (Settings.AutoDebugMode) { Player.m_debugMode = false; } if (Settings.AutoGodMode) { localPlayer.SetGodMode(false); } if (Settings.AutoGhostMode) { localPlayer.SetGhostMode(false); } if (Settings.AutoFly) { localPlayer.m_debugFly = false; ((Character)localPlayer).m_nview.GetZDO().Set(ZDOVars.s_debugFly, false); } if (Settings.AutoNoCost) { localPlayer.m_noPlacementCost = false; } } if (Object.op_Implicit((Object)(object)EnvMan.instance)) { if (Settings.AutoTod != "") { EnvMan.instance.m_debugTimeOfDay = false; } if (Settings.AutoEnv != "") { EnvMan.instance.m_debugEnv = ""; } } } public static void Set(bool value) { if (Terminal.m_cheat != value) { Gogan.LogEvent("Cheat", "CheatsEnabled", value.ToString(), 0L); } Terminal.m_cheat = value; ((Terminal)Console.instance).updateCommandList(); ((Terminal)Chat.instance).updateCommandList(); DisableAutoFeatures(); EnableAutoFeatures(); if (value && Settings.AutoExecDevOn != "") { ((Terminal)Console.instance).TryRunCommand(Settings.AutoExecDevOn, false, false); } if (!value && Settings.AutoExecDevOff != "") { ((Terminal)Console.instance).TryRunCommand(Settings.AutoExecDevOff, false, false); } } public DevcommandsCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__4_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (Terminal.m_cheat) { Set(args.Context, value: false); } else if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { Set(args.Context, value: true); } else { args.Context.AddString("Authenticating for devcommands..."); Admin.ManualCheck(); } }; <>c.<>9__4_0 = val; obj = (object)val; } new ConsoleCommand("devcommands", "Toggles cheats", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.RegisterEmpty("devcommands"); } } [HarmonyPatch(typeof(Terminal), "IsCheatsEnabled")] public class IsCheatsEnabledWithoutServerCheck { private static bool Postfix(bool result) { if (!result && !Terminal.m_cheat) { ZNet instance = ZNet.instance; if (instance == null) { return false; } return instance.IsDedicated(); } return true; } } [HarmonyPatch(typeof(ConsoleCommand), "IsValid")] public class IsValidWithoutServerCheck { private static bool Postfix(bool result) { if (!result && !Terminal.m_cheat) { ZNet instance = ZNet.instance; if (instance == null) { return false; } return instance.IsDedicated(); } return true; } } [HarmonyPatch(typeof(Terminal), "Awake")] public class AutoCompleteSecrets { private static void Postfix(Terminal __instance) { __instance.m_autoCompleteSecrets = true; } } public class DmgCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__0_2; public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { //IL_00c9: 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) //IL_0085: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing target."); Helper.ArgsCheck(args, 3, "Missing amount."); string text = args.Args[1]; float num = Parse.Float(args.Args[2]); float num2 = Math.Abs(num); string arg = ((num >= 0f) ? " damage" : " healing"); List list = PlayerInfo.FindPlayers(new string[1] { text }); foreach (PlayerInfo item in list) { if (num >= 0f) { HitData val = new HitData { m_damage = { m_damage = num }, m_hitType = (HitType)14 }; ZRoutedRpc.instance.InvokeRoutedRPC(0L, item.ZDOID, "RPC_Damage", new object[1] { val }); } else { ZRoutedRpc.instance.InvokeRoutedRPC(0L, item.ZDOID, "RPC_Heal", new object[2] { num2, true }); } } string text2 = string.Format("{0}{1} applied to: {2}", num2, arg, string.Join(", ", list.Select((PlayerInfo p) => p.Name))); args.Context.AddString(text2); } internal string <.ctor>b__0_2(PlayerInfo p) { return p.Name; } internal List <.ctor>b__0_1(int index) { switch (index) { case 0: { string item = "others"; string item2 = "all"; List playerNames = ParameterInfo.PlayerNames; List list = new List(2 + playerNames.Count); list.Add(item); list.Add(item2); list.AddRange(playerNames); return list; } case 1: return ParameterInfo.Create("Value", "Positive = damage / Negative = healing"); default: return ParameterInfo.None; } } } public DmgCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_00c9: 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) //IL_0085: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing target."); Helper.ArgsCheck(args, 3, "Missing amount."); string text = args.Args[1]; float num = Parse.Float(args.Args[2]); float num2 = Math.Abs(num); string arg = ((num >= 0f) ? " damage" : " healing"); List list2 = PlayerInfo.FindPlayers(new string[1] { text }); foreach (PlayerInfo item3 in list2) { if (num >= 0f) { HitData val2 = new HitData { m_damage = { m_damage = num }, m_hitType = (HitType)14 }; ZRoutedRpc.instance.InvokeRoutedRPC(0L, item3.ZDOID, "RPC_Damage", new object[1] { val2 }); } else { ZRoutedRpc.instance.InvokeRoutedRPC(0L, item3.ZDOID, "RPC_Heal", new object[2] { num2, true }); } } string text2 = string.Format("{0}{1} applied to: {2}", num2, arg, string.Join(", ", list2.Select((PlayerInfo p) => p.Name))); args.Context.AddString(text2); }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("dmg", "[target] [amount] - (Negative values heal the character).", (ConsoleEvent)obj); AutoComplete.Register("dmg", delegate(int index) { switch (index) { case 0: { string item = "others"; string item2 = "all"; List playerNames = ParameterInfo.PlayerNames; List list = new List(2 + playerNames.Count); list.Add(item); list.Add(item2); list.AddRange(playerNames); return list; } case 1: return ParameterInfo.Create("Value", "Positive = damage / Negative = healing"); default: return ParameterInfo.None; } }); } } public class EnvCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { <>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0(); EnvMan instance = EnvMan.instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } if (args.Length < 2) { Helper.AddMessage(args.Context, $"Environment: {instance.GetCurrentEnvironment()}."); return; } CS$<>8__locals0.text = string.Join(" ", args.Args, 1, args.Args.Length - 1); if (!EnvMan.instance.m_environments.Any((EnvSetup env) => env.m_name == CS$<>8__locals0.text)) { CS$<>8__locals0.text = CS$<>8__locals0.text.Replace("_", " "); } Helper.AddMessage(args.Context, "Setting debug environment: " + CS$<>8__locals0.text); instance.m_debugEnv = CS$<>8__locals0.text; } internal List <.ctor>b__0_1(int index) { if (index != 0) { return ParameterInfo.None; } return ParameterInfo.Environments; } } [CompilerGenerated] private sealed class <>c__DisplayClass0_0 { public string text; internal bool <.ctor>b__2(EnvSetup env) { return env.m_name == text; } } public EnvCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { EnvMan instance = EnvMan.instance; if (Object.op_Implicit((Object)(object)instance)) { if (args.Length < 2) { Helper.AddMessage(args.Context, $"Environment: {instance.GetCurrentEnvironment()}."); } else { string text = string.Join(" ", args.Args, 1, args.Args.Length - 1); if (!EnvMan.instance.m_environments.Any((EnvSetup env) => env.m_name == text)) { text = text.Replace("_", " "); } Helper.AddMessage(args.Context, "Setting debug environment: " + text); instance.m_debugEnv = text; } } }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("env", "[value] - Prints or overrides the environment.", (ConsoleEvent)obj); AutoComplete.Register("env", (int index) => (index != 0) ? ParameterInfo.None : ParameterInfo.Environments); } } public class FindCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_3; public static Func> <>9__0_5; public static Func, string> <>9__0_8; public static Func, string> <>9__0_9; public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0 { args = args }; Helper.ArgsCheck(CS$<>8__locals0.args, 2, "Missing the search term."); if (CS$<>8__locals0.args.Length < 3) { ConsoleEventArgs args2 = CS$<>8__locals0.args; string[] args3 = CS$<>8__locals0.args.Args; int num = 0; string[] array = new string[1 + args3.Length]; string[] array2 = args3; foreach (string text in array2) { array[num] = text; num++; } array[num] = "10"; num++; args2.Args = array; } string[] args4 = Helper.AddPlayerPosXZY(CS$<>8__locals0.args.Args, 3); if (!ZNet.instance.IsServer()) { ServerExecution.Send((IEnumerable)args4); return; } CS$<>8__locals0.prefabs = Selector.GetAllPrefabs(new string[1] { CS$<>8__locals0.args[1] }); CS$<>8__locals0.pos = Parse.VectorXZY(string.Join(",", CS$<>8__locals0.args.Args.Skip(3))); List list = (from l in ZoneSystem.instance.GetLocationList() where Helper.IsValid(l.m_location) && l.m_location.m_prefab.Name == CS$<>8__locals0.args[1] select l).ToList(); if (CS$<>8__locals0.prefabs.Count <= 0 && list.Count <= 0) { <>c__DisplayClass0_1 CS$<>8__locals1 = new <>c__DisplayClass0_1 { lower = CS$<>8__locals0.args[1].ToLower() }; list = (from l in ZoneSystem.instance.GetLocationList() where Helper.IsValid(l.m_location) && l.m_location.m_prefab.Name.ToLower().Contains(CS$<>8__locals1.lower) select l).ToList(); CS$<>8__locals0.prefabs = Selector.GetAllPrefabs(new string[1] { "*" + CS$<>8__locals0.args[1] + "*" }); } List> list2 = list.Select((LocationInstance l) => Tuple.Create(l.m_location.m_prefab.Name, l.m_position)).ToList(); IEnumerable source = ZDOMan.instance.m_objectsByID.Values.Where((ZDO zdo) => zdo.IsValid() && CS$<>8__locals0.prefabs.Contains(zdo.GetPrefab())); list2.AddRange(source.Select((ZDO zdo) => Tuple.Create(((Object)ZNetScene.instance.GetPrefab(zdo.m_prefab)).name, zdo.GetPosition()))); list2.Sort((Tuple a, Tuple b) => Vector3.Distance(a.Item2, CS$<>8__locals0.pos).CompareTo(Vector3.Distance(b.Item2, CS$<>8__locals0.pos))); int count = list2.Count; list2 = list2.Take(Parse.Int(CS$<>8__locals0.args.Args, 2, 10)).ToList(); List values = list2.Select((Tuple p) => Format(CS$<>8__locals0.pos, p.Item2, p.Item1)).ToList(); CS$<>8__locals0.args.Context.AddString($"Found {count} of {CS$<>8__locals0.args[1]}. Showing {list2.Count} closest:"); CS$<>8__locals0.args.Context.AddString(string.Join("\n", values)); if (RedirectOutput.Target == null) { ServerExecution.RPC_Do_Pins(null, string.Join("|", list2.Select((Tuple item) => Helper.PrintVectorXZY(item.Item2)))); return; } RedirectOutput.Target.Invoke(ServerExecution.RPC_Pins, new object[1] { string.Join("|", list2.Select((Tuple item) => Helper.PrintVectorXZY(item.Item2))) }); } internal Tuple <.ctor>b__0_3(LocationInstance l) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Tuple.Create(l.m_location.m_prefab.Name, l.m_position); } internal Tuple <.ctor>b__0_5(ZDO zdo) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Tuple.Create(((Object)ZNetScene.instance.GetPrefab(zdo.m_prefab)).name, zdo.GetPosition()); } internal string <.ctor>b__0_8(Tuple item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Helper.PrintVectorXZY(item.Item2); } internal string <.ctor>b__0_9(Tuple item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Helper.PrintVectorXZY(item.Item2); } internal List <.ctor>b__0_1(int index) { return index switch { 0 => ParameterInfo.Ids, 1 => ParameterInfo.Create("Max amount", "a positive integer (default 10)"), 2 => ParameterInfo.Create("X coordinate", "if not specified, the current position is used"), 3 => ParameterInfo.Create("Z coordinate", "if not specified, the current position is used"), _ => ParameterInfo.None, }; } } [CompilerGenerated] private sealed class <>c__DisplayClass0_0 { public ConsoleEventArgs args; public HashSet prefabs; public Vector3 pos; internal bool <.ctor>b__2(LocationInstance l) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsValid(l.m_location)) { return l.m_location.m_prefab.Name == args[1]; } return false; } internal bool <.ctor>b__4(ZDO zdo) { if (zdo.IsValid()) { return prefabs.Contains(zdo.GetPrefab()); } return false; } internal int <.ctor>b__6(Tuple a, Tuple b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) return Vector3.Distance(a.Item2, pos).CompareTo(Vector3.Distance(b.Item2, pos)); } internal string <.ctor>b__7(Tuple p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Format(pos, p.Item2, p.Item1); } } [CompilerGenerated] private sealed class <>c__DisplayClass0_1 { public string lower; internal bool <.ctor>b__10(LocationInstance l) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsValid(l.m_location)) { return l.m_location.m_prefab.Name.ToLower().Contains(lower); } return false; } } public FindCommand() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown ConsoleCommand val = Terminal.commands["find"]; string description = val.Description; object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing the search term."); if (args.Length < 3) { ConsoleEventArgs val3 = args; string[] args2 = args.Args; int num = 0; string[] array = new string[1 + args2.Length]; string[] array2 = args2; foreach (string text in array2) { array[num] = text; num++; } array[num] = "10"; num++; val3.Args = array; } string[] args3 = Helper.AddPlayerPosXZY(args.Args, 3); if (!ZNet.instance.IsServer()) { ServerExecution.Send((IEnumerable)args3); } else { HashSet prefabs = Selector.GetAllPrefabs(new string[1] { args[1] }); Vector3 pos = Parse.VectorXZY(string.Join(",", args.Args.Skip(3))); List list = (from l in ZoneSystem.instance.GetLocationList() where Helper.IsValid(l.m_location) && l.m_location.m_prefab.Name == args[1] select l).ToList(); if (prefabs.Count <= 0 && list.Count <= 0) { string lower = args[1].ToLower(); list = (from l in ZoneSystem.instance.GetLocationList() where Helper.IsValid(l.m_location) && l.m_location.m_prefab.Name.ToLower().Contains(lower) select l).ToList(); prefabs = Selector.GetAllPrefabs(new string[1] { "*" + args[1] + "*" }); } List> list2 = list.Select((LocationInstance l) => Tuple.Create(l.m_location.m_prefab.Name, l.m_position)).ToList(); IEnumerable source = ZDOMan.instance.m_objectsByID.Values.Where((ZDO zdo) => zdo.IsValid() && prefabs.Contains(zdo.GetPrefab())); list2.AddRange(source.Select((ZDO zdo) => Tuple.Create(((Object)ZNetScene.instance.GetPrefab(zdo.m_prefab)).name, zdo.GetPosition()))); list2.Sort((Tuple a, Tuple b) => Vector3.Distance(a.Item2, pos).CompareTo(Vector3.Distance(b.Item2, pos))); int count = list2.Count; list2 = list2.Take(Parse.Int(args.Args, 2, 10)).ToList(); List values = list2.Select((Tuple p) => Format(pos, p.Item2, p.Item1)).ToList(); args.Context.AddString($"Found {count} of {args[1]}. Showing {list2.Count} closest:"); args.Context.AddString(string.Join("\n", values)); if (RedirectOutput.Target == null) { ServerExecution.RPC_Do_Pins(null, string.Join("|", list2.Select((Tuple item) => Helper.PrintVectorXZY(item.Item2)))); } else { RedirectOutput.Target.Invoke(ServerExecution.RPC_Pins, new object[1] { string.Join("|", list2.Select((Tuple item) => Helper.PrintVectorXZY(item.Item2))) }); } } }; <>c.<>9__0_0 = val2; obj = (object)val2; } Helper.Command("find", description, (ConsoleEvent)obj); AutoComplete.Register("find", (int index) => index switch { 0 => ParameterInfo.Ids, 1 => ParameterInfo.Create("Max amount", "a positive integer (default 10)"), 2 => ParameterInfo.Create("X coordinate", "if not specified, the current position is used"), 3 => ParameterInfo.Create("Z coordinate", "if not specified, the current position is used"), _ => ParameterInfo.None, }); } private static string Format(Vector3 pos, Vector3 p, string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Distance(pos, p); return string.Format(Settings.FindFormat.Replace("{pos_x", "{0").Replace("{pos_y", "{1").Replace("{pos_z", "{2") .Replace("{distance", "{3") .Replace("{name", "{4"), p.x, p.y, p.z, num, name); } } public class GotoCommand { private Vector3? LastPosition; private Quaternion? LastRotation; private void ParseArgs(ConsoleEventArgs args, Player player, ref Vector3 pos, ref Quaternion rot) { //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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (args.Length < 2) { pos.y = WorldGenerator.instance.GetHeight(pos.x, pos.z); return; } if (args.Length == 2 && args[1] == "last") { if (!LastPosition.HasValue) { throw new InvalidOperationException("No last position"); } pos = (Vector3)(((??)LastPosition) ?? pos); rot = (Quaternion)(((??)LastRotation) ?? rot); return; } string[] array = Parse.Split(args[1]); if (args.Length > 2) { array = args.Args.Skip(1).ToArray(); } if (Parse.TryFloat(array[0], out var value)) { if (array.Length < 2) { pos.y = value; return; } Vector3 val = Parse.VectorXZY(array); float num = (((Character)player).IsDebugFlying() ? ((Component)player).transform.position.y : WorldGenerator.instance.GetHeight(val.x, val.z)); pos = Parse.VectorXZY(array, new Vector3(pos.x, num, pos.z)); } else { PlayerInfo val2 = Helper.FindPlayer(string.Join(" ", args.Args.Skip(1))); pos = val2.m_position; } } public GotoCommand() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown AutoComplete.Register("goto", delegate(int index, int subIndex) { if (index == 0 && subIndex == 0) { return ParameterInfo.PublicPlayerNames; } return (index == 0) ? ParameterInfo.XZY("Coordinates", subIndex) : ParameterInfo.XZY("Coordinates", index); }); Helper.Command("goto", "[x,z,y or altitude or last or player or no parameter] - Teleports to the coordinates. If y is not given, teleports to the ground level.", (ConsoleEvent)delegate(ConsoleEventArgs args) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001d: 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_0047: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) Player player = Helper.GetPlayer(); Vector3 pos = ((Component)player).transform.position; Quaternion rot = ((Component)player).transform.rotation; ParseArgs(args, player, ref pos, ref rot); LastPosition = ((Component)player).transform.position; LastRotation = ((Component)player).transform.rotation; ((Character)player).TeleportTo(pos, rot, true); Helper.AddMessage(args.Context, $"Teleported to (X,Z,Y): {pos.x}, {pos.z}, {pos.y}."); }); } } [HarmonyPatch(typeof(Player), "TeleportTo")] public class FasterTeleport1 { private static void Postfix(Player __instance, bool __result) { if (Settings.DebugModeFastTeleport && __result && Player.m_debugMode) { __instance.m_teleportTimer = 15f; } } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] public class FasterTeleport2 { private static void Postfix(Player __instance) { if (Settings.DebugModeFastTeleport && Player.m_debugMode) { __instance.m_teleportCooldown = Mathf.Max(__instance.m_teleportCooldown, 1.5f); } } } public class HUDCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { if (!Object.op_Implicit((Object)(object)Hud.m_instance)) { Helper.AddMessage(args.Context, "Error: No HUD instance."); return; } if (args.Length >= 2) { Hud.m_instance.m_userHidden = args[1] != "1"; } else { Hud.m_instance.m_userHidden = !Hud.m_instance.m_userHidden; } string text = (Hud.m_instance.m_userHidden ? "disabled" : "enabled"); Helper.AddMessage(args.Context, "Hud " + text + "."); } internal List <.ctor>b__0_1(int index) { if (index == 0) { return ParameterInfo.Create("1 = enable, 0 = disable, no value = toggle"); } return ParameterInfo.None; } } public HUDCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (!Object.op_Implicit((Object)(object)Hud.m_instance)) { Helper.AddMessage(args.Context, "Error: No HUD instance."); } else { if (args.Length >= 2) { Hud.m_instance.m_userHidden = args[1] != "1"; } else { Hud.m_instance.m_userHidden = !Hud.m_instance.m_userHidden; } string text = (Hud.m_instance.m_userHidden ? "disabled" : "enabled"); Helper.AddMessage(args.Context, "Hud " + text + "."); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("hud", "[value] - Toggles or sets the HUD visibility.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("hud", (int index) => (index == 0) ? ParameterInfo.Create("1 = enable, 0 = disable, no value = toggle") : ParameterInfo.None); } } public class InventoryCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__5_2; public static Func <>9__5_3; public static Func <>9__5_4; public static ConsoleEvent <>9__5_0; public static Func> <>9__5_1; internal void <.ctor>b__5_0(ConsoleEventArgs args) { <>c__DisplayClass5_0 CS$<>8__locals0 = new <>c__DisplayClass5_0(); Helper.ArgsCheck(args, 2, "Missing clear, level, refill, repair or upgrade."); CS$<>8__locals0.amount = Parse.IntNull(args.Args, 2); string text = Parse.String(args.Args, 3, "all"); if (!CS$<>8__locals0.amount.HasValue) { text = Parse.String(args.Args, 2, "all"); CS$<>8__locals0.amount = Parse.IntNull(args.Args, 3); } Player player = Helper.GetPlayer(); Inventory inventory = ((Humanoid)player).GetInventory(); List list = inventory.GetAllItems(); if (text == "hand" || text == "worn") { list = inventory.GetEquippedItems(); } if (text == "hand") { list = list.Where((ItemData item) => HandTypes.Contains(item.m_shared.m_itemType)).ToList(); } switch (args[1]) { case "repair": { ItemData[] array5 = list.Where((ItemData item) => item.m_durability < item.GetMaxDurability()).ToArray(); ItemData[] array2 = array5; foreach (ItemData obj3 in array2) { obj3.m_durability = obj3.GetMaxDurability(); } Helper.AddMessage(args.Context, $"{array5.Length} items repaired."); break; } case "refill": { ItemData[] array3 = list.Where((ItemData item) => item.m_stack < item.m_shared.m_maxStackSize).ToArray(); ItemData[] array2 = array3; foreach (ItemData obj in array2) { obj.m_stack = obj.m_shared.m_maxStackSize; } Helper.AddMessage(args.Context, $"{array3.Length} items filled."); break; } case "clear": ((Humanoid)player).UnequipAllItems(); Helper.AddMessage(args.Context, $"{list.Count} items cleared."); inventory.RemoveAll(); break; case "level": { if (!CS$<>8__locals0.amount.HasValue) { throw new InvalidOperationException("Missing the level."); } ItemData[] array4 = list.Where(Valid).ToArray(); ItemData[] array2 = array4; foreach (ItemData obj2 in array2) { obj2.m_quality = CS$<>8__locals0.amount.Value; obj2.m_durability = obj2.GetMaxDurability(); } Helper.AddMessage(args.Context, $"{array4.Length} items upgraded."); break; } case "upgrade": { ItemData[] array = list.Where((ItemData item) => Valid(item) && (CS$<>8__locals0.amount.HasValue || item.m_quality != item.m_shared.m_maxQuality)).ToArray(); ItemData[] array2 = array; foreach (ItemData val in array2) { if (CS$<>8__locals0.amount.HasValue) { val.m_quality = CS$<>8__locals0.amount.Value; } else { val.m_quality = val.m_shared.m_maxQuality; } val.m_durability = val.GetMaxDurability(); } Helper.AddMessage(args.Context, $"{array.Length} items upgraded."); break; } default: throw new InvalidOperationException("Invalid operation. Use level, repair or upgrade."); } inventory.Changed(); } internal bool <.ctor>b__5_2(ItemData item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return HandTypes.Contains(item.m_shared.m_itemType); } internal bool <.ctor>b__5_3(ItemData item) { return item.m_durability < item.GetMaxDurability(); } internal bool <.ctor>b__5_4(ItemData item) { return item.m_stack < item.m_shared.m_maxStackSize; } internal List <.ctor>b__5_1(int index) { return index switch { 0 => Operations, 1 => Targets, 2 => ParameterInfo.Create("Amount", "How many levels to upgrade."), _ => ParameterInfo.None, }; } } [CompilerGenerated] private sealed class <>c__DisplayClass5_0 { public int? amount; internal bool <.ctor>b__5(ItemData item) { if (Valid(item)) { if (!amount.HasValue) { return item.m_quality != item.m_shared.m_maxQuality; } return true; } return false; } } private static readonly List Operations = new List(5) { "clear", "level", "refill", "repair", "upgrade" }; private static readonly List Targets = new List(3) { "all", "hand", "worn" }; private static readonly HashSet HandTypes = new HashSet { (ItemType)4, (ItemType)3, (ItemType)5, (ItemType)15, (ItemType)19, (ItemType)14 }; private static readonly HashSet ArmorTypes = new HashSet { (ItemType)7, (ItemType)12, (ItemType)6, (ItemType)11, (ItemType)17 }; private static bool Valid(ItemData item) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (item.m_shared.m_maxQuality <= 1 && !HandTypes.Contains(item.m_shared.m_itemType)) { return ArmorTypes.Contains(item.m_shared.m_itemType); } return true; } public InventoryCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__5_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing clear, level, refill, repair or upgrade."); int? amount = Parse.IntNull(args.Args, 2); string text = Parse.String(args.Args, 3, "all"); if (!amount.HasValue) { text = Parse.String(args.Args, 2, "all"); amount = Parse.IntNull(args.Args, 3); } Player player = Helper.GetPlayer(); Inventory inventory = ((Humanoid)player).GetInventory(); List list = inventory.GetAllItems(); if (text == "hand" || text == "worn") { list = inventory.GetEquippedItems(); } if (text == "hand") { list = list.Where((ItemData item) => HandTypes.Contains(item.m_shared.m_itemType)).ToList(); } switch (args[1]) { case "repair": { ItemData[] array5 = list.Where((ItemData item) => item.m_durability < item.GetMaxDurability()).ToArray(); ItemData[] array2 = array5; foreach (ItemData obj4 in array2) { obj4.m_durability = obj4.GetMaxDurability(); } Helper.AddMessage(args.Context, $"{array5.Length} items repaired."); break; } case "refill": { ItemData[] array3 = list.Where((ItemData item) => item.m_stack < item.m_shared.m_maxStackSize).ToArray(); ItemData[] array2 = array3; foreach (ItemData obj2 in array2) { obj2.m_stack = obj2.m_shared.m_maxStackSize; } Helper.AddMessage(args.Context, $"{array3.Length} items filled."); break; } case "clear": ((Humanoid)player).UnequipAllItems(); Helper.AddMessage(args.Context, $"{list.Count} items cleared."); inventory.RemoveAll(); break; case "level": { if (!amount.HasValue) { throw new InvalidOperationException("Missing the level."); } ItemData[] array4 = list.Where(Valid).ToArray(); ItemData[] array2 = array4; foreach (ItemData obj3 in array2) { obj3.m_quality = amount.Value; obj3.m_durability = obj3.GetMaxDurability(); } Helper.AddMessage(args.Context, $"{array4.Length} items upgraded."); break; } case "upgrade": { ItemData[] array = list.Where((ItemData item) => Valid(item) && (amount.HasValue || item.m_quality != item.m_shared.m_maxQuality)).ToArray(); ItemData[] array2 = array; foreach (ItemData val2 in array2) { if (amount.HasValue) { val2.m_quality = amount.Value; } else { val2.m_quality = val2.m_shared.m_maxQuality; } val2.m_durability = val2.GetMaxDurability(); } Helper.AddMessage(args.Context, $"{array.Length} items upgraded."); break; } default: throw new InvalidOperationException("Invalid operation. Use level, repair or upgrade."); } inventory.Changed(); }; <>c.<>9__5_0 = val; obj = (object)val; } Helper.Command("inventory", "[level/repair/upgrade] [hand/worn/all] [amount or max level if not given] - Modifies items in the inventory.", (ConsoleEvent)obj); AutoComplete.Register("inventory", (int index) => index switch { 0 => Operations, 1 => Targets, 2 => ParameterInfo.Create("Amount", "How many levels to upgrade."), _ => ParameterInfo.None, }); } } public class KillCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown List allCharacters = Character.GetAllCharacters(); int num = 0; int num2 = 0; foreach (Character item in allCharacters) { if (!item.IsPlayer()) { item.Damage(new HitData(1E+10f)); num++; } } if (Settings.KillDestroySpawners) { SpawnArea[] array = Object.FindObjectsByType((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Destructible component = ((Component)array[i]).gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.Damage(new HitData(1E+10f)); num2++; } } } ((Character)Player.m_localPlayer).Message((MessageType)1, string.Format("Killed {0} monsters{1}", num, (num2 > 0) ? $" & {num2} spawners." : "."), 0, (Sprite)null); } internal void <.ctor>b__0_1(ConsoleEventArgs args) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown List allCharacters = Character.GetAllCharacters(); int num = 0; int num2 = 0; foreach (Character item in allCharacters) { if (!item.IsPlayer() && !item.IsTamed()) { item.Damage(new HitData(1E+10f)); num++; } } if (Settings.KillDestroySpawners) { SpawnArea[] array = Object.FindObjectsByType((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Destructible component = ((Component)array[i]).gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.Damage(new HitData(1E+10f)); num2++; } } } ((Character)Player.m_localPlayer).Message((MessageType)1, string.Format("Killed {0} monsters{1}", num, (num2 > 0) ? $" & {num2} spawners." : "."), 0, (Sprite)null); } } public KillCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown List allCharacters2 = Character.GetAllCharacters(); int num3 = 0; int num4 = 0; foreach (Character item in allCharacters2) { if (!item.IsPlayer()) { item.Damage(new HitData(1E+10f)); num3++; } } if (Settings.KillDestroySpawners) { SpawnArea[] array2 = Object.FindObjectsByType((FindObjectsSortMode)0); for (int j = 0; j < array2.Length; j++) { Destructible component2 = ((Component)array2[j]).gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component2)) { component2.Damage(new HitData(1E+10f)); num4++; } } } ((Character)Player.m_localPlayer).Message((MessageType)1, string.Format("Killed {0} monsters{1}", num3, (num4 > 0) ? $" & {num4} spawners." : "."), 0, (Sprite)null); }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("killall", "kill nearby creatures", (ConsoleEvent)obj); AutoComplete.RegisterEmpty("killall"); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown List allCharacters = Character.GetAllCharacters(); int num = 0; int num2 = 0; foreach (Character item2 in allCharacters) { if (!item2.IsPlayer() && !item2.IsTamed()) { item2.Damage(new HitData(1E+10f)); num++; } } if (Settings.KillDestroySpawners) { SpawnArea[] array = Object.FindObjectsByType((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Destructible component = ((Component)array[i]).gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.Damage(new HitData(1E+10f)); num2++; } } } ((Character)Player.m_localPlayer).Message((MessageType)1, string.Format("Killed {0} monsters{1}", num, (num2 > 0) ? $" & {num2} spawners." : "."), 0, (Sprite)null); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } Helper.Command("killenemies", "kill nearby enemies", (ConsoleEvent)obj2); AutoComplete.RegisterEmpty("killenemies"); } } public class MappingCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__1_0; public static ConsoleEvent <>9__4_0; public static ConsoleEvent <>9__4_1; public static ConsoleEvent <>9__4_2; internal List b__1_0(int index) { return index switch { 0 => ParameterInfo.Create("X coordinate."), 1 => ParameterInfo.Create("Z coordinate."), 2 => ParameterInfo.Create("Radius (default 0)."), _ => ParameterInfo.None, }; } internal void <.ctor>b__4_0(ConsoleEventArgs args) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (ParseArgs(args, out var x, out var z, out var radius)) { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x, 0f, z); int num = 0; while (Minimap.instance.RemovePin(val, radius)) { num++; } Helper.AddMessage(args.Context, num + " pins removed."); } } internal void <.ctor>b__4_1(ConsoleEventArgs args) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) float x; float z; float radius; if (args.Length == 1) { Minimap.instance.ExploreAll(); } else if (ParseArgs(args, out x, out z, out radius)) { Vector3 p = default(Vector3); ((Vector3)(ref p))..ctor(x, 0f, z); ExploreRadius(args.Context, p, radius, explore: true); } } internal void <.ctor>b__4_2(ConsoleEventArgs args) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) float x; float z; float radius; if (args.Length == 1) { Minimap.instance.Reset(); } else if (ParseArgs(args, out x, out z, out radius)) { Vector3 p = default(Vector3); ((Vector3)(ref p))..ctor(x, 0f, z); ExploreRadius(args.Context, p, radius, explore: false); } } } private static bool ParseArgs(ConsoleEventArgs args, out float x, out float z, out float radius) { x = 0f; z = 0f; radius = 0f; if (args.Length < 2) { args.Context.AddString("Error: Missing coordinate X"); return false; } if (args.Length < 3) { args.Context.AddString("Error: Missing coordinate Z"); return false; } x = Parse.Float(args[1], float.MinValue); if (x == float.MinValue) { args.Context.AddString("Error: Invalid format for X coordinate."); return false; } z = Parse.Float(args[2], float.MinValue); if (z == float.MinValue) { args.Context.AddString("Error: Invalid format for Z coordinate."); return false; } if (args.Length > 3) { radius = Parse.Float(args[3], float.MinValue); if (radius == float.MinValue) { args.Context.AddString("Error: Invalid format for radius."); return false; } } return true; } private static void Register(string command) { AutoComplete.Register(command, (int index) => index switch { 0 => ParameterInfo.Create("X coordinate."), 1 => ParameterInfo.Create("Z coordinate."), 2 => ParameterInfo.Create("Radius (default 0)."), _ => ParameterInfo.None, }); } private static void ExploreRadius(Terminal terminal, Vector3 p, float radius, bool explore) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; int num = (int)Mathf.Ceil(radius / instance.m_pixelSize); int num2 = default(int); int num3 = default(int); instance.WorldToPixel(p, ref num2, ref num3); int num4 = 0; for (int i = num3 - num; i <= num3 + num; i++) { if (i < 0 || i >= instance.m_textureSize) { continue; } for (int j = num2 - num; j <= num2 + num; j++) { if (j >= 0 && j < instance.m_textureSize) { Vector2 val = new Vector2((float)(j - num2), (float)(i - num3)); if (!(((Vector2)(ref val)).magnitude > (float)num) && ExploreSpot(j, i, explore)) { num4++; } } } } if (num4 > 0) { instance.m_fogTexture.Apply(); } Helper.AddMessage(terminal, num4 + " spots " + (explore ? "explored" : "unexplored") + "."); } private static bool ExploreSpot(int x, int y, bool explore) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if (explore == instance.m_explored[y * instance.m_textureSize + x]) { return false; } Color pixel = instance.m_fogTexture.GetPixel(x, y); pixel.r = ((!explore) ? 255 : 0); instance.m_fogTexture.SetPixel(x, y, pixel); instance.m_explored[y * instance.m_textureSize + x] = explore; return true; } public MappingCommand() { //IL_0042: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0084: 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 //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown Register("resetpins"); object obj = <>c.<>9__4_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (ParseArgs(args, out var x3, out var z3, out var radius3)) { Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(x3, 0f, z3); int num = 0; while (Minimap.instance.RemovePin(val4, radius3)) { num++; } Helper.AddMessage(args.Context, num + " pins removed."); } }; <>c.<>9__4_0 = val; obj = (object)val; } new ConsoleCommand("resetpins", "[x] [z] [radius=0] - Removes pins from the map at a given position with a given radius.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); Register("exploremap"); object obj2 = <>c.<>9__4_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) float x2; float z2; float radius2; if (args.Length == 1) { Minimap.instance.ExploreAll(); } else if (ParseArgs(args, out x2, out z2, out radius2)) { Vector3 p2 = default(Vector3); ((Vector3)(ref p2))..ctor(x2, 0f, z2); ExploreRadius(args.Context, p2, radius2, explore: true); } }; <>c.<>9__4_1 = val2; obj2 = (object)val2; } new ConsoleCommand("exploremap", "[x] [z] [radius=0] - Reveals part of the map. Without parameters, reveals the whole map.", (ConsoleEvent)obj2, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); Register("resetmap"); object obj3 = <>c.<>9__4_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) float x; float z; float radius; if (args.Length == 1) { Minimap.instance.Reset(); } else if (ParseArgs(args, out x, out z, out radius)) { Vector3 p = default(Vector3); ((Vector3)(ref p))..ctor(x, 0f, z); ExploreRadius(args.Context, p, radius, explore: false); } }; <>c.<>9__4_2 = val3; obj3 = (object)val3; } new ConsoleCommand("resetmap", "[x] [z] [radius=0] - Hides part of the map. Without parameters, hides the whole map.", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public class MoveSpawn { public MoveSpawn() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("move_spawn", "[x,z,y] Moves the default spawn point to the given coordinates (player's current coordinates if not given).", (ConsoleEvent)delegate(ConsoleEventArgs args) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) string[] array = Helper.AddPlayerPosXZY(args.Args, 1); if (ZNet.instance.IsServer()) { ZoneSystem instance = ZoneSystem.instance; if (Object.op_Implicit((Object)(object)instance)) { Vector3 val = Parse.VectorXZY(Parse.Split(array[1])); instance.tempIconList.Clear(); instance.GetLocationIcons(instance.tempIconList); Vector3[] array2 = (from icon in instance.tempIconList where icon.Value == "StartTemple" select icon.Key).ToArray(); if (array2.Length == 0) { Helper.AddMessage(args.Context, "Default spawn point not found. Creating a new one."); if (CreateSpawnLocation(val)) { Helper.AddMessage(args.Context, $"Spawn created at {val:F0}"); instance.SendLocationIcons(ZRoutedRpc.Everybody); } else { Helper.AddMessage(args.Context, "Failed to create spawn point. Default spawn point not found in location prefabs."); } } else { if (array2.Length > 1) { Helper.AddMessage(args.Context, "Multiple spawn points found, moving the first one."); } if (MoveSpawnLocation(array2[0], val)) { Helper.AddMessage(args.Context, $"Spawn moved to {val:F0}"); instance.SendLocationIcons(ZRoutedRpc.Everybody); } else { Helper.AddMessage(args.Context, "Failed to move spawn point. Default spawn point not found in location instances."); } } } } else { ServerExecution.Send((IEnumerable)array); } }, true, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("move_spawn", (int index, int subIndex) => (index == 0) ? ParameterInfo.XZY("Coordinates (player's current coordinates if not given).", subIndex) : ParameterInfo.None); } private bool CreateSpawnLocation(Vector3 to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_003f: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) ZoneSystem instance = ZoneSystem.instance; Vector2i zone = ZoneSystem.GetZone(to); ZoneLocation val = ((IEnumerable)instance.m_locations).FirstOrDefault((Func)((ZoneLocation l) => l.m_prefabName == "StartTemple")); if (val == null) { return false; } LocationInstance val2 = default(LocationInstance); val2.m_position = to; val2.m_location = val; LocationInstance value = val2; instance.m_locationInstances[zone] = value; return true; } private bool MoveSpawnLocation(Vector3 from, Vector3 to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_000d: 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_0013: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0041: 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) ZoneSystem instance = ZoneSystem.instance; Vector2i zone = ZoneSystem.GetZone(from); Vector2i zone2 = ZoneSystem.GetZone(to); if (!instance.m_locationInstances.TryGetValue(zone, out var value)) { return false; } value.m_position = to; instance.m_locationInstances.Remove(zone); instance.m_locationInstances[zone2] = value; return true; } } public class NoMapCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index) { if (index != 0) { return ParameterInfo.None; } return ParameterInfo.Create("1 = disable map, 0 = enable map, no value = toggle"); } internal void <.ctor>b__0_1(ConsoleEventArgs args) { bool flag = false; bool flag2 = Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer(); Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) && !flag2) { return; } if (args.Length < 2) { if (flag2) { flag = !ZoneSystem.instance.GetGlobalKey((GlobalKeys)26); } else if (Object.op_Implicit((Object)(object)localPlayer)) { flag = PlayerPrefs.GetFloat("mapenabled_" + Player.m_localPlayer.GetPlayerName(), 1f) == 1f; } } else { flag = args[1] == "1"; } if (flag2) { if (flag) { ZoneSystem.instance.SetGlobalKey((GlobalKeys)26); } else { ZoneSystem.instance.RemoveGlobalKey((GlobalKeys)26); } } if (Object.op_Implicit((Object)(object)localPlayer)) { PlayerPrefs.SetFloat("mapenabled_" + Player.m_localPlayer.GetPlayerName(), flag ? 0f : 1f); } string text = "client and server"; if (Object.op_Implicit((Object)(object)localPlayer) && !flag2) { text = "client"; } if (!Object.op_Implicit((Object)(object)localPlayer) && flag2) { text = "server"; } Helper.AddMessage(args.Context, "Map " + (flag ? "disabled" : "enabled") + " for the " + text + "."); } } public NoMapCommand() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("nomap", (int index) => (index != 0) ? ParameterInfo.None : ParameterInfo.Create("1 = disable map, 0 = enable map, no value = toggle")); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { bool flag = false; bool flag2 = Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer(); Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) || flag2) { if (args.Length < 2) { if (flag2) { flag = !ZoneSystem.instance.GetGlobalKey((GlobalKeys)26); } else if (Object.op_Implicit((Object)(object)localPlayer)) { flag = PlayerPrefs.GetFloat("mapenabled_" + Player.m_localPlayer.GetPlayerName(), 1f) == 1f; } } else { flag = args[1] == "1"; } if (flag2) { if (flag) { ZoneSystem.instance.SetGlobalKey((GlobalKeys)26); } else { ZoneSystem.instance.RemoveGlobalKey((GlobalKeys)26); } } if (Object.op_Implicit((Object)(object)localPlayer)) { PlayerPrefs.SetFloat("mapenabled_" + Player.m_localPlayer.GetPlayerName(), flag ? 0f : 1f); } string text = "client and server"; if (Object.op_Implicit((Object)(object)localPlayer) && !flag2) { text = "client"; } if (!Object.op_Implicit((Object)(object)localPlayer) && flag2) { text = "server"; } Helper.AddMessage(args.Context, "Map " + (flag ? "disabled" : "enabled") + " for the " + text + "."); } }; <>c.<>9__0_1 = val; obj = (object)val; } new ConsoleCommand("nomap", "[set] - Toggles or sets the nomap mode. Can be executed on the server.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public class PermissionsCommand { [CompilerGenerated] private static class <>O { public static ConsoleEvent <0>__Handle; public static Func> <1>__GetOperationSpecificHints; } private static readonly List Operations = new List(11) { "add_group", "remove_group", "clear_groups", "add_command", "ban_command", "clear_command", "add_feature", "ban_feature", "force_feature", "clear_feature", "clear_all" }; private static List FindTargetPlayers(string target) { try { return PlayerInfo.FindPlayers(new string[1] { target }); } catch { return new List(); } } private static string JoinArgs(ConsoleEventArgs args, int startIndex) { if (args.Length <= startIndex) { return ""; } return string.Join(" ", args.Args.Skip(startIndex)).Trim(); } private static (string Hostname, string CharacterId, string DisplayName) ResolvePlayerTarget(string target) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) string target2 = target; List list = FindTargetPlayers(target2); if (list.Count > 1) { throw new InvalidOperationException("Target '" + target2 + "' matched multiple online players."); } if (list.Count == 1) { PlayerInfo playerInfo = list[0]; ZDO zDO = ZDOMan.instance.GetZDO(playerInfo.ZDOID); string text = ((zDO != null) ? zDO.GetLong(ZDOVars.s_playerID, 0L).ToString() : null); if (text == null) { throw new InvalidOperationException("Unable to resolve character id for player '" + playerInfo.Name + "'."); } return (playerInfo.HostId, text, playerInfo.Name); } List list2 = (from entry in PermissionLoader.Data.Entries where entry.character == target2 || entry.name.Equals(target2, StringComparison.OrdinalIgnoreCase) where !string.IsNullOrWhiteSpace(entry.id) && !string.IsNullOrWhiteSpace(entry.character) select entry).ToList(); if (list2.Count == 0) { throw new InvalidOperationException("Unable to find player by id/name '" + target2 + "'."); } if (list2.Count > 1) { throw new InvalidOperationException("Target '" + target2 + "' is ambiguous. Use a unique character id."); } PermissionEntry permissionEntry = list2[0]; string item = (string.IsNullOrWhiteSpace(permissionEntry.name) ? permissionEntry.character : permissionEntry.name); return (permissionEntry.id, permissionEntry.character, item); } private static void HandlePlayerEdit(ConsoleEventArgs args, string target, Func update) { (string Hostname, string CharacterId, string DisplayName) tuple = ResolvePlayerTarget(target); string item = tuple.Hostname; string item2 = tuple.CharacterId; string item3 = tuple.DisplayName; string text = PermissionData.PeerKey(item, item2); PermissionEntry arg = PermissionLoader.GetOrCreatePeerEntry(item, item2, item3) ?? throw new InvalidOperationException("Unable to create permission entry."); bool flag = update(arg); if (flag) { PermissionLoader.Save(); PermissionLoader.SendPeerPermissions(item, item2); } Helper.AddMessage(args.Context, flag ? ("Permissions updated for " + item3 + " (" + text + ").") : ("No permission changes for " + item3 + " (" + text + ").")); } private static void Handle(ConsoleEventArgs args) { ConsoleEventArgs args2 = args; if (args2.Length < 2) { throw new InvalidOperationException("Missing operation. Use add_group, remove_group, clear_groups, add_command, ban_command, clear_command, add_feature, ban_feature, force_feature, clear_feature, clear_all."); } if (!ZNet.instance.IsServer()) { ServerExecution.Send(args2); return; } string text = args2[1].ToLowerInvariant(); switch (text) { case "add_group": { Helper.ArgsCheck(args2, 4, "Usage: permissions add_group "); string group = args2[2].Trim(); string text3 = JoinArgs(args2, 3); if (text3 == "") { throw new InvalidOperationException("Missing target character id or name."); } HandlePlayerEdit(args2, text3, (PermissionEntry entry) => PermissionLoader.Data.AddGroup(entry, group)); break; } case "remove_group": { Helper.ArgsCheck(args2, 4, "Usage: permissions remove_group "); string group2 = args2[2].Trim(); string text2 = JoinArgs(args2, 3); if (text2 == "") { throw new InvalidOperationException("Missing target character id or name."); } HandlePlayerEdit(args2, text2, (PermissionEntry entry) => PermissionLoader.Data.RemoveGroup(entry, group2)); break; } case "clear_groups": { Helper.ArgsCheck(args2, 3, "Usage: permissions clear_groups "); string text4 = JoinArgs(args2, 2); if (text4 == "") { throw new InvalidOperationException("Missing target character id or name."); } HandlePlayerEdit(args2, text4, (PermissionEntry entry) => PermissionLoader.Data.ClearGroups(entry)); break; } case "add_command": { Helper.ArgsCheck(args2, 4, "Usage: permissions add_command "); string target8 = JoinArgs(args2, 3); HandlePlayerEdit(args2, target8, (PermissionEntry entry) => PermissionLoader.Data.SetCommandPermission(entry, args2[2], PermissionManager.FeaturePermission.Yes)); break; } case "ban_command": { Helper.ArgsCheck(args2, 4, "Usage: permissions ban_command "); string target7 = JoinArgs(args2, 3); HandlePlayerEdit(args2, target7, (PermissionEntry entry) => PermissionLoader.Data.SetCommandPermission(entry, args2[2], PermissionManager.FeaturePermission.No)); break; } case "clear_command": { Helper.ArgsCheck(args2, 4, "Usage: permissions clear_command "); string target6 = JoinArgs(args2, 3); HandlePlayerEdit(args2, target6, (PermissionEntry entry) => PermissionLoader.Data.ClearCommand(entry, args2[2])); break; } case "add_feature": { Helper.ArgsCheck(args2, 5, "Usage: permissions add_feature
"); string target5 = JoinArgs(args2, 4); HandlePlayerEdit(args2, target5, (PermissionEntry entry) => PermissionLoader.Data.SetFeaturePermission(entry, args2[2], args2[3], PermissionManager.FeaturePermission.Yes)); break; } case "ban_feature": { Helper.ArgsCheck(args2, 5, "Usage: permissions ban_feature
"); string target4 = JoinArgs(args2, 4); HandlePlayerEdit(args2, target4, (PermissionEntry entry) => PermissionLoader.Data.SetFeaturePermission(entry, args2[2], args2[3], PermissionManager.FeaturePermission.No)); break; } case "force_feature": { Helper.ArgsCheck(args2, 5, "Usage: permissions force_feature
"); string target3 = JoinArgs(args2, 4); HandlePlayerEdit(args2, target3, (PermissionEntry entry) => PermissionLoader.Data.SetFeaturePermission(entry, args2[2], args2[3], PermissionManager.FeaturePermission.Force)); break; } case "clear_feature": { Helper.ArgsCheck(args2, 5, "Usage: permissions clear_feature
"); string target2 = JoinArgs(args2, 4); HandlePlayerEdit(args2, target2, (PermissionEntry entry) => PermissionLoader.Data.ClearFeature(entry, args2[2], args2[3])); break; } case "clear_all": { Helper.ArgsCheck(args2, 3, "Usage: permissions clear_all "); string target = JoinArgs(args2, 2); HandlePlayerEdit(args2, target, (PermissionEntry entry) => PermissionLoader.Data.ClearAll(entry)); break; } default: throw new InvalidOperationException("Unknown operation '" + text + "'."); } } private static List GetOperationSpecificHints(int index, int _, string[] args) { if (index == 0) { return Operations; } switch ((args.Length != 0) ? args[0].Trim().ToLowerInvariant() : "") { case "add_group": case "remove_group": if (index == 1) { return ParameterInfo.Create("Group name"); } if (index >= 2) { return ParameterInfo.PlayerNames; } return ParameterInfo.None; case "clear_groups": case "clear_all": if (index >= 1) { return ParameterInfo.PlayerNames; } return ParameterInfo.None; case "add_command": case "ban_command": case "clear_command": if (index == 1) { return ParameterInfo.Create("Command name"); } if (index >= 2) { return ParameterInfo.PlayerNames; } return ParameterInfo.None; case "add_feature": case "ban_feature": case "force_feature": case "clear_feature": if (index == 1) { return ParameterInfo.Create("Feature section"); } if (index == 2) { return ParameterInfo.Create("Feature name"); } if (index >= 3) { return ParameterInfo.PlayerNames; } return ParameterInfo.None; default: return ParameterInfo.Create("Unknown operation. Use: add_group, remove_group, clear_groups, add_command, ban_command, clear_command, add_feature, ban_feature, force_feature, clear_feature, clear_all"); } } public PermissionsCommand() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown object obj = <>O.<0>__Handle; if (obj == null) { ConsoleEvent val = Handle; <>O.<0>__Handle = val; obj = (object)val; } Helper.Command("permissions", "[operation] - Manage player permission overrides.", (ConsoleEvent)obj); AutoComplete.Register("permissions", GetOperationSpecificHints); } } public class PlayerListCommand { private string Format(ZNetPeer player) { return string.Format(Settings.Format(Settings.PlayerListFormat), player.m_playerName, player.m_socket.GetHostName(), ((ZDOID)(ref player.m_characterID)).UserID, player.m_refPos.x, player.m_refPos.y, player.m_refPos.z); } private string Format() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0046: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Vector3 referencePosition = ZNet.instance.m_referencePosition; return string.Format(Settings.Format(Settings.PlayerListFormat), Game.instance.GetPlayerProfile().GetName(), UserInfo.GetLocalUser().UserId, ZNet.instance.m_characterID, referencePosition.x, referencePosition.y, referencePosition.z); } private void Execute(Terminal context) { List list = ZNet.instance.GetPeers().Select(Format).ToList(); if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsDedicated()) { list.Add(Format()); } context.AddString(string.Join("\n", list)); } public PlayerListCommand() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Helper.Command("playerlist", "- Prints online players.", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ZNet.instance.IsServer()) { Execute(args.Context); } else { ServerExecution.Send((IEnumerable)args.Args); } }); AutoComplete.RegisterEmpty("playerlist"); } } public class PosCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Helper.GetPlayer()).transform.position; int num = 0; if (args.Length >= 2) { num = args.TryParameterInt(1, 0); if (num == 0) { position = Helper.FindPlayer(args[1]).m_position; } } if (args.Length >= 3) { num = args.TryParameterInt(2, 0); } Helper.AddMessage(args.Context, "Player position (X,Z,Y): (" + position.x.ToString($"F{num}") + ", " + position.z.ToString($"F{num}") + ", " + position.y.ToString($"F{num}") + ")"); } internal List <.ctor>b__0_1(int index) { return index switch { 0 => ParameterInfo.PlayerNames, 1 => ParameterInfo.Create("Precision", "a positive integer"), _ => ParameterInfo.None, }; } } public PosCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Helper.GetPlayer()).transform.position; int num = 0; if (args.Length >= 2) { num = args.TryParameterInt(1, 0); if (num == 0) { position = Helper.FindPlayer(args[1]).m_position; } } if (args.Length >= 3) { num = args.TryParameterInt(2, 0); } Helper.AddMessage(args.Context, "Player position (X,Z,Y): (" + position.x.ToString($"F{num}") + ", " + position.z.ToString($"F{num}") + ", " + position.y.ToString($"F{num}") + ")"); }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("pos", "[name/precision] [precision] - Prints the position of a player. If name is not given, prints the current position.", (ConsoleEvent)obj); AutoComplete.Register("pos", (int index) => index switch { 0 => ParameterInfo.PlayerNames, 1 => ParameterInfo.Create("Precision", "a positive integer"), _ => ParameterInfo.None, }); } } public class PullCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) Player player = Helper.GetPlayer(); float num = args.TryParameterFloat(1, player.m_autoPickupRange); Collider[] array = Physics.OverlapSphere(((Component)player).transform.position + Vector3.up, num, player.m_autoPickupMask); foreach (Collider val in array) { if (Object.op_Implicit((Object)(object)val.attachedRigidbody)) { ItemDrop component = ((Component)val.attachedRigidbody).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.m_autoPickup = true; ((Component)component).transform.position = ((Component)player).transform.position + Vector3.up * 0.5f; } } } Helper.AddMessage(args.Context, $"Pulled items within {num:F0} meters."); } internal List <.ctor>b__0_1(int index) { if (index == 0) { return ParameterInfo.Create("Radius", "a positive integer"); } return ParameterInfo.None; } } public PullCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) Player player = Helper.GetPlayer(); float num = args.TryParameterFloat(1, player.m_autoPickupRange); Collider[] array = Physics.OverlapSphere(((Component)player).transform.position + Vector3.up, num, player.m_autoPickupMask); foreach (Collider val2 in array) { if (Object.op_Implicit((Object)(object)val2.attachedRigidbody)) { ItemDrop component = ((Component)val2.attachedRigidbody).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.m_autoPickup = true; ((Component)component).transform.position = ((Component)player).transform.position + Vector3.up * 0.5f; } } } Helper.AddMessage(args.Context, $"Pulled items within {num:F0} meters."); }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("pull", "[radius] - Pulls all items within the radius.", (ConsoleEvent)obj); AutoComplete.Register("pull", (int index) => (index == 0) ? ParameterInfo.Create("Radius", "a positive integer") : ParameterInfo.None); } } public class RecallCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index) { if (index == 0) { return ParameterInfo.PublicPlayerNames; } return ParameterInfo.None; } internal void <.ctor>b__0_1(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing players"); args.Context.TryRunCommand("tp " + args[1], false, false); } } public RecallCommand() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("recall", (int index) => (index == 0) ? ParameterInfo.PublicPlayerNames : ParameterInfo.None); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing players"); args.Context.TryRunCommand("tp " + args[1], false, false); }; <>c.<>9__0_1 = val; obj = (object)val; } Helper.Command("recall", "[players] - Teleports players to you", (ConsoleEvent)obj); } } public class RepairCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index) { if (index == 0) { return ParameterInfo.Create("Radius", "a positive integer"); } return ParameterInfo.None; } internal void <.ctor>b__0_1(ConsoleEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) Vector3 position = ((Component)Helper.GetPlayer()).transform.position; int num = 0; float num2 = args.TryParameterFloat(1, 20f); new List(); foreach (Piece s_allPiece in Piece.s_allPieces) { if (!(Vector3.Distance(position, ((Component)s_allPiece).transform.position) > num2)) { WearNTear component = ((Component)s_allPiece).GetComponent(); if (component != null && component.Repair()) { num++; } } } Helper.AddMessage(args.Context, $"Repaired {num} structures."); } } public RepairCommand() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("repair", (int index) => (index == 0) ? ParameterInfo.Create("Radius", "a positive integer") : ParameterInfo.None); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) Vector3 position = ((Component)Helper.GetPlayer()).transform.position; int num = 0; float num2 = args.TryParameterFloat(1, 20f); new List(); foreach (Piece s_allPiece in Piece.s_allPieces) { if (!(Vector3.Distance(position, ((Component)s_allPiece).transform.position) > num2)) { WearNTear component = ((Component)s_allPiece).GetComponent(); if (component != null && component.Repair()) { num++; } } } Helper.AddMessage(args.Context, $"Repaired {num} structures."); }; <>c.<>9__0_1 = val; obj = (object)val; } Helper.Command("repair", "[radius=20] - Repair structures within given meters.", (ConsoleEvent)obj); } } public class ResetDungeonCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__2_2; public static ConsoleEvent <>9__2_0; internal void <.ctor>b__2_0(ConsoleEventArgs args) { //IL_0047: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Invalid comparison between Unknown and I4 //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass2_0 CS$<>8__locals0 = new <>c__DisplayClass2_0(); DungeonGenerator[] source = Object.FindObjectsByType((FindObjectsSortMode)0); CS$<>8__locals0.player = Helper.GetPlayer(); DungeonGenerator val = source.OrderBy((DungeonGenerator dg) => Utils.DistanceXZ(((Component)dg).transform.position, ((Component)CS$<>8__locals0.player).transform.position)).FirstOrDefault(); if (!Object.op_Implicit((Object)(object)val)) { throw new Exception("No dungeon found."); } if (Utils.DistanceXZ(((Component)val).transform.position, ((Component)CS$<>8__locals0.player).transform.position) > 20f) { throw new Exception("The dungeon is too far."); } Vector2i zone = ZoneSystem.GetZone(((Component)val).transform.position); int num = ZDOMan.instance.SectorToIndex(zone); if (num < 0 || num >= ZDOMan.instance.m_objectsBySector.Length) { throw new Exception("No objects found."); } List obj = ZDOMan.instance.m_objectsBySector[num]; ZDO val2 = ((IEnumerable)obj).FirstOrDefault((Func)((ZDO x) => x.GetPrefab() == ProxyHash)); if (val2 != null) { int @int = val2.GetInt(ZDOVars.s_location, 0); if (ZoneSystem.instance.m_locationsByHash.TryGetValue(@int, out var value)) { value.m_prefab.Load(); Location component = value.m_prefab.Asset.GetComponent(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_generator) && component.m_useCustomInteriorTransform && Object.op_Implicit((Object)(object)component.m_interiorTransform)) { val.m_originalPosition = ((Component)component.m_generator).transform.localPosition; } value.m_prefab.Release(); } } foreach (ZDO item in obj) { if (((int)val.m_algorithm != 0 || !(item.GetPosition().y < 3000f)) && ((int)val.m_algorithm != 1 || !(Utils.DistanceXZ(item.GetPosition(), ((Component)val).transform.position) > val.m_campRadiusMax)) && item.GetPrefab() != PlayerHash && item.GetPrefab() != ProxyHash && item != val.m_nview.GetZDO()) { ZDOMan.instance.DestroyZDO(item); } } val.m_nview.ClaimOwnership(); val.Generate((SpawnMode)0); Helper.AddMessage(args.Context, $"Reset dungeon {((Object)val).name} at {Helper.PrintVectorXZY(((Component)val).transform.position)} with m_originalPosition {val.m_originalPosition.y}."); } internal bool <.ctor>b__2_2(ZDO x) { return x.GetPrefab() == ProxyHash; } } [CompilerGenerated] private sealed class <>c__DisplayClass2_0 { public Player player; internal float <.ctor>b__1(DungeonGenerator dg) { //IL_0006: 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) return Utils.DistanceXZ(((Component)dg).transform.position, ((Component)player).transform.position); } } private static readonly int ProxyHash = StringExtensionMethods.GetStableHashCode("LocationProxy"); private static readonly int PlayerHash = StringExtensionMethods.GetStableHashCode("Player"); public ResetDungeonCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__2_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0047: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Invalid comparison between Unknown and I4 //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) DungeonGenerator[] source = Object.FindObjectsByType((FindObjectsSortMode)0); Player player = Helper.GetPlayer(); DungeonGenerator val2 = source.OrderBy((DungeonGenerator dg) => Utils.DistanceXZ(((Component)dg).transform.position, ((Component)player).transform.position)).FirstOrDefault(); if (!Object.op_Implicit((Object)(object)val2)) { throw new Exception("No dungeon found."); } if (Utils.DistanceXZ(((Component)val2).transform.position, ((Component)player).transform.position) > 20f) { throw new Exception("The dungeon is too far."); } Vector2i zone = ZoneSystem.GetZone(((Component)val2).transform.position); int num = ZDOMan.instance.SectorToIndex(zone); if (num < 0 || num >= ZDOMan.instance.m_objectsBySector.Length) { throw new Exception("No objects found."); } List obj2 = ZDOMan.instance.m_objectsBySector[num]; ZDO val3 = ((IEnumerable)obj2).FirstOrDefault((Func)((ZDO x) => x.GetPrefab() == ProxyHash)); if (val3 != null) { int @int = val3.GetInt(ZDOVars.s_location, 0); if (ZoneSystem.instance.m_locationsByHash.TryGetValue(@int, out var value)) { value.m_prefab.Load(); Location component = value.m_prefab.Asset.GetComponent(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_generator) && component.m_useCustomInteriorTransform && Object.op_Implicit((Object)(object)component.m_interiorTransform)) { val2.m_originalPosition = ((Component)component.m_generator).transform.localPosition; } value.m_prefab.Release(); } } foreach (ZDO item in obj2) { if (((int)val2.m_algorithm != 0 || !(item.GetPosition().y < 3000f)) && ((int)val2.m_algorithm != 1 || !(Utils.DistanceXZ(item.GetPosition(), ((Component)val2).transform.position) > val2.m_campRadiusMax)) && item.GetPrefab() != PlayerHash && item.GetPrefab() != ProxyHash && item != val2.m_nview.GetZDO()) { ZDOMan.instance.DestroyZDO(item); } } val2.m_nview.ClaimOwnership(); val2.Generate((SpawnMode)0); Helper.AddMessage(args.Context, $"Reset dungeon {((Object)val2).name} at {Helper.PrintVectorXZY(((Component)val2).transform.position)} with m_originalPosition {val2.m_originalPosition.y}."); }; <>c.<>9__2_0 = val; obj = (object)val; } Helper.Command("resetdungeon", "- Resets the nearest camp or dungeon within 20 meters.", (ConsoleEvent)obj); AutoComplete.RegisterEmpty("resetdungeon"); } } public class ResolutionCommand { private string GetMode() { //IL_0006: 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_0019: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 string result = "window"; if ((int)Screen.fullScreenMode == 0) { result = "exclusive"; } if ((int)Screen.fullScreenMode == 2) { result = "max"; } if ((int)Screen.fullScreenMode == 1) { result = "full"; } return result; } private void PrintResolution(Terminal terminal) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Resolution currentResolution = Screen.currentResolution; Helper.AddMessage(terminal, $"Resolution is {Screen.width}x{Screen.height} ({((Resolution)(ref currentResolution)).width}x{((Resolution)(ref currentResolution)).height}) with {((Resolution)(ref currentResolution)).refreshRateRatio.numerator} hz and {GetMode()} mode."); } private void SetResolution(Terminal terminal, string[] args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Resolution currentResolution = Screen.currentResolution; string text = Parse.String(args, 1, GetMode()); int num = Parse.Int(args, 2, ((Resolution)(ref currentResolution)).width); int num2 = Parse.Int(args, 3, ((Resolution)(ref currentResolution)).height); int num3 = Parse.Int(args, 4, (int)((Resolution)(ref currentResolution)).refreshRateRatio.numerator); FullScreenMode val = (FullScreenMode)3; if (text == "exclusive") { val = (FullScreenMode)0; } if (text == "max") { val = (FullScreenMode)2; } if (text == "full") { val = (FullScreenMode)1; } RefreshRate val2 = default(RefreshRate); val2.numerator = (uint)num3; val2.denominator = 1u; RefreshRate val3 = val2; Screen.SetResolution(num, num2, val, val3); string text2 = ((num3 == 0) ? "max" : num3.ToString()); Helper.AddMessage(terminal, $"Resolution set to {num}x{num2} with {text2} hz and {text} mode."); } public ResolutionCommand() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("resolution", "[mode] [width] [height] [refresh] - Prints or sets the resolution.", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (args.Length == 1) { PrintResolution(args.Context); } else { SetResolution(args.Context, args.Args); } }, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("resolution", (int index) => index switch { 0 => new List(4) { "exclusive", "full", "max", "window" }, 1 => ParameterInfo.Create("Width", "a positive integer (max supported if not given)"), 2 => ParameterInfo.Create("Height", "a positive integer (max supported if not given)"), 3 => ParameterInfo.Create("Refresh rate", "a positive integer (max supported if not given)"), _ => ParameterInfo.None, }); } } public class RPCCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static Func <>9__0_2; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index) { return index switch { 0 => ParameterInfo.PlayerNames, 1 => ParameterInfo.Create("RPC name."), _ => ParameterInfo.Create("Parameters."), }; } internal void <.ctor>b__0_1(ConsoleEventArgs args) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing id."); Helper.ArgsCheck(args, 3, "Missing RPC name"); string[] array = Parse.Split(args[1]); foreach (PlayerInfo item in PlayerInfo.FindPlayers(array)) { ZRoutedRpc instance = ZRoutedRpc.instance; long uID = ZNet.GetUID(); ZDOID zDOID = item.ZDOID; string text = args[2]; object[] array2 = args.Args.Skip(3).ToArray(); instance.InvokeRoutedRPC(uID, zDOID, text, array2); } ZDO[] array3 = ((IEnumerable)array).Select((Func)delegate(string s) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) string[] array4 = s.Split(new char[1] { ':' }); if (array4.Length == 1) { return null; } if (!long.TryParse(array4[0], out var result)) { return null; } if (!uint.TryParse(array4[1], out var result2)) { return null; } ZDOID key = default(ZDOID); ((ZDOID)(ref key))..ctor(result, result2); ZDO value; return (!ZDOMan.instance.m_objectsByID.TryGetValue(key, out value)) ? null : value; }).ToArray(); foreach (ZDO val in array3) { if (val != null) { ZRoutedRpc instance2 = ZRoutedRpc.instance; long uID2 = ZNet.GetUID(); ZDOID uid = val.m_uid; string text2 = args[2]; object[] array2 = args.Args.Skip(3).ToArray(); instance2.InvokeRoutedRPC(uID2, uid, text2, array2); } } } internal ZDO <.ctor>b__0_2(string s) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) string[] array = s.Split(new char[1] { ':' }); if (array.Length == 1) { return null; } if (!long.TryParse(array[0], out var result)) { return null; } if (!uint.TryParse(array[1], out var result2)) { return null; } ZDOID key = default(ZDOID); ((ZDOID)(ref key))..ctor(result, result2); if (!ZDOMan.instance.m_objectsByID.TryGetValue(key, out var value)) { return null; } return value; } } public RPCCommand() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("rpc", (int index) => index switch { 0 => ParameterInfo.PlayerNames, 1 => ParameterInfo.Create("RPC name."), _ => ParameterInfo.Create("Parameters."), }); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing id."); Helper.ArgsCheck(args, 3, "Missing RPC name"); string[] array = Parse.Split(args[1]); foreach (PlayerInfo item in PlayerInfo.FindPlayers(array)) { ZRoutedRpc instance = ZRoutedRpc.instance; long uID = ZNet.GetUID(); ZDOID zDOID = item.ZDOID; string text = args[2]; object[] array2 = args.Args.Skip(3).ToArray(); instance.InvokeRoutedRPC(uID, zDOID, text, array2); } ZDO[] array3 = ((IEnumerable)array).Select((Func)delegate(string s) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) string[] array4 = s.Split(new char[1] { ':' }); if (array4.Length == 1) { return null; } if (!long.TryParse(array4[0], out var result)) { return null; } if (!uint.TryParse(array4[1], out var result2)) { return null; } ZDOID key = default(ZDOID); ((ZDOID)(ref key))..ctor(result, result2); ZDO value; return (!ZDOMan.instance.m_objectsByID.TryGetValue(key, out value)) ? null : value; }).ToArray(); foreach (ZDO val2 in array3) { if (val2 != null) { ZRoutedRpc instance2 = ZRoutedRpc.instance; long uID2 = ZNet.GetUID(); ZDOID uid = val2.m_uid; string text2 = args[2]; object[] array2 = args.Args.Skip(3).ToArray(); instance2.InvokeRoutedRPC(uID2, uid, text2, array2); } } }; <>c.<>9__0_1 = val; obj = (object)val; } Helper.Command("rpc", "[id1,id2,...] [name] [arg1] [arg2] ... - Sends rpc.", (ConsoleEvent)obj); } } public class SearchComponentCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__0_3; public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { <>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0(); Helper.ArgsCheck(args, 2, "Missing the object/location"); Helper.ArgsCheck(args, 3, "Missing the component"); CS$<>8__locals0.component = args[2].ToLowerInvariant(); string text = ""; string value = ""; string[] array = CS$<>8__locals0.component.Split(new char[1] { ',' }); if (array.Length == 3) { CS$<>8__locals0.component = array[0]; text = array[1]; value = array[2]; } int num = args.TryParameterInt(2, 5); IEnumerable source = from l in ZoneSystem.instance.m_locations.Where(Helper.IsValid).Where(delegate(ZoneLocation l) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) l.m_prefab.Load(); l.m_prefab.Asset.GetComponentsInChildren(ZNetView.m_tempComponents); l.m_prefab.Release(); return ZNetView.m_tempComponents.Any((MonoBehaviour s) => ((object)s).GetType().Name.ToLowerInvariant() == CS$<>8__locals0.component); }) select l.m_prefab.Name; string[] array2 = ((args[1] == "location") ? source.ToArray() : ((text == "") ? ComponentInfo.PrefabsByComponent(CS$<>8__locals0.component) : ComponentInfo.PrefabsByField(CS$<>8__locals0.component, text, value))); if (array2.Length > 100) { args.Context.AddString("Over 100 results, printing to the log file."); ZLog.Log((object)("\n" + string.Join("\n", array2))); return; } int num2 = (int)Math.Ceiling((float)array2.Length / (float)num); string[] array3 = new string[num2]; for (int i = 0; i < array2.Length; i += num2) { if (array2.Length - i < num2) { num2 = array2.Length - i; array3 = new string[num2]; } Array.Copy(array2, i, array3, 0, num2); args.Context.AddString(string.Join(", ", array3)); } } internal string <.ctor>b__0_3(ZoneLocation l) { return l.m_prefab.Name; } internal List <.ctor>b__0_1(int index) { return index switch { 0 => new List(2) { "object", "location" }, 1 => ParameterInfo.Create("Search component"), 2 => ParameterInfo.Create("Max lines", "number (default 5)"), _ => ParameterInfo.None, }; } } [CompilerGenerated] private sealed class <>c__DisplayClass0_0 { public string component; public Func <>9__4; internal bool <.ctor>b__2(ZoneLocation l) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) l.m_prefab.Load(); l.m_prefab.Asset.GetComponentsInChildren(ZNetView.m_tempComponents); l.m_prefab.Release(); return ZNetView.m_tempComponents.Any((MonoBehaviour s) => ((object)s).GetType().Name.ToLowerInvariant() == component); } internal bool <.ctor>b__4(MonoBehaviour s) { return ((object)s).GetType().Name.ToLowerInvariant() == component; } } public SearchComponentCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing the object/location"); Helper.ArgsCheck(args, 3, "Missing the component"); string component = args[2].ToLowerInvariant(); string text = ""; string value = ""; string[] array = component.Split(new char[1] { ',' }); if (array.Length == 3) { component = array[0]; text = array[1]; value = array[2]; } int num = args.TryParameterInt(2, 5); IEnumerable source = from l in ZoneSystem.instance.m_locations.Where(Helper.IsValid).Where(delegate(ZoneLocation l) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) l.m_prefab.Load(); l.m_prefab.Asset.GetComponentsInChildren(ZNetView.m_tempComponents); l.m_prefab.Release(); return ZNetView.m_tempComponents.Any((MonoBehaviour s) => ((object)s).GetType().Name.ToLowerInvariant() == component); }) select l.m_prefab.Name; string[] array2 = ((args[1] == "location") ? source.ToArray() : ((text == "") ? ComponentInfo.PrefabsByComponent(component) : ComponentInfo.PrefabsByField(component, text, value))); if (array2.Length > 100) { args.Context.AddString("Over 100 results, printing to the log file."); ZLog.Log((object)("\n" + string.Join("\n", array2))); } else { int num2 = (int)Math.Ceiling((float)array2.Length / (float)num); string[] array3 = new string[num2]; for (int i = 0; i < array2.Length; i += num2) { if (array2.Length - i < num2) { num2 = array2.Length - i; array3 = new string[num2]; } Array.Copy(array2, i, array3, 0, num2); args.Context.AddString(string.Join(", ", array3)); } } }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("search_component", "[object/location] [component] [max_lines=5] - Prints object or location ids having the component.", (ConsoleEvent)obj); AutoComplete.Register("search_component", (int index) => index switch { 0 => new List(2) { "object", "location" }, 1 => ParameterInfo.Create("Search component"), 2 => ParameterInfo.Create("Max lines", "number (default 5)"), _ => ParameterInfo.None, }); } } public class SearchItemCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__0_2; public static ConsoleEvent <>9__0_0; public static Func <>9__2_0; public static Func <>9__2_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing the search term"); List list = ObjectDB.instance.m_items; for (int i = 1; i < args.Length; i++) { string[] array = args[i].Split(new char[1] { ',' }); if (array.Length != 2) { args.Context.AddString("Invalid search term: " + args[i]); continue; } string field = array[0]; string value = array[1].ToLowerInvariant(); list = ItemDropsByField(list, field, value); } List list2 = list.Select((GameObject item) => ((Object)item).name).ToList(); if (list2.Count > 50) { args.Context.AddString("Over 50 results, printing to the log file."); Debug.Log((object)("Search item results:\n" + string.Join("\n", list2))); return; } foreach (string item in list2) { args.Context.AddString(item); } } internal string <.ctor>b__0_2(GameObject item) { return ((Object)item).name; } internal bool b__2_0(FieldInfo f) { if (!validTypes.Contains(f.FieldType)) { return f.FieldType.IsEnum; } return true; } internal string b__2_1(FieldInfo p) { return p.Name; } } private static readonly HashSet validTypes = new HashSet { typeof(bool), typeof(int), typeof(float), typeof(string) }; public SearchItemCommand() { //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) //IL_0035: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.ArgsCheck(args, 2, "Missing the search term"); List list = ObjectDB.instance.m_items; for (int i = 1; i < args.Length; i++) { string[] array = args[i].Split(new char[1] { ',' }); if (array.Length != 2) { args.Context.AddString("Invalid search term: " + args[i]); } else { string field = array[0]; string value = array[1].ToLowerInvariant(); list = ItemDropsByField(list, field, value); } } List list2 = list.Select((GameObject item) => ((Object)item).name).ToList(); if (list2.Count > 50) { args.Context.AddString("Over 50 results, printing to the log file."); Debug.Log((object)("Search item results:\n" + string.Join("\n", list2))); return; } foreach (string item in list2) { args.Context.AddString(item); } }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("search_item", "[field,value] [field,value] ... - Searches items.", (ConsoleEvent)obj); List itemFields = new List(); AutoComplete.Register("search_item", delegate(int index, int subIndex) { if (itemFields.Count == 0) { itemFields = GenerateAutocomplete(); } return subIndex switch { 0 => itemFields, 1 => ParameterInfo.Create("Value"), _ => ParameterInfo.None, }; }); } private static List GenerateAutocomplete() { return (from f in typeof(SharedData).GetFields(BindingFlags.Instance | BindingFlags.Public) where validTypes.Contains(f.FieldType) || f.FieldType.IsEnum select f into p select p.Name).ToList(); } private static List ItemDropsByField(List items, string field, string value) { string field2 = field; string value2 = value; return items.Where(delegate(GameObject item) { ItemDrop component = item.GetComponent(); if ((Object)(object)component == (Object)null) { return false; } ItemData itemData = component.m_itemData; if (itemData == null) { return false; } SharedData shared = itemData.m_shared; if (shared == null) { return false; } FieldInfo field3 = typeof(SharedData).GetField(field2, BindingFlags.Instance | BindingFlags.Public); return !(field3 == null) && field3.GetValue(shared).ToString().ToLowerInvariant() == value2; }).ToList(); } } public class SearchIdCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { <>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0(); if (args.Length < 2) { ZLog.Log((object)("\n" + string.Join("\n", ParameterInfo.ObjectIds))); return; } CS$<>8__locals0.term = ((args.Length < 2) ? "" : args[1].ToLower()); int num = args.TryParameterInt(2, 5); string[] array = ((CS$<>8__locals0.term == "") ? ParameterInfo.ObjectIds.ToArray() : ParameterInfo.ObjectIds.Where((string id) => id.ToLower().Contains(CS$<>8__locals0.term)).ToArray()); if (array.Length > 100) { args.Context.AddString("Over 100 results, printing to the log file."); ZLog.Log((object)("\n" + string.Join("\n", array))); return; } int num2 = (int)Math.Ceiling((float)array.Length / (float)num); string[] array2 = new string[num2]; for (int i = 0; i < array.Length; i += num2) { if (array.Length - i < num2) { num2 = array.Length - i; array2 = new string[num2]; } Array.Copy(array, i, array2, 0, num2); args.Context.AddString(string.Join(", ", array2)); } } internal List <.ctor>b__0_1(int index) { return index switch { 0 => ParameterInfo.Create("Search term"), 1 => ParameterInfo.Create("Max lines", "number (default 5)"), _ => ParameterInfo.None, }; } } [CompilerGenerated] private sealed class <>c__DisplayClass0_0 { public string term; internal bool <.ctor>b__2(string id) { return id.ToLower().Contains(term); } } public SearchIdCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length < 2) { ZLog.Log((object)("\n" + string.Join("\n", ParameterInfo.ObjectIds))); } else { string term = ((args.Length < 2) ? "" : args[1].ToLower()); int num = args.TryParameterInt(2, 5); string[] array = ((term == "") ? ParameterInfo.ObjectIds.ToArray() : ParameterInfo.ObjectIds.Where((string id) => id.ToLower().Contains(term)).ToArray()); if (array.Length > 100) { args.Context.AddString("Over 100 results, printing to the log file."); ZLog.Log((object)("\n" + string.Join("\n", array))); } else { int num2 = (int)Math.Ceiling((float)array.Length / (float)num); string[] array2 = new string[num2]; for (int i = 0; i < array.Length; i += num2) { if (array.Length - i < num2) { num2 = array.Length - i; array2 = new string[num2]; } Array.Copy(array, i, array2, 0, num2); args.Context.AddString(string.Join(", ", array2)); } } } }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("search_id", "[term] [max_lines=5] - Prints object ids matching the search term. Without term, prints all of them to the log file.", (ConsoleEvent)obj); AutoComplete.Register("search_id", (int index) => index switch { 0 => ParameterInfo.Create("Search term"), 1 => ParameterInfo.Create("Max lines", "number (default 5)"), _ => ParameterInfo.None, }); } } public class SeedCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <.ctor>b__0_0(ConsoleEventArgs args) { Helper.AddMessage(args.Context, WorldGenerator.instance.m_world.m_seedName); } } public SeedCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.AddMessage(args.Context, WorldGenerator.instance.m_world.m_seedName); }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("seed", "Prints the world seed.", (ConsoleEvent)obj); AutoComplete.RegisterEmpty("seed"); } } public class ServerCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; public static Func> <>9__1_1; internal void <.ctor>b__1_0(ConsoleEventArgs args) { if (args.Length >= 2) { ServerExecution.Send(string.Join(" ", args.Args.Skip(1))); } } internal List <.ctor>b__1_1(int index) { if (index == 0) { return ParameterInfo.Create("Seconds", "a number (default 240.0)"); } return ParameterInfo.None; } } private void MakeServer(string name) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown ConsoleCommand original = Terminal.commands[name]; Helper.Command(name, original.Description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { ServerExecution.Send(args); } else { original.action.Invoke(args); } }); } public ServerCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length >= 2) { ServerExecution.Send(string.Join(" ", args.Args.Skip(1))); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("server", "[command] - Executes the given command on the server.", (ConsoleEvent)obj, false, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.RegisterEmpty("server"); AutoComplete.Offsets["server"] = 0; MakeServer("randomevent"); AutoComplete.RegisterEmpty("randomevent"); MakeServer("stopevent"); AutoComplete.RegisterEmpty("stopevent"); AutoComplete.RegisterEmpty("genloc"); AutoComplete.RegisterEmpty("sleep"); AutoComplete.Register("skiptime", (int index) => (index == 0) ? ParameterInfo.Create("Seconds", "a number (default 240.0)") : ParameterInfo.None); AutoComplete.RegisterEmpty("resetkeys"); } } public class ShutdownCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <.ctor>b__0_0(ConsoleEventArgs args) { Helper.AddMessage(args.Context, "Shutting down..."); Menu.instance.OnQuitYes(); } } public ShutdownCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Helper.AddMessage(args.Context, "Shutting down..."); Menu.instance.OnQuitYes(); }; <>c.<>9__0_0 = val; obj = (object)val; } Helper.Command("shutdown", "- Closes the game.", (ConsoleEvent)obj); AutoComplete.RegisterEmpty("shutdown"); } } public class StartEventCommand { [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 Func> <>9__1_1; internal void <.ctor>b__1_0(ConsoleEventArgs args) { if (args.Length >= 2) { string[] args2 = Helper.AddPlayerPosXZ(args.Args, 2); if (ZNet.instance.IsServer()) { DoStartEvent(args2, args.Context); } else { ServerExecution.Send((IEnumerable)args2); } } } internal List <.ctor>b__1_1(int index) { return index switch { 0 => RandEventSystem.instance.m_events.Select((RandomEvent ev) => ev.m_name).ToList(), 1 => ParameterInfo.Create("X coordinate", "number (default is the current position)"), 2 => ParameterInfo.Create("Z coordinate", "number (default is the current position)"), _ => ParameterInfo.None, }; } internal string <.ctor>b__1_2(RandomEvent ev) { return ev.m_name; } } private static void DoStartEvent(string[] args, Terminal context) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (args.Length >= 2) { string text = args[1]; if (!RandEventSystem.instance.HaveEvent(text)) { context.AddString("Random event not found:" + text); return; } float num = Parse.Float(args, 2); float num2 = Parse.Float(args, 3); RandEventSystem.instance.SetRandomEventByName(text, new Vector3(num, 0f, num2)); } } public StartEventCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length >= 2) { string[] args2 = Helper.AddPlayerPosXZ(args.Args, 2); if (ZNet.instance.IsServer()) { DoStartEvent(args2, args.Context); } else { ServerExecution.Send((IEnumerable)args2); } } }; <>c.<>9__1_0 = val; obj = (object)val; } Helper.Command("event", "[name] [x] [z] - start event.", (ConsoleEvent)obj); AutoComplete.Register("event", (int index) => index switch { 0 => RandEventSystem.instance.m_events.Select((RandomEvent ev) => ev.m_name).ToList(), 1 => ParameterInfo.Create("X coordinate", "number (default is the current position)"), 2 => ParameterInfo.Create("Z coordinate", "number (default is the current position)"), _ => ParameterInfo.None, }); } } [HarmonyPatch(typeof(RandEventSystem), "StartRandomEvent")] public class DisableRandomEvents { private static bool Prefix() { return !Settings.DisableEvents; } } public class TeleportCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func> <>9__0_0; public static ConsoleEvent <>9__0_1; internal List <.ctor>b__0_0(int index, int subIndex) { switch (index) { case 0: return ParameterInfo.PlayerNames; case 1: if (subIndex != 0) { return ParameterInfo.XZYR("Coordinates", subIndex); } return ParameterInfo.PublicPlayerNames; case 2: return ParameterInfo.Flag("fast", subIndex); default: return ParameterInfo.None; } } internal void <.ctor>b__0_1(ConsoleEventArgs args) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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) //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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing player id/name."); List list = PlayerInfo.FindPlayers(Parse.Split(args[1])); Vector3 val = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero); Quaternion val2 = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.rotation : Quaternion.identity); if (args.Length > 2) { string[] array = Parse.Split(args[2]); if (array.Length > 1) { val = Parse.VectorXZY(array); float height = WorldGenerator.instance.GetHeight(val.x, val.z); val.y = Mathf.Max(val.y, height); if (array.Length > 3) { float num = Parse.Float(array[3]); val2 = Quaternion.Euler(0f, num, 0f); } } else { List list2 = PlayerInfo.FindPlayers(array); if (list2.Count == 0) { throw new InvalidOperationException("No target player found with id/name '" + args[2] + "'."); } val = list2[0].Pos; val2 = list2[0].Rot; } } bool flag = args.Length > 3 && args[3].Equals("fast", StringComparison.OrdinalIgnoreCase); foreach (PlayerInfo item in list) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, item.ZDOID, "RPC_TeleportTo", new object[3] { val, val2, !flag }); } } } public TeleportCommand() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown AutoComplete.Register("tp", delegate(int index, int subIndex) { switch (index) { case 0: return ParameterInfo.PlayerNames; case 1: if (subIndex != 0) { return ParameterInfo.XZYR("Coordinates", subIndex); } return ParameterInfo.PublicPlayerNames; case 2: return ParameterInfo.Flag("fast", subIndex); default: return ParameterInfo.None; } }); object obj = <>c.<>9__0_1; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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) //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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) Helper.ArgsCheck(args, 2, "Missing player id/name."); List list = PlayerInfo.FindPlayers(Parse.Split(args[1])); Vector3 val2 = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero); Quaternion val3 = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.rotation : Quaternion.identity); if (args.Length > 2) { string[] array = Parse.Split(args[2]); if (array.Length > 1) { val2 = Parse.VectorXZY(array); float height = WorldGenerator.instance.GetHeight(val2.x, val2.z); val2.y = Mathf.Max(val2.y, height); if (array.Length > 3) { float num = Parse.Float(array[3]); val3 = Quaternion.Euler(0f, num, 0f); } } else { List list2 = PlayerInfo.FindPlayers(array); if (list2.Count == 0) { throw new InvalidOperationException("No target player found with id/name '" + args[2] + "'."); } val2 = list2[0].Pos; val3 = list2[0].Rot; } } bool flag = args.Length > 3 && args[3].Equals("fast", StringComparison.OrdinalIgnoreCase); foreach (PlayerInfo item in list) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, item.ZDOID, "RPC_TeleportTo", new object[3] { val2, val3, !flag }); } }; <>c.<>9__0_1 = val; obj = (object)val; } Helper.Command("tp", "[player1,player2,...] [x,z,y,rot/player] [fast=false] - Teleports the player to coordinates or another player.", (ConsoleEvent)obj); } } public class UndoRedoCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { UndoManager.Undo(args.Context); } internal void <.ctor>b__0_1(ConsoleEventArgs args) { UndoManager.Redo(args.Context); } } public UndoRedoCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0070: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { UndoManager.Undo(args.Context); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("undo", "Reverts some commands.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { UndoManager.Redo(args.Context); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("redo", "Restores reverted commands.", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.RegisterEmpty("undo"); AutoComplete.RegisterEmpty("redo"); } } public class WaitCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { } internal List <.ctor>b__0_1(int index) { if (index != 0) { return ParameterInfo.None; } return ParameterInfo.Create("Duration in milliseconds."); } } public WaitCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate { }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("wait", "[duration] - Milliseconds to wait before executing the next command.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("wait", (int index) => (index != 0) ? ParameterInfo.None : ParameterInfo.Create("Duration in milliseconds.")); } } public class WindCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static Func> <>9__0_1; internal void <.ctor>b__0_0(ConsoleEventArgs args) { EnvMan instance = EnvMan.instance; if (Object.op_Implicit((Object)(object)instance)) { if (args.Length < 3) { Helper.AddMessage(args.Context, $"Wind: {instance.GetWindIntensity()}."); return; } float num = Parse.Float(args[1]); float num2 = Parse.Float(args[2]); EnvMan.instance.SetDebugWind(num, num2); } } internal List <.ctor>b__0_1(int index) { return index switch { 0 => ParameterInfo.Create("Angle", "a number (from -360.0 to 360.0)"), 1 => ParameterInfo.Create("Intensity", "a positive number (from 0.0 to 1.0)"), _ => ParameterInfo.None, }; } } public WindCommand() { //IL_0038: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { EnvMan instance = EnvMan.instance; if (Object.op_Implicit((Object)(object)instance)) { if (args.Length < 3) { Helper.AddMessage(args.Context, $"Wind: {instance.GetWindIntensity()}."); } else { float num = Parse.Float(args[1]); float num2 = Parse.Float(args[2]); EnvMan.instance.SetDebugWind(num, num2); } } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("wind", "[angle] [intensity] - Prints or overrides the wind.", (ConsoleEvent)obj, true, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); AutoComplete.Register("wind", (int index) => index switch { 0 => ParameterInfo.Create("Angle", "a number (from -360.0 to 360.0)"), 1 => ParameterInfo.Create("Intensity", "a positive number (from 0.0 to 1.0)"), _ => ParameterInfo.None, }); } } [HarmonyPatch] public class AliasManager { public static string FileName = "alias.yaml"; public static string FilePath = Path.Combine(Paths.ConfigPath, FileName); public static bool ToBeSaved = false; public static void Init() { if (File.Exists(FilePath)) { FromFile(); } else { ToFile(); } } public static void ToFile() { ToBeSaved = false; Dictionary dictionary = Settings.AliasKeys.ToDictionary((string key) => key, (string key) => Settings.GetAliasValue(key)); if (dictionary.Count == 0) { if (File.Exists(FilePath)) { File.Delete(FilePath); } } else { string contents = Yaml.Serializer().Serialize(dictionary); File.WriteAllText(FilePath, contents); } } public static void FromFile() { try { Dictionary dictionary = Yaml.Read(FilePath, Yaml.Deserialize>); Settings.AddAlias(dictionary); ServerDevcommands.Log.LogInfo((object)$"Reloading {dictionary.Count} alias data."); } catch (Exception ex) { ServerDevcommands.Log.LogError((object)ex.StackTrace); } } public static void SetupWatcher() { Yaml.SetupWatcher(FileName, FromFile); } } public class BindData { [DefaultValue("")] public string keys = ""; [DefaultValue("")] public string state = ""; public string? key; public string? modifiers; [DefaultValue("")] public string command = ""; [DefaultValue("")] public string offCommand = ""; } public class CommandBind { public List Required = new List(); public List? Banned; public List? RequiredState; public List? BannedState; public bool MouseWheel; public string Command = ""; public string OffCommand = ""; public bool Executed; public bool WasExecuted; public string? Keys; public bool Temporary; } [HarmonyPatch] public class BindManager { public static string FileName = "binds.yaml"; public static string FilePath = Path.Combine(Paths.ConfigPath, FileName); private static List Binds = new List(); private static List WheelBinds = new List(); private static readonly List TemporaryBinds = new List(); public static bool ToBeSaved = false; private static string Mode = ""; public static void AddBind(string keys, string command) { CommandBind commandBind = FromData(new BindData { key = keys, command = command }, temporary: false); if (commandBind.MouseWheel) { WheelBinds.Add(commandBind); } else { Binds.Add(commandBind); } ToBeSaved = true; } public static void RemoveBind(string key) { KeyCode keyCode; if (key == "wheel") { WheelBinds.Clear(); } else if (TryParse(key, out keyCode)) { Binds.RemoveAll((CommandBind bind) => bind.Required != null && bind.Required.Contains(keyCode)); WheelBinds.RemoveAll((CommandBind bind) => bind.Required != null && bind.Required.Contains(keyCode)); } ToBeSaved = true; } public static void SetTemporaryBind(string keys, string mode, string command, string offCommand) { string command2 = command; BindData data = new BindData { key = keys, modifiers = mode, command = command2, offCommand = offCommand }; TemporaryBinds.RemoveAll((CommandBind b) => b.Command == command2); WheelBinds.RemoveAll((CommandBind b) => b.Command == command2); Binds.RemoveAll((CommandBind b) => b.Command == command2); CommandBind commandBind = FromData(data, temporary: true); if (commandBind.MouseWheel || commandBind.Required.Count != 0) { TemporaryBinds.Add(commandBind); if (commandBind.MouseWheel) { WheelBinds.Add(commandBind); } else if (commandBind.Required.Count > 0) { Binds.Add(commandBind); } } } public static void ClearBinds() { Binds.Clear(); WheelBinds.Clear(); ToBeSaved = true; } public static CommandBind FromData(BindData data, bool temporary) { //IL_00f0: 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) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) CommandBind commandBind = new CommandBind { Command = data.command, OffCommand = data.offCommand, Keys = data.key, Temporary = temporary }; if (data.keys != null) { string[] array = Parse.Split(data.keys); foreach (string text in array) { if (text == "wheel") { commandBind.MouseWheel = true; } else if (text == "-wheel") { commandBind.MouseWheel = false; } else if (text.StartsWith("-")) { CommandBind commandBind2 = commandBind; if (commandBind2.Banned == null) { commandBind2.Banned = new List(); } if (TryParse(text.Substring(1), out var keyCode)) { commandBind.Banned.Add(keyCode); } } else { CommandBind commandBind2 = commandBind; if (commandBind2.Required == null) { commandBind2.Required = new List(); } if (TryParse(text, out var keyCode2)) { commandBind.Required.Add(keyCode2); } } } } if (data.state != null) { string[] array = Parse.Split(data.state); foreach (string text2 in array) { if (text2 == "wheel") { commandBind.MouseWheel = true; } else if (text2 == "-wheel") { commandBind.MouseWheel = false; } else if (text2.StartsWith("-")) { CommandBind commandBind2 = commandBind; if (commandBind2.BannedState == null) { commandBind2.BannedState = new List(); } commandBind.BannedState.Add(text2.Substring(1)); } else { CommandBind commandBind2 = commandBind; if (commandBind2.RequiredState == null) { commandBind2.RequiredState = new List(); } commandBind.RequiredState.Add(text2); } } } if (data.key != null) { string[] array = Parse.Split(data.key); foreach (string text3 in array) { if (text3 == "wheel") { commandBind.MouseWheel = true; } else if (text3 == "-wheel") { commandBind.MouseWheel = false; } else if (text3.StartsWith("-")) { CommandBind commandBind2 = commandBind; if (commandBind2.Banned == null) { commandBind2.Banned = new List(); } if (Enum.TryParse(text3.Substring(1), ignoreCase: true, out KeyCode result)) { commandBind.Banned.Add(result); } } else { CommandBind commandBind2 = commandBind; if (commandBind2.Required == null) { commandBind2.Required = new List(); } if (Enum.TryParse(text3, ignoreCase: true, out KeyCode result2)) { commandBind.Required.Add(result2); } } } } if (data.modifiers != null) { string[] array = Parse.Split(data.modifiers); foreach (string text4 in array) { if (text4 == "wheel") { commandBind.MouseWheel = true; continue; } if (text4 == "-wheel") { commandBind.MouseWheel = false; continue; } CommandBind commandBind2; if (text4.StartsWith("-")) { commandBind2 = commandBind; if (commandBind2.Banned == null) { commandBind2.Banned = new List(); } if (Enum.TryParse(text4.Substring(1), ignoreCase: true, out KeyCode result3)) { commandBind.Banned.Add(result3); continue; } commandBind2 = commandBind; if (commandBind2.BannedState == null) { commandBind2.BannedState = new List(); } commandBind.BannedState.Add(text4.Substring(1)); continue; } commandBind2 = commandBind; if (commandBind2.Required == null) { commandBind2.Required = new List(); } if (Enum.TryParse(text4, ignoreCase: true, out KeyCode result4)) { commandBind.Required.Add(result4); continue; } commandBind2 = commandBind; if (commandBind2.RequiredState == null) { commandBind2.RequiredState = new List(); } commandBind.RequiredState.Add(text4); } } if (!temporary && commandBind.Command.StartsWith("_")) { commandBind.Temporary = true; } List? requiredState = commandBind.RequiredState; if (requiredState != null && requiredState.Contains("unbound")) { commandBind.MouseWheel = false; commandBind.Required = new List(); ToBeSaved = true; } return commandBind; } private static bool TryParse(string str, out KeyCode keyCode) { if (Enum.TryParse(str, ignoreCase: true, out keyCode)) { return true; } ServerDevcommands.Log.LogWarning((object)("Failed to parse " + str + " as KeyCode.")); return false; } public static BindData ToData(string command) { string[] array = command.Split(new char[1] { ' ' }); BindData bindData = new BindData { key = array[0] }; if (bindData.key.ToLower() == "none") { bindData.key = "wheel"; } string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string[] array3 = array2[i].Split(new char[1] { '=' }); if (array3.Length != 1 && array3[0] == "keys") { bindData.modifiers = array3[1]; } } IEnumerable values = from arg in array.Skip(1) where !arg.StartsWith("keys=", StringComparison.OrdinalIgnoreCase) select arg; bindData.command = string.Join(" ", values); return bindData; } public static BindData ToData(CommandBind commandBind) { List list = new List(); if (commandBind.Required != null) { list.AddRange(commandBind.Required.Select((KeyCode key) => ((object)(KeyCode)(ref key)).ToString().ToLower())); } if (commandBind.Banned != null) { list.AddRange(commandBind.Banned.Select((KeyCode key) => "-" + ((object)(KeyCode)(ref key)).ToString().ToLower())); } if (commandBind.MouseWheel) { list.Add("wheel"); } List list2 = new List(); if (commandBind.RequiredState != null) { list2.AddRange(commandBind.RequiredState.Select((string state) => state.ToString().ToLower())); } if (commandBind.BannedState != null) { list2.AddRange(commandBind.BannedState.Select((string state) => "-" + state.ToString().ToLower())); } return new BindData { keys = string.Join(", ", list), state = string.Join(", ", list2), command = commandBind.Command, offCommand = commandBind.OffCommand }; } private static void ImportBinds() { BindData[] array = Terminal.m_bindList.Select(ToData).ToArray(); if (array.Length != 0) { string contents = Yaml.Serializer().Serialize(array); File.WriteAllText(FilePath, contents); ServerDevcommands.Log.LogInfo((object)$"Importing {array.Length} bind data."); } } [HarmonyPatch(typeof(Chat), "Awake")] [HarmonyPostfix] public static void ChatAwake() { if (File.Exists(FilePath)) { FromFile(); } else { ImportBinds(); } } public static void ToFile() { ToBeSaved = false; List list = new List(); list.AddRange(Binds.Where((CommandBind b) => !b.Temporary).Select(ToData)); list.AddRange(WheelBinds.Where((CommandBind b) => !b.Temporary).Select(ToData)); List list2 = list; if (list2.Count == 0) { if (File.Exists(FilePath)) { File.Delete(FilePath); } } else { string contents = Yaml.Serializer().Serialize(list2); File.WriteAllText(FilePath, contents); } } public static void FromFile() { try { Terminal.m_bindList.Clear(); Terminal.m_binds.Clear(); List list = (from d in Yaml.Read(FilePath, Yaml.Deserialize>) select FromData(d, temporary: false) into b where b.MouseWheel || b.Required.Count > 0 select b).ToList(); list.AddRange(TemporaryBinds); List list2 = new List(); list2.AddRange(list.Where((CommandBind bind) => !bind.MouseWheel)); Binds = list2; List list3 = new List(); list3.AddRange(list.Where((CommandBind bind) => bind.MouseWheel)); WheelBinds = list3; ServerDevcommands.Log.LogInfo((object)$"Reloading {list.Count} bind data."); } catch (Exception ex) { ServerDevcommands.Log.LogError((object)ex.StackTrace); } } public static void SetupWatcher() { ZInput.s_keyCodeToKeyMap[(KeyCode)294] = (Key)112; ZInput.s_keyCodeToKeyMap[(KeyCode)295] = (Key)113; ZInput.s_keyCodeToKeyMap[(KeyCode)296] = (Key)114; ZInput.s_keyCodeToKeyMap[(KeyCode)670] = (Key)115; ZInput.s_keyCodeToKeyMap[(KeyCode)671] = (Key)116; ZInput.s_keyCodeToKeyMap[(KeyCode)672] = (Key)117; ZInput.s_keyCodeToKeyMap[(KeyCode)673] = (Key)118; ZInput.s_keyCodeToKeyMap[(KeyCode)674] = (Key)119; ZInput.s_keyCodeToKeyMap[(KeyCode)675] = (Key)120; ZInput.s_keyCodeToKeyMap[(KeyCode)676] = (Key)121; ZInput.s_keyCodeToKeyMap[(KeyCode)677] = (Key)122; ZInput.s_keyCodeToKeyMap[(KeyCode)678] = (Key)123; Yaml.SetupWatcher(FileName, FromFile); } public static List GetBestKeyCommands() { return GetBestCommands(Binds); } public static List GetBestWheelCommands() { return GetBestCommands(WheelBinds); } private static List GetBestCommands(List binds) { int num = 0; List list = new List(); foreach (CommandBind bind in binds) { if (!IsValid(bind)) { continue; } int count = bind.Required.Count; if (count >= num) { if (count > num) { list.Clear(); } num = count; list.Add(bind); } } return list; } public static int GetBestKeyCount() { return GetKeyCount(Binds); } public static int GetBestWheelCount() { return GetKeyCount(WheelBinds); } private static int GetKeyCount(List binds) { int num = 0; foreach (CommandBind bind in binds) { if (IsValid(bind)) { int num2 = ((bind.Required != null) ? bind.Required.Count : 0); if (num2 > num) { num = num2; } } } return num; } public static bool CouldKeyExecute() { return CouldExecute(Binds); } public static bool CouldWheelExecute() { return CouldExecute(WheelBinds); } private static bool CouldExecute(List binds) { foreach (CommandBind bind in binds) { if (IsValid(bind)) { return true; } } return false; } public static void SetMode(string mode) { Mode = mode; } private static bool IsValid(CommandBind bind) { object obj; if (!(Mode == "")) { obj = Mode; } else { Player localPlayer = Player.m_localPlayer; obj = ((localPlayer != null && ((Character)localPlayer).InPlaceMode()) ? "build" : ""); } string mode = (string)obj; if (!bind.MouseWheel && (bind.Required == null || bind.Required.Count == 0)) { return false; } if (bind.Required.Any((KeyCode key) => !GetKey(key))) { return false; } if (bind.Banned != null && bind.Banned.Any(GetKey)) { return false; } if (bind.RequiredState != null && bind.RequiredState.All((string state) => state != mode)) { return false; } if (bind.BannedState != null && bind.BannedState.Any((string state) => state == mode)) { return false; } return true; } public static bool GetKey(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((int)key == 326) { return ZInput.GetKey((KeyCode)327, true); } if ((int)key == 327) { return ZInput.GetKey((KeyCode)326, true); } if ((int)key == 328) { return Input.GetKey((KeyCode)328); } if ((int)key == 329) { return Input.GetKey((KeyCode)329); } return ZInput.GetKey(key, true); } public static void PrintBinds(Terminal terminal) { if (Binds.Count == 0 && WheelBinds.Count == 0) { terminal.AddString("No binds found."); return; } if (Binds.Count > 0) { terminal.AddString("Binds:"); } foreach (CommandBind bind in Binds) { terminal.AddString(PrintBind(bind)); } if (WheelBinds.Count > 0) { terminal.AddString("Wheel binds:"); } foreach (CommandBind wheelBind in WheelBinds) { terminal.AddString(PrintBind(wheelBind)); } } public static Tuple[] GetBinds() { List> list = new List>(); list.AddRange(Binds.Select((CommandBind bind) => new Tuple(GetInput(bind), bind.Command))); return list.ToArray(); } public static Tuple[] GetWheelBinds() { List> list = new List>(); list.AddRange(WheelBinds.Select((CommandBind bind) => new Tuple(GetInput(bind), bind.Command))); return list.ToArray(); } private static string PrintBind(CommandBind bind) { return GetInput(bind) + ": " + bind.Command; } private static string GetInput(CommandBind bind) { List list = new List(); if (bind.Required != null) { list.AddRange(bind.Required.Select((KeyCode key) => ((object)(KeyCode)(ref key)).ToString())); } if (bind.Banned != null) { list.AddRange(bind.Banned.Select((KeyCode key) => "-" + ((object)(KeyCode)(ref key)).ToString())); } if (bind.RequiredState != null) { list.AddRange(bind.RequiredState.Select((string state) => state.ToString())); } if (bind.BannedState != null) { list.AddRange(bind.BannedState.Select((string state) => "-" + state.ToString())); } return string.Join(",", list); } public static List GetOffBinds() { List list = new List(); foreach (CommandBind bind in Binds) { if (bind.Executed) { bind.WasExecuted = true; bind.Executed = false; } else if (bind.WasExecuted) { list.Add(bind); } } return list; } } public class Yaml { public static void SetupWatcher(string pattern, Action action) { SetupWatcher(Paths.ConfigPath, pattern, action); } public static void SetupWatcher(string path, string pattern, Action action) { Action action2 = action; FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(path, pattern); fileSystemWatcher.Created += delegate { action2(); }; fileSystemWatcher.Changed += delegate { action2(); }; fileSystemWatcher.Renamed += delegate { action2(); }; fileSystemWatcher.Deleted += delegate { action2(); }; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } public static IDeserializer Deserializer() { return new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); } public static IDeserializer DeserializerUnSafe() { return new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).IgnoreUnmatchedProperties().Build(); } public static ISerializer Serializer() { return new SerializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).DisableAliases().ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults) .WithTypeConverter(new FloatConverter()) .WithEventEmitter((IEventEmitter nextEmitter) => new MultilineScalarFlowStyleEmitter(nextEmitter)) .Build(); } public static T Deserialize(string raw, string fileName) where T : new() { try { return Deserializer().Deserialize(raw); } catch (Exception ex) { ServerDevcommands.Log.LogError((object)(fileName + ": " + ex.Message)); try { return DeserializerUnSafe().Deserialize(raw); } catch (Exception) { return new T(); } } } public static List LoadList(string file) where T : new() { if (!File.Exists(file)) { return new List(); } return Deserialize>(File.ReadAllText(file), file); } public static T Load(string file) where T : new() { if (!File.Exists(file)) { return new T(); } return Deserialize(File.ReadAllText(file), file); } public static T Read(string file, Func action) where T : new() { if (!File.Exists(file)) { return new T(); } return action(File.ReadAllText(file), file); } public static Dictionary> Read(string pattern, Func> action) { Dictionary> dictionary = new Dictionary>(); string[] files = Directory.GetFiles(Paths.ConfigPath, pattern); foreach (string text in files) { foreach (KeyValuePair item in action(File.ReadAllText(text), text)) { if (!dictionary.TryGetValue(item.Key, out var value)) { value = new List(); dictionary[item.Key] = value; } value.AddRange(item.Value); } } return dictionary; } } public class FloatConverter : IYamlTypeConverter { public bool Accepts(Type type) { return type == typeof(float); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { float num = float.Parse(((YamlDotNet.Core.Events.Scalar)parser.Current).Value, NumberStyles.Float, CultureInfo.InvariantCulture); parser.MoveNext(); return num; } public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer) { emitter.Emit(new YamlDotNet.Core.Events.Scalar(((float)value).ToString("0.###", CultureInfo.InvariantCulture))); } } public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter { public MultilineScalarFlowStyleEmitter(IEventEmitter nextEmitter) : base(nextEmitter) { } public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter) { if (typeof(string).IsAssignableFrom(eventInfo.Source.Type)) { string text = eventInfo.Source.Value as string; if (!string.IsNullOrEmpty(text) && text.IndexOfAny(new char[5] { '\r', '\n', '\u0085', '\u2028', '\u2029' }) >= 0) { eventInfo = new ScalarEventInfo(eventInfo.Source) { Style = ScalarStyle.Literal }; } } nextEmitter.Emit(eventInfo, emitter); } } [HarmonyPatch(typeof(Container))] public class AccessPrivateChests { [HarmonyPatch("CheckAccess")] [HarmonyPostfix] private static bool CheckAccess(bool result) { if (!result) { return Settings.AccessPrivateChests; } return true; } [HarmonyPatch("RPC_OpenRespons")] [HarmonyPrefix] private static void RPC_OpenRespons(ref bool granted) { granted |= Settings.AccessPrivateChests; } } [HarmonyPatch(typeof(PrivateArea), "HaveLocalAccess")] public class AccessWardedAreas { private static void Postfix(ref bool __result) { __result |= Settings.AccessWardedAreas; } } public static class Aliasing { private static string Alias = ""; public static void RemoveAlias(GuiInputField input) { if (!Settings.Aliasing) { return; } Alias = GetAlias(((TMP_InputField)input).text); if (!(Alias == string.Empty)) { if (Alias == ((TMP_InputField)input).text) { Alias = string.Empty; return; } string text = Plain(Alias); ((TMP_InputField)input).text = text + ((TMP_InputField)input).text.Substring(Alias.Length); ((TMP_InputField)input).caretPosition = ((TMP_InputField)input).caretPosition + (text.Length - Alias.Length); } } public static void RestoreAlias(GuiInputField input) { if (Settings.Aliasing && !(Alias == string.Empty)) { string text = Plain(Alias); if (((TMP_InputField)input).text.StartsWith(text)) { ((TMP_InputField)input).caretPosition = ((TMP_InputField)input).caretPosition - (text.Length - Alias.Length); ((TMP_InputField)input).text = Alias + ((TMP_InputField)input).text.Substring(text.Length); } } } public static string Plain(string command) { return Plain(command, 10); } private static string Plain(string command, int rounds) { if (!Settings.Aliasing) { return command; } if (command == "") { return ""; } if (TerminalUtils.SkipProcessing(command)) { return command; } if (rounds == 0) { return command; } string[] aliasKeys = Settings.AliasKeys; foreach (string text in aliasKeys) { if (command.Length < text.Length) { continue; } if (command == text) { return Plain(Settings.GetAliasValue(text), rounds - 1); } if (command != text) { if (!command.StartsWith(text)) { continue; } char c = command[text.Length]; if (c != ' ' && c != ',' && c != '=' && c != ';') { continue; } } command = TerminalUtils.Substitute(Settings.GetAliasValue(text), command.Substring(text.Length + 1)); return Plain(command, rounds - 1); } return command; } private static string GetAlias(string command) { if (command == "") { return ""; } if (TerminalUtils.SkipProcessing(command)) { return command; } string[] aliasKeys = Settings.AliasKeys; foreach (string text in aliasKeys) { if (command.Length < text.Length) { continue; } if (command != text) { if (!command.StartsWith(text)) { continue; } char c = command[text.Length]; if (c != ' ' && c != ',' && c != '=') { continue; } } return text; } return ""; } } public static class AutoComplete { private static readonly Dictionary>> OptionsFetchers = new Dictionary>>(); private static readonly Dictionary>>> OptionsNamedFetchers = new Dictionary>>>(); public static Dictionary Offsets = new Dictionary(); public static List? GetOptions(string command, int index) { command = command.ToLower(); if (OptionsFetchers.ContainsKey(command)) { return OptionsFetchers[command](index, 0, Array.Empty()); } if (index == 0 && Terminal.commands.TryGetValue(command, out var value) && value.m_tabOptionsFetcher != null) { return value.m_tabOptionsFetcher.Invoke(); } return null; } private static List GetOptions(string command, int index, int subIndex, string namedArg, string[] args) { command = command.ToLower(); if (namedArg != "") { if (OptionsNamedFetchers.TryGetValue(command, out Dictionary>> value) && value.TryGetValue(namedArg.ToLower(), out var value2)) { return value2(index) ?? ParameterInfo.None; } return ParameterInfo.InvalidNamed(namedArg); } if (OptionsFetchers.ContainsKey(command)) { return OptionsFetchers[command](index, subIndex, args) ?? ParameterInfo.None; } if (Terminal.commands.TryGetValue(command, out var value3) && value3.m_tabOptionsFetcher != null) { return value3.m_tabOptionsFetcher.Invoke() ?? ParameterInfo.Missing; } return ParameterInfo.Missing; } public static void Register(string command, Func> fetcher, Dictionary>> namedFetchers) { OptionsFetchers[command.ToLower()] = fetcher; OptionsNamedFetchers[command.ToLower()] = namedFetchers.ToDictionary>>, string, Func>>((KeyValuePair>> kvp) => kvp.Key.ToLower(), (KeyValuePair>> kvp) => kvp.Value); } public static void Register(string command, Func> fetcher, Dictionary>> namedFetchers) { Func> fetcher2 = fetcher; Register(command, (int index, int subIndex, string[] args) => fetcher2(index, subIndex), namedFetchers); } public static void Register(string command, Func> fetcher, Dictionary>> namedFetchers) { Func> fetcher2 = fetcher; Register(command, (int index, int subIndex, string[] args) => fetcher2(index), namedFetchers); } public static void Register(string command, Func> fetcher) { OptionsFetchers[command] = fetcher; } public static void Register(string command, Func> fetcher) { Func> fetcher2 = fetcher; OptionsFetchers[command] = (int index, int subIndex, string[] args) => fetcher2(index, subIndex); } public static void Register(string command, Func> fetcher) { Func> fetcher2 = fetcher; OptionsFetchers[command] = (int index, int subIndex, string[] args) => fetcher2(index); } public static void RegisterEmpty(string command) { Register(command, (int index) => ParameterInfo.None); } public static void RegisterAdmin(string command) { Register(command, (int index) => (index == 0) ? ParameterInfo.Create("Name / IP / UserId") : ParameterInfo.None); } public static void RegisterDefault(string command) { string command2 = command; Register(command2, (int index) => (index == 0) ? Terminal.commands[command2].m_tabOptionsFetcher.Invoke() : ParameterInfo.None); } public static List GetOptions(string[] args) { string text = args.First(); if (Offsets.TryGetValue(text, out var value) && args.Length - 1 > value) { List list = new List(); list.AddRange(args.Skip(value + 1)); args = list.ToArray(); text = args.First(); } if (args.Length < 2) { return ((Terminal)Console.instance).m_commandList; } args = args.Skip(1).ToArray(); string parameter = args.Last(); string name = GetName(parameter); int subIndex = GetSubIndex(parameter); int num; if (name != "") { num = subIndex; } else { num = TerminalUtils.GetPositionalParameters(args).Count() - 1; if (Settings.Substitution != "") { int num2 = TerminalUtils.GetAmountOfSubstitutions(args); for (int i = 0; i < args.Length; i++) { if (num2 <= 0) { break; } string parameter2 = args[i]; int num3 = CountSubstitution(parameter2); num -= num3; num2 -= num3; if (num2 <= 0) { name = GetName(parameter2); num = ((!(name != "")) ? i : (num2 + GetSubIndex(parameter) + GetSubIndex(parameter2))); } } } } return GetOptions(text, num, subIndex, name, args); } private static string GetName(string parameter) { string[] array = parameter.Split(new char[1] { '=' }); if (array.Length < 2) { return ""; } return array[0]; } private static int GetSubIndex(string parameter) { return parameter.Split(new char[1] { ',' }).Length - 1; } private static int CountSubstitution(string parameter) { int num = 0; int length = Settings.Substitution.Length; int num2 = -length; while ((num2 = parameter.IndexOf(Settings.Substitution, num2 + length)) > -1) { num++; } return num; } } [HarmonyPatch(typeof(ConsoleCommand), "GetTabOptions")] public class GetTabOptionsWithImprovedAutoComplete { private static bool Prefix(Terminal __instance, ref List __result) { if ((Object)(object)__instance == (Object)(object)Chat.instance) { return true; } if (!Settings.ImprovedAutoComplete) { return true; } if (TerminalUtils.IsExecuting) { __result = new List(); } else { string[] args = ParseParameters(((TMP_InputField)((Terminal)Console.instance).m_input).text.Split(new char[1] { ';' }).Last()); __result = AutoComplete.GetOptions(args); } return false; } private static string[] ParseParameters(string arg) { List list = new List(); string[] array = arg.Split(new char[1] { ' ' }); for (int i = 0; i < array.Length; i++) { if (array[i].StartsWith("\"")) { int j; for (j = i; j < array.Length && !array[j].TrimEnd(Array.Empty()).EndsWith("\""); j++) { } list.Add(string.Join(" ", array.Skip(i).Take(j - i + 1))); i = j; } else { list.Add(array[i].Trim()); } } return list.ToArray(); } } [HarmonyPatch(typeof(Terminal), "tabCycle")] public class TabCycleWithImprovedAutoComplete { private static void Prefix(Terminal __instance, ref List options, ref string word, bool usePrefix) { if (options == null) { return; } List list = new List(); list.AddRange(options.Where((string option) => option != null && !option.Contains("?"))); options = list; if (usePrefix) { if (word != null && word.StartsWith("_", StringComparison.OrdinalIgnoreCase)) { List list2 = new List(); list2.AddRange(options.Where((string cmd) => cmd.StartsWith("_", StringComparison.OrdinalIgnoreCase))); options = list2; } else { List list3 = new List(); list3.AddRange(options.Where((string cmd) => !cmd.StartsWith("_", StringComparison.OrdinalIgnoreCase))); options = list3; } } if (Settings.ImprovedAutoComplete && !((Object)(object)__instance == (Object)(object)Chat.instance)) { word = TerminalUtils.GetLastWord(__instance); if (word.EndsWith(" ")) { word = ""; } } } } [HarmonyPatch(typeof(Terminal), "tabCycle")] public class TabCycleForceSearchRefresh { private static void Postfix(Terminal __instance) { __instance.m_lastSearchLength = -1; } } [HarmonyPatch(typeof(Terminal), "updateSearch")] public class UpdateSearchWithImprovedAutoComplete { private static void Prefix(Terminal __instance, ref string word) { if (Settings.ImprovedAutoComplete && Object.op_Implicit((Object)(object)__instance.m_search) && !((Object)(object)__instance == (Object)(object)Chat.instance)) { word = TerminalUtils.GetLastWord(__instance); } } private static void Postfix(Terminal __instance, List options, ref string word, bool usePrefix) { if (usePrefix) { options = ((!word.StartsWith("_", StringComparison.OrdinalIgnoreCase)) ? options.Where((string cmd) => !cmd.StartsWith("_", StringComparison.OrdinalIgnoreCase)).ToList() : options.Where((string cmd) => cmd.StartsWith("_", StringComparison.OrdinalIgnoreCase)).ToList()); } if (!Settings.ImprovedAutoComplete || options == null || !Object.op_Implicit((Object)(object)__instance.m_search) || (Object)(object)__instance == (Object)(object)Chat.instance) { return; } if (Settings.CommandDescriptions && options == __instance.m_commandList && Terminal.commands.TryGetValue(word, out var value)) { options = ParameterInfo.Create(value.Description); } if (options.All((string option) => option.StartsWith("?"))) { __instance.m_search.text = "" + string.Join(", ", options.Select((string option) => option.Substring(1))) + ""; } } } [HarmonyPatch(typeof(Terminal), "UpdateInput")] public class PlainInputForAutoComplete { private static int Anchor = 0; private static int Focus = 0; private static string[]? PreviousCommands = null; private static int CurrentCommand = -1; private static int DiscardCaretDelta = 0; private static bool Prefix(Terminal __instance) { if ((Object)(object)__instance == (Object)(object)Chat.instance) { return true; } if (ZInput.GetKeyDown((KeyCode)13, true) && ZInput.GetKeyDown((KeyCode)9, true)) { return false; } if (ZInput.GetKeyDown((KeyCode)13, true)) { return true; } if (ZInput.GetButtonDown("ChatUp") || ZInput.GetButtonDown("ChatDown")) { return true; } if (ZInput.GetKey((KeyCode)306, true) || ZInput.GetKey((KeyCode)305, true)) { return true; } ToCurrentInput(__instance); return true; } private static void Postfix(Terminal __instance) { if (!((Object)(object)__instance == (Object)(object)Chat.instance) && !ZInput.GetKeyDown((KeyCode)13, true) && !ZInput.GetButtonDown("ChatUp") && !ZInput.GetButtonDown("ChatDown") && !ZInput.GetKey((KeyCode)306, true) && !ZInput.GetKey((KeyCode)305, true)) { ToActualInput(__instance); } } private static void ToCurrentInput(Terminal terminal) { GuiInputField input = terminal.m_input; Anchor = ((TMP_InputField)input).selectionAnchorPosition; Focus = ((TMP_InputField)input).selectionFocusPosition; DiscardPreviousCommands(input); Aliasing.RemoveAlias(input); } private static void ToActualInput(Terminal terminal) { GuiInputField input = terminal.m_input; Aliasing.RestoreAlias(input); RestorePreviousCommands(input); if (ZInput.GetKeyDown((KeyCode)9, true)) { ((TMP_InputField)input).selectionAnchorPosition = ((TMP_InputField)input).text.Length; ((TMP_InputField)input).selectionFocusPosition = ((TMP_InputField)input).text.Length; } else { ((TMP_InputField)input).selectionAnchorPosition = Anchor; ((TMP_InputField)input).selectionFocusPosition = Focus; } } private static void DiscardPreviousCommands(GuiInputField input) { if (!Settings.MultiCommand) { return; } PreviousCommands = ((TMP_InputField)input).text.Split(new char[1] { ';' }); DiscardCaretDelta = ((TMP_InputField)input).caretPosition; for (CurrentCommand = 0; CurrentCommand < PreviousCommands.Length; CurrentCommand++) { string text = PreviousCommands[CurrentCommand]; if (((TMP_InputField)input).caretPosition <= text.Length) { break; } ((TMP_InputField)input).caretPosition = ((TMP_InputField)input).caretPosition - text.Length; int caretPosition = ((TMP_InputField)input).caretPosition; ((TMP_InputField)input).caretPosition = caretPosition - 1; } DiscardCaretDelta -= ((TMP_InputField)input).caretPosition; if (CurrentCommand >= PreviousCommands.Length) { PreviousCommands = null; CurrentCommand = -1; } else { ((TMP_InputField)input).text = PreviousCommands[CurrentCommand]; } } private static void RestorePreviousCommands(GuiInputField input) { if (PreviousCommands != null) { PreviousCommands[CurrentCommand] = ((TMP_InputField)input).text; ((TMP_InputField)input).text = string.Join(";", PreviousCommands); if (DiscardCaretDelta != 0) { ((TMP_InputField)input).caretPosition = ((TMP_InputField)input).caretPosition + DiscardCaretDelta; } PreviousCommands = null; CurrentCommand = -1; } } } [HarmonyPatch(typeof(Terminal), "updateCommandList")] public class RemoveHiddenCommands { private static void Postfix(Terminal __instance) { __instance.m_commandList.RemoveAll((string command) => command.StartsWith("_", StringComparison.OrdinalIgnoreCase)); } } [HarmonyPatch(typeof(FejdStartup), "Awake")] public class FejdStartupAwake { private static void Postfix() { if (Settings.AutoExecBoot != "") { ((Terminal)Console.instance).TryRunCommand(Settings.AutoExecBoot, false, false); } } } [HarmonyPatch(typeof(Game), "Awake")] public class AutoExec { private static void Postfix() { if (Settings.AutoExec != "") { ((Terminal)Console.instance).TryRunCommand(Settings.AutoExec, false, false); } } } [HarmonyPatch(typeof(Player), "Awake")] public class AutomaticPickUp { private static void Postfix() { Player.m_enableAutoPickup = Settings.AutomaticItemPickUp; } } [HarmonyPatch(typeof(ZoneSystem))] public class CleanServerModifiers { [HarmonyPatch("GlobalKeyAdd")] [HarmonyPostfix] private static void GlobalKeyAdd() { Clean(); } [HarmonyPatch("GlobalKeyRemove")] [HarmonyPostfix] private static void GlobalKeyRemove() { Clean(); } private static void Clean() { if (ZNet.World?.m_startingGlobalKeys == null) { return; } List startingGlobalKeys = ZNet.World.m_startingGlobalKeys; for (int num = startingGlobalKeys.Count - 1; num >= 0; num--) { string text = startingGlobalKeys[num].Split(new char[1] { ' ' })[0].ToLowerInvariant(); for (int num2 = num - 1; num2 >= 0; num2--) { string text2 = startingGlobalKeys[num2].Split(new char[1] { ' ' })[0].ToLowerInvariant(); if (text == text2) { startingGlobalKeys.RemoveAt(num2); num--; } } } } } [HarmonyPatch(typeof(Terminal), "TryRunCommand")] public class LogCommand { private static void Postfix(string text) { if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { serverRPC.Invoke(CommandLogging.RPC_Log, new object[1] { text }); } } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public class CommandLogging { public static string RPC_Log = "DEV_Log"; private static string Format(ZNetPeer peer, string command) { return string.Format(Settings.Format(Settings.CommandLogFormat).Replace("{command", "{6"), peer.m_socket.GetHostName(), peer.m_playerName, ((ZDOID)(ref peer.m_characterID)).UserID.ToString(), peer.m_refPos.x, peer.m_refPos.y, peer.m_refPos.z, command); } private static void RPC_LogCommand(ZRpc rpc, string command) { string text = Format(ZNet.instance.GetPeer(rpc), command); if (text != "") { ZLog.Log((object)text); } } private static void Postfix(ZNet __instance, ZRpc rpc) { if (__instance.IsServer()) { rpc.Register(RPC_Log, (Action)RPC_LogCommand); } } } [HarmonyPatch(typeof(ConsoleCommand), "RunAction")] public class DisableCommandMessages { private static void Prefix() { PreventMessages.Enabled = Settings.DisableMessages; } private static void Postfix() { PreventMessages.Enabled = false; } } [HarmonyPatch(typeof(MessageHud), "ShowMessage")] public class PreventMessages { public static bool Enabled; private static bool Prefix() { return !Enabled; } } [HarmonyPatch(typeof(Player), "Update")] public class DisableDebugModeKeys { private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0002: 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_0034: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Player), "m_debugMode"), (string)null) }).SetAndAdvance(OpCodes.Call, Transpilers.EmitDelegate>((Func)(() => Player.m_debugMode && !Settings.DisableDebugModeKeys)).operand).InstructionEnumeration(); } } [HarmonyPatch(typeof(ZoneSystem), "RPC_SetGlobalKey")] public class DisableGlobalKeys { private static bool Prefix(string name) { return !Settings.IsGlobalKeyDisabled(name); } public static void RemoveDisabled() { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { return; } ZoneSystem instance = ZoneSystem.instance; if (Object.op_Implicit((Object)(object)instance) && instance.m_globalKeys.Any(Settings.IsGlobalKeyDisabled)) { instance.m_globalKeys = instance.m_globalKeys.Where((string key) => !Settings.IsGlobalKeyDisabled(key)).ToHashSet(); instance.m_globalKeysValues = instance.m_globalKeysValues.Where((KeyValuePair key) => !Settings.IsGlobalKeyDisabled(key.Key)).ToDictionary((KeyValuePair key) => key.Key, (KeyValuePair key) => key.Value); instance.SendGlobalKeys(ZRoutedRpc.Everybody); } } } [HarmonyPatch(typeof(Game), "UpdateNoMap")] public class DisableNoMap { private static void Postfix() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Settings.DisableNoMap) { Game.m_noMap = false; Minimap.instance.SetMapMode((MapMode)1); } } } [HarmonyPatch(typeof(Game), "SpawnPlayer")] public class DisableStartShout { private static void Postfix(Game __instance) { if (Settings.DisableStartShout) { __instance.m_firstSpawn = false; } } } [HarmonyPatch(typeof(MessageHud), "QueueUnlockMsg")] public class DisableUnlockMessages { private static bool Prefix() { return !Settings.DisableUnlockMessages; } } [HarmonyPatch] public class FlyFeatures { private static bool NoClipTurnedOn; private static bool NoClipPlayerEnabled() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Character)Player.m_localPlayer).IsDebugFlying()) { return Settings.FlyNoClip; } return false; } private static bool NoClipCameraEnabled() { if (!Settings.NoClipView) { return NoClipPlayerEnabled(); } return true; } private static bool CheckKeys(List required, List banned) { if (required.All(BindManager.GetKey)) { return !banned.Any(BindManager.GetKey); } return false; } private static bool IsFlyUp() { if (!CheckKeys(Settings.FlyUpRequiredKeys, Settings.FlyUpBannedKeys)) { return false; } if (Settings.FlyUpRequiredKeys.Count > Settings.FlyDownRequiredKeys.Count) { return true; } return !CheckKeys(Settings.FlyDownRequiredKeys, Settings.FlyDownBannedKeys); } private static bool IsFlyDown() { if (!CheckKeys(Settings.FlyDownRequiredKeys, Settings.FlyDownBannedKeys)) { return false; } if (Settings.FlyDownRequiredKeys.Count > Settings.FlyUpRequiredKeys.Count) { return true; } return !CheckKeys(Settings.FlyUpRequiredKeys, Settings.FlyUpBannedKeys); } private static Vector2 CheckInvert(Vector2 vector) { //IL_0007: 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) if (!Settings.FreeFlyCameraInvert) { return vector; } if (ZInput.IsGamepadActive()) { if (PlayerController.m_invertCameraX) { vector.x *= -1f; } if (PlayerController.m_invertCameraY) { vector.y *= -1f; } } else if (PlayerController.m_invertMouse) { vector.y *= -1f; } return vector; } [HarmonyPatch(typeof(Character), "UpdateDebugFly")] [HarmonyTranspiler] private static IEnumerable UpdateDebugFlyTranspiler(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"Jump", (string)null) }).SetOpcodeAndAdvance(OpCodes.Nop).Set(OpCodes.Call, Transpilers.EmitDelegate>((Func)IsFlyUp).operand) .MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldc_I4, (object)306, (string)null) }) .SetOpcodeAndAdvance(OpCodes.Nop) .SetOpcodeAndAdvance(OpCodes.Nop) .Set(OpCodes.Call, Transpilers.EmitDelegate>((Func)IsFlyDown).operand) .InstructionEnumeration(); } [HarmonyPatch(typeof(GameCamera), "UpdateFreeFly")] [HarmonyTranspiler] private static IEnumerable UpdateFreeFlyTranspiler(IEnumerable instructions) { //IL_0002: 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_0034: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GameCamera), "m_freeFlyYaw"), (string)null) }).Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(FlyFeatures), "CheckInvert", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Stloc_0, (object)null) }) .InstructionEnumeration(); } [HarmonyPatch(typeof(Player), "SetControls")] [HarmonyPrefix] private static void SetControlsPrefix(Player __instance, ref bool jump, ref bool crouch) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { jump = jump && !((Character)__instance).IsDebugFlying(); crouch = crouch && !((Character)__instance).IsDebugFlying(); } } [HarmonyPatch(typeof(Player), "LateUpdate")] [HarmonyPostfix] private static void LateUpdatePostfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } if (((Character)__instance).IsDebugFlying()) { __instance.m_crouchToggled = false; ((Character)__instance).m_zanim.SetBool(Character.s_onGround, true); ((Character)__instance).m_zanim.SetBool(Character.s_inWater, false); ((Character)__instance).m_zanim.SetBool(Character.s_encumbered, false); ((Character)__instance).m_zanim.SetFloat(Character.s_sidewaySpeed, 0f); ((Character)__instance).m_zanim.SetFloat(Character.s_forwardSpeed, 0f); ((Character)__instance).m_zanim.SetFloat(Character.s_turnSpeed, 0f); } if (NoClipPlayerEnabled()) { if (!NoClipTurnedOn) { if (Settings.NoClipClearEnvironment) { EnvMan.instance.SetForceEnvironment(""); } Ship localShip = Ship.GetLocalShip(); if (localShip != null) { localShip.OnTriggerExit((Collider)(object)((Character)__instance).m_collider); } IWaterInteractable component = ((Component)__instance).GetComponent(); LiquidSurface[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (LiquidSurface val in array) { if (val.m_inWater != null && val.m_inWater.Contains(component)) { val.OnTriggerExit((Collider)(object)((Character)__instance).m_collider); } } WaterVolume[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (WaterVolume val2 in array2) { if (val2.m_inWater != null && val2.m_inWater.Contains(component)) { val2.OnTriggerExit((Collider)(object)((Character)__instance).m_collider); } } } NoClipTurnedOn = true; ((Collider)((Character)__instance).m_collider).enabled = false; } else if (NoClipTurnedOn) { NoClipTurnedOn = false; ((Collider)((Character)__instance).m_collider).enabled = true; } } [HarmonyPatch(typeof(Character), "UpdateEyeRotation")] [HarmonyPrefix] private static void UpdateEyeRotationPrefix(Character __instance) { //IL_0007: 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) __instance.m_lookDir = ((Vector3)(ref __instance.m_lookDir)).normalized; } [HarmonyPatch(typeof(Player), "IsDebugFlying")] [HarmonyPostfix] private static bool IsDebugFlyingPostfix(bool result, Player __instance) { if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { return result; } return Settings.IsEnabled(PermissionHash.Fly, result); } [HarmonyPatch(typeof(Player), "InDebugFlyMode")] [HarmonyPostfix] private static bool InDebugFlyModePostfix(bool result, Player __instance) { if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { return result; } return Settings.IsEnabled(PermissionHash.Fly, result); } [HarmonyPatch(typeof(Character), "UnderWorldCheck")] [HarmonyPrefix] private static bool UnderWorldCheckPrefix(Character __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { return !NoClipPlayerEnabled(); } return true; } [HarmonyPatch(typeof(GameCamera), "GetCameraPosition")] [HarmonyTranspiler] private static IEnumerable GetCameraPositionTranspiler(IEnumerable instructions) { //IL_0002: 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_0034: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GameCamera), "m_minWaterDistance"), (string)null) }).Repeat((Action)delegate(CodeMatcher matcher) { matcher.SetAndAdvance(OpCodes.Call, Transpilers.EmitDelegate>((Func)((GameCamera instance) => (!NoClipCameraEnabled()) ? instance.m_minWaterDistance : float.MinValue)).operand); }, (Action)null).InstructionEnumeration(); } [HarmonyPatch(typeof(GameCamera), "CollideRay2")] [HarmonyPrefix] private static bool CollideRay2Prefix() { return !NoClipCameraEnabled(); } } [HarmonyPatch] public class GhostFeatures { public static readonly int HashIgnoreSleep = "DEV_GhostIgnoreSleep".GetHashCode(); public static readonly int HashGhost = "DEV_Ghost".GetHashCode(); private static float? PreviousGhostY = null; private static bool? PreviousPublicReferencePosition = null; public static bool IsGhost(Player player) { if (!((Character)player).InGhostMode()) { ZNetView nview = ((Character)player).m_nview; if (nview == null) { return false; } ZDO zDO = nview.GetZDO(); return ((zDO != null) ? new bool?(zDO.GetBool(HashGhost, false)) : null).GetValueOrDefault(); } return true; } [HarmonyPatch(typeof(Player), "InGhostMode")] [HarmonyPostfix] private static bool InGhostModePostfix(bool result, Player __instance) { if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { return result; } return Settings.IsEnabled(PermissionHash.Ghost, result); } private static List Players() { if (!Settings.GhostNoSpawns) { return Player.s_players; } return Player.s_players.Where((Player player) => !IsGhost(player)).ToList(); } private static IEnumerable ReplacePlayers(IEnumerable instructions) { //IL_0002: 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_0034: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Player), "s_players"), (string)null) }).SetAndAdvance(OpCodes.Call, Transpilers.EmitDelegate>>((Func>)Players).operand).InstructionEnumeration(); } [HarmonyPatch(typeof(Game), "EverybodyIsTryingToSleep")] [HarmonyPostfix] private static bool EverybodyIsTryingToSleepPostfix(bool result) { if (result) { return result; } List allCharacterZDOS = ZNet.instance.GetAllCharacterZDOS(); if (allCharacterZDOS.Count == 0) { return false; } if (!allCharacterZDOS.Any((ZDO zdo) => zdo.GetBool(ZDOVars.s_inBed, false))) { return false; } return allCharacterZDOS.All((ZDO zdo) => zdo.GetBool(ZDOVars.s_inBed, false) || zdo.GetBool(HashIgnoreSleep, false)); } [HarmonyPatch(typeof(Player), "SetGhostMode")] [HarmonyPostfix] private static void SetGhostModePostfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } ZNetView nview = ((Character)__instance).m_nview; if (nview != null) { ZDO zDO = nview.GetZDO(); if (zDO != null) { zDO.Set(HashGhost, ((Character)__instance).InGhostMode()); } } if (!Settings.GhostIgnoreSleep) { return; } ZNetView nview2 = ((Character)__instance).m_nview; if (nview2 != null) { ZDO zDO2 = nview2.GetZDO(); if (zDO2 != null) { zDO2.Set(HashIgnoreSleep, ((Character)__instance).InGhostMode()); } } } [HarmonyPatch(typeof(ZDOMan), "SendZDOs")] [HarmonyPrefix] private static void SendZDOsPrefix() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)((Character)Player.m_localPlayer).m_nview) || !((Character)Player.m_localPlayer).InGhostMode() || !Settings.GhostInvisibility) { return; } ZDO zDO = ((Character)Player.m_localPlayer).m_nview.GetZDO(); if (zDO == null) { return; } PreviousGhostY = zDO.m_position.y; zDO.m_position.y = 10000f; SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan(); if (sEMan == null) { return; } foreach (StatusEffect statusEffect in sEMan.GetStatusEffects()) { statusEffect.RemoveStartEffects(); } } [HarmonyPatch(typeof(ZDOMan), "SendZDOs")] [HarmonyPostfix] private static void SendZDOsPostfix() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)((Character)Player.m_localPlayer).m_nview) && PreviousGhostY.HasValue) { ((Character)Player.m_localPlayer).m_nview.GetZDO().m_position.y = PreviousGhostY.Value; PreviousGhostY = null; } } [HarmonyPatch(typeof(ZNet), "SendPeriodicData")] [HarmonyPrefix] private static void SendPeriodicDataPrefix(ZNet __instance) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)((Character)Player.m_localPlayer).m_nview) && ((Character)Player.m_localPlayer).InGhostMode() && Settings.GhostInvisibility) { PreviousPublicReferencePosition = __instance.m_publicReferencePosition; __instance.m_publicReferencePosition = false; } } [HarmonyPatch(typeof(ZNet), "SendPeriodicData")] [HarmonyPostfix] private static void SendPeriodicDataPostfix(ZNet __instance) { if (PreviousPublicReferencePosition.HasValue) { __instance.m_publicReferencePosition = PreviousPublicReferencePosition.Value; PreviousPublicReferencePosition = null; } } [HarmonyPatch(typeof(SpawnSystem), "GetPlayersInZone")] [HarmonyPostfix] private static void GetPlayersInZonePostfix(List players) { if (!Settings.GhostNoSpawns) { return; } foreach (Player item in players.Where(IsGhost).ToList()) { players.Remove(item); } } [HarmonyPatch(typeof(Player), "GetClosestPlayer")] [HarmonyTranspiler] private static IEnumerable GetClosestPlayerTranspiler(IEnumerable instructions) { return ReplacePlayers(instructions); } [HarmonyPatch(typeof(Player), "IsPlayerInRange", new Type[] { typeof(Vector3), typeof(float) })] [HarmonyTranspiler] private static IEnumerable IsPlayerInRangeTranspiler(IEnumerable instructions) { return ReplacePlayers(instructions); } [HarmonyPatch(typeof(Player), "IsPlayerInRange", new Type[] { typeof(Vector3), typeof(float), typeof(float) })] [HarmonyTranspiler] private static IEnumerable IsPlayerInRange2Transpiler(IEnumerable instructions) { return ReplacePlayers(instructions); } } [HarmonyPatch] public class GodFeatures { private static bool IsAttacking; [HarmonyPatch(typeof(Player), "InGodMode")] [HarmonyPostfix] private static bool InGodModePostfix(bool result, Player __instance) { if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { return result; } return Settings.IsEnabled(PermissionHash.God, result); } [HarmonyPatch(typeof(Player), "IsDodgeInvincible")] [HarmonyPostfix] private static void IsDodgeInvinciblePostfix(Player __instance, ref bool __result) { bool flag = Settings.GodModeAlwaysDodge && ((Character)__instance).InGodMode(); __result |= flag; } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPostfix] private static void ApplyDamagePostfix(Character __instance, HitData hit) { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (Settings.GodModeAlwaysParry && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __instance.InGodMode()) { Character attacker = hit.GetAttacker(); if (Object.op_Implicit((Object)(object)attacker) && !((Object)(object)attacker == (Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).m_blockTimer < 0f) { ((Humanoid)Player.m_localPlayer).m_perfectBlockEffect.Create(hit.m_point, Quaternion.identity, (Transform)null, 1f, -1); attacker.Stagger(-hit.m_dir); } } } [HarmonyPatch(typeof(Player), "EdgeOfWorldKill")] [HarmonyPrefix] private static bool EdgeOfWorldKillPrefix(Player __instance) { if (Settings.GodModeNoEdgeOfWorld) { return !((Character)__instance).InGodMode(); } return true; } [HarmonyPatch(typeof(Player), "HaveEitr")] [HarmonyPostfix] private static void HaveEitrPostfix(Player __instance, ref bool __result) { bool flag = Settings.GodModeNoEitr && ((Character)__instance).InGodMode(); __result |= flag; } [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPrefix] private static void AttackStartPrefix(Humanoid character) { if ((Object)(object)character == (Object)(object)Player.m_localPlayer) { IsAttacking = true; } } [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPostfix] private static void AttackStartPostfix(Humanoid character) { if ((Object)(object)character == (Object)(object)Player.m_localPlayer) { IsAttacking = false; } } [HarmonyPatch(typeof(Player), "GetMaxEitr")] [HarmonyPostfix] private static void GetMaxEitrPostfix(Player __instance, ref float __result) { if (Settings.GodModeNoEitr && ((Character)__instance).InGodMode() && IsAttacking) { __result = Math.Max(__result, 0.1f); } } [HarmonyPatch(typeof(Player), "UseEitr")] [HarmonyPrefix] private static bool UseEitrPrefix(Player __instance) { return !Settings.GodModeNoEitr || !((Character)__instance).InGodMode(); } [HarmonyPatch(typeof(Character), "ApplyPushback", new Type[] { typeof(Vector3), typeof(float) })] [HarmonyPrefix] private static bool ApplyPushbackPrefix(Character __instance) { return !Settings.GodModeNoKnockback || !__instance.InGodMode() || !__instance.IsPlayer(); } [HarmonyPatch(typeof(ParticleMist), "Update")] [HarmonyPrefix] private static bool ParticleMistUpdatePrefix() { Player localPlayer = Player.m_localPlayer; return !Settings.GodModeNoMist || !Object.op_Implicit((Object)(object)localPlayer) || !((Character)localPlayer).InGodMode(); } [HarmonyPatch(typeof(Character), "AddStaggerDamage")] [HarmonyPrefix] private static bool AddStaggerDamagePrefix(Character __instance) { return !Settings.GodModeNoStagger || !__instance.InGodMode() || !__instance.IsPlayer(); } [HarmonyPatch(typeof(Player), "HaveStamina")] [HarmonyPostfix] private static void HaveStaminaPostfix(Player __instance, ref bool __result) { bool flag = Settings.GodModeNoStamina && ((Character)__instance).InGodMode(); __result |= flag; } [HarmonyPatch(typeof(Player), "UseStamina")] [HarmonyPrefix] private static bool UseStaminaPrefix(Player __instance) { return !Settings.GodModeNoStamina || !((Character)__instance).InGodMode(); } [HarmonyPatch(typeof(Inventory), "RemoveOneItem")] [HarmonyPrefix] private static bool RemoveOneItemPrefix(Inventory __instance, ref bool __result) { if (((Humanoid)(Player.m_localPlayer?)).m_inventory != __instance) { return true; } int num; if (Settings.GodModeNoUsage) { num = (((Character)Player.m_localPlayer).InGodMode() ? 1 : 0); if (num != 0) { __result = true; } } else { num = 0; } return num == 0; } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData), typeof(int) })] [HarmonyPrefix] private static bool RemoveItemByDataPrefix(Inventory __instance, int amount, ref bool __result) { if (amount > 1) { return true; } if (((Humanoid)(Player.m_localPlayer?)).m_inventory != __instance) { return true; } int num; if (Settings.GodModeNoUsage) { num = (((Character)Player.m_localPlayer).InGodMode() ? 1 : 0); if (num != 0) { __result = true; } } else { num = 0; } return num == 0; } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(string), typeof(int), typeof(int), typeof(bool) })] [HarmonyPrefix] private static bool RemoveItemByNamePrefix(Inventory __instance, int amount) { if (amount > 1) { return true; } if (((Humanoid)(Player.m_localPlayer?)).m_inventory != __instance) { return true; } return !Settings.GodModeNoUsage || !((Character)Player.m_localPlayer).InGodMode(); } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] [HarmonyPostfix] private static void GetMaxCarryWeightPostfix(Player __instance, ref float __result) { if (Settings.GodModeNoWeightLimit && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && ((Character)__instance).InGodMode()) { __result = 1E+10f; } } [HarmonyPatch(typeof(InventoryGui), "UpdateInventoryWeight")] [HarmonyPrefix] private static bool UpdateInventoryWeightPrefix(Player player, InventoryGui __instance) { int num; if (Settings.GodModeNoWeightLimit && (Object)(object)player == (Object)(object)Player.m_localPlayer) { num = (((Character)player).InGodMode() ? 1 : 0); if (num != 0) { int num2 = Mathf.CeilToInt(((Humanoid)player).GetInventory().GetTotalWeight()); __instance.m_weight.text = $"{num2}/-"; } } else { num = 0; } return num == 0; } } [HarmonyPatch(typeof(Chat), "SendText")] public class HideShoutPing { private static void Prefix(ref Vector3 __state) { //IL_001f: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Settings.HideShoutPings) { __state = ((Character)Player.m_localPlayer).m_head.position; ((Character)Player.m_localPlayer).m_head.position = default(Vector3); } } private static void Postfix(Vector3 __state) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Settings.HideShoutPings) { ((Character)Player.m_localPlayer).m_head.position = __state; } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] internal static class LimitRecipesToStationPatch { [HarmonyPriority(800)] private static void Prefix(ref List recipes) { if (!Settings.configNoCostLimitRecipesToStation.Value) { return; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)localPlayer.m_currentStation) && (ZoneSystem.instance.GetGlobalKey((GlobalKeys)20) || localPlayer.NoCostCheat())) { recipes.RemoveAll((Recipe recipe) => !localPlayer.RequiredCraftingStation(recipe, 1, Settings.configNoCostRespectStationLevel.Value)); } } } [HarmonyPatch(typeof(Minimap), "Awake")] public class Minimap_Alignment { private static void Postfix(Minimap __instance) { __instance.m_biomeNameSmall.alignment = (TextAlignmentOptions)260; __instance.m_biomeNameLarge.alignment = (TextAlignmentOptions)260; } } [HarmonyPatch(typeof(Minimap), "UpdateBiome")] public class Minimap_ShowPos { private static string PreviousSmallText = ""; private static string PreviousLargeText = ""; private static void AddText(TMP_Text input, string text) { if (!input.text.Contains(text)) { input.text += text; } } private static void CleanUp(TMP_Text input, string text) { if (!(text == "") && input.text.Contains(text)) { input.text = input.text.Replace(text, ""); } } private static string Format(Vector3 position) { //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) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) string text = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? Player.m_localPlayer.GetPlayerName() : "Unknown"); long num; if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ZDOID none = ZDOID.None; num = ((ZDOID)(ref none)).UserID; } else { num = Player.m_localPlayer.GetPlayerID(); } long num2 = num; return string.Format(Settings.Format(Settings.MinimapFormat), "Not available", text, num2, position.x, position.y, position.z); } private static string GetText(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0007: Unknown result type (might be due to invalid IL or missing references) Vector2i zone = ZoneSystem.GetZone(position); string text = Format(position); string text2 = "zone: " + zone.x + "/" + zone.y; return "\n" + text2 + "\n" + text; } private static void Postfix(Minimap __instance, Player player) { //IL_0001: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_0127: Unknown result type (might be due to invalid IL or missing references) MapMode mode = __instance.m_mode; if (PreviousSmallText != "") { CleanUp(__instance.m_biomeNameSmall, PreviousSmallText); PreviousSmallText = ""; } if (PreviousLargeText != "") { CleanUp(__instance.m_biomeNameLarge, PreviousLargeText); PreviousLargeText = ""; } Vector3 position = ((GameCamera.InFreeFly() && Object.op_Implicit((Object)(object)Utils.GetMainCamera())) ? ((Component)Utils.GetMainCamera()).transform.position : ((Component)player).transform.position); if ((int)mode == 1 && Settings.MiniMapCoordinates) { string text = GetText(position); AddText(__instance.m_biomeNameSmall, text); PreviousSmallText = text; } if ((int)mode == 2 && Settings.MapCoordinates) { position = __instance.ScreenToWorldPoint((Vector3)(ZInput.IsMouseActive() ? Input.mousePosition : new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f))); position.y = WorldGenerator.instance.GetHeight(position.x, position.z); string text2 = GetText(position); text2 += $"\ndistance: {Utils.DistanceXZ(((Component)player).transform.position, position):F0}"; AddText(__instance.m_biomeNameLarge, text2); PreviousLargeText = text2; } } } [HarmonyPatch(typeof(ZNet), "UpdatePlayerList")] public class Server_UpdatePrivatePositions { private static void Postfix(ZNet __instance) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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) if (!__instance.IsServer() || !Settings.ShowPrivatePlayers) { return; } Dictionary dictionary = __instance.m_peers.Where((ZNetPeer peer) => peer.IsReady() && peer.m_characterID != ZDOID.None).ToDictionary((ZNetPeer peer) => peer.m_characterID, (ZNetPeer peer) => peer); for (int i = 0; i < __instance.m_players.Count; i++) { PlayerInfo val = __instance.m_players[i]; if (!(val.m_characterID == __instance.m_characterID)) { if (!dictionary.TryGetValue(val.m_characterID, out var value)) { ServerDevcommands.Log.LogError((object)"Unable to find the peer to set private position."); } else if (!value.m_publicRefPos) { val.m_position = value.m_refPos; __instance.m_players[i] = val; } } } } } [HarmonyPatch(typeof(ZNet), "SendPlayerList")] public class SendPrivatePositionsToAdmins { private static void Postfix(ZNet __instance) { if (__instance.IsServer() && Settings.ShowPrivatePlayers && __instance.m_peers.Count != 0) { SendToAdmins(__instance); } } private static void SendToAdmins(ZNet obj) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) ZNet obj2 = obj; int num = obj2.m_players.Where((PlayerInfo p) => !p.m_publicPosition).Count(); if (num == 0) { return; } List list = obj2.m_peers.Where((ZNetPeer peer) => peer.IsReady() && obj2.IsAdmin(peer.m_rpc.GetSocket().GetHostName())).ToList(); if (list.Count == 0) { return; } ZPackage val = new ZPackage(); val.Write(num); foreach (PlayerInfo player in obj2.m_players) { if (!player.m_publicPosition) { val.Write(player.m_characterID); val.Write(player.m_position); } } foreach (ZNetPeer item in list) { item.m_rpc.Invoke("DEV_PrivatePlayerList2", new object[1] { val }); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public class RegisterRpcPrivatePositions { public static readonly Dictionary PrivatePositions = new Dictionary(); private static void RPC_PrivatePlayerList(ZRpc rpc, ZPackage pkg) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ShowPrivatePlayers) { return; } int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { ZDOID key = pkg.ReadZDOID(); Vector3 value = pkg.ReadVector3(); PrivatePositions[key] = value; } for (int j = 0; j < ZNet.instance.m_players.Count; j++) { if (!ZNet.instance.m_players[j].m_publicPosition && PrivatePositions.TryGetValue(ZNet.instance.m_players[j].m_characterID, out var value2)) { List players = ZNet.instance.m_players; int index = j; PlayerInfo value3 = ZNet.instance.m_players[j]; value3.m_position = value2; players[index] = value3; } } } private static void Postfix(ZNet __instance, ZRpc rpc) { if (!__instance.IsServer()) { rpc.Register("DEV_PrivatePlayerList2", (Action)RPC_PrivatePlayerList); } } } [HarmonyPatch(typeof(ZNet), "GetOtherPublicPlayers")] public class IncludePrivatePlayersInTheMap { private static void Postfix(ZNet __instance, List playerList) { //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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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) if (!Settings.ShowPrivatePlayers) { return; } foreach (PlayerInfo player in __instance.m_players) { if (!player.m_publicPosition) { ZDOID characterID = player.m_characterID; if (!((ZDOID)(ref characterID)).IsNone() && !(player.m_characterID == __instance.m_characterID) && !(player.m_position == Vector3.zero)) { playerList.Add(player); } } } } } [HarmonyPatch(typeof(Minimap), "UpdatePlayerPins")] public class AddCheckedToPrivatePlayers { private static void Postfix(Minimap __instance) { //IL_001f: 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_0025: Unknown result type (might be due to invalid IL or missing references) if (Settings.ShowPrivatePlayers) { for (int i = 0; i < __instance.m_tempPlayerInfo.Count; i++) { PinData obj = __instance.m_playerPins[i]; PlayerInfo val = __instance.m_tempPlayerInfo[i]; obj.m_checked = !val.m_publicPosition; } } } } [HarmonyPatch(typeof(Minimap))] public class MinimapTeleport { private static bool TryTeleport(Minimap map, KeyCode mainKey) { //IL_001a: 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) //IL_0020: 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_002d: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Console.instance) || !((Terminal)Console.instance).IsCheatsEnabled()) { return false; } KeyboardShortcut mapTeleport = Settings.MapTeleport; if (mainKey == ((KeyboardShortcut)(ref mapTeleport)).MainKey) { mapTeleport = Settings.MapTeleport; if (((KeyboardShortcut)(ref mapTeleport)).Modifiers.All((KeyCode k) => ZInput.GetKey(k, true))) { Vector3 val = map.ScreenToWorldPoint(ZInput.mousePosition); val.y = ((Component)Player.m_localPlayer).transform.position.y; float val2 = default(float); Heightmap.GetHeight(val, ref val2); val.y = Math.Max(0f, val2); ((Character)Player.m_localPlayer).TeleportTo(val, ((Component)Player.m_localPlayer).transform.rotation, true); return true; } } return false; } [HarmonyPatch("OnMapLeftClick")] [HarmonyPrefix] private static bool OnMapLeftClick(Minimap __instance) { return !TryTeleport(__instance, (KeyCode)323); } [HarmonyPatch("OnMapRightClick")] [HarmonyPrefix] private static bool OnMapRightClick(Minimap __instance) { return !TryTeleport(__instance, (KeyCode)324); } [HarmonyPatch("OnMapMiddleClick")] [HarmonyPrefix] private static bool OnMapMiddleClick(Minimap __instance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0020: Unknown result type (might be due to invalid IL or missing references) if (TryTeleport(__instance, (KeyCode)325)) { return false; } Vector3 val = __instance.ScreenToWorldPoint(ZInput.mousePosition); Chat.instance.SendPing(val); return false; } } public class MouseWheelBinding { public static void Execute(float ticks) { if (ticks == 0f || !Object.op_Implicit((Object)(object)Chat.instance)) { return; } List bestWheelCommands = BindManager.GetBestWheelCommands(); if (bestWheelCommands.Count == 0) { return; } string command = ticks.ToString(CultureInfo.InvariantCulture); foreach (CommandBind item in bestWheelCommands) { ((Terminal)Chat.instance).TryRunCommand(TerminalUtils.Substitute(item.Command, command), true, true); } } public static bool CouldExecute() { if (ZInput.GetMouseScrollWheel() == 0f) { return false; } return BindManager.CouldWheelExecute(); } public static int ExecuteCount() { return BindManager.GetBestWheelCount(); } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] public class PreventRotation { private static void Prefix(Player __instance, ref int __state) { __state = __instance.m_placeRotation; } private static void Postfix(Player __instance, int __state) { if (MouseWheelBinding.CouldExecute()) { __instance.m_placeRotation = __state; } } } public class ComfyGizmoPatcher { public static void DoPatching(Assembly assembly) { //IL_001e: 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_0075: Expected O, but got Unknown if (!(assembly == null)) { ServerDevcommands.Log.LogInfo((object)"\"ComfyGizmo\" detected. Patching \"Rotate\" for mouse wheel binding."); Harmony val = new Harmony("valheim.jerekuusela.server_devcommand.comfygizmo"); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("ComfyGizmo.RotationManager"), "Rotate", (Type[])null, (Type[])null); MethodInfo methodInfo2 = SymbolExtensions.GetMethodInfo((Expression)(() => Prefix())); val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool Prefix() { return !MouseWheelBinding.CouldExecute(); } } public class GizmoReloadedPatcher { public static void DoPatching(Assembly assembly) { //IL_001e: 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_0075: Expected O, but got Unknown if (!(assembly == null)) { ServerDevcommands.Log.LogInfo((object)"\"GizmoReloaded\" detected. Patching \"HandleAxisInput\" for mouse wheel binding."); Harmony val = new Harmony("valheim.jerekuusela.server_devcommand.m3to.mods.GizmoReloaded"); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("GizmoReloaded.Plugin"), "HandleAxisInput", (Type[])null, (Type[])null); MethodInfo methodInfo2 = SymbolExtensions.GetMethodInfo((Expression)(() => Prefix())); val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool Prefix() { return !MouseWheelBinding.CouldExecute(); } } public class MultiCommands { private static readonly List Groups = new List(); private readonly Queue Commands = new Queue(commands); private readonly Terminal Terminal; private float WaitTimer; public MultiCommands(Terminal terminal, string[] commands) { Terminal = terminal; base..ctor(); } public static string[] Split(string text) { if (!Settings.MultiCommand) { return new string[1] { text }; } return (from s in text.Split(new char[1] { ';' }) select s.Trim()).ToArray(); } public static void Handle(Terminal terminal, string[] commands) { MultiCommands multiCommands = new MultiCommands(terminal, commands); multiCommands.Run(0f); if (!multiCommands.IsDone()) { Groups.Add(multiCommands); } } public static void Execute(float dt) { for (int i = 0; i < Groups.Count; i++) { Groups[i].Run(dt); if (Groups[i].IsDone()) { Groups.RemoveAt(i); i--; } } } public bool IsDone() { return Commands.Count() == 0; } public void Run(float dt) { if ((double)WaitTimer > -0.01) { WaitTimer -= dt; } if ((double)WaitTimer > -0.01) { return; } while (Commands.Count() > 0) { string text = Commands.Dequeue(); if (text.StartsWith("wait ", StringComparison.InvariantCultureIgnoreCase)) { string[] array = text.Split(new char[1] { ' ' }); if (array.Length >= 2) { WaitTimer = float.Parse(array[1]) / 1000f; break; } } else { Terminal.TryRunCommand(text, false, false); } } } } [HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")] public class GenerateDropList { private static bool Prefix(ref List> __result) { if (Settings.NoDrops) { __result = new List>(); return false; } return true; } } public class ParameterInfo { private static List components = new List(); private static readonly List globalKeys; private static List ids; private static List environments; private static readonly List colors; private static List objectIds; private static List roomIds; private static List? LocationDataCache; private static List? LocationIdsCache; private static List? ServerLocationIdsCache; private static List? VegetationDataCache; private static List? VegetationIdsCache; private static List? ServerVegetationIdsCache; private static List statusEffects; private static List itemIds; private static List hairs; private static List beards; private static List keyCodes; private static List keyCodesWithNegative; public static List Origin; public static List None; public static List Missing; public static List Components { get { if (components.Count == 0) { List list = new List(); list.AddRange(ComponentInfo.Types.Select((Type t) => t.Name)); components = list; } return components; } } public static List GlobalKeys => globalKeys; public static List Ids { get { if (ObjectIds.Count + LocationIds.Count != objectIds.Count) { List list = ObjectIds; List locationIds = LocationIds; List list2 = new List(list.Count + locationIds.Count); list2.AddRange(list); list2.AddRange(locationIds); ids = list2; ids.Sort(); } return ids; } } public static List Environments { get { if (Object.op_Implicit((Object)(object)EnvMan.instance) && EnvMan.instance.m_environments.Count != environments.Count) { List list = new List(); list.AddRange(EnvMan.instance.m_environments.Select((EnvSetup env) => env.m_name.Replace(" ", "_"))); environments = list; environments.Sort(); } return environments; } } public static List Colors => colors; public static List ObjectIds { get { if (Object.op_Implicit((Object)(object)ZNetScene.instance) && ZNetScene.instance.m_namedPrefabs.Count != objectIds.Count) { objectIds = ZNetScene.instance.GetPrefabNames(); } return objectIds; } } public static List RoomIds { get { if (Object.op_Implicit((Object)(object)DungeonDB.instance) && DungeonDB.instance.m_rooms.Count != roomIds.Count) { List list = new List(); list.AddRange(DungeonDB.instance.m_rooms.Select((RoomData room) => room.m_prefab.Name)); roomIds = list; } return roomIds; } } public static List LocationIds { get { if (ServerLocationIdsCache != null) { return ServerLocationIdsCache; } if (!Object.op_Implicit((Object)(object)ZoneSystem.instance)) { return new List(); } if (LocationDataCache != ZoneSystem.instance.m_locations) { LocationIdsCache = null; } if (LocationIdsCache == null) { List list = new List(); list.AddRange((from l in ZoneSystem.instance.m_locations.Where(Helper.IsValid) select l.m_prefab.Name).Distinct()); LocationIdsCache = list; } LocationDataCache = ZoneSystem.instance.m_locations; return LocationIdsCache; } } public static List VegetationIds { get { if (ServerVegetationIdsCache != null) { return ServerVegetationIdsCache; } if (!Object.op_Implicit((Object)(object)ZoneSystem.instance)) { return new List(); } if (VegetationDataCache != ZoneSystem.instance.m_vegetation) { VegetationIdsCache = null; } if (VegetationIdsCache == null) { List list = new List(); list.AddRange((from veg in ZoneSystem.instance.m_vegetation where veg != null && (Object)(object)veg.m_prefab != (Object)null select veg into l select l.m_name).Distinct()); VegetationIdsCache = list; } VegetationDataCache = ZoneSystem.instance.m_vegetation; return VegetationIdsCache; } } public static List Events { get { List list = new List(); list.AddRange(RandEventSystem.instance.m_events.Select((RandomEvent ev) => ev.m_name)); return list; } } public static List StatusEffects { get { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.m_StatusEffects.Count != statusEffects.Count) { List list = new List(); list.AddRange(ObjectDB.instance.m_StatusEffects.Select((StatusEffect se) => ((Object)se).name)); statusEffects = list; } return statusEffects; } } public static List EffectAreas { get { string[] names = Enum.GetNames(typeof(Type)); List list = new List(names.Length); list.AddRange(names); return list; } } public static List ItemIds { get { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.m_items.Count != itemIds.Count) { List list = new List(); list.AddRange(ObjectDB.instance.m_items.Select((GameObject item) => ((Object)item).name)); itemIds = list; } return itemIds; } } public static List PlayerNames => ZNet.instance?.m_players.Select((PlayerInfo player) => (!player.m_name.Contains(" ")) ? player.m_name : ("\"" + player.m_name + "\"")).ToList() ?? new List(1) { "No players found!" }; public static List PublicPlayerNames => (from player in ZNet.instance?.m_players where player.m_publicPosition select (!player.m_name.Contains(" ")) ? player.m_name : ("\"" + player.m_name + "\"")).ToList() ?? new List(1) { "No public players found!" }; public static List Hairs { get { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { List list = new List(); list.AddRange(from item in ObjectDB.instance.GetAllItems((ItemType)10, "Hair") select ((Object)item).name); hairs = list; } return hairs; } } public static List Beards { get { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { List list = new List(); list.AddRange(from item in ObjectDB.instance.GetAllItems((ItemType)10, "Beard") select ((Object)item).name); beards = list; } return beards; } } public static List KeyCodes { get { if (keyCodes.Count == 0) { string[] names = Enum.GetNames(typeof(KeyCode)); List list = new List(); list.AddRange(names.Select((string value) => value.ToLower())); keyCodes = list; keyCodes.Add("wheel"); } return keyCodes; } } public static List KeyCodesWithNegative { get { if (keyCodesWithNegative.Count == 0) { string[] names = Enum.GetNames(typeof(KeyCode)); List list = new List(); list.AddRange(names.Select((string value) => value.ToLower())); keyCodesWithNegative = list; keyCodesWithNegative.AddRange(keyCodesWithNegative.Select((string value) => "-" + value).ToList()); } return keyCodesWithNegative; } } public static List CommandNames { get { Dictionary.KeyCollection keys = Terminal.commands.Keys; List list = new List(keys.Count); list.AddRange(keys); return list; } } public static void SetServerLocationIds(List? data) { ServerLocationIdsCache = data; } public static void SetServerVegetationIds(List? data) { ServerVegetationIdsCache = data; } public static List Create(string value) { return new List(1) { "?" + value }; } public static List Error(string value) { return new List(1) { "?Error: " + value }; } public static List Create(string name, string value, string description) { return Create(name + "=" + value + " | " + description); } public static List CreateWithMinMax(string name, string value, string description) { return Create(name + "=" + value + " or " + name + "=min-max | " + description); } public static List Create(string values, string description) { return Create(values + " | " + description); } public static List InvalidNamed(string name) { return Error("Invalid named parameter " + name + "!"); } public static List Flag(string name) { return Error(name + " is a flag so it doesn't have any arguments!"); } public static List Flag(string name, int subIndex) { if (subIndex != 0) { return Flag(name); } return new List(1) { name }; } public static List Flag(string name, string description) { return Error(name + " is a flag so it doesn't have any arguments! | " + description); } public static List Flag(string name, string description, int subIndex) { if (subIndex != 0) { return Flag(name, description); } return new List(1) { name }; } public static List XZY(string name, string description, int index) { return index switch { 0 => Create(name + "=X,Z,Y | " + description + "."), 1 => Create(name + "=X,Z,Y | " + description + "."), 2 => Create(name + "=X,Z,Y | " + description + "."), _ => None, }; } public static List XZYR(string description, int index) { return index switch { 0 => Create("X,Z,Y,R | " + description + "."), 1 => Create("X,Z,Y,R | " + description + "."), 2 => Create("X,Z,Y,R | " + description + "."), 4 => Create("X,Z,Y,R | " + description + "."), _ => None, }; } public static List XZY(string description, int index) { return index switch { 0 => Create("X,Z,Y | " + description + "."), 1 => Create("X,Z,Y | " + description + "."), 2 => Create("X,Z,Y | " + description + "."), _ => None, }; } public static List XYZ(string name, string description, int index) { return index switch { 0 => Create(name + "=X,Z,Y | " + description + "."), 1 => Create(name + "=X,Y,Z | " + description + "."), 2 => Create(name + "=X,Y,Z | " + description + "."), _ => None, }; } public static List XYZ(string description, int index) { return index switch { 0 => Create("X,Z,Y | " + description + "."), 1 => Create("X,Y,Z | " + description + "."), 2 => Create("X,Y,Z | " + description + "."), _ => None, }; } public static List YXZ(string name, string description, int index) { return index switch { 0 => Create(name + "=Y,X,Z | " + description + "."), 1 => Create(name + "=Y,X,Z | " + description + "."), 2 => Create(name + "=Y,X,Z | " + description + "."), _ => None, }; } public static List YXZ(string description, int index) { return index switch { 0 => Create("Y,X,Z | " + description + "."), 1 => Create("Y,X,Z | " + description + "."), 2 => Create("Y,X,Z | " + description + "."), _ => None, }; } public static List XZ(string name, string description, int index) { return index switch { 0 => Create(name + "=X,Z | " + description + "."), 1 => Create(name + "=X,Z | " + description + "."), _ => None, }; } public static List XZ(string description, int index) { return index switch { 0 => Create("X,Z | " + description + "."), 1 => Create("X,Z | " + description + "."), _ => None, }; } public static List FRU(string name, string description, int index) { return index switch { 0 => Create(name + "=forward,right,up | " + description + "."), 1 => Create(name + "=forward,right,up | " + description + "."), 2 => Create(name + "=forward,right,up | " + description + "."), _ => None, }; } public static List FRU(string description, int index) { return index switch { 0 => Create("forward,right,up | " + description + "."), 1 => Create("forward,right,up | " + description + "."), 2 => Create("forward,right,up | " + description + "."), _ => None, }; } public static List Scale(string name, string description, int index) { return index switch { 0 => Create(name + "=number or " + name + "=X,Z,Y,free | " + description), 1 => Create(name + "=X,Y,Z,free | " + description + "."), 2 => Create(name + "=X,Y,Z,free | " + description + "."), 3 => Create(name + "=X,Y,Zfree | If given, each axis is randomized separately."), _ => None, }; } public static List Scale(string description, int index) { if (index == 0) { return Create("number or " + XYZ(description, index)[0].Substring(0)); } return XYZ(description, index); } public static List RollPitchYaw(string name, string description, int index) { return index switch { 0 => Create(name + "=roll,pitch,yaw | " + description + "."), 1 => Create(name + "=roll,pitch,yaw | " + description + "."), 2 => Create(name + "=roll,pitch,yaw | " + description + "."), _ => None, }; } public static List RollPitchYaw(string description, int index) { return index switch { 0 => Create("roll,pitch,yaw | " + description + "."), 1 => Create("roll,pitch,yaw | " + description + "."), 2 => Create("roll,pitch,yaw | " + description + "."), _ => None, }; } public static List YawRollPitch(string name, string description, int index) { return index switch { 0 => Create(name + "=yaw,roll,pitch | " + description + "."), 1 => Create(name + "=yaw,roll,pitch | " + description + "."), 2 => Create(name + "=yaw,roll,pitch | " + description + "."), _ => None, }; } public static List YawRollPitch(string description, int index) { return index switch { 0 => Create("yaw,roll,pitch | " + description + "."), 1 => Create("yaw,roll,pitch | " + description + "."), 2 => Create("yaw,roll,pitch | " + description + "."), _ => None, }; } static ParameterInfo() { List list = new List(); list.AddRange(from s in Enum.GetNames(typeof(GlobalKeys)) select s.ToLowerInvariant()); globalKeys = list; ids = new List(); environments = new List(); colors = new List(23) { "#rrggbbaa", "aqua", "black", "blue", "brown", "cyan", "darkblue", "fuchsia", "green", "grey", "lightblue", "lime", "magenta", "maroon", "navy", "olive", "orange", "purple", "red", "silver", "teal", "white", "yellow" }; objectIds = new List(); roomIds = new List(); LocationDataCache = null; LocationIdsCache = null; ServerLocationIdsCache = null; VegetationDataCache = null; VegetationIdsCache = null; ServerVegetationIdsCache = null; statusEffects = new List(); itemIds = new List(); hairs = new List(); beards = new List(); keyCodes = new List(); keyCodesWithNegative = new List(); Origin = new List(3) { "player", "object", "world" }; None = Error("Too many parameters!"); Missing = Create("No autocomplete available."); } } [HarmonyPatch(typeof(Chat), "SendText")] public class ServerChat { private static PlayerInfo? serverClient; private static UserInfo? userInfo; public static PlayerInfo ServerClient { get { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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) //IL_0028: Unknown result type (might be due to invalid IL or missing references) PlayerInfo valueOrDefault = serverClient.GetValueOrDefault(); if (!serverClient.HasValue) { valueOrDefault = CreatePlayerInfo(); serverClient = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } public static UserInfo UserInfo { get { //IL_0009: 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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown object obj = userInfo; if (obj == null) { UserInfo val = new UserInfo { Name = ServerClient.m_userInfo.m_displayName, UserId = ServerClient.m_userInfo.m_id }; userInfo = val; obj = (object)val; } return (UserInfo)obj; } } private static PlayerInfo CreatePlayerInfo() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) //IL_0057: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) PlayerInfo result = default(PlayerInfo); result.m_name = Settings.ServerChatName; result.m_characterID = new ZDOID(ZDOMan.GetSessionID(), uint.MaxValue); result.m_userInfo = new CrossNetworkUserInfo { m_id = new PlatformUserID(ZNet.instance.m_steamPlatform, GetId()), m_displayName = Settings.ServerChatName }; result.m_serverAssignedDisplayName = Settings.ServerChatName; result.m_publicPosition = false; result.m_position = Vector3.zero; return result; } public static void RefreshPlayerInfo() { serverClient = null; userInfo = null; } private static string GetId() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) try { CSteamID steamID = SteamGameServer.GetSteamID(); return ((object)(CSteamID)(ref steamID)).ToString(); } catch (InvalidOperationException) { return "0"; } } public static void Write(ZPackage pkg) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0059: Unknown result type (might be due to invalid IL or missing references) pkg.Write(ServerClient.m_name); pkg.Write(ServerClient.m_characterID); PlayerInfo val = ServerClient; pkg.Write(((object)(PlatformUserID)(ref val.m_userInfo.m_id)).ToString()); pkg.Write(ServerClient.m_userInfo.m_displayName); pkg.Write(ServerClient.m_serverAssignedDisplayName); pkg.Write(false); } private static void Postfix(Type type, string text) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) && Settings.IsServerChat) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ChatMessage", new object[4] { Vector3.zero, (int)type, UserInfo, text }); } } } [HarmonyPatch(typeof(ZNet), "TryGetPlayerByPlatformUserID")] public class RecognizeServerClient { private static bool Postfix(bool result, PlatformUserID platformUserID, ref PlayerInfo playerInfo) { //IL_0005: 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) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) if (result) { return result; } if (platformUserID != ServerChat.ServerClient.m_userInfo.m_id) { return result; } playerInfo = ServerChat.ServerClient; return true; } } [HarmonyPatch(typeof(ZNet), "SendPlayerList")] public class AddExtraPlayer { private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0002: 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_0048: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(ZPackage), "Write", new Type[1] { typeof(int) }, (Type[])null), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(AddExtraPlayer), "AddServer", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } private static void AddServer(ZNet net, ZPackage pkg) { if (Settings.IsServerChat) { int pos = pkg.GetPos(); pkg.SetPos(0); if (IsExtraPlayerAdded(net, pkg.ReadInt())) { pkg.SetPos(pos); return; } pkg.SetPos(0); pkg.Write(net.m_players.Count + 1); ServerChat.Write(pkg); } } private static bool IsExtraPlayerAdded(ZNet net, int count) { return count >= net.m_players.Count + 1; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("server_devcommands", "Server Devcommands", "1.108")] public class ServerDevcommands : BaseUnityPlugin { public const string GUID = "server_devcommands"; public const string NAME = "Server Devcommands"; public const string VERSION = "1.108"; public const string COMFY_GIZMO_GUID = "bruce.valheim.comfymods.gizmo"; public const string RELOADED_GIZMO_GUID = "m3to.mods.GizmoReloaded"; private static ManualLogSource? Logs; public static ManualLogSource Log => Logs; public void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Logs = ((BaseUnityPlugin)this).Logger; new Harmony("server_devcommands").PatchAll(); Settings.Init(((BaseUnityPlugin)this).Config); Console.SetConsoleEnabled(true); try { SetupWatcher(); AliasManager.SetupWatcher(); BindManager.SetupWatcher(); PermissionLoader.SetupWatcher(); } catch { } } public void Start() { if (Chainloader.PluginInfos.TryGetValue("bruce.valheim.comfymods.gizmo", out var value)) { ComfyGizmoPatcher.DoPatching(((object)value.Instance).GetType().Assembly); } if (Chainloader.PluginInfos.TryGetValue("m3to.mods.GizmoReloaded", out value)) { GizmoReloadedPatcher.DoPatching(((object)value.Instance).GetType().Assembly); } Api.RegisterGroupHandler("serverdevcommands", PermissionApi.HasGroup); } public void LateUpdate() { MultiCommands.Execute(Time.deltaTime); MouseWheelBinding.Execute(ZInput.GetMouseScrollWheel() * 20f); if (AliasManager.ToBeSaved) { AliasManager.ToFile(); } if (BindManager.ToBeSaved) { BindManager.ToFile(); } if (!Object.op_Implicit((Object)(object)ZNet.instance)) { ParameterInfo.SetServerLocationIds(null); ParameterInfo.SetServerVegetationIds(null); } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { return; } try { ((BaseUnityPlugin)this).Config.Reload(); } catch { Log.LogError((object)("There was an issue loading your " + ((BaseUnityPlugin)this).Config.ConfigFilePath)); Log.LogError((object)"Please check your config entries for spelling and format!"); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] [HarmonyPriority(500)] public class SetCommands { private static bool Initialized; private static void Postfix() { if (!Initialized) { Initialized = true; new DevcommandsCommand(); new ConfigCommand(); new StartEventCommand(); new PosCommand(); new AliasCommand(); new SearchIdCommand(); new UndoRedoCommand(); new ResolutionCommand(); new WaitCommand(); new ServerCommand(); new HUDCommand(); new NoMapCommand(); new BindCommand(); new BroadcastCommand(); new SeedCommand(); new MoveSpawn(); new MappingCommand(); new WindCommand(); new EnvCommand(); new GotoCommand(); new InventoryCommand(); new CalmCommand(); new RepairCommand(); new AddStatusCommand(); new PlayerListCommand(); new FindCommand(); new PullCommand(); new ResetDungeonCommand(); new TeleportCommand(); new SearchComponentCommand(); new SearchItemCommand(); new RPCCommand(); new DmgCommand(); new KillCommand(); new PermissionsCommand(); new ShutdownCommand(); DefaultAutoComplete.Register(); AliasManager.Init(); Settings.RegisterCommands(); } } } [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 && !text.StartsWith("[")) { ZNet.instance.RemotePrint(Target, text); } } } [HarmonyPatch] public class ServerExecution { [CompilerGenerated] private static class <>O { public static Func <0>__VectorXZY; public static Method <1>__RPC_DoRequestIds; public static Action <2>__RPC_Do_Pins; public static Action <3>__ReceiveLocationIds; public static Action <4>__ReceiveVegetationIds; public static Action <5>__ReceivePermissions; } public static string RPC_Pins = "DEV_Pins"; public static string RPC_RequestIds = "EW_RequestIds"; public static string RPC_SyncLocationIds = "EW_SyncLocationIds"; public static string RPC_SyncVegetationIds = "EW_SyncVegetationIds"; [HarmonyPatch(typeof(ZNet), "RPC_RemoteCommand")] [HarmonyPrefix] private static bool ReplceAdminCheckWithCustomCheck(ZNet __instance, ZRpc rpc, string command) { if (!__instance.IsServer()) { return true; } RedirectOutput.Target = rpc; if (!IsRpcCommandAllowed(__instance, rpc, command)) { __instance.RemotePrint(rpc, "Unauthorized to use command '" + GetCommandName(command) + "'."); return false; } __instance.InternalCommand(rpc, command); return false; } [HarmonyPatch(typeof(ZNet), "RPC_RemoteCommand")] [HarmonyFinalizer] private static void ClearTarget() { RedirectOutput.Target = null; } private static bool IsRpcCommandAllowed(ZNet znet, ZRpc rpc, string command) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (rpc == null) { return true; } string commandName = GetCommandName(command); if (!Terminal.commands.TryGetValue(commandName, out var value)) { return false; } ZNetPeer peer = znet.GetPeer(rpc); if (peer == null) { return false; } string hostName = rpc.GetSocket().GetHostName(); ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO == null) { return false; } string characterId = zDO.GetLong(ZDOVars.s_playerID, 0L).ToString(); return PermissionLoader.Data.Resolve(hostName, characterId).IsCommandAllowed(value, command, remote: true); } private static string GetCommandName(string command) { return Parse.Kvp(command, ' ').Key; } public static void Send(string command) { ((Terminal)Console.instance).AddString("Sending command: " + command); ZNet.instance.RemoteCommand(command); } public static void Send(IEnumerable args) { Send(string.Join(" ", args)); } public static void Send(ConsoleEventArgs args) { Send((IEnumerable)args.Args); } public static void RPC_Do_Pins(ZRpc? rpc, string data) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00b5: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = Parse.Split(data, '|').Select(Parse.VectorXZY).ToArray(); List findPins = ((Terminal)Console.instance).m_findPins; foreach (PinData item in findPins) { Minimap instance = Minimap.instance; if (instance != null) { instance.RemovePin(item); } } findPins.Clear(); Vector3[] array2 = array; foreach (Vector3 val in array2) { Minimap instance2 = Minimap.instance; PinData val2 = ((instance2 != null) ? instance2.AddPin(val, (PinType)3, "", false, false, Player.m_localPlayer.GetPlayerID(), default(PlatformUserID)) : null); if (val2 != null) { findPins.Add(val2); } } } public static void RequestIds() { ZRpc serverRPC = ZNet.instance.GetServerRPC(); if (serverRPC != null) { serverRPC.Invoke(RPC_RequestIds, Array.Empty()); } } public static void RPC_DoRequestIds(ZRpc rpc) { string text = string.Join("|", ParameterInfo.LocationIds); string text2 = string.Join("|", ParameterInfo.VegetationIds); rpc.Invoke(RPC_SyncLocationIds, new object[1] { text }); rpc.Invoke(RPC_SyncVegetationIds, new object[1] { text2 }); } public static void ReceiveLocationIds(ZRpc rpc, string locationIds) { List list = new List(); list.AddRange(from s in locationIds.Split(new char[1] { '|' }) where !string.IsNullOrEmpty(s) select s); ParameterInfo.SetServerLocationIds(list); } public static void ReceiveVegetationIds(ZRpc rpc, string vegetationIds) { List list = new List(); list.AddRange(from s in vegetationIds.Split(new char[1] { '|' }) where !string.IsNullOrEmpty(s) select s); ParameterInfo.SetServerVegetationIds(list); } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPostfix] private static void RegisterRPCs(ZNet __instance, ZRpc rpc) { //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 if (__instance.IsServer()) { string rPC_RequestIds = RPC_RequestIds; object obj = <>O.<1>__RPC_DoRequestIds; if (obj == null) { Method val = RPC_DoRequestIds; <>O.<1>__RPC_DoRequestIds = val; obj = (object)val; } rpc.Register(rPC_RequestIds, (Method)obj); } else if (__instance.GetPeer(rpc).m_server) { rpc.Register(RPC_Pins, (Action)RPC_Do_Pins); rpc.Register(RPC_SyncLocationIds, (Action)ReceiveLocationIds); rpc.Register(RPC_SyncVegetationIds, (Action)ReceiveVegetationIds); rpc.Register(PermissionLoader.RPC_Permissions, (Action)Admin.ReceivePermissions); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] [HarmonyPostfix] private static void InitServer() { if (ZNet.instance.IsServer()) { PermissionLoader.FromFile(); } } } public static class Admin { public static bool Checking { get; set; } private static void Check() { if (Object.op_Implicit((Object)(object)ZNet.instance)) { Checking = true; PermissionManager.Instance.ResetToDefaults(); if (ZNet.instance.IsServer()) { OnSuccess(); } else { ZNet.instance.Unban("admintest_" + GetPlayerId()); } } } private static long GetPlayerId() { long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); if (playerID != 0L) { return playerID; } Player localPlayer = Player.m_localPlayer; return (localPlayer != null) ? localPlayer.GetPlayerID() : 0; } public static bool Verify(string text) { if (text == "Unbanning user admintest_" + GetPlayerId()) { OnSuccess(); } else { if (!(text == "You are not admin")) { return false; } OnFail(); } return true; } public static void ReceivePermissions(ZRpc rpc, ZPackage pkg) { PermissionManager.Instance.Read(pkg); if (PermissionManager.Instance.IsAdmin) { OnSuccess(); } else { OnFail(); } } public static void AutomaticCheck() { if (Settings.AutoDevcommands) { Check(); } } private static void OnSuccess() { Checking = false; PermissionManager.Instance.IsAdmin = true; DevcommandsCommand.Set(value: true); ((Terminal)Console.instance).AddString("Authorized to use devcommands."); ServerExecution.RequestIds(); } private static void OnFail() { Checking = false; ((Terminal)Console.instance).AddString("Unauthorized to use devcommands."); } public static void ManualCheck() { Check(); } public static void Reset() { Checking = false; DevcommandsCommand.Set(value: false); } } [HarmonyPatch(typeof(ZNet), "RPC_RemotePrint")] public class ZNet_RPC_RemotePrint { private static bool Prefix(string text) { if (!Admin.Checking) { return true; } return !Admin.Verify(text); } } [HarmonyPatch(typeof(Game), "Start")] public class AdminReset { private static void Postfix() { Admin.Reset(); } } [HarmonyPatch(typeof(Player), "OnSpawned")] public class AdminCheck { private static void Postfix() { if (Game.instance.m_firstSpawn) { Admin.AutomaticCheck(); } else { DevcommandsCommand.EnableAutoFeatures(); } } } [HarmonyPatch(typeof(ZNet), "ListContainsId")] public class ListContainsId { private static bool Prefix(ZNet __instance, SyncedList list, string idString, ref bool __result) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!idString.Contains("_")) { idString = PlatformUserID.GetPlatformPrefix(ZNet.instance.m_steamPlatform) + idString; } if (list != __instance.m_adminList) { return true; } bool? flag = PermissionLoader.Data.ResolveAdminOverride(idString); if (!flag.HasValue) { return true; } __result = flag.Value; return false; } } public class ComponentInfo { private static Type[]? types; private static Dictionary? nameToType; private static Dictionary> PrefabComponents = new Dictionary>(); public static Type[] Types => types ?? (types = LoadTypes()); private static Dictionary NameToType => nameToType ?? (nameToType = LoadNames()); private static Dictionary LoadNames() { Dictionary dictionary = new Dictionary(); Type[] array = Types; foreach (Type type in array) { dictionary[type.Name.ToLowerInvariant()] = type; } return dictionary; } private static Type[] LoadTypes() { List list = new List(); list.Add(Assembly.GetAssembly(typeof(ZNetView))); list.AddRange(from p in Chainloader.PluginInfos.Values where (Object)(object)p.Instance != (Object)null select ((object)p.Instance).GetType().Assembly); Type baseType = typeof(MonoBehaviour); return list.SelectMany(delegate(Assembly s) { try { return s.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type t) => t != null); } }).Where(delegate(Type t) { try { return baseType.IsAssignableFrom(t); } catch { return false; } }).Distinct() .ToArray(); } private static Type[] GetTypes(HashSet components) { return components.Select(delegate(string c) { if (!NameToType.TryGetValue(c.ToLowerInvariant(), out Type value)) { throw new InvalidOperationException("Type " + c + " not recognized."); } return value; }).ToArray(); } private static void SearchComponents() { PrefabComponents = ZNetScene.instance.m_namedPrefabs.Where((KeyValuePair kvp) => Object.op_Implicit((Object)(object)kvp.Value)).ToDictionary((KeyValuePair kvp) => ((Object)kvp.Value).name, delegate(KeyValuePair kvp) { kvp.Value.GetComponentsInChildren(ZNetView.m_tempComponents); return ZNetView.m_tempComponents.Select((MonoBehaviour s) => ((object)s).GetType().Name.ToLowerInvariant()).ToHashSet(); }); } public static string[] PrefabsByComponent(string component) { if (PrefabComponents.Count == 0) { SearchComponents(); } string lower = component.ToLowerInvariant(); return (from kvp in PrefabComponents where kvp.Value.Contains(lower) select kvp.Key).ToArray(); } public static string[] PrefabsByField(string component, string field, string value) { string component2 = component; string field2 = field; string value2 = value; string[] source = PrefabsByComponent(component2); Type type = Types.FirstOrDefault((Type t) => t.Name.ToLowerInvariant() == component2); if (type == null) { return Array.Empty(); } return source.Where(delegate(string prefab) { Component componentInChildren = ZNetScene.instance.GetPrefab(prefab).GetComponentInChildren(type); if (!Object.op_Implicit((Object)(object)componentInChildren)) { return false; } FieldInfo field3 = ((object)componentInChildren).GetType().GetField(field2); return !(field3 == null) && field3.GetValue(componentInChildren).ToString() == value2; }).ToArray(); } public static string[] Get(ZNetView view) { ((Component)view).GetComponentsInChildren(ZNetView.m_tempComponents); return ZNetView.m_tempComponents.Select((MonoBehaviour s) => ((object)s).GetType().Name).ToArray(); } public static bool HasType(ZNetView view, Type[] types) { Type[] types2 = types; ((Component)view).GetComponentsInChildren(ZNetView.m_tempComponents); return ZNetView.m_tempComponents.Any((MonoBehaviour s) => types2.Contains(((object)s).GetType())); } public static IEnumerable HaveComponent(IEnumerable views, HashSet components) { Type[] types = GetTypes(components); return views.Where((ZNetView view) => HasType(view, types)); } public static bool HasComponent(ZNetView view, HashSet components) { Type[] array = GetTypes(components); return HasType(view, array); } } public abstract class Helper { public static bool IsValid(ZoneLocation loc) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (loc != null) { _ = loc.m_prefab; if (!loc.m_prefab.IsValid) { return loc.m_prefab.m_name != null; } return true; } return false; } public static void AddMessage(Terminal context, string message, bool priority = false) { if ((Object)(object)context == (Object)(object)Console.instance || Settings.ChatOutput) { context.AddString(message); } MessageHud instance = MessageHud.instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } if (priority) { MsgData[] array = instance.m_msgQeue.ToArray(); instance.m_msgQeue.Clear(); ((Character)Player.m_localPlayer).Message((MessageType)1, message, 0, (Sprite)null); MsgData[] array2 = array; foreach (MsgData item in array2) { instance.m_msgQeue.Enqueue(item); } instance.m_msgQueueTimer = 10f; } else { ((Character)Player.m_localPlayer).Message((MessageType)1, message, 0, (Sprite)null); } } public static GameObject? GetPrefab(string name) { string name2 = name; GameObject prefab = ZNetScene.instance.GetPrefab(name2); if (Object.op_Implicit((Object)(object)prefab)) { return prefab; } string text = ParameterInfo.ObjectIds.Find((string id) => string.Equals(id, name2, StringComparison.OrdinalIgnoreCase)); prefab = ((text == null) ? null : ZNetScene.instance.GetPrefab(text)); if (!Object.op_Implicit((Object)(object)prefab)) { ((Character)Player.m_localPlayer).Message((MessageType)1, "Missing object " + name2, 0, (Sprite)null); } return prefab; } public static string GetPrefabName(int hash) { GameObject prefab = ZNetScene.instance.GetPrefab(hash); if (!Object.op_Implicit((Object)(object)prefab)) { return ""; } return Utils.GetPrefabName(prefab); } public static int Hash(string key) { if (int.TryParse(key, out var result)) { return result; } if (key.StartsWith("$", StringComparison.InvariantCultureIgnoreCase)) { int hash = ZSyncAnimation.GetHash(key.Substring(1)); if (key == "$anim_speed") { return hash; } return 438569 + hash; } return StringExtensionMethods.GetStableHashCode(key); } public static bool Within(Range range, float value) { if (range.Min == range.Max) { return value <= range.Max; } if (range.Min <= value) { return value <= range.Max; } return false; } public static bool Within(Range range1, Range range2, float value1, float value2) { if (value1 > range1.Max) { return false; } if (value2 > range2.Max) { return false; } if (range1.Min == range1.Max || value1 >= range1.Min) { return true; } if (range2.Min == range2.Max || value2 >= range2.Min) { return true; } return false; } public static float RandomValue(Range? range) { if (range != null) { if (range.Min != range.Max) { return Random.Range(range.Min, range.Max); } return range.Min; } return 0f; } public static int RandomValue(Range? range) { if (range != null) { if (range.Min != range.Max) { return Random.Range(range.Min, range.Max + 1); } return range.Min; } return 0; } public static Vector3 RandomValue(Range? range) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) if (range == null) { return Vector3.zero; } if (range.Uniform) { float num = Random.Range(0f, 1f); return Vector3.Lerp(range.Min, range.Max, num); } float num2 = Random.Range(range.Min.x, range.Max.x); float num3 = Random.Range(range.Min.y, range.Max.y); float num4 = Random.Range(range.Min.z, range.Max.z); return new Vector3(num2, num3, num4); } public static Quaternion RandomValue(Range? range) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (range == null) { return Quaternion.identity; } float num = Random.Range(range.Min.x, range.Max.x); float num2 = Random.Range(range.Min.y, range.Max.y); float num3 = Random.Range(range.Min.z, range.Max.z); float num4 = Random.Range(range.Min.w, range.Max.w); return new Quaternion(num, num2, num3, num4); } public static string[] AddPlayerPosXZ(string[] args, int count) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (args.Length < count) { return args; } if ((Object)(object)Player.m_localPlayer == (Object)null) { return args; } List list = args.ToList(); Vector3 position = ((Component)Player.m_localPlayer).transform.position; if (list.Count < count + 1) { list.Add(position.x.ToString(CultureInfo.InvariantCulture)); } if (list.Count < count + 2) { list.Add(position.z.ToString(CultureInfo.InvariantCulture)); } return list.ToArray(); } public static string[] AddPlayerPosXZY(string[] args, int count) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (args.Length < count) { return args; } if ((Object)(object)Player.m_localPlayer == (Object)null) { return args; } List list = args.ToList(); Vector3 position = ((Component)Player.m_localPlayer).transform.position; if (list.Count < count + 1) { list.Add(position.x.ToString(CultureInfo.InvariantCulture) + "," + position.z.ToString(CultureInfo.InvariantCulture) + "," + position.y.ToString(CultureInfo.InvariantCulture)); } return list.ToArray(); } public static PlayerInfo FindPlayer(string name, bool publicOnly = false) { //IL_002c: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) string name2 = name; List players = ZNet.instance.m_players; PlayerInfo result = ((IEnumerable)players).FirstOrDefault((Func)((PlayerInfo player) => player.m_name == name2 && (player.m_publicPosition || !publicOnly))); if (!((ZDOID)(ref result.m_characterID)).IsNone()) { return result; } result = ((IEnumerable)players).FirstOrDefault((Func)((PlayerInfo player) => player.m_name.ToLower().StartsWith(name2.ToLower()) && (player.m_publicPosition || !publicOnly))); if (!((ZDOID)(ref result.m_characterID)).IsNone()) { return result; } result = ((IEnumerable)players).FirstOrDefault((Func)((PlayerInfo player) => player.m_name.ToLower().Contains(name2.ToLower()) && (player.m_publicPosition || !publicOnly))); if (!((ZDOID)(ref result.m_characterID)).IsNone()) { return result; } throw new InvalidOperationException("Unable to find the player."); } public static float Round(float value) { return Mathf.Round(value * 1000f) / 1000f; } public static bool IsZero(float a) { return Mathf.Abs(a) < 0.001f; } public static bool Approx(float a, float b) { return Mathf.Abs(a - b) < 0.001f; } public static bool ApproxBetween(float a, float min, float max) { if (min - 0.001f <= a) { return a <= max + 0.001f; } return false; } public static string PrintVectorXZY(Vector3 vector) { return vector.x.ToString("0.##", CultureInfo.InvariantCulture) + ", " + vector.z.ToString("0.##", CultureInfo.InvariantCulture) + ", " + vector.y.ToString("0.##", CultureInfo.InvariantCulture); } public static string PrintVectorYXZ(Vector3 vector) { return vector.y.ToString("0.##", CultureInfo.InvariantCulture) + ", " + vector.x.ToString("0.##", CultureInfo.InvariantCulture) + ", " + vector.z.ToString("0.##", CultureInfo.InvariantCulture); } public static string PrintAngleYXZ(Quaternion quaternion) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return PrintVectorYXZ(((Quaternion)(ref quaternion)).eulerAngles); } public static void AddError(Terminal context, string message, bool priority = false) { AddMessage(context, "Error: " + message, priority); } public static bool? IsDown(string key) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (key.StartsWith("-", StringComparison.OrdinalIgnoreCase)) { if (!Enum.TryParse(key.Substring(1), ignoreCase: true, out KeyCode result)) { return null; } return !Input.GetKey(result); } if (!Enum.TryParse(key, ignoreCase: true, out KeyCode result2)) { return null; } return Input.GetKey(result2); } public static Player GetPlayer() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { throw new InvalidOperationException("No player."); } return localPlayer; } public static void ArgsCheck(ConsoleEventArgs args, int amount, string message) { if (args.Length < amount) { throw new InvalidOperationException(message); } } public static void Command(string name, string description, ConsoleEvent action, bool remote = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(name, description, Catch(action), true, true, false, false, false, (ConsoleOptionsFetcher)null, false, remote, false); } public static void Command(string name, string description, ConsoleEvent action) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(name, description, Catch(action), true, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } public static ConsoleEvent Catch(ConsoleEvent action) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown ConsoleEvent action2 = action; return (ConsoleEvent)delegate(ConsoleEventArgs args) { try { action2.Invoke(args); } catch (InvalidOperationException ex) { AddError(args.Context, ex.Message); } }; } public static void Command(string name, string description, ConsoleEventFailable action) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(name, description, Catch(action), true, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } public static ConsoleEventFailable Catch(ConsoleEventFailable action) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown ConsoleEventFailable action2 = action; return (ConsoleEventFailable)delegate(ConsoleEventArgs args) { try { return action2.Invoke(args); } catch (InvalidOperationException ex) { AddError(args.Context, ex.Message); } return null; }; } public static bool IsDedicated() { if (Object.op_Implicit((Object)(object)ZNet.instance)) { return ZNet.instance.IsDedicated(); } return true; } public static bool IsServer() { if (Object.op_Implicit((Object)(object)ZNet.instance)) { return ZNet.instance.IsServer(); } return false; } public static bool IsClient() { return !IsServer(); } public static string GetPlayerID() { Player localPlayer = Player.m_localPlayer; return ((localPlayer != null) ? localPlayer.GetPlayerID().ToString() : null) ?? ""; } 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; } } public class Range { public T Min; public T Max; public bool Uniform; public Range(T value) { Min = value; Max = value; } public Range(T min, T max) { Min = min; Max = max; } } public static class Parse { private static readonly HashSet Truthies = new HashSet { "1", "t", "true", "yes", "on" }; private static readonly HashSet Falsies = new HashSet { "0", "f", "false", "no", "off" }; private static Range Range(string arg) { List list = arg.Split(new char[1] { ';' }).ToList(); if (list.Count == 2) { return new Range(list[0], list[1]); } list = arg.Split(new char[1] { '-' }).ToList(); if (list.Count > 1 && list[0] == "") { list[0] = "-" + list[1]; list.RemoveAt(1); } if (list.Count > 2 && list[1] == "") { list[1] = "-" + list[2]; list.RemoveAt(2); } if (list.Count == 1) { return new Range(list[0]); } return new Range(list[0], list[1]); } public static int Int(string arg, int defaultValue = 0) { if (int.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static int Int(string[] args, int index, int defaultValue = 0) { if (args.Length <= index) { return defaultValue; } return Int(args[index], defaultValue); } public static int? IntNull(string arg) { if (int.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return null; } public static int? IntNull(string[] args, int index) { if (args.Length <= index) { return null; } return IntNull(args[index]); } public static Range IntRange(string arg, int defaultValue = 0) { Range range = Range(arg); return new Range(Int(range.Min, defaultValue), Int(range.Max, defaultValue)); } public static Range IntRange(string[] args, int index, int defaultValue = 0) { if (args.Length <= index) { return new Range(defaultValue); } return IntRange(args[index], defaultValue); } public static uint UInt(string arg, uint defaultValue = 0u) { if (uint.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static uint UInt(string[] args, int index, uint defaultValue = 0u) { if (args.Length <= index) { return defaultValue; } return UInt(args[index], defaultValue); } public static Range UIntRange(string arg, uint defaultValue = 0u) { Range range = Range(arg); return new Range(UInt(range.Min, defaultValue), UInt(range.Max, defaultValue)); } public static Range UIntRange(string[] args, int index, uint defaultValue = 0u) { if (args.Length <= index) { return new Range(defaultValue); } return UIntRange(args[index], defaultValue); } public static long Long(string arg, long defaultValue = 0L) { if (long.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return defaultValue; } public static long Long(string[] args, int index, long defaultValue = 0L) { if (args.Length <= index) { return defaultValue; } return Long(args[index], defaultValue); } public static long? LongNull(string[] args, int index) { if (args.Length <= index) { return null; } return LongNull(args[index]); } public static long? LongNull(string arg) { if (long.TryParse(arg, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result; } return null; } public static Range LongRange(string arg, long defaultValue = 0L) { Range range = Range(arg); return new Range(Long(range.Min, defaultValue), Long(range.Max, defaultValue)); } public static Range LongRange(string[] args, int index, long defaultValue = 0L) { if (args.Length <= index) { return new Range(defaultValue); } return LongRange(args[index], defaultValue); } public static float Float(string arg, float defaultValue = 0f) { if (!float.TryParse(arg, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return defaultValue; } return result; } public static bool TryFloat(string arg, out float value) { return float.TryParse(arg, NumberStyles.Float, CultureInfo.InvariantCulture, out value); } public static float Float(string[] args, int index, float defaultValue = 0f) { if (args.Length <= index) { return defaultValue; } return Float(args[index], defaultValue); } public static float? FloatNull(string arg) { if (float.TryParse(arg, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } return null; } public static float? FloatNull(string[] args, int index) { if (args.Length <= index) { return null; } return FloatNull(args[index]); } public static Range FloatRange(string arg, float defaultValue = 0f) { Range range = Range(arg); return new Range(Float(range.Min, defaultValue), Float(range.Max, defaultValue)); } public static Range FloatRange(string[] args, int index, float defaultValue = 0f) { if (args.Length <= index) { return new Range(defaultValue); } return FloatRange(args[index], defaultValue); } public static string String(string[] args, int index, string defaultValue = "") { if (args.Length <= index) { return defaultValue; } return args[index]; } public static Quaternion AngleYXZ(string arg) { //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) return AngleYXZ(arg, Quaternion.identity); } public static Quaternion AngleYXZ(string[] values, int index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return AngleYXZ(values, Quaternion.identity, index); } public static Quaternion AngleYXZ(string arg, Quaternion defaultValue) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return AngleYXZ(Split(arg), defaultValue); } public static Quaternion AngleYXZ(string[] values, Quaternion defaultValue, int index = 0) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0059: Unknown result type (might be due to invalid IL or missing references) Vector3 zero = Vector3.zero; zero.y = Float(values, index, ((Quaternion)(ref defaultValue)).eulerAngles.y); zero.x = Float(values, 1 + index, ((Quaternion)(ref defaultValue)).eulerAngles.x); zero.z = Float(values, 2 + index, ((Quaternion)(ref defaultValue)).eulerAngles.z); return Quaternion.Euler(zero); } public static Quaternion? AngleYXZNull(string arg) { return AngleYXZNull(Split(arg)); } public static Quaternion? AngleYXZNull(string[] values) { //IL_0052: 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) float? num = FloatNull(values, 0); float? num2 = FloatNull(values, 1); float? num3 = FloatNull(values, 2); if (!num.HasValue || !num2.HasValue || !num3.HasValue) { return null; } return Quaternion.Euler(new Vector3(num2.Value, num.Value, num3.Value)); } public static Range AngleYXZRange(string arg) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return AngleYXZRange(arg, Quaternion.identity); } public static Range AngleYXZRange(string arg, Quaternion defaultValue) { //IL_000a: 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_0025: Unknown result type (might be due to invalid IL or missing references) string[] args = Split(arg); Range y = FloatRange(args, 0, defaultValue.y); Range x = FloatRange(args, 1, defaultValue.x); Range z = FloatRange(args, 2, defaultValue.z); return ToAngleRange(x, y, z); } private static Range ToAngleRange(Range x, Range y, Range z) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Quaternion min = Quaternion.Euler(new Vector3(x.Min, y.Min, z.Min)); Quaternion max = Quaternion.Euler(new Vector3(x.Max, y.Max, z.Max)); return new Range(min, max); } public static Vector3 VectorXZY(string arg) { //IL_0009: 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) return VectorXZY(Split(arg), 0, Vector3.zero); } public static Vector3 VectorXZY(string[] args) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return VectorXZY(args, 0, Vector3.zero); } public static Vector3 VectorXZY(string[] args, Vector3 defaultValue) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return VectorXZY(args, 0, defaultValue); } public static Vector3 VectorXZY(string[] args, int index) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return VectorXZY(args, index, Vector3.zero); } public static Vector3 VectorXZY(string[] args, int index, Vector3 defaultValue) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) Vector3 zero = Vector3.zero; zero.x = Float(args, index, defaultValue.x); zero.y = Float(args, index + 2, defaultValue.y); zero.z = Float(args, index + 1, defaultValue.z); return zero; } public static Vector3? VectorXZYNull(string arg) { return VectorXZYNull(Split(arg)); } public static Vector3? VectorXZYNull(string[] args) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) float? num = FloatNull(args, 0); float? num2 = FloatNull(args, 2); float? num3 = FloatNull(args, 1); if (!num.HasValue || !num2.HasValue || !num3.HasValue) { return null; } return new Vector3(num.Value, num2.Value, num3.Value); } public static Vector3 VectorZYX(string arg) { //IL_0009: 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) return VectorZYX(Split(arg), 0, Vector3.zero); } public static Vector3 VectorZYX(string[] args, int index, Vector3 defaultValue) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) Vector3 zero = Vector3.zero; zero.x = Float(args, index + 2, defaultValue.z); zero.y = Float(args, index + 1, defaultValue.y); zero.z = Float(args, index, defaultValue.x); return zero; } public static Range VectorZYXRange(string arg, Vector3 defaultValue) { //IL_000a: 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_0025: Unknown result type (might be due to invalid IL or missing references) string[] args = Split(arg); Range x = FloatRange(args, 2, defaultValue.x); Range y = FloatRange(args, 1, defaultValue.y); Range z = FloatRange(args, 0, defaultValue.z); return ToVectorRange(x, y, z); } public static Range VectorIntZYXRange(string arg, Vector3Int defaultValue) { string[] args = Split(arg); Range x = IntRange(args, 2, ((Vector3Int)(ref defaultValue)).x); Range y = IntRange(args, 1, ((Vector3Int)(ref defaultValue)).y); Range z = IntRange(args, 0, ((Vector3Int)(ref defaultValue)).z); return ToVectorRange(x, y, z); } public static Range VectorXZYRange(string arg, Vector3 defaultValue) { //IL_000a: 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_0025: Unknown result type (might be due to invalid IL or missing references) string[] args = Split(arg); Range x = FloatRange(args, 0, defaultValue.x); Range y = FloatRange(args, 2, defaultValue.y); Range z = FloatRange(args, 1, defaultValue.z); return ToVectorRange(x, y, z); } public static Vector2i Vector2Int(string arg) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) string[] array = SplitWithEmpty(arg); return new Vector2i(Int(array[0]), (array.Length > 1) ? Int(array[1]) : 0); } public static Vector3 VectorZXY(string[] args) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return VectorZXY(args, 0, Vector3.zero); } public static Vector3 VectorZXY(string[] args, Vector3 defaultValue) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return VectorZXY(args, 0, defaultValue); } public static Vector3 VectorZXY(string[] args, int index) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return VectorZXY(args, index, Vector3.zero); } public static Vector3 VectorZXY(string[] args, int index, Vector3 defaultValue) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) Vector3 zero = Vector3.zero; zero.x = Float(args, index + 1, defaultValue.x); zero.y = Float(args, index + 2, defaultValue.y); zero.z = Float(args, index, defaultValue.z); return zero; } public static Range VectorZXYRange(string arg, Vector3 defaultValue) { //IL_000a: 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_0025: Unknown result type (might be due to invalid IL or missing references) string[] args = Split(arg); Range x = FloatRange(args, 1, defaultValue.x); Range y = FloatRange(args, 2, defaultValue.y); Range z = FloatRange(args, 0, defaultValue.z); return ToVectorRange(x, y, z); } private static Range ToVectorRange(Range x, Range y, Range z) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Vector3 min = new Vector3(x.Min, y.Min, z.Min); Vector3 max = default(Vector3); ((Vector3)(ref max))..ctor(x.Max, y.Max, z.Max); return new Range(min, max); } private static Range ToVectorRange(Range x, Range y, Range z) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Vector3Int min = new Vector3Int(x.Min, y.Min, z.Min); Vector3Int max = default(Vector3Int); ((Vector3Int)(ref max))..ctor(x.Max, y.Max, z.Max); return new Range(min, max); } public static Vector3 VectorYXZ(string arg) { //IL_0009: 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) return VectorYXZ(Split(arg), 0, Vector3.zero); } public static Vector3 VectorYXZ(string[] args) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return VectorYXZ(args, 0, Vector3.zero); } public static Vector3 VectorYXZ(string[] args, Vector3 defaultValue) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return VectorYXZ(args, 0, defaultValue); } public static Vector3 VectorYXZ(string[] args, int index) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return VectorYXZ(args, index, Vector3.zero); } public static Vector3 VectorYXZ(string[] args, int index, Vector3 defaultValue) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) Vector3 zero = Vector3.zero; zero.y = Float(args, index, defaultValue.y); zero.x = Float(args, index + 1, defaultValue.x); zero.z = Float(args, index + 2, defaultValue.z); return zero; } public static Range VectorYXZRange(string arg, Vector3 defaultValue) { //IL_000a: 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_0025: Unknown result type (might be due to invalid IL or missing references) string[] args = Split(arg); Range x = FloatRange(args, 1, defaultValue.x); Range y = FloatRange(args, 0, defaultValue.y); Range z = FloatRange(args, 2, defaultValue.z); return ToVectorRange(x, y, z); } public static Vector3 Scale(string[] args) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Scale(args, 0); } public static Vector3 Scale(string[] args, int index) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return SanityCheck(VectorXZY(args, index)); } private static Vector3 SanityCheck(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) if (scale.x == 0f) { scale.x = 1f; } if (scale.y == 0f) { scale.y = scale.x; } if (scale.z == 0f) { scale.z = scale.x; } return scale; } public static Range ScaleRange(string arg) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) string[] array = Split(arg); Range x = FloatRange(array, 0); Range y = FloatRange(array, 2); Range z = FloatRange(array, 1); Range range = ToVectorRange(x, y, z); range.Min = SanityCheck(range.Min); range.Max = SanityCheck(range.Max); range.Uniform = array.Length < 4; return range; } public static string[] SplitWithEscape(string arg, char separator = ',') { List list = new List(); string[] array = arg.Split(new char[1] { separator }); for (int i = 0; i < array.Length; i++) { string text = array[i].TrimStart(Array.Empty()); if (text.StartsWith("\"")) { array[i] = text.Substring(1); int j; for (j = i; j < array.Length; j++) { text = array[j].TrimEnd(Array.Empty()); if (text.EndsWith("\"")) { array[j] = text.Substring(0, text.Length - 1); break; } } list.Add(string.Join(separator.ToString(), array.Skip(i).Take(j - i + 1))); i = j; } else { list.Add(array[i].Trim()); } } return list.ToArray(); } public static KeyValuePair Kvp(string str, char separator = ',') { int num = str.IndexOf(separator); if (num < 0) { return new KeyValuePair(str, ""); } return new KeyValuePair(str.Substring(0, num), str.Substring(num + 1).Trim()); } public static string[] SplitWithEmpty(string arg, char separator = ',') { return (from s in arg.Split(new char[1] { separator }) select s.Trim()).ToArray(); } public static string[] Split(string arg, char separator = ',') { return (from s in arg.Split(new char[1] { separator }) select s.Trim() into s where s != "" select s).ToArray(); } public static string[] Split(string[] args, int index, char separator) { if (args.Length <= index) { return Array.Empty(); } return Split(args[index], separator); } private static bool IsTruthy(string value) { return Truthies.Contains(value); } private static bool IsFalsy(string value) { return Falsies.Contains(value); } public static bool? Boolean(string value) { if (IsTruthy(value)) { return true; } if (IsFalsy(value)) { return false; } return Helper.IsDown(value); } public static bool? BoolNull(string? arg) { if (arg == null) { return null; } arg = arg.ToLower(); if (IsTruthy(arg)) { return true; } if (IsFalsy(arg)) { return false; } return null; } public static string Logic(string value) { if (!value.Contains("?") || !value.Contains(":")) { return value; } string[] array = value.Split(new char[1] { '?' }); string value2 = array[0]; array = array[1].Split(new char[1] { ':' }); if (!Boolean(value2).GetValueOrDefault()) { return array[1]; } return array[0]; } public static float Multiplier(string value) { float num = 1f; string[] array = value.Split(new char[1] { '*' }); foreach (string arg in array) { num *= Float(arg, 1f); } return num; } public static float TryMultiplier(string[] args, int index, float defaultValue = 1f) { if (args.Length <= index) { return defaultValue; } return Multiplier(args[index]); } public static float Direction(string[] args, int index) { if (args.Length > index) { return Direction(args[index]); } return 1f; } public static float Direction(string arg) { if (!(Float(arg, 1f) > 0f)) { return -1f; } return 1f; } } public interface IUndoAction { string Undo(); string Redo(); } public class UndoManager { private static readonly BindingFlags Binding = BindingFlags.Instance | BindingFlags.Public; private static List History = new List(); private static int Index = -1; private static bool Executing = false; public static int MaxSteps = 50; public static void Add(IUndoAction action) { Add((object)action); } private static void Add(object action) { if (!Executing) { if (History.Count > MaxSteps - 1) { History = History.Skip(History.Count - MaxSteps + 1).ToList(); } if (Index < History.Count - 1) { History = History.Take(Index + 1).ToList(); } History.Add(action); Index = History.Count - 1; } } public static bool Undo(Terminal terminal) { if (Index < 0) { Helper.AddMessage(terminal, "Nothing to undo."); return false; } Executing = true; try { object obj = History[Index]; object obj2 = obj.GetType().GetMethod("Undo", Binding).Invoke(obj, null); if (string.IsNullOrEmpty((string)obj2)) { obj2 = obj.GetType().GetMethod("UndoMessage", Binding).Invoke(obj, null); } Helper.AddMessage(terminal, (string)obj2); } catch (Exception ex) { ServerDevcommands.Log.LogWarning((object)ex); } Index--; Executing = false; return true; } public static bool Redo(Terminal terminal) { if (Index < History.Count - 1) { Executing = true; Index++; try { object obj = History[Index]; object obj2 = obj.GetType().GetMethod("Redo", Binding).Invoke(obj, null); if (string.IsNullOrEmpty((string)obj2)) { obj2 = obj.GetType().GetMethod("RedoMessage", Binding).Invoke(obj, null); } Helper.AddMessage(terminal, (string)obj2); } catch (Exception ex) { ServerDevcommands.Log.LogWarning((object)ex); } Executing = false; return true; } Helper.AddMessage(terminal, "Nothing to redo."); return false; } } public class PermissionData { private const string AnyCharacter = "*"; private readonly List _entries; private readonly Dictionary _entriesByKey; private readonly Dictionary> _groupsCache; private readonly Dictionary _adminOverrideCache; public List Entries => _entries; public int Count => _entriesByKey.Count; public static string PeerKey(string hostname, string characterId) { if (string.IsNullOrWhiteSpace(hostname) || string.IsNullOrWhiteSpace(characterId)) { return ""; } return hostname + "_" + characterId; } public static string PeerWildcardKey(string hostname) { return PeerKey(hostname, "*"); } public PermissionData() { _entries = new List(); _entriesByKey = new Dictionary(); _groupsCache = new Dictionary>(); _adminOverrideCache = new Dictionary(); } public PermissionData(List? entries) { _entries = entries ?? new List(); _entriesByKey = ToDictionary(_entries); _groupsCache = new Dictionary>(); _adminOverrideCache = new Dictionary(); RebuildGroupCache(); } public bool TryGetValue(string key, out PermissionEntry entry) { return _entriesByKey.TryGetValue(key, out entry); } public PermissionEntry GetOrCreate(string key) { if (_entriesByKey.TryGetValue(key, out PermissionEntry value)) { return value; } value = new PermissionEntry { name = key }; _entries.Add(value); _entriesByKey[key] = value; _groupsCache[key] = new HashSet(); return value; } public bool AddGroup(PermissionEntry entry, string group) { string group2 = group; if (!TryGetTrackedEntry(entry, out string key, out PermissionEntry tracked)) { return false; } group2 = group2?.Trim() ?? ""; if (group2 == "") { return false; } PermissionEntry permissionEntry = tracked; if (permissionEntry.groups == null) { permissionEntry.groups = new List(); } if (tracked.groups.Exists((string raw) => raw.Trim().Equals(group2, StringComparison.OrdinalIgnoreCase))) { return false; } tracked.groups.Add(group2); RefreshGroupCache(key); _adminOverrideCache.Remove(key); return true; } public bool RemoveGroup(PermissionEntry entry, string group) { string group2 = group; if (!TryGetTrackedEntry(entry, out string key, out PermissionEntry tracked)) { return false; } group2 = group2?.Trim() ?? ""; if (group2 == "") { return false; } if (tracked.groups == null) { return false; } int count = tracked.groups.Count; tracked.groups.RemoveAll((string raw) => raw.Trim().Equals(group2, StringComparison.OrdinalIgnoreCase)); if (tracked.groups.Count == 0) { tracked.groups = null; } bool num = count != (tracked.groups?.Count ?? 0); if (num) { RefreshGroupCache(key); _adminOverrideCache.Remove(key); } return num; } public bool ClearGroups(PermissionEntry entry) { if (!TryGetTrackedEntry(entry, out string key, out PermissionEntry tracked)) { return false; } if (tracked.groups == null || tracked.groups.Count == 0) { return false; } tracked.groups = null; RefreshGroupCache(key); _adminOverrideCache.Remove(key); return true; } public bool SetFeaturePermission(PermissionEntry entry, string section, string feature, PermissionManager.FeaturePermission permission) { string feature2 = feature; if (!TryGetTrackedEntry(entry, out string _, out PermissionEntry tracked)) { return false; } section = section?.Trim().ToLowerInvariant() ?? ""; feature2 = feature2?.Trim() ?? ""; if (section == "" || feature2 == "") { throw new InvalidOperationException("Missing section or feature name."); } PermissionEntry permissionEntry = tracked; if (permissionEntry.features == null) { permissionEntry.features = new Dictionary>(); } if (!tracked.features.TryGetValue(section, out List value)) { value = new List(); tracked.features[section] = value; } string text = PermissionToSuffix(permission); string replacement = ((text == "yes") ? feature2 : (feature2 + ": " + text)); bool num = value.Exists((string raw) => raw.Equals(replacement, StringComparison.OrdinalIgnoreCase)); int count = value.Count; value.RemoveAll((string raw) => IsMatchingFeature(raw, feature2)); value.Add(replacement); if (num) { return count != value.Count; } return true; } public bool ClearFeature(PermissionEntry entry, string section, string feature) { string feature2 = feature; if (!TryGetTrackedEntry(entry, out string _, out PermissionEntry tracked)) { return false; } section = section?.Trim().ToLowerInvariant() ?? ""; feature2 = feature2?.Trim() ?? ""; if (section == "" || feature2 == "") { throw new InvalidOperationException("Missing section or feature name."); } if (tracked.features == null) { return false; } if (!tracked.features.TryGetValue(section, out List value)) { return false; } int count = value.Count; value.RemoveAll((string raw) => IsMatchingFeature(raw, feature2)); if (value.Count == 0) { tracked.features.Remove(section); } if (tracked.features.Count == 0) { tracked.features = null; } return count != value.Count; } public bool SetCommandPermission(PermissionEntry entry, string command, PermissionManager.FeaturePermission permission) { string command2 = command; if (!TryGetTrackedEntry(entry, out string _, out PermissionEntry tracked)) { return false; } command2 = command2?.Trim() ?? ""; if (command2 == "") { throw new InvalidOperationException("Missing command name."); } PermissionEntry permissionEntry = tracked; if (permissionEntry.commands == null) { permissionEntry.commands = new List(); } string text = PermissionToSuffix(permission); string replacement = ((text == "yes") ? command2 : (command2 + ": " + text)); bool num = tracked.commands.Exists((string raw) => raw.Equals(replacement, StringComparison.OrdinalIgnoreCase)); int count = tracked.commands.Count; tracked.commands.RemoveAll((string raw) => IsMatchingCommand(raw, command2)); tracked.commands.Add(replacement); if (num) { return count != tracked.commands.Count; } return true; } public bool ClearCommand(PermissionEntry entry, string command) { string command2 = command; if (!TryGetTrackedEntry(entry, out string _, out PermissionEntry tracked)) { return false; } command2 = command2?.Trim() ?? ""; if (command2 == "") { throw new InvalidOperationException("Missing command name."); } if (tracked.commands == null) { return false; } int count = tracked.commands.Count; tracked.commands.RemoveAll((string raw) => IsMatchingCommand(raw, command2)); int count2 = tracked.commands.Count; if (tracked.commands.Count == 0) { tracked.commands = null; } return count != count2; } public bool ClearAll(PermissionEntry entry) { if (!TryGetTrackedEntry(entry, out string _, out PermissionEntry tracked)) { return false; } bool result = ClearGroups(tracked); if (tracked.commands != null) { tracked.commands = null; result = true; } if (tracked.features != null) { tracked.features = null; result = true; } if (!string.IsNullOrWhiteSpace(tracked.admin)) { tracked.admin = ""; _adminOverrideCache[EntryKey(tracked)] = null; result = true; } return result; } public bool HasGroup(string key, string group) { if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(group)) { return false; } if (!_groupsCache.TryGetValue(key, out HashSet value)) { return false; } return value.Contains(group.Trim().ToLowerInvariant()); } public bool HasGroup(string hostname, string characterId, string group) { string text = PeerKey(hostname, characterId); if (text == "") { return false; } if (HasGroup(text, group)) { return true; } string key = PeerWildcardKey(hostname); return HasGroup(key, group); } private static bool IsMatchingFeature(string raw, string feature) { return Parse.Kvp(raw, ':').Key.Trim().Equals(feature.Trim(), StringComparison.OrdinalIgnoreCase); } private static bool IsMatchingCommand(string raw, string command) { return Parse.Kvp(raw, ':').Key.Trim().Equals(command.Trim(), StringComparison.OrdinalIgnoreCase); } private static string PermissionToSuffix(PermissionManager.FeaturePermission permission) { return permission switch { PermissionManager.FeaturePermission.No => "no", PermissionManager.FeaturePermission.Force => "force", _ => "yes", }; } public void RebuildGroupCache() { _groupsCache.Clear(); foreach (string key in _entriesByKey.Keys) { RefreshGroupCache(key); } } public void RefreshGroupCache(string key) { if (!string.IsNullOrWhiteSpace(key)) { if (!_entriesByKey.ContainsKey(key)) { _groupsCache.Remove(key); return; } HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); HashSet visitedPath = new HashSet(StringComparer.OrdinalIgnoreCase); AddResolvedGroups(key, hashSet, visitedPath); _groupsCache[key] = hashSet; } } private void AddResolvedGroups(string key, HashSet resolved, HashSet visitedPath) { if (!visitedPath.Add(key)) { return; } if (!_entriesByKey.TryGetValue(key, out PermissionEntry value) || value.groups == null) { visitedPath.Remove(key); return; } foreach (string group in value.groups) { string text = group.Trim().ToLowerInvariant(); if (!(text == "")) { resolved.Add(text); AddResolvedGroups(text, resolved, visitedPath); } } visitedPath.Remove(key); } public bool UpdatePeer(string hostname, string characterId, string playerName) { string text = PeerKey(hostname, characterId); if (text == "") { return false; } PermissionEntry orCreate = GetOrCreate(text); return false | UpdateString(orCreate, (PermissionEntry e) => e.name, delegate(PermissionEntry e, string value) { e.name = value; }, playerName) | UpdateString(orCreate, (PermissionEntry e) => e.id, delegate(PermissionEntry e, string value) { e.id = value; }, hostname) | UpdateString(orCreate, (PermissionEntry e) => e.character, delegate(PermissionEntry e, string value) { e.character = value; }, characterId); } public PermissionManager Resolve(string hostname, string characterId) { PermissionManager permissionManager = new PermissionManager(ZNet.instance.IsAdmin(hostname)); List list = BuildResolutionChain(hostname, characterId); for (int i = 0; i < list.Count; i++) { permissionManager.AddEntry(list[i]); } return permissionManager; } public bool? ResolveAdminOverride(string hostname, string characterId) { string text = PeerKey(hostname, characterId); if (text == "") { return null; } if (_adminOverrideCache.TryGetValue(text, out var value)) { return value; } List list = BuildResolutionChain(hostname, characterId); bool? flag = null; for (int i = 0; i < list.Count; i++) { string text2 = list[i].admin?.Trim().ToLowerInvariant() ?? ""; if (text2 == "yes") { flag = true; } else if (text2 == "no") { flag = false; } } _adminOverrideCache[text] = flag; return flag; } public bool? ResolveAdminOverride(string hostname) { return ResolveAdminOverride(hostname, "*"); } private List BuildResolutionChain(string hostname, string characterId) { List result = new List(); HashSet visitedPath = new HashSet(); HashSet addedEntries = new HashSet(); AddEntryWithParents("Everyone", result, visitedPath, addedEntries); string text = PeerWildcardKey(hostname); if (text != "") { AddEntryWithParents(text, result, visitedPath, addedEntries); } string key = PeerKey(hostname, characterId); AddEntryWithParents(key, result, visitedPath, addedEntries); return result; } private void AddEntryWithParents(string key, List result, HashSet visitedPath, HashSet addedEntries) { if (_entriesByKey.TryGetValue(key, out PermissionEntry value)) { AddGroupChains(value.groups, result, visitedPath, addedEntries); if (!addedEntries.Contains(key)) { addedEntries.Add(key); result.Add(value); } } } private void AddGroupChains(List? groupNames, List result, HashSet visitedPath, HashSet addedEntries) { if (groupNames == null) { return; } foreach (string groupName in groupNames) { AddGroupChain(groupName, result, visitedPath, addedEntries); } } private void AddGroupChain(string groupName, List result, HashSet visitedPath, HashSet addedEntries) { groupName = groupName.Trim(); if (!string.IsNullOrWhiteSpace(groupName) && !visitedPath.Contains(groupName) && _entriesByKey.TryGetValue(groupName, out PermissionEntry value)) { visitedPath.Add(groupName); AddGroupChains(value.groups, result, visitedPath, addedEntries); if (!addedEntries.Contains(groupName)) { addedEntries.Add(groupName); result.Add(value); } visitedPath.Remove(groupName); } } private static bool UpdateString(PermissionEntry entry, Func getter, Action setter, string value) { if (getter(entry) == value) { return false; } setter(entry, value); return true; } private static string EntryKey(PermissionEntry entry) { string text = PeerKey(entry.id, entry.character); if (text != "") { return text; } if (!string.IsNullOrWhiteSpace(entry.id)) { return PeerWildcardKey(entry.id); } return entry.name; } public static bool IsPeerChanged(HashSet changedKeys, string hostname, string characterId) { string text = PeerKey(hostname, characterId); if (text == "") { return false; } if (changedKeys.Contains(text)) { return true; } string item = PeerWildcardKey(hostname); return changedKeys.Contains(item); } private bool TryGetTrackedEntry(PermissionEntry? entry, out string key, out PermissionEntry tracked) { key = ""; tracked = null; if (entry == null) { return false; } key = EntryKey(entry); if (string.IsNullOrWhiteSpace(key)) { return false; } if (!_entriesByKey.TryGetValue(key, out tracked)) { return false; } return true; } private static Dictionary ToDictionary(List entries) { Dictionary dictionary = new Dictionary(); foreach (PermissionEntry entry in entries) { string text = EntryKey(entry); if (!string.IsNullOrWhiteSpace(text)) { dictionary[text] = entry; } } return dictionary; } private static bool IsNullOrEmpty(List? value) { if (value != null) { return value.Count == 0; } return true; } private static bool IsNullOrEmpty(Dictionary>? value) { if (value != null) { return value.Count == 0; } return true; } private static bool EqualStringList(List? a, List? b) { if (IsNullOrEmpty(a) && IsNullOrEmpty(b)) { return true; } if (a == null || b == null) { return false; } if (a.Count != b.Count) { return false; } for (int i = 0; i < a.Count; i++) { if (a[i] != b[i]) { return false; } } return true; } private static bool EqualFeatures(Dictionary>? a, Dictionary>? b) { if (IsNullOrEmpty(a) && IsNullOrEmpty(b)) { return true; } if (a == null || b == null) { return false; } if (a.Count != b.Count) { return false; } foreach (KeyValuePair> item in a) { if (!b.TryGetValue(item.Key, out List value)) { return false; } if (!EqualStringList(item.Value, value)) { return false; } } return true; } private static bool EqualEntry(PermissionEntry? a, PermissionEntry? b) { if (a == b) { return true; } if (a == null || b == null) { return false; } if (a.id != b.id) { return false; } if (a.name != b.name) { return false; } if (a.character != b.character) { return false; } if (!EqualStringList(a.groups, b.groups)) { return false; } if (!EqualFeatures(a.features, b.features)) { return false; } if (!EqualStringList(a.commands, b.commands)) { return false; } return true; } public static HashSet ChangedKeys(Dictionary oldData, Dictionary newData) { HashSet hashSet = new HashSet(); foreach (KeyValuePair oldDatum in oldData) { if (!newData.TryGetValue(oldDatum.Key, out PermissionEntry value) || !EqualEntry(oldDatum.Value, value)) { hashSet.Add(oldDatum.Key); } } foreach (string key in newData.Keys) { if (!oldData.ContainsKey(key)) { hashSet.Add(key); } } return hashSet; } public static HashSet ChangedKeys(PermissionData oldData, PermissionData newData) { return ChangedKeys(oldData._entriesByKey, newData._entriesByKey); } public static bool HasGroupChanges(HashSet changedKeys, Dictionary oldData, Dictionary newData) { foreach (string changedKey in changedKeys) { if (IsGroupEntry(SelectEntry(changedKey, oldData, newData))) { return true; } } return false; } public static bool HasGroupChanges(HashSet changedKeys, PermissionData oldData, PermissionData newData) { return HasGroupChanges(changedKeys, oldData._entriesByKey, newData._entriesByKey); } private static PermissionEntry? SelectEntry(string key, Dictionary oldData, Dictionary newData) { if (newData.TryGetValue(key, out PermissionEntry value)) { return value; } if (oldData.TryGetValue(key, out PermissionEntry value2)) { return value2; } return null; } private static bool IsGroupEntry(PermissionEntry? entry) { if (entry == null) { return false; } if (!string.IsNullOrWhiteSpace(entry.id)) { return false; } return !string.IsNullOrWhiteSpace(entry.name); } } public class PermissionEntry { [DefaultValue("")] public string id = ""; [DefaultValue("")] public string name = ""; [DefaultValue("")] public string character = ""; [DefaultValue("")] public string admin = ""; public List? groups; public Dictionary>? features; public List? commands; } public static class PermissionYaml { private static readonly HashSet ReservedKeys = new HashSet { "id", "name", "character", "admin", "groups", "commands" }; public static string SerializeEntries(List entries) { List> list = new List>(); foreach (PermissionEntry entry in entries) { list.Add(SerializeEntry(entry)); } return Yaml.Serializer().Serialize(list); } public static List DeserializeEntries(string value) { try { List> list = Yaml.Deserializer().Deserialize>>(value); if (list == null) { return new List(); } return list.Select(ParseEntry).ToList(); } catch (Exception ex) { ServerDevcommands.Log.LogError((object)("permissions: " + ex.Message)); return new List(); } } private static Dictionary SerializeEntry(PermissionEntry entry) { Dictionary dictionary = new Dictionary(); if (!string.IsNullOrWhiteSpace(entry.id)) { dictionary["id"] = entry.id; } if (!string.IsNullOrWhiteSpace(entry.name)) { dictionary["name"] = entry.name; } if (!string.IsNullOrWhiteSpace(entry.character)) { dictionary["character"] = entry.character; } string text = NormalizeAdmin(entry.admin); if (text != "") { dictionary["admin"] = text; } if (entry.groups != null && entry.groups.Count > 0) { dictionary["groups"] = entry.groups; } if (entry.features != null) { foreach (KeyValuePair> item in entry.features.OrderBy>, string>((KeyValuePair> kvp) => kvp.Key, StringComparer.OrdinalIgnoreCase)) { if (item.Value.Count != 0) { Dictionary dictionary2 = ToPermissionMap(item.Value); if (dictionary2.Count > 0) { dictionary[item.Key] = dictionary2; } } } } if (entry.commands != null && entry.commands.Count > 0) { Dictionary dictionary3 = ToPermissionMap(entry.commands); if (dictionary3.Count > 0) { dictionary["commands"] = dictionary3; } } return dictionary; } private static PermissionEntry ParseEntry(Dictionary raw) { PermissionEntry permissionEntry = new PermissionEntry { id = ReadScalar(raw, "id"), name = ReadScalar(raw, "name"), character = ReadScalar(raw, "character"), admin = ReadAdmin(raw, "admin"), groups = ReadStringList(raw, "groups"), commands = ReadPermissionList(raw, "commands") }; Dictionary> dictionary = new Dictionary>(); foreach (KeyValuePair item in raw) { string text = item.Key?.Trim() ?? ""; if (!(text == "") && !ReservedKeys.Contains(text.ToLowerInvariant())) { List list = ToPermissionList(item.Value); if (list.Count != 0) { dictionary[text.ToLowerInvariant()] = list; } } } if (dictionary.Count > 0) { permissionEntry.features = dictionary; } if (permissionEntry.commands != null && permissionEntry.commands.Count == 0) { permissionEntry.commands = null; } if (permissionEntry.groups != null && permissionEntry.groups.Count == 0) { permissionEntry.groups = null; } return permissionEntry; } private static string ReadScalar(Dictionary raw, string key) { if (!raw.TryGetValue(key, out object value)) { return ""; } return value?.ToString()?.Trim() ?? ""; } private static List? ReadPermissionList(Dictionary raw, string key) { if (!raw.TryGetValue(key, out object value)) { return null; } return ToPermissionList(value); } private static List? ReadStringList(Dictionary raw, string key) { if (!raw.TryGetValue(key, out object value)) { return null; } return ToStringList(value); } private static string ReadAdmin(Dictionary raw, string key) { if (!raw.TryGetValue(key, out object value)) { return ""; } return NormalizeAdmin(value?.ToString() ?? ""); } private static string NormalizeAdmin(string value) { return (value?.Trim().ToLowerInvariant() ?? "") switch { "yes" => "yes", "true" => "yes", "1" => "yes", "no" => "no", "false" => "no", "0" => "no", _ => "", }; } private static List ToStringList(object? value) { List list = new List(); if (value is IList list2) { { foreach (object item in list2) { string text = item?.ToString()?.Trim() ?? ""; if (text != "") { list.Add(text); } } return list; } } if (value is IList list3) { { foreach (string item2 in list3) { string text2 = item2?.Trim() ?? ""; if (text2 != "") { list.Add(text2); } } return list; } } string text3 = value?.ToString()?.Trim() ?? ""; if (text3 != "") { list.Add(text3); } return list; } private static List ToPermissionList(object? value) { Dictionary dictionary = new Dictionary(); if (value is IDictionary dictionary2) { foreach (KeyValuePair item in dictionary2) { string text = item.Key?.ToString()?.Trim() ?? ""; if (!(text == "")) { string value2 = item.Value?.ToString()?.Trim() ?? ""; dictionary[text] = value2; } } } else if (value is IDictionary dictionary3) { foreach (KeyValuePair item2 in dictionary3) { string text2 = item2.Key?.Trim() ?? ""; if (!(text2 == "")) { string value3 = item2.Value?.ToString()?.Trim() ?? ""; dictionary[text2] = value3; } } } List list = new List(); foreach (KeyValuePair item3 in dictionary) { string text3 = item3.Key.Trim(); if (!(text3 == "")) { string text4 = item3.Value.Trim(); if (text4 == "" || text4.Equals("yes", StringComparison.OrdinalIgnoreCase)) { list.Add(text3); } else { list.Add(text3 + ": " + text4); } } } return list; } private static Dictionary ToPermissionMap(List values) { Dictionary dictionary = new Dictionary(); foreach (string value in values) { KeyValuePair keyValuePair = Parse.Kvp(value, ':'); string text = keyValuePair.Key.Trim(); if (!(text == "")) { string text2 = keyValuePair.Value.Trim().ToLowerInvariant(); if (text2 == "") { text2 = "yes"; } dictionary[text] = text2; } } return dictionary; } } public static class PermissionHash { public const string Section = "serverdevcommands"; public static readonly int MapCoordinates = StringExtensionMethods.GetStableHashCode("mapcoordinates"); public static readonly int MiniMapCoordinates = StringExtensionMethods.GetStableHashCode("minimapcoordinates"); public static readonly int ShowPrivatePlayers = StringExtensionMethods.GetStableHashCode("showprivateplayers"); public static readonly int Ghost = StringExtensionMethods.GetStableHashCode("ghost"); public static readonly int God = StringExtensionMethods.GetStableHashCode("god"); public static readonly int Fly = StringExtensionMethods.GetStableHashCode("fly"); public static readonly int IgnoreWards = StringExtensionMethods.GetStableHashCode("ignorewards"); public static readonly int NoClipCamera = StringExtensionMethods.GetStableHashCode("noclipcamera"); public static readonly int NoCost = StringExtensionMethods.GetStableHashCode("nocost"); public static readonly int IgnoreNoMap = StringExtensionMethods.GetStableHashCode("ignorenomap"); public static readonly int DisableStartShout = StringExtensionMethods.GetStableHashCode("disablestartshout"); public static readonly int NoDrops = StringExtensionMethods.GetStableHashCode("nodrops"); public static readonly int HideShoutPings = StringExtensionMethods.GetStableHashCode("hideshoutpings"); } public class PermissionLoader { public static string RPC_Permissions = "DEV_Permissions"; public static PermissionData Data = new PermissionData(); public static string FileName = "permissions.yaml"; public static string FilePath = Path.Combine(Paths.ConfigPath, FileName); private static bool SkipReload = false; public static PermissionEntry? GetOrCreatePeerEntry(string hostname, string characterId, string playerName) { if (Helper.IsClient()) { return null; } string text = PermissionData.PeerKey(hostname, characterId); if (text == "") { return null; } Data.UpdatePeer(hostname, characterId, playerName); return Data.GetOrCreate(text); } public static void Save() { if (Helper.IsClient()) { return; } SkipReload = true; try { ToFile(); } finally { SkipReload = false; } } public static void SendPeerPermissions(string hostname, string characterId) { ZNet instance = ZNet.instance; if (!((Object)(object)instance == (Object)null) && instance.IsServer() && !(PermissionData.PeerKey(hostname, characterId) == "")) { ZNetPeer peerByHostName = instance.GetPeerByHostName(hostname); if (peerByHostName != null) { SendPermissions(peerByHostName.m_rpc, hostname, characterId); } } } public static void CreateFile() { if (!File.Exists(FilePath)) { Data.GetOrCreate("Everyone").commands = new List(1) { "permissions: no" }; ToFile(); } } public static void SendPermissions(ZRpc rpc, string hostname, string characterId) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown PermissionManager permissionManager = Data.Resolve(hostname, characterId); ZPackage val = new ZPackage(); permissionManager.Write(val); rpc.Invoke(RPC_Permissions, new object[1] { val }); } private static void SendChangedPermissions(HashSet changedKeys, bool updateAllPlayers) { //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_007f: Unknown result type (might be due to invalid IL or missing references) if (changedKeys.Count == 0) { return; } ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || !instance.IsServer()) { return; } foreach (ZNetPeer peer in instance.m_peers) { if (peer == null || peer.m_rpc == null || !peer.IsReady() || peer.m_characterID == ZDOID.None) { continue; } string hostName = peer.m_rpc.GetSocket().GetHostName(); ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO != null) { string characterId = zDO.GetLong(ZDOVars.s_playerID, 0L).ToString(); if (!(PermissionData.PeerKey(hostName, characterId) == "") && (updateAllPlayers || PermissionData.IsPeerChanged(changedKeys, hostName, characterId))) { SendPermissions(peer.m_rpc, hostName, characterId); } } } } public static void ToFile() { File.WriteAllText(FilePath, PermissionYaml.SerializeEntries(Data.Entries)); } public static void FromFile() { if (!Helper.IsClient() && !SkipReload) { PermissionData permissionData = new PermissionData(PermissionYaml.DeserializeEntries(File.ReadAllText(FilePath))); HashSet changedKeys = PermissionData.ChangedKeys(Data, permissionData); bool updateAllPlayers = PermissionData.HasGroupChanges(changedKeys, Data, permissionData); Data = permissionData; SendChangedPermissions(changedKeys, updateAllPlayers); ServerDevcommands.Log.LogInfo((object)$"Reloading {Data.Count} permission data."); } } public static void SetupWatcher() { CreateFile(); Yaml.SetupWatcher(FileName, FromFile); } public static void UpdatePeer(ZRpc rpc, string characterId) { if (characterId == "" || characterId == "0") { return; } ZNetPeer peer = ZNet.instance.GetPeer(rpc); if (peer != null) { string hostName = rpc.GetSocket().GetHostName(); if (Data.UpdatePeer(hostName, characterId, peer.m_playerName)) { Save(); } } } } [HarmonyPatch(typeof(ZNet), "RPC_Unban")] public class RPC_Unban { private static bool Prefix(ZNet __instance, ZRpc rpc, string user) { if (!user.StartsWith("admintest_", StringComparison.Ordinal)) { return true; } if (!__instance.IsServer()) { return true; } string value = Parse.Kvp(user, '_').Value; PermissionLoader.UpdatePeer(rpc, value); string hostName = rpc.GetSocket().GetHostName(); PermissionLoader.SendPermissions(rpc, hostName, value); return false; } } public class PermissionApi { private const string EveryoneGroup = "Everyone"; public static event Action? PermissionsUpdated; public static bool IsFeatureEnabled(string section, string feature, bool localConfigValue) { return IsFeatureEnabledByHash(section, StringExtensionMethods.GetStableHashCode(feature.ToLower()), localConfigValue); } public static bool IsFeatureEnabledByHash(string section, int featureHash, bool localConfigValue) { return PermissionManager.Instance.IsFeatureEnabledByHash(section, featureHash, localConfigValue); } public static bool IsCommandAllowed(string commandName) { string cmdName = Parse.Kvp(commandName, ' ').Key.ToLower(); ConsoleCommand value = Terminal.commands.FirstOrDefault((KeyValuePair c) => c.Key.Equals(cmdName, StringComparison.OrdinalIgnoreCase)).Value; if (value == null) { return false; } return PermissionManager.Instance.IsCommandAllowed(value, commandName, remote: false); } public static bool HasGroup(string playerId, long characterId, string group) { group = group?.Trim() ?? ""; if (group == "") { return false; } if (group.Equals("Everyone", StringComparison.OrdinalIgnoreCase)) { return true; } PermissionData data = PermissionLoader.Data; string characterId2 = characterId.ToString(); return data.HasGroup(playerId, characterId2, group); } public static void Subscribe(Action handler) { PermissionsUpdated += handler; } public static void Unsubscribe(Action handler) { PermissionsUpdated -= handler; } internal static void Notify() { PermissionApi.PermissionsUpdated?.Invoke(); } } public class PermissionManager { public enum FeaturePermission { Unknown = -1, Yes, No, Force } private static PermissionManager _instance; private Dictionary> _featurePermissions = new Dictionary>(); private bool _isAdmin; private static readonly int WildCardHash = StringExtensionMethods.GetStableHashCode("*"); private List _allowedCommands; private List _bannedCommands; public static PermissionManager Instance { get { if (_instance == null) { _instance = new PermissionManager(isAdmin: false); } return _instance; } } public bool CanCheat { get { if (!Terminal.m_cheat || !_isAdmin) { return Helper.IsDedicated(); } return true; } } public bool IsAdmin { get { return _isAdmin; } set { if (_isAdmin != value) { _isAdmin = value; PermissionApi.Notify(); } } } public PermissionManager(bool isAdmin) { _isAdmin = isAdmin; _allowedCommands = new List(); _bannedCommands = new List(); base..ctor(); } public void AddEntry(PermissionEntry entry) { if (entry == null) { return; } string text = entry.admin?.Trim().ToLowerInvariant() ?? ""; if (text == "yes") { _isAdmin = true; } else if (text == "no") { _isAdmin = false; } if (entry.features != null) { foreach (KeyValuePair> feature in entry.features) { string key = feature.Key.ToLower(); if (!_featurePermissions.ContainsKey(key)) { _featurePermissions[key] = new Dictionary(); } foreach (string item2 in feature.Value) { ParseFeature(item2, out string featureName, out FeaturePermission permission); if (!(featureName == "")) { int stableHashCode = StringExtensionMethods.GetStableHashCode(featureName.ToLower()); _featurePermissions[key][stableHashCode] = permission; } } } } if (entry.commands == null) { return; } foreach (string command in entry.commands) { ParseFeature(command, out string featureName2, out FeaturePermission permission2); if (!(featureName2 == "")) { string item = NormalizeCommand(featureName2); if (permission2 == FeaturePermission.No) { _bannedCommands.Add(item); } else { _allowedCommands.Add(item); } } } } public bool IsFeatureEnabledByHash(string section, int featureHash, bool localConfigValue) { return GetFeaturePermissionByHash(section, featureHash) switch { FeaturePermission.No => false, FeaturePermission.Force => true, FeaturePermission.Yes => localConfigValue, _ => (featureHash != WildCardHash) ? IsFeatureEnabledByHash(section, WildCardHash, localConfigValue) : (localConfigValue && CanCheat), }; } public FeaturePermission GetFeaturePermissionByHash(string section, int featureHash) { section = section.ToLower(); if (!_featurePermissions.TryGetValue(section, out Dictionary value)) { return FeaturePermission.Unknown; } if (!value.TryGetValue(featureHash, out var value2)) { return FeaturePermission.Unknown; } return value2; } private static string NormalizeCommand(string commandName) { return commandName?.Trim().ToLowerInvariant() ?? ""; } private static bool StartsWithAny(List commands, string cmd) { string cmd2 = cmd; return commands.Any((string check) => cmd2.StartsWith(check, StringComparison.Ordinal)); } public bool IsCommandAllowed(ConsoleCommand cmd, string commandName, bool remote) { string text = NormalizeCommand(commandName); if (text == "") { return false; } if (StartsWithAny(_bannedCommands, text)) { return false; } if (remote && !IsAdmin) { return false; } if (!remote && cmd.IsValid((Terminal)(object)Console.instance, false)) { return true; } if (StartsWithAny(_allowedCommands, text)) { return true; } return CanCheat; } public void Write(ZPackage pkg) { pkg.Write(_isAdmin); pkg.Write(_featurePermissions.Count); foreach (KeyValuePair> featurePermission in _featurePermissions) { pkg.Write(featurePermission.Key); pkg.Write(featurePermission.Value.Count); foreach (KeyValuePair item in featurePermission.Value) { pkg.Write(item.Key); pkg.Write((int)item.Value); } } pkg.Write(_allowedCommands.Count); foreach (string allowedCommand in _allowedCommands) { pkg.Write(allowedCommand); } pkg.Write(_bannedCommands.Count); foreach (string bannedCommand in _bannedCommands) { pkg.Write(bannedCommand); } } public void Read(ZPackage pkg) { ResetToDefaults(); _isAdmin = pkg.ReadBool(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { string key = pkg.ReadString(); int num2 = pkg.ReadInt(); if (!_featurePermissions.ContainsKey(key)) { _featurePermissions[key] = new Dictionary(); } for (int j = 0; j < num2; j++) { int key2 = pkg.ReadInt(); FeaturePermission value = (FeaturePermission)pkg.ReadInt(); _featurePermissions[key][key2] = value; } } int num3 = pkg.ReadInt(); _allowedCommands.Clear(); for (int k = 0; k < num3; k++) { _allowedCommands.Add(NormalizeCommand(pkg.ReadString())); } int num4 = pkg.ReadInt(); _bannedCommands.Clear(); for (int l = 0; l < num4; l++) { _bannedCommands.Add(NormalizeCommand(pkg.ReadString())); } HandleFeatureCommands(); PermissionApi.Notify(); } public void HandleFeatureCommands() { Dictionary dictionary = Terminal.commands.Select((KeyValuePair c) => c.Key.ToLower()).ToDictionary((string h) => StringExtensionMethods.GetStableHashCode(h), (string h) => h); foreach (KeyValuePair> featurePermission in _featurePermissions) { foreach (KeyValuePair item2 in featurePermission.Value) { if (dictionary.ContainsKey(item2.Key)) { string item = NormalizeCommand(dictionary[item2.Key]); if (item2.Value == FeaturePermission.No) { _allowedCommands.Remove(item); _bannedCommands.Add(item); } else { _allowedCommands.Add(item); _bannedCommands.Remove(item); } } } } } public void ResetToDefaults() { _isAdmin = false; _featurePermissions.Clear(); _allowedCommands.Clear(); _bannedCommands.Clear(); } private static void ParseFeature(string rawFeature, out string featureName, out FeaturePermission permission) { KeyValuePair keyValuePair = Parse.Kvp(rawFeature, ':'); featureName = keyValuePair.Key.Trim(); permission = ParsePermission(keyValuePair.Value); } private static FeaturePermission ParsePermission(string value) { return value.ToLowerInvariant() switch { "yes" => FeaturePermission.Yes, "no" => FeaturePermission.No, "force" => FeaturePermission.Force, _ => FeaturePermission.Yes, }; } } public static class Settings { public static ConfigEntry configMapCoordinates; public static ConfigEntry configMiniMapCoordinates; public static ConfigEntry configShowPrivatePlayers; public static ConfigEntry configAutoDevcommands; public static ConfigEntry configDebugModeFastTeleport; public static ConfigEntry configAutoDebugMode; public static ConfigEntry configKillDestroySpawners; public static ConfigEntry configAutoGodMode; public static ConfigEntry configDisableNoMap; public static ConfigEntry configAutoGhostMode; public static ConfigEntry configAutomaticItemPickUp; public static ConfigEntry configAutoNoCost; public static ConfigEntry configDisableEvents; public static ConfigEntry configDisableUnlockMessages; public static ConfigEntry configDisableDebugModeKeys; public static ConfigEntry configAutoFly; public static ConfigEntry configAutoTod; public static ConfigEntry configAutoEnv; public static ConfigEntry configDisableMessages; public static ConfigEntry configGodModeNoWeightLimit; public static ConfigEntry configGodModeNoStamina; public static ConfigEntry configGodModeNoEitr; public static ConfigEntry configGodModeNoUsage; public static ConfigEntry configGodModeAlwaysDodge; public static ConfigEntry configGodModeAlwaysParry; public static ConfigEntry configGodModeNoStagger; public static ConfigEntry configHideShoutPings; public static ConfigEntry configGodModeNoEdgeOfWorld; public static ConfigEntry configNoCostLimitRecipesToStation; public static ConfigEntry configNoCostRespectStationLevel; public static ConfigEntry configDisableStartShout; public static ConfigEntry configAccessPrivateChests; public static ConfigEntry configAccessWardedAreas; public static ConfigEntry configFlyNoClip; public static ConfigEntry configNoClipClearEnvironment; public static ConfigEntry configGodModeNoKnockback; public static ConfigEntry configGodModeNoMist; public static ConfigEntry configAliasing; public static ConfigEntry configSubstitution; public static ConfigEntry configWrapping; public static ConfigEntry configImprovedAutoComplete; public static ConfigEntry configMultiCommand; public static ConfigEntry configGhostInvisibility; public static ConfigEntry configGhostNoSpawns; public static ConfigEntry configServerChat; public static ConfigEntry configServerChatName; public static ConfigEntry configGhostIgnoreSleep; public static ConfigEntry configFlyUpKeys; public static List FlyUpRequiredKeys = new List(); public static List FlyUpBannedKeys = new List(); public static ConfigEntry configFlyDownKeys; public static List FlyDownRequiredKeys = new List(); public static List FlyDownBannedKeys = new List(); public static ConfigEntry configFreeFlyInvertCamera; public static ConfigEntry configNoDrops; public static ConfigEntry configNoClipView; public static ConfigEntry configCommandAliases; public static ConfigEntry configImprovedChat; public static ConfigEntry configMapTeleport; public static ConfigEntry configAutoExecBoot; public static ConfigEntry configAutoExec; public static ConfigEntry configAutoExecDevOn; public static ConfigEntry configAutoExecDevOff; public static ConfigEntry configCommandDescriptions; private static Dictionary Aliases = new Dictionary(); public static string[] AliasKeys = Array.Empty(); public static ConfigEntry configDisabledGlobalKeys; public static ConfigEntry configUndoLimit; public static ConfigEntry configPlayerListFormat; public static ConfigEntry configCommandLogFormat; public static ConfigEntry configFindFormat; public static ConfigEntry configMinimapFormat; public static ConfigEntry configChatOutput; public static List Options = new List(63) { "access_private_chests", "access_warded_areas", "map_coordinates", "private_players", "auto_devcommands", "auto_debugmode", "auto_fly", "god_no_stagger", "auto_nocost", "auto_ghost", "auto_god", "debug_console", "no_drops", "aliasing", "god_no_stamina", "substitution", "wrapping", "improved_autocomplete", "disable_events", "disable_warnings", "multiple_commands", "god_no_knockback", "ghost_invibisility", "auto_exec_dev_on", "auto_exec_dev_off", "auto_exec_boot", "auto_exec", "command_descriptions", "server_commands", "fly_no_clip", "disable_command", "minimap_coordinates", "disable_global_key", "disable_debug_mode_keys", "god_always_parry", "god_always_dodge", "fly_up_key", "fly_down_key", "disable_start_shout", "mouse_wheel_bind_key", "god_no_weight_limit", "automatic_item_pick_up", "disable_messages", "god_no_edge", "no_clip_clear_environment", "max_undo_steps", "best_command_match", "debug_fast_teleport", "disable_no_map", "hide_shout_pings", "disable_unlock_messages", "no_clip_view", "god_no_eitr", "god_no_item", "players_format", "command_log_format", "minimap_format", "chat_output", "free_fly_camera_invert", "server_chat", "server_chat_name", "limit_recipes_to_station", "respect_station_level" }; private static readonly HashSet Truthies = new HashSet { "1", "t", "true", "yes", "on" }; private static readonly HashSet Falsies = new HashSet { "0", "f", "false", "no", "off" }; public static bool MapCoordinates => IsEnabled(PermissionHash.MapCoordinates, configMapCoordinates.Value); public static bool MiniMapCoordinates => IsEnabled(PermissionHash.MiniMapCoordinates, configMiniMapCoordinates.Value); public static bool ShowPrivatePlayers => IsEnabled(PermissionHash.ShowPrivatePlayers, configShowPrivatePlayers.Value); public static bool AutoDevcommands => configAutoDevcommands.Value; public static bool DebugModeFastTeleport => configDebugModeFastTeleport.Value; public static bool AutoDebugMode => configAutoDebugMode.Value; public static bool KillDestroySpawners => configKillDestroySpawners.Value; public static bool AutoGodMode => configAutoGodMode.Value; public static bool DisableNoMap => IsEnabled(PermissionHash.IgnoreNoMap, configDisableNoMap.Value); public static bool AutoGhostMode => configAutoGhostMode.Value; public static bool AutomaticItemPickUp => configAutomaticItemPickUp.Value; public static bool AutoNoCost => configAutoNoCost.Value; public static bool DisableEvents => configDisableEvents.Value; public static bool DisableUnlockMessages => configDisableUnlockMessages.Value; public static bool DisableDebugModeKeys => configDisableDebugModeKeys.Value; public static bool AutoFly => configAutoFly.Value; public static string AutoTod => configAutoTod.Value; public static string AutoEnv => configAutoEnv.Value; public static bool DisableMessages => configDisableMessages.Value; public static bool GodModeNoWeightLimit => configGodModeNoWeightLimit.Value; public static bool GodModeNoStamina => configGodModeNoStamina.Value; public static bool GodModeNoEitr => configGodModeNoEitr.Value; public static bool GodModeNoUsage => configGodModeNoUsage.Value; public static bool GodModeAlwaysDodge => configGodModeAlwaysDodge.Value; public static bool GodModeAlwaysParry => configGodModeAlwaysParry.Value; public static bool GodModeNoStagger => configGodModeNoStagger.Value; public static bool HideShoutPings => IsEnabled(PermissionHash.HideShoutPings, configHideShoutPings.Value); public static bool NoCostLimitRecipesToStation => configNoCostLimitRecipesToStation.Value; public static bool NoCostRespectStationLevel => configNoCostRespectStationLevel.Value; public static bool GodModeNoEdgeOfWorld => configGodModeNoEdgeOfWorld.Value; public static bool DisableStartShout => configDisableStartShout.Value; public static bool AccessPrivateChests => IsEnabled(PermissionHash.IgnoreWards, configAccessPrivateChests.Value); public static bool AccessWardedAreas => IsEnabled(PermissionHash.IgnoreWards, configAccessWardedAreas.Value); public static bool FlyNoClip => configFlyNoClip.Value; public static bool NoClipClearEnvironment => configNoClipClearEnvironment.Value; public static bool GodModeNoKnockback => configGodModeNoKnockback.Value; public static bool GodModeNoMist => configGodModeNoMist.Value; public static bool Aliasing => configAliasing.Value; public static string Substitution => configSubstitution.Value; public static string Wrapping => configWrapping.Value; public static bool ImprovedAutoComplete => configImprovedAutoComplete.Value; public static bool MultiCommand => configMultiCommand.Value; public static bool GhostInvisibility => configGhostInvisibility.Value; public static bool GhostNoSpawns => configGhostNoSpawns.Value; public static bool IsServerChat => configServerChat.Value; public static string ServerChatName => configServerChatName.Value; public static bool GhostIgnoreSleep => configGhostIgnoreSleep.Value; public static bool FreeFlyCameraInvert => configFreeFlyInvertCamera.Value; public static bool NoDrops => IsEnabled(PermissionHash.NoDrops, configNoDrops.Value); public static bool NoClipView => IsEnabled(PermissionHash.NoClipCamera, configNoClipView.Value); public static bool ImprovedChat => configImprovedChat.Value; public static KeyboardShortcut MapTeleport => configMapTeleport.Value; public static string AutoExecBoot => configAutoExecBoot.Value; public static string AutoExec => configAutoExec.Value; public static string AutoExecDevOn => configAutoExecDevOn.Value; public static string AutoExecDevOff => configAutoExecDevOff.Value; public static bool CommandDescriptions => configCommandDescriptions.Value; public static int UndoLimit => Parse.Int(configUndoLimit.Value, 50); public static HashSet DisabledGlobalKeys => ParseList(configDisabledGlobalKeys.Value); public static string PlayerListFormat => configPlayerListFormat.Value; public static string CommandLogFormat => configCommandLogFormat.Value; public static string FindFormat => configFindFormat.Value; public static string MinimapFormat => configMinimapFormat.Value; public static bool ChatOutput => configChatOutput.Value; public static bool IsEnabled(int hash, bool localValue) { return PermissionManager.Instance.IsFeatureEnabledByHash("serverdevcommands", hash, localValue); } private static void ParseAliases(string value) { Aliases = (from str in value.Split(new char[1] { '¤' }) select str.Split(new char[1] { ' ' })).ToDictionary((string[] split) => split[0], (string[] split) => string.Join(" ", split.Skip(1))); Aliases = Aliases.Where((KeyValuePair kvp) => kvp.Key != "").ToDictionary((KeyValuePair kvp) => kvp.Key, (KeyValuePair kvp) => kvp.Value); List list = new List(); list.AddRange(Aliases.Keys.OrderBy((string key) => key)); AliasKeys = list.ToArray(); } public static string GetAliasValue(string key) { if (!Aliases.ContainsKey(key)) { return "_"; } return Aliases[key]; } public static void RegisterCommands() { foreach (KeyValuePair alias in Aliases) { AliasCommand.AddCommand(alias.Key, alias.Value); } } private static void SaveAliases() { string value = string.Join("¤", Aliases.Select((KeyValuePair kvp) => kvp.Key + " " + kvp.Value)); configCommandAliases.Value = value; } public static void AddAlias(string alias, string value) { if (value == "") { RemoveAlias(alias); return; } Aliases[alias] = value; SaveAliases(); } public static void AddAlias(Dictionary dict) { Aliases = dict; SaveAliases(); } public static void RemoveAlias(string alias) { if (Aliases.ContainsKey(alias)) { Aliases.Remove(alias); SaveAliases(); } } private static HashSet ParseList(string value) { HashSet hashSet = new HashSet(); foreach (string item in from s in Parse.Split(value) select s.ToLower()) { hashSet.Add(item); } return hashSet; } public static bool IsGlobalKeyDisabled(string key) { return DisabledGlobalKeys.Contains(key.ToLower()); } public static string Format(string format) { return format.Replace("{player_id", "{0").Replace("{character_name", "{1").Replace("{character_id", "{2") .Replace("{pos_x", "{3") .Replace("{pos_y", "{4") .Replace("{pos_z", "{5"); } public static void Init(ConfigFile config) { //IL_054a: Unknown result type (might be due to invalid IL or missing references) string text = "1. General"; configGhostInvisibility = config.Bind(text, "Invisible to other players with ghost mode", false, ""); configGhostNoSpawns = config.Bind(text, "Disables spawns with ghost mode", false, ""); configGhostIgnoreSleep = config.Bind(text, "Ignores sleep check with ghost mode", false, ""); configServerChat = config.Bind(text, "Server chat", false, "Adds the server as a fake player to allow server to send chat messages."); configServerChatName = config.Bind(text, "Server chat name", "Server", "Name of the server chat player."); configServerChatName.SettingChanged += delegate { ServerChat.RefreshPlayerInfo(); }; configNoDrops = config.Bind(text, "No creature drops", false, "Disables drops from creatures (if you control the zone), intended to fix high star enemies crashing the game."); configNoClipView = config.Bind(text, "No clip view", false, "Removes collision check for the camera."); configAutoDebugMode = config.Bind(text, "Automatic debug mode", false, "Automatically enables debug mode when enabling devcommands."); configKillDestroySpawners = config.Bind(text, "Kill destroys spawners", true, "Destroys spawners when using kill commands"); configAutoFly = config.Bind(text, "Automatic fly mode", false, "Automatically enables fly mode when enabling devcommands."); configAutoEnv = config.Bind(text, "Automatic environment", "", "Automatically enables environment when enabling devcommands (for example clear)."); configAutoTod = config.Bind(text, "Automatic time of day", "", "Automatically enables time of day when enabling devcommands (for example 0.33)."); configAutoNoCost = config.Bind(text, "Automatic no cost mode", false, "Automatically enables no cost mode when enabling devcommands."); configAutoGodMode = config.Bind(text, "Automatic god mode", false, "Automatically enables god mode when enabling devcommands."); configAutoGhostMode = config.Bind(text, "Automatic ghost mode", false, "Automatically enables ghost mode when enabling devcommands."); configAutomaticItemPickUp = config.Bind(text, "Automatic item pick up", true, "Sets the default value for the automatic item pick up feature."); configAutomaticItemPickUp.SettingChanged += delegate { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Player.m_enableAutoPickup = AutomaticItemPickUp; } }; configAutoDevcommands = config.Bind(text, "Automatic devcommands", true, "Automatically enables devcommands when joining servers."); configDebugModeFastTeleport = config.Bind(text, "Debug mode fast teleport", true, "All teleporting is much faster with the debug mode."); configDisableNoMap = config.Bind(text, "Disable no map", false, "Disables no map having effect."); configDisableNoMap.SettingChanged += delegate { Game.UpdateNoMap(); }; configGodModeNoStamina = config.Bind(text, "No stamina usage with god mode", true, ""); configGodModeNoEitr = config.Bind(text, "No eitr usage with god mode", true, ""); configGodModeNoUsage = config.Bind(text, "No item usage with god mode", false, ""); configGodModeNoWeightLimit = config.Bind(text, "No weight limit with god mode", false, ""); configGodModeAlwaysDodge = config.Bind(text, "Always dodge with god mode", false, ""); configGodModeAlwaysParry = config.Bind(text, "Always parry with god mode (when not blocking)", false, ""); configGodModeNoStagger = config.Bind(text, "No staggering with god mode", true, ""); configHideShoutPings = config.Bind(text, "Hide shout pings", false, "Forces shout pings at the world center."); configNoCostLimitRecipesToStation = config.Bind(text, "Limit recipes to station with nocost mode", true, "When nocost mode is active, only show recipes craftable at your current crafting station."); configNoCostRespectStationLevel = config.Bind(text, "Respect station level with nocost mode", false, "When limiting recipes to station, also require the station's upgrade level."); configGodModeNoEdgeOfWorld = config.Bind(text, "No edge of world pull with god mode", true, ""); configDisableStartShout = config.Bind(text, "Disable start shout", false, "Removes the initial shout message when joining the server."); configAccessPrivateChests = config.Bind(text, "Access private chests", true, "Allows opening private chests."); configAccessWardedAreas = config.Bind(text, "Access warded areas", true, "Allows accessing warded areas."); configFlyNoClip = config.Bind(text, "No clip with fly mode", false, ""); configFreeFlyInvertCamera = config.Bind(text, "Free fly uses camera invert", true, "Makes free fly to use camera invert settings."); configNoClipClearEnvironment = config.Bind(text, "No clip clears forced environments", true, "Removes any forced environments when the noclip is enabled. This disables any dark dungeon environments and prevents them from staying on when exiting the dungeon."); configGodModeNoKnockback = config.Bind(text, "No knockback with god mode", true, ""); configGodModeNoMist = config.Bind(text, "No Mistlands mist with god mode", false, ""); configMapCoordinates = config.Bind(text, "Show map coordinates", true, "The map shows coordinates on hover."); configMiniMapCoordinates = config.Bind(text, "Show minimap coordinates", false, "The minimap shows player coordinates."); configShowPrivatePlayers = config.Bind(text, "Show private players", false, "The map shows private players."); configDisableEvents = config.Bind(text, "Disable random events", false, "Disables random events (server side setting)."); configDisableUnlockMessages = config.Bind(text, "Disable unlock messages", false, "Disables messages about new pieces and items."); configDisableDebugModeKeys = config.Bind(text, "Disable debug mode keys", false, "Removes debug mode key bindings for killall, removedrops, fly and no cost."); configDisabledGlobalKeys = config.Bind(text, "Disabled global keys", "", "Global keys separated by , that won't be set (server side setting)."); configDisabledGlobalKeys.SettingChanged += delegate { DisableGlobalKeys.RemoveDisabled(); }; configUndoLimit = config.Bind(text, "Max undo steps", "50", "How many undo actions are stored."); configUndoLimit.SettingChanged += delegate { UndoManager.MaxSteps = UndoLimit; }; UndoManager.MaxSteps = UndoLimit; text = "2. Console"; configDisableMessages = config.Bind(text, "Disable messages", false, "Prevents messages from commands."); configMapTeleport = config.Bind(text, "Map teleport bind key", new KeyboardShortcut((KeyCode)325, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key bind for map teleport."); configAutoExecBoot = config.Bind(text, "Auto exec boot", "", "Executes the given command when starting the game."); configAutoExecDevOn = config.Bind(text, "Auto exec dev on", "", "Executes the given command when enabling devcommands."); configAutoExecDevOff = config.Bind(text, "Auto exec dev off", "", "Executes the given command when disabling devcommands."); configAutoExec = config.Bind(text, "Auto exec", "", "Executes the given command when joining a server (before admin is checked)."); configCommandDescriptions = config.Bind(text, "Command descriptions", true, "Shows command descriptions as autocomplete."); configAliasing = config.Bind(text, "Alias system", true, "Enables the command aliasing system (allows creating new commands)."); configImprovedAutoComplete = config.Bind(text, "Improved autocomplete", true, "Enables parameter info or options for every parameter."); configCommandAliases = config.Bind(text, "Command aliases", "", "Internal data for aliases."); configMultiCommand = config.Bind(text, "Multiple commands per line", true, "Enables multiple commands when separated with ;."); configImprovedChat = config.Bind(text, "Improved chat", true, "Enables alias and multicommands system for chat."); configSubstitution = config.Bind(text, "Substitution", "$$", "Enables the command parameter substitution system (substitution gets replaced with the next free parameter)."); configWrapping = config.Bind(text, "Wrapping", "\"", "Allows using space bars in command parameters."); configCommandAliases.SettingChanged += delegate { ParseAliases(configCommandAliases.Value); }; configFlyUpKeys = config.Bind(text, "Key for fly up", "Space", "Key codes separated by ,"); configFlyUpKeys.SettingChanged += delegate { ParseFlyUp(); }; ParseFlyUp(); configFlyDownKeys = config.Bind(text, "Key for fly down", "LeftControl", "Key codes separated by ,"); configFlyDownKeys.SettingChanged += delegate { ParseFlyDown(); }; ParseFlyDown(); configChatOutput = config.Bind(text, "Chat output", false, "Sends messages to the chat window from bound keys."); text = "3. Formatting"; ParseAliases(configCommandAliases.Value); configPlayerListFormat = config.Bind(text, "Player list format", "{player_id}/{character_name}/{character_id} ({pos_x:F0}, {pos_z:F0}, {pos_y:F0})", "Format of playerlist command."); configCommandLogFormat = config.Bind(text, "Command log format", "{player_id}/{character_name} ({pos_x:F0}, {pos_z:F0}, {pos_y:F0}): {command}", "Format for the command log."); configFindFormat = config.Bind(text, "Find format", "{pos_x:F0}, {pos_z:F0}, {pos_y:F0}, distance {distance:F0} ({name})", "Format for the find command. Server side setting."); configMinimapFormat = config.Bind(text, "Minimap format", "x: {pos_x:F0}, z: {pos_z:F0}, y: {pos_y:F0}", "Format for minimap coordinates."); } private static void ParseFlyUp() { //IL_0069: 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) FlyUpRequiredKeys.Clear(); FlyUpBannedKeys.Clear(); string[] array = Parse.Split(configFlyUpKeys.Value); foreach (string text in array) { KeyCode result2; if (text.StartsWith("-")) { if (Enum.TryParse(text.Substring(1), ignoreCase: true, out KeyCode result)) { FlyUpBannedKeys.Add(result); } } else if (Enum.TryParse(text, ignoreCase: true, out result2)) { FlyUpRequiredKeys.Add(result2); } } } private static void ParseFlyDown() { //IL_0069: 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) FlyDownRequiredKeys.Clear(); FlyDownBannedKeys.Clear(); string[] array = Parse.Split(configFlyDownKeys.Value); foreach (string text in array) { KeyCode result2; if (text.StartsWith("-")) { if (Enum.TryParse(text.Substring(1), ignoreCase: true, out KeyCode result)) { FlyDownBannedKeys.Add(result); } } else if (Enum.TryParse(text, ignoreCase: true, out result2)) { FlyDownRequiredKeys.Add(result2); } } } private static string State(bool value) { if (!value) { return "disabled"; } return "enabled"; } private static string Flag(bool value) { if (!value) { return "Added"; } return "Removed"; } private static bool IsTruthy(string value) { return Truthies.Contains(value); } private static bool IsFalsy(string value) { return Falsies.Contains(value); } private static void Toggle(Terminal context, ConfigEntry setting, string name, string value, bool reverse = false) { if (value == "") { setting.Value = !setting.Value; } else if (IsTruthy(value)) { setting.Value = true; } else if (IsFalsy(value)) { setting.Value = false; } Helper.AddMessage(context, name + " " + State(reverse ? (!setting.Value) : setting.Value) + "."); } private static void ToggleFlag(Terminal context, ConfigEntry setting, string name, string value) { if (value == "") { Helper.AddMessage(context, name + ": " + setting.Value + "."); return; } HashSet hashSet = ParseList(setting.Value); foreach (string item in ParseList(value)) { bool flag = hashSet.Contains(item); if (flag) { hashSet.Remove(item); } else { hashSet.Add(item); } setting.Value = string.Join(",", hashSet); Helper.AddMessage(context, name + ": " + Flag(flag) + " " + item + "."); } } private static void SetValue(Terminal context, ConfigEntry setting, string name, string value) { if (value == "") { Helper.AddMessage(context, name + ": " + setting.Value + "."); return; } if (value.Contains("/")) { string[] array = value.Split(new char[1] { '/' }); value = array[0]; for (int i = 0; i < array.Length - 1; i++) { if (string.Equals(setting.Value?.ToString(), array[i], StringComparison.OrdinalIgnoreCase)) { value = array[i + 1]; break; } } } setting.Value = value; Helper.AddMessage(context, name + " set to " + value + "."); } private static void SetKey(Terminal context, ConfigEntry setting, string name, string value) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) if (value == "") { Helper.AddMessage(context, $"{name}: {setting.Value}."); return; } if (!Enum.TryParse(value, ignoreCase: true, out KeyCode result)) { throw new InvalidOperationException("'" + value + "' is not a valid UnityEngine.KeyCode."); } setting.Value = new KeyboardShortcut(result, Array.Empty()); Helper.AddMessage(context, name + " set to " + value + "."); } public static void UpdateValue(Terminal context, string key, string value) { if (key == "no_clip_view") { Toggle(context, configNoClipView, key, value); } if (key == "fly_up_key") { SetValue(context, configFlyUpKeys, key, value); } if (key == "fly_down_key") { SetValue(context, configFlyDownKeys, key, value); } if (key == "max_undo_steps") { SetValue(context, configUndoLimit, key, value); } if (key == "auto_exec_dev_on") { SetValue(context, configAutoExecDevOn, key, value); } if (key == "auto_exec_dev_off") { SetValue(context, configAutoExecDevOff, key, value); } if (key == "auto_exec_boot") { SetValue(context, configAutoExecBoot, key, value); } if (key == "auto_exec") { SetValue(context, configAutoExec, key, value); } if (key == "substitution") { SetValue(context, configSubstitution, key, value); } if (key == "wrapping") { SetValue(context, configWrapping, key, value); } if (key == "auto_tod") { SetValue(context, configAutoTod, key, value); } if (key == "auto_env") { SetValue(context, configAutoEnv, key, value); } if (key == "debug_fast_teleport") { Toggle(context, configDebugModeFastTeleport, key, value); } if (key == "improved_chat") { Toggle(context, configImprovedChat, key, value); } if (key == "access_private_chests") { Toggle(context, configAccessPrivateChests, key, value); } if (key == "access_warded_areas") { Toggle(context, configAccessWardedAreas, key, value); } if (key == "no_clip_clear_environment") { Toggle(context, configNoClipClearEnvironment, key, value); } if (key == "disable_messages") { Toggle(context, configDisableMessages, "Command messages", value, reverse: true); } if (key == "automatic_item_pick_up") { Toggle(context, configAutomaticItemPickUp, "Automatic item pick up", value); } if (key == "command_descriptions") { Toggle(context, configCommandDescriptions, "Command descriptions", value); } if (key == "map_coordinates") { Toggle(context, configMapCoordinates, "Map coordinates", value); } if (key == "minimap_coordinates") { Toggle(context, configMiniMapCoordinates, "Minimap coordinates", value); } if (key == "private_players") { Toggle(context, configShowPrivatePlayers, "Private players", value); } if (key == "auto_devcommands") { Toggle(context, configAutoDevcommands, "Automatic devcommands", value); } if (key == "auto_debugmode") { Toggle(context, configAutoDebugMode, "Automatic debug mode", value); } if (key == "auto_fly") { Toggle(context, configAutoFly, "Automatic fly", value); } if (key == "auto_nocost") { Toggle(context, configAutoNoCost, "Automatic no cost", value); } if (key == "auto_god") { Toggle(context, configAutoGodMode, "Automatic god mode", value); } if (key == "auto_ghost") { Toggle(context, configAutoGhostMode, "Automatic ghost mode", value); } if (key == "no_drops") { Toggle(context, configNoDrops, "Creature drops", value, reverse: true); } if (key == "aliasing") { Toggle(context, configAliasing, "Command aliasing", value); } if (key == "improved_autocomplete") { Toggle(context, configImprovedAutoComplete, "Improved autocomplete", value); } if (key == "disable_unlock_messages") { Toggle(context, configDisableUnlockMessages, "Unlock messages", value, reverse: true); } if (key == "disable_events") { Toggle(context, configDisableEvents, "Random events", value, reverse: true); } if (key == "multiple_commands") { Toggle(context, configMultiCommand, "Multiple commands per line", value); } if (key == "god_no_stamina") { Toggle(context, configGodModeNoStamina, "Stamina usage with god mode", value, reverse: true); } if (key == "god_no_eitr") { Toggle(context, configGodModeNoEitr, "Eitr usage with god mode", value, reverse: true); } if (key == "god_no_item") { Toggle(context, configGodModeNoUsage, "Item usage with god mode", value, reverse: true); } if (key == "god_no_weight_limit") { Toggle(context, configGodModeNoWeightLimit, "Weight limit with god mode", value, reverse: true); } if (key == "god_no_stagger") { Toggle(context, configGodModeNoStagger, "Staggering with god mode", value, reverse: true); } if (key == "hide_shout_pings") { Toggle(context, configHideShoutPings, "Shout pings", value, reverse: true); } if (key == "god_no_edge") { Toggle(context, configGodModeNoEdgeOfWorld, "Edge of world pull with god mode", value, reverse: true); } if (key == "god_no_knockback") { Toggle(context, configGodModeNoKnockback, "Knockback with god mode", value, reverse: true); } if (key == "god_no_mist") { Toggle(context, configGodModeNoMist, "Mist with god mode", value, reverse: true); } if (key == "fly_no_clip") { Toggle(context, configFlyNoClip, "No clip with fly mode", value); } if (key == "ghost_invibisility") { Toggle(context, configGhostInvisibility, "Invisibility with ghost mode", value); } if (key == "ghost_no_spawns") { Toggle(context, configGhostNoSpawns, "Spawns with ghost", value, reverse: true); } if (key == "ghost_ignore_sleep") { Toggle(context, configGhostIgnoreSleep, "Sleeping checked with ghost", value, reverse: true); } if (key == "disable_global_key") { ToggleFlag(context, configDisabledGlobalKeys, "Disabled global keys", value); } if (key == "disable_debug_mode_keys") { Toggle(context, configDisableDebugModeKeys, "Debug mode key bindings", value, reverse: true); } if (key == "god_always_parry") { Toggle(context, configGodModeAlwaysParry, "Always parry with god mode", value); } if (key == "god_always_dodge") { Toggle(context, configGodModeAlwaysDodge, "Always dodge with god mode", value); } if (key == "disable_start_shout") { Toggle(context, configDisableStartShout, "Start shout", value, reverse: true); } if (key == "disable_no_map") { Toggle(context, configDisableNoMap, "Disable no map", value); } if (key == "chat_output") { Toggle(context, configChatOutput, "Chat output", value); } if (key == "playerlist_format") { SetValue(context, configPlayerListFormat, key, value); } if (key == "command_log_format") { SetValue(context, configCommandLogFormat, key, value); } if (key == "find_format") { SetValue(context, configFindFormat, key, value); } if (key == "minimap_format") { SetValue(context, configMinimapFormat, key, value); } if (key == "kill_destroys_spawners") { Toggle(context, configKillDestroySpawners, "Kill commands destroy spawners", value); } if (key == "free_fly_camera_invert") { Toggle(context, configFreeFlyInvertCamera, "Free fly camera invert", value); } if (key == "server_chat") { Toggle(context, configServerChat, "Server chat", value); } if (key == "server_chat_name") { SetValue(context, configServerChatName, "Server chat name", value); } if (key == "limit_recipes_to_station") { Toggle(context, configNoCostLimitRecipesToStation, "Limit recipes to station with nocost mode", value); } if (key == "respect_station_level") { Toggle(context, configNoCostRespectStationLevel, "Respect station level with nocost mode", value); } } } public static class TerminalUtils { public static bool IsExecuting; public static string GetLastWord(Terminal obj) { return ((TMP_InputField)obj.m_input).text.Split(new char[1] { ' ' }).Last().Split(new char[1] { '=' }) .Last() .Split(new char[1] { ',' }) .Last(); } public static IEnumerable GetPositionalParameters(string[] parameters) { return parameters.Where((string par) => !par.Contains("=") && !par.StartsWith("<", StringComparison.OrdinalIgnoreCase)); } public static void GetSubstitutions(string[] parameters, out IEnumerable mainPars, out IEnumerable substitutions) { int num = -1; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].Contains(Settings.Substitution)) { num = i + 1; } } if (num == -1) { mainPars = parameters; substitutions = Array.Empty(); } else { mainPars = parameters.Take(num); substitutions = parameters.Skip(num); } } public static int GetAmountOfSubstitutions(string[] parameters) { int num = -1; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].Contains(Settings.Substitution)) { num = i + 1; } } if (num == -1) { return 0; } return (from par in parameters.Skip(num) where !par.Contains("=") select par).Count(); } private static string ReplaceValues(string text, string search, Queue replace) { int num = text.IndexOf(search); while (num >= 0 && replace.Count > 0) { string text2 = replace.Dequeue(); text = text.Substring(0, num) + text2 + text.Substring(num + search.Length); num = text.IndexOf(search); } return text; } public static bool CanSubstitute(string input) { return input.Contains(Settings.Substitution); } public static string Substitute(string alias, string command) { if (Settings.Substitution == "") { return alias + " " + command; } if (alias.StartsWith("alias")) { return alias + " " + command; } if (!CanSubstitute(alias)) { return alias + " " + command; } Queue queue = new Queue(command.Split(new char[1] { ' ' })); alias = ReplaceValues(alias, Settings.Substitution, queue); alias = alias.Replace("," + Settings.Substitution, ""); if (CanSubstitute(alias)) { alias = string.Join(" ", from s in alias.Split(new char[1] { ' ' }) where !s.Contains(Settings.Substitution) select s); } return alias + " " + string.Join(" ", queue); } public static bool SkipProcessing(string command) { string command2 = command; return AutoComplete.Offsets.Any>((KeyValuePair kvp) => command2.StartsWith(kvp.Key + " ", StringComparison.OrdinalIgnoreCase)); } } [HarmonyPatch(typeof(Terminal), "TryRunCommand")] public class TryRunCommand { private static bool Prefix(Terminal __instance, ref string text) { if (!Settings.ImprovedChat && (Object)(object)__instance == (Object)(object)Chat.instance) { return true; } if (TerminalUtils.SkipProcessing(text)) { return true; } string[] array = MultiCommands.Split(text).Select(Aliasing.Plain).SelectMany(MultiCommands.Split) .ToArray(); if (array.Length > 1) { MultiCommands.Handle(__instance, array); return false; } text = array[0]; text = CheckLogic(text); RunCommand(__instance, text); return false; } private static string CheckLogic(string text) { IEnumerable values = text.Split(new char[1] { ' ' }).Select(delegate(string arg) { string[] array = arg.Split(new char[1] { '=' }); if (array.Length == 1) { return Parse.Logic(arg); } return (array.Length > 2) ? arg : (array[0] + "=" + Parse.Logic(array[1])); }); return string.Join(" ", values); } private static void RunCommand(Terminal t, string text) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown string text2 = text.Split(new char[1] { ' ' })[0]; if (!Terminal.commands.TryGetValue(text2, out var value)) { t.AddString("Unknown command '" + text2 + "'. Type 'help' to see a list of valid commands"); } else if (!PermissionManager.Instance.IsCommandAllowed(value, text, remote: false)) { t.AddString("Unauthorized to use command '" + text2 + "'."); } else if (value.RemoteCommand && Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { t.AddString("Sending command: " + text); ZNet.instance.RemoteCommand(text); } else { value.RunAction(new ConsoleEventArgs(text, t)); } } } [HarmonyPatch(typeof(ConsoleCommand), "RunAction")] public class RunAction { private static void Prefix(ConsoleEventArgs args) { TerminalUtils.IsExecuting = true; string command = args.Args[0]; for (int i = 1; i < args.Args.Length; i++) { List options = AutoComplete.GetOptions(command, i - 1); if (options == null) { continue; } foreach (string item in options) { if (item != null && item.Equals(args.Args[i], StringComparison.OrdinalIgnoreCase)) { args.Args[i] = item; break; } } } } private static void Postfix() { TerminalUtils.IsExecuting = false; } } [HarmonyPatch(typeof(Terminal), "Awake")] public class UnlockCharacterLimit { private static void Postfix(Terminal __instance) { if (Object.op_Implicit((Object)(object)__instance.m_input)) { ((TMP_InputField)__instance.m_input).characterLimit = 0; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public class Wrapping { private static void Postfix(ConsoleEventArgs __instance) { if (string.IsNullOrWhiteSpace(Settings.Wrapping) || !__instance.FullLine.Contains(Settings.Wrapping)) { return; } List list = new List(); string text = ""; string[] args = __instance.Args; foreach (string text2 in args) { if (text == "") { if (text2.Contains(Settings.Wrapping)) { if (text2.Count((char c) => c == Settings.Wrapping[0]) % 2 == 0 && text2.EndsWith(Settings.Wrapping, StringComparison.OrdinalIgnoreCase)) { int startIndex = text2.IndexOf(Settings.Wrapping); int startIndex2 = text2.LastIndexOf(Settings.Wrapping); string item = text2.Remove(startIndex2, 1).Remove(startIndex, 1); list.Add(item); } else { text = text2; } } else { list.Add(text2); } } else { text = text + " " + text2; if (text2.EndsWith(Settings.Wrapping, StringComparison.OrdinalIgnoreCase)) { int startIndex3 = text.IndexOf(Settings.Wrapping); int startIndex4 = text.LastIndexOf(Settings.Wrapping); string item2 = text.Remove(startIndex4, 1).Remove(startIndex3, 1); list.Add(item2); text = ""; } } } __instance.Args = list.ToArray(); } } [HarmonyPatch(typeof(TMP_InputField), "KeyPressed")] public class TerminalFix { private static int caretPos; private static int textLen; private static int anchorPos; private static void Prefix(TMP_InputField __instance) { textLen = __instance.text.Length; caretPos = __instance.caretPosition; anchorPos = __instance.selectionAnchorPosition; } private static void Postfix(TMP_InputField __instance, Event evt) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 if (caretPos != anchorPos) { if (__instance.caretPosition == 0 && ((int)evt.keyCode == 127 || (int)evt.keyCode == 8) && textLen != __instance.text.Length) { __instance.caretPosition = Math.Min(Math.Min(caretPos, anchorPos), textLen); } if (__instance.caretPosition == 1 && evt.character != 0) { __instance.caretPosition = Math.Min(Math.Min(caretPos, anchorPos), textLen) + 1; } } } } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } namespace YamlDotNet { internal sealed class CultureInfoAdapter : CultureInfo { private readonly IFormatProvider provider; public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) : base(baseCulture.Name) { this.provider = provider; } public override object? GetFormat(Type formatType) { return provider.GetFormat(formatType); } } internal static class Polyfills { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool Contains(this string source, char c) { return source.IndexOf(c) != -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool EndsWith(this string source, char c) { if (source.Length > 0) { return source[source.Length - 1] == c; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool StartsWith(this string source, char c) { if (source.Length > 0) { return source[0] == c; } return false; } } internal static class PropertyInfoExtensions { public static object? ReadValue(this PropertyInfo property, object target) { return property.GetValue(target, null); } } internal static class ReflectionExtensions { private static readonly Func IsInstance = (PropertyInfo property) => !(property.GetMethod ?? property.SetMethod).IsStatic; private static readonly Func IsInstancePublic = (PropertyInfo property) => IsInstance(property) && (property.GetMethod ?? property.SetMethod).IsPublic; private static readonly ConcurrentDictionary TypesHaveNullContext = new ConcurrentDictionary(); public static Type? BaseType(this Type type) { return type.GetTypeInfo().BaseType; } public static bool IsValueType(this Type type) { return type.GetTypeInfo().IsValueType; } public static bool IsGenericType(this Type type) { return type.GetTypeInfo().IsGenericType; } public static bool IsGenericTypeDefinition(this Type type) { return type.GetTypeInfo().IsGenericTypeDefinition; } public static Type? GetImplementationOfOpenGenericInterface(this Type type, Type openGenericType) { if (!openGenericType.IsGenericType || !openGenericType.IsInterface) { throw new ArgumentException("The type must be a generic type definition and an interface", "openGenericType"); } if (IsGenericDefinitionOfType(type, openGenericType)) { return type; } return type.FindInterfaces((Type t, object context) => IsGenericDefinitionOfType(t, context), openGenericType).FirstOrDefault(); static bool IsGenericDefinitionOfType(Type t, object? context) { if (t.IsGenericType) { return t.GetGenericTypeDefinition() == (Type)context; } return false; } } public static bool IsInterface(this Type type) { return type.GetTypeInfo().IsInterface; } public static bool IsEnum(this Type type) { return type.GetTypeInfo().IsEnum; } public static bool IsRequired(this MemberInfo member) { return member.GetCustomAttributes(inherit: true).Any((object x) => x.GetType().FullName == "System.Runtime.CompilerServices.RequiredMemberAttribute"); } public static bool HasDefaultConstructor(this Type type, bool allowPrivateConstructors) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public; if (allowPrivateConstructors) { bindingFlags |= BindingFlags.NonPublic; } if (!type.IsValueType) { return type.GetConstructor(bindingFlags, null, Type.EmptyTypes, null) != null; } return true; } public static bool IsAssignableFrom(this Type type, Type source) { return type.IsAssignableFrom(source.GetTypeInfo()); } public static bool IsAssignableFrom(this Type type, TypeInfo source) { return type.GetTypeInfo().IsAssignableFrom(source); } public static TypeCode GetTypeCode(this Type type) { if (type.IsEnum()) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { return TypeCode.Boolean; } if (type == typeof(char)) { return TypeCode.Char; } if (type == typeof(sbyte)) { return TypeCode.SByte; } if (type == typeof(byte)) { return TypeCode.Byte; } if (type == typeof(short)) { return TypeCode.Int16; } if (type == typeof(ushort)) { return TypeCode.UInt16; } if (type == typeof(int)) { return TypeCode.Int32; } if (type == typeof(uint)) { return TypeCode.UInt32; } if (type == typeof(long)) { return TypeCode.Int64; } if (type == typeof(ulong)) { return TypeCode.UInt64; } if (type == typeof(float)) { return TypeCode.Single; } if (type == typeof(double)) { return TypeCode.Double; } if (type == typeof(decimal)) { return TypeCode.Decimal; } if (type == typeof(DateTime)) { return TypeCode.DateTime; } if (type == typeof(string)) { return TypeCode.String; } return TypeCode.Object; } public static bool IsDbNull(this object value) { return value?.GetType()?.FullName == "System.DBNull"; } public static Type[] GetGenericArguments(this Type type) { return type.GetTypeInfo().GenericTypeArguments; } public static PropertyInfo? GetPublicProperty(this Type type, string name) { string name2 = name; return type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public).FirstOrDefault((PropertyInfo p) => p.Name == name2); } public static FieldInfo? GetPublicStaticField(this Type type, string name) { return type.GetRuntimeField(name); } public static IEnumerable GetProperties(this Type type, bool includeNonPublic) { Func predicate = (includeNonPublic ? IsInstance : IsInstancePublic); if (!type.IsInterface()) { return type.GetRuntimeProperties().Where(predicate); } return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetRuntimeProperties().Where(predicate)); } public static IEnumerable GetPublicProperties(this Type type) { return type.GetProperties(includeNonPublic: false); } public static IEnumerable GetPublicFields(this Type type) { return from f in type.GetRuntimeFields() where !f.IsStatic && f.IsPublic select f; } public static IEnumerable GetPublicStaticMethods(this Type type) { return from m in type.GetRuntimeMethods() where m.IsPublic && m.IsStatic select m; } public static MethodInfo GetPrivateStaticMethod(this Type type, string name) { string name2 = name; return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => !m.IsPublic && m.IsStatic && m.Name.Equals(name2)) ?? throw new MissingMethodException("Expected to find a method named '" + name2 + "' in '" + type.FullName + "'."); } public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) { string name2 = name; Type[] parameterTypes2 = parameterTypes; return type.GetRuntimeMethods().FirstOrDefault(delegate(MethodInfo m) { if (m.IsPublic && m.IsStatic && m.Name.Equals(name2)) { System.Reflection.ParameterInfo[] parameters = m.GetParameters(); if (parameters.Length == parameterTypes2.Length) { return parameters.Zip(parameterTypes2, (System.Reflection.ParameterInfo pi, Type pt) => pi.ParameterType == pt).All((bool r) => r); } return false; } return false; }); } public static MethodInfo? GetPublicInstanceMethod(this Type type, string name) { string name2 = name; return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => m.IsPublic && !m.IsStatic && m.Name.Equals(name2)); } public static MethodInfo? GetGetMethod(this PropertyInfo property, bool nonPublic) { MethodInfo methodInfo = property.GetMethod; if (!nonPublic && !methodInfo.IsPublic) { methodInfo = null; } return methodInfo; } public static MethodInfo? GetSetMethod(this PropertyInfo property) { return property.SetMethod; } public static IEnumerable GetInterfaces(this Type type) { return type.GetTypeInfo().ImplementedInterfaces; } public static bool IsInstanceOf(this Type type, object o) { if (!(o.GetType() == type)) { return o.GetType().GetTypeInfo().IsSubclassOf(type); } return true; } public static Attribute[] GetAllCustomAttributes(this PropertyInfo member) { return Attribute.GetCustomAttributes(member, typeof(TAttribute), inherit: true); } public static bool AcceptsNull(this MemberInfo member) { bool result = true; if (TypesHaveNullContext.GetOrAdd(member.DeclaringType, delegate(Type t) { object[] customAttributes2 = t.GetCustomAttributes(inherit: true); return customAttributes2.Any((object x) => x.GetType().FullName == "System.Runtime.CompilerServices.NullableContextAttribute"); })) { object[] customAttributes = member.GetCustomAttributes(inherit: true); result = customAttributes.Any((object x) => x.GetType().FullName == "System.Runtime.CompilerServices.NullableAttribute"); } return result; } } internal static class StandardRegexOptions { public const RegexOptions Compiled = RegexOptions.Compiled; } } namespace YamlDotNet.Serialization { internal abstract class BuilderSkeleton where TBuilder : BuilderSkeleton { internal INamingConvention namingConvention = NullNamingConvention.Instance; internal INamingConvention enumNamingConvention = NullNamingConvention.Instance; internal ITypeResolver typeResolver; internal readonly YamlAttributeOverrides overrides; internal readonly LazyComponentRegistrationList typeConverterFactories; internal readonly LazyComponentRegistrationList typeInspectorFactories; internal bool ignoreFields; internal bool includeNonPublicProperties; internal Settings settings; internal YamlFormatter yamlFormatter = YamlFormatter.Default; protected abstract TBuilder Self { get; } internal BuilderSkeleton(ITypeResolver typeResolver) { overrides = new YamlAttributeOverrides(); typeConverterFactories = new LazyComponentRegistrationList { { typeof(YamlDotNet.Serialization.Converters.GuidConverter), (Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false) }, { typeof(SystemTypeConverter), (Nothing _) => new SystemTypeConverter() } }; typeInspectorFactories = new LazyComponentRegistrationList(); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); settings = new Settings(); } public TBuilder IgnoreFields() { ignoreFields = true; return Self; } public TBuilder IncludeNonPublicProperties() { includeNonPublicProperties = true; return Self; } public TBuilder EnablePrivateConstructors() { settings.AllowPrivateConstructors = true; return Self; } public TBuilder WithNamingConvention(INamingConvention namingConvention) { this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention"); return Self; } public TBuilder WithEnumNamingConvention(INamingConvention enumNamingConvention) { this.enumNamingConvention = enumNamingConvention; return Self; } public TBuilder WithTypeResolver(ITypeResolver typeResolver) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); return Self; } public abstract TBuilder WithTagMapping(TagName tag, Type type); public TBuilder WithAttributeOverride(Expression> propertyAccessor, Attribute attribute) { overrides.Add(propertyAccessor, attribute); return Self; } public TBuilder WithAttributeOverride(Type type, string member, Attribute attribute) { overrides.Add(type, member, attribute); return Self; } public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter) { return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action> where) { IYamlTypeConverter typeConverter2 = typeConverter; if (typeConverter2 == null) { throw new ArgumentNullException("typeConverter"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2)); return Self; } public TBuilder WithTypeConverter(WrapperFactory typeConverterFactory, Action> where) where TYamlTypeConverter : IYamlTypeConverter { WrapperFactory typeConverterFactory2 = typeConverterFactory; if (typeConverterFactory2 == null) { throw new ArgumentNullException("typeConverterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(wrapped))); return Self; } public TBuilder WithoutTypeConverter() where TYamlTypeConverter : IYamlTypeConverter { return WithoutTypeConverter(typeof(TYamlTypeConverter)); } public TBuilder WithoutTypeConverter(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } typeConverterFactories.Remove(converterType); return Self; } public TBuilder WithTypeInspector(Func typeInspectorFactory) where TTypeInspector : ITypeInspector { return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public TBuilder WithTypeInspector(Func typeInspectorFactory, Action> where) where TTypeInspector : ITypeInspector { Func typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner))); return Self; } public TBuilder WithTypeInspector(WrapperFactory typeInspectorFactory, Action> where) where TTypeInspector : ITypeInspector { WrapperFactory typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(wrapped, inner))); return Self; } public TBuilder WithoutTypeInspector() where TTypeInspector : ITypeInspector { return WithoutTypeInspector(typeof(TTypeInspector)); } public TBuilder WithoutTypeInspector(Type inspectorType) { if (inspectorType == null) { throw new ArgumentNullException("inspectorType"); } typeInspectorFactories.Remove(inspectorType); return Self; } public TBuilder WithYamlFormatter(YamlFormatter formatter) { yamlFormatter = formatter ?? throw new ArgumentNullException("formatter"); return Self; } protected IEnumerable BuildTypeConverters() { return typeConverterFactories.BuildComponentList(); } } internal delegate TComponent WrapperFactory(TComponentBase wrapped) where TComponent : TComponentBase; internal delegate TComponent WrapperFactory(TComponentBase wrapped, TArgument argument) where TComponent : TComponentBase; [Flags] internal enum DefaultValuesHandling { Preserve = 0, OmitNull = 1, OmitDefaults = 2, OmitEmptyCollections = 4 } internal sealed class Deserializer : IDeserializer { private readonly IValueDeserializer valueDeserializer; public Deserializer() : this(new DeserializerBuilder().BuildValueDeserializer()) { } private Deserializer(IValueDeserializer valueDeserializer) { this.valueDeserializer = valueDeserializer ?? throw new ArgumentNullException("valueDeserializer"); } public static Deserializer FromValueDeserializer(IValueDeserializer valueDeserializer) { return new Deserializer(valueDeserializer); } public T Deserialize(string input) { using StringReader input2 = new StringReader(input); return Deserialize(input2); } public T Deserialize(TextReader input) { return Deserialize(new Parser(input)); } public T Deserialize(IParser parser) { return (T)Deserialize(parser, typeof(T)); } public object? Deserialize(string input) { return Deserialize(input); } public object? Deserialize(TextReader input) { return Deserialize(input); } public object? Deserialize(IParser parser) { return Deserialize(parser); } public object? Deserialize(string input, Type type) { using StringReader input2 = new StringReader(input); return Deserialize(input2, type); } public object? Deserialize(TextReader input, Type type) { return Deserialize(new Parser(input), type); } public object? Deserialize(IParser parser, Type type) { if (parser == null) { throw new ArgumentNullException("parser"); } if (type == null) { throw new ArgumentNullException("type"); } YamlDotNet.Core.Events.StreamStart @event; bool flag = parser.TryConsume(out @event); YamlDotNet.Core.Events.DocumentStart event2; bool flag2 = parser.TryConsume(out event2); object result = null; if (!parser.Accept(out var _) && !parser.Accept(out var _)) { using SerializerState serializerState = new SerializerState(); result = valueDeserializer.DeserializeValue(parser, type, serializerState, valueDeserializer); serializerState.OnDeserialization(); } if (flag2) { parser.Consume(); } if (flag) { parser.Consume(); } return result; } } internal sealed class DeserializerBuilder : BuilderSkeleton { private Lazy objectFactory; private readonly LazyComponentRegistrationList nodeDeserializerFactories; private readonly LazyComponentRegistrationList nodeTypeResolverFactories; private readonly Dictionary tagMappings; private readonly Dictionary typeMappings; private readonly ITypeConverter typeConverter; private bool ignoreUnmatched; private bool duplicateKeyChecking; private bool attemptUnknownTypeDeserialization; private bool enforceNullability; private bool caseInsensitivePropertyMatching; private bool enforceRequiredProperties; protected override DeserializerBuilder Self => this; public DeserializerBuilder() : base((ITypeResolver)new StaticTypeResolver()) { typeMappings = new Dictionary(); objectFactory = new Lazy(() => new DefaultObjectFactory(typeMappings, settings), isThreadSafe: true); tagMappings = new Dictionary { { FailsafeSchema.Tags.Map, typeof(Dictionary) }, { FailsafeSchema.Tags.Str, typeof(string) }, { JsonSchema.Tags.Bool, typeof(bool) }, { JsonSchema.Tags.Float, typeof(double) }, { JsonSchema.Tags.Int, typeof(int) }, { DefaultSchema.Tags.Timestamp, typeof(DateTime) } }; typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner)); typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner); typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner)); typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone())); typeInspectorFactories.Add(typeof(ReadableAndWritablePropertiesTypeInspector), (ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner)); nodeDeserializerFactories = new LazyComponentRegistrationList { { typeof(YamlConvertibleNodeDeserializer), (Nothing _) => new YamlConvertibleNodeDeserializer(objectFactory.Value) }, { typeof(YamlSerializableNodeDeserializer), (Nothing _) => new YamlSerializableNodeDeserializer(objectFactory.Value) }, { typeof(TypeConverterNodeDeserializer), (Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters()) }, { typeof(NullNodeDeserializer), (Nothing _) => new NullNodeDeserializer() }, { typeof(ScalarNodeDeserializer), (Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, BuildTypeInspector(), yamlFormatter, enumNamingConvention) }, { typeof(ArrayNodeDeserializer), (Nothing _) => new ArrayNodeDeserializer(enumNamingConvention, BuildTypeInspector()) }, { typeof(DictionaryNodeDeserializer), (Nothing _) => new DictionaryNodeDeserializer(objectFactory.Value, duplicateKeyChecking) }, { typeof(CollectionNodeDeserializer), (Nothing _) => new CollectionNodeDeserializer(objectFactory.Value, enumNamingConvention, BuildTypeInspector()) }, { typeof(EnumerableNodeDeserializer), (Nothing _) => new EnumerableNodeDeserializer() }, { typeof(ObjectNodeDeserializer), (Nothing _) => new ObjectNodeDeserializer(objectFactory.Value, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter, enumNamingConvention, enforceNullability, caseInsensitivePropertyMatching, enforceRequiredProperties, BuildTypeConverters()) }, { typeof(FsharpListNodeDeserializer), (Nothing _) => new FsharpListNodeDeserializer(BuildTypeInspector(), enumNamingConvention) } }; nodeTypeResolverFactories = new LazyComponentRegistrationList { { typeof(MappingNodeTypeResolver), (Nothing _) => new MappingNodeTypeResolver(typeMappings) }, { typeof(YamlConvertibleTypeResolver), (Nothing _) => new YamlConvertibleTypeResolver() }, { typeof(YamlSerializableTypeResolver), (Nothing _) => new YamlSerializableTypeResolver() }, { typeof(TagNodeTypeResolver), (Nothing _) => new TagNodeTypeResolver(tagMappings) }, { typeof(PreventUnknownTagsNodeTypeResolver), (Nothing _) => new PreventUnknownTagsNodeTypeResolver() }, { typeof(DefaultContainersNodeTypeResolver), (Nothing _) => new DefaultContainersNodeTypeResolver() } }; typeConverter = new ReflectionTypeConverter(); } public ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = new WritablePropertiesTypeInspector(typeResolver, includeNonPublicProperties); if (!ignoreFields) { typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector); } return typeInspectorFactories.BuildComponentChain(typeInspector); } public DeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization() { attemptUnknownTypeDeserialization = true; return this; } public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory) { IObjectFactory objectFactory2 = objectFactory; if (objectFactory2 == null) { throw new ArgumentNullException("objectFactory"); } this.objectFactory = new Lazy(() => objectFactory2, isThreadSafe: true); return this; } public DeserializerBuilder WithObjectFactory(Func objectFactory) { if (objectFactory == null) { throw new ArgumentNullException("objectFactory"); } return WithObjectFactory(new LambdaObjectFactory(objectFactory)); } public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer) { return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action> where) { INodeDeserializer nodeDeserializer2 = nodeDeserializer; if (nodeDeserializer2 == null) { throw new ArgumentNullException("nodeDeserializer"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2)); return this; } public DeserializerBuilder WithNodeDeserializer(WrapperFactory nodeDeserializerFactory, Action> where) where TNodeDeserializer : INodeDeserializer { WrapperFactory nodeDeserializerFactory2 = nodeDeserializerFactory; if (nodeDeserializerFactory2 == null) { throw new ArgumentNullException("nodeDeserializerFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(wrapped))); return this; } public DeserializerBuilder WithoutNodeDeserializer() where TNodeDeserializer : INodeDeserializer { return WithoutNodeDeserializer(typeof(TNodeDeserializer)); } public DeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType) { if (nodeDeserializerType == null) { throw new ArgumentNullException("nodeDeserializerType"); } nodeDeserializerFactories.Remove(nodeDeserializerType); return this; } public DeserializerBuilder WithTypeDiscriminatingNodeDeserializer(Action configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1) { TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions(); configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions); TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength); return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax s) { s.Before(); }); } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver) { return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action> where) { INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver; if (nodeTypeResolver2 == null) { throw new ArgumentNullException("nodeTypeResolver"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2)); return this; } public DeserializerBuilder WithNodeTypeResolver(WrapperFactory nodeTypeResolverFactory, Action> where) where TNodeTypeResolver : INodeTypeResolver { WrapperFactory nodeTypeResolverFactory2 = nodeTypeResolverFactory; if (nodeTypeResolverFactory2 == null) { throw new ArgumentNullException("nodeTypeResolverFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(wrapped))); return this; } public DeserializerBuilder WithCaseInsensitivePropertyMatching() { caseInsensitivePropertyMatching = true; return this; } public DeserializerBuilder WithEnforceNullability() { enforceNullability = true; return this; } public DeserializerBuilder WithEnforceRequiredMembers() { enforceRequiredProperties = true; return this; } public DeserializerBuilder WithoutNodeTypeResolver() where TNodeTypeResolver : INodeTypeResolver { return WithoutNodeTypeResolver(typeof(TNodeTypeResolver)); } public DeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType) { if (nodeTypeResolverType == null) { throw new ArgumentNullException("nodeTypeResolverType"); } nodeTypeResolverFactories.Remove(nodeTypeResolverType); return this; } public override DeserializerBuilder WithTagMapping(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(tag, out Type value)) { throw new ArgumentException($"Type already has a registered type '{value.FullName}' for tag '{tag}'", "tag"); } tagMappings.Add(tag, type); return this; } public DeserializerBuilder WithTypeMapping() where TConcrete : TInterface { Type typeFromHandle = typeof(TInterface); Type typeFromHandle2 = typeof(TConcrete); if (!typeFromHandle.IsAssignableFrom(typeFromHandle2)) { throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'."); } if (!DictionaryExtensions.TryAdd(typeMappings, typeFromHandle, typeFromHandle2)) { typeMappings[typeFromHandle] = typeFromHandle2; } return this; } public DeserializerBuilder WithoutTagMapping(TagName tag) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (!tagMappings.Remove(tag)) { throw new KeyNotFoundException($"Tag '{tag}' is not registered"); } return this; } public DeserializerBuilder IgnoreUnmatchedProperties() { ignoreUnmatched = true; return this; } public DeserializerBuilder WithDuplicateKeyChecking() { duplicateKeyChecking = true; return this; } public IDeserializer Build() { return Deserializer.FromValueDeserializer(BuildValueDeserializer()); } public IValueDeserializer BuildValueDeserializer() { return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter, enumNamingConvention, BuildTypeInspector())); } } internal sealed class EmissionPhaseObjectGraphVisitorArgs { private readonly IEnumerable> preProcessingPhaseVisitors; public IObjectGraphVisitor InnerVisitor { get; private set; } public IEventEmitter EventEmitter { get; private set; } public ObjectSerializer NestedObjectSerializer { get; private set; } public IEnumerable TypeConverters { get; private set; } public EmissionPhaseObjectGraphVisitorArgs(IObjectGraphVisitor innerVisitor, IEventEmitter eventEmitter, IEnumerable> preProcessingPhaseVisitors, IEnumerable typeConverters, ObjectSerializer nestedObjectSerializer) { InnerVisitor = innerVisitor ?? throw new ArgumentNullException("innerVisitor"); EventEmitter = eventEmitter ?? throw new ArgumentNullException("eventEmitter"); this.preProcessingPhaseVisitors = preProcessingPhaseVisitors ?? throw new ArgumentNullException("preProcessingPhaseVisitors"); TypeConverters = typeConverters ?? throw new ArgumentNullException("typeConverters"); NestedObjectSerializer = nestedObjectSerializer ?? throw new ArgumentNullException("nestedObjectSerializer"); } public T GetPreProcessingPhaseObjectGraphVisitor() where T : IObjectGraphVisitor { return preProcessingPhaseVisitors.OfType().Single(); } } public abstract class EventInfo { public IObjectDescriptor Source { get; } protected EventInfo(IObjectDescriptor source) { Source = source ?? throw new ArgumentNullException("source"); } } public class AliasEventInfo : EventInfo { public AnchorName Alias { get; } public bool NeedsExpansion { get; set; } public AliasEventInfo(IObjectDescriptor source, AnchorName alias) : base(source) { if (alias.IsEmpty) { throw new ArgumentNullException("alias"); } Alias = alias; } } public class ObjectEventInfo : EventInfo { public AnchorName Anchor { get; set; } public TagName Tag { get; set; } protected ObjectEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class ScalarEventInfo : ObjectEventInfo { public string RenderedValue { get; set; } public ScalarStyle Style { get; set; } public bool IsPlainImplicit { get; set; } public bool IsQuotedImplicit { get; set; } public ScalarEventInfo(IObjectDescriptor source) : base(source) { Style = source.ScalarStyle; RenderedValue = string.Empty; } } public sealed class MappingStartEventInfo : ObjectEventInfo { public bool IsImplicit { get; set; } public MappingStyle Style { get; set; } public MappingStartEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class MappingEndEventInfo : EventInfo { public MappingEndEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class SequenceStartEventInfo : ObjectEventInfo { public bool IsImplicit { get; set; } public SequenceStyle Style { get; set; } public SequenceStartEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class SequenceEndEventInfo : EventInfo { public SequenceEndEventInfo(IObjectDescriptor source) : base(source) { } } internal interface IAliasProvider { AnchorName GetAlias(object target); } public interface IDeserializer { T Deserialize(string input); T Deserialize(TextReader input); T Deserialize(IParser parser); object? Deserialize(string input); object? Deserialize(TextReader input); object? Deserialize(IParser parser); object? Deserialize(string input, Type type); object? Deserialize(TextReader input, Type type); object? Deserialize(IParser parser, Type type); } public interface IEventEmitter { void Emit(AliasEventInfo eventInfo, IEmitter emitter); void Emit(ScalarEventInfo eventInfo, IEmitter emitter); void Emit(MappingStartEventInfo eventInfo, IEmitter emitter); void Emit(MappingEndEventInfo eventInfo, IEmitter emitter); void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter); void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter); } internal interface INamingConvention { string Apply(string value); string Reverse(string value); } internal interface INodeDeserializer { bool Deserialize(IParser reader, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer); } internal interface INodeTypeResolver { bool Resolve(NodeEvent? nodeEvent, ref Type currentType); } internal interface IObjectAccessor { void Set(string name, object target, object value); object? Read(string name, object target); } public interface IObjectDescriptor { object? Value { get; } Type Type { get; } Type StaticType { get; } ScalarStyle ScalarStyle { get; } } internal static class ObjectDescriptorExtensions { public static object NonNullValue(this IObjectDescriptor objectDescriptor) { return objectDescriptor.Value ?? throw new InvalidOperationException("Attempted to use a IObjectDescriptor of type '" + objectDescriptor.Type.FullName + "' whose Value is null at a point whete it is invalid to do so. This may indicate a bug in YamlDotNet."); } } internal interface IObjectFactory { object Create(Type type); object? CreatePrimitive(Type type); bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments); Type GetValueType(Type type); void ExecuteOnDeserializing(object value); void ExecuteOnDeserialized(object value); void ExecuteOnSerializing(object value); void ExecuteOnSerialized(object value); } internal interface IObjectGraphTraversalStrategy { void Traverse(IObjectDescriptor graph, IObjectGraphVisitor visitor, TContext context, ObjectSerializer serializer); } internal interface IObjectGraphVisitor { bool Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, TContext context, ObjectSerializer serializer); bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, TContext context, ObjectSerializer serializer); bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, TContext context, ObjectSerializer serializer); void VisitScalar(IObjectDescriptor scalar, TContext context, ObjectSerializer serializer); void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, TContext context, ObjectSerializer serializer); void VisitMappingEnd(IObjectDescriptor mapping, TContext context, ObjectSerializer serializer); void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, TContext context, ObjectSerializer serializer); void VisitSequenceEnd(IObjectDescriptor sequence, TContext context, ObjectSerializer serializer); } internal interface IPropertyDescriptor { string Name { get; } bool AllowNulls { get; } bool CanWrite { get; } Type Type { get; } Type? TypeOverride { get; set; } int Order { get; set; } ScalarStyle ScalarStyle { get; set; } bool Required { get; } Type? ConverterType { get; } T? GetCustomAttribute() where T : Attribute; IObjectDescriptor Read(object target); void Write(object target, object? value); } internal interface IRegistrationLocationSelectionSyntax { void InsteadOf() where TRegistrationType : TBaseRegistrationType; void Before() where TRegistrationType : TBaseRegistrationType; void After() where TRegistrationType : TBaseRegistrationType; void OnTop(); void OnBottom(); } internal interface ITrackingRegistrationLocationSelectionSyntax { void InsteadOf() where TRegistrationType : TBaseRegistrationType; } public interface ISerializer { string Serialize(object? graph); string Serialize(object? graph, Type type); void Serialize(TextWriter writer, object? graph); void Serialize(TextWriter writer, object? graph, Type type); void Serialize(IEmitter emitter, object? graph); void Serialize(IEmitter emitter, object? graph, Type type); } internal interface ITypeInspector { IEnumerable GetProperties(Type type, object? container); IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched, bool caseInsensitivePropertyMatching); string GetEnumName(Type enumType, string name); string GetEnumValue(object enumValue); } internal interface ITypeResolver { Type Resolve(Type staticType, object? actualValue); } internal interface IValueDeserializer { object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer); } internal interface IValuePromise { event Action ValueAvailable; } internal interface IValueSerializer { void SerializeValue(IEmitter emitter, object? value, Type? type); } internal interface IYamlConvertible { void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer); void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer); } public delegate object? ObjectDeserializer(Type type); public delegate void ObjectSerializer(object? value, Type? type = null); [Obsolete("Please use IYamlConvertible instead")] internal interface IYamlSerializable { void ReadYaml(IParser parser); void WriteYaml(IEmitter emitter); } internal interface IYamlTypeConverter { bool Accepts(Type type); object? ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer); void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer); } internal sealed class LazyComponentRegistrationList : IEnumerable>, IEnumerable { public sealed class LazyComponentRegistration { public readonly Type ComponentType; public readonly Func Factory; public LazyComponentRegistration(Type componentType, Func factory) { ComponentType = componentType; Factory = factory; } } public sealed class TrackingLazyComponentRegistration { public readonly Type ComponentType; public readonly Func Factory; public TrackingLazyComponentRegistration(Type componentType, Func factory) { ComponentType = componentType; Factory = factory; } } private class RegistrationLocationSelector : IRegistrationLocationSelectionSyntax { private readonly LazyComponentRegistrationList registrations; private readonly LazyComponentRegistration newRegistration; public RegistrationLocationSelector(LazyComponentRegistrationList registrations, LazyComponentRegistration newRegistration) { this.registrations = registrations; this.newRegistration = newRegistration; } void IRegistrationLocationSelectionSyntax.InsteadOf() { if (newRegistration.ComponentType != typeof(TRegistrationType)) { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); } int index = registrations.EnsureRegistrationExists(); registrations.entries[index] = newRegistration; } void IRegistrationLocationSelectionSyntax.After() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); int num = registrations.EnsureRegistrationExists(); registrations.entries.Insert(num + 1, newRegistration); } void IRegistrationLocationSelectionSyntax.Before() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); int index = registrations.EnsureRegistrationExists(); registrations.entries.Insert(index, newRegistration); } void IRegistrationLocationSelectionSyntax.OnBottom() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); registrations.entries.Add(newRegistration); } void IRegistrationLocationSelectionSyntax.OnTop() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); registrations.entries.Insert(0, newRegistration); } } private class TrackingRegistrationLocationSelector : ITrackingRegistrationLocationSelectionSyntax { private readonly LazyComponentRegistrationList registrations; private readonly TrackingLazyComponentRegistration newRegistration; public TrackingRegistrationLocationSelector(LazyComponentRegistrationList registrations, TrackingLazyComponentRegistration newRegistration) { this.registrations = registrations; this.newRegistration = newRegistration; } void ITrackingRegistrationLocationSelectionSyntax.InsteadOf() { if (newRegistration.ComponentType != typeof(TRegistrationType)) { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); } int index = registrations.EnsureRegistrationExists(); Func innerComponentFactory = registrations.entries[index].Factory; registrations.entries[index] = new LazyComponentRegistration(newRegistration.ComponentType, (TArgument arg) => newRegistration.Factory(innerComponentFactory(arg), arg)); } } private readonly List entries = new List(); public int Count => entries.Count; public IEnumerable> InReverseOrder { get { int i = entries.Count - 1; while (i >= 0) { yield return entries[i].Factory; int num = i - 1; i = num; } } } public LazyComponentRegistrationList Clone() { LazyComponentRegistrationList lazyComponentRegistrationList = new LazyComponentRegistrationList(); foreach (LazyComponentRegistration entry in entries) { lazyComponentRegistrationList.entries.Add(entry); } return lazyComponentRegistrationList; } public void Clear() { entries.Clear(); } public void Add(Type componentType, Func factory) { entries.Add(new LazyComponentRegistration(componentType, factory)); } public void Remove(Type componentType) { for (int i = 0; i < entries.Count; i++) { if (entries[i].ComponentType == componentType) { entries.RemoveAt(i); return; } } throw new KeyNotFoundException("A component registration of type '" + componentType.FullName + "' was not found."); } public IRegistrationLocationSelectionSyntax CreateRegistrationLocationSelector(Type componentType, Func factory) { return new RegistrationLocationSelector(this, new LazyComponentRegistration(componentType, factory)); } public ITrackingRegistrationLocationSelectionSyntax CreateTrackingRegistrationLocationSelector(Type componentType, Func factory) { return new TrackingRegistrationLocationSelector(this, new TrackingLazyComponentRegistration(componentType, factory)); } public IEnumerator> GetEnumerator() { return entries.Select((LazyComponentRegistration e) => e.Factory).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private int IndexOfRegistration(Type registrationType) { for (int i = 0; i < entries.Count; i++) { if (registrationType == entries[i].ComponentType) { return i; } } return -1; } private void EnsureNoDuplicateRegistrationType(Type componentType) { if (IndexOfRegistration(componentType) != -1) { throw new InvalidOperationException("A component of type '" + componentType.FullName + "' has already been registered."); } } private int EnsureRegistrationExists() { int num = IndexOfRegistration(typeof(TRegistrationType)); if (num == -1) { throw new InvalidOperationException("A component of type '" + typeof(TRegistrationType).FullName + "' has not been registered."); } return num; } } internal static class LazyComponentRegistrationListExtensions { public static TComponent BuildComponentChain(this LazyComponentRegistrationList registrations, TComponent innerComponent) { return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func factory) => factory(inner)); } public static TComponent BuildComponentChain(this LazyComponentRegistrationList registrations, TComponent innerComponent, Func argumentBuilder) { Func argumentBuilder2 = argumentBuilder; return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func factory) => factory(argumentBuilder2(inner))); } public static List BuildComponentList(this LazyComponentRegistrationList registrations) { return registrations.Select((Func factory) => factory(default(Nothing))).ToList(); } public static List BuildComponentList(this LazyComponentRegistrationList registrations, TArgument argument) { TArgument argument2 = argument; return registrations.Select((Func factory) => factory(argument2)).ToList(); } } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct Nothing { } internal sealed class ObjectDescriptor : IObjectDescriptor { public object? Value { get; private set; } public Type Type { get; private set; } public Type StaticType { get; private set; } public ScalarStyle ScalarStyle { get; private set; } public ObjectDescriptor(object? value, Type type, Type staticType) : this(value, type, staticType, ScalarStyle.Any) { } public ObjectDescriptor(object? value, Type type, Type staticType, ScalarStyle scalarStyle) { Value = value; Type = type ?? throw new ArgumentNullException("type"); StaticType = staticType ?? throw new ArgumentNullException("staticType"); ScalarStyle = scalarStyle; } } internal delegate IObjectGraphTraversalStrategy ObjectGraphTraversalStrategyFactory(ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable typeConverters, int maximumRecursion); internal sealed class PropertyDescriptor : IPropertyDescriptor { private readonly IPropertyDescriptor baseDescriptor; public bool AllowNulls => baseDescriptor.AllowNulls; public string Name { get; set; } public bool Required => baseDescriptor.Required; public Type Type => baseDescriptor.Type; public Type? TypeOverride { get { return baseDescriptor.TypeOverride; } set { baseDescriptor.TypeOverride = value; } } public Type? ConverterType => baseDescriptor.ConverterType; public int Order { get; set; } public ScalarStyle ScalarStyle { get { return baseDescriptor.ScalarStyle; } set { baseDescriptor.ScalarStyle = value; } } public bool CanWrite => baseDescriptor.CanWrite; public PropertyDescriptor(IPropertyDescriptor baseDescriptor) { this.baseDescriptor = baseDescriptor; Name = baseDescriptor.Name; } public void Write(object target, object? value) { baseDescriptor.Write(target, value); } public T? GetCustomAttribute() where T : Attribute { return baseDescriptor.GetCustomAttribute(); } public IObjectDescriptor Read(object target) { return baseDescriptor.Read(target); } } internal sealed class Serializer : ISerializer { private readonly IValueSerializer valueSerializer; private readonly EmitterSettings emitterSettings; public Serializer() : this(new SerializerBuilder().BuildValueSerializer(), EmitterSettings.Default) { } private Serializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings) { this.valueSerializer = valueSerializer ?? throw new ArgumentNullException("valueSerializer"); this.emitterSettings = emitterSettings ?? throw new ArgumentNullException("emitterSettings"); } public static Serializer FromValueSerializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings) { return new Serializer(valueSerializer, emitterSettings); } public string Serialize(object? graph) { using StringWriter stringWriter = new StringWriter(); Serialize(stringWriter, graph); return stringWriter.ToString(); } public string Serialize(object? graph, Type type) { using StringWriter stringWriter = new StringWriter(); Serialize(stringWriter, graph, type); return stringWriter.ToString(); } public void Serialize(TextWriter writer, object? graph) { Serialize(new Emitter(writer, emitterSettings), graph); } public void Serialize(TextWriter writer, object? graph, Type type) { Serialize(new Emitter(writer, emitterSettings), graph, type); } public void Serialize(IEmitter emitter, object? graph) { if (emitter == null) { throw new ArgumentNullException("emitter"); } EmitDocument(emitter, graph, null); } public void Serialize(IEmitter emitter, object? graph, Type type) { if (emitter == null) { throw new ArgumentNullException("emitter"); } if (type == null) { throw new ArgumentNullException("type"); } EmitDocument(emitter, graph, type); } private void EmitDocument(IEmitter emitter, object? graph, Type? type) { emitter.Emit(new YamlDotNet.Core.Events.StreamStart()); emitter.Emit(new YamlDotNet.Core.Events.DocumentStart()); valueSerializer.SerializeValue(emitter, graph, type); emitter.Emit(new YamlDotNet.Core.Events.DocumentEnd(isImplicit: true)); emitter.Emit(new YamlDotNet.Core.Events.StreamEnd()); } } internal sealed class SerializerBuilder : BuilderSkeleton { private class ValueSerializer : IValueSerializer { private readonly IObjectGraphTraversalStrategy traversalStrategy; private readonly IEventEmitter eventEmitter; private readonly IEnumerable typeConverters; private readonly LazyComponentRegistrationList, IObjectGraphVisitor> preProcessingPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList> emissionPhaseObjectGraphVisitorFactories; public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable typeConverters, LazyComponentRegistrationList, IObjectGraphVisitor> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList> emissionPhaseObjectGraphVisitorFactories) { this.traversalStrategy = traversalStrategy; this.eventEmitter = eventEmitter; this.typeConverters = typeConverters; this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories; this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories; } public void SerializeValue(IEmitter emitter, object? value, Type? type) { IEmitter emitter2 = emitter; Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object)); Type staticType = type ?? typeof(object); ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType); List> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters); IObjectGraphVisitor visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, NestedObjectSerializer)); foreach (IObjectGraphVisitor item in preProcessingPhaseObjectGraphVisitors) { traversalStrategy.Traverse(graph, item, default(Nothing), NestedObjectSerializer); } traversalStrategy.Traverse(graph, visitor, emitter2, NestedObjectSerializer); void NestedObjectSerializer(object? v, Type? t) { SerializeValue(emitter2, v, t); } } } private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory; private readonly LazyComponentRegistrationList, IObjectGraphVisitor> preProcessingPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList> emissionPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList eventEmitterFactories; private readonly Dictionary tagMappings = new Dictionary(); private readonly IObjectFactory objectFactory; private int maximumRecursion = 50; private EmitterSettings emitterSettings = EmitterSettings.Default; private DefaultValuesHandling defaultValuesHandlingConfiguration; private ScalarStyle defaultScalarStyle; private bool quoteNecessaryStrings; private bool quoteYaml1_1Strings; protected override SerializerBuilder Self => this; public SerializerBuilder() : base((ITypeResolver)new DynamicTypeResolver()) { typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner)); typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner); typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner)); typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone())); preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList, IObjectGraphVisitor> { { typeof(AnchorAssigner), (IEnumerable typeConverters) => new AnchorAssigner(typeConverters) } }; emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList> { { typeof(CustomSerializationObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer) }, { typeof(AnchorAssigningObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor()) }, { typeof(DefaultValuesObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor, new DefaultObjectFactory()) }, { typeof(CommentsObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor) } }; eventEmitterFactories = new LazyComponentRegistrationList { { typeof(TypeAssigningEventEmitter), (IEventEmitter inner) => new TypeAssigningEventEmitter(inner, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention, BuildTypeInspector()) } }; objectFactory = new DefaultObjectFactory(); objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, objectFactory); } public SerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false) { quoteNecessaryStrings = true; this.quoteYaml1_1Strings = quoteYaml1_1Strings; return this; } public SerializerBuilder WithDefaultScalarStyle(ScalarStyle style) { defaultScalarStyle = style; return this; } public SerializerBuilder WithMaximumRecursion(int maximumRecursion) { if (maximumRecursion <= 0) { throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer."); } this.maximumRecursion = maximumRecursion; return this; } public SerializerBuilder WithEventEmitter(Func eventEmitterFactory) where TEventEmitter : IEventEmitter { return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public SerializerBuilder WithEventEmitter(Func eventEmitterFactory) where TEventEmitter : IEventEmitter { return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public SerializerBuilder WithEventEmitter(Func eventEmitterFactory, Action> where) where TEventEmitter : IEventEmitter { Func eventEmitterFactory2 = eventEmitterFactory; return WithEventEmitter((IEventEmitter e, ITypeInspector _) => eventEmitterFactory2(e), where); } public SerializerBuilder WithEventEmitter(Func eventEmitterFactory, Action> where) where TEventEmitter : IEventEmitter { Func eventEmitterFactory2 = eventEmitterFactory; if (eventEmitterFactory2 == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory2(inner, BuildTypeInspector()))); return Self; } public SerializerBuilder WithEventEmitter(WrapperFactory eventEmitterFactory, Action> where) where TEventEmitter : IEventEmitter { WrapperFactory eventEmitterFactory2 = eventEmitterFactory; if (eventEmitterFactory2 == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory2(wrapped, inner))); return Self; } public SerializerBuilder WithoutEventEmitter() where TEventEmitter : IEventEmitter { return WithoutEventEmitter(typeof(TEventEmitter)); } public SerializerBuilder WithoutEventEmitter(Type eventEmitterType) { if (eventEmitterType == null) { throw new ArgumentNullException("eventEmitterType"); } eventEmitterFactories.Remove(eventEmitterType); return this; } public override SerializerBuilder WithTagMapping(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(type, out var value)) { throw new ArgumentException($"Type already has a registered tag '{value}' for type '{type.FullName}'", "type"); } tagMappings.Add(type, tag); return this; } public SerializerBuilder WithoutTagMapping(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!tagMappings.Remove(type)) { throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered"); } return this; } public SerializerBuilder EnsureRoundtrip() { objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention, settings, objectFactory); WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention, BuildTypeInspector()), delegate(IRegistrationLocationSelectionSyntax loc) { loc.InsteadOf(); }); return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax loc) { loc.OnBottom(); }); } public SerializerBuilder DisableAliases() { preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner)); emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor)); return this; } [Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)] public SerializerBuilder EmitDefaults() { return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve); } public SerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration) { defaultValuesHandlingConfiguration = configuration; return this; } public SerializerBuilder JsonCompatible() { emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue).WithoutAnchorName(); return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax w) { w.InsteadOf(); }).WithTypeConverter(new DateTime8601Converter(ScalarStyle.DoubleQuoted)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter, enumNamingConvention, BuildTypeInspector()), delegate(IRegistrationLocationSelectionSyntax loc) { loc.InsteadOf(); }); } public SerializerBuilder WithNewLine(string newLine) { emitterSettings = emitterSettings.WithNewLine(newLine); return this; } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor { return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax> w) { w.OnTop(); }); } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(Func, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor { return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax> w) { w.OnTop(); }); } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(TObjectGraphVisitor objectGraphVisitor, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { TObjectGraphVisitor objectGraphVisitor2 = objectGraphVisitor; if (objectGraphVisitor2 == null) { throw new ArgumentNullException("objectGraphVisitor"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable _) => objectGraphVisitor2)); return this; } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(Func, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { Func, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable typeConverters) => objectGraphVisitorFactory2(typeConverters))); return this; } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor wrapped, IEnumerable _) => objectGraphVisitorFactory2(wrapped))); return this; } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(WrapperFactory, IObjectGraphVisitor, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { WrapperFactory, IObjectGraphVisitor, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor wrapped, IEnumerable typeConverters) => objectGraphVisitorFactory2(wrapped, typeConverters))); return this; } public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor() where TObjectGraphVisitor : IObjectGraphVisitor { return WithoutPreProcessingPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor)); } public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor(Type objectGraphVisitorType) { if (objectGraphVisitorType == null) { throw new ArgumentNullException("objectGraphVisitorType"); } preProcessingPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType); return this; } public SerializerBuilder WithObjectGraphTraversalStrategyFactory(ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory) { this.objectGraphTraversalStrategyFactory = objectGraphTraversalStrategyFactory; return this; } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor(Func objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor { return WithEmissionPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax> w) { w.OnTop(); }); } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor(Func objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { Func objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(args))); return this; } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor(WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(wrapped, args))); return this; } public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor() where TObjectGraphVisitor : IObjectGraphVisitor { return WithoutEmissionPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor)); } public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor(Type objectGraphVisitorType) { if (objectGraphVisitorType == null) { throw new ArgumentNullException("objectGraphVisitorType"); } emissionPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType); return this; } public SerializerBuilder WithIndentedSequences() { emitterSettings = emitterSettings.WithIndentedSequences(); return this; } public ISerializer Build() { return Serializer.FromValueSerializer(BuildValueSerializer(), emitterSettings); } public IValueSerializer BuildValueSerializer() { IEnumerable typeConverters = BuildTypeConverters(); ITypeInspector typeInspector = BuildTypeInspector(); IObjectGraphTraversalStrategy traversalStrategy = objectGraphTraversalStrategyFactory(typeInspector, typeResolver, typeConverters, maximumRecursion); IEventEmitter eventEmitter = eventEmitterFactories.BuildComponentChain(new WriterEventEmitter()); return new ValueSerializer(traversalStrategy, eventEmitter, typeConverters, preProcessingPhaseObjectGraphVisitorFactories.Clone(), emissionPhaseObjectGraphVisitorFactories.Clone()); } public ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver, includeNonPublicProperties); if (!ignoreFields) { typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector); } return typeInspectorFactories.BuildComponentChain(typeInspector); } } internal class Settings { public bool AllowPrivateConstructors { get; set; } } internal abstract class StaticBuilderSkeleton where TBuilder : StaticBuilderSkeleton { internal INamingConvention namingConvention = NullNamingConvention.Instance; internal INamingConvention enumNamingConvention = NullNamingConvention.Instance; internal ITypeResolver typeResolver; internal readonly LazyComponentRegistrationList typeConverterFactories; internal readonly LazyComponentRegistrationList typeInspectorFactories; internal bool includeNonPublicProperties; internal Settings settings; internal YamlFormatter yamlFormatter = YamlFormatter.Default; protected abstract TBuilder Self { get; } internal StaticBuilderSkeleton(ITypeResolver typeResolver) { typeConverterFactories = new LazyComponentRegistrationList { { typeof(YamlDotNet.Serialization.Converters.GuidConverter), (Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false) } }; typeInspectorFactories = new LazyComponentRegistrationList(); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); settings = new Settings(); } public TBuilder WithNamingConvention(INamingConvention namingConvention) { this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention"); return Self; } public TBuilder WithEnumNamingConvention(INamingConvention enumNamingConvention) { this.enumNamingConvention = enumNamingConvention ?? throw new ArgumentNullException("enumNamingConvention"); return Self; } public TBuilder WithTypeResolver(ITypeResolver typeResolver) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); return Self; } public abstract TBuilder WithTagMapping(TagName tag, Type type); public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter) { return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action> where) { IYamlTypeConverter typeConverter2 = typeConverter; if (typeConverter2 == null) { throw new ArgumentNullException("typeConverter"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2)); return Self; } public TBuilder WithTypeConverter(WrapperFactory typeConverterFactory, Action> where) where TYamlTypeConverter : IYamlTypeConverter { WrapperFactory typeConverterFactory2 = typeConverterFactory; if (typeConverterFactory2 == null) { throw new ArgumentNullException("typeConverterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(wrapped))); return Self; } public TBuilder WithoutTypeConverter() where TYamlTypeConverter : IYamlTypeConverter { return WithoutTypeConverter(typeof(TYamlTypeConverter)); } public TBuilder WithoutTypeConverter(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } typeConverterFactories.Remove(converterType); return Self; } public TBuilder WithTypeInspector(Func typeInspectorFactory) where TTypeInspector : ITypeInspector { return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public TBuilder WithTypeInspector(Func typeInspectorFactory, Action> where) where TTypeInspector : ITypeInspector { Func typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner))); return Self; } public TBuilder WithTypeInspector(WrapperFactory typeInspectorFactory, Action> where) where TTypeInspector : ITypeInspector { WrapperFactory typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(wrapped, inner))); return Self; } public TBuilder WithoutTypeInspector() where TTypeInspector : ITypeInspector { return WithoutTypeInspector(typeof(TTypeInspector)); } public TBuilder WithoutTypeInspector(Type inspectorType) { if (inspectorType == null) { throw new ArgumentNullException("inspectorType"); } typeInspectorFactories.Remove(inspectorType); return Self; } public TBuilder WithYamlFormatter(YamlFormatter formatter) { yamlFormatter = formatter ?? throw new ArgumentNullException("formatter"); return Self; } protected IEnumerable BuildTypeConverters() { return typeConverterFactories.BuildComponentList(); } } internal abstract class StaticContext { public virtual bool IsKnownType(Type type) { throw new NotImplementedException(); } public virtual ITypeResolver GetTypeResolver() { throw new NotImplementedException(); } public virtual StaticObjectFactory GetFactory() { throw new NotImplementedException(); } public virtual ITypeInspector GetTypeInspector() { throw new NotImplementedException(); } } internal sealed class StaticDeserializerBuilder : StaticBuilderSkeleton { private readonly StaticContext context; private readonly StaticObjectFactory factory; private readonly LazyComponentRegistrationList nodeDeserializerFactories; private readonly LazyComponentRegistrationList nodeTypeResolverFactories; private readonly Dictionary tagMappings; private readonly ITypeConverter typeConverter; private readonly Dictionary typeMappings; private bool ignoreUnmatched; private bool duplicateKeyChecking; private bool attemptUnknownTypeDeserialization; private bool enforceNullability; private bool caseInsensitivePropertyMatching; protected override StaticDeserializerBuilder Self => this; public StaticDeserializerBuilder(StaticContext context) : base(context.GetTypeResolver()) { this.context = context; factory = context.GetFactory(); typeMappings = new Dictionary(); tagMappings = new Dictionary { { FailsafeSchema.Tags.Map, typeof(Dictionary) }, { FailsafeSchema.Tags.Str, typeof(string) }, { JsonSchema.Tags.Bool, typeof(bool) }, { JsonSchema.Tags.Float, typeof(double) }, { JsonSchema.Tags.Int, typeof(int) }, { DefaultSchema.Tags.Timestamp, typeof(DateTime) } }; typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner)); typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner); typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner)); nodeDeserializerFactories = new LazyComponentRegistrationList { { typeof(YamlConvertibleNodeDeserializer), (Nothing _) => new YamlConvertibleNodeDeserializer(factory) }, { typeof(YamlSerializableNodeDeserializer), (Nothing _) => new YamlSerializableNodeDeserializer(factory) }, { typeof(TypeConverterNodeDeserializer), (Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters()) }, { typeof(NullNodeDeserializer), (Nothing _) => new NullNodeDeserializer() }, { typeof(ScalarNodeDeserializer), (Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, BuildTypeInspector(), yamlFormatter, enumNamingConvention) }, { typeof(StaticArrayNodeDeserializer), (Nothing _) => new StaticArrayNodeDeserializer(factory) }, { typeof(StaticDictionaryNodeDeserializer), (Nothing _) => new StaticDictionaryNodeDeserializer(factory, duplicateKeyChecking) }, { typeof(StaticCollectionNodeDeserializer), (Nothing _) => new StaticCollectionNodeDeserializer(factory) }, { typeof(ObjectNodeDeserializer), (Nothing _) => new ObjectNodeDeserializer(factory, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter, enumNamingConvention, enforceNullability, caseInsensitivePropertyMatching, enforceRequiredProperties: false, BuildTypeConverters()) } }; nodeTypeResolverFactories = new LazyComponentRegistrationList { { typeof(MappingNodeTypeResolver), (Nothing _) => new MappingNodeTypeResolver(typeMappings) }, { typeof(YamlConvertibleTypeResolver), (Nothing _) => new YamlConvertibleTypeResolver() }, { typeof(YamlSerializableTypeResolver), (Nothing _) => new YamlSerializableTypeResolver() }, { typeof(TagNodeTypeResolver), (Nothing _) => new TagNodeTypeResolver(tagMappings) }, { typeof(PreventUnknownTagsNodeTypeResolver), (Nothing _) => new PreventUnknownTagsNodeTypeResolver() }, { typeof(DefaultContainersNodeTypeResolver), (Nothing _) => new DefaultContainersNodeTypeResolver() } }; typeConverter = new NullTypeConverter(); } public ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = context.GetTypeInspector(); return typeInspectorFactories.BuildComponentChain(typeInspector); } public StaticDeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization() { attemptUnknownTypeDeserialization = true; return this; } public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer) { return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action> where) { INodeDeserializer nodeDeserializer2 = nodeDeserializer; if (nodeDeserializer2 == null) { throw new ArgumentNullException("nodeDeserializer"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2)); return this; } public StaticDeserializerBuilder WithNodeDeserializer(WrapperFactory nodeDeserializerFactory, Action> where) where TNodeDeserializer : INodeDeserializer { WrapperFactory nodeDeserializerFactory2 = nodeDeserializerFactory; if (nodeDeserializerFactory2 == null) { throw new ArgumentNullException("nodeDeserializerFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(wrapped))); return this; } public StaticDeserializerBuilder WithCaseInsensitivePropertyMatching() { caseInsensitivePropertyMatching = true; return this; } public StaticDeserializerBuilder WithEnforceNullability() { enforceNullability = true; return this; } public StaticDeserializerBuilder WithoutNodeDeserializer() where TNodeDeserializer : INodeDeserializer { return WithoutNodeDeserializer(typeof(TNodeDeserializer)); } public StaticDeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType) { if (nodeDeserializerType == null) { throw new ArgumentNullException("nodeDeserializerType"); } nodeDeserializerFactories.Remove(nodeDeserializerType); return this; } public StaticDeserializerBuilder WithTypeDiscriminatingNodeDeserializer(Action configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1) { TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions(); configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions); TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength); return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax s) { s.Before(); }); } public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver) { return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action> where) { INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver; if (nodeTypeResolver2 == null) { throw new ArgumentNullException("nodeTypeResolver"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2)); return this; } public StaticDeserializerBuilder WithNodeTypeResolver(WrapperFactory nodeTypeResolverFactory, Action> where) where TNodeTypeResolver : INodeTypeResolver { WrapperFactory nodeTypeResolverFactory2 = nodeTypeResolverFactory; if (nodeTypeResolverFactory2 == null) { throw new ArgumentNullException("nodeTypeResolverFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(wrapped))); return this; } public StaticDeserializerBuilder WithoutNodeTypeResolver() where TNodeTypeResolver : INodeTypeResolver { return WithoutNodeTypeResolver(typeof(TNodeTypeResolver)); } public StaticDeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType) { if (nodeTypeResolverType == null) { throw new ArgumentNullException("nodeTypeResolverType"); } nodeTypeResolverFactories.Remove(nodeTypeResolverType); return this; } public override StaticDeserializerBuilder WithTagMapping(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(tag, out Type value)) { throw new ArgumentException($"Type already has a registered type '{value.FullName}' for tag '{tag}'", "tag"); } tagMappings.Add(tag, type); return this; } public StaticDeserializerBuilder WithTypeMapping() where TConcrete : TInterface { Type typeFromHandle = typeof(TInterface); Type typeFromHandle2 = typeof(TConcrete); if (!typeFromHandle.IsAssignableFrom(typeFromHandle2)) { throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'."); } typeMappings[typeFromHandle] = typeFromHandle2; return this; } public StaticDeserializerBuilder WithoutTagMapping(TagName tag) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (!tagMappings.Remove(tag)) { throw new KeyNotFoundException($"Tag '{tag}' is not registered"); } return this; } public StaticDeserializerBuilder IgnoreUnmatchedProperties() { ignoreUnmatched = true; return this; } public StaticDeserializerBuilder WithDuplicateKeyChecking() { duplicateKeyChecking = true; return this; } public IDeserializer Build() { return Deserializer.FromValueDeserializer(BuildValueDeserializer()); } public IValueDeserializer BuildValueDeserializer() { return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter, enumNamingConvention, BuildTypeInspector())); } } internal sealed class StaticSerializerBuilder : StaticBuilderSkeleton { private class ValueSerializer : IValueSerializer { private readonly IObjectGraphTraversalStrategy traversalStrategy; private readonly IEventEmitter eventEmitter; private readonly IEnumerable typeConverters; private readonly LazyComponentRegistrationList, IObjectGraphVisitor> preProcessingPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList> emissionPhaseObjectGraphVisitorFactories; public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable typeConverters, LazyComponentRegistrationList, IObjectGraphVisitor> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList> emissionPhaseObjectGraphVisitorFactories) { this.traversalStrategy = traversalStrategy; this.eventEmitter = eventEmitter; this.typeConverters = typeConverters; this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories; this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories; } public void SerializeValue(IEmitter emitter, object? value, Type? type) { IEmitter emitter2 = emitter; Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object)); Type staticType = type ?? typeof(object); ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType); List> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters); foreach (IObjectGraphVisitor item in preProcessingPhaseObjectGraphVisitors) { traversalStrategy.Traverse(graph, item, default(Nothing), NestedObjectSerializer); } IObjectGraphVisitor visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, NestedObjectSerializer)); traversalStrategy.Traverse(graph, visitor, emitter2, NestedObjectSerializer); void NestedObjectSerializer(object? v, Type? t) { SerializeValue(emitter2, v, t); } } } private readonly StaticContext context; private readonly StaticObjectFactory factory; private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory; private readonly LazyComponentRegistrationList, IObjectGraphVisitor> preProcessingPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList> emissionPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList eventEmitterFactories; private readonly Dictionary tagMappings = new Dictionary(); private int maximumRecursion = 50; private EmitterSettings emitterSettings = EmitterSettings.Default; private DefaultValuesHandling defaultValuesHandlingConfiguration; private bool quoteNecessaryStrings; private bool quoteYaml1_1Strings; private ScalarStyle defaultScalarStyle; protected override StaticSerializerBuilder Self => this; public StaticSerializerBuilder(StaticContext context) : base((ITypeResolver)new DynamicTypeResolver()) { this.context = context; factory = context.GetFactory(); typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner)); typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner); typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner)); preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList, IObjectGraphVisitor> { { typeof(AnchorAssigner), (IEnumerable typeConverters) => new AnchorAssigner(typeConverters) } }; emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList> { { typeof(CustomSerializationObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer) }, { typeof(AnchorAssigningObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor()) }, { typeof(DefaultValuesObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor, factory) }, { typeof(CommentsObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor) } }; eventEmitterFactories = new LazyComponentRegistrationList { { typeof(TypeAssigningEventEmitter), (IEventEmitter inner) => new TypeAssigningEventEmitter(inner, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention, BuildTypeInspector()) } }; objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, factory); } public StaticSerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false) { quoteNecessaryStrings = true; this.quoteYaml1_1Strings = quoteYaml1_1Strings; return this; } public StaticSerializerBuilder WithQuotingNecessaryStrings() { quoteNecessaryStrings = true; return this; } public StaticSerializerBuilder WithDefaultScalarStyle(ScalarStyle style) { defaultScalarStyle = style; return this; } public StaticSerializerBuilder WithMaximumRecursion(int maximumRecursion) { if (maximumRecursion <= 0) { throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer."); } this.maximumRecursion = maximumRecursion; return this; } public StaticSerializerBuilder WithEventEmitter(Func eventEmitterFactory) where TEventEmitter : IEventEmitter { return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public StaticSerializerBuilder WithEventEmitter(Func eventEmitterFactory) where TEventEmitter : IEventEmitter { return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax w) { w.OnTop(); }); } public StaticSerializerBuilder WithEventEmitter(Func eventEmitterFactory, Action> where) where TEventEmitter : IEventEmitter { Func eventEmitterFactory2 = eventEmitterFactory; return WithEventEmitter((IEventEmitter e, ITypeInspector _) => eventEmitterFactory2(e), where); } public StaticSerializerBuilder WithEventEmitter(Func eventEmitterFactory, Action> where) where TEventEmitter : IEventEmitter { Func eventEmitterFactory2 = eventEmitterFactory; if (eventEmitterFactory2 == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory2(inner, BuildTypeInspector()))); return Self; } public StaticSerializerBuilder WithEventEmitter(WrapperFactory eventEmitterFactory, Action> where) where TEventEmitter : IEventEmitter { WrapperFactory eventEmitterFactory2 = eventEmitterFactory; if (eventEmitterFactory2 == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory2(wrapped, inner))); return Self; } public StaticSerializerBuilder WithoutEventEmitter() where TEventEmitter : IEventEmitter { return WithoutEventEmitter(typeof(TEventEmitter)); } public StaticSerializerBuilder WithoutEventEmitter(Type eventEmitterType) { if (eventEmitterType == null) { throw new ArgumentNullException("eventEmitterType"); } eventEmitterFactories.Remove(eventEmitterType); return this; } public override StaticSerializerBuilder WithTagMapping(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(type, out var value)) { throw new ArgumentException($"Type already has a registered tag '{value}' for type '{type.FullName}'", "type"); } tagMappings.Add(type, tag); return this; } public StaticSerializerBuilder WithoutTagMapping(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!tagMappings.Remove(type)) { throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered"); } return this; } public StaticSerializerBuilder EnsureRoundtrip() { objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention, settings, factory); WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings: false, ScalarStyle.Plain, YamlFormatter.Default, enumNamingConvention, BuildTypeInspector()), delegate(IRegistrationLocationSelectionSyntax loc) { loc.InsteadOf(); }); return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax loc) { loc.OnBottom(); }); } public StaticSerializerBuilder DisableAliases() { preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner)); emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor)); return this; } [Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)] public StaticSerializerBuilder EmitDefaults() { return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve); } public StaticSerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration) { defaultValuesHandlingConfiguration = configuration; return this; } public StaticSerializerBuilder JsonCompatible() { emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue).WithoutAnchorName(); return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax w) { w.InsteadOf(); }).WithTypeConverter(new DateTime8601Converter(ScalarStyle.DoubleQuoted)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter, enumNamingConvention, BuildTypeInspector()), delegate(IRegistrationLocationSelectionSyntax loc) { loc.InsteadOf(); }); } public StaticSerializerBuilder WithNewLine(string newLine) { emitterSettings = emitterSettings.WithNewLine(newLine); return this; } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor { return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax> w) { w.OnTop(); }); } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(Func, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor { return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax> w) { w.OnTop(); }); } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(TObjectGraphVisitor objectGraphVisitor, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { TObjectGraphVisitor objectGraphVisitor2 = objectGraphVisitor; if (objectGraphVisitor2 == null) { throw new ArgumentNullException("objectGraphVisitor"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable _) => objectGraphVisitor2)); return this; } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(Func, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { Func, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable typeConverters) => objectGraphVisitorFactory2(typeConverters))); return this; } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor wrapped, IEnumerable _) => objectGraphVisitorFactory2(wrapped))); return this; } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor(WrapperFactory, IObjectGraphVisitor, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { WrapperFactory, IObjectGraphVisitor, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor wrapped, IEnumerable typeConverters) => objectGraphVisitorFactory2(wrapped, typeConverters))); return this; } public StaticSerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor() where TObjectGraphVisitor : IObjectGraphVisitor { return WithoutPreProcessingPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor)); } public StaticSerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor(Type objectGraphVisitorType) { if (objectGraphVisitorType == null) { throw new ArgumentNullException("objectGraphVisitorType"); } preProcessingPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType); return this; } public StaticSerializerBuilder WithObjectGraphTraversalStrategyFactory(ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory) { this.objectGraphTraversalStrategyFactory = objectGraphTraversalStrategyFactory; return this; } public StaticSerializerBuilder WithEmissionPhaseObjectGraphVisitor(Func objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor { return WithEmissionPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax> w) { w.OnTop(); }); } public StaticSerializerBuilder WithEmissionPhaseObjectGraphVisitor(Func objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { Func objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(args))); return this; } public StaticSerializerBuilder WithEmissionPhaseObjectGraphVisitor(WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory, Action>> where) where TObjectGraphVisitor : IObjectGraphVisitor { WrapperFactory, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(wrapped, args))); return this; } public StaticSerializerBuilder WithoutEmissionPhaseObjectGraphVisitor() where TObjectGraphVisitor : IObjectGraphVisitor { return WithoutEmissionPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor)); } public StaticSerializerBuilder WithoutEmissionPhaseObjectGraphVisitor(Type objectGraphVisitorType) { if (objectGraphVisitorType == null) { throw new ArgumentNullException("objectGraphVisitorType"); } emissionPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType); return this; } public StaticSerializerBuilder WithIndentedSequences() { emitterSettings = emitterSettings.WithIndentedSequences(); return this; } public ISerializer Build() { return Serializer.FromValueSerializer(BuildValueSerializer(), emitterSettings); } public IValueSerializer BuildValueSerializer() { IEnumerable typeConverters = BuildTypeConverters(); ITypeInspector typeInspector = BuildTypeInspector(); IObjectGraphTraversalStrategy traversalStrategy = objectGraphTraversalStrategyFactory(typeInspector, typeResolver, typeConverters, maximumRecursion); IEventEmitter eventEmitter = eventEmitterFactories.BuildComponentChain(new WriterEventEmitter()); return new ValueSerializer(traversalStrategy, eventEmitter, typeConverters, preProcessingPhaseObjectGraphVisitorFactories.Clone(), emissionPhaseObjectGraphVisitorFactories.Clone()); } public ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = context.GetTypeInspector(); return typeInspectorFactories.BuildComponentChain(typeInspector); } } internal sealed class StreamFragment : IYamlConvertible { private readonly List events = new List(); public IList Events => events; void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer) { events.Clear(); int num = 0; do { if (!parser.MoveNext()) { throw new InvalidOperationException("The parser has reached the end before deserialization completed."); } ParsingEvent current = parser.Current; events.Add(current); num += current.NestingIncrease; } while (num > 0); } void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer) { foreach (ParsingEvent @event in events) { emitter.Emit(@event); } } } internal sealed class TagMappings { private readonly Dictionary mappings; public TagMappings() { mappings = new Dictionary(); } public TagMappings(IDictionary mappings) { this.mappings = new Dictionary(mappings); } public void Add(string tag, Type mapping) { mappings.Add(tag, mapping); } internal Type? GetMapping(string tag) { if (!mappings.TryGetValue(tag, out Type value)) { return null; } return value; } } internal sealed class YamlAttributeOverrides { private readonly struct AttributeKey { public readonly Type AttributeType; public readonly string PropertyName; public AttributeKey(Type attributeType, string propertyName) { AttributeType = attributeType; PropertyName = propertyName; } public override bool Equals(object? obj) { if (obj is AttributeKey attributeKey && AttributeType.Equals(attributeKey.AttributeType)) { return PropertyName.Equals(attributeKey.PropertyName); } return false; } public override int GetHashCode() { return YamlDotNet.Core.HashCode.CombineHashCodes(AttributeType.GetHashCode(), PropertyName.GetHashCode()); } } private sealed class AttributeMapping { public readonly Type RegisteredType; public readonly Attribute Attribute; public AttributeMapping(Type registeredType, Attribute attribute) { RegisteredType = registeredType; Attribute = attribute; } public override bool Equals(object? obj) { if (obj is AttributeMapping attributeMapping && RegisteredType.Equals(attributeMapping.RegisteredType)) { return Attribute.Equals(attributeMapping.Attribute); } return false; } public override int GetHashCode() { return YamlDotNet.Core.HashCode.CombineHashCodes(RegisteredType.GetHashCode(), Attribute.GetHashCode()); } public int Matches(Type matchType) { int num = 0; Type type = matchType; while (type != null) { num++; if (type == RegisteredType) { return num; } type = type.BaseType(); } if (matchType.GetInterfaces().Contains(RegisteredType)) { return num; } return 0; } } private readonly Dictionary> overrides = new Dictionary>(); [return: MaybeNull] public T GetAttribute(Type type, string member) where T : Attribute { if (overrides.TryGetValue(new AttributeKey(typeof(T), member), out List value)) { int num = 0; AttributeMapping attributeMapping = null; foreach (AttributeMapping item in value) { int num2 = item.Matches(type); if (num2 > num) { num = num2; attributeMapping = item; } } if (num > 0) { return (T)attributeMapping.Attribute; } } return null; } public void Add(Type type, string member, Attribute attribute) { AttributeMapping item = new AttributeMapping(type, attribute); AttributeKey key = new AttributeKey(attribute.GetType(), member); if (!overrides.TryGetValue(key, out List value)) { value = new List(); overrides.Add(key, value); } else if (value.Contains(item)) { throw new InvalidOperationException($"Attribute ({attribute}) already set for Type {type.FullName}, Member {member}"); } value.Add(item); } public YamlAttributeOverrides Clone() { YamlAttributeOverrides yamlAttributeOverrides = new YamlAttributeOverrides(); foreach (KeyValuePair> @override in overrides) { foreach (AttributeMapping item in @override.Value) { yamlAttributeOverrides.Add(item.RegisteredType, @override.Key.PropertyName, item.Attribute); } } return yamlAttributeOverrides; } public void Add(Expression> propertyAccessor, Attribute attribute) { PropertyInfo propertyInfo = propertyAccessor.AsProperty(); Add(typeof(TClass), propertyInfo.Name, attribute); } } internal sealed class YamlAttributeOverridesInspector : ReflectionTypeInspector { public sealed class OverridePropertyDescriptor : IPropertyDescriptor { private readonly IPropertyDescriptor baseDescriptor; private readonly YamlAttributeOverrides overrides; private readonly Type classType; public string Name => baseDescriptor.Name; public bool Required => baseDescriptor.Required; public bool AllowNulls => baseDescriptor.AllowNulls; public bool CanWrite => baseDescriptor.CanWrite; public Type Type => baseDescriptor.Type; public Type? TypeOverride { get { return baseDescriptor.TypeOverride; } set { baseDescriptor.TypeOverride = value; } } public Type? ConverterType => baseDescriptor.ConverterType; public int Order { get { return baseDescriptor.Order; } set { baseDescriptor.Order = value; } } public ScalarStyle ScalarStyle { get { return baseDescriptor.ScalarStyle; } set { baseDescriptor.ScalarStyle = value; } } public OverridePropertyDescriptor(IPropertyDescriptor baseDescriptor, YamlAttributeOverrides overrides, Type classType) { this.baseDescriptor = baseDescriptor; this.overrides = overrides; this.classType = classType; } public void Write(object target, object? value) { baseDescriptor.Write(target, value); } public T? GetCustomAttribute() where T : Attribute { T attribute = overrides.GetAttribute(classType, Name); return attribute ?? baseDescriptor.GetCustomAttribute(); } public IObjectDescriptor Read(object target) { return baseDescriptor.Read(target); } } private readonly ITypeInspector innerTypeDescriptor; private readonly YamlAttributeOverrides overrides; public YamlAttributeOverridesInspector(ITypeInspector innerTypeDescriptor, YamlAttributeOverrides overrides) { this.innerTypeDescriptor = innerTypeDescriptor; this.overrides = overrides; } public override IEnumerable GetProperties(Type type, object? container) { Type type2 = type; IEnumerable enumerable = innerTypeDescriptor.GetProperties(type2, container); if (overrides != null) { enumerable = enumerable.Select((Func)((IPropertyDescriptor p) => new OverridePropertyDescriptor(p, overrides, type2))); } return enumerable; } } internal sealed class YamlAttributesTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; public YamlAttributesTypeInspector(ITypeInspector innerTypeDescriptor) { this.innerTypeDescriptor = innerTypeDescriptor; } public override string GetEnumName(Type enumType, string name) { return innerTypeDescriptor.GetEnumName(enumType, name); } public override string GetEnumValue(object enumValue) { return innerTypeDescriptor.GetEnumValue(enumValue); } public override IEnumerable GetProperties(Type type, object? container) { return from p in (from p in innerTypeDescriptor.GetProperties(type, container) where p.GetCustomAttribute() == null select p).Select((Func)delegate(IPropertyDescriptor p) { PropertyDescriptor propertyDescriptor = new PropertyDescriptor(p); YamlMemberAttribute customAttribute = p.GetCustomAttribute(); if (customAttribute != null) { if (customAttribute.SerializeAs != null) { propertyDescriptor.TypeOverride = customAttribute.SerializeAs; } propertyDescriptor.Order = customAttribute.Order; propertyDescriptor.ScalarStyle = customAttribute.ScalarStyle; if (customAttribute.Alias != null) { propertyDescriptor.Name = customAttribute.Alias; } } return propertyDescriptor; }) orderby p.Order select p; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] internal sealed class YamlConverterAttribute : Attribute { public Type ConverterType { get; } public YamlConverterAttribute(Type converterType) { ConverterType = converterType; } } internal class YamlFormatter { public static YamlFormatter Default { get; } = new YamlFormatter(); public NumberFormatInfo NumberFormat { get; set; } = new NumberFormatInfo { CurrencyDecimalSeparator = ".", CurrencyGroupSeparator = "_", CurrencyGroupSizes = new int[1] { 3 }, CurrencySymbol = string.Empty, CurrencyDecimalDigits = 99, NumberDecimalSeparator = ".", NumberGroupSeparator = "_", NumberGroupSizes = new int[1] { 3 }, NumberDecimalDigits = 99, NaNSymbol = ".nan", PositiveInfinitySymbol = ".inf", NegativeInfinitySymbol = "-.inf" }; public virtual Func FormatEnum { get; set; } = delegate(object value, ITypeInspector typeInspector, INamingConvention enumNamingConvention) { string empty = string.Empty; empty = ((value != null) ? typeInspector.GetEnumValue(value) : string.Empty); return enumNamingConvention.Apply(empty); }; public virtual Func PotentiallyQuoteEnums { get; set; } = (object _) => true; public string FormatNumber(object number) { return Convert.ToString(number, NumberFormat); } public string FormatNumber(double number) { return number.ToString("G", NumberFormat); } public string FormatNumber(float number) { return number.ToString("G", NumberFormat); } public string FormatBoolean(object boolean) { if (!boolean.Equals(true)) { return "false"; } return "true"; } public string FormatDateTime(object dateTime) { return ((DateTime)dateTime).ToString("o", CultureInfo.InvariantCulture); } public string FormatTimeSpan(object timeSpan) { return ((TimeSpan)timeSpan).ToString(); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] internal sealed class YamlIgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] internal sealed class YamlMemberAttribute : Attribute { private DefaultValuesHandling? defaultValuesHandling; public string? Description { get; set; } public Type? SerializeAs { get; set; } public int Order { get; set; } public string? Alias { get; set; } public bool ApplyNamingConventions { get; set; } public ScalarStyle ScalarStyle { get; set; } public DefaultValuesHandling DefaultValuesHandling { get { return defaultValuesHandling.GetValueOrDefault(); } set { defaultValuesHandling = value; } } public bool IsDefaultValuesHandlingSpecified => defaultValuesHandling.HasValue; public YamlMemberAttribute() { ScalarStyle = ScalarStyle.Any; ApplyNamingConventions = true; } public YamlMemberAttribute(Type serializeAs) : this() { SerializeAs = serializeAs ?? throw new ArgumentNullException("serializeAs"); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, Inherited = false, AllowMultiple = true)] internal sealed class YamlSerializableAttribute : Attribute { public YamlSerializableAttribute() { } public YamlSerializableAttribute(Type serializableType) { } } [AttributeUsage(AttributeTargets.Class)] internal sealed class YamlStaticContextAttribute : Attribute { } } namespace YamlDotNet.Serialization.ValueDeserializers { internal sealed class AliasValueDeserializer : IValueDeserializer { private sealed class AliasState : Dictionary, IPostDeserializationCallback { public void OnDeserialization() { foreach (ValuePromise value in base.Values) { if (!value.HasValue) { YamlDotNet.Core.Events.AnchorAlias alias = value.Alias; Mark start = alias.Start; Mark end = alias.End; throw new AnchorNotFoundException(in start, in end, $"Anchor '{alias.Value}' not found"); } } } } private sealed class ValuePromise : IValuePromise { private object? value; public readonly YamlDotNet.Core.Events.AnchorAlias? Alias; public bool HasValue { get; private set; } public object? Value { get { if (!HasValue) { throw new InvalidOperationException("Value not set"); } return value; } set { if (HasValue) { throw new InvalidOperationException("Value already set"); } HasValue = true; this.value = value; this.ValueAvailable?.Invoke(value); } } public event Action? ValueAvailable; public ValuePromise(YamlDotNet.Core.Events.AnchorAlias alias) { Alias = alias; } public ValuePromise(object? value) { HasValue = true; this.value = value; } } private readonly IValueDeserializer innerDeserializer; public AliasValueDeserializer(IValueDeserializer innerDeserializer) { this.innerDeserializer = innerDeserializer ?? throw new ArgumentNullException("innerDeserializer"); } public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) { if (parser.TryConsume(out var @event)) { AliasState aliasState = state.Get(); if (!aliasState.TryGetValue(@event.Value, out ValuePromise value)) { Mark start = @event.Start; Mark end = @event.End; throw new AnchorNotFoundException(in start, in end, $"Alias ${@event.Value} cannot precede anchor declaration"); } if (!value.HasValue) { return value; } return value.Value; } AnchorName anchorName = AnchorName.Empty; if (parser.Accept(out var event2) && !event2.Anchor.IsEmpty) { anchorName = event2.Anchor; AliasState aliasState2 = state.Get(); if (!aliasState2.ContainsKey(anchorName)) { aliasState2[anchorName] = new ValuePromise(new YamlDotNet.Core.Events.AnchorAlias(anchorName)); } } object obj = innerDeserializer.DeserializeValue(parser, expectedType, state, nestedObjectDeserializer); if (!anchorName.IsEmpty) { AliasState aliasState3 = state.Get(); if (!aliasState3.TryGetValue(anchorName, out ValuePromise value2)) { aliasState3.Add(anchorName, new ValuePromise(obj)); } else if (!value2.HasValue) { value2.Value = obj; } else { aliasState3[anchorName] = new ValuePromise(obj); } } return obj; } } internal sealed class NodeValueDeserializer : IValueDeserializer { private readonly IList deserializers; private readonly IList typeResolvers; private readonly ITypeConverter typeConverter; private readonly INamingConvention enumNamingConvention; private readonly ITypeInspector typeInspector; public NodeValueDeserializer(IList deserializers, IList typeResolvers, ITypeConverter typeConverter, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { this.deserializers = deserializers ?? throw new ArgumentNullException("deserializers"); this.typeResolvers = typeResolvers ?? throw new ArgumentNullException("typeResolvers"); this.typeConverter = typeConverter ?? throw new ArgumentNullException("typeConverter"); this.enumNamingConvention = enumNamingConvention ?? throw new ArgumentNullException("enumNamingConvention"); this.typeInspector = typeInspector; } public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) { IParser parser2 = parser; SerializerState state2 = state; IValueDeserializer nestedObjectDeserializer2 = nestedObjectDeserializer; parser2.Accept(out var @event); Type typeFromEvent = GetTypeFromEvent(@event, expectedType); ObjectDeserializer rootDeserializer = (Type x) => DeserializeValue(parser2, x, state2, nestedObjectDeserializer2); Mark start; Mark end; try { foreach (INodeDeserializer deserializer in deserializers) { if (deserializer.Deserialize(parser2, typeFromEvent, (IParser r, Type t) => nestedObjectDeserializer2.DeserializeValue(r, t, state2, nestedObjectDeserializer2), out object value, rootDeserializer)) { return typeConverter.ChangeType(value, expectedType, enumNamingConvention, typeInspector); } } } catch (YamlException) { throw; } catch (Exception innerException) { start = @event?.Start ?? Mark.Empty; end = @event?.End ?? Mark.Empty; throw new YamlException(in start, in end, "Exception during deserialization", innerException); } start = @event?.Start ?? Mark.Empty; end = @event?.End ?? Mark.Empty; throw new YamlException(in start, in end, "No node deserializer was able to deserialize the node into type " + expectedType.AssemblyQualifiedName); } private Type GetTypeFromEvent(NodeEvent? nodeEvent, Type currentType) { foreach (INodeTypeResolver typeResolver in typeResolvers) { if (typeResolver.Resolve(nodeEvent, ref currentType)) { break; } } return currentType; } } } namespace YamlDotNet.Serialization.Utilities { internal interface IPostDeserializationCallback { void OnDeserialization(); } internal interface ITypeConverter { object? ChangeType(object? value, Type expectedType, INamingConvention enumNamingConvention, ITypeInspector typeInspector); } internal class NullTypeConverter : ITypeConverter { public object? ChangeType(object? value, Type expectedType, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { return value; } } internal sealed class ObjectAnchorCollection { private readonly Dictionary objectsByAnchor = new Dictionary(); private readonly Dictionary anchorsByObject = new Dictionary(); public object this[string anchor] { get { if (objectsByAnchor.TryGetValue(anchor, out object value)) { return value; } throw new AnchorNotFoundException("The anchor '" + anchor + "' does not exists"); } } public void Add(string anchor, object @object) { objectsByAnchor.Add(anchor, @object); if (@object != null) { anchorsByObject.Add(@object, anchor); } } public bool TryGetAnchor(object @object, [MaybeNullWhen(false)] out string? anchor) { return anchorsByObject.TryGetValue(@object, out anchor); } } internal class ReflectionTypeConverter : ITypeConverter { public object? ChangeType(object? value, Type expectedType, ITypeInspector typeInspector) { return ChangeType(value, expectedType, NullNamingConvention.Instance, typeInspector); } public object? ChangeType(object? value, Type expectedType, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { return TypeConverter.ChangeType(value, expectedType, enumNamingConvention, typeInspector); } } internal sealed class SerializerState : IDisposable { private readonly Dictionary items = new Dictionary(); public T Get() where T : class, new() { if (!items.TryGetValue(typeof(T), out object value)) { value = new T(); items.Add(typeof(T), value); } return (T)value; } public void OnDeserialization() { foreach (IPostDeserializationCallback item in items.Values.OfType()) { item.OnDeserialization(); } } public void Dispose() { foreach (IDisposable item in items.Values.OfType()) { item.Dispose(); } } } internal static class StringExtensions { private static string ToCamelOrPascalCase(string str, Func firstLetterTransform) { string text = Regex.Replace(str, "([_\\-])(?[a-z])", (Match match) => match.Groups["char"].Value.ToUpperInvariant(), RegexOptions.IgnoreCase); return firstLetterTransform(text[0]) + text.Substring(1); } public static string ToCamelCase(this string str) { return ToCamelOrPascalCase(str, char.ToLowerInvariant); } public static string ToPascalCase(this string str) { return ToCamelOrPascalCase(str, char.ToUpperInvariant); } public static string FromCamelCase(this string str, string separator) { string separator2 = separator; str = char.ToLower(str[0], CultureInfo.InvariantCulture) + str.Substring(1); str = Regex.Replace(str.ToCamelCase(), "(?[A-Z])", (Match match) => separator2 + match.Groups["char"].Value.ToLowerInvariant()); return str; } } internal static class TypeConverter { public static T ChangeType(object? value, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { return (T)ChangeType(value, typeof(T), enumNamingConvention, typeInspector); } public static object? ChangeType(object? value, Type destinationType, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { return ChangeType(value, destinationType, CultureInfo.InvariantCulture, enumNamingConvention, typeInspector); } public static object? ChangeType(object? value, Type destinationType, IFormatProvider provider, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider), enumNamingConvention, typeInspector); } public static object? ChangeType(object? value, Type destinationType, CultureInfo culture, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { if (value == null || value.IsDbNull()) { if (!destinationType.IsValueType()) { return null; } return Activator.CreateInstance(destinationType); } Type type = value.GetType(); if (destinationType == type || destinationType.IsAssignableFrom(type)) { return value; } if (destinationType.IsGenericType()) { Type genericTypeDefinition = destinationType.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(Nullable<>) || FsharpHelper.IsOptionType(genericTypeDefinition)) { Type destinationType2 = destinationType.GetGenericArguments()[0]; object obj = ChangeType(value, destinationType2, culture, enumNamingConvention, typeInspector); return Activator.CreateInstance(destinationType, obj); } } if (destinationType.IsEnum()) { object result = value; if (value is string value2) { string name = enumNamingConvention.Reverse(value2); name = typeInspector.GetEnumName(destinationType, name); result = Enum.Parse(destinationType, name, ignoreCase: true); } return result; } if (destinationType == typeof(bool)) { if ("0".Equals(value)) { return false; } if ("1".Equals(value)) { return true; } } System.ComponentModel.TypeConverter converter = TypeDescriptor.GetConverter(type); if (converter != null && converter.CanConvertTo(destinationType)) { return converter.ConvertTo(null, culture, value, destinationType); } System.ComponentModel.TypeConverter converter2 = TypeDescriptor.GetConverter(destinationType); if (converter2 != null && converter2.CanConvertFrom(type)) { return converter2.ConvertFrom(null, culture, value); } Type[] array = new Type[2] { type, destinationType }; foreach (Type type2 in array) { foreach (MethodInfo publicStaticMethod2 in type2.GetPublicStaticMethods()) { if (!publicStaticMethod2.IsSpecialName || (!(publicStaticMethod2.Name == "op_Implicit") && !(publicStaticMethod2.Name == "op_Explicit")) || !destinationType.IsAssignableFrom(publicStaticMethod2.ReturnParameter.ParameterType)) { continue; } System.Reflection.ParameterInfo[] parameters = publicStaticMethod2.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(type)) { try { return publicStaticMethod2.Invoke(null, new object[1] { value }); } catch (TargetInvocationException ex) { throw ex.InnerException; } } } } if (type == typeof(string)) { try { MethodInfo publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string), typeof(IFormatProvider)); if (publicStaticMethod != null) { return publicStaticMethod.Invoke(null, new object[2] { value, culture }); } publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string)); if (publicStaticMethod != null) { return publicStaticMethod.Invoke(null, new object[1] { value }); } } catch (TargetInvocationException ex2) { throw ex2.InnerException; } } if (destinationType == typeof(TimeSpan)) { return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture, enumNamingConvention, typeInspector), CultureInfo.InvariantCulture); } return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture); } public static void RegisterTypeConverter() where TConverter : System.ComponentModel.TypeConverter { if (!TypeDescriptor.GetAttributes(typeof(TConvertible)).OfType().Any((TypeConverterAttribute a) => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName)) { TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter))); } } } internal sealed class TypeConverterCache { private readonly IYamlTypeConverter[] typeConverters; private readonly ConcurrentDictionary cache = new ConcurrentDictionary(); public TypeConverterCache(IEnumerable? typeConverters) : this(typeConverters?.ToArray() ?? Array.Empty()) { } public TypeConverterCache(IYamlTypeConverter[] typeConverters) { this.typeConverters = typeConverters; } public bool TryGetConverterForType(Type type, [NotNullWhen(true)] out IYamlTypeConverter? typeConverter) { (bool, IYamlTypeConverter) orAdd = DictionaryExtensions.GetOrAdd(cache, type, (Type t, IYamlTypeConverter[] tc) => LookupTypeConverter(t, tc), typeConverters); typeConverter = orAdd.Item2; return orAdd.Item1; } public IYamlTypeConverter GetConverterByType(Type converter) { IYamlTypeConverter[] array = typeConverters; foreach (IYamlTypeConverter yamlTypeConverter in array) { if (yamlTypeConverter.GetType() == converter) { return yamlTypeConverter; } } throw new ArgumentException("IYamlTypeConverter of type " + converter.FullName + " not found", "converter"); } private static (bool HasMatch, IYamlTypeConverter? TypeConverter) LookupTypeConverter(Type type, IYamlTypeConverter[] typeConverters) { foreach (IYamlTypeConverter yamlTypeConverter in typeConverters) { if (yamlTypeConverter.Accepts(type)) { return (true, yamlTypeConverter); } } return (false, null); } } } namespace YamlDotNet.Serialization.TypeResolvers { internal sealed class DynamicTypeResolver : ITypeResolver { public Type Resolve(Type staticType, object? actualValue) { if (actualValue == null) { return staticType; } return actualValue.GetType(); } } internal class StaticTypeResolver : ITypeResolver { public virtual Type Resolve(Type staticType, object? actualValue) { if (actualValue != null) { if (actualValue.GetType().IsEnum) { return staticType; } switch (actualValue.GetType().GetTypeCode()) { case TypeCode.Boolean: return typeof(bool); case TypeCode.Char: return typeof(char); case TypeCode.SByte: return typeof(sbyte); case TypeCode.Byte: return typeof(byte); case TypeCode.Int16: return typeof(short); case TypeCode.UInt16: return typeof(ushort); case TypeCode.Int32: return typeof(int); case TypeCode.UInt32: return typeof(uint); case TypeCode.Int64: return typeof(long); case TypeCode.UInt64: return typeof(ulong); case TypeCode.Single: return typeof(float); case TypeCode.Double: return typeof(double); case TypeCode.Decimal: return typeof(decimal); case TypeCode.String: return typeof(string); case TypeCode.DateTime: return typeof(DateTime); } } return staticType; } } } namespace YamlDotNet.Serialization.TypeInspectors { internal class CachedTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; private readonly ConcurrentDictionary> cache = new ConcurrentDictionary>(); private readonly ConcurrentDictionary> enumNameCache = new ConcurrentDictionary>(); private readonly ConcurrentDictionary enumValueCache = new ConcurrentDictionary(); public CachedTypeInspector(ITypeInspector innerTypeDescriptor) { this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor"); } public override string GetEnumName(Type enumType, string name) { ConcurrentDictionary orAdd = enumNameCache.GetOrAdd(enumType, (Type _) => new ConcurrentDictionary()); return DictionaryExtensions.GetOrAdd(orAdd, name, delegate(string n, (Type enumType, ITypeInspector innerTypeDescriptor) context) { var (enumType2, typeInspector) = context; return typeInspector.GetEnumName(enumType2, n); }, (enumType, innerTypeDescriptor)); } public override string GetEnumValue(object enumValue) { return DictionaryExtensions.GetOrAdd(enumValueCache, enumValue, delegate(object _, (object enumValue, ITypeInspector innerTypeDescriptor) context) { var (enumValue2, typeInspector) = context; return typeInspector.GetEnumValue(enumValue2); }, (enumValue, innerTypeDescriptor)); } public override IEnumerable GetProperties(Type type, object? container) { return DictionaryExtensions.GetOrAdd(cache, type, delegate(Type t, (object container, ITypeInspector innerTypeDescriptor) context) { var (container2, typeInspector) = context; return typeInspector.GetProperties(t, container2).ToList(); }, (container, innerTypeDescriptor)); } } internal class CompositeTypeInspector : TypeInspectorSkeleton { private readonly IEnumerable typeInspectors; public CompositeTypeInspector(params ITypeInspector[] typeInspectors) : this((IEnumerable)typeInspectors) { } public CompositeTypeInspector(IEnumerable typeInspectors) { this.typeInspectors = typeInspectors?.ToList() ?? throw new ArgumentNullException("typeInspectors"); } public override string GetEnumName(Type enumType, string name) { foreach (ITypeInspector typeInspector in typeInspectors) { try { return typeInspector.GetEnumName(enumType, name); } catch { } } throw new ArgumentOutOfRangeException("enumType,name", "Name not found on enum type"); } public override string GetEnumValue(object enumValue) { if (enumValue == null) { throw new ArgumentNullException("enumValue"); } foreach (ITypeInspector typeInspector in typeInspectors) { try { return typeInspector.GetEnumValue(enumValue); } catch { } } throw new ArgumentOutOfRangeException("enumValue", $"Value not found for ({enumValue})"); } public override IEnumerable GetProperties(Type type, object? container) { Type type2 = type; object container2 = container; return typeInspectors.SelectMany((ITypeInspector i) => i.GetProperties(type2, container2)); } } internal class NamingConventionTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; private readonly INamingConvention namingConvention; public NamingConventionTypeInspector(ITypeInspector innerTypeDescriptor, INamingConvention namingConvention) { this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor"); this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention"); } public override string GetEnumName(Type enumType, string name) { return innerTypeDescriptor.GetEnumName(enumType, name); } public override string GetEnumValue(object enumValue) { return innerTypeDescriptor.GetEnumValue(enumValue); } public override IEnumerable GetProperties(Type type, object? container) { return innerTypeDescriptor.GetProperties(type, container).Select(delegate(IPropertyDescriptor p) { YamlMemberAttribute customAttribute = p.GetCustomAttribute(); return (customAttribute != null && !customAttribute.ApplyNamingConventions) ? p : new PropertyDescriptor(p) { Name = namingConvention.Apply(p.Name) }; }); } } internal class ReadableAndWritablePropertiesTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; public ReadableAndWritablePropertiesTypeInspector(ITypeInspector innerTypeDescriptor) { this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor"); } public override string GetEnumName(Type enumType, string name) { return innerTypeDescriptor.GetEnumName(enumType, name); } public override string GetEnumValue(object enumValue) { return innerTypeDescriptor.GetEnumValue(enumValue); } public override IEnumerable GetProperties(Type type, object? container) { return from p in innerTypeDescriptor.GetProperties(type, container) where p.CanWrite select p; } } internal class ReadableFieldsTypeInspector : ReflectionTypeInspector { protected class ReflectionFieldDescriptor : IPropertyDescriptor { private readonly FieldInfo fieldInfo; private readonly ITypeResolver typeResolver; public string Name => fieldInfo.Name; public bool Required => fieldInfo.IsRequired(); public Type Type => fieldInfo.FieldType; public Type? ConverterType { get; } public Type? TypeOverride { get; set; } public bool AllowNulls => fieldInfo.AcceptsNull(); public int Order { get; set; } public bool CanWrite => !fieldInfo.IsInitOnly; public ScalarStyle ScalarStyle { get; set; } public ReflectionFieldDescriptor(FieldInfo fieldInfo, ITypeResolver typeResolver) { this.fieldInfo = fieldInfo; this.typeResolver = typeResolver; YamlConverterAttribute customAttribute = fieldInfo.GetCustomAttribute(); if (customAttribute != null) { ConverterType = customAttribute.ConverterType; } ScalarStyle = ScalarStyle.Any; } public void Write(object target, object? value) { fieldInfo.SetValue(target, value); } public T? GetCustomAttribute() where T : Attribute { object[] customAttributes = fieldInfo.GetCustomAttributes(typeof(T), inherit: true); return (T)customAttributes.FirstOrDefault(); } public IObjectDescriptor Read(object target) { object value = fieldInfo.GetValue(target); Type type = TypeOverride ?? typeResolver.Resolve(Type, value); return new ObjectDescriptor(value, type, Type, ScalarStyle); } } private readonly ITypeResolver typeResolver; public ReadableFieldsTypeInspector(ITypeResolver typeResolver) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); } public override IEnumerable GetProperties(Type type, object? container) { return type.GetPublicFields().Select((Func)((FieldInfo p) => new ReflectionFieldDescriptor(p, typeResolver))); } } internal class ReadablePropertiesTypeInspector : ReflectionTypeInspector { protected class ReflectionPropertyDescriptor : IPropertyDescriptor { private readonly PropertyInfo propertyInfo; private readonly ITypeResolver typeResolver; public string Name => propertyInfo.Name; public bool Required => propertyInfo.IsRequired(); public Type Type => propertyInfo.PropertyType; public Type? TypeOverride { get; set; } public Type? ConverterType { get; set; } public bool AllowNulls => propertyInfo.AcceptsNull(); public int Order { get; set; } public bool CanWrite => propertyInfo.CanWrite; public ScalarStyle ScalarStyle { get; set; } public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver) { this.propertyInfo = propertyInfo ?? throw new ArgumentNullException("propertyInfo"); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); ScalarStyle = ScalarStyle.Any; YamlConverterAttribute customAttribute = propertyInfo.GetCustomAttribute(); if (customAttribute != null) { ConverterType = customAttribute.ConverterType; } } public void Write(object target, object? value) { propertyInfo.SetValue(target, value, null); } public T? GetCustomAttribute() where T : Attribute { Attribute[] allCustomAttributes = propertyInfo.GetAllCustomAttributes(); return (T)allCustomAttributes.FirstOrDefault(); } public IObjectDescriptor Read(object target) { object obj = propertyInfo.ReadValue(target); Type type = TypeOverride ?? typeResolver.Resolve(Type, obj); return new ObjectDescriptor(obj, type, Type, ScalarStyle); } } private readonly ITypeResolver typeResolver; private readonly bool includeNonPublicProperties; public ReadablePropertiesTypeInspector(ITypeResolver typeResolver) : this(typeResolver, includeNonPublicProperties: false) { } public ReadablePropertiesTypeInspector(ITypeResolver typeResolver, bool includeNonPublicProperties) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); this.includeNonPublicProperties = includeNonPublicProperties; } private static bool IsValidProperty(PropertyInfo property) { if (property.CanRead) { return property.GetGetMethod(nonPublic: true).GetParameters().Length == 0; } return false; } public override IEnumerable GetProperties(Type type, object? container) { return type.GetProperties(includeNonPublicProperties).Where(IsValidProperty).Select((Func)((PropertyInfo p) => new ReflectionPropertyDescriptor(p, typeResolver))); } } internal abstract class ReflectionTypeInspector : TypeInspectorSkeleton { public override string GetEnumName(Type enumType, string name) { return name; } public override string GetEnumValue(object enumValue) { if (enumValue == null) { return string.Empty; } return enumValue.ToString(); } } internal abstract class TypeInspectorSkeleton : ITypeInspector { public abstract string GetEnumName(Type enumType, string name); public abstract string GetEnumValue(object enumValue); public abstract IEnumerable GetProperties(Type type, object? container); public IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched, bool caseInsensitivePropertyMatching) { string name2 = name; IEnumerable enumerable = ((!caseInsensitivePropertyMatching) ? (from p in GetProperties(type, container) where p.Name == name2 select p) : (from p in GetProperties(type, container) where p.Name.Equals(name2, StringComparison.OrdinalIgnoreCase) select p)); using IEnumerator enumerator = enumerable.GetEnumerator(); if (!enumerator.MoveNext()) { if (ignoreUnmatched) { return null; } throw new SerializationException("Property '" + name2 + "' not found on type '" + type.FullName + "'."); } IPropertyDescriptor current = enumerator.Current; if (enumerator.MoveNext()) { throw new SerializationException("Multiple properties with the name/alias '" + name2 + "' already exists on type '" + type.FullName + "', maybe you're misusing YamlAlias or maybe you are using the wrong naming convention? The matching properties are: " + string.Join(", ", enumerable.Select((IPropertyDescriptor p) => p.Name).ToArray())); } return current; } } internal class WritablePropertiesTypeInspector : ReflectionTypeInspector { protected class ReflectionPropertyDescriptor : IPropertyDescriptor { private readonly PropertyInfo propertyInfo; private readonly ITypeResolver typeResolver; public string Name => propertyInfo.Name; public bool Required => propertyInfo.IsRequired(); public Type Type => propertyInfo.PropertyType; public Type? TypeOverride { get; set; } public Type? ConverterType { get; set; } public bool AllowNulls => propertyInfo.AcceptsNull(); public int Order { get; set; } public bool CanWrite => propertyInfo.CanWrite; public ScalarStyle ScalarStyle { get; set; } public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver) { this.propertyInfo = propertyInfo ?? throw new ArgumentNullException("propertyInfo"); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); ScalarStyle = ScalarStyle.Any; YamlConverterAttribute customAttribute = propertyInfo.GetCustomAttribute(); if (customAttribute != null) { ConverterType = customAttribute.ConverterType; } } public void Write(object target, object? value) { propertyInfo.SetValue(target, value, null); } public T? GetCustomAttribute() where T : Attribute { Attribute[] allCustomAttributes = propertyInfo.GetAllCustomAttributes(); return (T)allCustomAttributes.FirstOrDefault(); } public IObjectDescriptor Read(object target) { object obj = propertyInfo.ReadValue(target); Type type = TypeOverride ?? typeResolver.Resolve(Type, obj); return new ObjectDescriptor(obj, type, Type, ScalarStyle); } } private readonly ITypeResolver typeResolver; private readonly bool includeNonPublicProperties; public WritablePropertiesTypeInspector(ITypeResolver typeResolver) : this(typeResolver, includeNonPublicProperties: false) { } public WritablePropertiesTypeInspector(ITypeResolver typeResolver, bool includeNonPublicProperties) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); this.includeNonPublicProperties = includeNonPublicProperties; } private static bool IsValidProperty(PropertyInfo property) { if (property.CanWrite) { return property.GetSetMethod(nonPublic: true).GetParameters().Length == 1; } return false; } public override IEnumerable GetProperties(Type type, object? container) { return type.GetProperties(includeNonPublicProperties).Where(IsValidProperty).Select((Func)((PropertyInfo p) => new ReflectionPropertyDescriptor(p, typeResolver))) .ToArray(); } } } namespace YamlDotNet.Serialization.Schemas { internal sealed class FailsafeSchema { public static class Tags { public static readonly TagName Map = new TagName("tag:yaml.org,2002:map"); public static readonly TagName Seq = new TagName("tag:yaml.org,2002:seq"); public static readonly TagName Str = new TagName("tag:yaml.org,2002:str"); } } internal sealed class JsonSchema { public static class Tags { public static readonly TagName Null = new TagName("tag:yaml.org,2002:null"); public static readonly TagName Bool = new TagName("tag:yaml.org,2002:bool"); public static readonly TagName Int = new TagName("tag:yaml.org,2002:int"); public static readonly TagName Float = new TagName("tag:yaml.org,2002:float"); } } internal sealed class CoreSchema { public static class Tags { } } internal sealed class DefaultSchema { public static class Tags { public static readonly TagName Timestamp = new TagName("tag:yaml.org,2002:timestamp"); } } } namespace YamlDotNet.Serialization.ObjectGraphVisitors { internal sealed class AnchorAssigner : PreProcessingPhaseObjectGraphVisitorSkeleton, IAliasProvider { private class AnchorAssignment { public AnchorName Anchor; } private readonly Dictionary assignments = new Dictionary(); private uint nextId; public AnchorAssigner(IEnumerable typeConverters) : base(typeConverters) { } protected override bool Enter(IObjectDescriptor value, ObjectSerializer serializer) { if (value.Value != null && assignments.TryGetValue(value.Value, out AnchorAssignment value2)) { if (value2.Anchor.IsEmpty) { value2.Anchor = new AnchorName("o" + nextId.ToString(CultureInfo.InvariantCulture)); nextId++; } return false; } return true; } protected override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, ObjectSerializer serializer) { return true; } protected override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, ObjectSerializer serializer) { return true; } protected override void VisitScalar(IObjectDescriptor scalar, ObjectSerializer serializer) { } protected override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, ObjectSerializer serializer) { VisitObject(mapping); } protected override void VisitMappingEnd(IObjectDescriptor mapping, ObjectSerializer serializer) { } protected override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, ObjectSerializer serializer) { VisitObject(sequence); } protected override void VisitSequenceEnd(IObjectDescriptor sequence, ObjectSerializer serializer) { } private void VisitObject(IObjectDescriptor value) { if (value.Value != null) { assignments.Add(value.Value, new AnchorAssignment()); } } AnchorName IAliasProvider.GetAlias(object target) { if (target != null && assignments.TryGetValue(target, out AnchorAssignment value)) { return value.Anchor; } return AnchorName.Empty; } } internal sealed class AnchorAssigningObjectGraphVisitor : ChainedObjectGraphVisitor { private readonly IEventEmitter eventEmitter; private readonly IAliasProvider aliasProvider; private readonly HashSet emittedAliases = new HashSet(); public AnchorAssigningObjectGraphVisitor(IObjectGraphVisitor nextVisitor, IEventEmitter eventEmitter, IAliasProvider aliasProvider) : base(nextVisitor) { this.eventEmitter = eventEmitter; this.aliasProvider = aliasProvider; } public override bool Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { if (value.Value != null) { AnchorName alias = aliasProvider.GetAlias(value.Value); if (!alias.IsEmpty && !emittedAliases.Add(alias)) { AliasEventInfo aliasEventInfo = new AliasEventInfo(value, alias); eventEmitter.Emit(aliasEventInfo, context); return aliasEventInfo.NeedsExpansion; } } return base.Enter(propertyDescriptor, value, context, serializer); } public override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, IEmitter context, ObjectSerializer serializer) { AnchorName alias = aliasProvider.GetAlias(mapping.NonNullValue()); eventEmitter.Emit(new MappingStartEventInfo(mapping) { Anchor = alias }, context); } public override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, IEmitter context, ObjectSerializer serializer) { AnchorName alias = aliasProvider.GetAlias(sequence.NonNullValue()); eventEmitter.Emit(new SequenceStartEventInfo(sequence) { Anchor = alias }, context); } public override void VisitScalar(IObjectDescriptor scalar, IEmitter context, ObjectSerializer serializer) { ScalarEventInfo scalarEventInfo = new ScalarEventInfo(scalar); if (scalar.Value != null) { scalarEventInfo.Anchor = aliasProvider.GetAlias(scalar.Value); } eventEmitter.Emit(scalarEventInfo, context); } } internal abstract class ChainedObjectGraphVisitor : IObjectGraphVisitor { private readonly IObjectGraphVisitor nextVisitor; protected ChainedObjectGraphVisitor(IObjectGraphVisitor nextVisitor) { this.nextVisitor = nextVisitor; } public virtual bool Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { return nextVisitor.Enter(propertyDescriptor, value, context, serializer); } public virtual bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { return nextVisitor.EnterMapping(key, value, context, serializer); } public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { return nextVisitor.EnterMapping(key, value, context, serializer); } public virtual void VisitScalar(IObjectDescriptor scalar, IEmitter context, ObjectSerializer serializer) { nextVisitor.VisitScalar(scalar, context, serializer); } public virtual void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, IEmitter context, ObjectSerializer serializer) { nextVisitor.VisitMappingStart(mapping, keyType, valueType, context, serializer); } public virtual void VisitMappingEnd(IObjectDescriptor mapping, IEmitter context, ObjectSerializer serializer) { nextVisitor.VisitMappingEnd(mapping, context, serializer); } public virtual void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, IEmitter context, ObjectSerializer serializer) { nextVisitor.VisitSequenceStart(sequence, elementType, context, serializer); } public virtual void VisitSequenceEnd(IObjectDescriptor sequence, IEmitter context, ObjectSerializer serializer) { nextVisitor.VisitSequenceEnd(sequence, context, serializer); } } internal sealed class CommentsObjectGraphVisitor : ChainedObjectGraphVisitor { public CommentsObjectGraphVisitor(IObjectGraphVisitor nextVisitor) : base(nextVisitor) { } public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { YamlMemberAttribute customAttribute = key.GetCustomAttribute(); if (customAttribute != null && customAttribute.Description != null) { context.Emit(new YamlDotNet.Core.Events.Comment(customAttribute.Description, isInline: false)); } return base.EnterMapping(key, value, context, serializer); } } internal sealed class CustomSerializationObjectGraphVisitor : ChainedObjectGraphVisitor { private readonly TypeConverterCache typeConverters; private readonly ObjectSerializer nestedObjectSerializer; public CustomSerializationObjectGraphVisitor(IObjectGraphVisitor nextVisitor, IEnumerable typeConverters, ObjectSerializer nestedObjectSerializer) : base(nextVisitor) { this.typeConverters = new TypeConverterCache(typeConverters); this.nestedObjectSerializer = nestedObjectSerializer; } public override bool Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { if (propertyDescriptor?.ConverterType != null) { IYamlTypeConverter converterByType = typeConverters.GetConverterByType(propertyDescriptor.ConverterType); converterByType.WriteYaml(context, value.Value, value.Type, serializer); return false; } if (typeConverters.TryGetConverterForType(value.Type, out IYamlTypeConverter typeConverter)) { typeConverter.WriteYaml(context, value.Value, value.Type, serializer); return false; } if (value.Value is IYamlConvertible yamlConvertible) { yamlConvertible.Write(context, nestedObjectSerializer); return false; } if (value.Value is IYamlSerializable yamlSerializable) { yamlSerializable.WriteYaml(context); return false; } return base.Enter(propertyDescriptor, value, context, serializer); } } internal sealed class DefaultExclusiveObjectGraphVisitor : ChainedObjectGraphVisitor { public DefaultExclusiveObjectGraphVisitor(IObjectGraphVisitor nextVisitor) : base(nextVisitor) { } private static object? GetDefault(Type type) { if (!type.IsValueType()) { return null; } return Activator.CreateInstance(type); } public override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { if (!object.Equals(value.Value, GetDefault(value.Type))) { return base.EnterMapping(key, value, context, serializer); } return false; } public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { DefaultValueAttribute customAttribute = key.GetCustomAttribute(); object objB = ((customAttribute != null) ? customAttribute.Value : GetDefault(key.Type)); if (!object.Equals(value.Value, objB)) { return base.EnterMapping(key, value, context, serializer); } return false; } } internal sealed class DefaultValuesObjectGraphVisitor : ChainedObjectGraphVisitor { private readonly DefaultValuesHandling handling; private readonly IObjectFactory factory; public DefaultValuesObjectGraphVisitor(DefaultValuesHandling handling, IObjectGraphVisitor nextVisitor, IObjectFactory factory) : base(nextVisitor) { this.handling = handling; this.factory = factory; } private object? GetDefault(Type type) { return factory.CreatePrimitive(type); } public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { DefaultValuesHandling defaultValuesHandling = handling; YamlMemberAttribute customAttribute = key.GetCustomAttribute(); if (customAttribute != null && customAttribute.IsDefaultValuesHandlingSpecified) { defaultValuesHandling = customAttribute.DefaultValuesHandling; } if ((defaultValuesHandling & DefaultValuesHandling.OmitNull) != 0 && value.Value == null) { return false; } if ((defaultValuesHandling & DefaultValuesHandling.OmitEmptyCollections) != 0 && value.Value is IEnumerable enumerable) { IEnumerator enumerator = enumerable.GetEnumerator(); bool flag = enumerator.MoveNext(); if (enumerator is IDisposable disposable) { disposable.Dispose(); } if (!flag) { return false; } } if ((defaultValuesHandling & DefaultValuesHandling.OmitDefaults) != 0) { object objB = key.GetCustomAttribute()?.Value ?? GetDefault(key.Type); if (object.Equals(value.Value, objB)) { return false; } } return base.EnterMapping(key, value, context, serializer); } } internal sealed class EmittingObjectGraphVisitor : IObjectGraphVisitor { private readonly IEventEmitter eventEmitter; public EmittingObjectGraphVisitor(IEventEmitter eventEmitter) { this.eventEmitter = eventEmitter; } bool IObjectGraphVisitor.Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { return true; } bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { return true; } bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context, ObjectSerializer serializer) { return true; } void IObjectGraphVisitor.VisitScalar(IObjectDescriptor scalar, IEmitter context, ObjectSerializer serializer) { eventEmitter.Emit(new ScalarEventInfo(scalar), context); } void IObjectGraphVisitor.VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, IEmitter context, ObjectSerializer serializer) { eventEmitter.Emit(new MappingStartEventInfo(mapping), context); } void IObjectGraphVisitor.VisitMappingEnd(IObjectDescriptor mapping, IEmitter context, ObjectSerializer serializer) { eventEmitter.Emit(new MappingEndEventInfo(mapping), context); } void IObjectGraphVisitor.VisitSequenceStart(IObjectDescriptor sequence, Type elementType, IEmitter context, ObjectSerializer serializer) { eventEmitter.Emit(new SequenceStartEventInfo(sequence), context); } void IObjectGraphVisitor.VisitSequenceEnd(IObjectDescriptor sequence, IEmitter context, ObjectSerializer serializer) { eventEmitter.Emit(new SequenceEndEventInfo(sequence), context); } } internal abstract class PreProcessingPhaseObjectGraphVisitorSkeleton : IObjectGraphVisitor { protected readonly IEnumerable typeConverters; private readonly TypeConverterCache typeConverterCache; public PreProcessingPhaseObjectGraphVisitorSkeleton(IEnumerable typeConverters) { typeConverterCache = new TypeConverterCache((IYamlTypeConverter[])(this.typeConverters = typeConverters?.ToArray() ?? Array.Empty())); } bool IObjectGraphVisitor.Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, Nothing context, ObjectSerializer serializer) { if (typeConverterCache.TryGetConverterForType(value.Type, out IYamlTypeConverter _)) { return false; } if (value.Value is IYamlConvertible) { return false; } if (value.Value is IYamlSerializable) { return false; } return Enter(value, serializer); } bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, Nothing context, ObjectSerializer serializer) { return EnterMapping(key, value, serializer); } bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor value, Nothing context, ObjectSerializer serializer) { return EnterMapping(key, value, serializer); } void IObjectGraphVisitor.VisitMappingEnd(IObjectDescriptor mapping, Nothing context, ObjectSerializer serializer) { VisitMappingEnd(mapping, serializer); } void IObjectGraphVisitor.VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, Nothing context, ObjectSerializer serializer) { VisitMappingStart(mapping, keyType, valueType, serializer); } void IObjectGraphVisitor.VisitScalar(IObjectDescriptor scalar, Nothing context, ObjectSerializer serializer) { VisitScalar(scalar, serializer); } void IObjectGraphVisitor.VisitSequenceEnd(IObjectDescriptor sequence, Nothing context, ObjectSerializer serializer) { VisitSequenceEnd(sequence, serializer); } void IObjectGraphVisitor.VisitSequenceStart(IObjectDescriptor sequence, Type elementType, Nothing context, ObjectSerializer serializer) { VisitSequenceStart(sequence, elementType, serializer); } protected abstract bool Enter(IObjectDescriptor value, ObjectSerializer serializer); protected abstract bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, ObjectSerializer serializer); protected abstract bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, ObjectSerializer serializer); protected abstract void VisitMappingEnd(IObjectDescriptor mapping, ObjectSerializer serializer); protected abstract void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, ObjectSerializer serializer); protected abstract void VisitScalar(IObjectDescriptor scalar, ObjectSerializer serializer); protected abstract void VisitSequenceEnd(IObjectDescriptor sequence, ObjectSerializer serializer); protected abstract void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, ObjectSerializer serializer); } } namespace YamlDotNet.Serialization.ObjectGraphTraversalStrategies { internal class FullObjectGraphTraversalStrategy : IObjectGraphTraversalStrategy { protected readonly struct ObjectPathSegment { public readonly object Name; public readonly IObjectDescriptor Value; public ObjectPathSegment(object name, IObjectDescriptor value) { Name = name; Value = value; } } private readonly int maxRecursion; private readonly ITypeInspector typeDescriptor; private readonly ITypeResolver typeResolver; private readonly INamingConvention namingConvention; private readonly IObjectFactory objectFactory; public FullObjectGraphTraversalStrategy(ITypeInspector typeDescriptor, ITypeResolver typeResolver, int maxRecursion, INamingConvention namingConvention, IObjectFactory objectFactory) { if (maxRecursion <= 0) { throw new ArgumentOutOfRangeException("maxRecursion", maxRecursion, "maxRecursion must be greater than 1"); } this.typeDescriptor = typeDescriptor ?? throw new ArgumentNullException("typeDescriptor"); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); this.maxRecursion = maxRecursion; this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention"); this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory"); } void IObjectGraphTraversalStrategy.Traverse(IObjectDescriptor graph, IObjectGraphVisitor visitor, TContext context, ObjectSerializer serializer) { Traverse(null, "", graph, visitor, context, new Stack(maxRecursion), serializer); } protected virtual void Traverse(IPropertyDescriptor? propertyDescriptor, object name, IObjectDescriptor value, IObjectGraphVisitor visitor, TContext context, Stack path, ObjectSerializer serializer) { if (path.Count >= maxRecursion) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Too much recursion when traversing the object graph."); stringBuilder.AppendLine("The path to reach this recursion was:"); Stack> stack = new Stack>(path.Count); int num = 0; foreach (ObjectPathSegment item in path) { string text = item.Name?.ToString() ?? string.Empty; num = Math.Max(num, text.Length); stack.Push(new KeyValuePair(text, item.Value.Type.FullName)); } foreach (KeyValuePair item2 in stack) { stringBuilder.Append(" -> ").Append(item2.Key.PadRight(num)).Append(" [") .Append(item2.Value) .AppendLine("]"); } throw new MaximumRecursionLevelReachedException(stringBuilder.ToString()); } if (!visitor.Enter(propertyDescriptor, value, context, serializer)) { return; } path.Push(new ObjectPathSegment(name, value)); try { TypeCode typeCode = value.Type.GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: visitor.VisitScalar(value, context, serializer); return; case TypeCode.Empty: throw new NotSupportedException($"TypeCode.{typeCode} is not supported."); } if (value.IsDbNull()) { visitor.VisitScalar(new ObjectDescriptor(null, typeof(object), typeof(object)), context, serializer); } if (value.Value == null || value.Type == typeof(TimeSpan)) { visitor.VisitScalar(value, context, serializer); return; } Type underlyingType = Nullable.GetUnderlyingType(value.Type); Type type = underlyingType ?? FsharpHelper.GetOptionUnderlyingType(value.Type); object obj = ((type != null) ? FsharpHelper.GetValue(value) : null); if (underlyingType != null) { Traverse(propertyDescriptor, "Value", new ObjectDescriptor(value.Value, underlyingType, value.Type, value.ScalarStyle), visitor, context, path, serializer); } else if (type != null && obj != null) { Traverse(propertyDescriptor, "Value", new ObjectDescriptor(FsharpHelper.GetValue(value), type, value.Type, value.ScalarStyle), visitor, context, path, serializer); } else { TraverseObject(propertyDescriptor, value, visitor, context, path, serializer); } } finally { path.Pop(); } } protected virtual void TraverseObject(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, IObjectGraphVisitor visitor, TContext context, Stack path, ObjectSerializer serializer) { IDictionary dictionary; Type[] genericArguments; if (typeof(IDictionary).IsAssignableFrom(value.Type)) { TraverseDictionary(propertyDescriptor, value, visitor, typeof(object), typeof(object), context, path, serializer); } else if (objectFactory.GetDictionary(value, out dictionary, out genericArguments)) { TraverseDictionary(propertyDescriptor, new ObjectDescriptor(dictionary, value.Type, value.StaticType, value.ScalarStyle), visitor, genericArguments[0], genericArguments[1], context, path, serializer); } else if (typeof(IEnumerable).IsAssignableFrom(value.Type)) { TraverseList(propertyDescriptor, value, visitor, context, path, serializer); } else { TraverseProperties(value, visitor, context, path, serializer); } } protected virtual void TraverseDictionary(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor dictionary, IObjectGraphVisitor visitor, Type keyType, Type valueType, TContext context, Stack path, ObjectSerializer serializer) { visitor.VisitMappingStart(dictionary, keyType, valueType, context, serializer); bool flag = dictionary.Type.FullName.Equals("System.Dynamic.ExpandoObject"); foreach (DictionaryEntry? item in (IDictionary)dictionary.NonNullValue()) { DictionaryEntry value = item.Value; object obj = (flag ? namingConvention.Apply(value.Key.ToString()) : value.Key); ObjectDescriptor objectDescriptor = GetObjectDescriptor(obj, keyType); ObjectDescriptor objectDescriptor2 = GetObjectDescriptor(value.Value, valueType); if (visitor.EnterMapping(objectDescriptor, objectDescriptor2, context, serializer)) { Traverse(propertyDescriptor, obj, objectDescriptor, visitor, context, path, serializer); Traverse(propertyDescriptor, obj, objectDescriptor2, visitor, context, path, serializer); } } visitor.VisitMappingEnd(dictionary, context, serializer); } private void TraverseList(IPropertyDescriptor propertyDescriptor, IObjectDescriptor value, IObjectGraphVisitor visitor, TContext context, Stack path, ObjectSerializer serializer) { Type valueType = objectFactory.GetValueType(value.Type); visitor.VisitSequenceStart(value, valueType, context, serializer); int num = 0; foreach (object item in (IEnumerable)value.NonNullValue()) { Traverse(propertyDescriptor, num, GetObjectDescriptor(item, valueType), visitor, context, path, serializer); num++; } visitor.VisitSequenceEnd(value, context, serializer); } protected virtual void TraverseProperties(IObjectDescriptor value, IObjectGraphVisitor visitor, TContext context, Stack path, ObjectSerializer serializer) { if (context.GetType() != typeof(Nothing)) { objectFactory.ExecuteOnSerializing(value.Value); } visitor.VisitMappingStart(value, typeof(string), typeof(object), context, serializer); object obj = value.NonNullValue(); foreach (IPropertyDescriptor property in typeDescriptor.GetProperties(value.Type, obj)) { IObjectDescriptor value2 = property.Read(obj); if (visitor.EnterMapping(property, value2, context, serializer)) { Traverse(null, property.Name, new ObjectDescriptor(property.Name, typeof(string), typeof(string), ScalarStyle.Plain), visitor, context, path, serializer); Traverse(property, property.Name, value2, visitor, context, path, serializer); } } visitor.VisitMappingEnd(value, context, serializer); if (context.GetType() != typeof(Nothing)) { objectFactory.ExecuteOnSerialized(value.Value); } } private ObjectDescriptor GetObjectDescriptor(object? value, Type staticType) { return new ObjectDescriptor(value, typeResolver.Resolve(staticType, value), staticType); } } internal class RoundtripObjectGraphTraversalStrategy : FullObjectGraphTraversalStrategy { private readonly TypeConverterCache converters; private readonly Settings settings; public RoundtripObjectGraphTraversalStrategy(IEnumerable converters, ITypeInspector typeDescriptor, ITypeResolver typeResolver, int maxRecursion, INamingConvention namingConvention, Settings settings, IObjectFactory factory) : base(typeDescriptor, typeResolver, maxRecursion, namingConvention, factory) { this.converters = new TypeConverterCache(converters); this.settings = settings; } protected override void TraverseProperties(IObjectDescriptor value, IObjectGraphVisitor visitor, TContext context, Stack path, ObjectSerializer serializer) { if (!value.Type.HasDefaultConstructor(settings.AllowPrivateConstructors) && !converters.TryGetConverterForType(value.Type, out IYamlTypeConverter _)) { throw new InvalidOperationException($"Type '{value.Type}' cannot be deserialized because it does not have a default constructor or a type converter."); } base.TraverseProperties(value, visitor, context, path, serializer); } } } namespace YamlDotNet.Serialization.ObjectFactories { internal class DefaultObjectFactory : ObjectFactoryBase { private readonly Dictionary> stateMethods = new Dictionary> { { typeof(YamlDotNet.Serialization.Callbacks.OnDeserializedAttribute), new ConcurrentDictionary() }, { typeof(YamlDotNet.Serialization.Callbacks.OnDeserializingAttribute), new ConcurrentDictionary() }, { typeof(YamlDotNet.Serialization.Callbacks.OnSerializedAttribute), new ConcurrentDictionary() }, { typeof(YamlDotNet.Serialization.Callbacks.OnSerializingAttribute), new ConcurrentDictionary() } }; private readonly Dictionary defaultGenericInterfaceImplementations = new Dictionary { { typeof(IEnumerable<>), typeof(List<>) }, { typeof(ICollection<>), typeof(List<>) }, { typeof(IList<>), typeof(List<>) }, { typeof(IDictionary<, >), typeof(Dictionary<, >) } }; private readonly Dictionary defaultNonGenericInterfaceImplementations = new Dictionary { { typeof(IEnumerable), typeof(List) }, { typeof(ICollection), typeof(List) }, { typeof(IList), typeof(List) }, { typeof(IDictionary), typeof(Dictionary) } }; private readonly Settings settings; public DefaultObjectFactory() : this(new Dictionary(), new Settings()) { } public DefaultObjectFactory(IDictionary mappings) : this(mappings, new Settings()) { } public DefaultObjectFactory(IDictionary mappings, Settings settings) { foreach (KeyValuePair mapping in mappings) { if (!mapping.Key.IsAssignableFrom(mapping.Value)) { throw new InvalidOperationException($"Type '{mapping.Value}' does not implement type '{mapping.Key}'."); } defaultNonGenericInterfaceImplementations.Add(mapping.Key, mapping.Value); } this.settings = settings; } public override object Create(Type type) { if (type.IsInterface()) { Type value2; if (type.IsGenericType()) { if (defaultGenericInterfaceImplementations.TryGetValue(type.GetGenericTypeDefinition(), out Type value)) { type = value.MakeGenericType(type.GetGenericArguments()); } } else if (defaultNonGenericInterfaceImplementations.TryGetValue(type, out value2)) { type = value2; } } try { return Activator.CreateInstance(type, settings.AllowPrivateConstructors); } catch (Exception innerException) { string message = "Failed to create an instance of type '" + type.FullName + "'."; throw new InvalidOperationException(message, innerException); } } public override void ExecuteOnDeserialized(object value) { ExecuteState(typeof(YamlDotNet.Serialization.Callbacks.OnDeserializedAttribute), value); } public override void ExecuteOnDeserializing(object value) { ExecuteState(typeof(YamlDotNet.Serialization.Callbacks.OnDeserializingAttribute), value); } public override void ExecuteOnSerialized(object value) { ExecuteState(typeof(YamlDotNet.Serialization.Callbacks.OnSerializedAttribute), value); } public override void ExecuteOnSerializing(object value) { ExecuteState(typeof(YamlDotNet.Serialization.Callbacks.OnSerializingAttribute), value); } private void ExecuteState(Type attributeType, object value) { if (value != null) { Type type = value.GetType(); MethodInfo[] array = GetStateMethods(attributeType, type); MethodInfo[] array2 = array; foreach (MethodInfo methodInfo in array2) { methodInfo.Invoke(value, null); } } } private MethodInfo[] GetStateMethods(Type attributeType, Type valueType) { Type attributeType2 = attributeType; ConcurrentDictionary concurrentDictionary = stateMethods[attributeType2]; return concurrentDictionary.GetOrAdd(valueType, delegate(Type type) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return methods.Where((MethodInfo x) => x.GetCustomAttributes(attributeType2, inherit: true).Length != 0).ToArray(); }); } } internal sealed class LambdaObjectFactory : ObjectFactoryBase { private readonly Func factory; public LambdaObjectFactory(Func factory) { this.factory = factory ?? throw new ArgumentNullException("factory"); } public override object Create(Type type) { return factory(type); } } internal abstract class ObjectFactoryBase : IObjectFactory { public abstract object Create(Type type); public virtual object? CreatePrimitive(Type type) { if (!type.IsValueType()) { return null; } return Activator.CreateInstance(type); } public virtual void ExecuteOnDeserialized(object value) { } public virtual void ExecuteOnDeserializing(object value) { } public virtual void ExecuteOnSerialized(object value) { } public virtual void ExecuteOnSerializing(object value) { } public virtual bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments) { Type implementationOfOpenGenericInterface = descriptor.Type.GetImplementationOfOpenGenericInterface(typeof(IDictionary<, >)); if (implementationOfOpenGenericInterface != null) { genericArguments = implementationOfOpenGenericInterface.GetGenericArguments(); object obj = Activator.CreateInstance(typeof(GenericDictionaryToNonGenericAdapter<, >).MakeGenericType(genericArguments), descriptor.Value); dictionary = obj as IDictionary; return true; } genericArguments = null; dictionary = null; return false; } public virtual Type GetValueType(Type type) { Type implementationOfOpenGenericInterface = type.GetImplementationOfOpenGenericInterface(typeof(IEnumerable<>)); return (implementationOfOpenGenericInterface != null) ? implementationOfOpenGenericInterface.GetGenericArguments()[0] : typeof(object); } } internal abstract class StaticObjectFactory : IObjectFactory { public abstract object Create(Type type); public abstract Array CreateArray(Type type, int count); public abstract bool IsDictionary(Type type); public abstract bool IsArray(Type type); public abstract bool IsList(Type type); public abstract Type GetKeyType(Type type); public abstract Type GetValueType(Type type); public virtual object? CreatePrimitive(Type type) { return Type.GetTypeCode(type) switch { TypeCode.Boolean => false, TypeCode.Byte => (byte)0, TypeCode.Int16 => (short)0, TypeCode.Int32 => 0, TypeCode.Int64 => 0L, TypeCode.SByte => (sbyte)0, TypeCode.UInt16 => (ushort)0, TypeCode.UInt32 => 0u, TypeCode.UInt64 => 0uL, TypeCode.Single => 0f, TypeCode.Double => 0.0, TypeCode.Decimal => 0m, TypeCode.Char => '\0', TypeCode.DateTime => default(DateTime), _ => null, }; } public bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments) { dictionary = null; genericArguments = null; return false; } public abstract void ExecuteOnDeserializing(object value); public abstract void ExecuteOnDeserialized(object value); public abstract void ExecuteOnSerializing(object value); public abstract void ExecuteOnSerialized(object value); } } namespace YamlDotNet.Serialization.NodeTypeResolvers { internal sealed class DefaultContainersNodeTypeResolver : INodeTypeResolver { bool INodeTypeResolver.Resolve(NodeEvent? nodeEvent, ref Type currentType) { if (currentType == typeof(object)) { if (nodeEvent is SequenceStart) { currentType = typeof(List); return true; } if (nodeEvent is MappingStart) { currentType = typeof(Dictionary); return true; } } return false; } } internal class MappingNodeTypeResolver : INodeTypeResolver { private readonly IDictionary mappings; public MappingNodeTypeResolver(IDictionary mappings) { if (mappings == null) { throw new ArgumentNullException("mappings"); } foreach (KeyValuePair mapping in mappings) { if (!mapping.Key.IsAssignableFrom(mapping.Value)) { throw new InvalidOperationException($"Type '{mapping.Value}' does not implement type '{mapping.Key}'."); } } this.mappings = mappings; } public bool Resolve(NodeEvent? nodeEvent, ref Type currentType) { if (mappings.TryGetValue(currentType, out Type value)) { currentType = value; return true; } return false; } } internal class PreventUnknownTagsNodeTypeResolver : INodeTypeResolver { bool INodeTypeResolver.Resolve(NodeEvent? nodeEvent, ref Type currentType) { if (nodeEvent != null && !nodeEvent.Tag.IsEmpty) { Mark start = nodeEvent.Start; Mark end = nodeEvent.End; throw new YamlException(in start, in end, $"Encountered an unresolved tag '{nodeEvent.Tag}'"); } return false; } } internal sealed class TagNodeTypeResolver : INodeTypeResolver { private readonly IDictionary tagMappings; public TagNodeTypeResolver(IDictionary tagMappings) { this.tagMappings = tagMappings ?? throw new ArgumentNullException("tagMappings"); } bool INodeTypeResolver.Resolve(NodeEvent? nodeEvent, ref Type currentType) { if (nodeEvent != null && !nodeEvent.Tag.IsEmpty && tagMappings.TryGetValue(nodeEvent.Tag, out Type value)) { currentType = value; return true; } return false; } } [Obsolete("The mechanism that this class uses to specify type names is non-standard. Register the tags explicitly instead of using this convention.")] internal sealed class TypeNameInTagNodeTypeResolver : INodeTypeResolver { bool INodeTypeResolver.Resolve(NodeEvent? nodeEvent, ref Type currentType) { if (nodeEvent != null && !nodeEvent.Tag.IsEmpty) { Type type = Type.GetType(nodeEvent.Tag.Value.Substring(1), throwOnError: false); if (type != null) { currentType = type; return true; } } return false; } } internal sealed class YamlConvertibleTypeResolver : INodeTypeResolver { public bool Resolve(NodeEvent? nodeEvent, ref Type currentType) { return typeof(IYamlConvertible).IsAssignableFrom(currentType); } } internal sealed class YamlSerializableTypeResolver : INodeTypeResolver { public bool Resolve(NodeEvent? nodeEvent, ref Type currentType) { return typeof(IYamlSerializable).IsAssignableFrom(currentType); } } } namespace YamlDotNet.Serialization.NodeDeserializers { internal sealed class ArrayNodeDeserializer : INodeDeserializer { private sealed class ArrayList : IList, ICollection, IEnumerable { private object?[] data; public bool IsFixedSize => false; public bool IsReadOnly => false; public object? this[int index] { get { return data[index]; } set { data[index] = value; } } public int Count { get; private set; } public bool IsSynchronized => false; public object SyncRoot => data; public ArrayList() { Clear(); } public int Add(object? value) { if (Count == data.Length) { Array.Resize(ref data, data.Length * 2); } data[Count] = value; return Count++; } public void Clear() { data = new object[10]; Count = 0; } bool IList.Contains(object? value) { throw new NotSupportedException(); } int IList.IndexOf(object? value) { throw new NotSupportedException(); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } public void CopyTo(Array array, int index) { Array.Copy(data, 0, array, index, Count); } public IEnumerator GetEnumerator() { int i = 0; while (i < Count) { yield return data[i]; int num = i + 1; i = num; } } } private readonly INamingConvention enumNamingConvention; private readonly ITypeInspector typeInspector; public ArrayNodeDeserializer(INamingConvention enumNamingConvention, ITypeInspector typeInspector) { this.enumNamingConvention = enumNamingConvention; this.typeInspector = typeInspector; } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!expectedType.IsArray) { value = false; return false; } Type itemType = expectedType.GetElementType(); ArrayList arrayList = new ArrayList(); Array array = null; CollectionNodeDeserializer.DeserializeHelper(itemType, parser, nestedObjectDeserializer, arrayList, canUpdate: true, enumNamingConvention, typeInspector, PromiseResolvedHandler); array = Array.CreateInstance(itemType, arrayList.Count); arrayList.CopyTo(array, 0); value = array; return true; void PromiseResolvedHandler(int index, object? value) { if (array == null) { throw new InvalidOperationException("Destination array is still null"); } array.SetValue(YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(value, itemType, enumNamingConvention, typeInspector), index); } } } internal abstract class CollectionDeserializer { protected static void DeserializeHelper(Type tItem, IParser parser, Func nestedObjectDeserializer, IList result, bool canUpdate, IObjectFactory objectFactory) { IList result2 = result; parser.Consume(); SequenceEnd @event; while (!parser.TryConsume(out @event)) { ParsingEvent current = parser.Current; object obj = nestedObjectDeserializer(parser, tItem); if (obj is IValuePromise valuePromise) { if (!canUpdate) { Mark start = current?.Start ?? Mark.Empty; Mark end = current?.End ?? Mark.Empty; throw new ForwardAnchorNotSupportedException(in start, in end, "Forward alias references are not allowed because this type does not implement IList<>"); } int index = result2.Add(objectFactory.CreatePrimitive(tItem)); valuePromise.ValueAvailable += delegate(object? v) { result2[index] = v; }; } else { result2.Add(obj); } } } } internal sealed class CollectionNodeDeserializer : INodeDeserializer { private readonly IObjectFactory objectFactory; private readonly INamingConvention enumNamingConvention; private readonly ITypeInspector typeInspector; public CollectionNodeDeserializer(IObjectFactory objectFactory, INamingConvention enumNamingConvention, ITypeInspector typeInspector) { this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory"); this.enumNamingConvention = enumNamingConvention; this.typeInspector = typeInspector; } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { bool canUpdate = true; Type implementationOfOpenGenericInterface = expectedType.GetImplementationOfOpenGenericInterface(typeof(ICollection<>)); Type type; IList list; if (implementationOfOpenGenericInterface != null) { Type[] genericArguments = implementationOfOpenGenericInterface.GetGenericArguments(); type = genericArguments[0]; value = objectFactory.Create(expectedType); list = value as IList; if (list == null) { Type implementationOfOpenGenericInterface2 = expectedType.GetImplementationOfOpenGenericInterface(typeof(IList<>)); canUpdate = implementationOfOpenGenericInterface2 != null; list = (IList)Activator.CreateInstance(typeof(GenericCollectionToNonGenericAdapter<>).MakeGenericType(type), value); } } else { if (!typeof(IList).IsAssignableFrom(expectedType)) { value = null; return false; } type = typeof(object); value = objectFactory.Create(expectedType); list = (IList)value; } DeserializeHelper(type, parser, nestedObjectDeserializer, list, canUpdate, enumNamingConvention, typeInspector); return true; } internal static void DeserializeHelper(Type tItem, IParser parser, Func nestedObjectDeserializer, IList result, bool canUpdate, INamingConvention enumNamingConvention, ITypeInspector typeInspector, Action? promiseResolvedHandler = null) { Action promiseResolvedHandler2 = promiseResolvedHandler; IList result2 = result; Type tItem2 = tItem; INamingConvention enumNamingConvention2 = enumNamingConvention; ITypeInspector typeInspector2 = typeInspector; parser.Consume(); SequenceEnd @event; while (!parser.TryConsume(out @event)) { ParsingEvent current = parser.Current; object obj = nestedObjectDeserializer(parser, tItem2); if (obj is IValuePromise valuePromise) { if (!canUpdate) { Mark start = current?.Start ?? Mark.Empty; Mark end = current?.End ?? Mark.Empty; throw new ForwardAnchorNotSupportedException(in start, in end, "Forward alias references are not allowed because this type does not implement IList<>"); } int index = result2.Add(tItem2.IsValueType() ? Activator.CreateInstance(tItem2) : null); if (promiseResolvedHandler2 != null) { valuePromise.ValueAvailable += delegate(object? v) { promiseResolvedHandler2(index, v); }; } else { valuePromise.ValueAvailable += delegate(object? v) { result2[index] = YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(v, tItem2, enumNamingConvention2, typeInspector2); }; } } else { result2.Add(YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(obj, tItem2, enumNamingConvention2, typeInspector2)); } } } } internal abstract class DictionaryDeserializer { private readonly bool duplicateKeyChecking; public DictionaryDeserializer(bool duplicateKeyChecking) { this.duplicateKeyChecking = duplicateKeyChecking; } private void TryAssign(IDictionary result, object key, object value, MappingStart propertyName) { if (duplicateKeyChecking && result.Contains(key)) { Mark start = propertyName.Start; Mark end = propertyName.End; throw new YamlException(in start, in end, $"Encountered duplicate key {key}"); } result[key] = value; } protected virtual void Deserialize(Type tKey, Type tValue, IParser parser, Func nestedObjectDeserializer, IDictionary result, ObjectDeserializer rootDeserializer) { IDictionary result2 = result; MappingStart property = parser.Consume(); MappingEnd @event; while (!parser.TryConsume(out @event)) { object key = nestedObjectDeserializer(parser, tKey); object value = nestedObjectDeserializer(parser, tValue); IValuePromise valuePromise = value as IValuePromise; if (key is IValuePromise valuePromise2) { if (valuePromise == null) { valuePromise2.ValueAvailable += delegate(object? v) { result2[v] = value; }; continue; } bool hasFirstPart = false; valuePromise2.ValueAvailable += delegate(object? v) { if (hasFirstPart) { TryAssign(result2, v, value, property); } else { key = v; hasFirstPart = true; } }; valuePromise.ValueAvailable += delegate(object? v) { if (hasFirstPart) { TryAssign(result2, key, v, property); } else { value = v; hasFirstPart = true; } }; continue; } if (key == null) { throw new ArgumentException("Empty key names are not supported yet.", "tKey"); } if (valuePromise == null) { TryAssign(result2, key, value, property); continue; } valuePromise.ValueAvailable += delegate(object? v) { result2[key] = v; }; } } } internal class DictionaryNodeDeserializer : DictionaryDeserializer, INodeDeserializer { private readonly IObjectFactory objectFactory; public DictionaryNodeDeserializer(IObjectFactory objectFactory, bool duplicateKeyChecking) : base(duplicateKeyChecking) { this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory"); } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { Type implementationOfOpenGenericInterface = expectedType.GetImplementationOfOpenGenericInterface(typeof(IDictionary<, >)); Type type; Type type2; IDictionary dictionary; if (implementationOfOpenGenericInterface != null) { Type[] genericArguments = implementationOfOpenGenericInterface.GetGenericArguments(); type = genericArguments[0]; type2 = genericArguments[1]; value = objectFactory.Create(expectedType); dictionary = value as IDictionary; if (dictionary == null) { dictionary = (IDictionary)Activator.CreateInstance(typeof(GenericDictionaryToNonGenericAdapter<, >).MakeGenericType(type, type2), value); } } else { if (!typeof(IDictionary).IsAssignableFrom(expectedType)) { value = null; return false; } type = typeof(object); type2 = typeof(object); value = objectFactory.Create(expectedType); dictionary = (IDictionary)value; } Deserialize(type, type2, parser, nestedObjectDeserializer, dictionary, rootDeserializer); return true; } } internal sealed class EnumerableNodeDeserializer : INodeDeserializer { public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { Type type; if (expectedType == typeof(IEnumerable)) { type = typeof(object); } else { Type implementationOfOpenGenericInterface = expectedType.GetImplementationOfOpenGenericInterface(typeof(IEnumerable<>)); if (implementationOfOpenGenericInterface != expectedType) { value = null; return false; } type = implementationOfOpenGenericInterface.GetGenericArguments()[0]; } Type arg = typeof(List<>).MakeGenericType(type); value = nestedObjectDeserializer(parser, arg); return true; } } internal sealed class FsharpListNodeDeserializer : INodeDeserializer { private readonly ITypeInspector typeInspector; private readonly INamingConvention enumNamingConvention; public FsharpListNodeDeserializer(ITypeInspector typeInspector, INamingConvention enumNamingConvention) { this.typeInspector = typeInspector; this.enumNamingConvention = enumNamingConvention; } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!FsharpHelper.IsFsharpListType(expectedType)) { value = false; return false; } Type type = expectedType.GetGenericArguments()[0]; Type t = expectedType.GetGenericTypeDefinition().MakeGenericType(type); ArrayList arrayList = new ArrayList(); CollectionNodeDeserializer.DeserializeHelper(type, parser, nestedObjectDeserializer, arrayList, canUpdate: true, enumNamingConvention, typeInspector); Array array = Array.CreateInstance(type, arrayList.Count); arrayList.CopyTo(array, 0); object obj = FsharpHelper.CreateFsharpListFromArray(t, type, array); value = obj; return true; } } internal sealed class NullNodeDeserializer : INodeDeserializer { public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { value = null; if (parser.Accept(out var @event) && NodeIsNull(@event)) { parser.SkipThisAndNestedEvents(); return true; } return false; } private static bool NodeIsNull(NodeEvent nodeEvent) { if (nodeEvent.Tag == "tag:yaml.org,2002:null") { return true; } if (nodeEvent is YamlDotNet.Core.Events.Scalar scalar && scalar.Style == ScalarStyle.Plain && !scalar.IsKey) { string value = scalar.Value; switch (value) { default: return value == "NULL"; case "": case "~": case "null": case "Null": return true; } } return false; } } internal sealed class ObjectNodeDeserializer : INodeDeserializer { private readonly IObjectFactory objectFactory; private readonly ITypeInspector typeInspector; private readonly bool ignoreUnmatched; private readonly bool duplicateKeyChecking; private readonly ITypeConverter typeConverter; private readonly INamingConvention enumNamingConvention; private readonly bool enforceNullability; private readonly bool caseInsensitivePropertyMatching; private readonly bool enforceRequiredProperties; private readonly TypeConverterCache typeConverters; public ObjectNodeDeserializer(IObjectFactory objectFactory, ITypeInspector typeInspector, bool ignoreUnmatched, bool duplicateKeyChecking, ITypeConverter typeConverter, INamingConvention enumNamingConvention, bool enforceNullability, bool caseInsensitivePropertyMatching, bool enforceRequiredProperties, IEnumerable typeConverters) { this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory"); this.typeInspector = typeInspector ?? throw new ArgumentNullException("typeInspector"); this.ignoreUnmatched = ignoreUnmatched; this.duplicateKeyChecking = duplicateKeyChecking; this.typeConverter = typeConverter ?? throw new ArgumentNullException("typeConverter"); this.enumNamingConvention = enumNamingConvention ?? throw new ArgumentNullException("enumNamingConvention"); this.enforceNullability = enforceNullability; this.caseInsensitivePropertyMatching = caseInsensitivePropertyMatching; this.enforceRequiredProperties = enforceRequiredProperties; this.typeConverters = new TypeConverterCache(typeConverters); } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!parser.TryConsume(out var _)) { value = null; return false; } Type type = Nullable.GetUnderlyingType(expectedType) ?? FsharpHelper.GetOptionUnderlyingType(expectedType) ?? expectedType; value = objectFactory.Create(type); objectFactory.ExecuteOnDeserializing(value); HashSet hashSet = new HashSet(StringComparer.Ordinal); HashSet hashSet2 = new HashSet(StringComparer.Ordinal); Mark start = Mark.Empty; MappingEnd event2; while (!parser.TryConsume(out event2)) { YamlDotNet.Core.Events.Scalar propertyName = parser.Consume(); if (duplicateKeyChecking && !hashSet.Add(propertyName.Value)) { Mark start2 = propertyName.Start; Mark end = propertyName.End; throw new YamlException(in start2, in end, "Encountered duplicate key " + propertyName.Value); } try { IPropertyDescriptor property = typeInspector.GetProperty(type, null, propertyName.Value, ignoreUnmatched, caseInsensitivePropertyMatching); if (property == null) { parser.SkipThisAndNestedEvents(); continue; } hashSet2.Add(property.Name); object obj; if (property.ConverterType != null) { IYamlTypeConverter converterByType = typeConverters.GetConverterByType(property.ConverterType); obj = converterByType.ReadYaml(parser, property.Type, rootDeserializer); } else { obj = nestedObjectDeserializer(parser, property.Type); } if (obj is IValuePromise valuePromise) { object valueRef = value; valuePromise.ValueAvailable += delegate(object? v) { object value3 = typeConverter.ChangeType(v, property.Type, enumNamingConvention, typeInspector); NullCheck(value3, property, propertyName); property.Write(valueRef, value3); }; } else { object value2 = typeConverter.ChangeType(obj, property.Type, enumNamingConvention, typeInspector); NullCheck(value2, property, propertyName); property.Write(value, value2); } goto IL_0267; } catch (SerializationException ex) { Mark start2 = propertyName.Start; Mark end = propertyName.End; throw new YamlException(in start2, in end, ex.Message); } catch (YamlException) { throw; } catch (Exception innerException) { Mark start2 = propertyName.Start; Mark end = propertyName.End; throw new YamlException(in start2, in end, "Exception during deserialization", innerException); } IL_0267: start = propertyName.End; } if (enforceRequiredProperties) { IEnumerable properties = typeInspector.GetProperties(type, value); List list = new List(); foreach (IPropertyDescriptor item in properties) { if (item.Required && !hashSet2.Contains(item.Name)) { list.Add(item.Name); } } if (list.Count > 0) { string text = string.Join(",", list); throw new YamlException(in start, in start, "Missing properties, '" + text + "' in source yaml."); } } objectFactory.ExecuteOnDeserialized(value); return true; } public void NullCheck(object value, IPropertyDescriptor property, YamlDotNet.Core.Events.Scalar propertyName) { if (enforceNullability && value == null && !property.AllowNulls) { Mark start = propertyName.Start; Mark end = propertyName.End; throw new YamlException(in start, in end, "Strict nullability enforcement error.", new NullReferenceException("Yaml value is null when target property requires non null values.")); } } } internal sealed class ScalarNodeDeserializer : INodeDeserializer { private const string BooleanTruePattern = "^(true|y|yes|on)$"; private const string BooleanFalsePattern = "^(false|n|no|off)$"; private readonly bool attemptUnknownTypeDeserialization; private readonly ITypeConverter typeConverter; private readonly ITypeInspector typeInspector; private readonly YamlFormatter formatter; private readonly INamingConvention enumNamingConvention; public ScalarNodeDeserializer(bool attemptUnknownTypeDeserialization, ITypeConverter typeConverter, ITypeInspector typeInspector, YamlFormatter formatter, INamingConvention enumNamingConvention) { this.attemptUnknownTypeDeserialization = attemptUnknownTypeDeserialization; this.typeConverter = typeConverter ?? throw new ArgumentNullException("typeConverter"); this.typeInspector = typeInspector; this.formatter = formatter; this.enumNamingConvention = enumNamingConvention; } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!parser.TryConsume(out var @event)) { value = null; return false; } Type type = Nullable.GetUnderlyingType(expectedType) ?? FsharpHelper.GetOptionUnderlyingType(expectedType) ?? expectedType; if (type.IsEnum()) { string name = enumNamingConvention.Reverse(@event.Value); name = typeInspector.GetEnumName(type, name); value = Enum.Parse(type, name, ignoreCase: true); return true; } TypeCode typeCode = type.GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: value = DeserializeBooleanHelper(@event.Value); break; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: value = DeserializeIntegerHelper(typeCode, @event.Value); break; case TypeCode.Single: value = float.Parse(@event.Value, formatter.NumberFormat); break; case TypeCode.Double: value = double.Parse(@event.Value, formatter.NumberFormat); break; case TypeCode.Decimal: value = decimal.Parse(@event.Value, formatter.NumberFormat); break; case TypeCode.String: value = @event.Value; break; case TypeCode.Char: value = @event.Value[0]; break; case TypeCode.DateTime: value = DateTime.Parse(@event.Value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); break; default: if (expectedType == typeof(object)) { if (!@event.IsKey && attemptUnknownTypeDeserialization) { value = AttemptUnknownTypeDeserialization(@event); } else { value = @event.Value; } } else { value = typeConverter.ChangeType(@event.Value, expectedType, enumNamingConvention, typeInspector); } break; } return true; } private static bool DeserializeBooleanHelper(string value) { if (Regex.IsMatch(value, "^(true|y|yes|on)$", RegexOptions.IgnoreCase)) { return true; } if (Regex.IsMatch(value, "^(false|n|no|off)$", RegexOptions.IgnoreCase)) { return false; } throw new FormatException("The value \"" + value + "\" is not a valid YAML Boolean"); } private object DeserializeIntegerHelper(TypeCode typeCode, string value) { StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; int i = 0; bool flag = false; ulong num = 0uL; if (value[0] == '-') { i++; flag = true; } else if (value[0] == '+') { i++; } if (value[i] == '0') { int num2; if (i == value.Length - 1) { num2 = 10; num = 0uL; } else { i++; if (value[i] == 'b') { num2 = 2; i++; } else if (value[i] == 'x') { num2 = 16; i++; } else { num2 = 8; } } for (; i < value.Length; i++) { if (value[i] != '_') { builder.Append(value[i]); } } switch (num2) { case 2: case 8: num = Convert.ToUInt64(builder.ToString(), num2); break; case 16: num = ulong.Parse(builder.ToString(), NumberStyles.HexNumber, formatter.NumberFormat); break; } } else { string[] array = value.Substring(i).Split(new char[1] { ':' }); num = 0uL; for (int j = 0; j < array.Length; j++) { num *= 60; num += ulong.Parse(array[j].Replace("_", ""), CultureInfo.InvariantCulture); } } if (!flag) { return CastInteger(num, typeCode); } long number = ((num != 9223372036854775808uL) ? checked(-(long)num) : long.MinValue); return CastInteger(number, typeCode); } finally { ((IDisposable)builderWrapper).Dispose(); } } private static object CastInteger(long number, TypeCode typeCode) { return checked(typeCode switch { TypeCode.Byte => (byte)number, TypeCode.Int16 => (short)number, TypeCode.Int32 => (int)number, TypeCode.Int64 => number, TypeCode.SByte => (sbyte)number, TypeCode.UInt16 => (ushort)number, TypeCode.UInt32 => (uint)number, TypeCode.UInt64 => (ulong)number, _ => number, }); } private static object CastInteger(ulong number, TypeCode typeCode) { return checked(typeCode switch { TypeCode.Byte => (byte)number, TypeCode.Int16 => (short)number, TypeCode.Int32 => (int)number, TypeCode.Int64 => (long)number, TypeCode.SByte => (sbyte)number, TypeCode.UInt16 => (ushort)number, TypeCode.UInt32 => (uint)number, TypeCode.UInt64 => number, _ => number, }); } private object? AttemptUnknownTypeDeserialization(YamlDotNet.Core.Events.Scalar value) { if (value.Style == ScalarStyle.SingleQuoted || value.Style == ScalarStyle.DoubleQuoted || value.Style == ScalarStyle.Folded) { return value.Value; } string v = value.Value; switch (v) { case "null": case "Null": case "NULL": case "~": case "": return null; case "true": case "True": case "TRUE": return true; case "False": case "FALSE": case "false": return false; default: { object value2; if (Regex.IsMatch(v, "0x[0-9a-fA-F]+")) { if (!TryAndSwallow(() => Convert.ToByte(v, 16), out value2) && !TryAndSwallow(() => Convert.ToInt16(v, 16), out value2) && !TryAndSwallow(() => Convert.ToInt32(v, 16), out value2) && !TryAndSwallow(() => Convert.ToInt64(v, 16), out value2) && !TryAndSwallow(() => Convert.ToUInt64(v, 16), out value2)) { return v; } } else if (Regex.IsMatch(v, "0o[0-9a-fA-F]+")) { if (!TryAndSwallow(() => Convert.ToByte(v, 8), out value2) && !TryAndSwallow(() => Convert.ToInt16(v, 8), out value2) && !TryAndSwallow(() => Convert.ToInt32(v, 8), out value2) && !TryAndSwallow(() => Convert.ToInt64(v, 8), out value2) && !TryAndSwallow(() => Convert.ToUInt64(v, 8), out value2)) { return v; } } else { if (!Regex.IsMatch(v, "[-+]?(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?")) { if (Regex.IsMatch(v, "^[-+]?(\\.inf|\\.Inf|\\.INF)$")) { if (Polyfills.StartsWith(v, '-')) { return float.NegativeInfinity; } return float.PositiveInfinity; } if (Regex.IsMatch(v, "^(\\.nan|\\.NaN|\\.NAN)$")) { return float.NaN; } return v; } if (!TryAndSwallow(() => byte.Parse(v, formatter.NumberFormat), out value2) && !TryAndSwallow(() => short.Parse(v, formatter.NumberFormat), out value2) && !TryAndSwallow(() => int.Parse(v, formatter.NumberFormat), out value2) && !TryAndSwallow(() => long.Parse(v, formatter.NumberFormat), out value2) && !TryAndSwallow(() => ulong.Parse(v, formatter.NumberFormat), out value2) && !TryAndSwallow(() => float.Parse(v, formatter.NumberFormat), out value2) && !TryAndSwallow(() => double.Parse(v, formatter.NumberFormat), out value2)) { return v; } } return value2; } } } private static bool TryAndSwallow(Func attempt, out object? value) { try { value = attempt(); return true; } catch { value = null; return false; } } } internal sealed class StaticArrayNodeDeserializer : INodeDeserializer { private sealed class ArrayList : IList, ICollection, IEnumerable { private object?[] data; public bool IsFixedSize => false; public bool IsReadOnly => false; public object? this[int index] { get { return data[index]; } set { data[index] = value; } } public int Count { get; private set; } public bool IsSynchronized => false; public object SyncRoot => data; public ArrayList() { Clear(); } public int Add(object? value) { if (Count == data.Length) { Array.Resize(ref data, data.Length * 2); } data[Count] = value; return Count++; } public void Clear() { data = new object[10]; Count = 0; } bool IList.Contains(object? value) { throw new NotSupportedException(); } int IList.IndexOf(object? value) { throw new NotSupportedException(); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } public void CopyTo(Array array, int index) { Array.Copy(data, 0, array, index, Count); } public IEnumerator GetEnumerator() { int i = 0; while (i < Count) { yield return data[i]; int num = i + 1; i = num; } } } private readonly StaticObjectFactory factory; public StaticArrayNodeDeserializer(StaticObjectFactory factory) { this.factory = factory ?? throw new ArgumentNullException("factory"); } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!factory.IsArray(expectedType)) { value = false; return false; } Type valueType = factory.GetValueType(expectedType); ArrayList arrayList = new ArrayList(); StaticCollectionNodeDeserializer.DeserializeHelper(valueType, parser, nestedObjectDeserializer, arrayList, factory); Array array = factory.CreateArray(expectedType, arrayList.Count); arrayList.CopyTo(array, 0); value = array; return true; } } internal sealed class StaticCollectionNodeDeserializer : INodeDeserializer { private readonly StaticObjectFactory factory; public StaticCollectionNodeDeserializer(StaticObjectFactory factory) { this.factory = factory ?? throw new ArgumentNullException("factory"); } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!factory.IsList(expectedType)) { value = null; return false; } DeserializeHelper(result: (IList)(value = factory.Create(expectedType) as IList), tItem: factory.GetValueType(expectedType), parser: parser, nestedObjectDeserializer: nestedObjectDeserializer, factory: factory); return true; } internal static void DeserializeHelper(Type tItem, IParser parser, Func nestedObjectDeserializer, IList result, IObjectFactory factory) { IList result2 = result; parser.Consume(); SequenceEnd @event; while (!parser.TryConsume(out @event)) { ParsingEvent current = parser.Current; object obj = nestedObjectDeserializer(parser, tItem); if (obj is IValuePromise valuePromise) { int index = result2.Add(factory.CreatePrimitive(tItem)); valuePromise.ValueAvailable += delegate(object? v) { result2[index] = v; }; } else { result2.Add(obj); } } } } internal class StaticDictionaryNodeDeserializer : DictionaryDeserializer, INodeDeserializer { private readonly StaticObjectFactory objectFactory; public StaticDictionaryNodeDeserializer(StaticObjectFactory objectFactory, bool duplicateKeyChecking) : base(duplicateKeyChecking) { this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory"); } public bool Deserialize(IParser reader, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (objectFactory.IsDictionary(expectedType)) { if (!(objectFactory.Create(expectedType) is IDictionary dictionary)) { value = null; return false; } Type keyType = objectFactory.GetKeyType(expectedType); Type valueType = objectFactory.GetValueType(expectedType); value = dictionary; base.Deserialize(keyType, valueType, reader, nestedObjectDeserializer, dictionary, rootDeserializer); return true; } value = null; return false; } } internal sealed class TypeConverterNodeDeserializer : INodeDeserializer { private readonly TypeConverterCache converters; public TypeConverterNodeDeserializer(IEnumerable converters) { this.converters = new TypeConverterCache(converters); } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (!converters.TryGetConverterForType(expectedType, out IYamlTypeConverter typeConverter)) { value = null; return false; } value = typeConverter.ReadYaml(parser, expectedType, rootDeserializer); return true; } } internal sealed class YamlConvertibleNodeDeserializer : INodeDeserializer { private readonly IObjectFactory objectFactory; public YamlConvertibleNodeDeserializer(IObjectFactory objectFactory) { this.objectFactory = objectFactory; } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { Func nestedObjectDeserializer2 = nestedObjectDeserializer; IParser parser2 = parser; if (typeof(IYamlConvertible).IsAssignableFrom(expectedType)) { IYamlConvertible yamlConvertible = (IYamlConvertible)objectFactory.Create(expectedType); yamlConvertible.Read(parser2, expectedType, (Type type) => nestedObjectDeserializer2(parser2, type)); value = yamlConvertible; return true; } value = null; return false; } } internal sealed class YamlSerializableNodeDeserializer : INodeDeserializer { private readonly IObjectFactory objectFactory; public YamlSerializableNodeDeserializer(IObjectFactory objectFactory) { this.objectFactory = objectFactory; } public bool Deserialize(IParser parser, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { if (typeof(IYamlSerializable).IsAssignableFrom(expectedType)) { IYamlSerializable yamlSerializable = (IYamlSerializable)objectFactory.Create(expectedType); yamlSerializable.ReadYaml(parser); value = yamlSerializable; return true; } value = null; return false; } } } namespace YamlDotNet.Serialization.NamingConventions { internal sealed class CamelCaseNamingConvention : INamingConvention { public static readonly INamingConvention Instance = new CamelCaseNamingConvention(); [Obsolete("Use the Instance static field instead of creating new instances")] public CamelCaseNamingConvention() { } public string Apply(string value) { return value.ToCamelCase(); } public string Reverse(string value) { return value.ToPascalCase(); } } internal sealed class HyphenatedNamingConvention : INamingConvention { public static readonly INamingConvention Instance = new HyphenatedNamingConvention(); [Obsolete("Use the Instance static field instead of creating new instances")] public HyphenatedNamingConvention() { } public string Apply(string value) { return value.FromCamelCase("-"); } public string Reverse(string value) { return value.ToPascalCase(); } } internal sealed class LowerCaseNamingConvention : INamingConvention { public static readonly INamingConvention Instance = new LowerCaseNamingConvention(); private LowerCaseNamingConvention() { } public string Apply(string value) { return value.ToCamelCase().ToLower(CultureInfo.InvariantCulture); } public string Reverse(string value) { if (string.IsNullOrEmpty(value)) { return value; } return char.ToUpperInvariant(value[0]) + value.Substring(1); } } internal sealed class NullNamingConvention : INamingConvention { public static readonly INamingConvention Instance = new NullNamingConvention(); [Obsolete("Use the Instance static field instead of creating new instances")] public NullNamingConvention() { } public string Apply(string value) { return value; } public string Reverse(string value) { return value; } } internal sealed class PascalCaseNamingConvention : INamingConvention { public static readonly INamingConvention Instance = new PascalCaseNamingConvention(); [Obsolete("Use the Instance static field instead of creating new instances")] public PascalCaseNamingConvention() { } public string Apply(string value) { return value.ToPascalCase(); } public string Reverse(string value) { return value.ToPascalCase(); } } internal sealed class UnderscoredNamingConvention : INamingConvention { public static readonly INamingConvention Instance = new UnderscoredNamingConvention(); [Obsolete("Use the Instance static field instead of creating new instances")] public UnderscoredNamingConvention() { } public string Apply(string value) { return value.FromCamelCase("_"); } public string Reverse(string value) { return value.ToPascalCase(); } } } namespace YamlDotNet.Serialization.EventEmitters { public abstract class ChainedEventEmitter : IEventEmitter { protected readonly IEventEmitter nextEmitter; protected ChainedEventEmitter(IEventEmitter nextEmitter) { this.nextEmitter = nextEmitter ?? throw new ArgumentNullException("nextEmitter"); } public virtual void Emit(AliasEventInfo eventInfo, IEmitter emitter) { nextEmitter.Emit(eventInfo, emitter); } public virtual void Emit(ScalarEventInfo eventInfo, IEmitter emitter) { nextEmitter.Emit(eventInfo, emitter); } public virtual void Emit(MappingStartEventInfo eventInfo, IEmitter emitter) { nextEmitter.Emit(eventInfo, emitter); } public virtual void Emit(MappingEndEventInfo eventInfo, IEmitter emitter) { nextEmitter.Emit(eventInfo, emitter); } public virtual void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter) { nextEmitter.Emit(eventInfo, emitter); } public virtual void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter) { nextEmitter.Emit(eventInfo, emitter); } } internal sealed class JsonEventEmitter : ChainedEventEmitter { private readonly YamlFormatter formatter; private readonly INamingConvention enumNamingConvention; private readonly ITypeInspector typeInspector; private static readonly Regex NumericRegex = new Regex("^-?\\d+\\.?\\d+$", RegexOptions.Compiled); public JsonEventEmitter(IEventEmitter nextEmitter, YamlFormatter formatter, INamingConvention enumNamingConvention, ITypeInspector typeInspector) : base(nextEmitter) { this.formatter = formatter; this.enumNamingConvention = enumNamingConvention; this.typeInspector = typeInspector; } public override void Emit(AliasEventInfo eventInfo, IEmitter emitter) { eventInfo.NeedsExpansion = true; } public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter) { eventInfo.IsPlainImplicit = true; eventInfo.Style = ScalarStyle.Plain; object value = eventInfo.Source.Value; if (value == null) { eventInfo.RenderedValue = "null"; } else { TypeCode typeCode = eventInfo.Source.Type.GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: eventInfo.RenderedValue = formatter.FormatBoolean(value); break; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: if (eventInfo.Source.Type.IsEnum()) { eventInfo.RenderedValue = formatter.FormatEnum(value, typeInspector, enumNamingConvention); eventInfo.Style = ((!formatter.PotentiallyQuoteEnums(value)) ? ScalarStyle.Plain : ScalarStyle.DoubleQuoted); } else { eventInfo.RenderedValue = formatter.FormatNumber(value); } break; case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: eventInfo.RenderedValue = formatter.FormatNumber(value); if (!NumericRegex.IsMatch(eventInfo.RenderedValue)) { eventInfo.Style = ScalarStyle.DoubleQuoted; } break; case TypeCode.Char: case TypeCode.String: eventInfo.RenderedValue = value.ToString(); eventInfo.Style = ScalarStyle.DoubleQuoted; break; case TypeCode.DateTime: eventInfo.RenderedValue = formatter.FormatDateTime(value); break; case TypeCode.Empty: eventInfo.RenderedValue = "null"; break; default: if (eventInfo.Source.Type == typeof(TimeSpan)) { eventInfo.RenderedValue = formatter.FormatTimeSpan(value); break; } throw new NotSupportedException($"TypeCode.{typeCode} is not supported."); } } base.Emit(eventInfo, emitter); } public override void Emit(MappingStartEventInfo eventInfo, IEmitter emitter) { eventInfo.Style = MappingStyle.Flow; base.Emit(eventInfo, emitter); } public override void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter) { eventInfo.Style = SequenceStyle.Flow; base.Emit(eventInfo, emitter); } } internal sealed class TypeAssigningEventEmitter : ChainedEventEmitter { private readonly IDictionary tagMappings; private readonly bool quoteNecessaryStrings; private readonly Regex? isSpecialStringValue_Regex; private static readonly string SpecialStrings_Pattern = "^(null|Null|NULL|\\~|true|True|TRUE|false|False|FALSE|[-+]?[0-9]+|0o[0-7]+|0x[0-9a-fA-F]+|[-+]?(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?|[-+]?(\\.inf|\\.Inf|\\.INF)|\\.nan|\\.NaN|\\.NAN|\\s.*)$"; private static readonly string CombinedYaml1_1SpecialStrings_Pattern = "^(null|Null|NULL|\\~|true|True|TRUE|false|False|FALSE|y|Y|yes|Yes|YES|n|N|no|No|NO|on|On|ON|off|Off|OFF|[-+]?0b[0-1_]+|[-+]?0o?[0-7_]+|[-+]?(0|[1-9][0-9_]*)|[-+]?0x[0-9a-fA-F_]+|[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+|[-+]?([0-9][0-9_]*)?\\.[0-9_]*([eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(inf|Inf|INF)|\\.(nan|NaN|NAN))$"; private readonly ScalarStyle defaultScalarStyle; private readonly YamlFormatter formatter; private readonly INamingConvention enumNamingConvention; private readonly ITypeInspector typeInspector; public TypeAssigningEventEmitter(IEventEmitter nextEmitter, IDictionary tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings, ScalarStyle defaultScalarStyle, YamlFormatter formatter, INamingConvention enumNamingConvention, ITypeInspector typeInspector) : base(nextEmitter) { this.defaultScalarStyle = defaultScalarStyle; this.formatter = formatter; this.tagMappings = tagMappings; this.quoteNecessaryStrings = quoteNecessaryStrings; isSpecialStringValue_Regex = new Regex(quoteYaml1_1Strings ? CombinedYaml1_1SpecialStrings_Pattern : SpecialStrings_Pattern, RegexOptions.Compiled); this.enumNamingConvention = enumNamingConvention; this.typeInspector = typeInspector; } public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter) { ScalarStyle style = ScalarStyle.Plain; object value = eventInfo.Source.Value; if (value == null) { eventInfo.Tag = JsonSchema.Tags.Null; eventInfo.RenderedValue = ""; } else { TypeCode typeCode = eventInfo.Source.Type.GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: eventInfo.Tag = JsonSchema.Tags.Bool; eventInfo.RenderedValue = formatter.FormatBoolean(value); break; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: if (eventInfo.Source.Type.IsEnum) { eventInfo.Tag = FailsafeSchema.Tags.Str; eventInfo.RenderedValue = formatter.FormatEnum(value, typeInspector, enumNamingConvention); style = ((!quoteNecessaryStrings || !IsSpecialStringValue(eventInfo.RenderedValue) || !formatter.PotentiallyQuoteEnums(value)) ? defaultScalarStyle : ScalarStyle.DoubleQuoted); } else { eventInfo.Tag = JsonSchema.Tags.Int; eventInfo.RenderedValue = formatter.FormatNumber(value); } break; case TypeCode.Single: eventInfo.Tag = JsonSchema.Tags.Float; eventInfo.RenderedValue = formatter.FormatNumber((float)value); break; case TypeCode.Double: eventInfo.Tag = JsonSchema.Tags.Float; eventInfo.RenderedValue = formatter.FormatNumber((double)value); break; case TypeCode.Decimal: eventInfo.Tag = JsonSchema.Tags.Float; eventInfo.RenderedValue = formatter.FormatNumber(value); break; case TypeCode.Char: case TypeCode.String: eventInfo.Tag = FailsafeSchema.Tags.Str; eventInfo.RenderedValue = value.ToString(); style = ((!quoteNecessaryStrings || !IsSpecialStringValue(eventInfo.RenderedValue)) ? defaultScalarStyle : ScalarStyle.DoubleQuoted); break; case TypeCode.DateTime: eventInfo.Tag = DefaultSchema.Tags.Timestamp; eventInfo.RenderedValue = formatter.FormatDateTime(value); break; case TypeCode.Empty: eventInfo.Tag = JsonSchema.Tags.Null; eventInfo.RenderedValue = ""; break; default: if (eventInfo.Source.Type == typeof(TimeSpan)) { eventInfo.RenderedValue = formatter.FormatTimeSpan(value); break; } throw new NotSupportedException($"TypeCode.{typeCode} is not supported."); } } eventInfo.IsPlainImplicit = true; if (eventInfo.Style == ScalarStyle.Any) { eventInfo.Style = style; } base.Emit(eventInfo, emitter); } public override void Emit(MappingStartEventInfo eventInfo, IEmitter emitter) { AssignTypeIfNeeded(eventInfo); base.Emit(eventInfo, emitter); } public override void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter) { AssignTypeIfNeeded(eventInfo); base.Emit(eventInfo, emitter); } private void AssignTypeIfNeeded(ObjectEventInfo eventInfo) { if (tagMappings.TryGetValue(eventInfo.Source.Type, out var value)) { eventInfo.Tag = value; } } private bool IsSpecialStringValue(string value) { if (value.Trim() == string.Empty) { return true; } return isSpecialStringValue_Regex?.IsMatch(value) ?? false; } } internal sealed class WriterEventEmitter : IEventEmitter { void IEventEmitter.Emit(AliasEventInfo eventInfo, IEmitter emitter) { emitter.Emit(new YamlDotNet.Core.Events.AnchorAlias(eventInfo.Alias)); } void IEventEmitter.Emit(ScalarEventInfo eventInfo, IEmitter emitter) { emitter.Emit(new YamlDotNet.Core.Events.Scalar(eventInfo.Anchor, eventInfo.Tag, eventInfo.RenderedValue, eventInfo.Style, eventInfo.IsPlainImplicit, eventInfo.IsQuotedImplicit)); } void IEventEmitter.Emit(MappingStartEventInfo eventInfo, IEmitter emitter) { emitter.Emit(new MappingStart(eventInfo.Anchor, eventInfo.Tag, eventInfo.IsImplicit, eventInfo.Style)); } void IEventEmitter.Emit(MappingEndEventInfo eventInfo, IEmitter emitter) { emitter.Emit(new MappingEnd()); } void IEventEmitter.Emit(SequenceStartEventInfo eventInfo, IEmitter emitter) { emitter.Emit(new SequenceStart(eventInfo.Anchor, eventInfo.Tag, eventInfo.IsImplicit, eventInfo.Style)); } void IEventEmitter.Emit(SequenceEndEventInfo eventInfo, IEmitter emitter) { emitter.Emit(new SequenceEnd()); } } } namespace YamlDotNet.Serialization.Converters { internal class DateTime8601Converter : IYamlTypeConverter { private readonly ScalarStyle scalarStyle; public DateTime8601Converter() : this(ScalarStyle.Any) { } public DateTime8601Converter(ScalarStyle scalarStyle) { this.scalarStyle = scalarStyle; } public bool Accepts(Type type) { return type == typeof(DateTime); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { string value = parser.Consume().Value; DateTime dateTime = DateTime.ParseExact(value, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); return dateTime; } public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) { string value2 = ((DateTime)value).ToString("O", CultureInfo.InvariantCulture); emitter.Emit(new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, value2, scalarStyle, isPlainImplicit: true, isQuotedImplicit: false)); } } internal class DateTimeConverter : IYamlTypeConverter { private readonly DateTimeKind kind; private readonly IFormatProvider provider; private readonly bool doubleQuotes; private readonly string[] formats; public DateTimeConverter(DateTimeKind kind = DateTimeKind.Utc, IFormatProvider? provider = null, bool doubleQuotes = false, params string[] formats) { this.kind = ((kind == DateTimeKind.Unspecified) ? DateTimeKind.Utc : kind); this.provider = provider ?? CultureInfo.InvariantCulture; this.doubleQuotes = doubleQuotes; this.formats = formats.DefaultIfEmpty("G").ToArray(); } public bool Accepts(Type type) { return type == typeof(DateTime); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { string value = parser.Consume().Value; DateTimeStyles style = ((kind == DateTimeKind.Local) ? DateTimeStyles.AssumeLocal : DateTimeStyles.AssumeUniversal); DateTime dt = DateTime.ParseExact(value, formats, provider, style); dt = EnsureDateTimeKind(dt, kind); return dt; } public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) { DateTime dateTime = (DateTime)value; string value2 = ((kind == DateTimeKind.Local) ? dateTime.ToLocalTime() : dateTime.ToUniversalTime()).ToString(formats.First(), provider); emitter.Emit(new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, value2, doubleQuotes ? ScalarStyle.DoubleQuoted : ScalarStyle.Any, isPlainImplicit: true, isQuotedImplicit: false)); } private static DateTime EnsureDateTimeKind(DateTime dt, DateTimeKind kind) { if (dt.Kind == DateTimeKind.Local && kind == DateTimeKind.Utc) { return dt.ToUniversalTime(); } if (dt.Kind == DateTimeKind.Utc && kind == DateTimeKind.Local) { return dt.ToLocalTime(); } return dt; } } internal class DateTimeOffsetConverter : IYamlTypeConverter { private readonly IFormatProvider provider; private readonly ScalarStyle style; private readonly DateTimeStyles dateStyle; private readonly string[] formats; public DateTimeOffsetConverter(IFormatProvider? provider = null, ScalarStyle style = ScalarStyle.Any, DateTimeStyles dateStyle = DateTimeStyles.None, params string[] formats) { this.provider = provider ?? CultureInfo.InvariantCulture; this.style = style; this.dateStyle = dateStyle; this.formats = formats.DefaultIfEmpty("O").ToArray(); } public bool Accepts(Type type) { return type == typeof(DateTimeOffset); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { string value = parser.Consume().Value; DateTimeOffset dateTimeOffset = DateTimeOffset.ParseExact(value, formats, provider, dateStyle); return dateTimeOffset; } public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) { string value2 = ((DateTimeOffset)value).ToString(formats.First(), provider); emitter.Emit(new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, value2, style, isPlainImplicit: true, isQuotedImplicit: false)); } } internal class GuidConverter : IYamlTypeConverter { private readonly bool jsonCompatible; public GuidConverter(bool jsonCompatible) { this.jsonCompatible = jsonCompatible; } public bool Accepts(Type type) { return type == typeof(Guid); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { string value = parser.Consume().Value; return new Guid(value); } public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) { Guid guid = (Guid)value; emitter.Emit(new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, guid.ToString("D"), jsonCompatible ? ScalarStyle.DoubleQuoted : ScalarStyle.Any, isPlainImplicit: true, isQuotedImplicit: false)); } } internal class SystemTypeConverter : IYamlTypeConverter { public bool Accepts(Type type) { return typeof(Type).IsAssignableFrom(type); } public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) { string value = parser.Consume().Value; return Type.GetType(value, throwOnError: true); } public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) { Type type2 = (Type)value; emitter.Emit(new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, type2.AssemblyQualifiedName, ScalarStyle.Any, isPlainImplicit: true, isQuotedImplicit: false)); } } } namespace YamlDotNet.Serialization.Callbacks { [AttributeUsage(AttributeTargets.Method)] internal sealed class OnDeserializedAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class OnDeserializingAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class OnSerializedAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class OnSerializingAttribute : Attribute { } } namespace YamlDotNet.Serialization.BufferedDeserialization { internal interface ITypeDiscriminatingNodeDeserializerOptions { void AddTypeDiscriminator(ITypeDiscriminator discriminator); void AddKeyValueTypeDiscriminator(string discriminatorKey, IDictionary valueTypeMapping); void AddUniqueKeyTypeDiscriminator(IDictionary uniqueKeyTypeMapping); } internal class ParserBuffer : IParser { private readonly LinkedList buffer; private LinkedListNode? current; public ParsingEvent? Current => current?.Value; public ParserBuffer(IParser parserToBuffer, int maxDepth, int maxLength) { buffer = new LinkedList(); buffer.AddLast(parserToBuffer.Consume()); int num = 0; do { ParsingEvent parsingEvent = parserToBuffer.Consume(); num += parsingEvent.NestingIncrease; buffer.AddLast(parsingEvent); if (maxDepth > -1 && num > maxDepth) { throw new ArgumentOutOfRangeException("parserToBuffer", "Parser buffer exceeded max depth"); } if (maxLength > -1 && buffer.Count > maxLength) { throw new ArgumentOutOfRangeException("parserToBuffer", "Parser buffer exceeded max length"); } } while (num >= 0); current = buffer.First; } public bool MoveNext() { current = current?.Next; return current != null; } public void Reset() { current = buffer.First; } } internal class TypeDiscriminatingNodeDeserializer : INodeDeserializer { private readonly IList innerDeserializers; private readonly IList typeDiscriminators; private readonly int maxDepthToBuffer; private readonly int maxLengthToBuffer; public TypeDiscriminatingNodeDeserializer(IList innerDeserializers, IList typeDiscriminators, int maxDepthToBuffer, int maxLengthToBuffer) { this.innerDeserializers = innerDeserializers; this.typeDiscriminators = typeDiscriminators; this.maxDepthToBuffer = maxDepthToBuffer; this.maxLengthToBuffer = maxLengthToBuffer; } public bool Deserialize(IParser reader, Type expectedType, Func nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer) { Type expectedType2 = expectedType; if (!reader.Accept(out var _)) { value = null; return false; } IEnumerable enumerable = typeDiscriminators.Where((ITypeDiscriminator t) => t.BaseType.IsAssignableFrom(expectedType2)); if (!enumerable.Any()) { value = null; return false; } Mark start = reader.Current.Start; Type expectedType3 = expectedType2; ParserBuffer parserBuffer; try { parserBuffer = new ParserBuffer(reader, maxDepthToBuffer, maxLengthToBuffer); } catch (Exception innerException) { Mark end = reader.Current.End; throw new YamlException(in start, in end, "Failed to buffer yaml node", innerException); } try { foreach (ITypeDiscriminator item in enumerable) { parserBuffer.Reset(); if (item.TryDiscriminate(parserBuffer, out Type suggestedType)) { expectedType3 = suggestedType; break; } } } catch (Exception innerException2) { Mark end = reader.Current.End; throw new YamlException(in start, in end, "Failed to discriminate type", innerException2); } parserBuffer.Reset(); foreach (INodeDeserializer innerDeserializer in innerDeserializers) { if (innerDeserializer.Deserialize(parserBuffer, expectedType3, nestedObjectDeserializer, out value, rootDeserializer)) { return true; } } value = null; return false; } } internal class TypeDiscriminatingNodeDeserializerOptions : ITypeDiscriminatingNodeDeserializerOptions { internal readonly List discriminators = new List(); public void AddTypeDiscriminator(ITypeDiscriminator discriminator) { discriminators.Add(discriminator); } public void AddKeyValueTypeDiscriminator(string discriminatorKey, IDictionary valueTypeMapping) { discriminators.Add(new KeyValueTypeDiscriminator(typeof(T), discriminatorKey, valueTypeMapping)); } public void AddUniqueKeyTypeDiscriminator(IDictionary uniqueKeyTypeMapping) { discriminators.Add(new UniqueKeyTypeDiscriminator(typeof(T), uniqueKeyTypeMapping)); } } } namespace YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators { internal interface ITypeDiscriminator { Type BaseType { get; } bool TryDiscriminate(IParser buffer, out Type? suggestedType); } internal class KeyValueTypeDiscriminator : ITypeDiscriminator { private readonly string targetKey; private readonly IDictionary typeMapping; public Type BaseType { get; private set; } public KeyValueTypeDiscriminator(Type baseType, string targetKey, IDictionary typeMapping) { foreach (KeyValuePair item in typeMapping) { if (!baseType.IsAssignableFrom(item.Value)) { throw new ArgumentOutOfRangeException("typeMapping", $"{item.Value} is not a assignable to {baseType}"); } } BaseType = baseType; this.targetKey = targetKey; this.typeMapping = typeMapping; } public bool TryDiscriminate(IParser parser, out Type? suggestedType) { if (parser.TryFindMappingEntry((YamlDotNet.Core.Events.Scalar scalar) => targetKey == scalar.Value, out YamlDotNet.Core.Events.Scalar _, out ParsingEvent value) && value is YamlDotNet.Core.Events.Scalar scalar2 && typeMapping.TryGetValue(scalar2.Value, out Type value2)) { suggestedType = value2; return true; } suggestedType = null; return false; } } internal class UniqueKeyTypeDiscriminator : ITypeDiscriminator { private readonly IDictionary typeMapping; public Type BaseType { get; private set; } public UniqueKeyTypeDiscriminator(Type baseType, IDictionary typeMapping) { foreach (KeyValuePair item in typeMapping) { if (!baseType.IsAssignableFrom(item.Value)) { throw new ArgumentOutOfRangeException("typeMapping", $"{item.Value} is not a assignable to {baseType}"); } } BaseType = baseType; this.typeMapping = typeMapping; } public bool TryDiscriminate(IParser parser, out Type? suggestedType) { if (parser.TryFindMappingEntry((YamlDotNet.Core.Events.Scalar scalar) => typeMapping.ContainsKey(scalar.Value), out YamlDotNet.Core.Events.Scalar key, out ParsingEvent _)) { suggestedType = typeMapping[key.Value]; return true; } suggestedType = null; return false; } } } namespace YamlDotNet.RepresentationModel { internal class DocumentLoadingState { private readonly Dictionary anchors = new Dictionary(); private readonly List nodesWithUnresolvedAliases = new List(); public void AddAnchor(YamlNode node) { if (node.Anchor.IsEmpty) { throw new ArgumentException("The specified node does not have an anchor"); } anchors[node.Anchor] = node; } public YamlNode GetNode(AnchorName anchor, Mark start, Mark end) { if (anchors.TryGetValue(anchor, out YamlNode value)) { return value; } throw new AnchorNotFoundException(in start, in end, $"The anchor '{anchor}' does not exists"); } public bool TryGetNode(AnchorName anchor, [NotNullWhen(true)] out YamlNode? node) { return anchors.TryGetValue(anchor, out node); } public void AddNodeWithUnresolvedAliases(YamlNode node) { nodesWithUnresolvedAliases.Add(node); } public void ResolveAliases() { foreach (YamlNode nodesWithUnresolvedAlias in nodesWithUnresolvedAliases) { nodesWithUnresolvedAlias.ResolveAliases(this); } } } internal class EmitterState { public HashSet EmittedAnchors { get; } = new HashSet(); } internal interface IYamlVisitor { void Visit(YamlStream stream); void Visit(YamlDocument document); void Visit(YamlScalarNode scalar); void Visit(YamlSequenceNode sequence); void Visit(YamlMappingNode mapping); } internal class LibYamlEventStream { private readonly IParser parser; public LibYamlEventStream(IParser iParser) { parser = iParser ?? throw new ArgumentNullException("iParser"); } public void WriteTo(TextWriter textWriter) { while (parser.MoveNext()) { ParsingEvent current = parser.Current; if (!(current is YamlDotNet.Core.Events.AnchorAlias anchorAlias)) { if (!(current is YamlDotNet.Core.Events.DocumentEnd documentEnd)) { if (!(current is YamlDotNet.Core.Events.DocumentStart documentStart)) { if (!(current is MappingEnd)) { if (!(current is MappingStart nodeEvent)) { if (!(current is YamlDotNet.Core.Events.Scalar scalar)) { if (!(current is SequenceEnd)) { if (!(current is SequenceStart nodeEvent2)) { if (!(current is YamlDotNet.Core.Events.StreamEnd)) { if (current is YamlDotNet.Core.Events.StreamStart) { textWriter.Write("+STR"); } } else { textWriter.Write("-STR"); } } else { textWriter.Write("+SEQ"); WriteAnchorAndTag(textWriter, nodeEvent2); } } else { textWriter.Write("-SEQ"); } } else { textWriter.Write("=VAL"); WriteAnchorAndTag(textWriter, scalar); switch (scalar.Style) { case ScalarStyle.DoubleQuoted: textWriter.Write(" \""); break; case ScalarStyle.SingleQuoted: textWriter.Write(" '"); break; case ScalarStyle.Folded: textWriter.Write(" >"); break; case ScalarStyle.Literal: textWriter.Write(" |"); break; default: textWriter.Write(" :"); break; } string value = scalar.Value; foreach (char c in value) { switch (c) { case '\b': textWriter.Write("\\b"); break; case '\t': textWriter.Write("\\t"); break; case '\n': textWriter.Write("\\n"); break; case '\r': textWriter.Write("\\r"); break; case '\\': textWriter.Write("\\\\"); break; default: textWriter.Write(c); break; } } } } else { textWriter.Write("+MAP"); WriteAnchorAndTag(textWriter, nodeEvent); } } else { textWriter.Write("-MAP"); } } else { textWriter.Write("+DOC"); if (!documentStart.IsImplicit) { textWriter.Write(" ---"); } } } else { textWriter.Write("-DOC"); if (!documentEnd.IsImplicit) { textWriter.Write(" ..."); } } } else { textWriter.Write("=ALI *"); textWriter.Write(anchorAlias.Value); } textWriter.WriteLine(); } } private static void WriteAnchorAndTag(TextWriter textWriter, NodeEvent nodeEvent) { if (!nodeEvent.Anchor.IsEmpty) { textWriter.Write(" &"); textWriter.Write(nodeEvent.Anchor); } if (!nodeEvent.Tag.IsEmpty) { textWriter.Write(" <"); textWriter.Write(nodeEvent.Tag.Value); textWriter.Write(">"); } } } internal class YamlAliasNode : YamlNode { public override YamlNodeType NodeType => YamlNodeType.Alias; internal YamlAliasNode(AnchorName anchor) { base.Anchor = anchor; } internal override void ResolveAliases(DocumentLoadingState state) { throw new NotSupportedException("Resolving an alias on an alias node does not make sense"); } internal override void Emit(IEmitter emitter, EmitterState state) { throw new NotSupportedException("A YamlAliasNode is an implementation detail and should never be saved."); } public override void Accept(IYamlVisitor visitor) { throw new NotSupportedException("A YamlAliasNode is an implementation detail and should never be visited."); } public override bool Equals(object? obj) { if (obj is YamlAliasNode yamlAliasNode && Equals(yamlAliasNode)) { return object.Equals(base.Anchor, yamlAliasNode.Anchor); } return false; } public override int GetHashCode() { return base.GetHashCode(); } internal override string ToString(RecursionLevel level) { return "*" + base.Anchor; } internal override IEnumerable SafeAllNodes(RecursionLevel level) { yield return this; } } internal class YamlDocument { private class AnchorAssigningVisitor : YamlVisitorBase { private readonly HashSet existingAnchors = new HashSet(); private readonly Dictionary visitedNodes = new Dictionary(); public void AssignAnchors(YamlDocument document) { existingAnchors.Clear(); visitedNodes.Clear(); document.Accept(this); Random random = new Random(); foreach (KeyValuePair visitedNode in visitedNodes) { if (!visitedNode.Value) { continue; } AnchorName anchorName; if (!visitedNode.Key.Anchor.IsEmpty && !existingAnchors.Contains(visitedNode.Key.Anchor)) { anchorName = visitedNode.Key.Anchor; } else { do { anchorName = new AnchorName(random.Next().ToString(CultureInfo.InvariantCulture)); } while (existingAnchors.Contains(anchorName)); } existingAnchors.Add(anchorName); visitedNode.Key.Anchor = anchorName; } } private bool VisitNodeAndFindDuplicates(YamlNode node) { if (visitedNodes.TryGetValue(node, out var value)) { if (!value) { visitedNodes[node] = true; } return !value; } visitedNodes.Add(node, value: false); return false; } public override void Visit(YamlScalarNode scalar) { VisitNodeAndFindDuplicates(scalar); } public override void Visit(YamlMappingNode mapping) { if (!VisitNodeAndFindDuplicates(mapping)) { base.Visit(mapping); } } public override void Visit(YamlSequenceNode sequence) { if (!VisitNodeAndFindDuplicates(sequence)) { base.Visit(sequence); } } } public YamlNode RootNode { get; private set; } public IEnumerable AllNodes => RootNode.AllNodes; public YamlDocument(YamlNode rootNode) { RootNode = rootNode; } public YamlDocument(string rootNode) { RootNode = new YamlScalarNode(rootNode); } internal YamlDocument(IParser parser) { DocumentLoadingState documentLoadingState = new DocumentLoadingState(); parser.Consume(); YamlDotNet.Core.Events.DocumentEnd @event; while (!parser.TryConsume(out @event)) { RootNode = YamlNode.ParseNode(parser, documentLoadingState); if (RootNode is YamlAliasNode) { throw new YamlException("A document cannot contain only an alias"); } } documentLoadingState.ResolveAliases(); if (RootNode == null) { throw new ArgumentException("Atempted to parse an empty document"); } } private void AssignAnchors() { AnchorAssigningVisitor anchorAssigningVisitor = new AnchorAssigningVisitor(); anchorAssigningVisitor.AssignAnchors(this); } internal void Save(IEmitter emitter, bool assignAnchors = true) { if (assignAnchors) { AssignAnchors(); } emitter.Emit(new YamlDotNet.Core.Events.DocumentStart()); RootNode.Save(emitter, new EmitterState()); emitter.Emit(new YamlDotNet.Core.Events.DocumentEnd(isImplicit: false)); } public void Accept(IYamlVisitor visitor) { visitor.Visit(this); } } internal sealed class YamlMappingNode : YamlNode, IEnumerable>, IEnumerable, IYamlConvertible { private readonly OrderedDictionary children = new OrderedDictionary(); public IOrderedDictionary Children => children; public MappingStyle Style { get; set; } public override YamlNodeType NodeType => YamlNodeType.Mapping; internal YamlMappingNode(IParser parser, DocumentLoadingState state) { Load(parser, state); } private void Load(IParser parser, DocumentLoadingState state) { MappingStart mappingStart = parser.Consume(); Load(mappingStart, state); Style = mappingStart.Style; bool flag = false; MappingEnd @event; while (!parser.TryConsume(out @event)) { YamlNode yamlNode = YamlNode.ParseNode(parser, state); YamlNode yamlNode2 = YamlNode.ParseNode(parser, state); if (!children.TryAdd(yamlNode, yamlNode2)) { Mark start = yamlNode.Start; Mark end = yamlNode.End; throw new YamlException(in start, in end, $"Duplicate key {yamlNode}"); } flag = flag || yamlNode is YamlAliasNode || yamlNode2 is YamlAliasNode; } if (flag) { state.AddNodeWithUnresolvedAliases(this); } } public YamlMappingNode() { } public YamlMappingNode(params KeyValuePair[] children) : this((IEnumerable>)children) { } public YamlMappingNode(IEnumerable> children) { foreach (KeyValuePair child in children) { this.children.Add(child); } } public YamlMappingNode(params YamlNode[] children) : this((IEnumerable)children) { } public YamlMappingNode(IEnumerable children) { using IEnumerator enumerator = children.GetEnumerator(); while (enumerator.MoveNext()) { YamlNode current = enumerator.Current; if (!enumerator.MoveNext()) { throw new ArgumentException("When constructing a mapping node with a sequence, the number of elements of the sequence must be even."); } Add(current, enumerator.Current); } } public void Add(YamlNode key, YamlNode value) { children.Add(key, value); } public void Add(string key, YamlNode value) { children.Add(new YamlScalarNode(key), value); } public void Add(YamlNode key, string value) { children.Add(key, new YamlScalarNode(value)); } public void Add(string key, string value) { children.Add(new YamlScalarNode(key), new YamlScalarNode(value)); } internal override void ResolveAliases(DocumentLoadingState state) { Dictionary dictionary = null; Dictionary dictionary2 = null; foreach (KeyValuePair child in children) { if (child.Key is YamlAliasNode) { if (dictionary == null) { dictionary = new Dictionary(); } dictionary.Add(child.Key, state.GetNode(child.Key.Anchor, child.Key.Start, child.Key.End)); } if (child.Value is YamlAliasNode) { if (dictionary2 == null) { dictionary2 = new Dictionary(); } dictionary2.Add(child.Key, state.GetNode(child.Value.Anchor, child.Value.Start, child.Value.End)); } } if (dictionary2 != null) { foreach (KeyValuePair item in dictionary2) { children[item.Key] = item.Value; } } if (dictionary == null) { return; } foreach (KeyValuePair item2 in dictionary) { YamlNode value = children[item2.Key]; children.Remove(item2.Key); children.Add(item2.Value, value); } } internal override void Emit(IEmitter emitter, EmitterState state) { emitter.Emit(new MappingStart(base.Anchor, base.Tag, isImplicit: true, Style)); foreach (KeyValuePair child in children) { child.Key.Save(emitter, state); child.Value.Save(emitter, state); } emitter.Emit(new MappingEnd()); } public override void Accept(IYamlVisitor visitor) { visitor.Visit(this); } public override bool Equals(object? obj) { if (!(obj is YamlMappingNode yamlMappingNode) || !object.Equals(base.Tag, yamlMappingNode.Tag) || children.Count != yamlMappingNode.children.Count) { return false; } foreach (KeyValuePair child in children) { if (!yamlMappingNode.children.TryGetValue(child.Key, out YamlNode value) || !object.Equals(child.Value, value)) { return false; } } return true; } public override int GetHashCode() { int num = base.GetHashCode(); foreach (KeyValuePair child in children) { num = YamlDotNet.Core.HashCode.CombineHashCodes(num, child.Key); num = (child.Value.Anchor.IsEmpty ? YamlDotNet.Core.HashCode.CombineHashCodes(num, child.Value) : YamlDotNet.Core.HashCode.CombineHashCodes(num, child.Value.Anchor)); } return num; } internal override IEnumerable SafeAllNodes(RecursionLevel level) { level.Increment(); yield return this; foreach (KeyValuePair child in children) { foreach (YamlNode item in child.Key.SafeAllNodes(level)) { yield return item; } foreach (YamlNode item2 in child.Value.SafeAllNodes(level)) { yield return item2; } } level.Decrement(); } internal override string ToString(RecursionLevel level) { if (!level.TryIncrement()) { return "WARNING! INFINITE RECURSION!"; } StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; builder.Append("{ "); foreach (KeyValuePair child in children) { if (builder.Length > 2) { builder.Append(", "); } builder.Append("{ ").Append(child.Key.ToString(level)).Append(", ") .Append(child.Value.ToString(level)) .Append(" }"); } builder.Append(" }"); level.Decrement(); return builder.ToString(); } finally { ((IDisposable)builderWrapper).Dispose(); } } public IEnumerator> GetEnumerator() { return children.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer) { Load(parser, new DocumentLoadingState()); } void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer) { Emit(emitter, new EmitterState()); } public static YamlMappingNode FromObject(object mapping) { if (mapping == null) { throw new ArgumentNullException("mapping"); } YamlMappingNode yamlMappingNode = new YamlMappingNode(); foreach (PropertyInfo publicProperty in mapping.GetType().GetPublicProperties()) { if (publicProperty.CanRead && publicProperty.GetGetMethod(nonPublic: false).GetParameters().Length == 0) { object value = publicProperty.GetValue(mapping, null); YamlNode yamlNode = value as YamlNode; if (yamlNode == null) { string text = Convert.ToString(value, CultureInfo.InvariantCulture); yamlNode = text ?? string.Empty; } yamlMappingNode.Add(publicProperty.Name, yamlNode); } } return yamlMappingNode; } } internal abstract class YamlNode { private const int MaximumRecursionLevel = 1000; internal const string MaximumRecursionLevelReachedToStringValue = "WARNING! INFINITE RECURSION!"; public AnchorName Anchor { get; set; } public TagName Tag { get; set; } public Mark Start { get; private set; } = Mark.Empty; public Mark End { get; private set; } = Mark.Empty; public IEnumerable AllNodes { get { RecursionLevel level = new RecursionLevel(1000); return SafeAllNodes(level); } } public abstract YamlNodeType NodeType { get; } public YamlNode this[int index] { get { if (!(this is YamlSequenceNode yamlSequenceNode)) { throw new ArgumentException($"Accessed '{NodeType}' with an invalid index: {index}. Only Sequences can be indexed by number."); } return yamlSequenceNode.Children[index]; } } public YamlNode this[YamlNode key] { get { if (!(this is YamlMappingNode yamlMappingNode)) { throw new ArgumentException($"Accessed '{NodeType}' with an invalid index: {key}. Only Mappings can be indexed by key."); } return yamlMappingNode.Children[key]; } } internal void Load(NodeEvent yamlEvent, DocumentLoadingState state) { Tag = yamlEvent.Tag; if (!yamlEvent.Anchor.IsEmpty) { Anchor = yamlEvent.Anchor; state.AddAnchor(this); } Start = yamlEvent.Start; End = yamlEvent.End; } internal static YamlNode ParseNode(IParser parser, DocumentLoadingState state) { if (parser.Accept(out var _)) { return new YamlScalarNode(parser, state); } if (parser.Accept(out var _)) { return new YamlSequenceNode(parser, state); } if (parser.Accept(out var _)) { return new YamlMappingNode(parser, state); } if (parser.TryConsume(out var event4)) { if (!state.TryGetNode(event4.Value, out YamlNode node)) { return new YamlAliasNode(event4.Value); } return node; } throw new ArgumentException("The current event is of an unsupported type.", "parser"); } internal abstract void ResolveAliases(DocumentLoadingState state); internal void Save(IEmitter emitter, EmitterState state) { if (!Anchor.IsEmpty && !state.EmittedAnchors.Add(Anchor)) { emitter.Emit(new YamlDotNet.Core.Events.AnchorAlias(Anchor)); } else { Emit(emitter, state); } } internal abstract void Emit(IEmitter emitter, EmitterState state); public abstract void Accept(IYamlVisitor visitor); public override string ToString() { RecursionLevel recursionLevel = new RecursionLevel(1000); return ToString(recursionLevel); } internal abstract string ToString(RecursionLevel level); internal abstract IEnumerable SafeAllNodes(RecursionLevel level); public static implicit operator YamlNode(string value) { return new YamlScalarNode(value); } public static implicit operator YamlNode(string[] sequence) { return new YamlSequenceNode(((IEnumerable)sequence).Select((Func)((string i) => i))); } public static explicit operator string?(YamlNode node) { if (!(node is YamlScalarNode yamlScalarNode)) { throw new ArgumentException($"Attempted to convert a '{node.NodeType}' to string. This conversion is valid only for Scalars."); } return yamlScalarNode.Value; } } internal sealed class YamlNodeIdentityEqualityComparer : IEqualityComparer { public bool Equals([AllowNull] YamlNode x, [AllowNull] YamlNode y) { return x == y; } public int GetHashCode(YamlNode obj) { return obj.GetHashCode(); } } internal enum YamlNodeType { Alias, Mapping, Scalar, Sequence } [DebuggerDisplay("{Value}")] internal sealed class YamlScalarNode : YamlNode, IYamlConvertible { private bool forceImplicitPlain; private string? value; public string? Value { get { return value; } set { if (value == null) { forceImplicitPlain = true; } else { forceImplicitPlain = false; } this.value = value; } } public ScalarStyle Style { get; set; } public override YamlNodeType NodeType => YamlNodeType.Scalar; internal YamlScalarNode(IParser parser, DocumentLoadingState state) { Load(parser, state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Load(IParser parser, DocumentLoadingState state) { YamlDotNet.Core.Events.Scalar scalar = parser.Consume(); Load(scalar, state); string text = scalar.Value; if (scalar.Style == ScalarStyle.Plain && base.Tag.IsEmpty) { forceImplicitPlain = text.Length switch { 0 => true, 1 => text == "~", 4 => text == "null" || text == "Null" || text == "NULL", _ => false, }; } value = text; Style = scalar.Style; } public YamlScalarNode() { } public YamlScalarNode(string? value) { Value = value; } internal override void ResolveAliases(DocumentLoadingState state) { throw new NotSupportedException("Resolving an alias on a scalar node does not make sense"); } internal override void Emit(IEmitter emitter, EmitterState state) { TagName tag = base.Tag; bool isPlainImplicit = tag.IsEmpty; if (forceImplicitPlain && Style == ScalarStyle.Plain && (Value == null || Value == "")) { tag = JsonSchema.Tags.Null; isPlainImplicit = true; } else if (tag.IsEmpty && Value == null && (Style == ScalarStyle.Plain || Style == ScalarStyle.Any)) { tag = JsonSchema.Tags.Null; isPlainImplicit = true; } emitter.Emit(new YamlDotNet.Core.Events.Scalar(base.Anchor, tag, Value ?? string.Empty, Style, isPlainImplicit, isQuotedImplicit: false)); } public override void Accept(IYamlVisitor visitor) { visitor.Visit(this); } public override bool Equals(object? obj) { if (obj is YamlScalarNode yamlScalarNode && object.Equals(base.Tag, yamlScalarNode.Tag)) { return object.Equals(Value, yamlScalarNode.Value); } return false; } public override int GetHashCode() { return YamlDotNet.Core.HashCode.CombineHashCodes(base.Tag.GetHashCode(), Value); } public static explicit operator string?(YamlScalarNode value) { return value.Value; } internal override string ToString(RecursionLevel level) { return Value ?? string.Empty; } internal override IEnumerable SafeAllNodes(RecursionLevel level) { yield return this; } void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer) { Load(parser, new DocumentLoadingState()); } void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer) { Emit(emitter, new EmitterState()); } } [DebuggerDisplay("Count = {children.Count}")] internal sealed class YamlSequenceNode : YamlNode, IEnumerable, IEnumerable, IYamlConvertible { private readonly List children = new List(); public IList Children => children; public SequenceStyle Style { get; set; } public override YamlNodeType NodeType => YamlNodeType.Sequence; internal YamlSequenceNode(IParser parser, DocumentLoadingState state) { Load(parser, state); } private void Load(IParser parser, DocumentLoadingState state) { SequenceStart sequenceStart = parser.Consume(); Load(sequenceStart, state); Style = sequenceStart.Style; bool flag = false; SequenceEnd @event; while (!parser.TryConsume(out @event)) { YamlNode yamlNode = YamlNode.ParseNode(parser, state); children.Add(yamlNode); flag = flag || yamlNode is YamlAliasNode; } if (flag) { state.AddNodeWithUnresolvedAliases(this); } } public YamlSequenceNode() { } public YamlSequenceNode(params YamlNode[] children) : this((IEnumerable)children) { } public YamlSequenceNode(IEnumerable children) { foreach (YamlNode child in children) { this.children.Add(child); } } public void Add(YamlNode child) { children.Add(child); } public void Add(string child) { children.Add(new YamlScalarNode(child)); } internal override void ResolveAliases(DocumentLoadingState state) { for (int i = 0; i < children.Count; i++) { if (children[i] is YamlAliasNode) { children[i] = state.GetNode(children[i].Anchor, children[i].Start, children[i].End); } } } internal override void Emit(IEmitter emitter, EmitterState state) { emitter.Emit(new SequenceStart(base.Anchor, base.Tag, base.Tag.IsEmpty, Style)); foreach (YamlNode child in children) { child.Save(emitter, state); } emitter.Emit(new SequenceEnd()); } public override void Accept(IYamlVisitor visitor) { visitor.Visit(this); } public override bool Equals(object? obj) { if (!(obj is YamlSequenceNode yamlSequenceNode) || !object.Equals(base.Tag, yamlSequenceNode.Tag) || children.Count != yamlSequenceNode.children.Count) { return false; } for (int i = 0; i < children.Count; i++) { if (!object.Equals(children[i], yamlSequenceNode.children[i])) { return false; } } return true; } public override int GetHashCode() { int h = 0; foreach (YamlNode child in children) { h = YamlDotNet.Core.HashCode.CombineHashCodes(h, child); } return YamlDotNet.Core.HashCode.CombineHashCodes(h, base.Tag); } internal override IEnumerable SafeAllNodes(RecursionLevel level) { level.Increment(); yield return this; foreach (YamlNode child in children) { foreach (YamlNode item in child.SafeAllNodes(level)) { yield return item; } } level.Decrement(); } internal override string ToString(RecursionLevel level) { if (!level.TryIncrement()) { return "WARNING! INFINITE RECURSION!"; } StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; builder.Append("[ "); foreach (YamlNode child in children) { if (builder.Length > 2) { builder.Append(", "); } builder.Append(child.ToString(level)); } builder.Append(" ]"); level.Decrement(); return builder.ToString(); } finally { ((IDisposable)builderWrapper).Dispose(); } } public IEnumerator GetEnumerator() { return Children.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer) { Load(parser, new DocumentLoadingState()); } void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer) { Emit(emitter, new EmitterState()); } } internal class YamlStream : IEnumerable, IEnumerable { private readonly List documents = new List(); public IList Documents => documents; public YamlStream() { } public YamlStream(params YamlDocument[] documents) : this((IEnumerable)documents) { } public YamlStream(IEnumerable documents) { foreach (YamlDocument document in documents) { this.documents.Add(document); } } public void Add(YamlDocument document) { documents.Add(document); } public void Load(TextReader input) { Load(new Parser(input)); } public void Load(IParser parser) { documents.Clear(); parser.Consume(); YamlDotNet.Core.Events.StreamEnd @event; while (!parser.TryConsume(out @event)) { YamlDocument item = new YamlDocument(parser); documents.Add(item); } } public void Save(TextWriter output) { Save(output, assignAnchors: true); } public void Save(TextWriter output, bool assignAnchors) { Save(new Emitter(output), assignAnchors); } public void Save(IEmitter emitter, bool assignAnchors) { emitter.Emit(new YamlDotNet.Core.Events.StreamStart()); foreach (YamlDocument document in documents) { document.Save(emitter, assignAnchors); } emitter.Emit(new YamlDotNet.Core.Events.StreamEnd()); } public void Accept(IYamlVisitor visitor) { visitor.Visit(this); } public IEnumerator GetEnumerator() { return documents.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [Obsolete("Use YamlVisitorBase")] internal abstract class YamlVisitor : IYamlVisitor { protected virtual void Visit(YamlStream stream) { } protected virtual void Visited(YamlStream stream) { } protected virtual void Visit(YamlDocument document) { } protected virtual void Visited(YamlDocument document) { } protected virtual void Visit(YamlScalarNode scalar) { } protected virtual void Visited(YamlScalarNode scalar) { } protected virtual void Visit(YamlSequenceNode sequence) { } protected virtual void Visited(YamlSequenceNode sequence) { } protected virtual void Visit(YamlMappingNode mapping) { } protected virtual void Visited(YamlMappingNode mapping) { } protected virtual void VisitChildren(YamlStream stream) { foreach (YamlDocument document in stream.Documents) { document.Accept(this); } } protected virtual void VisitChildren(YamlDocument document) { if (document.RootNode != null) { document.RootNode.Accept(this); } } protected virtual void VisitChildren(YamlSequenceNode sequence) { foreach (YamlNode child in sequence.Children) { child.Accept(this); } } protected virtual void VisitChildren(YamlMappingNode mapping) { foreach (KeyValuePair child in mapping.Children) { child.Key.Accept(this); child.Value.Accept(this); } } void IYamlVisitor.Visit(YamlStream stream) { Visit(stream); VisitChildren(stream); Visited(stream); } void IYamlVisitor.Visit(YamlDocument document) { Visit(document); VisitChildren(document); Visited(document); } void IYamlVisitor.Visit(YamlScalarNode scalar) { Visit(scalar); Visited(scalar); } void IYamlVisitor.Visit(YamlSequenceNode sequence) { Visit(sequence); VisitChildren(sequence); Visited(sequence); } void IYamlVisitor.Visit(YamlMappingNode mapping) { Visit(mapping); VisitChildren(mapping); Visited(mapping); } } internal abstract class YamlVisitorBase : IYamlVisitor { public virtual void Visit(YamlStream stream) { VisitChildren(stream); } public virtual void Visit(YamlDocument document) { VisitChildren(document); } public virtual void Visit(YamlScalarNode scalar) { } public virtual void Visit(YamlSequenceNode sequence) { VisitChildren(sequence); } public virtual void Visit(YamlMappingNode mapping) { VisitChildren(mapping); } protected virtual void VisitPair(YamlNode key, YamlNode value) { key.Accept(this); value.Accept(this); } protected virtual void VisitChildren(YamlStream stream) { foreach (YamlDocument document in stream.Documents) { document.Accept(this); } } protected virtual void VisitChildren(YamlDocument document) { if (document.RootNode != null) { document.RootNode.Accept(this); } } protected virtual void VisitChildren(YamlSequenceNode sequence) { foreach (YamlNode child in sequence.Children) { child.Accept(this); } } protected virtual void VisitChildren(YamlMappingNode mapping) { foreach (KeyValuePair child in mapping.Children) { VisitPair(child.Key, child.Value); } } } } namespace YamlDotNet.Helpers { internal static class DictionaryExtensions { public static bool TryAdd(this Dictionary dictionary, T key, V value) { if (dictionary.ContainsKey(key)) { return false; } dictionary.Add(key, value); return true; } public static TValue GetOrAdd(this ConcurrentDictionary dictionary, TKey key, Func valueFactory, TArg arg) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } if (key == null) { throw new ArgumentNullException("key"); } if (valueFactory == null) { throw new ArgumentNullException("valueFactory"); } TValue value; do { if (dictionary.TryGetValue(key, out value)) { return value; } value = valueFactory(key, arg); } while (!dictionary.TryAdd(key, value)); return value; } } internal static class ExpressionExtensions { public static PropertyInfo AsProperty(this LambdaExpression propertyAccessor) { PropertyInfo propertyInfo = TryGetMemberExpression(propertyAccessor); if (propertyInfo == null) { throw new ArgumentException("Expected a lambda expression in the form: x => x.SomeProperty", "propertyAccessor"); } return propertyInfo; } [return: MaybeNull] private static TMemberInfo TryGetMemberExpression(LambdaExpression lambdaExpression) where TMemberInfo : MemberInfo { if (lambdaExpression.Parameters.Count != 1) { return null; } Expression expression = lambdaExpression.Body; if (expression is UnaryExpression unaryExpression) { if (unaryExpression.NodeType != ExpressionType.Convert) { return null; } expression = unaryExpression.Operand; } if (expression is MemberExpression memberExpression) { if (memberExpression.Expression != lambdaExpression.Parameters[0]) { return null; } return memberExpression.Member as TMemberInfo; } return null; } } internal static class FsharpHelper { private static bool IsFsharpCore(Type t) { return t.Namespace == "Microsoft.FSharp.Core"; } public static bool IsOptionType(Type t) { if (IsFsharpCore(t)) { return t.Name == "FSharpOption`1"; } return false; } public static Type? GetOptionUnderlyingType(Type t) { if (!t.IsGenericType || !IsOptionType(t)) { return null; } return t.GenericTypeArguments[0]; } public static object? GetValue(IObjectDescriptor objectDescriptor) { if (!IsOptionType(objectDescriptor.Type)) { throw new InvalidOperationException("Should not be called on non-Option<> type"); } if (objectDescriptor.Value == null) { return null; } return objectDescriptor.Type.GetProperty("Value").GetValue(objectDescriptor.Value); } public static bool IsFsharpListType(Type t) { if (t.Namespace == "Microsoft.FSharp.Collections") { return t.Name == "FSharpList`1"; } return false; } public static object? CreateFsharpListFromArray(Type t, Type itemsType, Array arr) { if (!IsFsharpListType(t)) { return null; } return t.Assembly.GetType("Microsoft.FSharp.Collections.ListModule").GetMethod("OfArray").MakeGenericMethod(itemsType) .Invoke(null, new object[1] { arr }); } } internal sealed class GenericCollectionToNonGenericAdapter : IList, ICollection, IEnumerable { private readonly ICollection genericCollection; public bool IsFixedSize { get { throw new NotSupportedException(); } } public bool IsReadOnly { get { throw new NotSupportedException(); } } public object? this[int index] { get { throw new NotSupportedException(); } set { ((IList)genericCollection)[index] = (T)value; } } public int Count { get { throw new NotSupportedException(); } } public bool IsSynchronized { get { throw new NotSupportedException(); } } public object SyncRoot { get { throw new NotSupportedException(); } } public GenericCollectionToNonGenericAdapter(ICollection genericCollection) { this.genericCollection = genericCollection ?? throw new ArgumentNullException("genericCollection"); } public int Add(object? value) { int count = genericCollection.Count; genericCollection.Add((T)value); return count; } public void Clear() { genericCollection.Clear(); } public bool Contains(object? value) { throw new NotSupportedException(); } public int IndexOf(object? value) { throw new NotSupportedException(); } public void Insert(int index, object? value) { throw new NotSupportedException(); } public void Remove(object? value) { throw new NotSupportedException(); } public void RemoveAt(int index) { throw new NotSupportedException(); } public void CopyTo(Array array, int index) { throw new NotSupportedException(); } public IEnumerator GetEnumerator() { return genericCollection.GetEnumerator(); } } internal sealed class GenericDictionaryToNonGenericAdapter : IDictionary, ICollection, IEnumerable where TKey : notnull { private class DictionaryEnumerator : IDictionaryEnumerator, IEnumerator { private readonly IEnumerator> enumerator; public DictionaryEntry Entry => new DictionaryEntry(Key, Value); public object Key => enumerator.Current.Key; public object? Value => enumerator.Current.Value; public object Current => Entry; public DictionaryEnumerator(IEnumerator> enumerator) { this.enumerator = enumerator; } public bool MoveNext() { return enumerator.MoveNext(); } public void Reset() { enumerator.Reset(); } } private readonly IDictionary genericDictionary; public bool IsFixedSize { get { throw new NotSupportedException(); } } public bool IsReadOnly { get { throw new NotSupportedException(); } } public ICollection Keys { get { throw new NotSupportedException(); } } public ICollection Values { get { throw new NotSupportedException(); } } public object? this[object key] { get { throw new NotSupportedException(); } set { genericDictionary[(TKey)key] = (TValue)value; } } public int Count { get { throw new NotSupportedException(); } } public bool IsSynchronized { get { throw new NotSupportedException(); } } public object SyncRoot { get { throw new NotSupportedException(); } } public GenericDictionaryToNonGenericAdapter(IDictionary genericDictionary) { this.genericDictionary = genericDictionary ?? throw new ArgumentNullException("genericDictionary"); } public void Add(object key, object? value) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public bool Contains(object key) { throw new NotSupportedException(); } public IDictionaryEnumerator GetEnumerator() { return new DictionaryEnumerator(genericDictionary.GetEnumerator()); } public void Remove(object key) { throw new NotSupportedException(); } public void CopyTo(Array array, int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal interface IOrderedDictionary : IDictionary, ICollection>, IEnumerable>, IEnumerable where TKey : notnull { KeyValuePair this[int index] { get; set; } void Insert(int index, TKey key, TValue value); void RemoveAt(int index); } internal static class NumberExtensions { public static bool IsPowerOfTwo(this int value) { return (value & (value - 1)) == 0; } } [Serializable] internal sealed class OrderedDictionary : IOrderedDictionary, IDictionary, ICollection>, IEnumerable>, IEnumerable where TKey : notnull { private class KeyCollection : ICollection, IEnumerable, IEnumerable { private readonly OrderedDictionary orderedDictionary; public int Count => orderedDictionary.list.Count; public bool IsReadOnly => true; public void Add(TKey item) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public bool Contains(TKey item) { return orderedDictionary.dictionary.ContainsKey(item); } public KeyCollection(OrderedDictionary orderedDictionary) { this.orderedDictionary = orderedDictionary; } public void CopyTo(TKey[] array, int arrayIndex) { for (int i = 0; i < orderedDictionary.list.Count; i++) { array[i] = orderedDictionary.list[i + arrayIndex].Key; } } public IEnumerator GetEnumerator() { return orderedDictionary.list.Select((KeyValuePair kvp) => kvp.Key).GetEnumerator(); } public bool Remove(TKey item) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } private class ValueCollection : ICollection, IEnumerable, IEnumerable { private readonly OrderedDictionary orderedDictionary; public int Count => orderedDictionary.list.Count; public bool IsReadOnly => true; public void Add(TValue item) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public bool Contains(TValue item) { return orderedDictionary.dictionary.ContainsValue(item); } public ValueCollection(OrderedDictionary orderedDictionary) { this.orderedDictionary = orderedDictionary; } public void CopyTo(TValue[] array, int arrayIndex) { for (int i = 0; i < orderedDictionary.list.Count; i++) { array[i] = orderedDictionary.list[i + arrayIndex].Value; } } public IEnumerator GetEnumerator() { return orderedDictionary.list.Select((KeyValuePair kvp) => kvp.Value).GetEnumerator(); } public bool Remove(TValue item) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [NonSerialized] private Dictionary dictionary; private readonly List> list; private readonly IEqualityComparer comparer; public TValue this[TKey key] { get { return dictionary[key]; } set { TKey key2 = key; if (dictionary.ContainsKey(key2)) { int index = list.FindIndex((KeyValuePair kvp) => comparer.Equals(kvp.Key, key2)); dictionary[key2] = value; list[index] = new KeyValuePair(key2, value); } else { Add(key2, value); } } } public ICollection Keys => new KeyCollection(this); public ICollection Values => new ValueCollection(this); public int Count => dictionary.Count; public bool IsReadOnly => false; public KeyValuePair this[int index] { get { return list[index]; } set { list[index] = value; } } public OrderedDictionary() : this((IEqualityComparer)EqualityComparer.Default) { } public OrderedDictionary(IEqualityComparer comparer) { list = new List>(); dictionary = new Dictionary(comparer); this.comparer = comparer; } public void Add(KeyValuePair item) { if (!TryAdd(item)) { ThrowDuplicateKeyException(item.Key); } } public void Add(TKey key, TValue value) { if (!TryAdd(key, value)) { ThrowDuplicateKeyException(key); } } private static void ThrowDuplicateKeyException(TKey key) { throw new ArgumentException($"An item with the same key {key} has already been added."); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryAdd(TKey key, TValue value) { if (DictionaryExtensions.TryAdd(dictionary, key, value)) { list.Add(new KeyValuePair(key, value)); return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryAdd(KeyValuePair item) { if (DictionaryExtensions.TryAdd(dictionary, item.Key, item.Value)) { list.Add(item); return true; } return false; } public void Clear() { dictionary.Clear(); list.Clear(); } public bool Contains(KeyValuePair item) { return dictionary.Contains(item); } public bool ContainsKey(TKey key) { return dictionary.ContainsKey(key); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { list.CopyTo(array, arrayIndex); } public IEnumerator> GetEnumerator() { return list.GetEnumerator(); } public void Insert(int index, TKey key, TValue value) { dictionary.Add(key, value); list.Insert(index, new KeyValuePair(key, value)); } public bool Remove(TKey key) { TKey key2 = key; if (dictionary.ContainsKey(key2)) { int index = list.FindIndex((KeyValuePair kvp) => comparer.Equals(kvp.Key, key2)); list.RemoveAt(index); if (!dictionary.Remove(key2)) { throw new InvalidOperationException(); } return true; } return false; } public bool Remove(KeyValuePair item) { return Remove(item.Key); } public void RemoveAt(int index) { TKey key = list[index].Key; dictionary.Remove(key); list.RemoveAt(index); } public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) { return dictionary.TryGetValue(key, out value); } IEnumerator IEnumerable.GetEnumerator() { return list.GetEnumerator(); } [System.Runtime.Serialization.OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { dictionary = new Dictionary(); foreach (KeyValuePair item in list) { dictionary[item.Key] = item.Value; } } } internal static class ReadOnlyCollectionExtensions { public static IReadOnlyList AsReadonlyList(this List list) { return list; } public static IReadOnlyDictionary AsReadonlyDictionary(this Dictionary dictionary) where TKey : notnull { return dictionary; } } internal static class ThrowHelper { [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowArgumentOutOfRangeException(string paramName, string message) { throw new ArgumentOutOfRangeException(paramName, message); } } } namespace YamlDotNet.Core { public readonly struct AnchorName : IEquatable { public static readonly AnchorName Empty; private static readonly Regex AnchorPattern = new Regex("^[^\\[\\]\\{\\},]+$", RegexOptions.Compiled); private readonly string? value; public string Value => value ?? throw new InvalidOperationException("Cannot read the Value of an empty anchor"); public bool IsEmpty => value == null; public AnchorName(string value) { this.value = value ?? throw new ArgumentNullException("value"); if (!AnchorPattern.IsMatch(value)) { throw new ArgumentException("Anchor cannot be empty or contain disallowed characters: []{},\nThe value was '" + value + "'.", "value"); } } public override string ToString() { return value ?? "[empty]"; } public bool Equals(AnchorName other) { return object.Equals(value, other.value); } public override bool Equals(object? obj) { if (obj is AnchorName other) { return Equals(other); } return false; } public override int GetHashCode() { return value?.GetHashCode() ?? 0; } public static bool operator ==(AnchorName left, AnchorName right) { return left.Equals(right); } public static bool operator !=(AnchorName left, AnchorName right) { return !(left == right); } public static implicit operator AnchorName(string? value) { if (value != null) { return new AnchorName(value); } return Empty; } } internal class AnchorNotFoundException : YamlException { public AnchorNotFoundException(string message) : base(message) { } public AnchorNotFoundException(in Mark start, in Mark end, string message) : base(in start, in end, message) { } public AnchorNotFoundException(string message, Exception inner) : base(message, inner) { } } [DebuggerStepThrough] internal readonly struct CharacterAnalyzer where TBuffer : ILookAheadBuffer { public TBuffer Buffer { get; } public bool EndOfInput => Buffer.EndOfInput; public CharacterAnalyzer(TBuffer buffer) { if (buffer == null) { throw new ArgumentNullException("buffer"); } Buffer = buffer; } public char Peek(int offset) { return Buffer.Peek(offset); } public void Skip(int length) { Buffer.Skip(length); } public bool IsAlphaNumericDashOrUnderscore(int offset = 0) { char c = Buffer.Peek(offset); if ((c < '0' || c > '9') && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && c != '_') { return c == '-'; } return true; } public bool IsAscii(int offset = 0) { return Buffer.Peek(offset) <= '\u007f'; } public bool IsPrintable(int offset = 0) { char c = Buffer.Peek(offset); switch (c) { default: if (c != '\u0085' && (c < '\u00a0' || c > '\ud7ff')) { if (c >= '\ue000') { return c <= '\ufffd'; } return false; } break; case '\t': case '\n': case '\r': case ' ': case '!': case '"': case '#': case '$': case '%': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '<': case '=': case '>': case '?': case '@': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '[': case '\\': case ']': case '^': case '_': case '`': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}': case '~': break; } return true; } public bool IsDigit(int offset = 0) { char c = Buffer.Peek(offset); if (c >= '0') { return c <= '9'; } return false; } public int AsDigit(int offset = 0) { return Buffer.Peek(offset) - 48; } public bool IsHex(int offset) { char c = Buffer.Peek(offset); if ((c < '0' || c > '9') && (c < 'A' || c > 'F')) { if (c >= 'a') { return c <= 'f'; } return false; } return true; } public int AsHex(int offset) { char c = Buffer.Peek(offset); if (c <= '9') { return c - 48; } if (c <= 'F') { return c - 65 + 10; } return c - 97 + 10; } public bool IsSpace(int offset = 0) { return Check(' ', offset); } public bool IsZero(int offset = 0) { return Check('\0', offset); } public bool IsTab(int offset = 0) { return Check('\t', offset); } public bool IsWhite(int offset = 0) { if (!IsSpace(offset)) { return IsTab(offset); } return true; } public bool IsBreak(int offset = 0) { return Check("\r\n\u0085\u2028\u2029", offset); } public bool IsCrLf(int offset = 0) { if (Check('\r', offset)) { return Check('\n', offset + 1); } return false; } public bool IsBreakOrZero(int offset = 0) { if (!IsBreak(offset)) { return IsZero(offset); } return true; } public bool IsWhiteBreakOrZero(int offset = 0) { if (!IsWhite(offset)) { return IsBreakOrZero(offset); } return true; } public bool Check(char expected, int offset = 0) { return Buffer.Peek(offset) == expected; } public bool Check(string expectedCharacters, int offset = 0) { char c = Buffer.Peek(offset); return Polyfills.Contains(expectedCharacters, c); } } internal static class Constants { public static readonly TagDirective[] DefaultTagDirectives = new TagDirective[2] { new TagDirective("!", "!"), new TagDirective("!!", "tag:yaml.org,2002:") }; public const int MajorVersion = 1; public const int MinorVersion = 3; } [DebuggerStepThrough] internal sealed class Cursor { public long Index { get; private set; } public long Line { get; private set; } public long LineOffset { get; private set; } public Cursor() { Line = 1L; } public Cursor(Cursor cursor) { Index = cursor.Index; Line = cursor.Line; LineOffset = cursor.LineOffset; } public Mark Mark() { return new Mark(Index, Line, LineOffset + 1); } public void Skip() { Index++; LineOffset++; } public void SkipLineByOffset(int offset) { Index += offset; Line++; LineOffset = 0L; } public void ForceSkipLineAfterNonBreak() { if (LineOffset != 0L) { Line++; LineOffset = 0L; } } } internal class Emitter : IEmitter { private class AnchorData { public AnchorName Anchor; public bool IsAlias; } private class TagData { public string? Handle; public string? Suffix; } private class ScalarData { public string Value = string.Empty; public bool IsMultiline; public bool IsFlowPlainAllowed; public bool IsBlockPlainAllowed; public bool IsSingleQuotedAllowed; public bool IsBlockAllowed; public bool HasSingleQuotes; public ScalarStyle Style; } private static readonly Regex UriReplacer = new Regex("[^0-9A-Za-z_\\-;?@=$~\\\\\\)\\]/:&+,\\.\\*\\(\\[!]", RegexOptions.Compiled | RegexOptions.Singleline); private static readonly string[] NewLineSeparators = new string[3] { "\r\n", "\r", "\n" }; private readonly TextWriter output; private readonly bool outputUsesUnicodeEncoding; private readonly int maxSimpleKeyLength; private readonly bool isCanonical; private readonly bool skipAnchorName; private readonly int bestIndent; private readonly int bestWidth; private EmitterState state; private readonly Stack states = new Stack(); private readonly Queue events = new Queue(); private readonly Stack indents = new Stack(); private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); private int indent; private int flowLevel; private bool isMappingContext; private bool isSimpleKeyContext; private int column; private bool isWhitespace; private bool isIndentation; private readonly bool forceIndentLess; private readonly string newLine; private bool isDocumentEndWritten; private readonly AnchorData anchorData = new AnchorData(); private readonly TagData tagData = new TagData(); private readonly ScalarData scalarData = new ScalarData(); public Emitter(TextWriter output) : this(output, EmitterSettings.Default) { } public Emitter(TextWriter output, int bestIndent) : this(output, bestIndent, int.MaxValue) { } public Emitter(TextWriter output, int bestIndent, int bestWidth) : this(output, bestIndent, bestWidth, isCanonical: false) { } public Emitter(TextWriter output, int bestIndent, int bestWidth, bool isCanonical) : this(output, new EmitterSettings(bestIndent, bestWidth, isCanonical, 1024)) { } public Emitter(TextWriter output, EmitterSettings settings) { bestIndent = settings.BestIndent; bestWidth = settings.BestWidth; isCanonical = settings.IsCanonical; maxSimpleKeyLength = settings.MaxSimpleKeyLength; skipAnchorName = settings.SkipAnchorName; forceIndentLess = !settings.IndentSequences; newLine = settings.NewLine; this.output = output; outputUsesUnicodeEncoding = IsUnicode(output.Encoding); } public void Emit(ParsingEvent @event) { events.Enqueue(@event); while (!NeedMoreEvents()) { ParsingEvent evt = events.Peek(); try { AnalyzeEvent(evt); StateMachine(evt); } finally { events.Dequeue(); } } } private bool NeedMoreEvents() { if (events.Count == 0) { return true; } int num; switch (events.Peek().Type) { case EventType.DocumentStart: num = 1; break; case EventType.SequenceStart: num = 2; break; case EventType.MappingStart: num = 3; break; default: return false; } if (events.Count > num) { return false; } int num2 = 0; foreach (ParsingEvent @event in events) { switch (@event.Type) { case EventType.DocumentStart: case EventType.SequenceStart: case EventType.MappingStart: num2++; break; case EventType.DocumentEnd: case EventType.SequenceEnd: case EventType.MappingEnd: num2--; break; } if (num2 == 0) { return false; } } return true; } private void AnalyzeEvent(ParsingEvent evt) { anchorData.Anchor = AnchorName.Empty; tagData.Handle = null; tagData.Suffix = null; if (evt is YamlDotNet.Core.Events.AnchorAlias anchorAlias) { AnalyzeAnchor(anchorAlias.Value, isAlias: true); } else if (evt is NodeEvent nodeEvent) { if (evt is YamlDotNet.Core.Events.Scalar scalar) { AnalyzeScalar(scalar); } AnalyzeAnchor(nodeEvent.Anchor, isAlias: false); if (!nodeEvent.Tag.IsEmpty && (isCanonical || nodeEvent.IsCanonical)) { AnalyzeTag(nodeEvent.Tag); } } } private void AnalyzeAnchor(AnchorName anchor, bool isAlias) { anchorData.Anchor = anchor; anchorData.IsAlias = isAlias; } private void AnalyzeScalar(YamlDotNet.Core.Events.Scalar scalar) { string value = scalar.Value; scalarData.Value = value; if (value.Length == 0) { if (scalar.Tag == "tag:yaml.org,2002:null") { scalarData.IsMultiline = false; scalarData.IsFlowPlainAllowed = false; scalarData.IsBlockPlainAllowed = true; scalarData.IsSingleQuotedAllowed = false; scalarData.IsBlockAllowed = false; } else { scalarData.IsMultiline = false; scalarData.IsFlowPlainAllowed = false; scalarData.IsBlockPlainAllowed = false; scalarData.IsSingleQuotedAllowed = true; scalarData.IsBlockAllowed = false; } return; } bool flag = false; bool flag2 = false; if (value.StartsWith("---", StringComparison.Ordinal) || value.StartsWith("...", StringComparison.Ordinal)) { flag = true; flag2 = true; } StringLookAheadBufferPool.BufferWrapper bufferWrapper = StringLookAheadBufferPool.Rent(value); try { CharacterAnalyzer characterAnalyzer = new CharacterAnalyzer(bufferWrapper.Buffer); bool flag3 = true; bool flag4 = characterAnalyzer.IsWhiteBreakOrZero(1); bool flag5 = false; bool flag6 = false; bool flag7 = false; bool flag8 = false; bool flag9 = false; bool flag10 = false; bool flag11 = false; bool flag12 = false; bool flag13 = false; bool flag14 = false; bool flag15 = false; bool flag16 = !ValueIsRepresentableInOutputEncoding(value); bool flag17 = false; bool flag18 = false; bool flag19 = true; while (!characterAnalyzer.EndOfInput) { if (flag19) { if (characterAnalyzer.Check("#,[]{}&*!|>\"%@`'")) { flag = true; flag2 = true; flag9 = characterAnalyzer.Check('\''); flag17 |= characterAnalyzer.Check('\''); } if (characterAnalyzer.Check("?:")) { flag = true; if (flag4) { flag2 = true; } } if (characterAnalyzer.Check('-') && flag4) { flag = true; flag2 = true; } } else { if (characterAnalyzer.Check(",?[]{}")) { flag = true; } if (characterAnalyzer.Check(':')) { flag = true; if (flag4) { flag2 = true; } } if (characterAnalyzer.Check('#') && flag3) { flag = true; flag2 = true; } flag17 |= characterAnalyzer.Check('\''); } if (!flag16 && !characterAnalyzer.IsPrintable()) { flag16 = true; } if (characterAnalyzer.IsBreak()) { flag15 = true; } if (characterAnalyzer.IsSpace()) { if (flag19) { flag5 = true; } if (characterAnalyzer.Buffer.Position >= characterAnalyzer.Buffer.Length - 1) { flag7 = true; } if (flag13) { flag10 = true; flag14 = true; } flag12 = true; flag13 = false; } else if (characterAnalyzer.IsBreak()) { if (flag19) { flag6 = true; } if (characterAnalyzer.Buffer.Position >= characterAnalyzer.Buffer.Length - 1) { flag8 = true; } if (flag12) { flag11 = true; } if (flag14) { flag18 = true; } flag12 = false; flag13 = true; } else { flag12 = false; flag13 = false; flag14 = false; } flag3 = characterAnalyzer.IsWhiteBreakOrZero(); characterAnalyzer.Skip(1); if (!characterAnalyzer.EndOfInput) { flag4 = characterAnalyzer.IsWhiteBreakOrZero(1); } flag19 = false; } scalarData.IsFlowPlainAllowed = true; scalarData.IsBlockPlainAllowed = true; scalarData.IsSingleQuotedAllowed = true; scalarData.IsBlockAllowed = true; if (flag5 || flag6 || flag7 || flag8 || flag9) { scalarData.IsFlowPlainAllowed = false; scalarData.IsBlockPlainAllowed = false; } if (flag7) { scalarData.IsBlockAllowed = false; } if (flag10) { scalarData.IsFlowPlainAllowed = false; scalarData.IsBlockPlainAllowed = false; scalarData.IsSingleQuotedAllowed = false; } if (flag11 || flag16) { scalarData.IsFlowPlainAllowed = false; scalarData.IsBlockPlainAllowed = false; scalarData.IsSingleQuotedAllowed = false; } if (flag18) { scalarData.IsBlockAllowed = false; } scalarData.IsMultiline = flag15; if (flag15) { scalarData.IsFlowPlainAllowed = false; scalarData.IsBlockPlainAllowed = false; } if (flag) { scalarData.IsFlowPlainAllowed = false; } if (flag2) { scalarData.IsBlockPlainAllowed = false; } scalarData.HasSingleQuotes = flag17; } finally { ((IDisposable)bufferWrapper).Dispose(); } } private bool ValueIsRepresentableInOutputEncoding(string value) { if (outputUsesUnicodeEncoding) { return true; } try { byte[] bytes = output.Encoding.GetBytes(value); string @string = output.Encoding.GetString(bytes, 0, bytes.Length); return @string.Equals(value); } catch (EncoderFallbackException) { return false; } catch (ArgumentOutOfRangeException) { return false; } } private static bool IsUnicode(Encoding encoding) { if (!(encoding is UTF8Encoding) && !(encoding is UnicodeEncoding)) { return encoding is UTF7Encoding; } return true; } private void AnalyzeTag(TagName tag) { tagData.Handle = tag.Value; foreach (TagDirective tagDirective in tagDirectives) { if (tag.Value.StartsWith(tagDirective.Prefix, StringComparison.Ordinal)) { tagData.Handle = tagDirective.Handle; tagData.Suffix = tag.Value.Substring(tagDirective.Prefix.Length); break; } } } private void StateMachine(ParsingEvent evt) { if (evt is YamlDotNet.Core.Events.Comment comment) { EmitComment(comment); return; } switch (state) { case EmitterState.StreamStart: EmitStreamStart(evt); break; case EmitterState.FirstDocumentStart: EmitDocumentStart(evt, isFirst: true); break; case EmitterState.DocumentStart: EmitDocumentStart(evt, isFirst: false); break; case EmitterState.DocumentContent: EmitDocumentContent(evt); break; case EmitterState.DocumentEnd: EmitDocumentEnd(evt); break; case EmitterState.FlowSequenceFirstItem: EmitFlowSequenceItem(evt, isFirst: true); break; case EmitterState.FlowSequenceItem: EmitFlowSequenceItem(evt, isFirst: false); break; case EmitterState.FlowMappingFirstKey: EmitFlowMappingKey(evt, isFirst: true); break; case EmitterState.FlowMappingKey: EmitFlowMappingKey(evt, isFirst: false); break; case EmitterState.FlowMappingSimpleValue: EmitFlowMappingValue(evt, isSimple: true); break; case EmitterState.FlowMappingValue: EmitFlowMappingValue(evt, isSimple: false); break; case EmitterState.BlockSequenceFirstItem: EmitBlockSequenceItem(evt, isFirst: true); break; case EmitterState.BlockSequenceItem: EmitBlockSequenceItem(evt, isFirst: false); break; case EmitterState.BlockMappingFirstKey: EmitBlockMappingKey(evt, isFirst: true); break; case EmitterState.BlockMappingKey: EmitBlockMappingKey(evt, isFirst: false); break; case EmitterState.BlockMappingSimpleValue: EmitBlockMappingValue(evt, isSimple: true); break; case EmitterState.BlockMappingValue: EmitBlockMappingValue(evt, isSimple: false); break; case EmitterState.StreamEnd: throw new YamlException("Expected nothing after STREAM-END"); default: throw new InvalidOperationException(); } } private void EmitComment(YamlDotNet.Core.Events.Comment comment) { if (flowLevel > 0 || state == EmitterState.FlowMappingFirstKey || state == EmitterState.FlowSequenceFirstItem) { return; } string[] array = comment.Value.Split(NewLineSeparators, StringSplitOptions.None); if (comment.IsInline) { Write(" # "); Write(string.Join(" ", array)); } else { bool flag = state == EmitterState.BlockMappingFirstKey; if (flag) { IncreaseIndent(isFlow: false, isIndentless: false); } string[] array2 = array; foreach (string value in array2) { WriteIndent(); Write("# "); Write(value); WriteBreak(); } if (flag) { indent = indents.Pop(); } } isIndentation = true; } private void EmitStreamStart(ParsingEvent evt) { if (!(evt is YamlDotNet.Core.Events.StreamStart)) { throw new ArgumentException("Expected STREAM-START.", "evt"); } indent = -1; column = 0; isWhitespace = true; isIndentation = true; state = EmitterState.FirstDocumentStart; } private void EmitDocumentStart(ParsingEvent evt, bool isFirst) { if (evt is YamlDotNet.Core.Events.DocumentStart documentStart) { bool flag = documentStart.IsImplicit && isFirst && !isCanonical; TagDirectiveCollection tagDirectiveCollection = NonDefaultTagsAmong(documentStart.Tags); if (!isFirst && !isDocumentEndWritten && (documentStart.Version != null || tagDirectiveCollection.Count > 0)) { isDocumentEndWritten = false; WriteIndicator("...", needWhitespace: true, whitespace: false, indentation: false); WriteIndent(); } if (documentStart.Version != null) { AnalyzeVersionDirective(documentStart.Version); Version version = documentStart.Version.Version; flag = false; WriteIndicator("%YAML", needWhitespace: true, whitespace: false, indentation: false); WriteIndicator(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor), needWhitespace: true, whitespace: false, indentation: false); WriteIndent(); } foreach (TagDirective item in tagDirectiveCollection) { AppendTagDirectiveTo(item, allowDuplicates: false, tagDirectives); } TagDirective[] defaultTagDirectives = Constants.DefaultTagDirectives; foreach (TagDirective value in defaultTagDirectives) { AppendTagDirectiveTo(value, allowDuplicates: true, tagDirectives); } if (tagDirectiveCollection.Count > 0) { flag = false; TagDirective[] defaultTagDirectives2 = Constants.DefaultTagDirectives; foreach (TagDirective value2 in defaultTagDirectives2) { AppendTagDirectiveTo(value2, allowDuplicates: true, tagDirectiveCollection); } foreach (TagDirective item2 in tagDirectiveCollection) { WriteIndicator("%TAG", needWhitespace: true, whitespace: false, indentation: false); WriteTagHandle(item2.Handle); WriteTagContent(item2.Prefix, needsWhitespace: true); WriteIndent(); } } if (CheckEmptyDocument()) { flag = false; } if (!flag) { WriteIndent(); WriteIndicator("---", needWhitespace: true, whitespace: false, indentation: false); if (isCanonical) { WriteIndent(); } } state = EmitterState.DocumentContent; } else { if (!(evt is YamlDotNet.Core.Events.StreamEnd)) { throw new YamlException("Expected DOCUMENT-START or STREAM-END"); } state = EmitterState.StreamEnd; } } private static TagDirectiveCollection NonDefaultTagsAmong(IEnumerable? tagCollection) { TagDirectiveCollection tagDirectiveCollection = new TagDirectiveCollection(); if (tagCollection == null) { return tagDirectiveCollection; } foreach (TagDirective item2 in tagCollection) { AppendTagDirectiveTo(item2, allowDuplicates: false, tagDirectiveCollection); } TagDirective[] defaultTagDirectives = Constants.DefaultTagDirectives; foreach (TagDirective item in defaultTagDirectives) { tagDirectiveCollection.Remove(item); } return tagDirectiveCollection; } private static void AnalyzeVersionDirective(VersionDirective versionDirective) { if (versionDirective.Version.Major != 1 || versionDirective.Version.Minor > 3) { throw new YamlException("Incompatible %YAML directive"); } } private static void AppendTagDirectiveTo(TagDirective value, bool allowDuplicates, TagDirectiveCollection tagDirectives) { if (tagDirectives.Contains(value)) { if (!allowDuplicates) { throw new YamlException("Duplicate %TAG directive."); } } else { tagDirectives.Add(value); } } private void EmitDocumentContent(ParsingEvent evt) { states.Push(EmitterState.DocumentEnd); EmitNode(evt, isMapping: false, isSimpleKey: false); } private void EmitNode(ParsingEvent evt, bool isMapping, bool isSimpleKey) { isMappingContext = isMapping; isSimpleKeyContext = isSimpleKey; switch (evt.Type) { case EventType.Alias: EmitAlias(); break; case EventType.Scalar: EmitScalar(evt); break; case EventType.SequenceStart: EmitSequenceStart(evt); break; case EventType.MappingStart: EmitMappingStart(evt); break; default: throw new YamlException($"Expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, got {evt.Type}"); } } private void EmitAlias() { ProcessAnchor(); state = states.Pop(); } private void EmitScalar(ParsingEvent evt) { SelectScalarStyle(evt); ProcessAnchor(); ProcessTag(); IncreaseIndent(isFlow: true, isIndentless: false); ProcessScalar(); indent = indents.Pop(); state = states.Pop(); } private void SelectScalarStyle(ParsingEvent evt) { YamlDotNet.Core.Events.Scalar scalar = (YamlDotNet.Core.Events.Scalar)evt; ScalarStyle scalarStyle = scalar.Style; bool flag = tagData.Handle == null && tagData.Suffix == null; if (flag && !scalar.IsPlainImplicit && !scalar.IsQuotedImplicit) { throw new YamlException("Neither tag nor isImplicit flags are specified."); } if (scalarStyle == ScalarStyle.Any) { scalarStyle = ((!scalarData.IsMultiline) ? ScalarStyle.Plain : ScalarStyle.Folded); } if (isCanonical) { scalarStyle = ScalarStyle.DoubleQuoted; } if (isSimpleKeyContext && scalarData.IsMultiline) { scalarStyle = ScalarStyle.DoubleQuoted; } if (scalarStyle == ScalarStyle.Plain) { if ((flowLevel != 0 && !scalarData.IsFlowPlainAllowed) || (flowLevel == 0 && !scalarData.IsBlockPlainAllowed)) { scalarStyle = ((scalarData.IsSingleQuotedAllowed && !scalarData.HasSingleQuotes) ? ScalarStyle.SingleQuoted : ScalarStyle.DoubleQuoted); } if (string.IsNullOrEmpty(scalarData.Value) && (flowLevel != 0 || isSimpleKeyContext)) { scalarStyle = ScalarStyle.SingleQuoted; } if (flag && !scalar.IsPlainImplicit) { scalarStyle = ScalarStyle.SingleQuoted; } } if (scalarStyle == ScalarStyle.SingleQuoted && !scalarData.IsSingleQuotedAllowed) { scalarStyle = ScalarStyle.DoubleQuoted; } if ((scalarStyle == ScalarStyle.Literal || scalarStyle == ScalarStyle.Folded) && (!scalarData.IsBlockAllowed || flowLevel != 0 || isSimpleKeyContext)) { scalarStyle = ScalarStyle.DoubleQuoted; } if (scalarStyle == ScalarStyle.ForcePlain) { scalarStyle = ScalarStyle.Plain; } scalarData.Style = scalarStyle; } private void ProcessScalar() { switch (scalarData.Style) { case ScalarStyle.Plain: WritePlainScalar(scalarData.Value, !isSimpleKeyContext); break; case ScalarStyle.SingleQuoted: WriteSingleQuotedScalar(scalarData.Value, !isSimpleKeyContext); break; case ScalarStyle.DoubleQuoted: WriteDoubleQuotedScalar(scalarData.Value, !isSimpleKeyContext); break; case ScalarStyle.Literal: WriteLiteralScalar(scalarData.Value); break; case ScalarStyle.Folded: WriteFoldedScalar(scalarData.Value); break; default: throw new InvalidOperationException(); } } private void WritePlainScalar(string value, bool allowBreaks) { if (!isWhitespace) { Write(' '); } bool flag = false; bool flag2 = false; for (int i = 0; i < value.Length; i++) { char c = value[i]; if (IsSpace(c)) { if (allowBreaks && !flag && column > bestWidth && i + 1 < value.Length && value[i + 1] != ' ') { WriteIndent(); } else { Write(c); } flag = true; continue; } if (IsBreak(c, out var breakChar)) { if (!flag2 && c == '\n') { WriteBreak(); } WriteBreak(breakChar); isIndentation = true; flag2 = true; continue; } if (flag2) { WriteIndent(); } Write(c); isIndentation = false; flag = false; flag2 = false; } isWhitespace = false; isIndentation = false; } private void WriteSingleQuotedScalar(string value, bool allowBreaks) { WriteIndicator("'", needWhitespace: true, whitespace: false, indentation: false); bool flag = false; bool flag2 = false; for (int i = 0; i < value.Length; i++) { char c = value[i]; if (c == ' ') { if (allowBreaks && !flag && column > bestWidth && i != 0 && i + 1 < value.Length && value[i + 1] != ' ') { WriteIndent(); } else { Write(c); } flag = true; continue; } if (IsBreak(c, out var breakChar)) { if (!flag2 && c == '\n') { WriteBreak(); } WriteBreak(breakChar); isIndentation = true; flag2 = true; continue; } if (flag2) { WriteIndent(); } if (c == '\'') { Write(c); } Write(c); isIndentation = false; flag = false; flag2 = false; } WriteIndicator("'", needWhitespace: false, whitespace: false, indentation: false); isWhitespace = false; isIndentation = false; } private void WriteDoubleQuotedScalar(string value, bool allowBreaks) { WriteIndicator("\"", needWhitespace: true, whitespace: false, indentation: false); bool flag = false; for (int i = 0; i < value.Length; i++) { char c = value[i]; if (IsPrintable(c) && !IsBreak(c, out var _)) { switch (c) { case '"': case '\\': break; case ' ': if (allowBreaks && !flag && column > bestWidth && i > 0 && i + 1 < value.Length) { WriteIndent(); if (value[i + 1] == ' ') { Write('\\'); } } else { Write(c); } flag = true; continue; default: Write(c); flag = false; continue; } } Write('\\'); switch (c) { case '\0': Write('0'); break; case '\a': Write('a'); break; case '\b': Write('b'); break; case '\t': Write('t'); break; case '\n': Write('n'); break; case '\v': Write('v'); break; case '\f': Write('f'); break; case '\r': Write('r'); break; case '\u001b': Write('e'); break; case '"': Write('"'); break; case '\\': Write('\\'); break; case '\u0085': Write('N'); break; case '\u00a0': Write('_'); break; case '\u2028': Write('L'); break; case '\u2029': Write('P'); break; default: { ushort num = c; if (num <= 255) { Write('x'); Write(num.ToString("X02", CultureInfo.InvariantCulture)); } else if (IsHighSurrogate(c)) { if (i + 1 >= value.Length || !IsLowSurrogate(value[i + 1])) { throw new SyntaxErrorException("While writing a quoted scalar, found an orphaned high surrogate."); } Write('U'); Write(char.ConvertToUtf32(c, value[i + 1]).ToString("X08", CultureInfo.InvariantCulture)); i++; } else { Write('u'); Write(num.ToString("X04", CultureInfo.InvariantCulture)); } break; } } flag = false; } WriteIndicator("\"", needWhitespace: false, whitespace: false, indentation: false); isWhitespace = false; isIndentation = false; } private void WriteLiteralScalar(string value) { bool flag = true; WriteIndicator("|", needWhitespace: true, whitespace: false, indentation: false); WriteBlockScalarHints(value); WriteBreak(); isIndentation = true; isWhitespace = true; for (int i = 0; i < value.Length; i++) { char c = value[i]; if (c == '\r' && i + 1 < value.Length && value[i + 1] == '\n') { continue; } if (IsBreak(c, out var breakChar)) { WriteBreak(breakChar); isIndentation = true; flag = true; continue; } if (flag) { WriteIndent(); } Write(c); isIndentation = false; flag = false; } } private void WriteFoldedScalar(string value) { bool flag = true; bool flag2 = true; WriteIndicator(">", needWhitespace: true, whitespace: false, indentation: false); WriteBlockScalarHints(value); WriteBreak(); isIndentation = true; isWhitespace = true; for (int i = 0; i < value.Length; i++) { char c = value[i]; if (IsBreak(c, out var breakChar)) { if (c == '\r' && i + 1 < value.Length && value[i + 1] == '\n') { continue; } if (!flag && !flag2 && breakChar == '\n') { int j; char breakChar2; for (j = 0; i + j < value.Length && IsBreak(value[i + j], out breakChar2); j++) { } if (i + j < value.Length && !IsBlank(value[i + j]) && !IsBreak(value[i + j], out breakChar2)) { WriteBreak(); } } WriteBreak(breakChar); isIndentation = true; flag = true; } else { if (flag) { WriteIndent(); flag2 = IsBlank(c); } if (!flag && c == ' ' && i + 1 < value.Length && value[i + 1] != ' ' && column > bestWidth) { WriteIndent(); } else { Write(c); } isIndentation = false; flag = false; } } } private static bool IsSpace(char character) { return character == ' '; } private static bool IsBreak(char character, out char breakChar) { switch (character) { case '\n': case '\r': case '\u0085': breakChar = '\n'; return true; case '\u2028': case '\u2029': breakChar = character; return true; default: breakChar = '\0'; return false; } } private static bool IsBlank(char character) { if (character != ' ') { return character == '\t'; } return true; } private static bool IsPrintable(char character) { switch (character) { default: if (character != '\u0085' && (character < '\u00a0' || character > '\ud7ff')) { if (character >= '\ue000') { return character <= '\ufffd'; } return false; } break; case '\t': case '\n': case '\r': case ' ': case '!': case '"': case '#': case '$': case '%': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '<': case '=': case '>': case '?': case '@': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '[': case '\\': case ']': case '^': case '_': case '`': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}': case '~': break; } return true; } private static bool IsHighSurrogate(char c) { if ('\ud800' <= c) { return c <= '\udbff'; } return false; } private static bool IsLowSurrogate(char c) { if ('\udc00' <= c) { return c <= '\udfff'; } return false; } private void EmitSequenceStart(ParsingEvent evt) { ProcessAnchor(); ProcessTag(); SequenceStart sequenceStart = (SequenceStart)evt; if (flowLevel != 0 || isCanonical || sequenceStart.Style == SequenceStyle.Flow || CheckEmptySequence()) { state = EmitterState.FlowSequenceFirstItem; } else { state = EmitterState.BlockSequenceFirstItem; } } private void EmitMappingStart(ParsingEvent evt) { ProcessAnchor(); ProcessTag(); MappingStart mappingStart = (MappingStart)evt; if (flowLevel != 0 || isCanonical || mappingStart.Style == MappingStyle.Flow || CheckEmptyMapping()) { state = EmitterState.FlowMappingFirstKey; } else { state = EmitterState.BlockMappingFirstKey; } } private void ProcessAnchor() { if (!anchorData.Anchor.IsEmpty && !skipAnchorName) { WriteIndicator(anchorData.IsAlias ? "*" : "&", needWhitespace: true, whitespace: false, indentation: false); WriteAnchor(anchorData.Anchor); } } private void ProcessTag() { if (tagData.Handle == null && tagData.Suffix == null) { return; } if (tagData.Handle != null) { WriteTagHandle(tagData.Handle); if (tagData.Suffix != null) { WriteTagContent(tagData.Suffix, needsWhitespace: false); } } else { WriteIndicator("!<", needWhitespace: true, whitespace: false, indentation: false); WriteTagContent(tagData.Suffix, needsWhitespace: false); WriteIndicator(">", needWhitespace: false, whitespace: false, indentation: false); } } private void EmitDocumentEnd(ParsingEvent evt) { if (evt is YamlDotNet.Core.Events.DocumentEnd documentEnd) { WriteIndent(); if (!documentEnd.IsImplicit) { WriteIndicator("...", needWhitespace: true, whitespace: false, indentation: false); WriteIndent(); isDocumentEndWritten = true; } state = EmitterState.DocumentStart; tagDirectives.Clear(); return; } throw new YamlException("Expected DOCUMENT-END."); } private void EmitFlowSequenceItem(ParsingEvent evt, bool isFirst) { if (isFirst) { WriteIndicator("[", needWhitespace: true, whitespace: true, indentation: false); IncreaseIndent(isFlow: true, isIndentless: false); flowLevel++; } if (evt is SequenceEnd) { flowLevel--; indent = indents.Pop(); if (isCanonical && !isFirst) { WriteIndicator(",", needWhitespace: false, whitespace: false, indentation: false); WriteIndent(); } WriteIndicator("]", needWhitespace: false, whitespace: false, indentation: false); state = states.Pop(); } else { if (!isFirst) { WriteIndicator(",", needWhitespace: false, whitespace: false, indentation: false); } if (isCanonical || column > bestWidth) { WriteIndent(); } states.Push(EmitterState.FlowSequenceItem); EmitNode(evt, isMapping: false, isSimpleKey: false); } } private void EmitFlowMappingKey(ParsingEvent evt, bool isFirst) { if (isFirst) { WriteIndicator("{", needWhitespace: true, whitespace: true, indentation: false); IncreaseIndent(isFlow: true, isIndentless: false); flowLevel++; } if (evt is MappingEnd) { flowLevel--; indent = indents.Pop(); if (isCanonical && !isFirst) { WriteIndicator(",", needWhitespace: false, whitespace: false, indentation: false); WriteIndent(); } WriteIndicator("}", needWhitespace: false, whitespace: false, indentation: false); state = states.Pop(); return; } if (!isFirst) { WriteIndicator(",", needWhitespace: false, whitespace: false, indentation: false); } if (isCanonical || column > bestWidth) { WriteIndent(); } if (!isCanonical && CheckSimpleKey()) { states.Push(EmitterState.FlowMappingSimpleValue); EmitNode(evt, isMapping: true, isSimpleKey: true); } else { WriteIndicator("?", needWhitespace: true, whitespace: false, indentation: false); states.Push(EmitterState.FlowMappingValue); EmitNode(evt, isMapping: true, isSimpleKey: false); } } private void EmitFlowMappingValue(ParsingEvent evt, bool isSimple) { if (isSimple) { WriteIndicator(":", needWhitespace: false, whitespace: false, indentation: false); } else { if (isCanonical || column > bestWidth) { WriteIndent(); } WriteIndicator(":", needWhitespace: true, whitespace: false, indentation: false); } states.Push(EmitterState.FlowMappingKey); EmitNode(evt, isMapping: true, isSimpleKey: false); } private void EmitBlockSequenceItem(ParsingEvent evt, bool isFirst) { if (isFirst) { IncreaseIndent(isFlow: false, isMappingContext && !isIndentation); } if (evt is SequenceEnd) { indent = indents.Pop(); state = states.Pop(); return; } WriteIndent(); WriteIndicator("-", needWhitespace: true, whitespace: false, indentation: true); states.Push(EmitterState.BlockSequenceItem); EmitNode(evt, isMapping: false, isSimpleKey: false); } private void EmitBlockMappingKey(ParsingEvent evt, bool isFirst) { if (isFirst) { IncreaseIndent(isFlow: false, isIndentless: false); } if (evt is MappingEnd) { indent = indents.Pop(); state = states.Pop(); return; } WriteIndent(); if (CheckSimpleKey()) { states.Push(EmitterState.BlockMappingSimpleValue); EmitNode(evt, isMapping: true, isSimpleKey: true); WriteIndicator(":", needWhitespace: false, whitespace: false, indentation: false); } else { WriteIndicator("?", needWhitespace: true, whitespace: false, indentation: true); states.Push(EmitterState.BlockMappingValue); EmitNode(evt, isMapping: true, isSimpleKey: false); } } private void EmitBlockMappingValue(ParsingEvent evt, bool isSimple) { if (!isSimple) { WriteIndent(); WriteIndicator(":", needWhitespace: true, whitespace: false, indentation: true); } states.Push(EmitterState.BlockMappingKey); EmitNode(evt, isMapping: true, isSimpleKey: false); } private void IncreaseIndent(bool isFlow, bool isIndentless) { indents.Push(indent); if (indent < 0) { indent = (isFlow ? bestIndent : 0); } else if (!isIndentless || !forceIndentLess) { indent += bestIndent; } } private bool CheckEmptyDocument() { int num = 0; foreach (ParsingEvent @event in events) { num++; if (num == 2) { if (@event is YamlDotNet.Core.Events.Scalar scalar) { return string.IsNullOrEmpty(scalar.Value); } break; } } return false; } private bool CheckSimpleKey() { if (events.Count < 1) { return false; } int num; switch (events.Peek().Type) { case EventType.Alias: num = AnchorNameLength(anchorData.Anchor); break; case EventType.Scalar: if (scalarData.IsMultiline) { return false; } num = AnchorNameLength(anchorData.Anchor) + SafeStringLength(tagData.Handle) + SafeStringLength(tagData.Suffix) + SafeStringLength(scalarData.Value); break; case EventType.SequenceStart: if (!CheckEmptySequence()) { return false; } num = AnchorNameLength(anchorData.Anchor) + SafeStringLength(tagData.Handle) + SafeStringLength(tagData.Suffix); break; case EventType.MappingStart: if (!CheckEmptySequence()) { return false; } num = AnchorNameLength(anchorData.Anchor) + SafeStringLength(tagData.Handle) + SafeStringLength(tagData.Suffix); break; default: return false; } return num <= maxSimpleKeyLength; } private static int AnchorNameLength(AnchorName value) { if (!value.IsEmpty) { return value.Value.Length; } return 0; } private static int SafeStringLength(string? value) { return value?.Length ?? 0; } private bool CheckEmptySequence() { return CheckEmptyStructure(); } private bool CheckEmptyMapping() { return CheckEmptyStructure(); } private bool CheckEmptyStructure() where TStart : NodeEvent where TEnd : ParsingEvent { if (events.Count < 2) { return false; } using Queue.Enumerator enumerator = events.GetEnumerator(); return enumerator.MoveNext() && enumerator.Current is TStart && enumerator.MoveNext() && enumerator.Current is TEnd; } private void WriteBlockScalarHints(string value) { StringLookAheadBufferPool.BufferWrapper bufferWrapper = StringLookAheadBufferPool.Rent(value); try { CharacterAnalyzer characterAnalyzer = new CharacterAnalyzer(bufferWrapper.Buffer); if (characterAnalyzer.IsSpace() || characterAnalyzer.IsBreak()) { int num = bestIndent; string indicator = num.ToString(CultureInfo.InvariantCulture); WriteIndicator(indicator, needWhitespace: false, whitespace: false, indentation: false); } string text = null; if (value.Length == 0 || !characterAnalyzer.IsBreak(value.Length - 1)) { text = "-"; } else if (value.Length >= 2 && characterAnalyzer.IsBreak(value.Length - 2)) { text = "+"; } if (text != null) { WriteIndicator(text, needWhitespace: false, whitespace: false, indentation: false); } } finally { ((IDisposable)bufferWrapper).Dispose(); } } private void WriteIndicator(string indicator, bool needWhitespace, bool whitespace, bool indentation) { if (needWhitespace && !isWhitespace) { Write(' '); } Write(indicator); isWhitespace = whitespace; isIndentation &= indentation; } private void WriteIndent() { int num = Math.Max(indent, 0); if (!isIndentation || column > num || (column == num && !isWhitespace)) { WriteBreak(); } while (column < num) { Write(' '); } isWhitespace = true; isIndentation = true; } private void WriteAnchor(AnchorName value) { Write(value.Value); isWhitespace = false; isIndentation = false; } private void WriteTagHandle(string value) { if (!isWhitespace) { Write(' '); } Write(value); isWhitespace = false; isIndentation = false; } private void WriteTagContent(string value, bool needsWhitespace) { if (needsWhitespace && !isWhitespace) { Write(' '); } Write(UrlEncode(value)); isWhitespace = false; isIndentation = false; } private static string UrlEncode(string text) { return UriReplacer.Replace(text, delegate(Match match) { StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; byte[] bytes = Encoding.UTF8.GetBytes(match.Value); foreach (byte b in bytes) { builder.AppendFormat(CultureInfo.InvariantCulture, "%{0:X02}", b); } return builder.ToString(); } finally { ((IDisposable)builderWrapper).Dispose(); } }); } private void Write(char value) { output.Write(value); column++; } private void Write(string value) { output.Write(value); column += value.Length; } private void WriteBreak(char breakCharacter = '\n') { if (breakCharacter == '\n') { output.Write(newLine); } else { output.Write(breakCharacter); } column = 0; } } internal sealed class EmitterSettings { public static readonly EmitterSettings Default = new EmitterSettings(); public int BestIndent { get; } = 2; public int BestWidth { get; } = int.MaxValue; public string NewLine { get; } = Environment.NewLine; public bool IsCanonical { get; } public bool SkipAnchorName { get; private set; } public int MaxSimpleKeyLength { get; } = 1024; public bool IndentSequences { get; } public EmitterSettings() { } public EmitterSettings(int bestIndent, int bestWidth, bool isCanonical, int maxSimpleKeyLength, bool skipAnchorName = false, bool indentSequences = false, string? newLine = null) { if (bestIndent < 2 || bestIndent > 9) { throw new ArgumentOutOfRangeException("bestIndent", "BestIndent must be between 2 and 9, inclusive"); } if (bestWidth <= bestIndent * 2) { throw new ArgumentOutOfRangeException("bestWidth", "BestWidth must be greater than BestIndent x 2."); } if (maxSimpleKeyLength < 0) { throw new ArgumentOutOfRangeException("maxSimpleKeyLength", "MaxSimpleKeyLength must be >= 0"); } BestIndent = bestIndent; BestWidth = bestWidth; IsCanonical = isCanonical; MaxSimpleKeyLength = maxSimpleKeyLength; SkipAnchorName = skipAnchorName; IndentSequences = indentSequences; NewLine = newLine ?? Environment.NewLine; } public EmitterSettings WithBestIndent(int bestIndent) { return new EmitterSettings(bestIndent, BestWidth, IsCanonical, MaxSimpleKeyLength, SkipAnchorName, IndentSequences, NewLine); } public EmitterSettings WithBestWidth(int bestWidth) { return new EmitterSettings(BestIndent, bestWidth, IsCanonical, MaxSimpleKeyLength, SkipAnchorName, IndentSequences, NewLine); } public EmitterSettings WithMaxSimpleKeyLength(int maxSimpleKeyLength) { return new EmitterSettings(BestIndent, BestWidth, IsCanonical, maxSimpleKeyLength, SkipAnchorName, IndentSequences, NewLine); } public EmitterSettings WithNewLine(string newLine) { return new EmitterSettings(BestIndent, BestWidth, IsCanonical, MaxSimpleKeyLength, SkipAnchorName, IndentSequences, newLine); } public EmitterSettings Canonical() { return new EmitterSettings(BestIndent, BestWidth, isCanonical: true, MaxSimpleKeyLength, SkipAnchorName); } public EmitterSettings WithoutAnchorName() { return new EmitterSettings(BestIndent, BestWidth, IsCanonical, MaxSimpleKeyLength, skipAnchorName: true, IndentSequences, NewLine); } public EmitterSettings WithIndentedSequences() { return new EmitterSettings(BestIndent, BestWidth, IsCanonical, MaxSimpleKeyLength, SkipAnchorName, indentSequences: true, NewLine); } } internal enum EmitterState { StreamStart, StreamEnd, FirstDocumentStart, DocumentStart, DocumentContent, DocumentEnd, FlowSequenceFirstItem, FlowSequenceItem, FlowMappingFirstKey, FlowMappingKey, FlowMappingSimpleValue, FlowMappingValue, BlockSequenceFirstItem, BlockSequenceItem, BlockMappingFirstKey, BlockMappingKey, BlockMappingSimpleValue, BlockMappingValue } internal sealed class ForwardAnchorNotSupportedException : YamlException { public ForwardAnchorNotSupportedException(string message) : base(message) { } public ForwardAnchorNotSupportedException(in Mark start, in Mark end, string message) : base(in start, in end, message) { } public ForwardAnchorNotSupportedException(string message, Exception inner) : base(message, inner) { } } internal static class HashCode { public static int CombineHashCodes(int h1, int h2) { return ((h1 << 5) + h1) ^ h2; } public static int CombineHashCodes(int h1, object? o2) { return CombineHashCodes(h1, GetHashCode(o2)); } private static int GetHashCode(object? obj) { return obj?.GetHashCode() ?? 0; } } public interface IEmitter { void Emit(ParsingEvent @event); } internal interface ILookAheadBuffer { bool EndOfInput { get; } char Peek(int offset); void Skip(int length); } internal sealed class InsertionQueue : IEnumerable, IEnumerable { private const int DefaultInitialCapacity = 128; private T[] items; private int readPtr; private int writePtr; private int mask; private int count; public int Count => count; public int Capacity => items.Length; public InsertionQueue(int initialCapacity = 128) { if (initialCapacity <= 0) { throw new ArgumentOutOfRangeException("initialCapacity", "The initial capacity must be a positive number."); } if (!initialCapacity.IsPowerOfTwo()) { throw new ArgumentException("The initial capacity must be a power of 2.", "initialCapacity"); } items = new T[initialCapacity]; readPtr = initialCapacity / 2; writePtr = initialCapacity / 2; mask = initialCapacity - 1; } public void Enqueue(T item) { ResizeIfNeeded(); items[writePtr] = item; writePtr = (writePtr - 1) & mask; count++; } public T Dequeue() { if (count == 0) { throw new InvalidOperationException("The queue is empty"); } T result = items[readPtr]; readPtr = (readPtr - 1) & mask; count--; return result; } public void Insert(int index, T item) { if (index > count) { throw new InvalidOperationException("Cannot insert outside of the bounds of the queue"); } ResizeIfNeeded(); CalculateInsertionParameters(mask, count, index, ref readPtr, ref writePtr, out var insertPtr, out var copyIndex, out var copyOffset, out var copyLength); if (copyLength != 0) { Array.Copy(items, copyIndex, items, copyIndex + copyOffset, copyLength); } items[insertPtr] = item; count++; } private void ResizeIfNeeded() { int num = items.Length; if (count == num) { T[] destinationArray = new T[num * 2]; int num2 = readPtr + 1; if (num2 > 0) { Array.Copy(items, 0, destinationArray, 0, num2); } writePtr += num; int num3 = num - num2; if (num3 > 0) { Array.Copy(items, readPtr + 1, destinationArray, writePtr + 1, num3); } items = destinationArray; mask = mask * 2 + 1; } } internal static void CalculateInsertionParameters(int mask, int count, int index, ref int readPtr, ref int writePtr, out int insertPtr, out int copyIndex, out int copyOffset, out int copyLength) { int num = (readPtr + 1) & mask; if (index == 0) { insertPtr = (readPtr = num); copyIndex = 0; copyOffset = 0; copyLength = 0; return; } insertPtr = (readPtr - index) & mask; if (index == count) { writePtr = (writePtr - 1) & mask; copyIndex = 0; copyOffset = 0; copyLength = 0; return; } int num2 = ((num >= insertPtr) ? (readPtr - insertPtr) : int.MaxValue); int num3 = ((writePtr <= insertPtr) ? (insertPtr - writePtr) : int.MaxValue); if (num2 <= num3) { insertPtr++; readPtr++; copyIndex = insertPtr; copyOffset = 1; copyLength = num2; } else { copyIndex = writePtr + 1; copyOffset = -1; copyLength = num3; writePtr = (writePtr - 1) & mask; } } public IEnumerator GetEnumerator() { int ptr = readPtr; for (int i = 0; i < Count; i++) { yield return items[ptr]; ptr = (ptr - 1) & mask; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public interface IParser { ParsingEvent? Current { get; } bool MoveNext(); } internal interface IScanner { Mark CurrentPosition { get; } Token? Current { get; } bool MoveNext(); bool MoveNextWithoutConsuming(); void ConsumeCurrent(); } [DebuggerStepThrough] internal sealed class LookAheadBuffer : ILookAheadBuffer { private readonly TextReader input; private readonly char[] buffer; private readonly int blockSize; private readonly int mask; private int firstIndex; private int writeOffset; private int count; private bool endOfInput; public bool EndOfInput { get { if (endOfInput) { return count == 0; } return false; } } public LookAheadBuffer(TextReader input, int capacity) { if (capacity < 1) { throw new ArgumentOutOfRangeException("capacity", "The capacity must be positive."); } if (!capacity.IsPowerOfTwo()) { throw new ArgumentException("The capacity must be a power of 2.", "capacity"); } this.input = input ?? throw new ArgumentNullException("input"); blockSize = capacity; buffer = new char[capacity * 2]; mask = capacity * 2 - 1; } private int GetIndexForOffset(int offset) { return (firstIndex + offset) & mask; } public char Peek(int offset) { if (offset >= count) { FillBuffer(); } if (offset < count) { return buffer[(firstIndex + offset) & mask]; } return '\0'; } public void Cache(int length) { if (length >= count) { FillBuffer(); } } private void FillBuffer() { if (endOfInput) { return; } int num = blockSize; do { int num2 = input.Read(buffer, writeOffset, num); if (num2 == 0) { endOfInput = true; return; } num -= num2; writeOffset += num2; count += num2; } while (num > 0); if (writeOffset == buffer.Length) { writeOffset = 0; } } public void Skip(int length) { if (length < 1 || length > blockSize) { throw new ArgumentOutOfRangeException("length", "The length must be between 1 and the number of characters in the buffer. Use the Peek() and / or Cache() methods to fill the buffer."); } firstIndex = GetIndexForOffset(length); count -= length; } } public readonly struct Mark : IEquatable, IComparable, IComparable { public static readonly Mark Empty = new Mark(0L, 1L, 1L); public long Index { get; } public long Line { get; } public long Column { get; } public Mark(long index, long line, long column) { if (index < 0) { ThrowHelper.ThrowArgumentOutOfRangeException("index", "Index must be greater than or equal to zero."); } if (line < 1) { ThrowHelper.ThrowArgumentOutOfRangeException("line", "Line must be greater than or equal to 1."); } if (column < 1) { ThrowHelper.ThrowArgumentOutOfRangeException("column", "Column must be greater than or equal to 1."); } Index = index; Line = line; Column = column; } public override string ToString() { return $"Line: {Line}, Col: {Column}, Idx: {Index}"; } public override bool Equals(object? obj) { return Equals((Mark)(obj ?? ((object)Empty))); } public bool Equals(Mark other) { if (Index == other.Index && Line == other.Line) { return Column == other.Column; } return false; } public override int GetHashCode() { return HashCode.CombineHashCodes(Index.GetHashCode(), HashCode.CombineHashCodes(Line.GetHashCode(), Column.GetHashCode())); } public int CompareTo(object? obj) { return CompareTo((Mark)(obj ?? ((object)Empty))); } public int CompareTo(Mark other) { int num = Line.CompareTo(other.Line); if (num == 0) { num = Column.CompareTo(other.Column); } return num; } public static bool operator ==(Mark left, Mark right) { return left.Equals(right); } public static bool operator !=(Mark left, Mark right) { return !(left == right); } public static bool operator <(Mark left, Mark right) { return left.CompareTo(right) < 0; } public static bool operator <=(Mark left, Mark right) { return left.CompareTo(right) <= 0; } public static bool operator >(Mark left, Mark right) { return left.CompareTo(right) > 0; } public static bool operator >=(Mark left, Mark right) { return left.CompareTo(right) >= 0; } } internal sealed class MaximumRecursionLevelReachedException : YamlException { public MaximumRecursionLevelReachedException(string message) : base(message) { } public MaximumRecursionLevelReachedException(in Mark start, in Mark end, string message) : base(in start, in end, message) { } public MaximumRecursionLevelReachedException(string message, Exception inner) : base(message, inner) { } } internal sealed class MergingParser : IParser { private sealed class ParsingEventCollection : IEnumerable>, IEnumerable { private readonly LinkedList events; private readonly HashSet> deleted; private readonly Dictionary> references; public ParsingEventCollection() { events = new LinkedList(); deleted = new HashSet>(); references = new Dictionary>(); } public void AddAfter(LinkedListNode node, IEnumerable items) { foreach (ParsingEvent item in items) { node = events.AddAfter(node, item); } } public void Add(ParsingEvent item) { LinkedListNode node = events.AddLast(item); AddReference(item, node); } public void MarkDeleted(LinkedListNode node) { deleted.Add(node); } public bool IsDeleted(LinkedListNode node) { return deleted.Contains(node); } public void CleanMarked() { foreach (LinkedListNode item in deleted) { events.Remove(item); } } public IEnumerable> FromAnchor(AnchorName anchor) { LinkedListNode next = references[anchor].Next; return Enumerate(next); } public IEnumerator> GetEnumerator() { return Enumerate(events.First).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static IEnumerable> Enumerate(LinkedListNode? node) { while (node != null) { yield return node; node = node.Next; } } private void AddReference(ParsingEvent item, LinkedListNode node) { if (item is MappingStart mappingStart) { AnchorName anchor = mappingStart.Anchor; if (!anchor.IsEmpty) { references[anchor] = node; } } } } private sealed class ParsingEventCloner : IParsingEventVisitor { private ParsingEvent? clonedEvent; public ParsingEvent Clone(ParsingEvent e) { e.Accept(this); if (clonedEvent == null) { throw new InvalidOperationException($"Could not clone event of type '{e.Type}'"); } return clonedEvent; } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.AnchorAlias e) { clonedEvent = new YamlDotNet.Core.Events.AnchorAlias(e.Value, e.Start, e.End); } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.StreamStart e) { throw new NotSupportedException(); } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.StreamEnd e) { throw new NotSupportedException(); } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.DocumentStart e) { throw new NotSupportedException(); } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.DocumentEnd e) { throw new NotSupportedException(); } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.Scalar e) { clonedEvent = new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, e.Tag, e.Value, e.Style, e.IsPlainImplicit, e.IsQuotedImplicit, e.Start, e.End); } void IParsingEventVisitor.Visit(SequenceStart e) { clonedEvent = new SequenceStart(AnchorName.Empty, e.Tag, e.IsImplicit, e.Style, e.Start, e.End); } void IParsingEventVisitor.Visit(SequenceEnd e) { Mark start = e.Start; Mark end = e.End; clonedEvent = new SequenceEnd(in start, in end); } void IParsingEventVisitor.Visit(MappingStart e) { clonedEvent = new MappingStart(AnchorName.Empty, e.Tag, e.IsImplicit, e.Style, e.Start, e.End); } void IParsingEventVisitor.Visit(MappingEnd e) { Mark start = e.Start; Mark end = e.End; clonedEvent = new MappingEnd(in start, in end); } void IParsingEventVisitor.Visit(YamlDotNet.Core.Events.Comment e) { throw new NotSupportedException(); } } private readonly ParsingEventCollection events; private readonly IParser innerParser; private IEnumerator> iterator; private bool merged; public ParsingEvent? Current => iterator.Current?.Value; public MergingParser(IParser innerParser) { events = new ParsingEventCollection(); merged = false; iterator = events.GetEnumerator(); this.innerParser = innerParser; } public bool MoveNext() { if (!merged) { Merge(); events.CleanMarked(); iterator = events.GetEnumerator(); merged = true; } return iterator.MoveNext(); } private void Merge() { while (innerParser.MoveNext()) { events.Add(innerParser.Current); } foreach (LinkedListNode @event in events) { if (IsMergeToken(@event)) { events.MarkDeleted(@event); if (!HandleMerge(@event.Next)) { Mark start = @event.Value.Start; Mark end = @event.Value.End; throw new SemanticErrorException(in start, in end, "Unrecognized merge key pattern"); } } } } private bool HandleMerge(LinkedListNode? node) { if (node == null) { return false; } if (node.Value is YamlDotNet.Core.Events.AnchorAlias anchorAlias) { return HandleAnchorAlias(node, node, anchorAlias); } if (node.Value is SequenceStart) { return HandleSequence(node); } return false; } private bool HandleMergeSequence(LinkedListNode sequenceStart, LinkedListNode? node) { if (node == null) { return false; } if (node.Value is YamlDotNet.Core.Events.AnchorAlias anchorAlias) { return HandleAnchorAlias(sequenceStart, node, anchorAlias); } if (node.Value is SequenceStart) { return HandleSequence(node); } return false; } private static bool IsMergeToken(LinkedListNode node) { if (node.Value is YamlDotNet.Core.Events.Scalar scalar) { return scalar.Value == "<<"; } return false; } private bool HandleAnchorAlias(LinkedListNode node, LinkedListNode anchorNode, YamlDotNet.Core.Events.AnchorAlias anchorAlias) { IEnumerable mappingEvents = GetMappingEvents(anchorAlias.Value); events.AddAfter(node, mappingEvents); events.MarkDeleted(anchorNode); return true; } private bool HandleSequence(LinkedListNode node) { events.MarkDeleted(node); LinkedListNode linkedListNode = node; while (linkedListNode != null) { if (linkedListNode.Value is SequenceEnd) { events.MarkDeleted(linkedListNode); return true; } LinkedListNode next = linkedListNode.Next; HandleMergeSequence(node, next); linkedListNode = next; } return true; } private IEnumerable GetMappingEvents(AnchorName anchor) { ParsingEventCloner @object = new ParsingEventCloner(); int nesting = 0; return (from e in events.FromAnchor(anchor) where !events.IsDeleted(e) select e.Value).TakeWhile((ParsingEvent e) => (nesting += e.NestingIncrease) >= 0).Select(@object.Clone); } } internal class Parser : IParser { private class EventQueue { private readonly Queue highPriorityEvents = new Queue(); private readonly Queue normalPriorityEvents = new Queue(); public int Count => highPriorityEvents.Count + normalPriorityEvents.Count; public void Enqueue(ParsingEvent @event) { EventType type = @event.Type; if (type == EventType.StreamStart || type == EventType.DocumentStart) { highPriorityEvents.Enqueue(@event); } else { normalPriorityEvents.Enqueue(@event); } } public ParsingEvent Dequeue() { if (highPriorityEvents.Count <= 0) { return normalPriorityEvents.Dequeue(); } return highPriorityEvents.Dequeue(); } } private readonly Stack states = new Stack(); private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); private ParserState state; private readonly IScanner scanner; private Token? currentToken; private VersionDirective? version; private readonly EventQueue pendingEvents = new EventQueue(); public ParsingEvent? Current { get; private set; } private Token? GetCurrentToken() { if (currentToken == null) { while (scanner.MoveNextWithoutConsuming()) { currentToken = scanner.Current; if (!(currentToken is YamlDotNet.Core.Tokens.Comment comment)) { break; } pendingEvents.Enqueue(new YamlDotNet.Core.Events.Comment(comment.Value, comment.IsInline, comment.Start, comment.End)); scanner.ConsumeCurrent(); } } return currentToken; } public Parser(TextReader input) : this(new Scanner(input)) { } public Parser(IScanner scanner) { this.scanner = scanner; } public bool MoveNext() { if (state == ParserState.StreamEnd) { Current = null; return false; } if (pendingEvents.Count == 0) { pendingEvents.Enqueue(StateMachine()); } Current = pendingEvents.Dequeue(); return true; } private ParsingEvent StateMachine() { return state switch { ParserState.StreamStart => ParseStreamStart(), ParserState.ImplicitDocumentStart => ParseDocumentStart(isImplicit: true), ParserState.DocumentStart => ParseDocumentStart(isImplicit: false), ParserState.DocumentContent => ParseDocumentContent(), ParserState.DocumentEnd => ParseDocumentEnd(), ParserState.BlockNode => ParseNode(isBlock: true, isIndentlessSequence: false), ParserState.BlockNodeOrIndentlessSequence => ParseNode(isBlock: true, isIndentlessSequence: true), ParserState.FlowNode => ParseNode(isBlock: false, isIndentlessSequence: false), ParserState.BlockSequenceFirstEntry => ParseBlockSequenceEntry(isFirst: true), ParserState.BlockSequenceEntry => ParseBlockSequenceEntry(isFirst: false), ParserState.IndentlessSequenceEntry => ParseIndentlessSequenceEntry(), ParserState.BlockMappingFirstKey => ParseBlockMappingKey(isFirst: true), ParserState.BlockMappingKey => ParseBlockMappingKey(isFirst: false), ParserState.BlockMappingValue => ParseBlockMappingValue(), ParserState.FlowSequenceFirstEntry => ParseFlowSequenceEntry(isFirst: true), ParserState.FlowSequenceEntry => ParseFlowSequenceEntry(isFirst: false), ParserState.FlowSequenceEntryMappingKey => ParseFlowSequenceEntryMappingKey(), ParserState.FlowSequenceEntryMappingValue => ParseFlowSequenceEntryMappingValue(), ParserState.FlowSequenceEntryMappingEnd => ParseFlowSequenceEntryMappingEnd(), ParserState.FlowMappingFirstKey => ParseFlowMappingKey(isFirst: true), ParserState.FlowMappingKey => ParseFlowMappingKey(isFirst: false), ParserState.FlowMappingValue => ParseFlowMappingValue(isEmpty: false), ParserState.FlowMappingEmptyValue => ParseFlowMappingValue(isEmpty: true), _ => throw new InvalidOperationException(), }; } private void Skip() { if (currentToken != null) { currentToken = null; scanner.ConsumeCurrent(); } } private YamlDotNet.Core.Events.StreamStart ParseStreamStart() { Token token = GetCurrentToken(); Mark start; Mark end; if (!(token is YamlDotNet.Core.Tokens.StreamStart streamStart)) { start = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; throw new SemanticErrorException(in start, in end, "Did not find expected ."); } Skip(); state = ParserState.ImplicitDocumentStart; start = streamStart.Start; end = streamStart.End; return new YamlDotNet.Core.Events.StreamStart(in start, in end); } private ParsingEvent ParseDocumentStart(bool isImplicit) { if (currentToken is VersionDirective) { throw new SyntaxErrorException("While parsing a document start node, could not find document end marker before version directive."); } Token token = GetCurrentToken(); if (!isImplicit) { while (token is YamlDotNet.Core.Tokens.DocumentEnd) { Skip(); token = GetCurrentToken(); } } if (token == null) { throw new SyntaxErrorException("Reached the end of the stream while parsing a document start."); } if (token is YamlDotNet.Core.Tokens.Scalar && (state == ParserState.ImplicitDocumentStart || state == ParserState.DocumentStart)) { isImplicit = true; } if ((isImplicit && !(token is VersionDirective) && !(token is TagDirective) && !(token is YamlDotNet.Core.Tokens.DocumentStart) && !(token is YamlDotNet.Core.Tokens.StreamEnd) && !(token is YamlDotNet.Core.Tokens.DocumentEnd)) || token is BlockMappingStart) { TagDirectiveCollection tags = new TagDirectiveCollection(); ProcessDirectives(tags); states.Push(ParserState.DocumentEnd); state = ParserState.BlockNode; return new YamlDotNet.Core.Events.DocumentStart(null, tags, isImplicit: true, token.Start, token.End); } Mark start2; Mark end; if (!(token is YamlDotNet.Core.Tokens.StreamEnd) && !(token is YamlDotNet.Core.Tokens.DocumentEnd)) { Mark start = token.Start; TagDirectiveCollection tags2 = new TagDirectiveCollection(); VersionDirective versionDirective = ProcessDirectives(tags2); token = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a document start"); if (!(token is YamlDotNet.Core.Tokens.DocumentStart)) { start2 = token.Start; end = token.End; throw new SemanticErrorException(in start2, in end, "Did not find expected ."); } states.Push(ParserState.DocumentEnd); state = ParserState.DocumentContent; Mark end2 = token.End; Skip(); return new YamlDotNet.Core.Events.DocumentStart(versionDirective, tags2, isImplicit: false, start, end2); } if (token is YamlDotNet.Core.Tokens.DocumentEnd) { Skip(); } state = ParserState.StreamEnd; token = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a document start"); start2 = token.Start; end = token.End; YamlDotNet.Core.Events.StreamEnd result = new YamlDotNet.Core.Events.StreamEnd(in start2, in end); if (scanner.MoveNextWithoutConsuming()) { throw new InvalidOperationException("The scanner should contain no more tokens."); } return result; } private VersionDirective? ProcessDirectives(TagDirectiveCollection tags) { bool flag = false; VersionDirective result = null; while (true) { if (GetCurrentToken() is VersionDirective versionDirective) { if (version != null) { Mark start = versionDirective.Start; Mark end = versionDirective.End; throw new SemanticErrorException(in start, in end, "Found duplicate %YAML directive."); } if (versionDirective.Version.Major != 1 || versionDirective.Version.Minor > 3) { Mark start = versionDirective.Start; Mark end = versionDirective.End; throw new SemanticErrorException(in start, in end, "Found incompatible YAML document."); } result = (version = versionDirective); flag = true; } else { if (!(GetCurrentToken() is TagDirective tagDirective)) { break; } if (tags.Contains(tagDirective.Handle)) { Mark start = tagDirective.Start; Mark end = tagDirective.End; throw new SemanticErrorException(in start, in end, "Found duplicate %TAG directive."); } tags.Add(tagDirective); flag = true; } Skip(); } if (GetCurrentToken() is YamlDotNet.Core.Tokens.DocumentStart && (version == null || (version.Version.Major == 1 && version.Version.Minor > 1))) { if (GetCurrentToken() is YamlDotNet.Core.Tokens.DocumentStart && version == null) { version = new VersionDirective(new Version(1, 2)); } flag = true; } AddTagDirectives(tags, Constants.DefaultTagDirectives); if (flag) { tagDirectives.Clear(); } AddTagDirectives(tagDirectives, tags); return result; } private static void AddTagDirectives(TagDirectiveCollection directives, IEnumerable source) { foreach (TagDirective item in source) { if (!directives.Contains(item)) { directives.Add(item); } } } private ParsingEvent ParseDocumentContent() { if (GetCurrentToken() is VersionDirective || GetCurrentToken() is TagDirective || GetCurrentToken() is YamlDotNet.Core.Tokens.DocumentStart || GetCurrentToken() is YamlDotNet.Core.Tokens.DocumentEnd || GetCurrentToken() is YamlDotNet.Core.Tokens.StreamEnd) { state = states.Pop(); Mark position = scanner.CurrentPosition; return ProcessEmptyScalar(in position); } return ParseNode(isBlock: true, isIndentlessSequence: false); } private static YamlDotNet.Core.Events.Scalar ProcessEmptyScalar(in Mark position) { return new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, string.Empty, ScalarStyle.Plain, isPlainImplicit: true, isQuotedImplicit: false, position, position); } private ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence) { Mark start; Mark end; if (GetCurrentToken() is Error error) { start = error.Start; end = error.End; throw new SemanticErrorException(in start, in end, error.Value); } Token token = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a node"); if (token is YamlDotNet.Core.Tokens.AnchorAlias anchorAlias) { state = states.Pop(); ParsingEvent result = new YamlDotNet.Core.Events.AnchorAlias(anchorAlias.Value, anchorAlias.Start, anchorAlias.End); Skip(); return result; } Mark start2 = token.Start; AnchorName anchor = AnchorName.Empty; TagName tag = TagName.Empty; Anchor anchor2 = null; Tag tag2 = null; while (true) { if (anchor.IsEmpty && token is Anchor anchor3) { anchor2 = anchor3; anchor = anchor3.Value; Skip(); } else { if (!tag.IsEmpty || !(token is Tag tag3)) { if (token is Anchor anchor4) { start = anchor4.Start; end = anchor4.End; throw new SemanticErrorException(in start, in end, "While parsing a node, found more than one anchor."); } if (token is YamlDotNet.Core.Tokens.AnchorAlias anchorAlias2) { start = anchorAlias2.Start; end = anchorAlias2.End; throw new SemanticErrorException(in start, in end, "While parsing a node, did not find expected token."); } if (!(token is Error error2)) { break; } if (tag2 != null && anchor2 != null && !anchor.IsEmpty) { return new YamlDotNet.Core.Events.Scalar(anchor, default(TagName), string.Empty, ScalarStyle.Any, isPlainImplicit: false, isQuotedImplicit: false, anchor2.Start, anchor2.End); } start = error2.Start; end = error2.End; throw new SemanticErrorException(in start, in end, error2.Value); } tag2 = tag3; if (string.IsNullOrEmpty(tag3.Handle)) { tag = new TagName(tag3.Suffix); } else { if (!tagDirectives.Contains(tag3.Handle)) { start = tag3.Start; end = tag3.End; throw new SemanticErrorException(in start, in end, "While parsing a node, found undefined tag handle."); } tag = new TagName(tagDirectives[tag3.Handle].Prefix + tag3.Suffix); } Skip(); } token = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a node"); } bool isEmpty = tag.IsEmpty; if (isIndentlessSequence && GetCurrentToken() is BlockEntry) { state = ParserState.IndentlessSequenceEntry; return new SequenceStart(anchor, tag, isEmpty, SequenceStyle.Block, start2, token.End); } if (token is YamlDotNet.Core.Tokens.Scalar scalar) { bool isPlainImplicit = false; bool isQuotedImplicit = false; if ((scalar.Style == ScalarStyle.Plain && tag.IsEmpty) || tag.IsNonSpecific) { isPlainImplicit = true; } else if (tag.IsEmpty) { isQuotedImplicit = true; } state = states.Pop(); Skip(); ParsingEvent result2 = new YamlDotNet.Core.Events.Scalar(anchor, tag, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start2, scalar.End, scalar.IsKey); if (!anchor.IsEmpty && scanner.MoveNextWithoutConsuming()) { currentToken = scanner.Current; if (currentToken is Error) { Error error3 = currentToken as Error; start = error3.Start; end = error3.End; throw new SemanticErrorException(in start, in end, error3.Value); } } if (state == ParserState.FlowMappingKey && !(scanner.Current is FlowMappingEnd) && scanner.MoveNextWithoutConsuming()) { currentToken = scanner.Current; if (currentToken != null && !(currentToken is FlowEntry) && !(currentToken is FlowMappingEnd)) { start = currentToken.Start; end = currentToken.End; throw new SemanticErrorException(in start, in end, "While parsing a flow mapping, did not find expected ',' or '}'."); } } return result2; } if (token is FlowSequenceStart flowSequenceStart) { state = ParserState.FlowSequenceFirstEntry; return new SequenceStart(anchor, tag, isEmpty, SequenceStyle.Flow, start2, flowSequenceStart.End); } if (token is FlowMappingStart flowMappingStart) { state = ParserState.FlowMappingFirstKey; return new MappingStart(anchor, tag, isEmpty, MappingStyle.Flow, start2, flowMappingStart.End); } if (isBlock) { if (token is BlockSequenceStart blockSequenceStart) { state = ParserState.BlockSequenceFirstEntry; return new SequenceStart(anchor, tag, isEmpty, SequenceStyle.Block, start2, blockSequenceStart.End); } if (token is BlockMappingStart blockMappingStart) { state = ParserState.BlockMappingFirstKey; return new MappingStart(anchor, tag, isEmpty, MappingStyle.Block, start2, blockMappingStart.End); } } if (!anchor.IsEmpty || !tag.IsEmpty) { state = states.Pop(); return new YamlDotNet.Core.Events.Scalar(anchor, tag, string.Empty, ScalarStyle.Plain, isEmpty, isQuotedImplicit: false, start2, token.End); } start = token.Start; end = token.End; throw new SemanticErrorException(in start, in end, "While parsing a node, did not find expected node content."); } private YamlDotNet.Core.Events.DocumentEnd ParseDocumentEnd() { Token token = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a document end"); bool isImplicit = true; Mark start = token.Start; Mark end = start; if (token is YamlDotNet.Core.Tokens.DocumentEnd) { end = token.End; Skip(); isImplicit = false; } else if (!(currentToken is YamlDotNet.Core.Tokens.StreamEnd) && !(currentToken is YamlDotNet.Core.Tokens.DocumentStart) && !(currentToken is FlowSequenceEnd) && !(currentToken is VersionDirective) && (!(Current is YamlDotNet.Core.Events.Scalar) || !(currentToken is Error))) { throw new SemanticErrorException(in start, in end, "Did not find expected ."); } if (version != null && version.Version.Major == 1 && version.Version.Minor > 1) { version = null; } state = ParserState.DocumentStart; return new YamlDotNet.Core.Events.DocumentEnd(isImplicit, start, end); } private ParsingEvent ParseBlockSequenceEntry(bool isFirst) { if (isFirst) { GetCurrentToken(); Skip(); } Token token = GetCurrentToken(); if (token is BlockEntry blockEntry) { Mark position = blockEntry.End; Skip(); token = GetCurrentToken(); if (!(token is BlockEntry) && !(token is BlockEnd)) { states.Push(ParserState.BlockSequenceEntry); return ParseNode(isBlock: true, isIndentlessSequence: false); } state = ParserState.BlockSequenceEntry; return ProcessEmptyScalar(in position); } Mark start; Mark end; if (token is BlockEnd blockEnd) { state = states.Pop(); start = blockEnd.Start; end = blockEnd.End; ParsingEvent result = new SequenceEnd(in start, in end); Skip(); return result; } start = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; throw new SemanticErrorException(in start, in end, "While parsing a block collection, did not find expected '-' indicator."); } private ParsingEvent ParseIndentlessSequenceEntry() { Token token = GetCurrentToken(); if (token is BlockEntry blockEntry) { Mark position = blockEntry.End; Skip(); token = GetCurrentToken(); if (!(token is BlockEntry) && !(token is Key) && !(token is Value) && !(token is BlockEnd)) { states.Push(ParserState.IndentlessSequenceEntry); return ParseNode(isBlock: true, isIndentlessSequence: false); } state = ParserState.IndentlessSequenceEntry; return ProcessEmptyScalar(in position); } state = states.Pop(); Mark start = token?.Start ?? Mark.Empty; Mark end = token?.End ?? Mark.Empty; return new SequenceEnd(in start, in end); } private ParsingEvent ParseBlockMappingKey(bool isFirst) { if (isFirst) { GetCurrentToken(); Skip(); } Token token = GetCurrentToken(); if (token is Key key) { Mark position = key.End; Skip(); token = GetCurrentToken(); if (!(token is Key) && !(token is Value) && !(token is BlockEnd)) { states.Push(ParserState.BlockMappingValue); return ParseNode(isBlock: true, isIndentlessSequence: true); } state = ParserState.BlockMappingValue; return ProcessEmptyScalar(in position); } Mark position2; if (token is Value value) { Skip(); position2 = value.End; return ProcessEmptyScalar(in position2); } if (token is YamlDotNet.Core.Tokens.AnchorAlias anchorAlias) { Skip(); return new YamlDotNet.Core.Events.AnchorAlias(anchorAlias.Value, anchorAlias.Start, anchorAlias.End); } Mark end; if (token is BlockEnd blockEnd) { state = states.Pop(); position2 = blockEnd.Start; end = blockEnd.End; ParsingEvent result = new MappingEnd(in position2, in end); Skip(); return result; } if (GetCurrentToken() is Error error) { position2 = error.Start; end = error.End; throw new SyntaxErrorException(in position2, in end, error.Value); } position2 = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; throw new SemanticErrorException(in position2, in end, "While parsing a block mapping, did not find expected key."); } private ParsingEvent ParseBlockMappingValue() { Token token = GetCurrentToken(); if (token is Value value) { Mark position = value.End; Skip(); token = GetCurrentToken(); if (!(token is Key) && !(token is Value) && !(token is BlockEnd)) { states.Push(ParserState.BlockMappingKey); return ParseNode(isBlock: true, isIndentlessSequence: true); } state = ParserState.BlockMappingKey; return ProcessEmptyScalar(in position); } Mark start; if (token is Error error) { start = error.Start; Mark end = error.End; throw new SemanticErrorException(in start, in end, error.Value); } state = ParserState.BlockMappingKey; start = token?.Start ?? Mark.Empty; return ProcessEmptyScalar(in start); } private ParsingEvent ParseFlowSequenceEntry(bool isFirst) { if (isFirst) { GetCurrentToken(); Skip(); } Token token = GetCurrentToken(); Mark start; Mark end; ParsingEvent result; if (!(token is FlowSequenceEnd)) { if (!isFirst) { if (!(token is FlowEntry)) { start = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; throw new SemanticErrorException(in start, in end, "While parsing a flow sequence, did not find expected ',' or ']'."); } Skip(); token = GetCurrentToken(); } if (token is Key) { state = ParserState.FlowSequenceEntryMappingKey; result = new MappingStart(AnchorName.Empty, TagName.Empty, isImplicit: true, MappingStyle.Flow); Skip(); return result; } if (!(token is FlowSequenceEnd)) { states.Push(ParserState.FlowSequenceEntry); return ParseNode(isBlock: false, isIndentlessSequence: false); } } state = states.Pop(); start = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; result = new SequenceEnd(in start, in end); Skip(); return result; } private ParsingEvent ParseFlowSequenceEntryMappingKey() { Token token = GetCurrentToken(); if (!(token is Value) && !(token is FlowEntry) && !(token is FlowSequenceEnd)) { states.Push(ParserState.FlowSequenceEntryMappingValue); return ParseNode(isBlock: false, isIndentlessSequence: false); } Mark position = token?.End ?? Mark.Empty; Skip(); state = ParserState.FlowSequenceEntryMappingValue; return ProcessEmptyScalar(in position); } private ParsingEvent ParseFlowSequenceEntryMappingValue() { Token token = GetCurrentToken(); if (token is Value) { Skip(); token = GetCurrentToken(); if (!(token is FlowEntry) && !(token is FlowSequenceEnd)) { states.Push(ParserState.FlowSequenceEntryMappingEnd); return ParseNode(isBlock: false, isIndentlessSequence: false); } } state = ParserState.FlowSequenceEntryMappingEnd; Mark position = token?.Start ?? Mark.Empty; return ProcessEmptyScalar(in position); } private MappingEnd ParseFlowSequenceEntryMappingEnd() { state = ParserState.FlowSequenceEntry; Token token = GetCurrentToken(); Mark start = token?.Start ?? Mark.Empty; Mark end = token?.End ?? Mark.Empty; return new MappingEnd(in start, in end); } private ParsingEvent ParseFlowMappingKey(bool isFirst) { if (isFirst) { GetCurrentToken(); Skip(); } Token token = GetCurrentToken(); Mark start; Mark end; if (!(token is FlowMappingEnd)) { if (!isFirst) { if (token is FlowEntry) { Skip(); token = GetCurrentToken(); } else if (!(token is YamlDotNet.Core.Tokens.Scalar)) { start = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; throw new SemanticErrorException(in start, in end, "While parsing a flow mapping, did not find expected ',' or '}'."); } } if (token is Key) { Skip(); token = GetCurrentToken(); if (!(token is Value) && !(token is FlowEntry) && !(token is FlowMappingEnd)) { states.Push(ParserState.FlowMappingValue); return ParseNode(isBlock: false, isIndentlessSequence: false); } state = ParserState.FlowMappingValue; start = token?.Start ?? Mark.Empty; return ProcessEmptyScalar(in start); } if (token is YamlDotNet.Core.Tokens.Scalar) { states.Push(ParserState.FlowMappingValue); return ParseNode(isBlock: false, isIndentlessSequence: false); } if (!(token is FlowMappingEnd)) { states.Push(ParserState.FlowMappingEmptyValue); return ParseNode(isBlock: false, isIndentlessSequence: false); } } state = states.Pop(); Skip(); start = token?.Start ?? Mark.Empty; end = token?.End ?? Mark.Empty; return new MappingEnd(in start, in end); } private ParsingEvent ParseFlowMappingValue(bool isEmpty) { Token token = GetCurrentToken(); if (!isEmpty && token is Value) { Skip(); token = GetCurrentToken(); if (!(token is FlowEntry) && !(token is FlowMappingEnd)) { states.Push(ParserState.FlowMappingKey); return ParseNode(isBlock: false, isIndentlessSequence: false); } } state = ParserState.FlowMappingKey; if (!isEmpty && token is YamlDotNet.Core.Tokens.Scalar scalar) { Skip(); return new YamlDotNet.Core.Events.Scalar(AnchorName.Empty, TagName.Empty, scalar.Value, scalar.Style, isPlainImplicit: false, isQuotedImplicit: false, token.Start, scalar.End); } Mark position = token?.Start ?? Mark.Empty; return ProcessEmptyScalar(in position); } } internal static class ParserExtensions { public static T Consume(this IParser parser) where T : ParsingEvent { T result = parser.Require(); parser.MoveNext(); return result; } public static bool TryConsume(this IParser parser, [MaybeNullWhen(false)] out T @event) where T : ParsingEvent { if (parser.Accept(out @event)) { parser.MoveNext(); return true; } return false; } public static T Require(this IParser parser) where T : ParsingEvent { if (!parser.Accept(out var @event)) { ParsingEvent current = parser.Current; if (current == null) { throw new YamlException("Expected '" + typeof(T).Name + "', got nothing."); } Mark start = current.Start; Mark end = current.End; throw new YamlException(in start, in end, $"Expected '{typeof(T).Name}', got '{current.GetType().Name}' (at {current.Start})."); } return @event; } public static bool Accept(this IParser parser, [MaybeNullWhen(false)] out T @event) where T : ParsingEvent { if (parser.Current == null && !parser.MoveNext()) { throw new EndOfStreamException(); } if (parser.Current is T val) { @event = val; return true; } @event = null; return false; } public static void SkipThisAndNestedEvents(this IParser parser) { int num = 0; do { ParsingEvent parsingEvent = parser.Consume(); num += parsingEvent.NestingIncrease; } while (num > 0); } [Obsolete("Please use Consume() instead")] public static T Expect(this IParser parser) where T : ParsingEvent { return parser.Consume(); } [Obsolete("Please use TryConsume(out var evt) instead")] [return: MaybeNull] public static T? Allow(this IParser parser) where T : ParsingEvent { if (!parser.TryConsume(out var @event)) { return null; } return @event; } [Obsolete("Please use Accept(out var evt) instead")] [return: MaybeNull] public static T? Peek(this IParser parser) where T : ParsingEvent { if (!parser.Accept(out var @event)) { return null; } return @event; } [Obsolete("Please use TryConsume(out var evt) or Accept(out var evt) instead")] public static bool Accept(this IParser parser) where T : ParsingEvent { T @event; return parser.Accept(out @event); } public static bool TryFindMappingEntry(this IParser parser, Func selector, [MaybeNullWhen(false)] out YamlDotNet.Core.Events.Scalar? key, [MaybeNullWhen(false)] out ParsingEvent? value) { if (parser.TryConsume(out var _)) { while (parser.Current != null) { ParsingEvent current = parser.Current; if (!(current is YamlDotNet.Core.Events.Scalar scalar)) { if (current is MappingStart || current is SequenceStart) { parser.SkipThisAndNestedEvents(); } else { parser.MoveNext(); } continue; } bool flag = selector(scalar); parser.MoveNext(); if (flag) { value = parser.Current; key = scalar; return true; } parser.SkipThisAndNestedEvents(); } } key = null; value = null; return false; } } internal enum ParserState { StreamStart, StreamEnd, ImplicitDocumentStart, DocumentStart, DocumentContent, DocumentEnd, BlockNode, BlockNodeOrIndentlessSequence, FlowNode, BlockSequenceFirstEntry, BlockSequenceEntry, IndentlessSequenceEntry, BlockMappingFirstKey, BlockMappingKey, BlockMappingValue, FlowSequenceFirstEntry, FlowSequenceEntry, FlowSequenceEntryMappingKey, FlowSequenceEntryMappingValue, FlowSequenceEntryMappingEnd, FlowMappingFirstKey, FlowMappingKey, FlowMappingValue, FlowMappingEmptyValue } internal sealed class RecursionLevel { private int current; public int Maximum { get; } public RecursionLevel(int maximum) { Maximum = maximum; } public void Increment() { if (!TryIncrement()) { throw new MaximumRecursionLevelReachedException("Maximum level of recursion reached"); } } public bool TryIncrement() { if (current < Maximum) { current++; return true; } return false; } public void Decrement() { if (current == 0) { throw new InvalidOperationException("Attempted to decrement RecursionLevel to a negative value"); } current--; } } public enum ScalarStyle { Any, Plain, SingleQuoted, DoubleQuoted, Literal, Folded, ForcePlain } internal class Scanner : IScanner { private const int MaxVersionNumberLength = 9; private static readonly SortedDictionary SimpleEscapeCodes = new SortedDictionary { { '0', '\0' }, { 'a', '\a' }, { 'b', '\b' }, { 't', '\t' }, { '\t', '\t' }, { 'n', '\n' }, { 'v', '\v' }, { 'f', '\f' }, { 'r', '\r' }, { 'e', '\u001b' }, { ' ', ' ' }, { '"', '"' }, { '\\', '\\' }, { '/', '/' }, { 'N', '\u0085' }, { '_', '\u00a0' }, { 'L', '\u2028' }, { 'P', '\u2029' } }; private readonly Stack indents = new Stack(); private readonly InsertionQueue tokens = new InsertionQueue(); private readonly Stack simpleKeys = new Stack(); private readonly CharacterAnalyzer analyzer; private readonly Cursor cursor; private bool streamStartProduced; private bool streamEndProduced; private bool plainScalarFollowedByComment; private bool flowCollectionFetched; private bool startFlowCollectionFetched; private long indent = -1L; private bool flowScalarFetched; private bool simpleKeyAllowed; private int flowLevel; private int tokensParsed; private bool tokenAvailable; private Token? previous; private Anchor? previousAnchor; private YamlDotNet.Core.Tokens.Scalar? lastScalar; private readonly int maxKeySize; private static readonly byte[] EmptyBytes = Array.Empty(); public bool SkipComments { get; private set; } public Token? Current { get; private set; } public Mark CurrentPosition => cursor.Mark(); private bool IsDocumentStart() { if (!analyzer.EndOfInput && cursor.LineOffset == 0L && analyzer.Check('-') && analyzer.Check('-', 1) && analyzer.Check('-', 2)) { return analyzer.IsWhiteBreakOrZero(3); } return false; } private bool IsDocumentEnd() { if (!analyzer.EndOfInput && cursor.LineOffset == 0L && analyzer.Check('.') && analyzer.Check('.', 1) && analyzer.Check('.', 2)) { return analyzer.IsWhiteBreakOrZero(3); } return false; } private bool IsDocumentIndicator() { if (!IsDocumentStart()) { return IsDocumentEnd(); } return true; } public Scanner(TextReader input, bool skipComments = true) : this(input, skipComments, 1024) { } public Scanner(TextReader input, bool skipComments, int maxKeySize) { analyzer = new CharacterAnalyzer(new LookAheadBuffer(input, 1024)); cursor = new Cursor(); SkipComments = skipComments; this.maxKeySize = maxKeySize; } public bool MoveNext() { if (Current != null) { ConsumeCurrent(); } return MoveNextWithoutConsuming(); } public bool MoveNextWithoutConsuming() { if (!tokenAvailable && !streamEndProduced) { FetchMoreTokens(); } if (tokens.Count > 0) { Current = tokens.Dequeue(); tokenAvailable = false; return true; } Current = null; return false; } public void ConsumeCurrent() { tokensParsed++; tokenAvailable = false; previous = Current; Current = null; } private char ReadCurrentCharacter() { char result = analyzer.Peek(0); Skip(); return result; } private char ReadLine() { if (analyzer.Check("\r\n\u0085")) { SkipLine(); return '\n'; } char result = analyzer.Peek(0); SkipLine(); return result; } private void FetchMoreTokens() { while (true) { bool flag = false; if (tokens.Count == 0) { flag = true; } else { foreach (SimpleKey simpleKey in simpleKeys) { if (simpleKey.IsPossible && simpleKey.TokenNumber == tokensParsed) { flag = true; break; } } } if (!flag) { break; } FetchNextToken(); } tokenAvailable = true; } private static bool StartsWith(StringBuilder what, char start) { if (what.Length > 0) { return what[0] == start; } return false; } private void StaleSimpleKeys() { foreach (SimpleKey simpleKey in simpleKeys) { if (simpleKey.IsPossible && (simpleKey.Line < cursor.Line || simpleKey.Index + maxKeySize < cursor.Index)) { if (simpleKey.IsRequired) { Mark mark = cursor.Mark(); tokens.Enqueue(new Error("While scanning a simple key, could not find expected ':'.", mark, mark)); } simpleKey.MarkAsImpossible(); } } } private void FetchNextToken() { if (!streamStartProduced) { FetchStreamStart(); return; } ScanToNextToken(); StaleSimpleKeys(); UnrollIndent(cursor.LineOffset); analyzer.Buffer.Cache(4); if (analyzer.Buffer.EndOfInput) { lastScalar = null; FetchStreamEnd(); } if (cursor.LineOffset == 0L && analyzer.Check('%')) { lastScalar = null; FetchDirective(); return; } if (IsDocumentStart()) { lastScalar = null; FetchDocumentIndicator(isStartToken: true); return; } if (IsDocumentEnd()) { lastScalar = null; FetchDocumentIndicator(isStartToken: false); return; } if (analyzer.Check('[')) { lastScalar = null; FetchFlowCollectionStart(isSequenceToken: true); return; } if (analyzer.Check('{')) { lastScalar = null; FetchFlowCollectionStart(isSequenceToken: false); return; } if (analyzer.Check(']')) { lastScalar = null; FetchFlowCollectionEnd(isSequenceToken: true); return; } if (analyzer.Check('}')) { lastScalar = null; FetchFlowCollectionEnd(isSequenceToken: false); return; } if (analyzer.Check(',')) { lastScalar = null; FetchFlowEntry(); return; } if (analyzer.Check('-')) { if (analyzer.IsWhiteBreakOrZero(1)) { FetchBlockEntry(); return; } if (flowLevel > 0 && analyzer.Check(",[]{}", 1)) { tokens.Enqueue(new Error("Invalid key indicator format.", cursor.Mark(), cursor.Mark())); } } if (analyzer.Check('?') && (flowLevel > 0 || analyzer.IsWhiteBreakOrZero(1)) && analyzer.IsWhiteBreakOrZero(1)) { FetchKey(); } else if (analyzer.Check(':') && (flowLevel > 0 || analyzer.IsWhiteBreakOrZero(1)) && (!simpleKeyAllowed || flowLevel <= 0) && (!flowScalarFetched || !analyzer.Check(':', 1)) && (analyzer.IsWhiteBreakOrZero(1) || analyzer.Check(',', 1) || flowScalarFetched || flowCollectionFetched || startFlowCollectionFetched)) { if (lastScalar != null) { lastScalar.IsKey = true; lastScalar = null; } FetchValue(); } else if (analyzer.Check('*')) { FetchAnchor(isAlias: true); } else if (analyzer.Check('&')) { FetchAnchor(isAlias: false); } else if (analyzer.Check('!')) { FetchTag(); } else if (analyzer.Check('|') && flowLevel == 0) { FetchBlockScalar(isLiteral: true); } else if (analyzer.Check('>') && flowLevel == 0) { FetchBlockScalar(isLiteral: false); } else if (analyzer.Check('\'')) { FetchQuotedScalar(isSingleQuoted: true); } else if (analyzer.Check('"')) { FetchQuotedScalar(isSingleQuoted: false); } else if ((!analyzer.IsWhiteBreakOrZero() && !analyzer.Check("-?:,[]{}#&*!|>'\"%@`")) || (analyzer.Check('-') && !analyzer.IsWhite(1)) || (analyzer.Check("?:") && !analyzer.IsWhiteBreakOrZero(1)) || (simpleKeyAllowed && flowLevel > 0)) { if (plainScalarFollowedByComment) { Mark mark = cursor.Mark(); tokens.Enqueue(new Error("While scanning plain scalar, found a comment between adjacent scalars.", mark, mark)); } if ((flowScalarFetched || (flowCollectionFetched && !startFlowCollectionFetched)) && analyzer.Check(':')) { Skip(); } flowScalarFetched = false; flowCollectionFetched = false; startFlowCollectionFetched = false; plainScalarFollowedByComment = false; FetchPlainScalar(); } else { if (simpleKeyAllowed && indent >= cursor.LineOffset && analyzer.IsTab()) { throw new SyntaxErrorException("While scanning a mapping, found invalid tab as indentation."); } if (!analyzer.IsWhiteBreakOrZero()) { Mark start = cursor.Mark(); Skip(); Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning for the next token, found character that cannot start any token."); } Skip(); } } private bool CheckWhiteSpace() { if (!analyzer.Check(' ')) { if (flowLevel > 0 || !simpleKeyAllowed) { return analyzer.Check('\t'); } return false; } return true; } private void Skip() { cursor.Skip(); analyzer.Buffer.Skip(1); } private void SkipLine() { if (analyzer.IsCrLf()) { cursor.SkipLineByOffset(2); analyzer.Buffer.Skip(2); } else if (analyzer.IsBreak()) { cursor.SkipLineByOffset(1); analyzer.Buffer.Skip(1); } else if (!analyzer.IsZero()) { throw new InvalidOperationException("Not at a break."); } } private void ScanToNextToken() { while (true) { if (CheckWhiteSpace()) { Skip(); continue; } ProcessComment(); if (analyzer.IsBreak()) { SkipLine(); if (flowLevel == 0) { simpleKeyAllowed = true; } continue; } break; } } private void ProcessComment() { if (!analyzer.Check('#')) { return; } Mark start = cursor.Mark(); Skip(); while (analyzer.IsSpace()) { Skip(); } StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; while (!analyzer.IsBreakOrZero()) { builder.Append(ReadCurrentCharacter()); } if (!SkipComments) { bool isInline = previous != null && previous.End.Line == start.Line && previous.End.Column != 1 && !(previous is YamlDotNet.Core.Tokens.StreamStart); tokens.Enqueue(new YamlDotNet.Core.Tokens.Comment(builder.ToString(), isInline, start, cursor.Mark())); } } finally { ((IDisposable)builderWrapper).Dispose(); } } private void FetchStreamStart() { simpleKeys.Push(new SimpleKey()); simpleKeyAllowed = true; streamStartProduced = true; Mark start = cursor.Mark(); tokens.Enqueue(new YamlDotNet.Core.Tokens.StreamStart(in start, in start)); } private void UnrollIndent(long column) { if (flowLevel == 0) { while (indent > column) { Mark start = cursor.Mark(); tokens.Enqueue(new BlockEnd(in start, in start)); indent = indents.Pop(); } } } private void FetchStreamEnd() { cursor.ForceSkipLineAfterNonBreak(); UnrollIndent(-1L); RemoveSimpleKey(); simpleKeyAllowed = false; streamEndProduced = true; Mark start = cursor.Mark(); tokens.Enqueue(new YamlDotNet.Core.Tokens.StreamEnd(in start, in start)); } private void FetchDirective() { UnrollIndent(-1L); RemoveSimpleKey(); simpleKeyAllowed = false; Token token = ScanDirective(); if (token != null) { tokens.Enqueue(token); } } private Token? ScanDirective() { Mark start = cursor.Mark(); Skip(); string text = ScanDirectiveName(in start); Token result; if (!(text == "YAML")) { if (!(text == "TAG")) { while (!analyzer.EndOfInput && !analyzer.Check('#') && !analyzer.IsBreak()) { Skip(); } return null; } result = ScanTagDirectiveValue(in start); } else { if (!(previous is YamlDotNet.Core.Tokens.DocumentStart) && !(previous is YamlDotNet.Core.Tokens.StreamStart) && !(previous is YamlDotNet.Core.Tokens.DocumentEnd)) { Mark end = cursor.Mark(); throw new SemanticErrorException(in start, in end, "While scanning a version directive, did not find preceding ."); } result = ScanVersionDirectiveValue(in start); } while (analyzer.IsWhite()) { Skip(); } ProcessComment(); if (!analyzer.IsBreakOrZero()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a directive, did not find expected comment or line break."); } if (analyzer.IsBreak()) { SkipLine(); } return result; } private void FetchDocumentIndicator(bool isStartToken) { UnrollIndent(-1L); RemoveSimpleKey(); simpleKeyAllowed = false; Mark end = cursor.Mark(); Skip(); Skip(); Skip(); if (isStartToken) { InsertionQueue insertionQueue = tokens; Mark end2 = cursor.Mark(); insertionQueue.Enqueue(new YamlDotNet.Core.Tokens.DocumentStart(in end, in end2)); return; } Token token = null; while (!analyzer.EndOfInput && !analyzer.IsBreak() && !analyzer.Check('#')) { if (!analyzer.IsWhite()) { token = new Error("While scanning a document end, found invalid content after '...' marker.", end, cursor.Mark()); break; } Skip(); } tokens.Enqueue(new YamlDotNet.Core.Tokens.DocumentEnd(in end, in end)); if (token != null) { tokens.Enqueue(token); } } private void FetchFlowCollectionStart(bool isSequenceToken) { SaveSimpleKey(); IncreaseFlowLevel(); simpleKeyAllowed = true; Mark start = cursor.Mark(); Skip(); Token item = ((!isSequenceToken) ? ((Token)new FlowMappingStart(in start, in start)) : ((Token)new FlowSequenceStart(in start, in start))); tokens.Enqueue(item); startFlowCollectionFetched = true; } private void IncreaseFlowLevel() { simpleKeys.Push(new SimpleKey()); flowLevel++; } private void FetchFlowCollectionEnd(bool isSequenceToken) { RemoveSimpleKey(); DecreaseFlowLevel(); simpleKeyAllowed = false; Mark start = cursor.Mark(); Skip(); Token token = null; Token item; if (isSequenceToken) { if (analyzer.Check('#')) { token = new Error("While scanning a flow sequence end, found invalid comment after ']'.", start, start); } item = new FlowSequenceEnd(in start, in start); } else { item = new FlowMappingEnd(in start, in start); } tokens.Enqueue(item); if (token != null) { tokens.Enqueue(token); } flowCollectionFetched = true; } private void DecreaseFlowLevel() { if (flowLevel > 0) { flowLevel--; simpleKeys.Pop(); } } private void FetchFlowEntry() { RemoveSimpleKey(); simpleKeyAllowed = true; Mark start = cursor.Mark(); Skip(); Mark end = cursor.Mark(); if (analyzer.Check('#')) { tokens.Enqueue(new Error("While scanning a flow entry, found invalid comment after comma.", start, end)); } else { tokens.Enqueue(new FlowEntry(in start, in end)); } } private void FetchBlockEntry() { Mark start; if (flowLevel == 0) { if (!simpleKeyAllowed) { if (previousAnchor != null && previousAnchor.End.Line == cursor.Line) { start = previousAnchor.Start; Mark end = previousAnchor.End; throw new SemanticErrorException(in start, in end, "Anchor before sequence entry on same line is not allowed."); } Mark mark = cursor.Mark(); tokens.Enqueue(new Error("Block sequence entries are not allowed in this context.", mark, mark)); } RollIndent(cursor.LineOffset, -1, isSequence: true, cursor.Mark()); } RemoveSimpleKey(); simpleKeyAllowed = true; Mark start2 = cursor.Mark(); Skip(); InsertionQueue insertionQueue = tokens; start = cursor.Mark(); insertionQueue.Enqueue(new BlockEntry(in start2, in start)); } private void FetchKey() { if (flowLevel == 0) { if (!simpleKeyAllowed) { Mark start = cursor.Mark(); throw new SyntaxErrorException(in start, in start, "Mapping keys are not allowed in this context."); } RollIndent(cursor.LineOffset, -1, isSequence: false, cursor.Mark()); } RemoveSimpleKey(); simpleKeyAllowed = flowLevel == 0; Mark start2 = cursor.Mark(); Skip(); InsertionQueue insertionQueue = tokens; Mark end = cursor.Mark(); insertionQueue.Enqueue(new Key(in start2, in end)); } private void FetchValue() { SimpleKey simpleKey = simpleKeys.Peek(); Mark start; if (simpleKey.IsPossible) { InsertionQueue insertionQueue = tokens; int index = simpleKey.TokenNumber - tokensParsed; start = simpleKey.Mark; Mark end = simpleKey.Mark; insertionQueue.Insert(index, new Key(in start, in end)); RollIndent(simpleKey.LineOffset, simpleKey.TokenNumber, isSequence: false, simpleKey.Mark); simpleKey.MarkAsImpossible(); simpleKeyAllowed = false; } else { bool flag = flowLevel == 0; if (flag) { if (!simpleKeyAllowed) { Mark mark = cursor.Mark(); tokens.Enqueue(new Error("Mapping values are not allowed in this context.", mark, mark)); return; } RollIndent(cursor.LineOffset, -1, isSequence: false, cursor.Mark()); if (cursor.LineOffset == 0L && simpleKey.LineOffset == 0L) { InsertionQueue insertionQueue2 = tokens; int count = tokens.Count; start = simpleKey.Mark; Mark end = simpleKey.Mark; insertionQueue2.Insert(count, new Key(in start, in end)); flag = false; } } simpleKeyAllowed = flag; } Mark start2 = cursor.Mark(); Skip(); InsertionQueue insertionQueue3 = tokens; start = cursor.Mark(); insertionQueue3.Enqueue(new Value(in start2, in start)); } private void RollIndent(long column, int number, bool isSequence, Mark position) { if (flowLevel <= 0 && indent < column) { indents.Push(indent); indent = column; Token item = ((!isSequence) ? ((Token)new BlockMappingStart(in position, in position)) : ((Token)new BlockSequenceStart(in position, in position))); if (number == -1) { tokens.Enqueue(item); } else { tokens.Insert(number - tokensParsed, item); } } } private void FetchAnchor(bool isAlias) { SaveSimpleKey(); simpleKeyAllowed = false; tokens.Enqueue(ScanAnchor(isAlias)); } private Token ScanAnchor(bool isAlias) { Mark start = cursor.Mark(); Skip(); bool flag = false; if (isAlias) { SimpleKey simpleKey = simpleKeys.Peek(); flag = simpleKey.IsRequired && simpleKey.IsPossible; } StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; while (!analyzer.IsWhiteBreakOrZero() && !analyzer.Check("[]{},") && (!flag || !analyzer.Check(':') || !analyzer.IsWhiteBreakOrZero(1))) { builder.Append(ReadCurrentCharacter()); } if (builder.Length == 0 || (!analyzer.IsWhiteBreakOrZero() && !analyzer.Check("?:,]}%@`"))) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning an anchor or alias, found value containing disallowed: []{},"); } AnchorName value = new AnchorName(builder.ToString()); if (isAlias) { return new YamlDotNet.Core.Tokens.AnchorAlias(value, start, cursor.Mark()); } return previousAnchor = new Anchor(value, start, cursor.Mark()); } finally { ((IDisposable)builderWrapper).Dispose(); } } private void FetchTag() { SaveSimpleKey(); simpleKeyAllowed = false; tokens.Enqueue(ScanTag()); } private Tag ScanTag() { Mark start = cursor.Mark(); string text; string text2; if (analyzer.Check('<', 1)) { text = string.Empty; Skip(); Skip(); text2 = ScanTagUri(null, start); if (!analyzer.Check('>')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, did not find the expected '>'."); } Skip(); } else { string text3 = ScanTagHandle(isDirective: false, start); if (text3.Length > 1 && text3[0] == '!' && text3[text3.Length - 1] == '!') { text = text3; text2 = ScanTagUri(null, start); } else { text2 = ScanTagUri(text3, start); text = "!"; if (text2.Length == 0) { text2 = text; text = string.Empty; } } } if (!analyzer.IsWhiteBreakOrZero() && !analyzer.Check(',')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, did not find expected whitespace, comma or line break."); } return new Tag(text, text2, start, cursor.Mark()); } private void FetchBlockScalar(bool isLiteral) { SaveSimpleKey(); simpleKeyAllowed = true; tokens.Enqueue(ScanBlockScalar(isLiteral)); } private YamlDotNet.Core.Tokens.Scalar ScanBlockScalar(bool isLiteral) { StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; StringBuilderPool.BuilderWrapper builderWrapper2 = StringBuilderPool.Rent(); try { StringBuilder builder2 = builderWrapper2.Builder; StringBuilderPool.BuilderWrapper builderWrapper3 = StringBuilderPool.Rent(); try { StringBuilder builder3 = builderWrapper3.Builder; int num = 0; int num2 = 0; long currentIndent = 0L; bool flag = false; bool? isFirstLine = null; Mark start = cursor.Mark(); Skip(); if (analyzer.Check("+-")) { num = (analyzer.Check('+') ? 1 : (-1)); Skip(); if (analyzer.IsDigit()) { if (analyzer.Check('0')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a block scalar, found an indentation indicator equal to 0."); } num2 = analyzer.AsDigit(); Skip(); } } else if (analyzer.IsDigit()) { if (analyzer.Check('0')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a block scalar, found an indentation indicator equal to 0."); } num2 = analyzer.AsDigit(); Skip(); if (analyzer.Check("+-")) { num = (analyzer.Check('+') ? 1 : (-1)); Skip(); } } if (analyzer.Check('#')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a block scalar, found a comment without whtespace after '>' indicator."); } while (analyzer.IsWhite()) { Skip(); } ProcessComment(); if (!analyzer.IsBreakOrZero()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a block scalar, did not find expected comment or line break."); } if (analyzer.IsBreak()) { SkipLine(); if (!isFirstLine.HasValue) { isFirstLine = true; } else if (isFirstLine.GetValueOrDefault()) { isFirstLine = false; } } Mark end2 = cursor.Mark(); if (num2 != 0) { currentIndent = ((indent >= 0) ? (indent + num2) : num2); } currentIndent = ScanBlockScalarBreaks(currentIndent, builder3, isLiteral, ref end2, ref isFirstLine); isFirstLine = false; while (cursor.LineOffset == currentIndent && !analyzer.IsZero() && !IsDocumentEnd()) { bool flag2 = analyzer.IsWhite(); if (!isLiteral && StartsWith(builder2, '\n') && !flag && !flag2) { if (builder3.Length == 0) { builder.Append(' '); } builder2.Length = 0; } else { builder.Append((object?)builder2); builder2.Length = 0; } builder.Append((object?)builder3); builder3.Length = 0; flag = analyzer.IsWhite(); while (!analyzer.IsBreakOrZero()) { builder.Append(ReadCurrentCharacter()); } char c = ReadLine(); if (c != 0) { builder2.Append(c); } currentIndent = ScanBlockScalarBreaks(currentIndent, builder3, isLiteral, ref end2, ref isFirstLine); } if (num != -1) { builder.Append((object?)builder2); } if (num == 1) { builder.Append((object?)builder3); } ScalarStyle style = (isLiteral ? ScalarStyle.Literal : ScalarStyle.Folded); return new YamlDotNet.Core.Tokens.Scalar(builder.ToString(), style, start, end2); } finally { ((IDisposable)builderWrapper3).Dispose(); } } finally { ((IDisposable)builderWrapper2).Dispose(); } } finally { ((IDisposable)builderWrapper).Dispose(); } } private long ScanBlockScalarBreaks(long currentIndent, StringBuilder breaks, bool isLiteral, ref Mark end, ref bool? isFirstLine) { long num = 0L; long num2 = -1L; end = cursor.Mark(); while (true) { if ((currentIndent == 0L || cursor.LineOffset < currentIndent) && analyzer.IsSpace()) { Skip(); continue; } if (cursor.LineOffset > num) { num = cursor.LineOffset; } if (!analyzer.IsBreak()) { break; } if (isFirstLine.GetValueOrDefault()) { isFirstLine = false; num2 = cursor.LineOffset; } breaks.Append(ReadLine()); end = cursor.Mark(); } if (isLiteral && isFirstLine.GetValueOrDefault()) { long num3 = cursor.LineOffset; int num4 = 0; while (!analyzer.IsBreak(num4) && analyzer.IsSpace(num4)) { num4++; num3++; } if (analyzer.IsBreak(num4) && num3 > cursor.LineOffset) { isFirstLine = false; num2 = num3; } } if (isLiteral && num2 > 1 && currentIndent < num2 - 1) { Mark end2 = cursor.Mark(); throw new SemanticErrorException(in end, in end2, "While scanning a literal block scalar, found extra spaces in first line."); } if (!isLiteral && num > cursor.LineOffset && num2 > -1) { Mark end2 = cursor.Mark(); throw new SemanticErrorException(in end, in end2, "While scanning a literal block scalar, found more spaces in lines above first content line."); } if (currentIndent == 0L && (cursor.LineOffset > 0 || indent > -1)) { currentIndent = Math.Max(num, Math.Max(indent + 1, 1L)); } return currentIndent; } private void FetchQuotedScalar(bool isSingleQuoted) { SaveSimpleKey(); simpleKeyAllowed = false; flowScalarFetched = flowLevel > 0; YamlDotNet.Core.Tokens.Scalar item = ScanFlowScalar(isSingleQuoted); tokens.Enqueue(item); lastScalar = item; if (!isSingleQuoted && analyzer.Check('#')) { Mark mark = cursor.Mark(); tokens.Enqueue(new Error("While scanning a flow sequence end, found invalid comment after double-quoted scalar.", mark, mark)); } } private YamlDotNet.Core.Tokens.Scalar ScanFlowScalar(bool isSingleQuoted) { Mark start = cursor.Mark(); Skip(); StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; StringBuilderPool.BuilderWrapper builderWrapper2 = StringBuilderPool.Rent(); try { StringBuilder builder2 = builderWrapper2.Builder; StringBuilderPool.BuilderWrapper builderWrapper3 = StringBuilderPool.Rent(); try { StringBuilder builder3 = builderWrapper3.Builder; StringBuilderPool.BuilderWrapper builderWrapper4 = StringBuilderPool.Rent(); try { StringBuilder builder4 = builderWrapper4.Builder; bool flag = false; while (true) { if (IsDocumentIndicator()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, found unexpected document indicator."); } if (analyzer.IsZero()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, found unexpected end of stream."); } if (flag && !isSingleQuoted && indent >= cursor.LineOffset) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a multi-line double-quoted scalar, found wrong indentation."); } flag = false; while (!analyzer.IsWhiteBreakOrZero()) { if (isSingleQuoted && analyzer.Check('\'') && analyzer.Check('\'', 1)) { builder.Append('\''); Skip(); Skip(); continue; } if (analyzer.Check(isSingleQuoted ? '\'' : '"')) { break; } if (!isSingleQuoted && analyzer.Check('\\') && analyzer.IsBreak(1)) { Skip(); SkipLine(); flag = true; break; } if (!isSingleQuoted && analyzer.Check('\\')) { int num = 0; char c = analyzer.Peek(1); switch (c) { case 'x': num = 2; break; case 'u': num = 4; break; case 'U': num = 8; break; default: { if (SimpleEscapeCodes.TryGetValue(c, out var value)) { builder.Append(value); break; } Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, found unknown escape character."); } } Skip(); Skip(); if (num <= 0) { continue; } int num2 = 0; for (int i = 0; i < num; i++) { if (!analyzer.IsHex(i)) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, did not find expected hexadecimal number."); } num2 = (num2 << 4) + analyzer.AsHex(i); } if (num2 >= 55296 && num2 <= 57343) { for (int j = 0; j < num; j++) { Skip(); } if (analyzer.Peek(0) != '\\' || (analyzer.Peek(1) != 'u' && analyzer.Peek(1) != 'U')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, found invalid Unicode surrogates."); } Skip(); num = ((analyzer.Peek(0) != 'u') ? 8 : 4); Skip(); int num3 = 0; for (int k = 0; k < num; k++) { if (!analyzer.IsHex(0)) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, did not find expected hexadecimal number."); } num3 = (num3 << 4) + analyzer.AsHex(k); } for (int l = 0; l < num; l++) { Skip(); } num2 = char.ConvertToUtf32((char)num2, (char)num3); } else { if (num2 > 1114111) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a quoted scalar, found invalid Unicode character escape code."); } for (int m = 0; m < num; m++) { Skip(); } } builder.Append(char.ConvertFromUtf32(num2)); } else { builder.Append(ReadCurrentCharacter()); } } if (analyzer.Check(isSingleQuoted ? '\'' : '"')) { break; } while (analyzer.IsWhite() || analyzer.IsBreak()) { if (analyzer.IsWhite()) { if (!flag) { builder2.Append(ReadCurrentCharacter()); } else { Skip(); } } else if (!flag) { builder2.Length = 0; builder3.Append(ReadLine()); flag = true; } else { builder4.Append(ReadLine()); } } if (flag) { if (StartsWith(builder3, '\n')) { if (builder4.Length == 0) { builder.Append(' '); } else { builder.Append((object?)builder4); } } else { builder.Append((object?)builder3); builder.Append((object?)builder4); } builder3.Length = 0; builder4.Length = 0; } else { builder.Append((object?)builder2); builder2.Length = 0; } } Skip(); return new YamlDotNet.Core.Tokens.Scalar(builder.ToString(), isSingleQuoted ? ScalarStyle.SingleQuoted : ScalarStyle.DoubleQuoted, start, cursor.Mark()); } finally { ((IDisposable)builderWrapper4).Dispose(); } } finally { ((IDisposable)builderWrapper3).Dispose(); } } finally { ((IDisposable)builderWrapper2).Dispose(); } } finally { ((IDisposable)builderWrapper).Dispose(); } } private void FetchPlainScalar() { SaveSimpleKey(); simpleKeyAllowed = false; bool isMultiline = false; YamlDotNet.Core.Tokens.Scalar item = (lastScalar = ScanPlainScalar(ref isMultiline)); if (isMultiline && analyzer.Check(':') && flowLevel == 0 && indent < cursor.LineOffset) { tokens.Enqueue(new Error("While scanning a multiline plain scalar, found invalid mapping.", cursor.Mark(), cursor.Mark())); } tokens.Enqueue(item); } private YamlDotNet.Core.Tokens.Scalar ScanPlainScalar(ref bool isMultiline) { StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; StringBuilderPool.BuilderWrapper builderWrapper2 = StringBuilderPool.Rent(); try { StringBuilder builder2 = builderWrapper2.Builder; StringBuilderPool.BuilderWrapper builderWrapper3 = StringBuilderPool.Rent(); try { StringBuilder builder3 = builderWrapper3.Builder; StringBuilderPool.BuilderWrapper builderWrapper4 = StringBuilderPool.Rent(); try { StringBuilder builder4 = builderWrapper4.Builder; bool flag = false; long num = indent + 1; Mark start = cursor.Mark(); Mark end = start; SimpleKey simpleKey = simpleKeys.Peek(); while (!IsDocumentIndicator()) { if (analyzer.Check('#')) { if (indent < 0 && flowLevel == 0) { plainScalarFollowedByComment = true; } break; } bool flag2 = analyzer.Check('*') && (!simpleKey.IsPossible || !simpleKey.IsRequired); while (!analyzer.IsWhiteBreakOrZero()) { if ((analyzer.Check(':') && !flag2 && (analyzer.IsWhiteBreakOrZero(1) || (flowLevel > 0 && analyzer.Check(',', 1)))) || (flowLevel > 0 && analyzer.Check(",[]{}"))) { if (flowLevel == 0 && !simpleKey.IsPossible) { tokens.Enqueue(new Error("While scanning a plain scalar value, found invalid mapping.", cursor.Mark(), cursor.Mark())); } break; } if (flag || builder2.Length > 0) { if (flag) { if (StartsWith(builder3, '\n')) { if (builder4.Length == 0) { builder.Append(' '); } else { builder.Append((object?)builder4); } } else { builder.Append((object?)builder3); builder.Append((object?)builder4); } builder3.Length = 0; builder4.Length = 0; flag = false; } else { builder.Append((object?)builder2); builder2.Length = 0; } } if (flowLevel > 0 && cursor.LineOffset < num) { throw new InvalidOperationException(); } builder.Append(ReadCurrentCharacter()); end = cursor.Mark(); } if (!analyzer.IsWhite() && !analyzer.IsBreak()) { break; } while (analyzer.IsWhite() || analyzer.IsBreak()) { if (analyzer.IsWhite()) { if (flag && cursor.LineOffset < num && analyzer.IsTab()) { Mark end2 = cursor.Mark(); throw new SyntaxErrorException(in start, in end2, "While scanning a plain scalar, found a tab character that violate indentation."); } if (!flag) { builder2.Append(ReadCurrentCharacter()); } else { Skip(); } } else { isMultiline = true; if (!flag) { builder2.Length = 0; builder3.Append(ReadLine()); flag = true; } else { builder4.Append(ReadLine()); } } } if (flowLevel == 0 && cursor.LineOffset < num) { break; } } if (flag) { simpleKeyAllowed = true; } return new YamlDotNet.Core.Tokens.Scalar(builder.ToString(), ScalarStyle.Plain, start, end); } finally { ((IDisposable)builderWrapper4).Dispose(); } } finally { ((IDisposable)builderWrapper3).Dispose(); } } finally { ((IDisposable)builderWrapper2).Dispose(); } } finally { ((IDisposable)builderWrapper).Dispose(); } } private void RemoveSimpleKey() { SimpleKey simpleKey = simpleKeys.Peek(); if (simpleKey.IsPossible && simpleKey.IsRequired) { Mark start = simpleKey.Mark; Mark end = simpleKey.Mark; throw new SyntaxErrorException(in start, in end, "While scanning a simple key, could not find expected ':'."); } simpleKey.MarkAsImpossible(); } private string ScanDirectiveName(in Mark start) { StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; while (analyzer.IsAlphaNumericDashOrUnderscore()) { builder.Append(ReadCurrentCharacter()); } if (builder.Length == 0) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a directive, could not find expected directive name."); } if (analyzer.EndOfInput) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a directive, found unexpected end of stream."); } if (!analyzer.IsWhiteBreakOrZero()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a directive, found unexpected non-alphabetical character."); } return builder.ToString(); } finally { ((IDisposable)builderWrapper).Dispose(); } } private void SkipWhitespaces() { while (analyzer.IsWhite()) { Skip(); } } private VersionDirective ScanVersionDirectiveValue(in Mark start) { SkipWhitespaces(); int major = ScanVersionDirectiveNumber(in start); if (!analyzer.Check('.')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a %YAML directive, did not find expected digit or '.' character."); } Skip(); int minor = ScanVersionDirectiveNumber(in start); return new VersionDirective(new Version(major, minor), start, start); } private TagDirective ScanTagDirectiveValue(in Mark start) { SkipWhitespaces(); string handle = ScanTagHandle(isDirective: true, start); if (!analyzer.IsWhite()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a %TAG directive, did not find expected whitespace."); } SkipWhitespaces(); string prefix = ScanTagUri(null, start); if (!analyzer.IsWhiteBreakOrZero()) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a %TAG directive, did not find expected whitespace or line break."); } return new TagDirective(handle, prefix, start, start); } private string ScanTagUri(string? head, Mark start) { StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; if (head != null && head.Length > 1) { builder.Append(head.Substring(1)); } while (analyzer.IsAlphaNumericDashOrUnderscore() || analyzer.Check(";/?:@&=+$.!~*'()[]%") || (analyzer.Check(',') && !analyzer.IsBreak(1))) { if (analyzer.Check('%')) { builder.Append(ScanUriEscapes(in start)); } else if (analyzer.Check('+')) { builder.Append(' '); Skip(); } else { builder.Append(ReadCurrentCharacter()); } } if (builder.Length == 0) { return string.Empty; } string text = builder.ToString(); if (Polyfills.EndsWith(text, ',')) { Mark start2 = cursor.Mark(); Mark end = cursor.Mark(); throw new SyntaxErrorException(in start2, in end, "Unexpected comma at end of tag"); } return text; } finally { ((IDisposable)builderWrapper).Dispose(); } } private string ScanUriEscapes(in Mark start) { byte[] array = EmptyBytes; int count = 0; int num = 0; do { if (!analyzer.Check('%') || !analyzer.IsHex(1) || !analyzer.IsHex(2)) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, did not find URI escaped octet."); } int num2 = (analyzer.AsHex(1) << 4) + analyzer.AsHex(2); if (num == 0) { num = (((num2 & 0x80) == 0) ? 1 : (((num2 & 0xE0) == 192) ? 2 : (((num2 & 0xF0) == 224) ? 3 : (((num2 & 0xF8) == 240) ? 4 : 0)))); if (num == 0) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, found an incorrect leading UTF-8 octet."); } array = new byte[num]; } else if ((num2 & 0xC0) != 128) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, found an incorrect trailing UTF-8 octet."); } array[count++] = (byte)num2; Skip(); Skip(); Skip(); } while (--num > 0); string @string = Encoding.UTF8.GetString(array, 0, count); if (@string.Length == 0 || @string.Length > 2) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, found an incorrect UTF-8 sequence."); } return @string; } private string ScanTagHandle(bool isDirective, Mark start) { if (!analyzer.Check('!')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag, did not find expected '!'."); } StringBuilderPool.BuilderWrapper builderWrapper = StringBuilderPool.Rent(); try { StringBuilder builder = builderWrapper.Builder; builder.Append(ReadCurrentCharacter()); while (analyzer.IsAlphaNumericDashOrUnderscore()) { builder.Append(ReadCurrentCharacter()); } if (analyzer.Check('!')) { builder.Append(ReadCurrentCharacter()); } else if (isDirective && (builder.Length != 1 || builder[0] != '!')) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a tag directive, did not find expected '!'."); } return builder.ToString(); } finally { ((IDisposable)builderWrapper).Dispose(); } } private int ScanVersionDirectiveNumber(in Mark start) { int num = 0; int num2 = 0; while (analyzer.IsDigit()) { if (++num2 > 9) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a %YAML directive, found extremely long version number."); } num = num * 10 + analyzer.AsDigit(); Skip(); } if (num2 == 0) { Mark end = cursor.Mark(); throw new SyntaxErrorException(in start, in end, "While scanning a %YAML directive, did not find expected version number."); } return num; } private void SaveSimpleKey() { bool isRequired = flowLevel == 0 && indent == cursor.LineOffset; if (simpleKeyAllowed) { SimpleKey item = new SimpleKey(isRequired, tokensParsed + tokens.Count, cursor); RemoveSimpleKey(); simpleKeys.Pop(); simpleKeys.Push(item); } } } internal class SemanticErrorException : YamlException { public SemanticErrorException(string message) : base(message) { } public SemanticErrorException(in Mark start, in Mark end, string message) : base(in start, in end, message) { } public SemanticErrorException(string message, Exception inner) : base(message, inner) { } } internal sealed class SimpleKey { private readonly Cursor cursor; public bool IsPossible { get; private set; } public bool IsRequired { get; } public int TokenNumber { get; } public long Index => cursor.Index; public long Line => cursor.Line; public long LineOffset => cursor.LineOffset; public Mark Mark => cursor.Mark(); public void MarkAsImpossible() { IsPossible = false; } public SimpleKey() { cursor = new Cursor(); } public SimpleKey(bool isRequired, int tokenNumber, Cursor cursor) { IsPossible = true; IsRequired = isRequired; TokenNumber = tokenNumber; this.cursor = new Cursor(cursor); } } internal sealed class StringLookAheadBuffer : ILookAheadBuffer, IResettable { public string Value { get; set; } = string.Empty; public int Position { get; private set; } public int Length => Value.Length; public bool EndOfInput => IsOutside(Position); public char Peek(int offset) { int index = Position + offset; if (!IsOutside(index)) { return Value[index]; } return '\0'; } private bool IsOutside(int index) { return index >= Value.Length; } public void Skip(int length) { if (length < 0) { throw new ArgumentOutOfRangeException("length", "The length must be positive."); } Position += length; } public bool TryReset() { Position = 0; Value = string.Empty; return true; } } internal sealed class SyntaxErrorException : YamlException { public SyntaxErrorException(string message) : base(message) { } public SyntaxErrorException(in Mark start, in Mark end, string message) : base(in start, in end, message) { } public SyntaxErrorException(string message, Exception inner) : base(message, inner) { } } public sealed class TagDirectiveCollection : KeyedCollection { public TagDirectiveCollection() { } public TagDirectiveCollection(IEnumerable tagDirectives) { foreach (TagDirective tagDirective in tagDirectives) { Add(tagDirective); } } protected override string GetKeyForItem(TagDirective item) { return item.Handle; } public new bool Contains(TagDirective directive) { return Contains(GetKeyForItem(directive)); } } public readonly struct TagName : IEquatable { public static readonly TagName Empty; private readonly string? value; public string Value => value ?? throw new InvalidOperationException("Cannot read the Value of a non-specific tag"); public bool IsEmpty => value == null; public bool IsNonSpecific { get { if (!IsEmpty) { if (!(value == "!")) { return value == "?"; } return true; } return false; } } public bool IsLocal { get { if (!IsEmpty) { return Value[0] == '!'; } return false; } } public bool IsGlobal { get { if (!IsEmpty) { return !IsLocal; } return false; } } public TagName(string value) { this.value = value ?? throw new ArgumentNullException("value"); if (value.Length == 0) { throw new ArgumentException("Tag value must not be empty.", "value"); } if (IsGlobal && !Uri.IsWellFormedUriString(value, UriKind.RelativeOrAbsolute)) { throw new ArgumentException("Global tags must be valid URIs.", "value"); } } public override string ToString() { return value ?? "?"; } public bool Equals(TagName other) { return object.Equals(value, other.value); } public override bool Equals(object? obj) { if (obj is TagName other) { return Equals(other); } return false; } public override int GetHashCode() { return value?.GetHashCode() ?? 0; } public static bool operator ==(TagName left, TagName right) { return left.Equals(right); } public static bool operator !=(TagName left, TagName right) { return !(left == right); } public static bool operator ==(TagName left, string right) { return object.Equals(left.value, right); } public static bool operator !=(TagName left, string right) { return !(left == right); } public static implicit operator TagName(string? value) { if (value != null) { return new TagName(value); } return Empty; } } public sealed class Version { public int Major { get; } public int Minor { get; } public Version(int major, int minor) { if (major < 0) { throw new ArgumentOutOfRangeException("major", $"{major} should be >= 0"); } Major = major; if (minor < 0) { throw new ArgumentOutOfRangeException("minor", $"{minor} should be >= 0"); } Minor = minor; } public override bool Equals(object? obj) { if (obj is Version version && Major == version.Major) { return Minor == version.Minor; } return false; } public override int GetHashCode() { return HashCode.CombineHashCodes(Major.GetHashCode(), Minor.GetHashCode()); } } internal class YamlException : Exception { public Mark Start { get; } public Mark End { get; } public YamlException(string message) : this(in Mark.Empty, in Mark.Empty, message) { } public YamlException(in Mark start, in Mark end, string message) : this(in start, in end, message, null) { } public YamlException(in Mark start, in Mark end, string message, Exception? innerException) : base(message, innerException) { Start = start; End = end; } public YamlException(string message, Exception inner) : this(in Mark.Empty, in Mark.Empty, message, inner) { } public override string ToString() { return $"({Start}) - ({End}): {Message}"; } } } namespace YamlDotNet.Core.Tokens { internal class Anchor : Token { public AnchorName Value { get; } public Anchor(AnchorName value) : this(value, Mark.Empty, Mark.Empty) { } public Anchor(AnchorName value, Mark start, Mark end) : base(in start, in end) { if (value.IsEmpty) { throw new ArgumentNullException("value"); } Value = value; } } internal sealed class AnchorAlias : Token { public AnchorName Value { get; } public AnchorAlias(AnchorName value) : this(value, Mark.Empty, Mark.Empty) { } public AnchorAlias(AnchorName value, Mark start, Mark end) : base(in start, in end) { if (value.IsEmpty) { throw new ArgumentNullException("value"); } Value = value; } } internal sealed class BlockEnd : Token { public BlockEnd() : this(in Mark.Empty, in Mark.Empty) { } public BlockEnd(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class BlockEntry : Token { public BlockEntry() : this(in Mark.Empty, in Mark.Empty) { } public BlockEntry(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class BlockMappingStart : Token { public BlockMappingStart() : this(in Mark.Empty, in Mark.Empty) { } public BlockMappingStart(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class BlockSequenceStart : Token { public BlockSequenceStart() : this(in Mark.Empty, in Mark.Empty) { } public BlockSequenceStart(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class Comment : Token { public string Value { get; } public bool IsInline { get; } public Comment(string value, bool isInline) : this(value, isInline, Mark.Empty, Mark.Empty) { } public Comment(string value, bool isInline, Mark start, Mark end) : base(in start, in end) { Value = value ?? throw new ArgumentNullException("value"); IsInline = isInline; } } internal sealed class DocumentEnd : Token { public DocumentEnd() : this(in Mark.Empty, in Mark.Empty) { } public DocumentEnd(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class DocumentStart : Token { public DocumentStart() : this(in Mark.Empty, in Mark.Empty) { } public DocumentStart(in Mark start, in Mark end) : base(in start, in end) { } } internal class Error : Token { public string Value { get; } public Error(string value, Mark start, Mark end) : base(in start, in end) { Value = value; } } internal sealed class FlowEntry : Token { public FlowEntry() : this(in Mark.Empty, in Mark.Empty) { } public FlowEntry(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class FlowMappingEnd : Token { public FlowMappingEnd() : this(in Mark.Empty, in Mark.Empty) { } public FlowMappingEnd(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class FlowMappingStart : Token { public FlowMappingStart() : this(in Mark.Empty, in Mark.Empty) { } public FlowMappingStart(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class FlowSequenceEnd : Token { public FlowSequenceEnd() : this(in Mark.Empty, in Mark.Empty) { } public FlowSequenceEnd(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class FlowSequenceStart : Token { public FlowSequenceStart() : this(in Mark.Empty, in Mark.Empty) { } public FlowSequenceStart(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class Key : Token { public Key() : this(in Mark.Empty, in Mark.Empty) { } public Key(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class Scalar : Token { public bool IsKey { get; set; } public string Value { get; } public ScalarStyle Style { get; } public Scalar(string value) : this(value, ScalarStyle.Any) { } public Scalar(string value, ScalarStyle style) : this(value, style, Mark.Empty, Mark.Empty) { } public Scalar(string value, ScalarStyle style, Mark start, Mark end) : base(in start, in end) { Value = value ?? throw new ArgumentNullException("value"); Style = style; } } internal sealed class StreamEnd : Token { public StreamEnd() : this(in Mark.Empty, in Mark.Empty) { } public StreamEnd(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class StreamStart : Token { public StreamStart() : this(in Mark.Empty, in Mark.Empty) { } public StreamStart(in Mark start, in Mark end) : base(in start, in end) { } } internal sealed class Tag : Token { public string Handle { get; } public string Suffix { get; } public Tag(string handle, string suffix) : this(handle, suffix, Mark.Empty, Mark.Empty) { } public Tag(string handle, string suffix, Mark start, Mark end) : base(in start, in end) { Handle = handle ?? throw new ArgumentNullException("handle"); Suffix = suffix ?? throw new ArgumentNullException("suffix"); } } public class TagDirective : Token { private static readonly Regex TagHandlePattern = new Regex("^!([0-9A-Za-z_\\-]*!)?$", RegexOptions.Compiled); public string Handle { get; } public string Prefix { get; } public TagDirective(string handle, string prefix) : this(handle, prefix, Mark.Empty, Mark.Empty) { } public TagDirective(string handle, string prefix, Mark start, Mark end) : base(in start, in end) { if (string.IsNullOrEmpty(handle)) { throw new ArgumentNullException("handle", "Tag handle must not be empty."); } if (!TagHandlePattern.IsMatch(handle)) { throw new ArgumentException("Tag handle must start and end with '!' and contain alphanumerical characters only.", "handle"); } Handle = handle; if (string.IsNullOrEmpty(prefix)) { throw new ArgumentNullException("prefix", "Tag prefix must not be empty."); } Prefix = prefix; } public override bool Equals(object? obj) { if (obj is TagDirective tagDirective && Handle.Equals(tagDirective.Handle)) { return Prefix.Equals(tagDirective.Prefix); } return false; } public override int GetHashCode() { return Handle.GetHashCode() ^ Prefix.GetHashCode(); } public override string ToString() { return Handle + " => " + Prefix; } } public abstract class Token { public Mark Start { get; } public Mark End { get; } protected Token(in Mark start, in Mark end) { Start = start; End = end; } } internal sealed class Value : Token { public Value() : this(in Mark.Empty, in Mark.Empty) { } public Value(in Mark start, in Mark end) : base(in start, in end) { } } public sealed class VersionDirective : Token { public Version Version { get; } public VersionDirective(Version version) : this(version, Mark.Empty, Mark.Empty) { } public VersionDirective(Version version, Mark start, Mark end) : base(in start, in end) { Version = version; } public override bool Equals(object? obj) { if (obj is VersionDirective versionDirective) { return Version.Equals(versionDirective.Version); } return false; } public override int GetHashCode() { return Version.GetHashCode(); } } } namespace YamlDotNet.Core.ObjectPool { internal class DefaultObjectPool : ObjectPool where T : class { private readonly Func createFunc; private readonly Func returnFunc; private readonly int maxCapacity; private int numItems; private protected readonly ConcurrentQueue items = new ConcurrentQueue(); private protected T? fastItem; public DefaultObjectPool(IPooledObjectPolicy policy) : this(policy, Environment.ProcessorCount * 2) { } public DefaultObjectPool(IPooledObjectPolicy policy, int maximumRetained) { createFunc = policy.Create; returnFunc = policy.Return; maxCapacity = maximumRetained - 1; } public override T Get() { T result = fastItem; if (result == null || Interlocked.CompareExchange(ref fastItem, null, result) != result) { if (items.TryDequeue(out result)) { Interlocked.Decrement(ref numItems); return result; } return createFunc(); } return result; } public override void Return(T obj) { ReturnCore(obj); } private protected bool ReturnCore(T obj) { if (!returnFunc(obj)) { return false; } if (fastItem != null || Interlocked.CompareExchange(ref fastItem, obj, null) != null) { if (Interlocked.Increment(ref numItems) <= maxCapacity) { items.Enqueue(obj); return true; } Interlocked.Decrement(ref numItems); return false; } return true; } } internal class DefaultPooledObjectPolicy : IPooledObjectPolicy where T : class, new() { public T Create() { return new T(); } public bool Return(T obj) { if (obj is IResettable resettable) { return resettable.TryReset(); } return true; } } internal interface IPooledObjectPolicy where T : notnull { T Create(); bool Return(T obj); } internal interface IResettable { bool TryReset(); } internal abstract class ObjectPool where T : class { public abstract T Get(); public abstract void Return(T obj); } internal static class ObjectPool { public static ObjectPool Create(IPooledObjectPolicy? policy = null) where T : class, new() { return new DefaultObjectPool(policy ?? new DefaultPooledObjectPolicy()); } public static ObjectPool Create(int maximumRetained, IPooledObjectPolicy? policy = null) where T : class, new() { return new DefaultObjectPool(policy ?? new DefaultPooledObjectPolicy(), maximumRetained); } } [DebuggerStepThrough] internal static class StringBuilderPool { internal readonly struct BuilderWrapper : IDisposable { public readonly StringBuilder Builder; private readonly ObjectPool pool; public BuilderWrapper(StringBuilder builder, ObjectPool pool) { Builder = builder; this.pool = pool; } public override string ToString() { return Builder.ToString(); } public void Dispose() { pool.Return(Builder); } } private static readonly ObjectPool Pool = ObjectPool.Create(new StringBuilderPooledObjectPolicy { InitialCapacity = 16, MaximumRetainedCapacity = 1024 }); public static BuilderWrapper Rent() { StringBuilder builder = Pool.Get(); return new BuilderWrapper(builder, Pool); } } internal class StringBuilderPooledObjectPolicy : IPooledObjectPolicy { public int InitialCapacity { get; set; } = 100; public int MaximumRetainedCapacity { get; set; } = 4096; public StringBuilder Create() { return new StringBuilder(InitialCapacity); } public bool Return(StringBuilder obj) { if (obj.Capacity > MaximumRetainedCapacity) { return false; } obj.Clear(); return true; } } internal static class StringLookAheadBufferPool { internal readonly struct BufferWrapper : IDisposable { public readonly StringLookAheadBuffer Buffer; private readonly ObjectPool pool; public BufferWrapper(StringLookAheadBuffer buffer, ObjectPool pool) { Buffer = buffer; this.pool = pool; } public override string ToString() { return Buffer.ToString(); } public void Dispose() { pool.Return(Buffer); } } private static readonly ObjectPool Pool = ObjectPool.Create(new DefaultPooledObjectPolicy()); public static BufferWrapper Rent(string value) { StringLookAheadBuffer stringLookAheadBuffer = Pool.Get(); stringLookAheadBuffer.Value = value; return new BufferWrapper(stringLookAheadBuffer, Pool); } } } namespace YamlDotNet.Core.Events { public sealed class AnchorAlias : ParsingEvent { internal override EventType Type => EventType.Alias; public AnchorName Value { get; } public AnchorAlias(AnchorName value, Mark start, Mark end) : base(in start, in end) { if (value.IsEmpty) { throw new YamlException(in start, in end, "Anchor value must not be empty."); } Value = value; } public AnchorAlias(AnchorName value) : this(value, Mark.Empty, Mark.Empty) { } public override string ToString() { return $"Alias [value = {Value}]"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public sealed class Comment : ParsingEvent { public string Value { get; } public bool IsInline { get; } internal override EventType Type => EventType.Comment; public Comment(string value, bool isInline) : this(value, isInline, Mark.Empty, Mark.Empty) { } public Comment(string value, bool isInline, Mark start, Mark end) : base(in start, in end) { Value = value; IsInline = isInline; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } public override string ToString() { return (IsInline ? "Inline" : "Block") + " Comment [" + Value + "]"; } } public sealed class DocumentEnd : ParsingEvent { public override int NestingIncrease => -1; internal override EventType Type => EventType.DocumentEnd; public bool IsImplicit { get; } public DocumentEnd(bool isImplicit, Mark start, Mark end) : base(in start, in end) { IsImplicit = isImplicit; } public DocumentEnd(bool isImplicit) : this(isImplicit, Mark.Empty, Mark.Empty) { } public override string ToString() { return $"Document end [isImplicit = {IsImplicit}]"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public sealed class DocumentStart : ParsingEvent { public override int NestingIncrease => 1; internal override EventType Type => EventType.DocumentStart; public TagDirectiveCollection? Tags { get; } public VersionDirective? Version { get; } public bool IsImplicit { get; } public DocumentStart(VersionDirective? version, TagDirectiveCollection? tags, bool isImplicit, Mark start, Mark end) : base(in start, in end) { Version = version; Tags = tags; IsImplicit = isImplicit; } public DocumentStart(VersionDirective? version, TagDirectiveCollection? tags, bool isImplicit) : this(version, tags, isImplicit, Mark.Empty, Mark.Empty) { } public DocumentStart(in Mark start, in Mark end) : this(null, null, isImplicit: true, start, end) { } public DocumentStart() : this(null, null, isImplicit: true, Mark.Empty, Mark.Empty) { } public override string ToString() { return $"Document start [isImplicit = {IsImplicit}]"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } internal enum EventType { None, StreamStart, StreamEnd, DocumentStart, DocumentEnd, Alias, Scalar, SequenceStart, SequenceEnd, MappingStart, MappingEnd, Comment } public interface IParsingEventVisitor { void Visit(AnchorAlias e); void Visit(StreamStart e); void Visit(StreamEnd e); void Visit(DocumentStart e); void Visit(DocumentEnd e); void Visit(Scalar e); void Visit(SequenceStart e); void Visit(SequenceEnd e); void Visit(MappingStart e); void Visit(MappingEnd e); void Visit(Comment e); } public class MappingEnd : ParsingEvent { public override int NestingIncrease => -1; internal override EventType Type => EventType.MappingEnd; public MappingEnd(in Mark start, in Mark end) : base(in start, in end) { } public MappingEnd() : this(in Mark.Empty, in Mark.Empty) { } public override string ToString() { return "Mapping end"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public sealed class MappingStart : NodeEvent { public override int NestingIncrease => 1; internal override EventType Type => EventType.MappingStart; public bool IsImplicit { get; } public override bool IsCanonical => !IsImplicit; public MappingStyle Style { get; } public MappingStart(AnchorName anchor, TagName tag, bool isImplicit, MappingStyle style, Mark start, Mark end) : base(anchor, tag, start, end) { IsImplicit = isImplicit; Style = style; } public MappingStart(AnchorName anchor, TagName tag, bool isImplicit, MappingStyle style) : this(anchor, tag, isImplicit, style, Mark.Empty, Mark.Empty) { } public MappingStart() : this(AnchorName.Empty, TagName.Empty, isImplicit: true, MappingStyle.Any, Mark.Empty, Mark.Empty) { } public override string ToString() { return $"Mapping start [anchor = {base.Anchor}, tag = {base.Tag}, isImplicit = {IsImplicit}, style = {Style}]"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public enum MappingStyle { Any, Block, Flow } public abstract class NodeEvent : ParsingEvent { public AnchorName Anchor { get; } public TagName Tag { get; } public abstract bool IsCanonical { get; } protected NodeEvent(AnchorName anchor, TagName tag, Mark start, Mark end) : base(in start, in end) { Anchor = anchor; Tag = tag; } protected NodeEvent(AnchorName anchor, TagName tag) : this(anchor, tag, Mark.Empty, Mark.Empty) { } } public abstract class ParsingEvent { public virtual int NestingIncrease => 0; internal abstract EventType Type { get; } public Mark Start { get; } public Mark End { get; } public abstract void Accept(IParsingEventVisitor visitor); internal ParsingEvent(in Mark start, in Mark end) { Start = start; End = end; } } public sealed class Scalar : NodeEvent { internal override EventType Type => EventType.Scalar; public string Value { get; } public ScalarStyle Style { get; } public bool IsPlainImplicit { get; } public bool IsQuotedImplicit { get; } public override bool IsCanonical { get { if (!IsPlainImplicit) { return !IsQuotedImplicit; } return false; } } public bool IsKey { get; } public Scalar(AnchorName anchor, TagName tag, string value, ScalarStyle style, bool isPlainImplicit, bool isQuotedImplicit, Mark start, Mark end, bool isKey = false) : base(anchor, tag, start, end) { Value = value; Style = style; IsPlainImplicit = isPlainImplicit; IsQuotedImplicit = isQuotedImplicit; IsKey = isKey; } public Scalar(AnchorName anchor, TagName tag, string value, ScalarStyle style, bool isPlainImplicit, bool isQuotedImplicit) : this(anchor, tag, value, style, isPlainImplicit, isQuotedImplicit, Mark.Empty, Mark.Empty) { } public Scalar(string value) : this(AnchorName.Empty, TagName.Empty, value, ScalarStyle.Any, isPlainImplicit: true, isQuotedImplicit: true, Mark.Empty, Mark.Empty) { } public Scalar(TagName tag, string value) : this(AnchorName.Empty, tag, value, ScalarStyle.Any, isPlainImplicit: true, isQuotedImplicit: true, Mark.Empty, Mark.Empty) { } public Scalar(AnchorName anchor, TagName tag, string value) : this(anchor, tag, value, ScalarStyle.Any, isPlainImplicit: true, isQuotedImplicit: true, Mark.Empty, Mark.Empty) { } public override string ToString() { return $"Scalar [anchor = {base.Anchor}, tag = {base.Tag}, value = {Value}, style = {Style}, isPlainImplicit = {IsPlainImplicit}, isQuotedImplicit = {IsQuotedImplicit}]"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public sealed class SequenceEnd : ParsingEvent { public override int NestingIncrease => -1; internal override EventType Type => EventType.SequenceEnd; public SequenceEnd(in Mark start, in Mark end) : base(in start, in end) { } public SequenceEnd() : this(in Mark.Empty, in Mark.Empty) { } public override string ToString() { return "Sequence end"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public sealed class SequenceStart : NodeEvent { public override int NestingIncrease => 1; internal override EventType Type => EventType.SequenceStart; public bool IsImplicit { get; } public override bool IsCanonical => !IsImplicit; public SequenceStyle Style { get; } public SequenceStart(AnchorName anchor, TagName tag, bool isImplicit, SequenceStyle style, Mark start, Mark end) : base(anchor, tag, start, end) { IsImplicit = isImplicit; Style = style; } public SequenceStart(AnchorName anchor, TagName tag, bool isImplicit, SequenceStyle style) : this(anchor, tag, isImplicit, style, Mark.Empty, Mark.Empty) { } public override string ToString() { return $"Sequence start [anchor = {base.Anchor}, tag = {base.Tag}, isImplicit = {IsImplicit}, style = {Style}]"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public enum SequenceStyle { Any, Block, Flow } public sealed class StreamEnd : ParsingEvent { public override int NestingIncrease => -1; internal override EventType Type => EventType.StreamEnd; public StreamEnd(in Mark start, in Mark end) : base(in start, in end) { } public StreamEnd() : this(in Mark.Empty, in Mark.Empty) { } public override string ToString() { return "Stream end"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } public sealed class StreamStart : ParsingEvent { public override int NestingIncrease => 1; internal override EventType Type => EventType.StreamStart; public StreamStart() : this(in Mark.Empty, in Mark.Empty) { } public StreamStart(in Mark start, in Mark end) : base(in start, in end) { } public override string ToString() { return "Stream start"; } public override void Accept(IParsingEventVisitor visitor) { visitor.Visit(this); } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } }