diff --git a/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule.csproj b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule.csproj new file mode 100644 index 0000000..3901773 --- /dev/null +++ b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule.csproj @@ -0,0 +1,20 @@ + + + AntiDickheadChatmodule + False + net10.0 + x64 + + + 14.0 + True + False + + + + + + + + + \ No newline at end of file diff --git a/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Configuration.cs b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Configuration.cs new file mode 100644 index 0000000..a158f65 --- /dev/null +++ b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Configuration.cs @@ -0,0 +1,28 @@ +using System; +using Dalamud.Configuration; +using Dalamud.Plugin; + +namespace AntiDickheadChatmodule; + +[Serializable] +public class Configuration : IPluginConfiguration +{ + [NonSerialized] + private IDalamudPluginInterface? pluginInterface; + + public int Version { get; set; } + + public bool Enabled { get; set; } = true; + + public int RightClickDelay { get; set; } = 250; + + public void Initialize(IDalamudPluginInterface pluginInterface) + { + this.pluginInterface = pluginInterface; + } + + public void Save() + { + pluginInterface.SavePluginConfig((IPluginConfiguration)(object)this); + } +} diff --git a/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Plugin.cs b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Plugin.cs new file mode 100644 index 0000000..a739996 --- /dev/null +++ b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Plugin.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Dalamud.Game.Command; +using Dalamud.Game.Text; +using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Game.Text.SeStringHandling.Payloads; +using Dalamud.Hooking; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace AntiDickheadChatmodule; + +public sealed class Plugin : IDalamudPlugin, IDisposable +{ + private unsafe delegate void* AgentShow(void* a1); + + private const string commandName = "/adh"; + + public string Name => "Anti-Dickhead chatmodule"; + + private IDalamudPluginInterface PluginInterface { get; init; } + + private ICommandManager CommandManager { get; init; } + + private Configuration Configuration { get; init; } + + private PluginUI PluginUi { get; init; } + + public long rcStartTime { get; private set; } + + private Hook? DutyFinderHook { get; set; } + + public unsafe AtkUnitBase* dutyFinderAtkUnitBase { get; private set; } + + public string DataPath { get; } = string.Empty; + + public Plugin(IDalamudPluginInterface pluginInterface, ICommandManager commandManager) + { + //IL_0084: Unknown result type (might be due to invalid IL or missing references) + //IL_008e: Expected O, but got Unknown + //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_009e: Expected O, but got Unknown + //IL_00e3: Unknown result type (might be due to invalid IL or missing references) + //IL_00ed: Expected O, but got Unknown + PluginInterface = pluginInterface; + CommandManager = commandManager; + pluginInterface.Create(Array.Empty()); + Configuration = (PluginInterface.GetPluginConfig() as Configuration) ?? new Configuration(); + Configuration.Initialize(PluginInterface); + PluginUi = new PluginUI(Configuration, DataPath); + CommandManager.AddHandler("/adh", new CommandInfo(new HandlerDelegate(OnCommand)) + { + HelpMessage = "Show the tracker UI" + }); + PluginInterface.UiBuilder.Draw += DrawUI; + PluginInterface.UiBuilder.OpenConfigUi += DrawConfigUI; + Service.Chat.ChatMessage += new OnMessageDelegate(Chat_ChatMessage1); + } + + private void Chat_ChatMessage1(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled) + { + //IL_0085: Unknown result type (might be due to invalid IL or missing references) + if (!new List + { + (XivChatType)15, + (XivChatType)37, + (XivChatType)101, + (XivChatType)102, + (XivChatType)103, + (XivChatType)104, + (XivChatType)105, + (XivChatType)106, + (XivChatType)107, + (XivChatType)14, + (XivChatType)11, + (XivChatType)10, + (XivChatType)30, + (XivChatType)24, + (XivChatType)13, + (XivChatType)27 + }.Contains(type)) + { + return; + } + try + { + bool flag = false; + foreach (Payload payload in message.Payloads) + { + TextPayload val = (TextPayload)(object)((payload is TextPayload) ? payload : null); + if (val == null) + { + continue; + } + if (flag) + { + flag = false; + continue; + } + string text = val.Text; + Service.PluginLog.Debug(text ?? string.Empty, Array.Empty()); + if (string.IsNullOrEmpty(text) || text.Contains('\ue0bb')) + { + Service.PluginLog.Debug("Skipping, because empty or symbol", Array.Empty()); + flag = true; + continue; + } + string text2 = text; + if (text2.Contains(".") || char.IsUpper(text2[0])) + { + string[] array = text2.Split(" "); + for (int i = 0; i < array.Length; i++) + { + if (array[i].Length > 1 && char.IsUpper(array[i][0]) && !char.IsUpper(array[i][1]) && array[i][1] != '\'') + { + array[i] = array[i].ToLower(); + } + if (!array[i].EndsWith(".")) + { + continue; + } + if (i + 1 < array.Length) + { + string pattern = "((?::|;|=)(?:-)?(?:\\)|D|P))"; + if (Regex.Match(array[i + 1], pattern, RegexOptions.IgnoreCase).Success) + { + array[i] = array[i].Substring(0, array[i].Length - 1); + } + } + else + { + array[i] = array[i].Substring(0, array[i].Length - 1); + } + } + string text3 = ""; + string[] array2 = array; + foreach (string text4 in array2) + { + text3 = text3 + text4 + " "; + } + text2 = text3; + } + if (!text.Equals(text2)) + { + val.Text = text2; + } + } + } + catch + { + Service.PluginLog.Debug($"Failed to process message: {message}.", Array.Empty()); + } + } + + public void Dispose() + { + //IL_0028: Unknown result type (might be due to invalid IL or missing references) + //IL_0032: Expected O, but got Unknown + PluginUi.Dispose(); + CommandManager.RemoveHandler("/adh"); + Service.Chat.ChatMessage -= new OnMessageDelegate(Chat_ChatMessage1); + } + + private void OnCommand(string command, string args) + { + PluginUi.Visible = true; + } + + private void DrawUI() + { + PluginUi.Draw(); + } + + private void DrawConfigUI() + { + PluginUi.SettingsVisible = true; + } +} diff --git a/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/PluginUI.cs b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/PluginUI.cs new file mode 100644 index 0000000..eaf4a61 --- /dev/null +++ b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/PluginUI.cs @@ -0,0 +1,102 @@ +using System; +using System.Numerics; +using Dalamud.Bindings.ImGui; + +namespace AntiDickheadChatmodule; + +internal class PluginUI : IDisposable +{ + private Configuration configuration; + + private bool settingsVisible; + + private bool visible; + + public string DataPath { get; } + + public bool SettingsVisible + { + get + { + return settingsVisible; + } + set + { + settingsVisible = value; + } + } + + public bool Visible + { + get + { + return visible; + } + set + { + visible = value; + } + } + + public PluginUI(Configuration configuration, string DataPath) + { + this.configuration = configuration; + this.DataPath = DataPath; + } + + public void DrawMainWindow() + { + //IL_0046: 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) + if (Visible) + { + ImGui.SetNextWindowSize(new Vector2(700f, 330f), (ImGuiCond)4); + ImGui.SetNextWindowSizeConstraints(new Vector2(700f, 330f), new Vector2(float.MaxValue, float.MaxValue)); + if (ImGui.Begin(ImU8String.op_Implicit("Dickheads be gone from mine chat"), ref visible, (ImGuiWindowFlags)24)) + { + ImGui.Text(ImU8String.op_Implicit("Anti-fags :D")); + } + ImGui.End(); + } + } + + public void Dispose() + { + } + + public void Draw() + { + DrawMainWindow(); + DrawSettingsWindow(); + } + + public void DrawSettingsWindow() + { + //IL_0023: 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_007e: 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_0091: Unknown result type (might be due to invalid IL or missing references) + if (!SettingsVisible) + { + return; + } + ImGui.SetNextWindowSize(new Vector2(450f, 100f), (ImGuiCond)1); + if (ImGui.Begin(ImU8String.op_Implicit("World Map Enhancer Settings"), ref settingsVisible, (ImGuiWindowFlags)58)) + { + bool enabled = configuration.Enabled; + if (ImGui.Checkbox(ImU8String.op_Implicit("Enable zooming out with right click"), ref enabled)) + { + configuration.Enabled = enabled; + configuration.Save(); + } + int rightClickDelay = configuration.RightClickDelay; + if (ImGui.InputInt(ImU8String.op_Implicit("Right click release delay"), ref rightClickDelay, 25, 100, default(ImU8String), (ImGuiInputTextFlags)0)) + { + configuration.RightClickDelay = rightClickDelay; + configuration.Save(); + } + } + ImGui.End(); + } +} diff --git a/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Service.cs b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Service.cs new file mode 100644 index 0000000..510a095 --- /dev/null +++ b/.recovery/decompiled/AntiDickheadChatmodule/AntiDickheadChatmodule/Service.cs @@ -0,0 +1,19 @@ +using Dalamud.IoC; +using Dalamud.Plugin.Services; + +namespace AntiDickheadChatmodule; + +public class Service +{ + [PluginService] + public static IClientState ClientState { get; private set; } + + [PluginService] + public static IChatGui Chat { get; private set; } + + [PluginService] + public static IDataManager Data { get; private set; } + + [PluginService] + public static IPluginLog PluginLog { get; private set; } +} diff --git a/.recovery/decompiled/AntiDickheadChatmodule/Properties/AssemblyInfo.cs b/.recovery/decompiled/AntiDickheadChatmodule/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e260593 --- /dev/null +++ b/.recovery/decompiled/AntiDickheadChatmodule/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyCompany("aRkker")] +[assembly: AssemblyConfiguration("Release")] +[assembly: AssemblyDescription("Sufferable chat = insufferable. :)")] +[assembly: AssemblyFileVersion("0.0.6.0")] +[assembly: AssemblyInformationalVersion("0.0.6.0+8c181f19a2ba71e0bee0e08ad8a42953b3276520")] +[assembly: AssemblyProduct("AntiDickheadChatmodule")] +[assembly: AssemblyTitle("AntiDickheadChatmodule")] +[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/aRkker/ffxiv-dalamud-wme.git")] +[assembly: AssemblyVersion("0.0.6.0")] diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.csproj b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.csproj new file mode 100644 index 0000000..9c383ae --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.csproj @@ -0,0 +1,23 @@ + + + CrystallineConflictWinsTracker + False + net7.0 + x64 + + + 14.0 + True + False + + + + + + + + + + + + \ No newline at end of file diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Configuration.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Configuration.cs new file mode 100644 index 0000000..8818bd4 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Configuration.cs @@ -0,0 +1,28 @@ +using System; +using Dalamud.Configuration; +using Dalamud.Plugin; + +namespace CrystallineConflictWinsTracker; + +[Serializable] +public class Configuration : IPluginConfiguration +{ + [NonSerialized] + private DalamudPluginInterface? pluginInterface; + + public int Version { get; set; } + + public bool Enabled { get; set; } = true; + + public int RightClickDelay { get; set; } = 250; + + public void Initialize(DalamudPluginInterface pluginInterface) + { + this.pluginInterface = pluginInterface; + } + + public void Save() + { + pluginInterface.SavePluginConfig((IPluginConfiguration)(object)this); + } +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/DalamudApi.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/DalamudApi.cs new file mode 100644 index 0000000..f46a216 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/DalamudApi.cs @@ -0,0 +1,48 @@ +using System; +using Dalamud.Game; +using Dalamud.IoC; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; + +namespace CrystallineConflictWinsTracker; + +public class DalamudApi +{ + [PluginService] + public static IChatGui ChatGui { get; private set; } + + [PluginService] + public static IClientState ClientState { get; private set; } + + [PluginService] + public static ICommandManager CommandManager { get; private set; } + + [PluginService] + public static DalamudPluginInterface PluginInterface { get; private set; } + + [PluginService] + public static IDataManager DataManager { get; private set; } + + [PluginService] + public static IDtrBar DtrBar { get; private set; } + + [PluginService] + public static IFramework Framework { get; private set; } + + [PluginService] + public static IGameGui GameGui { get; private set; } + + [PluginService] + public static ISigScanner SigScanner { get; private set; } + + [PluginService] + public static IGameInteropProvider Hooks { get; private set; } + + [PluginService] + public static IPluginLog PluginLog { get; private set; } + + public static void Initialize(DalamudPluginInterface pluginInterface) + { + pluginInterface.Create(Array.Empty()); + } +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Plugin.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Plugin.cs new file mode 100644 index 0000000..14dffa8 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Plugin.cs @@ -0,0 +1,378 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Game.Command; +using Dalamud.Game.Text; +using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Hooking; +using Dalamud.IoC; +using Dalamud.Logging; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Client.System.String; +using FFXIVClientStructs.FFXIV.Component.GUI; +using Newtonsoft.Json; + +namespace CrystallineConflictWinsTracker; + +public sealed class Plugin : IDalamudPlugin, IDisposable +{ + private unsafe delegate void* AgentShow(void* a1); + + private unsafe delegate void* FireCallbackDelegate(AtkUnitBase* atkUnitBase, int valueCount, AtkValue* atkValues, ulong a4); + + private const string commandName = "/ccwins"; + + public bool dutyFinderVisible; + + public bool pvpPageVisible; + + public bool casualCCEnabled; + + public bool rankedCCEnabled; + + public bool alertedDebugWindow; + + private Hook addonReceiveEventHook; + + public string Name => "Crystaline Conflict Winratio tracker"; + + private DalamudPluginInterface PluginInterface { get; init; } + + private ICommandManager CommandManager { get; init; } + + private Configuration Configuration { get; init; } + + private PluginUI PluginUi { get; init; } + + public long rcStartTime { get; private set; } + + private Hook DutyFinderHook { get; set; } + + public unsafe AtkUnitBase* dutyFinderAtkUnitBase { get; private set; } + + public string DataPath { get; } + + public Plugin([RequiredVersion("1.0")] DalamudPluginInterface pluginInterface) + { + //IL_003e: Unknown result type (might be due to invalid IL or missing references) + //IL_0048: Expected O, but got Unknown + //IL_0114: Unknown result type (might be due to invalid IL or missing references) + //IL_011e: Expected O, but got Unknown + //IL_0119: Unknown result type (might be due to invalid IL or missing references) + //IL_011e: Unknown result type (might be due to invalid IL or missing references) + //IL_012e: Expected O, but got Unknown + //IL_019f: Unknown result type (might be due to invalid IL or missing references) + //IL_01a9: Expected O, but got Unknown + DalamudApi.Initialize(pluginInterface); + DalamudApi.PluginLog.Debug("Initializing the plugin...", Array.Empty()); + PluginInterface = pluginInterface; + CommandManager = DalamudApi.CommandManager; + DalamudApi.Framework.Update += new OnUpdateDelegate(Framework_UpdateNew); + Configuration = (PluginInterface.GetPluginConfig() as Configuration) ?? new Configuration(); + Configuration.Initialize(PluginInterface); + DataPath = PluginInterface.ConfigDirectory?.ToString() + "/data/"; + try + { + Directory.CreateDirectory(DataPath); + } + catch (Exception ex) + { + PluginLog.LogError(ex, "Failed to create data directory.", Array.Empty()); + } + if (!File.Exists(DataPath + "pvpstats.json")) + { + File.Create(DataPath + "pvpstats.json"); + } + PluginUi = new PluginUI(Configuration, DataPath); + DalamudApi.CommandManager.AddHandler("/ccwins", new CommandInfo(new HandlerDelegate(OnCommand)) + { + HelpMessage = "Show the tracker UI" + }); + PluginInterface.UiBuilder.Draw += DrawUI; + PluginInterface.UiBuilder.OpenConfigUi += DrawConfigUI; + DalamudApi.ClientState.EnterPvP += ClientState_EnterPvP; + DalamudApi.ClientState.LeavePvP += ClientState_LeavePvP; + DalamudApi.ChatGui.ChatMessage += new OnMessageDelegate(Chat_ChatMessage); + } + + private void Framework_UpdateNew(IFramework framework) + { + if (Configuration.Enabled && DalamudApi.ClientState.IsLoggedIn) + { + CheckForDfSelections(); + } + } + + private void Chat_ChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) + { + //IL_0000: Unknown result type (might be due to invalid IL or missing references) + //IL_0006: Invalid comparison between Unknown and I4 + if ((int)type != 2112) + { + return; + } + PluginLog.Debug(message.TextValue, Array.Empty()); + if (message.TextValue.Contains("900 Series EXP.")) + { + PluginLog.Debug("WE WON THE GAME?", Array.Empty()); + if (casualCCEnabled) + { + PluginLog.Debug("CASUAL WIN", Array.Empty()); + StoreNewPvpRow(ranked: false, win: true); + } + else if (rankedCCEnabled) + { + PluginLog.Debug("RANKED WIN", Array.Empty()); + StoreNewPvpRow(ranked: true, win: true); + } + else + { + PluginLog.Error("NEITHER MODE IS UP? WAT?", Array.Empty()); + } + } + else if (message.TextValue.Contains("700 Series EXP.")) + { + PluginLog.Debug("WE LOST THE GAME?", Array.Empty()); + if (casualCCEnabled) + { + PluginLog.Debug("CASUAL LOSS", Array.Empty()); + StoreNewPvpRow(ranked: false, win: false); + } + else if (rankedCCEnabled) + { + PluginLog.Debug("RANKED LOSS", Array.Empty()); + StoreNewPvpRow(ranked: true, win: false); + } + else + { + PluginLog.Error("NEITHER MODE IS UP? WAT?", Array.Empty()); + } + } + } + + private void StoreNewPvpRow(bool ranked, bool win) + { + string text = File.ReadAllText(DataPath + "pvpstats.json"); + List obj = JsonConvert.DeserializeObject>(text) ?? new List(); + obj.Add(new PvpWinEntry + { + classId = ((Character)DalamudApi.ClientState.LocalPlayer).ClassJob.Id, + win = win, + ranked = ranked, + className = ((Character)DalamudApi.ClientState.LocalPlayer).ClassJob.GameData.Name.RawString, + matchDate = DateTime.Now + }); + text = JsonConvert.SerializeObject((object)obj); + File.WriteAllText(DataPath + "pvpstats.json", text); + } + + private void ClientState_LeavePvP() + { + PluginLog.Debug("Yes, we left pvp :)", Array.Empty()); + } + + private unsafe void* CallbackDetour(AtkUnitBase* atkunitbase, int valuecount, AtkValue* atkvalues, ulong a4) + { + //IL_0052: 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_0062: 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_0067: Unknown result type (might be due to invalid IL or missing references) + //IL_0081: Expected I4, but got Unknown + //IL_00eb: Unknown result type (might be due to invalid IL or missing references) + //IL_0139: Unknown result type (might be due to invalid IL or missing references) + //IL_013e: Unknown result type (might be due to invalid IL or missing references) + //IL_0140: Unknown result type (might be due to invalid IL or missing references) + //IL_0143: Invalid comparison between Unknown and I4 + //IL_0176: Unknown result type (might be due to invalid IL or missing references) + //IL_0179: Invalid comparison between Unknown and I4 + //IL_0180: Unknown result type (might be due to invalid IL or missing references) + //IL_0186: Invalid comparison between Unknown and I4 + if (dutyFinderAtkUnitBase == null) + { + return addonReceiveEventHook.Original(atkunitbase, valuecount, atkvalues, a4); + } + if (atkunitbase == dutyFinderAtkUnitBase) + { + PluginLog.Debug("OMG ITS CONTENTSFINDER :D", Array.Empty()); + List list = new List(); + List list2 = new List(); + try + { + AtkValue* ptr = atkvalues; + for (int i = 0; i < valuecount; i++) + { + list2.Add(((AtkValue)ptr).Type); + ValueType type = ((AtkValue)ptr).Type; + switch (type - 2) + { + case 0: + list.Add(((AtkValue)ptr).Byte > 0); + break; + case 1: + list.Add(((AtkValue)ptr).Int); + break; + case 2: + list.Add(((AtkValue)ptr).UInt); + break; + case 4: + list.Add(Marshal.PtrToStringUTF8(new IntPtr(((AtkValue)ptr).String))); + break; + default: + list.Add($"Unknown Type: {((AtkValue)ptr).Type}"); + break; + } + ptr = (AtkValue*)((byte*)ptr + Unsafe.SizeOf()); + } + } + catch + { + return addonReceiveEventHook.Original(atkunitbase, valuecount, atkvalues, a4); + } + if (valuecount > 1) + { + object obj2 = list[1]; + ValueType val = list2[1]; + if ((int)val == 3) + { + if ((int)obj2 == 8) + { + PluginLog.Debug("HOOO BOY WE GOING PVP", Array.Empty()); + pvpPageVisible = true; + } + else + { + pvpPageVisible = false; + } + } + else if ((int)val == 4 && (int)list2[0] == 3 && (int)list[0] == 3) + { + PluginLog.Debug("SOMETHIGNG CLICKED?", Array.Empty()); + if (pvpPageVisible) + { + AtkComponentCheckBox* nodeById = (AtkComponentCheckBox*)((AtkUnitBase)(nint)DalamudApi.GameGui.GetAddonByName("ContentsFinder", 1)).GetNodeById(4u); + AtkComponentCheckBox* ptr2 = (AtkComponentCheckBox*)2267615832848uL; + if ((uint)list[1] == 1) + { + PluginLog.Debug("FUCKING CASUAL :D", Array.Empty()); + } + else if ((uint)list[1] == 2) + { + PluginLog.Debug("FUCKING HARDCORE RANKED :D", Array.Empty()); + } + } + } + } + } + return addonReceiveEventHook.Original(atkunitbase, valuecount, atkvalues, a4); + } + + private void ClientState_EnterPvP() + { + PluginLog.Debug("Yes, we entered pvp :)", Array.Empty()); + } + + private unsafe void InstallAddonReceiveEventHook() + { + string text = "E8 ?? ?? ?? ?? 8B 4C 24 20 0F B6 D8"; + nint num = DalamudApi.SigScanner.ScanText(text); + addonReceiveEventHook = DalamudApi.Hooks.HookFromAddress((IntPtr)num, (FireCallbackDelegate)CallbackDetour, (HookBackend)0); + } + + private unsafe AtkUnitBase* GetDutyFinderPointer() + { + nint addonByName = DalamudApi.GameGui.GetAddonByName("ContentsFinder", 1); + if (addonByName != IntPtr.Zero) + { + AtkUnitBase* ptr = (AtkUnitBase*)addonByName; + if (((AtkUnitBase)ptr).RootNode != null) + { + return ptr; + } + return null; + } + return null; + } + + private void Framework_Update(IFramework framework) + { + if (Configuration.Enabled && DalamudApi.ClientState.IsLoggedIn) + { + CheckForDfSelections(); + } + } + + private unsafe void CheckForDfSelections() + { + nint addonByName = DalamudApi.GameGui.GetAddonByName("ContentsFinderConfirm", 1); + AtkUnitBase* ptr = (AtkUnitBase*)addonByName; + if (ptr != null && ((AtkUnitBase)ptr).IsVisible) + { + AtkTextNode* nodeById = (AtkTextNode*)((AtkUnitBase)ptr).GetNodeById(49u); + if (nodeById != null && ((Utf8String)(&((AtkTextNode)nodeById).NodeText)).StringPtr != null) + { + string text = Marshal.PtrToStringUTF8(new IntPtr(((Utf8String)(&((AtkTextNode)nodeById).NodeText)).StringPtr)); + if (text != null) + { + if (text.Contains("Crystalline Conflict (Casual Match)")) + { + if (!casualCCEnabled) + { + casualCCEnabled = true; + rankedCCEnabled = false; + PluginLog.Debug("CASUAL CC MATCH INCOMING, SETTING TRUE", Array.Empty()); + } + } + else if (text.Contains("Crystalline Conflict (Ranked Match)") && !rankedCCEnabled) + { + rankedCCEnabled = true; + casualCCEnabled = false; + PluginLog.Debug("RANKED CC MATCH INCOMING, SETTING TRUE", Array.Empty()); + } + } + } + } + nint addonByName2 = DalamudApi.GameGui.GetAddonByName("ContentsFinder", 1); + if (addonByName2 != IntPtr.Zero) + { + AtkUnitBase* ptr2 = (dutyFinderAtkUnitBase = (AtkUnitBase*)addonByName2); + if (((AtkUnitBase)ptr2).RootNode != null && ((AtkUnitBase)ptr2).IsVisible) + { + dutyFinderVisible = true; + } + } + } + + public void Dispose() + { + //IL_0027: Unknown result type (might be due to invalid IL or missing references) + //IL_0031: Expected O, but got Unknown + //IL_0069: Unknown result type (might be due to invalid IL or missing references) + //IL_0073: Expected O, but got Unknown + PluginUi.Dispose(); + DalamudApi.CommandManager.RemoveHandler("/ccwins"); + DalamudApi.Framework.Update -= new OnUpdateDelegate(Framework_Update); + DalamudApi.ClientState.LeavePvP -= ClientState_LeavePvP; + DalamudApi.ClientState.EnterPvP -= ClientState_EnterPvP; + DalamudApi.ChatGui.ChatMessage -= new OnMessageDelegate(Chat_ChatMessage); + } + + private void OnCommand(string command, string args) + { + PluginUi.Visible = true; + } + + private void DrawUI() + { + PluginUi.Draw(); + } + + private void DrawConfigUI() + { + PluginUi.SettingsVisible = true; + } +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PluginUI.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PluginUI.cs new file mode 100644 index 0000000..3502174 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PluginUI.cs @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Numerics; +using Dalamud.Game.ClientState.Objects.Types; +using ImGuiNET; +using Lumina.Text; +using Newtonsoft.Json; + +namespace CrystallineConflictWinsTracker; + +internal class PluginUI : IDisposable +{ + private Configuration configuration; + + private bool settingsVisible; + + private bool visible; + + public List pvpSeasons = new List(); + + private List? currentData; + + private string currentlySelectedClassName; + + private List currentClassGames; + + private bool pickedClass; + + private PvpSeason currentlySelectedSeason; + + private PvpSeason previouslySelectedSeason; + + private string previouslySelectedClassName; + + public string DataPath { get; } + + public bool SettingsVisible + { + get + { + return settingsVisible; + } + set + { + settingsVisible = value; + } + } + + public bool Visible + { + get + { + return visible; + } + set + { + visible = value; + } + } + + public PluginUI(Configuration configuration, string DataPath) + { + this.configuration = configuration; + this.DataPath = DataPath; + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(1970, 1, 1), + endDate = new DateTime(2095, 1, 1), + season = 0, + seasonLabel = "All" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2022, 4, 12), + endDate = new DateTime(2022, 7, 6), + season = 1, + seasonLabel = "Season 1" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2022, 7, 6), + endDate = new DateTime(2022, 8, 22), + season = 2, + seasonLabel = "Season 2" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2022, 8, 23), + endDate = new DateTime(2022, 10, 31), + season = 3, + seasonLabel = "Season 3" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2022, 10, 31), + endDate = new DateTime(2023, 1, 10), + season = 4, + seasonLabel = "Season 4" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2023, 1, 10), + endDate = new DateTime(2023, 4, 4), + season = 5, + seasonLabel = "Season 5" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2023, 4, 4), + endDate = new DateTime(2024, 10, 3), + season = 6, + seasonLabel = "Season 6" + }); + pvpSeasons.Add(new PvpSeason + { + startDate = new DateTime(2023, 10, 3), + season = 7, + seasonLabel = "Season 7" + }); + currentlySelectedSeason = pvpSeasons[7]; + } + + public void DrawMainWindow() + { + if (!Visible) + { + pickedClass = false; + return; + } + List list = (currentData = JsonConvert.DeserializeObject>(File.ReadAllText(DataPath + "pvpstats.json")) ?? new List()); + List list2 = list.FindAll((PvpWinEntry c) => !c.matchDate.HasValue); + List list3 = list.FindAll((PvpWinEntry c) => c.matchDate >= new DateTime(2022, 7, 6) && c.matchDate <= new DateTime(2022, 8, 22)); + List list4 = list.FindAll((PvpWinEntry c) => c.matchDate >= new DateTime(2022, 8, 22) && c.matchDate <= new DateTime(2022, 10, 31)); + List list5 = list.FindAll((PvpWinEntry c) => c.matchDate >= new DateTime(2022, 11, 1) && c.matchDate <= new DateTime(2023, 1, 10)); + List list6 = list.FindAll((PvpWinEntry c) => c.matchDate >= new DateTime(2023, 1, 10) && c.matchDate <= new DateTime(2023, 4, 4)); + List list7 = list.FindAll((PvpWinEntry c) => c.matchDate >= new DateTime(2023, 4, 4) && c.matchDate <= new DateTime(2023, 10, 3)); + List list8 = list.FindAll((PvpWinEntry c) => c.matchDate >= new DateTime(2023, 10, 3)); + if (currentlySelectedSeason != null && currentlySelectedSeason.season != 0) + { + List list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + switch (currentlySelectedSeason.season) + { + case 1: + currentData = list2; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + case 2: + currentData = list3; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + case 3: + currentData = list4; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + case 4: + currentData = list5; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + case 5: + currentData = list6; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + case 6: + currentData = list7; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + case 7: + currentData = list8; + list9 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list9; + break; + } + } + List list10 = new List(); + foreach (PvpWinEntry currentDatum in currentData) + { + if (!list10.Contains(currentDatum.className)) + { + list10.Add(currentDatum.className); + } + } + if (!pickedClass && DalamudApi.ClientState.IsLoggedIn && (GameObject)(object)DalamudApi.ClientState.LocalPlayer != (GameObject)null && ((Character)DalamudApi.ClientState.LocalPlayer).ClassJob.GameData != null) + { + currentlySelectedClassName = SeString.op_Implicit(((Character)DalamudApi.ClientState.LocalPlayer).ClassJob.GameData.Name); + List list11 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list11; + } + ImGui.SetNextWindowSize(new Vector2(700f, 330f), (ImGuiCond)4); + ImGui.SetNextWindowSizeConstraints(new Vector2(700f, 330f), new Vector2(float.MaxValue, float.MaxValue)); + if (ImGui.Begin("Crystalline Conflict stats", ref visible, (ImGuiWindowFlags)24) && (GameObject)(object)DalamudApi.ClientState.LocalPlayer != (GameObject)null && ((Character)DalamudApi.ClientState.LocalPlayer).ClassJob.GameData != null) + { + if (ImGui.BeginCombo("###seasonSelection", (currentlySelectedSeason == null) ? "All" : currentlySelectedSeason.seasonLabel)) + { + foreach (PvpSeason pvpSeason in pvpSeasons) + { + if (ImGui.Selectable(pvpSeason.seasonLabel)) + { + currentlySelectedSeason = pvpSeason; + } + } + ImGui.EndCombo(); + } + if (ImGui.BeginCombo("###jobSelection", (currentlySelectedClassName == null) ? SeString.op_Implicit(((Character)DalamudApi.ClientState.LocalPlayer).ClassJob.GameData.Name) : currentlySelectedClassName)) + { + foreach (string item in list10) + { + if (ImGui.Selectable(item)) + { + currentlySelectedClassName = item; + List list12 = currentData.FindAll((PvpWinEntry b) => b.className == currentlySelectedClassName); + currentClassGames = list12; + pickedClass = true; + } + } + ImGui.EndCombo(); + } + } + ImGui.Separator(); + if (currentClassGames != null) + { + List list13 = currentClassGames.FindAll((PvpWinEntry b) => !b.win); + List list14 = currentClassGames.FindAll((PvpWinEntry b) => b.win); + int count = list14.FindAll((PvpWinEntry b) => b.ranked).Count; + int count2 = list14.FindAll((PvpWinEntry b) => !b.ranked).Count; + int count3 = list13.FindAll((PvpWinEntry b) => b.ranked).Count; + int count4 = list13.FindAll((PvpWinEntry b) => !b.ranked).Count; + decimal num = default(decimal); + if (count3 > 0 || count > 0) + { + num = Math.Round(decimal.Divide(count, count + count3) * 100m, 2); + } + decimal num2 = default(decimal); + if (count2 > 0 || count4 > 0) + { + num2 = Math.Round(decimal.Divide(count2, count2 + count4) * 100m, 2); + } + ImGui.Text(currentlySelectedClassName + " stats"); + ImGui.TextColored(new Vector4(0f, 1f, 1f, 1f), "Ranked"); + ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Losses: " + count3); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "Wins: " + count); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "(WR: " + num + " %%)"); + ImGui.TextColored(new Vector4(0f, 1f, 1f, 1f), "Casual"); + ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Losses: " + count4); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "Wins: " + count2); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "(WR: " + num2 + " %%)"); + ImGui.Separator(); + List list15 = currentData.FindAll((PvpWinEntry w) => w.win && w.ranked); + List list16 = currentData.FindAll((PvpWinEntry w) => !w.win && w.ranked); + decimal num3 = default(decimal); + if (list15.Count > 0 && list16.Count > 0) + { + num3 = Math.Round(decimal.Divide(list15.Count, list15.Count + list16.Count) * 100m, 2); + } + ImGui.Text("Total stats"); + ImGui.TextColored(new Vector4(0f, 1f, 1f, 1f), "Ranked"); + ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Losses: " + list16.Count); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "Wins: " + list15.Count); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "(WR: " + num3 + " %%)"); + List list17 = currentData.FindAll((PvpWinEntry w) => w.win && !w.ranked); + List list18 = currentData.FindAll((PvpWinEntry w) => !w.win && !w.ranked); + decimal num4 = default(decimal); + if (list17.Count > 0 && list18.Count > 0) + { + num4 = Math.Round(decimal.Divide(list17.Count, list17.Count + list18.Count) * 100m, 2); + } + ImGui.TextColored(new Vector4(0f, 1f, 1f, 1f), "Casual"); + ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Losses: " + list18.Count); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "Wins: " + list17.Count); + ImGui.SameLine(); + ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "(WR: " + num4 + " %%)"); + } + ImGui.End(); + } + + public void Dispose() + { + } + + public void Draw() + { + DrawMainWindow(); + DrawSettingsWindow(); + } + + public void DrawSettingsWindow() + { + if (!SettingsVisible) + { + return; + } + ImGui.SetNextWindowSize(new Vector2(450f, 100f), (ImGuiCond)1); + if (ImGui.Begin("World Map Enhancer Settings", ref settingsVisible, (ImGuiWindowFlags)58)) + { + bool enabled = configuration.Enabled; + if (ImGui.Checkbox("Enable zooming out with right click", ref enabled)) + { + configuration.Enabled = enabled; + configuration.Save(); + } + int rightClickDelay = configuration.RightClickDelay; + if (ImGui.InputInt("Right click release delay", ref rightClickDelay, 25, 100)) + { + configuration.RightClickDelay = rightClickDelay; + configuration.Save(); + } + } + ImGui.End(); + } +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PvpSeason.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PvpSeason.cs new file mode 100644 index 0000000..3e585ca --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PvpSeason.cs @@ -0,0 +1,14 @@ +using System; + +namespace CrystallineConflictWinsTracker; + +public class PvpSeason +{ + public DateTime startDate { get; set; } + + public DateTime? endDate { get; set; } + + public int season { get; set; } + + public string seasonLabel { get; set; } +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PvpWinEntry.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PvpWinEntry.cs new file mode 100644 index 0000000..038ff06 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/PvpWinEntry.cs @@ -0,0 +1,16 @@ +using System; + +namespace CrystallineConflictWinsTracker; + +public class PvpWinEntry +{ + public bool ranked { get; set; } + + public bool win { get; set; } + + public uint classId { get; set; } + + public string className { get; set; } + + public DateTime? matchDate { get; set; } +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Service.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Service.cs new file mode 100644 index 0000000..4243e30 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker/Service.cs @@ -0,0 +1,5 @@ +namespace CrystallineConflictWinsTracker; + +public class Service +{ +} diff --git a/.recovery/decompiled/CrystallineConflictWinsTracker/Properties/AssemblyInfo.cs b/.recovery/decompiled/CrystallineConflictWinsTracker/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e711d37 --- /dev/null +++ b/.recovery/decompiled/CrystallineConflictWinsTracker/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyCompany("aRkker")] +[assembly: AssemblyConfiguration("Release")] +[assembly: AssemblyDescription("Yes, we track winners only here")] +[assembly: AssemblyFileVersion("0.0.2.9")] +[assembly: AssemblyInformationalVersion("0.0.1.4")] +[assembly: AssemblyProduct("CrystallineConflictWinsTracker")] +[assembly: AssemblyTitle("CrystallineConflictWinsTracker")] +[assembly: AssemblyVersion("0.0.2.9")] diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer.csproj b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer.csproj new file mode 100644 index 0000000..4a0f0e3 --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer.csproj @@ -0,0 +1,19 @@ + + + MultiboxMutexer + False + net7.0 + x64 + + + 14.0 + True + False + + + + + + + + \ No newline at end of file diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer.dll.Resourcer/ResourceHelper.cs b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer.dll.Resourcer/ResourceHelper.cs new file mode 100644 index 0000000..addacf6 --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer.dll.Resourcer/ResourceHelper.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace MultiboxMutexer.dll.Resourcer; + +[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] +internal static class ResourceHelper +{ + private static Assembly assembly; + + static ResourceHelper() + { + assembly = typeof(ResourceHelper).GetTypeInfo().Assembly; + } + + public static Stream AsStream(string P_0) + { + return assembly.GetManifestResourceStream(P_0); + } + + public static StreamReader AsStreamReader(string P_0) + { + Stream manifestResourceStream = assembly.GetManifestResourceStream(P_0); + if (manifestResourceStream == null) + { + return null; + } + return new StreamReader(manifestResourceStream); + } + + public static string AsString(string P_0) + { + StreamReader streamReader = null; + Stream stream = null; + try + { + stream = assembly.GetManifestResourceStream(P_0); + if (stream == null) + { + throw new Exception("Could not find a resource named '" + P_0 + "'."); + } + streamReader = new StreamReader(stream); + return streamReader.ReadToEnd(); + } + finally + { + streamReader?.Dispose(); + stream?.Dispose(); + } + } +} diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/HandleManager.cs b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/HandleManager.cs new file mode 100644 index 0000000..9a8b17d --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/HandleManager.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; + +namespace MultiboxMutexer; + +public static class HandleManager +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private struct SYSTEM_HANDLE_INFORMATION + { + public uint OwnerPID; + + public byte ObjectType; + + public byte HandleFlags; + + public ushort HandleValue; + + public nuint ObjectPointer; + + public nint AccessMask; + } + + private struct OBJECT_BASIC_INFORMATION + { + public uint Attributes; + + public uint GrantedAccess; + + public uint HandleCount; + + public uint PointerCount; + + public uint PagedPoolUsage; + + public uint NonPagedPoolUsage; + + public uint Reserved1; + + public uint Reserved2; + + public uint Reserved3; + + public uint NameInformationLength; + + public uint TypeInformationLength; + + public uint SecurityDescriptorLength; + + public FILETIME CreateTime; + } + + private struct IO_STATUS_BLOCK + { + public uint Status; + + public ulong Information; + } + + [Flags] + private enum DuplicateOptions : uint + { + DUPLICATE_CLOSE_SOURCE = 1u, + DUPLICATE_SAME_ACCESS = 2u + } + + [Flags] + private enum ProcessAccessFlags : uint + { + All = 0x1F0FFFu, + Terminate = 1u, + CreateThread = 2u, + VMOperation = 8u, + VMRead = 0x10u, + VMWrite = 0x20u, + DupHandle = 0x40u, + SetInformation = 0x200u, + QueryInformation = 0x400u, + Synchronize = 0x100000u + } + + [Flags] + private enum NTSTATUS : uint + { + STATUS_SUCCESS = 0u, + STATUS_INFO_LENGTH_MISMATCH = 0xC0000004u + } + + [Flags] + private enum OBJECT_INFORMATION_CLASS : uint + { + ObjectBasicInformation = 0u, + ObjectNameInformation = 1u, + ObjectTypeInformation = 2u, + ObjectAllTypesInformation = 3u, + ObjectHandleInformation = 4u + } + + [Flags] + private enum SYSTEM_INFORMATION_CLASS : uint + { + SystemHandleInformation = 0x10u + } + + [Flags] + private enum FILE_INFORMATION_CLASS + { + FileNameInformation = 9 + } + + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool CloseHandle(nint hObject); + + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool DuplicateHandle(nint hSourceProcessHandle, nint hSourceHandle, nint hTargetProcessHandle, out nint lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, DuplicateOptions dwOptions); + + [DllImport("kernel32.dll")] + private static extern nint OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessID); + + [DllImport("ntdll.dll", SetLastError = true)] + private static extern NTSTATUS NtQueryInformationFile(nint FileHandle, ref IO_STATUS_BLOCK IoStatusBlock, nint FileInformation, int FileInformationLength, FILE_INFORMATION_CLASS FileInformationClass); + + [DllImport("ntdll.dll")] + private static extern NTSTATUS NtQueryObject(nint ObjectHandle, OBJECT_INFORMATION_CLASS ObjectInformationClass, nint ObjectInformation, int ObjectInformationLength, out int ReturnLength); + + [DllImport("ntdll.dll")] + private static extern NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, nint SystemInformation, int SystemInformationLength, out int ReturnLength); + + public static bool ClearMutex() + { + bool result = false; + Process[] processes = Process.GetProcesses(); + foreach (Process process in processes) + { + if (process.ProcessName.Equals("ffxiv_dx11", StringComparison.OrdinalIgnoreCase) && KillHandle(process, "6AA83AB5-BAC4-4a36-9F66-A309770760CB_ffxiv_game00", isFile: false)) + { + result = true; + } + } + return result; + } + + public static bool KillHandle(Process targetProcess, string handleName, bool isFile) + { + bool result = false; + nint allHandles = GetAllHandles(); + if (allHandles == IntPtr.Zero) + { + return result; + } + List handles = GetHandles(targetProcess, allHandles); + Marshal.FreeHGlobal(allHandles); + nint num = OpenProcess(ProcessAccessFlags.DupHandle, bInheritHandle: false, (uint)targetProcess.Id); + foreach (SYSTEM_HANDLE_INFORMATION item in handles) + { + string text = ((!isFile) ? GetHandleName(item, num) : GetFileName(item, num)); + if (text.Contains(handleName) && CloseHandleEx(item.OwnerPID, new IntPtr(item.HandleValue))) + { + result = true; + } + } + CloseHandle(num); + return result; + } + + private static bool CloseHandleEx(uint processID, nint handleToClose) + { + nint num = OpenProcess(ProcessAccessFlags.All, bInheritHandle: false, processID); + nint lpTargetHandle; + bool result = DuplicateHandle(num, handleToClose, IntPtr.Zero, out lpTargetHandle, 0u, bInheritHandle: false, DuplicateOptions.DUPLICATE_CLOSE_SOURCE); + CloseHandle(num); + return result; + } + + private static string ConvertToString(nint pStringBuffer) + { + long num = ((IntPtr)pStringBuffer).ToInt64(); + int num2 = IntPtr.Size * 2; + return Marshal.PtrToStringAnsi(new IntPtr(num + num2)); + } + + private static nint GetAllHandles() + { + int num = 65536; + nint num2 = Marshal.AllocHGlobal(num); + int ReturnLength; + NTSTATUS nTSTATUS = NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, num2, num, out ReturnLength); + while (true) + { + switch (nTSTATUS) + { + case NTSTATUS.STATUS_INFO_LENGTH_MISMATCH: + break; + case NTSTATUS.STATUS_SUCCESS: + return num2; + default: + Marshal.FreeHGlobal(num2); + return IntPtr.Zero; + } + Marshal.FreeHGlobal(num2); + num *= 2; + num2 = Marshal.AllocHGlobal(num); + nTSTATUS = NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, num2, num, out ReturnLength); + } + } + + private static List GetHandles(Process targetProcess, nint pSysHandles) + { + List list = new List(); + long num = ((IntPtr)pSysHandles).ToInt64(); + int num2 = Marshal.ReadInt32(pSysHandles); + for (int i = 0; i < num2; i++) + { + long num3 = IntPtr.Size + i * Marshal.SizeOf(typeof(SYSTEM_HANDLE_INFORMATION)); + SYSTEM_HANDLE_INFORMATION item = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(new IntPtr(num + num3), typeof(SYSTEM_HANDLE_INFORMATION)); + if (item.OwnerPID == (uint)targetProcess.Id) + { + list.Add(item); + } + } + return list; + } + + private static string GetFileName(SYSTEM_HANDLE_INFORMATION handleInfo, nint hProcess) + { + try + { + nint handle = Process.GetCurrentProcess().Handle; + DuplicateHandle(hProcess, new IntPtr(handleInfo.HandleValue), handle, out var lpTargetHandle, 0u, bInheritHandle: false, DuplicateOptions.DUPLICATE_SAME_ACCESS); + int num = 512; + nint num2 = Marshal.AllocHGlobal(num); + IO_STATUS_BLOCK IoStatusBlock = default(IO_STATUS_BLOCK); + NtQueryInformationFile(lpTargetHandle, ref IoStatusBlock, num2, num, FILE_INFORMATION_CLASS.FileNameInformation); + CloseHandle(lpTargetHandle); + int num3 = 4; + string? result = Marshal.PtrToStringUni(new IntPtr(((IntPtr)num2).ToInt64() + num3)); + Marshal.FreeHGlobal(num2); + return result; + } + catch (Exception) + { + return string.Empty; + } + } + + private static string GetHandleName(SYSTEM_HANDLE_INFORMATION targetHandleInfo, nint hProcess) + { + if (((IntPtr)targetHandleInfo.AccessMask).ToInt64() == 1180063) + { + return string.Empty; + } + nint handle = Process.GetCurrentProcess().Handle; + DuplicateHandle(hProcess, new IntPtr(targetHandleInfo.HandleValue), handle, out var lpTargetHandle, 0u, bInheritHandle: false, DuplicateOptions.DUPLICATE_SAME_ACCESS); + int ReturnLength = GetHandleNameLength(lpTargetHandle); + nint num = Marshal.AllocHGlobal(ReturnLength); + NtQueryObject(lpTargetHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, num, ReturnLength, out ReturnLength); + nint zero = IntPtr.Zero; + zero = Marshal.AllocHGlobal(ReturnLength); + string result = ""; + if (NtQueryObject(lpTargetHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, zero, ReturnLength, out ReturnLength) == NTSTATUS.STATUS_SUCCESS) + { + result = Marshal.PtrToStringUni((nint)((long)zero + (long)(2 * IntPtr.Size))); + Marshal.FreeHGlobal(zero); + } + CloseHandle(lpTargetHandle); + ConvertToString(num); + Marshal.FreeHGlobal(num); + return result; + } + + private static int GetHandleNameLength(nint handle) + { + int ReturnLength = Marshal.SizeOf(typeof(OBJECT_BASIC_INFORMATION)); + nint num = Marshal.AllocHGlobal(ReturnLength); + NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectBasicInformation, num, ReturnLength, out ReturnLength); + OBJECT_BASIC_INFORMATION oBJECT_BASIC_INFORMATION = (OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(num, typeof(OBJECT_BASIC_INFORMATION)); + Marshal.FreeHGlobal(num); + if (oBJECT_BASIC_INFORMATION.NameInformationLength == 0) + { + return 256; + } + return (int)oBJECT_BASIC_INFORMATION.NameInformationLength; + } +} diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Plugin.cs b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Plugin.cs new file mode 100644 index 0000000..214c714 --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Plugin.cs @@ -0,0 +1,107 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using Dalamud.Game.Command; +using Dalamud.Game.Gui; +using Dalamud.IoC; +using Dalamud.Logging; +using Dalamud.Plugin; + +namespace MultiboxMutexer; + +public sealed class Plugin : IDalamudPlugin, IDisposable +{ + [Flags] + private enum ProcessAccessFlags : uint + { + All = 0x1F0FFFu, + Terminate = 1u, + CreateThread = 2u, + VMOperation = 8u, + VMRead = 0x10u, + VMWrite = 0x20u, + DupHandle = 0x40u, + SetInformation = 0x200u, + QueryInformation = 0x400u, + Synchronize = 0x100000u + } + + [Flags] + private enum DuplicateOptions : uint + { + DUPLICATE_CLOSE_SOURCE = 1u, + DUPLICATE_SAME_ACCESS = 2u + } + + private const uint PROCESS_DUP_HANDLE = 64u; + + public string Name => "Multibox Mutexer"; + + public DalamudPluginInterface PluginInterface { get; } + + public CommandManager CommandManager { get; } + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool CloseHandle(nint hObject); + + [DllImport("kernel32.dll")] + private static extern nint OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, nint dwProcessId); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool DuplicateHandle(nint hSourceProcessHandle, nint hSourceHandle, nint hTargetProcessHandle, out nint lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, DuplicateOptions dwOptions); + + public static bool CloseHandleEx(nint pid, nint handle) + { + nint num = OpenProcess(ProcessAccessFlags.DupHandle, bInheritHandle: false, pid); + nint lpTargetHandle = IntPtr.Zero; + bool result = DuplicateHandle(num, handle, IntPtr.Zero, out lpTargetHandle, 0u, bInheritHandle: false, DuplicateOptions.DUPLICATE_CLOSE_SOURCE); + CloseHandle(num); + return result; + } + + public Plugin([RequiredVersion("1.0")] DalamudPluginInterface pluginInterface, [RequiredVersion("1.0")] CommandManager commandManager, [RequiredVersion("1.0")] GameGui gameGui) + { + //IL_0026: Unknown result type (might be due to invalid IL or missing references) + //IL_0030: Expected O, but got Unknown + //IL_002b: 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_0040: Expected O, but got Unknown + PluginInterface = pluginInterface; + CommandManager = commandManager; + CommandManager.AddHandler("/mutex", new CommandInfo(new HandlerDelegate(OnCommand)) + { + HelpMessage = "Fix mutex" + }); + PluginLog.Debug("LOADED?", Array.Empty()); + Process currentProcess = Process.GetCurrentProcess(); + PluginLog.Debug("CURRENT PROCESS PID: " + currentProcess.Id, Array.Empty()); + ReleaseAllMutexes(currentProcess); + } + + public void ReleaseAllMutexes(Process proc) + { + PluginLog.Debug("MUTEXER CALLED", Array.Empty()); + if (HandleManager.ClearMutex()) + { + PluginLog.Debug("Succesfully killed the mutex", Array.Empty()); + } + else + { + PluginLog.Warning("Failed to kill mutex!", Array.Empty()); + } + } + + private void OnCommand(string command, string args) + { + PluginLog.Debug("RUNNING MUTEXER", Array.Empty()); + Process currentProcess = Process.GetCurrentProcess(); + ReleaseAllMutexes(currentProcess); + } + + public void Dispose() + { + CommandManager.RemoveHandler("/mutex"); + } +} diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Service.cs b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Service.cs new file mode 100644 index 0000000..3a0762d --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Service.cs @@ -0,0 +1,28 @@ +using Dalamud.Data; +using Dalamud.Game; +using Dalamud.Game.ClientState; +using Dalamud.Game.Gui; +using Dalamud.IoC; + +namespace MultiboxMutexer; + +public class Service +{ + [PluginService] + public static ClientState ClientState { get; private set; } + + [PluginService] + public static Framework Framework { get; private set; } + + [PluginService] + public static GameGui GameGui { get; private set; } + + [PluginService] + public static SigScanner SigScanner { get; private set; } + + [PluginService] + public static ChatGui Chat { get; private set; } + + [PluginService] + public static DataManager DataManager { get; private set; } +} diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Util.cs b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Util.cs new file mode 100644 index 0000000..b6dfe5a --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer/Util.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using Dalamud.Game; +using Dalamud.Interface; +using ImGuiNET; + +namespace MultiboxMutexer; + +internal static class Util +{ + internal static bool TryScanText(this SigScanner scanner, string sig, out nint result) + { + result = IntPtr.Zero; + try + { + result = scanner.ScanText(sig); + return true; + } + catch (KeyNotFoundException) + { + return false; + } + } + + private unsafe static byte[] ReadTerminatedBytes(byte* ptr) + { + if (ptr == null) + { + return new byte[0]; + } + List list = new List(); + while (*ptr != 0) + { + list.Add(*ptr); + ptr++; + } + return list.ToArray(); + } + + internal unsafe static string ReadTerminatedString(byte* ptr) + { + return Encoding.UTF8.GetString(ReadTerminatedBytes(ptr)); + } + + internal static bool ContainsIgnoreCase(this string haystack, string needle) + { + return CultureInfo.InvariantCulture.CompareInfo.IndexOf(haystack, needle, CompareOptions.IgnoreCase) >= 0; + } + + internal static bool IconButton(FontAwesomeIcon icon, string id) + { + //IL_0000: 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) + ImGui.PushFont(UiBuilder.IconFont); + bool result = ImGui.Button(FontAwesomeExtensions.ToIconString(icon) + "##" + id); + ImGui.PopFont(); + return result; + } +} diff --git a/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer_ProcessedByFody.cs b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer_ProcessedByFody.cs new file mode 100644 index 0000000..363d79a --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/MultiboxMutexer_ProcessedByFody.cs @@ -0,0 +1,6 @@ +internal class MultiboxMutexer_ProcessedByFody +{ + internal const string FodyVersion = "6.6.4.0"; + + internal const string Resourcer = "1.8.0.0"; +} diff --git a/.recovery/decompiled/MultiboxMutexer/Properties/AssemblyInfo.cs b/.recovery/decompiled/MultiboxMutexer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..17593ac --- /dev/null +++ b/.recovery/decompiled/MultiboxMutexer/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyCompany("aRkker")] +[assembly: AssemblyConfiguration("Release")] +[assembly: AssemblyDescription("Why are we still here? Just to suffer?")] +[assembly: AssemblyFileVersion("1.0.1.2")] +[assembly: AssemblyInformationalVersion("1.0.0")] +[assembly: AssemblyProduct("MultiboxMutexer")] +[assembly: AssemblyTitle("MultiboxMutexer")] +[assembly: AssemblyVersion("1.0.1.2")] diff --git a/.recovery/decompiled/OmicronMountMusicFixer/BGMController.cs b/.recovery/decompiled/OmicronMountMusicFixer/BGMController.cs new file mode 100644 index 0000000..f94a6c6 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/BGMController.cs @@ -0,0 +1,203 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Dalamud.Hooking; +using Dalamud.Plugin.Services; +using OmicronMountMusicFixer; + +public class BGMController +{ + public delegate void SongChangedHandler(int oldSong, int currentSong, int oldSecondSong, int secondSong); + + private unsafe delegate DisableRestart* AddDisableRestartIdPrototype(BGMScene* scene, ushort songId); + + private unsafe delegate int GetSpecialModeByScenePrototype(BGMPlayer* bgmPlayer); + + private const SceneFlags SceneZeroFlags = SceneFlags.Resume; + + private const int SceneCount = 12; + + private const int PlayersCount = 2; + + public SongChangedHandler OnSongChanged; + + private readonly AddDisableRestartIdPrototype _addDisableRestartId; + + private readonly Hook _getSpecialModeForSceneHook; + + public int OldSongId { get; private set; } + + public int OldScene { get; private set; } + + public int CurrentSongId { get; private set; } + + public int CurrentScene { get; private set; } + + public int SecondSongId { get; private set; } + + public int SecondScene { get; private set; } + + public int OldSecondSongId { get; private set; } + + public int OldSecondScene { get; private set; } + + public int PlayingSongId { get; private set; } + + public int PlayingScene { get; private set; } + + public int CurrentAudibleSong + { + get + { + if (PlayingSongId != 0) + { + return PlayingSongId; + } + return CurrentSongId; + } + } + + public unsafe BGMController() + { + _addDisableRestartId = Marshal.GetDelegateForFunctionPointer(BGMAddressResolver.AddRestartId); + _getSpecialModeForSceneHook = DalamudApi.Hooks.HookFromAddress((IntPtr)BGMAddressResolver.GetSpecialMode, (GetSpecialModeByScenePrototype)GetSpecialModeBySceneDetour, (HookBackend)0); + _getSpecialModeForSceneHook.Enable(); + } + + public void Dispose() + { + _getSpecialModeForSceneHook?.Disable(); + _getSpecialModeForSceneHook?.Dispose(); + } + + public void SetSpecialModeHandling(bool value) + { + if (value) + { + _getSpecialModeForSceneHook.Enable(); + } + else + { + _getSpecialModeForSceneHook.Disable(); + } + } + + public unsafe void Update() + { + ushort num = 0; + ushort num2 = 0; + int currentScene = 0; + int secondScene = 0; + if (BGMAddressResolver.BGMSceneList != IntPtr.Zero) + { + BGMScene* ptr = (BGMScene*)((IntPtr)BGMAddressResolver.BGMSceneList).ToPointer(); + for (int i = 0; i < 12; i++) + { + if (PlayingSongId != 0 && i == PlayingScene) + { + if (ptr[PlayingScene].BgmId != PlayingSongId) + { + SetSong((ushort)PlayingSongId, PlayingScene); + } + } + else if (ptr[i].BgmReference != 0 && ptr[i].BgmId != 0 && ptr[i].BgmId != 9999) + { + if (num != 0) + { + num2 = ptr[i].BgmId; + secondScene = i; + break; + } + num = ptr[i].BgmId; + currentScene = i; + } + } + } + int oldSong = 0; + int currentSong = 0; + int oldSecondSong = 0; + int secondSong = 0; + bool flag = false; + bool flag2 = false; + if (CurrentSongId != num) + { + OldSongId = CurrentSongId; + OldScene = CurrentScene; + CurrentSongId = num; + CurrentScene = currentScene; + flag = true; + oldSong = OldSongId; + currentSong = CurrentSongId; + } + if (SecondSongId != num2) + { + OldSecondSongId = SecondSongId; + OldSecondScene = SecondScene; + SecondSongId = num2; + SecondScene = secondScene; + flag2 = true; + oldSecondSong = OldSecondSongId; + secondSong = SecondSongId; + } + if (flag || flag2) + { + OnSongChanged?.Invoke(oldSong, currentSong, oldSecondSong, secondSong); + } + } + + public unsafe void SetSong(ushort songId, int priority = 0) + { + if ((priority < 0 || priority >= 12) ? true : false) + { + throw new IndexOutOfRangeException(); + } + if ((songId != 0 && SongList.Instance.TryGetSong(songId, out var song) && !song.FileExists) || BGMAddressResolver.BGMSceneList == IntPtr.Zero) + { + return; + } + BGMScene* bgms = (BGMScene*)((IntPtr)BGMAddressResolver.BGMSceneList).ToPointer(); + bgms[priority].BgmReference = songId; + bgms[priority].BgmId = songId; + bgms[priority].PreviousBgmId = songId; + if (songId == 0 && priority == 0) + { + bgms[priority].Flags = SceneFlags.Resume; + } + bgms[priority].Timer = 0f; + bgms[priority].TimerEnable = 0; + PlayingSongId = songId; + PlayingScene = priority; + if (SongList.Instance.IsDisableRestart(songId)) + { + bgms[priority].Flags = SceneFlags.EnableDisableRestart; + _addDisableRestartId(bgms + priority, songId); + bgms[priority].Flags = SceneFlags.ForceAutoReset; + Task.Delay(500).ContinueWith(delegate + { + bgms[priority].Flags = SceneFlags.ForceAutoReset | SceneFlags.EnableDisableRestart; + }); + } + } + + private unsafe int GetSpecialModeBySceneDetour(BGMPlayer* player) + { + if (player->BgmScene != PlayingScene || player->BgmId != PlayingSongId) + { + return _getSpecialModeForSceneHook.Original(player); + } + if (!SongList.Instance.TryGetSong(player->BgmId, out var song)) + { + return _getSpecialModeForSceneHook.Original(player); + } + uint bgmScene = 10u; + if (song.SpecialMode == 2) + { + bgmScene = 6u; + } + uint bgmScene2 = player->BgmScene; + player->BgmScene = bgmScene; + int result = _getSpecialModeForSceneHook.Original(player); + player->BgmScene = bgmScene2; + return result; + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer.csproj b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer.csproj new file mode 100644 index 0000000..d486e85 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer.csproj @@ -0,0 +1,22 @@ + + + OmicronMountMusicFixer + False + net10.0 + x64 + + + 14.0 + True + False + + + + + + + + + + + \ No newline at end of file diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer.dll.Resourcer/ResourceHelper.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer.dll.Resourcer/ResourceHelper.cs new file mode 100644 index 0000000..b3e1cb9 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer.dll.Resourcer/ResourceHelper.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace OmicronMountMusicFixer.dll.Resourcer; + +[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] +internal static class ResourceHelper +{ + private static Assembly assembly; + + static ResourceHelper() + { + assembly = typeof(ResourceHelper).GetTypeInfo().Assembly; + } + + public static Stream AsStream(string P_0) + { + return assembly.GetManifestResourceStream(P_0); + } + + public static StreamReader AsStreamReader(string P_0) + { + Stream manifestResourceStream = assembly.GetManifestResourceStream(P_0); + if (manifestResourceStream == null) + { + return null; + } + return new StreamReader(manifestResourceStream); + } + + public static string AsString(string P_0) + { + StreamReader streamReader = null; + Stream stream = null; + try + { + stream = assembly.GetManifestResourceStream(P_0); + if (stream == null) + { + throw new Exception("Could not find a resource named '" + P_0 + "'."); + } + streamReader = new StreamReader(stream); + return streamReader.ReadToEnd(); + } + finally + { + streamReader?.Dispose(); + stream?.Dispose(); + } + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMAddressResolver.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMAddressResolver.cs new file mode 100644 index 0000000..48b4dc2 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMAddressResolver.cs @@ -0,0 +1,44 @@ +using System; +using System.Runtime.InteropServices; +using FFXIVClientStructs.FFXIV.Client.System.Framework; + +namespace OmicronMountMusicFixer; + +public static class BGMAddressResolver +{ + private static nint _baseAddress; + + private static nint _musicManager; + + public static nint AddRestartId { get; private set; } + + public static nint GetSpecialMode { get; private set; } + + public static nint BGMSceneManager => Marshal.ReadIntPtr(_baseAddress); + + public static nint BGMSceneList + { + get + { + nint num = Marshal.ReadIntPtr(_baseAddress); + if (num != IntPtr.Zero) + { + return Marshal.ReadIntPtr(num + 192); + } + return IntPtr.Zero; + } + } + + public static bool StreamingEnabled => Marshal.ReadByte(_musicManager + 50) == 1; + + public unsafe static void Init() + { + _baseAddress = DalamudApi.SigScanner.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 85 C0 74 51 83 78 08 0B", 0); + AddRestartId = DalamudApi.SigScanner.ScanText("E8 ?? ?? ?? ?? 88 9E ?? ?? ?? ?? 84 DB"); + GetSpecialMode = DalamudApi.SigScanner.ScanText("40 57 48 83 EC 20 48 83 79 ?? ?? 48 8B F9 0F 84 ?? ?? ?? ?? 0F B6 51 4D"); + DalamudApi.PluginLog.Debug($"[BGMAddressResolver] init: base address at {((IntPtr)_baseAddress).ToInt64():X}", Array.Empty()); + int num = Marshal.ReadInt32((nint)DalamudApi.SigScanner.ScanText("48 8B 8F ?? ?? ?? ?? 85 C0 0F 95 C2 E8 ?? ?? ?? ?? 48 8B 9F") + 3); + _musicManager = Marshal.ReadIntPtr(new IntPtr(Framework.Instance()) + num); + DalamudApi.PluginLog.Debug($"[BGMAddressResolver] MusicManager found at {((IntPtr)_musicManager).ToInt64():X}", Array.Empty()); + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMManager.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMManager.cs new file mode 100644 index 0000000..037a023 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMManager.cs @@ -0,0 +1,99 @@ +using System; +using System.Runtime.CompilerServices; +using Dalamud.Plugin.Services; + +namespace OmicronMountMusicFixer; + +internal static class BGMManager +{ + public delegate void SongChanged(int oldSong, int currentSong, int oldSecondSong, int oldCurrentSong, bool oldPlayedByOrch, bool playedByOrchestrion); + + [CompilerGenerated] + private static class _003C_003EO + { + public static OnUpdateDelegate _003C0_003E__Update; + } + + private static readonly BGMController _bgmController; + + private static bool _isPlayingReplacement; + + private static string _ddPlaylist; + + public static int CurrentSongId => _bgmController.CurrentSongId; + + public static int PlayingSongId => _bgmController.PlayingSongId; + + public static int CurrentAudibleSong => _bgmController.CurrentAudibleSong; + + public static int PlayingScene => _bgmController.PlayingScene; + + public static event SongChanged OnSongChanged; + + static BGMManager() + { + //IL_003c: Unknown result type (might be due to invalid IL or missing references) + //IL_0046: Expected O, but got Unknown + _bgmController = new BGMController(); + BGMController bgmController = _bgmController; + bgmController.OnSongChanged = (BGMController.SongChangedHandler)Delegate.Combine(bgmController.OnSongChanged, new BGMController.SongChangedHandler(HandleSongChanged)); + DalamudApi.Framework.Update += new OnUpdateDelegate(Update); + } + + public static void Dispose() + { + //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: Expected O, but got Unknown + IFramework framework = DalamudApi.Framework; + object obj = _003C_003EO._003C0_003E__Update; + if (obj == null) + { + OnUpdateDelegate val = Update; + _003C_003EO._003C0_003E__Update = val; + obj = (object)val; + } + framework.Update -= (OnUpdateDelegate)obj; + Stop(); + _bgmController.Dispose(); + } + + public static void Update(IFramework ignored) + { + _bgmController.Update(); + } + + private static void HandleSongChanged(int oldSong, int newSong, int oldSecondSong, int newSecondSong) + { + InvokeSongChanged(oldSong, newSong, oldSecondSong, newSecondSong, oldPlayedByOrch: false, playedByOrch: false); + } + + public static void Play(int songId, bool isReplacement = false) + { + bool oldPlayedByOrch = PlayingSongId != 0; + int currentAudibleSong = CurrentAudibleSong; + int secondSongId = _bgmController.SecondSongId; + DalamudApi.PluginLog.Debug($"[Play] Playing {songId}", Array.Empty()); + InvokeSongChanged(currentAudibleSong, songId, secondSongId, currentAudibleSong, oldPlayedByOrch, playedByOrch: true); + _bgmController.SetSong((ushort)songId); + _isPlayingReplacement = isReplacement; + } + + public static void Stop() + { + _ddPlaylist = null; + if (PlayingSongId != 0) + { + DalamudApi.PluginLog.Debug($"[Stop] Stopping playing {_bgmController.PlayingSongId}...", Array.Empty()); + int secondSongId = _bgmController.SecondSongId; + InvokeSongChanged(PlayingSongId, CurrentSongId, secondSongId, secondSongId, oldPlayedByOrch: true, playedByOrch: false); + _bgmController.SetSong(0); + } + } + + private static void InvokeSongChanged(int oldSongId, int newSongId, int oldSecondSongId, int newSecondSongId, bool oldPlayedByOrch, bool playedByOrch) + { + DalamudApi.PluginLog.Debug($"[InvokeSongChanged] Invoking SongChanged event with {oldSongId} -> {newSongId}, {oldSecondSongId} -> {newSecondSongId} | {oldPlayedByOrch} {playedByOrch}", Array.Empty()); + BGMManager.OnSongChanged?.Invoke(oldSongId, newSongId, oldSecondSongId, newSecondSongId, oldPlayedByOrch, playedByOrch); + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMPlayer.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMPlayer.cs new file mode 100644 index 0000000..485f0c4 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMPlayer.cs @@ -0,0 +1,46 @@ +using System.Runtime.InteropServices; + +namespace OmicronMountMusicFixer; + +[StructLayout(LayoutKind.Explicit)] +internal struct BGMPlayer +{ + [FieldOffset(0)] + public float MaxStandbyTime; + + [FieldOffset(4)] + public uint State; + + [FieldOffset(8)] + public ushort BgmId; + + [FieldOffset(16)] + public uint BgmScene; + + [FieldOffset(32)] + public uint SpecialMode; + + [FieldOffset(37)] + public bool IsStandby; + + [FieldOffset(40)] + public uint FadeOutTime; + + [FieldOffset(44)] + public uint ResumeFadeInTime; + + [FieldOffset(48)] + public uint FadeInStartTime; + + [FieldOffset(52)] + public uint FadeInTime; + + [FieldOffset(56)] + public uint ElapsedTime; + + [FieldOffset(64)] + public float StandbyTime; + + [FieldOffset(77)] + public byte SpecialModeType; +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMScene.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMScene.cs new file mode 100644 index 0000000..6d14043 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/BGMScene.cs @@ -0,0 +1,52 @@ +namespace OmicronMountMusicFixer; + +public struct BGMScene +{ + public int SceneIndex; + + public SceneFlags Flags; + + private int Padding1; + + public ushort BgmReference; + + public ushort BgmId; + + public ushort PreviousBgmId; + + public byte TimerEnable; + + private byte Padding2; + + public float Timer; + + private unsafe fixed byte DisableRestartList[24]; + + private byte Unknown1; + + private uint Unknown2; + + private uint Unknown3; + + private uint Unknown4; + + private uint Unknown5; + + private uint Unknown6; + + private ulong Unknown7; + + private uint Unknown8; + + private byte Unknown9; + + private byte Unknown10; + + private byte Unknown11; + + private byte Unknown12; + + private float Unknown13; + + private uint Unknown14; +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Configuration.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Configuration.cs new file mode 100644 index 0000000..ed6784a --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Configuration.cs @@ -0,0 +1,28 @@ +using System; +using Dalamud.Configuration; +using Dalamud.Plugin; + +namespace OmicronMountMusicFixer; + +[Serializable] +public class Configuration : IPluginConfiguration +{ + [NonSerialized] + private IDalamudPluginInterface? pluginInterface; + + public int Version { get; set; } + + public bool Enabled { get; set; } = true; + + public int RightClickDelay { get; set; } = 250; + + public void Initialize(IDalamudPluginInterface pluginInterface) + { + this.pluginInterface = pluginInterface; + } + + public void Save() + { + pluginInterface.SavePluginConfig((IPluginConfiguration)(object)this); + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/DalamudApi.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/DalamudApi.cs new file mode 100644 index 0000000..1dc06f7 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/DalamudApi.cs @@ -0,0 +1,53 @@ +using System; +using Dalamud.IoC; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; + +namespace OmicronMountMusicFixer; + +public class DalamudApi +{ + [PluginService] + public static IChatGui ChatGui { get; private set; } + + [PluginService] + public static IClientState ClientState { get; private set; } + + [PluginService] + public static ICommandManager CommandManager { get; private set; } + + [PluginService] + public static IDalamudPluginInterface PluginInterface { get; private set; } + + [PluginService] + public static IDataManager DataManager { get; private set; } + + [PluginService] + public static IDtrBar DtrBar { get; private set; } + + [PluginService] + public static IFramework Framework { get; private set; } + + [PluginService] + public static IGameGui GameGui { get; private set; } + + [PluginService] + public static IKeyState KeyState { get; private set; } + + [PluginService] + public static ISigScanner SigScanner { get; private set; } + + [PluginService] + public static IGameInteropProvider Hooks { get; private set; } + + [PluginService] + public static IPluginLog PluginLog { get; private set; } + + [PluginService] + public static IAddonLifecycle AddonLifecycle { get; private set; } + + public static void Initialize(IDalamudPluginInterface pluginInterface) + { + pluginInterface.Create(Array.Empty()); + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/DisableRestart.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/DisableRestart.cs new file mode 100644 index 0000000..574ad64 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/DisableRestart.cs @@ -0,0 +1,16 @@ +namespace OmicronMountMusicFixer; + +public struct DisableRestart +{ + public ushort DisableRestartId; + + public bool IsTimedOut; + + public byte Padding1; + + public float ResetWaitTime; + + public float ElapsedTime; + + public bool TimerEnabled; +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Plugin.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Plugin.cs new file mode 100644 index 0000000..cfba7f5 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Plugin.cs @@ -0,0 +1,319 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Net.Http; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Dalamud.Game.ClientState.Objects.SubKinds; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Game.NativeWrapper; +using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Hooking; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace OmicronMountMusicFixer; + +public class Plugin : IDalamudPlugin, IDisposable +{ + private static class Signatures + { + internal const string GetSpecialMode = "48 89 5C 24 ?? 57 48 83 EC 20 8B 41 10 33 DB"; + } + + private unsafe delegate int GetSpecialMode(void* unused, byte specialModeType); + + private unsafe delegate void* AgentShow(void* a1); + + private Hook getSpecialModeHook; + + private bool isPlayingReplacement; + + private const int ResourceDataPointerOffset = 176; + + private const int MusicManagerStreamingOffset = 50; + + private const string commandName = "/omm"; + + private HttpClient httpCl; + + public int currentSpecialMode; + + public bool currentCastHandled; + + public bool modEnabled; + + public long enabledTimestamp; + + private bool swapNextSong; + + private List songEchoPayload; + + private readonly Dictionary mountIDToSongIDMap = new Dictionary(); + + private bool wasMounted; + + private uint lastMountId; + + private Hook? GetResourceSyncHook { get; set; } + + public string Name => "Omicron mount fixer"; + + private IDalamudPluginInterface PluginInterface { get; init; } + + private ICommandManager CommandManager { get; init; } + + private Configuration Configuration { get; init; } + + private PluginUI PluginUi { get; init; } + + public long rcStartTime { get; private set; } + + private Hook DutyFinderHook { get; set; } + + public unsafe AtkUnitBase* dutyFinderAtkUnitBase { get; private set; } + + public string DataPath { get; } + + private nint NoSoundPtr { get; } + + private nint InfoPtr { get; } + + public bool WasStreamingEnabled { get; private set; } + + public bool Streaming { get; private set; } + + private ConcurrentDictionary Scds { get; } = new ConcurrentDictionary(); + + internal ConcurrentQueue Recent { get; } = new ConcurrentQueue(); + + public uint lastSpellBeingCast { get; private set; } + + public long lastSpellCast { get; private set; } + + public Plugin(IDalamudPluginInterface pluginInterface, ICommandManager commandManager) + { + //IL_00f3: Unknown result type (might be due to invalid IL or missing references) + //IL_00fd: Expected O, but got Unknown + //IL_0109: Unknown result type (might be due to invalid IL or missing references) + //IL_0113: Expected O, but got Unknown + DalamudApi.Initialize(pluginInterface); + PluginInterface = pluginInterface; + CommandManager = commandManager; + pluginInterface.Create(Array.Empty()); + Configuration = (PluginInterface.GetPluginConfig() as Configuration) ?? new Configuration(); + Configuration.Initialize(PluginInterface); + PluginUi = new PluginUI(Configuration, DataPath); + PluginInterface.UiBuilder.Draw += DrawUI; + PluginInterface.UiBuilder.OpenConfigUi += DrawConfigUI; + httpCl = new HttpClient(); + BGMAddressResolver.Init(); + BGMManager.OnSongChanged += HandleSongChanged; + Service.Framework.Update += new OnUpdateDelegate(Framework_Update); + Service.ClientState.Logout += new LogoutDelegate(ClientState_Logout); + mountIDToSongIDMap.Add(298L, 929); + mountIDToSongIDMap.Add(287L, 906); + mountIDToSongIDMap.Add(343L, 20047); + mountIDToSongIDMap.Add(331L, 501); + mountIDToSongIDMap.Add(235L, 796); + } + + private void ClientState_Logout(int type, int code) + { + BGMManager.Play(0); + } + + private void ClientState_Login() + { + } + + private void HandleSongChanged(int oldSong, int newSong, int oldSecondSong, int newSecondSong, bool nocare, bool playedByPlugin) + { + //IL_00e6: Unknown result type (might be due to invalid IL or missing references) + //IL_00eb: Unknown result type (might be due to invalid IL or missing references) + DalamudApi.PluginLog.Debug($"HandleSongChanged called: {oldSong} -> {newSong}, playedByPlugin: {playedByPlugin}", Array.Empty()); + if (DalamudApi.ClientState.IsPvP) + { + DalamudApi.PluginLog.Debug("In PvP, ignoring song change", Array.Empty()); + return; + } + if (playedByPlugin) + { + DalamudApi.PluginLog.Debug("Song changed by plugin, ignoring", Array.Empty()); + return; + } + if (Service.ObjectTable.LocalPlayer == null) + { + DalamudApi.PluginLog.Debug("No mount.", Array.Empty()); + return; + } + uint num = (((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.HasValue ? ((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.Value.RowId : 0u); + DalamudApi.PluginLog.Debug("Mount ID: " + num, Array.Empty()); + byte value = (byte)Marshal.ReadIntPtr((nint)((IGameObject)Service.ObjectTable.LocalPlayer).Address + 9044); + DalamudApi.PluginLog.Debug($"MountID: {num:X} eventState: {value:X}. Addresses: {(nint)((IGameObject)Service.ObjectTable.LocalPlayer).Address + 1736:X} and {(nint)((IGameObject)Service.ObjectTable.LocalPlayer).Address + 8844:X}", Array.Empty()); + if (((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.HasValue) + { + DalamudApi.PluginLog.Debug("We are mounted, lets check if there is a replacement for our song. Current mount: " + num, Array.Empty()); + if (mountIDToSongIDMap.ContainsKey(num)) + { + DalamudApi.PluginLog.Debug("We do indeed have a replacement for this song. Lets play it then.", Array.Empty()); + PlaySong(mountIDToSongIDMap[num]); + } + } + else if (!((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.HasValue) + { + DalamudApi.PluginLog.Debug("We have dismounted. Lets stop music?", Array.Empty()); + StopSong(); + } + } + + public void StopSong() + { + DalamudApi.PluginLog.Debug($"StopSong called - Playing: {BGMManager.PlayingSongId}, Current: {BGMManager.CurrentSongId}", Array.Empty()); + IPluginLog pluginLog = DalamudApi.PluginLog; + DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(26, 1); + defaultInterpolatedStringHandler.AppendLiteral("LocalPlayer CastActionId: "); + IPlayerCharacter localPlayer = Service.ObjectTable.LocalPlayer; + defaultInterpolatedStringHandler.AppendFormatted((localPlayer != null) ? new uint?(((IBattleChara)localPlayer).CastActionId) : ((uint?)null)); + pluginLog.Debug(defaultInterpolatedStringHandler.ToStringAndClear(), Array.Empty()); + IPlayerCharacter localPlayer2 = Service.ObjectTable.LocalPlayer; + if (localPlayer2 != null && ((IBattleChara)localPlayer2).CastActionId == 298) + { + DalamudApi.PluginLog.Debug($"Song ID {BGMManager.CurrentSongId} has a replacement of {929}...", Array.Empty()); + if (929 != BGMManager.PlayingSongId) + { + PlaySong(929, isReplacement: true); + return; + } + DalamudApi.PluginLog.Debug($"But that's the song we're playing [{BGMManager.PlayingSongId}], so let's stop", Array.Empty()); + } + IPlayerCharacter localPlayer3 = Service.ObjectTable.LocalPlayer; + if (localPlayer3 != null && ((IBattleChara)localPlayer3).CastActionId == 287) + { + DalamudApi.PluginLog.Debug($"Song ID {BGMManager.CurrentSongId} has a replacement of {906}...", Array.Empty()); + if (906 != BGMManager.PlayingSongId) + { + PlaySong(906, isReplacement: true); + return; + } + DalamudApi.PluginLog.Debug($"But that's the song we're playing [{BGMManager.PlayingSongId}], so let's stop", Array.Empty()); + } + DalamudApi.PluginLog.Debug("Calling BGMManager.Play(0) to stop music", Array.Empty()); + BGMManager.Play(0); + } + + public void PlaySong(int songId, bool isReplacement = false) + { + DalamudApi.PluginLog.Debug($"Playing {songId}", Array.Empty()); + isPlayingReplacement = isReplacement; + BGMManager.Play(songId); + } + + private unsafe void installSpecialModeHook() + { + string text = "48 89 5C 24 ?? 57 48 83 EC 20 8B 41 10 33 DB"; + nint num = DalamudApi.SigScanner.ScanText(text); + DalamudApi.PluginLog.Debug("MCA: " + (IntPtr)num, Array.Empty()); + getSpecialModeHook = DalamudApi.Hooks.HookFromAddress((IntPtr)num, (GetSpecialMode)SpecialModeDetour, (HookBackend)0); + getSpecialModeHook?.Enable(); + } + + private unsafe int SpecialModeDetour(void* unused, byte specialModeType) + { + currentSpecialMode = specialModeType; + return getSpecialModeHook.Original(unused, specialModeType); + } + + private bool IsLoadingScreen() + { + //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_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_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) + AtkUnitBasePtr addonByName = Service.GameGui.GetAddonByName("_LocationTitle", 1); + AtkUnitBasePtr addonByName2 = Service.GameGui.GetAddonByName("FadeMiddle", 1); + if (((AtkUnitBasePtr)(ref addonByName)).IsNull || !((AtkUnitBase)(nint)addonByName.Address).IsVisible) + { + if (!((AtkUnitBasePtr)(ref addonByName2)).IsNull) + { + return ((AtkUnitBase)(nint)addonByName2.Address).IsVisible; + } + return false; + } + return true; + } + + private void Framework_Update(IFramework framework) + { + //IL_008f: 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) + if (Configuration.Enabled && Service.ClientState.IsLoggedIn) + { + CheckForCastBar(); + } + if (IsLoadingScreen()) + { + return; + } + if (Service.ClientState.IsLoggedIn && Service.ObjectTable.LocalPlayer != null) + { + bool hasValue = ((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.HasValue; + uint num = ((hasValue && ((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.HasValue) ? ((ICharacter)Service.ObjectTable.LocalPlayer).CurrentMount.Value.RowId : 0u); + if (wasMounted && !hasValue) + { + DalamudApi.PluginLog.Debug($"Dismounted detected! Was on mount {lastMountId}, now dismounted", Array.Empty()); + if (mountIDToSongIDMap.ContainsKey(lastMountId)) + { + DalamudApi.PluginLog.Debug("Had replacement music, stopping it now", Array.Empty()); + StopSong(); + } + } + wasMounted = hasValue; + lastMountId = num; + } + BGMManager.Update(null); + songEchoPayload = null; + } + + private void CheckForCastBar() + { + if (!IsLoadingScreen() && Service.ClientState != null && Service.ClientState.IsLoggedIn && !Service.ClientState.IsPvP && ((IBattleChara)Service.ObjectTable.LocalPlayer).IsCasting) + { + lastSpellBeingCast = ((IBattleChara)Service.ObjectTable.LocalPlayer).CastActionId; + lastSpellCast = long.Parse(Convert.ToString((int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds)); + } + } + + public void Dispose() + { + //IL_0028: Unknown result type (might be due to invalid IL or missing references) + //IL_0032: Expected O, but got Unknown + //IL_0054: Unknown result type (might be due to invalid IL or missing references) + //IL_005e: Expected O, but got Unknown + PluginUi.Dispose(); + CommandManager.RemoveHandler("/omm"); + Service.Framework.Update -= new OnUpdateDelegate(Framework_Update); + Service.ClientState.Login -= ClientState_Login; + Service.ClientState.Logout -= new LogoutDelegate(ClientState_Logout); + BGMManager.Play(0); + BGMManager.Dispose(); + } + + private void OnCommand(string command, string args) + { + PluginUi.Visible = true; + } + + private void DrawUI() + { + PluginUi.Draw(); + } + + private void DrawConfigUI() + { + PluginUi.SettingsVisible = true; + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/PluginUI.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/PluginUI.cs new file mode 100644 index 0000000..619baab --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/PluginUI.cs @@ -0,0 +1,102 @@ +using System; +using System.Numerics; +using Dalamud.Bindings.ImGui; + +namespace OmicronMountMusicFixer; + +internal class PluginUI : IDisposable +{ + private Configuration configuration; + + private bool settingsVisible; + + private bool visible; + + public string DataPath { get; } + + public bool SettingsVisible + { + get + { + return settingsVisible; + } + set + { + settingsVisible = value; + } + } + + public bool Visible + { + get + { + return visible; + } + set + { + visible = value; + } + } + + public PluginUI(Configuration configuration, string DataPath) + { + this.configuration = configuration; + this.DataPath = DataPath; + } + + public void DrawMainWindow() + { + //IL_0046: 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) + if (Visible) + { + ImGui.SetNextWindowSize(new Vector2(700f, 330f), (ImGuiCond)4); + ImGui.SetNextWindowSizeConstraints(new Vector2(700f, 330f), new Vector2(float.MaxValue, float.MaxValue)); + if (ImGui.Begin(ImU8String.op_Implicit("Dickheads be gone from mine chat"), ref visible, (ImGuiWindowFlags)24)) + { + ImGui.Text(ImU8String.op_Implicit("Anti-fags :D")); + } + ImGui.End(); + } + } + + public void Dispose() + { + } + + public void Draw() + { + DrawMainWindow(); + DrawSettingsWindow(); + } + + public void DrawSettingsWindow() + { + //IL_0023: 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_007e: 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_0091: Unknown result type (might be due to invalid IL or missing references) + if (!SettingsVisible) + { + return; + } + ImGui.SetNextWindowSize(new Vector2(450f, 100f), (ImGuiCond)1); + if (ImGui.Begin(ImU8String.op_Implicit("World Map Enhancer Settings"), ref settingsVisible, (ImGuiWindowFlags)58)) + { + bool enabled = configuration.Enabled; + if (ImGui.Checkbox(ImU8String.op_Implicit("Enable zooming out with right click"), ref enabled)) + { + configuration.Enabled = enabled; + configuration.Save(); + } + int rightClickDelay = configuration.RightClickDelay; + if (ImGui.InputInt(ImU8String.op_Implicit("Right click release delay"), ref rightClickDelay, 25, 100, default(ImU8String), (ImGuiInputTextFlags)0)) + { + configuration.RightClickDelay = rightClickDelay; + configuration.Save(); + } + } + ImGui.End(); + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SceneFlags.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SceneFlags.cs new file mode 100644 index 0000000..876c705 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SceneFlags.cs @@ -0,0 +1,15 @@ +using System; + +namespace OmicronMountMusicFixer; + +[Flags] +public enum SceneFlags : byte +{ + None = 0, + Unknown = 1, + Resume = 2, + EnablePassEnd = 4, + ForceAutoReset = 8, + EnableDisableRestart = 0x10, + IgnoreBattle = 0x20 +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Service.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Service.cs new file mode 100644 index 0000000..f6b9bad --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Service.cs @@ -0,0 +1,31 @@ +using Dalamud.IoC; +using Dalamud.Plugin.Services; + +namespace OmicronMountMusicFixer; + +public class Service +{ + [PluginService] + public static IClientState ClientState { get; private set; } + + [PluginService] + public static IFramework Framework { get; private set; } + + [PluginService] + public static IGameGui GameGui { get; private set; } + + [PluginService] + public static ISigScanner SigScanner { get; private set; } + + [PluginService] + public static IChatGui Chat { get; private set; } + + [PluginService] + public static IDataManager DataManager { get; private set; } + + [PluginService] + public static IGameInteropProvider Hooks { get; private set; } + + [PluginService] + public static IObjectTable ObjectTable { get; private set; } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Song.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Song.cs new file mode 100644 index 0000000..e1a1816 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Song.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace OmicronMountMusicFixer; + +public struct Song +{ + public int Id; + + public Dictionary Strings; + + public bool DisableRestart; + + public byte SpecialMode; + + public string FilePath; + + public bool FileExists; + + public TimeSpan Duration; + + public string Name => Strings.GetValueOrDefault(Util.Lang(), Strings["en"]).Name; + + public string AlternateName => Strings.GetValueOrDefault(Util.Lang(), Strings["en"]).AlternateName; + + public string SpecialModeName => Strings.GetValueOrDefault(Util.Lang(), Strings["en"]).SpecialModeName; + + public string Locations => Strings.GetValueOrDefault(Util.Lang(), Strings["en"]).Locations; + + public string AdditionalInfo => Strings.GetValueOrDefault(Util.Lang(), Strings["en"]).AdditionalInfo; + + public Song(Dictionary strings) + { + Id = 0; + DisableRestart = false; + SpecialMode = 0; + FilePath = null; + FileExists = false; + Duration = default(TimeSpan); + Strings = strings; + } + + public Song() + { + Id = 0; + DisableRestart = false; + SpecialMode = 0; + FilePath = null; + FileExists = false; + Duration = default(TimeSpan); + Strings = new Dictionary(); + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SongList.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SongList.cs new file mode 100644 index 0000000..53acdcf --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SongList.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using Dalamud.Plugin.Services; +using Lumina.Data; +using Lumina.Excel.Sheets; +using Lumina.Text.ReadOnly; + +namespace OmicronMountMusicFixer; + +public class SongList +{ + private const string SheetPath = "https://docs.google.com/spreadsheets/d/1s-xJjxqp6pwS7oewNy1aOQnr3gaJbewvIBbyYchZ6No/gviz/tq?tqx=out:csv&sheet={0}"; + + private const string SheetFileName = "xiv_bgm_{0}.csv"; + + private readonly Dictionary _songs; + + private readonly HttpClient _client = new HttpClient(); + + private static SongList _instance; + + public static SongList Instance => _instance ?? (_instance = new SongList()); + + private SongList() + { + _songs = new Dictionary(); + try + { + DalamudApi.PluginLog.Information("[SongList] Checking for updated bgm sheets", Array.Empty()); + LoadMetadataSheet(GetRemoteSheet("metadata")); + LoadLangSheet(GetRemoteSheet("en"), "en"); + LoadLangSheet(GetRemoteSheet("ja"), "ja"); + LoadLangSheet(GetRemoteSheet("de"), "de"); + LoadLangSheet(GetRemoteSheet("fr"), "fr"); + LoadLangSheet(GetRemoteSheet("zh"), "zh"); + } + catch (Exception ex) + { + DalamudApi.PluginLog.Error(ex, "[SongList] Orchestrion failed to update bgm sheet; using previous version", Array.Empty()); + LoadMetadataSheet(GetLocalSheet("metadata")); + LoadLangSheet(GetLocalSheet("en"), "en"); + LoadLangSheet(GetLocalSheet("ja"), "ja"); + LoadLangSheet(GetLocalSheet("de"), "de"); + LoadLangSheet(GetLocalSheet("fr"), "fr"); + LoadLangSheet(GetLocalSheet("zh"), "zh"); + } + } + + private void DebugLogSongs() + { + DalamudApi.PluginLog.Debug("Songs:", Array.Empty()); + foreach (KeyValuePair song in _songs) + { + DalamudApi.PluginLog.Debug($"{song.Key}: {song.Value.Id} {song.Value.Strings} {song.Value.FilePath}", Array.Empty()); + } + } + + private string GetRemoteSheet(string code) + { + return _client.GetStringAsync($"https://docs.google.com/spreadsheets/d/1s-xJjxqp6pwS7oewNy1aOQnr3gaJbewvIBbyYchZ6No/gviz/tq?tqx=out:csv&sheet={code}").Result; + } + + private string GetLocalSheet(string code) + { + return File.ReadAllText(Path.Combine(DalamudApi.PluginInterface.AssemblyLocation.DirectoryName, $"xiv_bgm_{code}.csv")); + } + + private void SaveLocalSheet(string text, string code) + { + File.WriteAllText(Path.Combine(DalamudApi.PluginInterface.AssemblyLocation.DirectoryName, $"xiv_bgm_{code}.csv"), text); + } + + private void LoadMetadataSheet(string sheetText) + { + //IL_017a: Unknown result type (might be due to invalid IL or missing references) + //IL_019c: Unknown result type (might be due to invalid IL or missing references) + //IL_01a1: Unknown result type (might be due to invalid IL or missing references) + //IL_01d1: 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_0209: Unknown result type (might be due to invalid IL or missing references) + //IL_020e: Unknown result type (might be due to invalid IL or missing references) + _songs.Clear(); + Dictionary dictionary = ((IEnumerable)DalamudApi.DataManager.Excel.GetSheet((Language?)null, (string)null)).ToDictionary((BGM k) => ((BGM)(ref k)).RowId, (BGM v) => v); + string[] array = sheetText.Split('\n'); + for (int num = 1; num < array.Length; num++) + { + string[] array2 = array[num].Split(new string[1] { "\"," }, StringSplitOptions.None); + int num2 = int.Parse(array2[0].Substring(1)); + string text = array2[1].Substring(1, array2[1].Length - 2).Replace("\"\"", "\""); + double result; + bool num3 = double.TryParse(text, out result); + TimeSpan duration = (num3 ? TimeSpan.FromSeconds(result) : TimeSpan.Zero); + if (!num3) + { + DalamudApi.PluginLog.Debug($"failed parse {num2}: {text}", Array.Empty()); + } + if (dictionary.TryGetValue((uint)num2, out var value)) + { + DalamudApi.PluginLog.Debug($"{num2}", Array.Empty()); + DalamudApi.PluginLog.Debug($"{((BGM)(ref value)).File}", Array.Empty()); + IPluginLog pluginLog = DalamudApi.PluginLog; + ReadOnlySeString file = ((BGM)(ref value)).File; + pluginLog.Debug(((ReadOnlySeString)(ref file)).ExtractText() ?? "", Array.Empty()); + Song song = new Song(); + song.Id = num2; + file = ((BGM)(ref value)).File; + song.FilePath = ((ReadOnlySeString)(ref file)).ExtractText(); + song.SpecialMode = ((BGM)(ref value)).SpecialMode; + song.DisableRestart = ((BGM)(ref value)).DisableRestart; + IDataManager dataManager = DalamudApi.DataManager; + file = ((BGM)(ref value)).File; + song.FileExists = dataManager.FileExists(((ReadOnlySeString)(ref file)).ExtractText()); + song.Duration = duration; + Song value2 = song; + _songs[num2] = value2; + } + } + SaveLocalSheet(sheetText, "metadata"); + } + + private void LoadLangSheet(string sheetText, string code) + { + string[] array = sheetText.Split('\n'); + for (int i = 1; i < array.Length; i++) + { + string[] array2 = array[i].Split(new string[1] { "\"," }, StringSplitOptions.None); + int key = int.Parse(array2[0].Substring(1)); + string text = array2[1].Substring(1); + string alternateName = array2[2].Substring(1); + string specialModeName = array2[3].Substring(1); + string locations = array2[4].Substring(1); + string additionalInfo = array2[5].Substring(1, array2[5].Length - 2).Replace("\"\"", "\""); + if (_songs.TryGetValue(key, out var value)) + { + if ((code == "en" && string.IsNullOrEmpty(text)) || text == "Null BGM" || text == "test") + { + _songs.Remove(key); + } + value.Strings[code] = new SongStrings + { + Name = text, + AlternateName = alternateName, + SpecialModeName = specialModeName, + Locations = locations, + AdditionalInfo = additionalInfo + }; + } + } + SaveLocalSheet(sheetText, code); + } + + public bool IsDisableRestart(int id) + { + if (_songs.TryGetValue(id, out var value)) + { + return value.DisableRestart; + } + return false; + } + + public Dictionary GetSongs() + { + return _songs; + } + + public Song GetSong(int id) + { + if (!_songs.TryGetValue(id, out var value)) + { + return default(Song); + } + return value; + } + + public bool TryGetSong(int id, out Song song) + { + return _songs.TryGetValue(id, out song); + } + + public string GetSongTitle(int id) + { + if (!_songs.TryGetValue(id, out var value)) + { + return ""; + } + return value.Name; + } + + public bool SongExists(int id) + { + return _songs.ContainsKey(id); + } + + public bool TryGetSongByName(string name, out int songId) + { + songId = 0; + foreach (Song value in _songs.Values) + { + foreach (string availableTitleLanguage in Util.AvailableTitleLanguages) + { + if (string.Equals(value.Strings[availableTitleLanguage].Name, name, StringComparison.InvariantCultureIgnoreCase) || string.Equals(value.Strings[availableTitleLanguage].AlternateName, name, StringComparison.InvariantCultureIgnoreCase)) + { + songId = value.Id; + return true; + } + } + } + return false; + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SongStrings.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SongStrings.cs new file mode 100644 index 0000000..502cc74 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/SongStrings.cs @@ -0,0 +1,14 @@ +namespace OmicronMountMusicFixer; + +public struct SongStrings +{ + public string Name; + + public string AlternateName; + + public string SpecialModeName; + + public string Locations; + + public string AdditionalInfo; +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Util.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Util.cs new file mode 100644 index 0000000..71b9b26 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer/Util.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Numerics; +using System.Text; +using Dalamud.Bindings.ImGui; +using Dalamud.Interface; +using Dalamud.Plugin.Services; + +namespace OmicronMountMusicFixer; + +internal static class Util +{ + public static List AvailableTitleLanguages => new List { "en" }; + + internal static bool TryScanText(this ISigScanner scanner, string sig, out nint result) + { + result = IntPtr.Zero; + try + { + result = scanner.ScanText(sig); + return true; + } + catch (KeyNotFoundException) + { + return false; + } + } + + public static string Lang() + { + return "en"; + } + + private unsafe static byte[] ReadTerminatedBytes(byte* ptr) + { + if (ptr == null) + { + return new byte[0]; + } + List list = new List(); + while (*ptr != 0) + { + list.Add(*ptr); + ptr++; + } + return list.ToArray(); + } + + internal unsafe static string ReadTerminatedString(byte* ptr) + { + return Encoding.UTF8.GetString(ReadTerminatedBytes(ptr)); + } + + internal static bool ContainsIgnoreCase(this string haystack, string needle) + { + return CultureInfo.InvariantCulture.CompareInfo.IndexOf(haystack, needle, CompareOptions.IgnoreCase) >= 0; + } + + internal static bool IconButton(FontAwesomeIcon icon, string id) + { + //IL_0000: 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_0034: Unknown result type (might be due to invalid IL or missing references) + ImGui.PushFont(UiBuilder.IconFont); + ImU8String val = default(ImU8String); + ((ImU8String)(ref val))._002Ector(2, 2); + ((ImU8String)(ref val)).AppendFormatted(FontAwesomeExtensions.ToIconString(icon)); + ((ImU8String)(ref val)).AppendLiteral("##"); + ((ImU8String)(ref val)).AppendFormatted(id); + bool result = ImGui.Button(val, default(Vector2)); + ImGui.PopFont(); + return result; + } +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer_ProcessedByFody.cs b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer_ProcessedByFody.cs new file mode 100644 index 0000000..ca336b9 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/OmicronMountMusicFixer_ProcessedByFody.cs @@ -0,0 +1,6 @@ +internal class OmicronMountMusicFixer_ProcessedByFody +{ + internal const string FodyVersion = "6.6.4.0"; + + internal const string Resourcer = "1.8.0.0"; +} diff --git a/.recovery/decompiled/OmicronMountMusicFixer/Properties/AssemblyInfo.cs b/.recovery/decompiled/OmicronMountMusicFixer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..927f1b0 --- /dev/null +++ b/.recovery/decompiled/OmicronMountMusicFixer/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyCompany("aRkker")] +[assembly: AssemblyConfiguration("Release")] +[assembly: AssemblyDescription("Music")] +[assembly: AssemblyFileVersion("1.0.7.0")] +[assembly: AssemblyInformationalVersion("1.0.0+8c181f19a2ba71e0bee0e08ad8a42953b3276520")] +[assembly: AssemblyProduct("OmicronMountMusicFixer")] +[assembly: AssemblyTitle("OmicronMountMusicFixer")] +[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/aRkker/ffxiv-dalamud-wme.git")] +[assembly: AssemblyVersion("1.0.7.0")] diff --git a/.recovery/decompiled/WorldMapEnhancer/Properties/AssemblyInfo.cs b/.recovery/decompiled/WorldMapEnhancer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..bdb844b --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyCompany("WorldMapEnhancer")] +[assembly: AssemblyConfiguration("Release")] +[assembly: AssemblyDescription("A plugin to enable right click zoom on the map")] +[assembly: AssemblyFileVersion("1.0.6.2")] +[assembly: AssemblyInformationalVersion("1.0.6.2+8c181f19a2ba71e0bee0e08ad8a42953b3276520")] +[assembly: AssemblyProduct("WorldMapEnhancer")] +[assembly: AssemblyTitle("WorldMapEnhancer")] +[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/aRkker/ffxiv-dalamud-wme.git")] +[assembly: AssemblyVersion("1.0.6.2")] diff --git a/.recovery/decompiled/WorldMapEnhancer/WorldMapEnhancer.csproj b/.recovery/decompiled/WorldMapEnhancer/WorldMapEnhancer.csproj new file mode 100644 index 0000000..568e001 --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/WorldMapEnhancer.csproj @@ -0,0 +1,21 @@ + + + WorldMapEnhancer + False + net10.0 + x64 + + + 14.0 + True + False + + + + + + + + + + \ No newline at end of file diff --git a/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Configuration.cs b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Configuration.cs new file mode 100644 index 0000000..b3a3410 --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Configuration.cs @@ -0,0 +1,28 @@ +using System; +using Dalamud.Configuration; +using Dalamud.Plugin; + +namespace WorldMapFixer; + +[Serializable] +public class Configuration : IPluginConfiguration +{ + [NonSerialized] + private IDalamudPluginInterface? pluginInterface; + + public int Version { get; set; } + + public bool Enabled { get; set; } = true; + + public int RightClickDelay { get; set; } = 250; + + public void Initialize(IDalamudPluginInterface pluginInterface) + { + this.pluginInterface = pluginInterface; + } + + public void Save() + { + pluginInterface.SavePluginConfig((IPluginConfiguration)(object)this); + } +} diff --git a/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/DalamudApi.cs b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/DalamudApi.cs new file mode 100644 index 0000000..ae43c57 --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/DalamudApi.cs @@ -0,0 +1,53 @@ +using System; +using Dalamud.IoC; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; + +namespace WorldMapFixer; + +public class DalamudApi +{ + [PluginService] + public static IChatGui ChatGui { get; private set; } + + [PluginService] + public static IClientState ClientState { get; private set; } + + [PluginService] + public static ICommandManager CommandManager { get; private set; } + + [PluginService] + public static IDalamudPluginInterface PluginInterface { get; private set; } + + [PluginService] + public static IDataManager DataManager { get; private set; } + + [PluginService] + public static IDtrBar DtrBar { get; private set; } + + [PluginService] + public static IFramework Framework { get; private set; } + + [PluginService] + public static IGameGui GameGui { get; private set; } + + [PluginService] + public static IKeyState KeyState { get; private set; } + + [PluginService] + public static ISigScanner SigScanner { get; private set; } + + [PluginService] + public static IGameInteropProvider Hooks { get; private set; } + + [PluginService] + public static IPluginLog PluginLog { get; private set; } + + [PluginService] + public static IAddonLifecycle AddonLifecycle { get; private set; } + + public static void Initialize(IDalamudPluginInterface pluginInterface) + { + pluginInterface.Create(Array.Empty()); + } +} diff --git a/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Plugin.cs b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Plugin.cs new file mode 100644 index 0000000..7598589 --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Plugin.cs @@ -0,0 +1,328 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using Dalamud.Game.ClientState.Keys; +using Dalamud.Game.Command; +using Dalamud.Game.NativeWrapper; +using Dalamud.Hooking; +using Dalamud.Plugin; +using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Component.GUI; +using InteropGenerator.Runtime; + +namespace WorldMapFixer; + +public sealed class Plugin : IDalamudPlugin, IDisposable +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void FireCallbackDelegate(nint atkUnitBase, uint valueCount, nint values, bool close); + + public delegate void AreaMapReceiveEventDelegate(long p1, long p2, uint p3, long p4, nint p5); + + private const string commandName = "/wme"; + + public bool alertedDebugWindow; + + private bool areaMapVisible; + + private IKeyState keyState; + + private nint fireCallbackAddress; + + private FireCallbackDelegate fireCallback; + + public string Name => "World Map Enhancer"; + + private IDalamudPluginInterface PluginInterface { get; init; } + + private ICommandManager CommandManager { get; init; } + + private Configuration Configuration { get; init; } + + private PluginUI PluginUi { get; init; } + + public Hook MouseDelegateHook { get; private set; } + + public long rcStartTime { get; private set; } + + public Plugin(IDalamudPluginInterface pluginInterface) + { + //IL_0045: Unknown result type (might be due to invalid IL or missing references) + //IL_004f: Expected O, but got Unknown + //IL_00ad: Unknown result type (might be due to invalid IL or missing references) + //IL_00b7: Expected O, but got Unknown + //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_00c7: Expected O, but got Unknown + DalamudApi.Initialize(pluginInterface); + PluginInterface = pluginInterface; + CommandManager = DalamudApi.CommandManager ?? throw new ArgumentNullException("CommandManager"); + pluginInterface.Create(Array.Empty()); + DalamudApi.Framework.Update += new OnUpdateDelegate(Framework_UpdateNew); + Configuration = (PluginInterface.GetPluginConfig() as Configuration) ?? new Configuration(); + Configuration.Initialize(PluginInterface); + PluginUi = new PluginUI(Configuration); + keyState = DalamudApi.KeyState; + CommandManager.AddHandler("/wme", new CommandInfo(new HandlerDelegate(OnCommand)) + { + HelpMessage = "Configuration for the right click behaviour" + }); + PluginInterface.UiBuilder.Draw += DrawUI; + PluginInterface.UiBuilder.OpenConfigUi += DrawConfigUI; + string text = "E8 ?? ?? ?? ?? 0F B6 E8 8B 44 24 20"; + fireCallbackAddress = DalamudApi.SigScanner.ScanText(text); + fireCallback = (FireCallbackDelegate)Marshal.GetDelegateForFunctionPointer(fireCallbackAddress, typeof(FireCallbackDelegate)); + InstallMouseHook(); + } + + private void Framework_UpdateNew(IFramework framework) + { + if (Configuration != null && Configuration.Enabled && DalamudApi.ClientState != null && DalamudApi.ClientState.IsLoggedIn) + { + CheckForMap(); + } + } + + private void InstallMouseHook() + { + string text = "40 55 56 57 48 8B EC 48 83 EC 70 0F B7 C2"; + nint num = DalamudApi.SigScanner.ScanText(text); + if (num != IntPtr.Zero) + { + DalamudApi.PluginLog.Debug("Hooking!", Array.Empty()); + MouseDelegateHook = DalamudApi.Hooks.HookFromAddress((IntPtr)num, (AreaMapReceiveEventDelegate)Detour, (HookBackend)0); + MouseDelegateHook?.Enable(); + } + } + + private void Detour(long p1, long p2, uint p3, long p4, nint p5) + { + Marshal.ReadIntPtr(p5); + byte b = Marshal.ReadByte(p5, 6); + byte b2 = Marshal.ReadByte(p5, 7); + _ = DalamudApi.KeyState[(VirtualKey)162]; + if (p2 == 4 && p3 == 16 && b == 1 && b2 != 1) + { + ZoomOutMap(); + } + MouseDelegateHook.Original(p1, p2, p3, p4, p5); + } + + public unsafe Vector4 GetMapParams() + { + if (areaMapVisible) + { + AtkUnitBase* areaMapPointer = GetAreaMapPointer(); + return new Vector4(((AtkResNode)((AtkUnitBase)areaMapPointer).RootNode).X, ((AtkResNode)((AtkUnitBase)areaMapPointer).RootNode).Y, (int)((AtkResNode)((AtkUnitBase)areaMapPointer).RootNode).GetWidth(), (int)((AtkResNode)((AtkUnitBase)areaMapPointer).RootNode).GetHeight()); + } + return new Vector4(float.MinValue, float.MinValue, float.MinValue, float.MinValue); + } + + public unsafe static AtkValue* CreateAtkValueArray(params object[] values) + { + //IL_008e: 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) + //IL_00dd: Unknown result type (might be due to invalid IL or missing references) + //IL_0131: Unknown result type (might be due to invalid IL or missing references) + //IL_0178: Unknown result type (might be due to invalid IL or missing references) + //IL_017d: 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) + AtkValue* ptr = (AtkValue*)Marshal.AllocHGlobal(values.Length * Unsafe.SizeOf()); + if (ptr == null) + { + return null; + } + try + { + for (int i = 0; i < values.Length; i++) + { + object obj = values[i]; + if (!(obj is uint uInt)) + { + if (!(obj is int num)) + { + if (!(obj is float num2)) + { + if (!(obj is bool flag)) + { + if (!(obj is string s)) + { + throw new ArgumentException($"Unable to convert type {obj.GetType()} to AtkValue"); + } + Unsafe.Write(&((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Type, (ValueType)8); + byte[] bytes = Encoding.UTF8.GetBytes(s); + nint num3 = Marshal.AllocHGlobal(bytes.Length + 1); + Marshal.Copy(bytes, 0, num3, bytes.Length); + Marshal.WriteByte(num3, bytes.Length, 0); + Unsafe.Write(&((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).String, CStringPointer.op_Implicit((byte*)num3)); + } + else + { + Unsafe.Write(&((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Type, (ValueType)2); + ((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Byte = (flag ? ((byte)1) : ((byte)0)); + } + } + else + { + Unsafe.Write(&((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Type, (ValueType)7); + ((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Float = num2; + } + } + else + { + Unsafe.Write(&((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Type, (ValueType)3); + ((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Int = num; + } + } + else + { + Unsafe.Write(&((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Type, (ValueType)5); + ((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).UInt = uInt; + } + } + return ptr; + } + catch + { + return null; + } + } + + public unsafe static bool GetUnitBase(string name, out AtkUnitBase* unitBase, int index = 1) + { + unitBase = GetUnitBase(name, index); + return unitBase != null; + } + + public unsafe static AtkUnitBase* GetUnitBase(string name, int index = 1) + { + //IL_0007: Unknown result type (might be due to invalid IL or missing references) + return (AtkUnitBase*)Service.GameGui.GetAddonByName(name, index).Address; + } + + public unsafe static void GenerateCallback(AtkUnitBase* unitBase, params object[] values) + { + //IL_002b: Unknown result type (might be due to invalid IL or missing references) + //IL_0031: Invalid comparison between Unknown and I4 + //IL_003e: Unknown result type (might be due to invalid IL or missing references) + AtkValue* ptr = CreateAtkValueArray(values); + if (ptr == null) + { + return; + } + try + { + ((AtkUnitBase)unitBase).FireCallback((uint)values.Length, ptr, false); + } + finally + { + for (int i = 0; i < values.Length; i++) + { + if ((int)((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).Type == 8) + { + Marshal.FreeHGlobal(new IntPtr(CStringPointer.op_Implicit(((AtkValue)((byte*)ptr + (nint)i * (nint)Unsafe.SizeOf())).String))); + } + } + Marshal.FreeHGlobal(new IntPtr(ptr)); + } + } + + private unsafe AtkUnitBase* GetAreaMapPointer() + { + //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_0011: 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) + AtkUnitBasePtr addonByName = DalamudApi.GameGui.GetAddonByName("AreaMap", 1); + if (addonByName.Address != (IntPtr)IntPtr.Zero) + { + AtkUnitBase* address = (AtkUnitBase*)addonByName.Address; + if (((AtkUnitBase)address).RootNode != null) + { + DalamudApi.PluginLog.Debug("PTR: " + (long)((AtkUnitBase)address).RootNode, Array.Empty()); + return address; + } + DalamudApi.PluginLog.Debug("Null pointer.", Array.Empty()); + return null; + } + DalamudApi.PluginLog.Debug("Null pointer.", Array.Empty()); + return null; + } + + private unsafe void CheckForMap() + { + //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_0011: 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) + AtkUnitBasePtr addonByName = DalamudApi.GameGui.GetAddonByName("AreaMap", 1); + if (addonByName.Address == (IntPtr)IntPtr.Zero) + { + return; + } + AtkUnitBase* address = (AtkUnitBase*)addonByName.Address; + if (((AtkUnitBase)address).RootNode == null) + { + return; + } + if (((AtkUnitBase)address).IsVisible) + { + if (!areaMapVisible) + { + areaMapVisible = true; + } + } + else if (areaMapVisible) + { + areaMapVisible = false; + } + } + + private void Framework_Update() + { + if (Configuration.Enabled && DalamudApi.ClientState.IsLoggedIn) + { + CheckForMap(); + } + } + + public void Dispose() + { + //IL_0028: Unknown result type (might be due to invalid IL or missing references) + //IL_0032: Expected O, but got Unknown + PluginUi.Dispose(); + CommandManager.RemoveHandler("/wme"); + DalamudApi.Framework.Update -= new OnUpdateDelegate(Framework_UpdateNew); + MouseDelegateHook.Dispose(); + } + + private void OnCommand(string command, string args) + { + PluginUi.SettingsVisible = true; + } + + private void DrawUI() + { + PluginUi.Draw(); + } + + private unsafe void ZoomOutMap() + { + AtkUnitBase* unitBase = GetUnitBase("AreaMap"); + if (unitBase == null) + { + DalamudApi.PluginLog.Debug("Null pointer to areamap. Going away", Array.Empty()); + return; + } + uint valueCount = 1u; + AtkValue* values = CreateAtkValueArray(5); + fireCallback((nint)unitBase, valueCount, (nint)values, close: false); + } + + private void DrawConfigUI() + { + PluginUi.SettingsVisible = true; + } +} diff --git a/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/PluginUI.cs b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/PluginUI.cs new file mode 100644 index 0000000..809785d --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/PluginUI.cs @@ -0,0 +1,68 @@ +using System; +using System.Numerics; +using Dalamud.Bindings.ImGui; + +namespace WorldMapFixer; + +internal class PluginUI : IDisposable +{ + private Configuration configuration; + + private bool settingsVisible; + + public bool SettingsVisible + { + get + { + return settingsVisible; + } + set + { + settingsVisible = value; + } + } + + public PluginUI(Configuration configuration) + { + this.configuration = configuration; + } + + public void Dispose() + { + } + + public void Draw() + { + DrawSettingsWindow(); + } + + public void DrawSettingsWindow() + { + //IL_0023: 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_007e: 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_0091: Unknown result type (might be due to invalid IL or missing references) + if (!SettingsVisible) + { + return; + } + ImGui.SetNextWindowSize(new Vector2(450f, 100f), (ImGuiCond)1); + if (ImGui.Begin(ImU8String.op_Implicit("World Map Enhancer Settings"), ref settingsVisible, (ImGuiWindowFlags)58)) + { + bool enabled = configuration.Enabled; + if (ImGui.Checkbox(ImU8String.op_Implicit("Enable zooming out with right click"), ref enabled)) + { + configuration.Enabled = enabled; + configuration.Save(); + } + int rightClickDelay = configuration.RightClickDelay; + if (ImGui.InputInt(ImU8String.op_Implicit("Right click release delay"), ref rightClickDelay, 25, 100, default(ImU8String), (ImGuiInputTextFlags)0)) + { + configuration.RightClickDelay = rightClickDelay; + configuration.Save(); + } + } + ImGui.End(); + } +} diff --git a/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Service.cs b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Service.cs new file mode 100644 index 0000000..be17211 --- /dev/null +++ b/.recovery/decompiled/WorldMapEnhancer/WorldMapFixer/Service.cs @@ -0,0 +1,25 @@ +using Dalamud.IoC; +using Dalamud.Plugin.Services; + +namespace WorldMapFixer; + +public class Service +{ + [PluginService] + public static IClientState? ClientState { get; private set; } + + [PluginService] + public static IFramework? Framework { get; private set; } + + [PluginService] + public static IGameGui? GameGui { get; private set; } + + [PluginService] + public static ISigScanner? SigScanner { get; private set; } + + [PluginService] + public static IAddonLifecycle? AddonLifecycle { get; private set; } + + [PluginService] + public static IKeyState? KeyState { get; private set; } +} diff --git a/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.deps.json b/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.deps.json new file mode 100644 index 0000000..25d357c --- /dev/null +++ b/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "AntiDickheadChatmodule/0.0.6.0": { + "runtime": { + "AntiDickheadChatmodule.dll": {} + } + } + } + }, + "libraries": { + "AntiDickheadChatmodule/0.0.6.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.dll b/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.dll new file mode 100644 index 0000000..dbd4e71 Binary files /dev/null and b/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.dll differ diff --git a/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.json b/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.json new file mode 100644 index 0000000..95acfd5 --- /dev/null +++ b/.recovery/extract/AntiDickheadChatmodule/AntiDickheadChatmodule.json @@ -0,0 +1,20 @@ +{ + "Author": "aRkker", + "Name": "Anti-Dickhead ChatModule", + "InternalName": "AntiDickheadChatmodule", + "AssemblyVersion": "0.0.6.0", + "Description": "Makes your chat more sufferable. :)", + "ApplicableVersion": "any", + "Tags": [ + "other", + "social" + ], + "DalamudApiLevel": 14, + "LoadRequiredState": 0, + "LoadSync": false, + "CanUnloadAsync": false, + "LoadPriority": 0, + "Punchline": "Removes periods, and capitals", + "Changelog": "0.0.1.1\nReuploadto fix?\n0.0.1.0\nProbably broken 6.3", + "AcceptsFeedback": true +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.deps.json b/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.deps.json new file mode 100644 index 0000000..8ccc5a3 --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.deps.json @@ -0,0 +1,64 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v7.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v7.0": { + "CrystallineConflictWinsTracker/0.0.1.4": { + "dependencies": { + "DalamudPackager": "2.1.8", + "System.Runtime": "4.3.1" + }, + "runtime": { + "CrystallineConflictWinsTracker.dll": {} + } + }, + "DalamudPackager/2.1.8": {}, + "Microsoft.NETCore.Platforms/1.1.1": {}, + "Microsoft.NETCore.Targets/1.1.3": {}, + "System.Runtime/4.3.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + } + } + }, + "libraries": { + "CrystallineConflictWinsTracker/0.0.1.4": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "DalamudPackager/2.1.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YqagNXs9InxmqkXzq7kLveImxnodkBEicAhydMXVp7dFjC7xb76U6zGgAax4/BWIWfZeWzr5DJyQSev31kj81A==", + "path": "dalamudpackager/2.1.8", + "hashPath": "dalamudpackager.2.1.8.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==", + "path": "microsoft.netcore.platforms/1.1.1", + "hashPath": "microsoft.netcore.platforms.1.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.1.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==", + "path": "microsoft.netcore.targets/1.1.3", + "hashPath": "microsoft.netcore.targets.1.1.3.nupkg.sha512" + }, + "System.Runtime/4.3.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", + "path": "system.runtime/4.3.1", + "hashPath": "system.runtime.4.3.1.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.dll b/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.dll new file mode 100644 index 0000000..584584e Binary files /dev/null and b/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.dll differ diff --git a/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.json b/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.json new file mode 100644 index 0000000..3f4219e --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/CrystallineConflictWinsTracker.json @@ -0,0 +1,17 @@ +{ + "Author": "aRkker", + "Name": "Crystalline Conflict Winratio tracker", + "InternalName": "CrystallineConflictWinsTracker", + "AssemblyVersion": "0.0.2.9", + "Description": "Tracks your CC wins and losses", + "ApplicableVersion": "any", + "Tags": [ + "pvp", + "stats", + "other" + ], + "DalamudApiLevel": 9, + "LoadPriority": 0, + "Punchline": "See how shite you are", + "Changelog": "0.0.1.4\nSeason 6\n0.0.1.1\nFixes for something dno\n0.0.1.0\nDalamud API 8, NET 7.0" +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker.deps.json b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker.deps.json new file mode 100644 index 0000000..81a565f --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker.deps.json @@ -0,0 +1,64 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "PvpWinsTracker/0.0.0.1": { + "dependencies": { + "DalamudPackager": "2.1.7", + "System.Runtime": "4.3.1" + }, + "runtime": { + "PvpWinsTracker.dll": {} + } + }, + "DalamudPackager/2.1.7": {}, + "Microsoft.NETCore.Platforms/1.1.1": {}, + "Microsoft.NETCore.Targets/1.1.3": {}, + "System.Runtime/4.3.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + } + } + }, + "libraries": { + "PvpWinsTracker/0.0.0.1": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "DalamudPackager/2.1.7": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jnZ/sdInyn07ycuWI+pPOtP/xE3v+c4+jYJfDt36FWnBF9NKqkpzfviJtPl/jGLgbaCmFIXu+Yid0N8GvdKefg==", + "path": "dalamudpackager/2.1.7", + "hashPath": "dalamudpackager.2.1.7.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==", + "path": "microsoft.netcore.platforms/1.1.1", + "hashPath": "microsoft.netcore.platforms.1.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.1.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==", + "path": "microsoft.netcore.targets/1.1.3", + "hashPath": "microsoft.netcore.targets.1.1.3.nupkg.sha512" + }, + "System.Runtime/4.3.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", + "path": "system.runtime/4.3.1", + "hashPath": "system.runtime.4.3.1.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker.json b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker.json new file mode 100644 index 0000000..02d7d77 --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker.json @@ -0,0 +1,42 @@ +{ + "Disabled": true, + "Testing": false, + "ScheduledForDeletion": false, + "InstalledFromUrl": "", + "IsThirdParty": false, + "EffectiveVersion": "0.0.0.1", + "IsAvailableForTesting": false, + "Author": "aRkker", + "Name": "CC wins tracker", + "Punchline": "See how shite you are", + "Description": "Tracks your CC wins and losses", + "Changelog": "0.0.0.1", + "Tags": [ + "pvp", + "stats" + ], + "CategoryTags": null, + "IsHide": false, + "InternalName": "PvpWinsTracker", + "AssemblyVersion": "0.0.0.1", + "TestingAssemblyVersion": null, + "IsTestingExclusive": false, + "RepoUrl": null, + "ApplicableVersion": "any", + "DalamudApiLevel": 6, + "DownloadCount": 0, + "LastUpdate": 0, + "DownloadLinkInstall": null, + "DownloadLinkUpdate": null, + "DownloadLinkTesting": null, + "LoadRequiredState": 0, + "LoadSync": false, + "LoadPriority": 0, + "CanUnloadAsync": false, + "ImageUrls": null, + "IconUrl": null, + "AcceptsFeedback": true, + "FeedbackMessage": null, + "_isDip17Plugin": false, + "_Dip17Channel": null +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker/PvpWinsTracker.json b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker/PvpWinsTracker.json new file mode 100644 index 0000000..2dc5df9 --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker/PvpWinsTracker.json @@ -0,0 +1,16 @@ +{ + "Author": "aRkker", + "Name": "CC wins tracker", + "InternalName": "PvpWinsTracker", + "AssemblyVersion": "0.0.0.1", + "Description": "Tracks your CC wins and losses", + "ApplicableVersion": "any", + "Tags": [ + "pvp", + "stats" + ], + "DalamudApiLevel": 6, + "LoadPriority": 0, + "Punchline": "See how shite you are", + "Changelog": "0.0.0.1" +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker/latest.zip b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker/latest.zip new file mode 100644 index 0000000..0bf08e3 Binary files /dev/null and b/.recovery/extract/CrystallineConflictWinsTracker/PvpWinsTracker/latest.zip differ diff --git a/.recovery/extract/CrystallineConflictWinsTracker/WinTracker.deps.json b/.recovery/extract/CrystallineConflictWinsTracker/WinTracker.deps.json new file mode 100644 index 0000000..ecbe8e5 --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/WinTracker.deps.json @@ -0,0 +1,64 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "WinTracker/0.0.0.1": { + "dependencies": { + "DalamudPackager": "2.1.7", + "System.Runtime": "4.3.1" + }, + "runtime": { + "WinTracker.dll": {} + } + }, + "DalamudPackager/2.1.7": {}, + "Microsoft.NETCore.Platforms/1.1.1": {}, + "Microsoft.NETCore.Targets/1.1.3": {}, + "System.Runtime/4.3.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + } + } + }, + "libraries": { + "WinTracker/0.0.0.1": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "DalamudPackager/2.1.7": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jnZ/sdInyn07ycuWI+pPOtP/xE3v+c4+jYJfDt36FWnBF9NKqkpzfviJtPl/jGLgbaCmFIXu+Yid0N8GvdKefg==", + "path": "dalamudpackager/2.1.7", + "hashPath": "dalamudpackager.2.1.7.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==", + "path": "microsoft.netcore.platforms/1.1.1", + "hashPath": "microsoft.netcore.platforms.1.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.1.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==", + "path": "microsoft.netcore.targets/1.1.3", + "hashPath": "microsoft.netcore.targets.1.1.3.nupkg.sha512" + }, + "System.Runtime/4.3.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", + "path": "system.runtime/4.3.1", + "hashPath": "system.runtime.4.3.1.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/WinTracker.json b/.recovery/extract/CrystallineConflictWinsTracker/WinTracker.json new file mode 100644 index 0000000..3b714fa --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/WinTracker.json @@ -0,0 +1,39 @@ +{ + "Disabled": true, + "Testing": false, + "ScheduledForDeletion": false, + "InstalledFromUrl": "", + "IsThirdParty": false, + "EffectiveVersion": "0.0.0.1", + "IsAvailableForTesting": false, + "Author": "developer", + "Name": "WinTracker", + "Punchline": null, + "Description": "", + "Changelog": null, + "Tags": null, + "CategoryTags": null, + "IsHide": false, + "InternalName": "WinTracker", + "AssemblyVersion": "0.0.0.1", + "TestingAssemblyVersion": null, + "IsTestingExclusive": false, + "RepoUrl": null, + "ApplicableVersion": "any", + "DalamudApiLevel": 7, + "DownloadCount": 0, + "LastUpdate": 0, + "DownloadLinkInstall": null, + "DownloadLinkUpdate": null, + "DownloadLinkTesting": null, + "LoadRequiredState": 0, + "LoadSync": false, + "LoadPriority": 0, + "CanUnloadAsync": false, + "ImageUrls": null, + "IconUrl": null, + "AcceptsFeedback": true, + "FeedbackMessage": null, + "_isDip17Plugin": false, + "_Dip17Channel": null +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer.deps.json b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer.deps.json new file mode 100644 index 0000000..1cd2fdc --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer.deps.json @@ -0,0 +1,34 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "WorldMapEnhancer/1.0.0.4": { + "dependencies": { + "DalamudPackager": "2.1.7" + }, + "runtime": { + "WorldMapEnhancer.dll": {} + } + }, + "DalamudPackager/2.1.7": {} + } + }, + "libraries": { + "WorldMapEnhancer/1.0.0.4": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "DalamudPackager/2.1.7": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jnZ/sdInyn07ycuWI+pPOtP/xE3v+c4+jYJfDt36FWnBF9NKqkpzfviJtPl/jGLgbaCmFIXu+Yid0N8GvdKefg==", + "path": "dalamudpackager/2.1.7", + "hashPath": "dalamudpackager.2.1.7.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer.json b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer.json new file mode 100644 index 0000000..8f33df3 --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer.json @@ -0,0 +1,44 @@ +{ + "Disabled": true, + "Testing": false, + "ScheduledForDeletion": false, + "InstalledFromUrl": "", + "IsThirdParty": false, + "EffectiveVersion": "1.0.0.4", + "Author": "aRkker", + "Name": "World Map Enhancer", + "Punchline": "Right click to zoom out the big map", + "Description": "Simply zoom out by right clicking the world map, like God intended it", + "Changelog": "1.0.0.3\n Testing changelog :)", + "Tags": [ + "world", + "map", + "enhance", + "rightclick", + "zoom" + ], + "CategoryTags": null, + "IsHide": false, + "InternalName": "WorldMapEnhancer", + "AssemblyVersion": "1.0.0.4", + "TestingAssemblyVersion": null, + "IsTestingExclusive": false, + "RepoUrl": null, + "ApplicableVersion": "any", + "DalamudApiLevel": 6, + "DownloadCount": 0, + "LastUpdate": 0, + "DownloadLinkInstall": null, + "DownloadLinkUpdate": null, + "DownloadLinkTesting": null, + "LoadRequiredState": 0, + "LoadSync": false, + "LoadPriority": 0, + "CanUnloadAsync": false, + "ImageUrls": null, + "IconUrl": null, + "AcceptsFeedback": true, + "FeedbackMessage": null, + "_isDip17Plugin": false, + "_Dip17Channel": null +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer/WorldMapEnhancer.json b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer/WorldMapEnhancer.json new file mode 100644 index 0000000..136294b --- /dev/null +++ b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer/WorldMapEnhancer.json @@ -0,0 +1,19 @@ +{ + "Author": "aRkker", + "Name": "World Map Enhancer", + "InternalName": "WorldMapEnhancer", + "AssemblyVersion": "1.0.0.4", + "Description": "Simply zoom out by right clicking the world map, like God intended it", + "ApplicableVersion": "any", + "Tags": [ + "world", + "map", + "enhance", + "rightclick", + "zoom" + ], + "DalamudApiLevel": 6, + "LoadPriority": 0, + "Punchline": "Right click to zoom out the big map", + "Changelog": "1.0.0.3\n Testing changelog :)" +} \ No newline at end of file diff --git a/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer/latest.zip b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer/latest.zip new file mode 100644 index 0000000..e3604f6 Binary files /dev/null and b/.recovery/extract/CrystallineConflictWinsTracker/WorldMapEnhancer/latest.zip differ diff --git a/.recovery/extract/MultiboxMutexer/MultiboxMutexer.deps.json b/.recovery/extract/MultiboxMutexer/MultiboxMutexer.deps.json new file mode 100644 index 0000000..226420d --- /dev/null +++ b/.recovery/extract/MultiboxMutexer/MultiboxMutexer.deps.json @@ -0,0 +1,1235 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v7.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v7.0": { + "MultiboxMutexer/1.0.0": { + "dependencies": { + "DalamudPackager": "2.1.8", + "Fody": "6.6.4", + "Resourcer.Fody": "1.8.0", + "System.Runtime": "4.3.1" + }, + "runtime": { + "MultiboxMutexer.dll": {} + } + }, + "DalamudPackager/2.1.8": {}, + "Fody/6.6.4": {}, + "Microsoft.NETCore.Platforms/1.1.1": {}, + "Microsoft.NETCore.Targets/1.1.3": {}, + "Microsoft.Win32.Primitives/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "NETStandard.Library/1.6.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.Win32.Primitives": "4.3.0", + "System.AppContext": "4.3.0", + "System.Collections": "4.3.0", + "System.Collections.Concurrent": "4.3.0", + "System.Console": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tools": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Calendars": "4.3.0", + "System.IO": "4.3.0", + "System.IO.Compression": "4.3.0", + "System.IO.Compression.ZipFile": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Linq": "4.3.0", + "System.Linq.Expressions": "4.3.0", + "System.Net.Http": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Net.Sockets": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Text.RegularExpressions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Timer": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0", + "System.Xml.XDocument": "4.3.0" + } + }, + "Resourcer.Fody/1.8.0": { + "dependencies": { + "Fody": "6.6.4", + "NETStandard.Library": "1.6.1" + } + }, + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.native.System/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + }, + "runtime.native.System.IO.Compression/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + }, + "runtime.native.System.Net.Http/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + }, + "runtime.native.System.Security.Cryptography.Apple/4.3.0": { + "dependencies": { + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0" + } + }, + "runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "dependencies": { + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple/4.3.0": {}, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {}, + "System.AppContext/4.3.0": { + "dependencies": { + "System.Runtime": "4.3.1" + } + }, + "System.Buffers/4.3.0": { + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Threading": "4.3.0" + } + }, + "System.Collections/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Collections.Concurrent/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Console/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.IO": "4.3.0", + "System.Runtime": "4.3.1", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Diagnostics.Debug/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Diagnostics.DiagnosticSource/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.1", + "System.Threading": "4.3.0" + } + }, + "System.Diagnostics.Tools/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Diagnostics.Tracing/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Globalization/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Globalization.Calendars/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Globalization": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Globalization.Extensions/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.InteropServices": "4.3.0" + } + }, + "System.IO/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.Compression/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Buffers": "4.3.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.IO.Compression": "4.3.0" + } + }, + "System.IO.Compression.ZipFile/4.3.0": { + "dependencies": { + "System.Buffers": "4.3.0", + "System.IO": "4.3.0", + "System.IO.Compression": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.IO.FileSystem/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.IO": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Handles": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.Primitives/4.3.0": { + "dependencies": { + "System.Runtime": "4.3.1" + } + }, + "System.Linq/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0" + } + }, + "System.Linq.Expressions/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Linq": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Emit.Lightweight": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Net.Http/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.DiagnosticSource": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Extensions": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.OpenSsl": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.Net.Http": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Net.Primitives/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Net.Sockets/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.IO": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Runtime": "4.3.1", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.ObjectModel/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Threading": "4.3.0" + } + }, + "System.Reflection/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Reflection.Emit/4.3.0": { + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Reflection.Emit.ILGeneration/4.3.0": { + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Reflection.Emit.Lightweight/4.3.0": { + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Reflection.Extensions/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Reflection.Primitives/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Reflection.TypeExtensions/4.3.0": { + "dependencies": { + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Resources.ResourceManager/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.1" + } + }, + "System.Runtime/4.3.1": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3" + } + }, + "System.Runtime.Extensions/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Runtime.Handles/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Runtime.InteropServices/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Reflection": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Runtime.InteropServices.RuntimeInformation/4.3.0": { + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.InteropServices": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0" + } + }, + "System.Runtime.Numerics/4.3.0": { + "dependencies": { + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0" + } + }, + "System.Security.Cryptography.Algorithms/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Collections": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.Apple": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.Cng/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Security.Cryptography.Csp/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Collections": "4.3.0", + "System.Collections.Concurrent": "4.3.0", + "System.Linq": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.OpenSsl/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.Primitives/4.3.0": { + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Security.Cryptography.X509Certificates/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Calendars": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Cng": "4.3.0", + "System.Security.Cryptography.Csp": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.OpenSsl": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.Net.Http": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Text.Encoding/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Text.Encoding.Extensions/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Text.RegularExpressions/4.3.0": { + "dependencies": { + "System.Runtime": "4.3.1" + } + }, + "System.Threading/4.3.0": { + "dependencies": { + "System.Runtime": "4.3.1", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Tasks/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Threading.Tasks.Extensions/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Runtime": "4.3.1", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Timer/4.3.0": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.1", + "Microsoft.NETCore.Targets": "1.1.3", + "System.Runtime": "4.3.1" + } + }, + "System.Xml.ReaderWriter/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Text.RegularExpressions": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Tasks.Extensions": "4.3.0" + } + }, + "System.Xml.XDocument/4.3.0": { + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tools": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.1", + "System.Runtime.Extensions": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0" + } + } + } + }, + "libraries": { + "MultiboxMutexer/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "DalamudPackager/2.1.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YqagNXs9InxmqkXzq7kLveImxnodkBEicAhydMXVp7dFjC7xb76U6zGgAax4/BWIWfZeWzr5DJyQSev31kj81A==", + "path": "dalamudpackager/2.1.8", + "hashPath": "dalamudpackager.2.1.8.nupkg.sha512" + }, + "Fody/6.6.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vLZS+oa+ndUHYPlx/8n9bBTT3dHkCF0riml4paKq4D663+cZd47x1uagQo32D/gKFZ/sfmV1oqKaLmH0elxq4A==", + "path": "fody/6.6.4", + "hashPath": "fody.6.6.4.nupkg.sha512" + }, + "Microsoft.NETCore.Platforms/1.1.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==", + "path": "microsoft.netcore.platforms/1.1.1", + "hashPath": "microsoft.netcore.platforms.1.1.1.nupkg.sha512" + }, + "Microsoft.NETCore.Targets/1.1.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==", + "path": "microsoft.netcore.targets/1.1.3", + "hashPath": "microsoft.netcore.targets.1.1.3.nupkg.sha512" + }, + "Microsoft.Win32.Primitives/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==", + "path": "microsoft.win32.primitives/4.3.0", + "hashPath": "microsoft.win32.primitives.4.3.0.nupkg.sha512" + }, + "NETStandard.Library/1.6.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-WcSp3+vP+yHNgS8EV5J7pZ9IRpeDuARBPN28by8zqff1wJQXm26PVU8L3/fYLBJVU7BtDyqNVWq2KlCVvSSR4A==", + "path": "netstandard.library/1.6.1", + "hashPath": "netstandard.library.1.6.1.nupkg.sha512" + }, + "Resourcer.Fody/1.8.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/zF71VIAPOQCoNefZJohrYs4xc7Sm0H5Em2iecS6d1kaLphlh82RVtN/wfNjieURXJqClIIazYTLnRKUiv8oPw==", + "path": "resourcer.fody/1.8.0", + "hashPath": "resourcer.fody.1.8.0.nupkg.sha512" + }, + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q==", + "path": "runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA==", + "path": "runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw==", + "path": "runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.native.System/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==", + "path": "runtime.native.system/4.3.0", + "hashPath": "runtime.native.system.4.3.0.nupkg.sha512" + }, + "runtime.native.System.IO.Compression/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==", + "path": "runtime.native.system.io.compression/4.3.0", + "hashPath": "runtime.native.system.io.compression.4.3.0.nupkg.sha512" + }, + "runtime.native.System.Net.Http/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==", + "path": "runtime.native.system.net.http/4.3.0", + "hashPath": "runtime.native.system.net.http.4.3.0.nupkg.sha512" + }, + "runtime.native.System.Security.Cryptography.Apple/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==", + "path": "runtime.native.system.security.cryptography.apple/4.3.0", + "hashPath": "runtime.native.system.security.cryptography.apple.4.3.0.nupkg.sha512" + }, + "runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==", + "path": "runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A==", + "path": "runtime.opensuse.13.2-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.opensuse.13.2-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ==", + "path": "runtime.opensuse.42.1-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.opensuse.42.1-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ==", + "path": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.apple/4.3.0", + "hashPath": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.apple.4.3.0.nupkg.sha512" + }, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g==", + "path": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg==", + "path": "runtime.rhel.7-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.rhel.7-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ==", + "path": "runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A==", + "path": "runtime.ubuntu.16.04-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.ubuntu.16.04-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==", + "path": "runtime.ubuntu.16.10-x64.runtime.native.system.security.cryptography.openssl/4.3.0", + "hashPath": "runtime.ubuntu.16.10-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "System.AppContext/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==", + "path": "system.appcontext/4.3.0", + "hashPath": "system.appcontext.4.3.0.nupkg.sha512" + }, + "System.Buffers/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ratu44uTIHgeBeI0dE8DWvmXVBSo4u7ozRZZHOMmK/JPpYyo0dAfgSiHlpiObMQ5lEtEyIXA40sKRYg5J6A8uQ==", + "path": "system.buffers/4.3.0", + "hashPath": "system.buffers.4.3.0.nupkg.sha512" + }, + "System.Collections/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "path": "system.collections/4.3.0", + "hashPath": "system.collections.4.3.0.nupkg.sha512" + }, + "System.Collections.Concurrent/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==", + "path": "system.collections.concurrent/4.3.0", + "hashPath": "system.collections.concurrent.4.3.0.nupkg.sha512" + }, + "System.Console/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==", + "path": "system.console/4.3.0", + "hashPath": "system.console.4.3.0.nupkg.sha512" + }, + "System.Diagnostics.Debug/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==", + "path": "system.diagnostics.debug/4.3.0", + "hashPath": "system.diagnostics.debug.4.3.0.nupkg.sha512" + }, + "System.Diagnostics.DiagnosticSource/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==", + "path": "system.diagnostics.diagnosticsource/4.3.0", + "hashPath": "system.diagnostics.diagnosticsource.4.3.0.nupkg.sha512" + }, + "System.Diagnostics.Tools/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==", + "path": "system.diagnostics.tools/4.3.0", + "hashPath": "system.diagnostics.tools.4.3.0.nupkg.sha512" + }, + "System.Diagnostics.Tracing/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==", + "path": "system.diagnostics.tracing/4.3.0", + "hashPath": "system.diagnostics.tracing.4.3.0.nupkg.sha512" + }, + "System.Globalization/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==", + "path": "system.globalization/4.3.0", + "hashPath": "system.globalization.4.3.0.nupkg.sha512" + }, + "System.Globalization.Calendars/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==", + "path": "system.globalization.calendars/4.3.0", + "hashPath": "system.globalization.calendars.4.3.0.nupkg.sha512" + }, + "System.Globalization.Extensions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==", + "path": "system.globalization.extensions/4.3.0", + "hashPath": "system.globalization.extensions.4.3.0.nupkg.sha512" + }, + "System.IO/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "path": "system.io/4.3.0", + "hashPath": "system.io.4.3.0.nupkg.sha512" + }, + "System.IO.Compression/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==", + "path": "system.io.compression/4.3.0", + "hashPath": "system.io.compression.4.3.0.nupkg.sha512" + }, + "System.IO.Compression.ZipFile/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-G4HwjEsgIwy3JFBduZ9quBkAu+eUwjIdJleuNSgmUojbH6O3mlvEIme+GHx/cLlTAPcrnnL7GqvB9pTlWRfhOg==", + "path": "system.io.compression.zipfile/4.3.0", + "hashPath": "system.io.compression.zipfile.4.3.0.nupkg.sha512" + }, + "System.IO.FileSystem/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==", + "path": "system.io.filesystem/4.3.0", + "hashPath": "system.io.filesystem.4.3.0.nupkg.sha512" + }, + "System.IO.FileSystem.Primitives/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==", + "path": "system.io.filesystem.primitives/4.3.0", + "hashPath": "system.io.filesystem.primitives.4.3.0.nupkg.sha512" + }, + "System.Linq/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==", + "path": "system.linq/4.3.0", + "hashPath": "system.linq.4.3.0.nupkg.sha512" + }, + "System.Linq.Expressions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==", + "path": "system.linq.expressions/4.3.0", + "hashPath": "system.linq.expressions.4.3.0.nupkg.sha512" + }, + "System.Net.Http/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==", + "path": "system.net.http/4.3.0", + "hashPath": "system.net.http.4.3.0.nupkg.sha512" + }, + "System.Net.Primitives/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==", + "path": "system.net.primitives/4.3.0", + "hashPath": "system.net.primitives.4.3.0.nupkg.sha512" + }, + "System.Net.Sockets/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-m6icV6TqQOAdgt5N/9I5KNpjom/5NFtkmGseEH+AK/hny8XrytLH3+b5M8zL/Ycg3fhIocFpUMyl/wpFnVRvdw==", + "path": "system.net.sockets/4.3.0", + "hashPath": "system.net.sockets.4.3.0.nupkg.sha512" + }, + "System.ObjectModel/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==", + "path": "system.objectmodel/4.3.0", + "hashPath": "system.objectmodel.4.3.0.nupkg.sha512" + }, + "System.Reflection/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "path": "system.reflection/4.3.0", + "hashPath": "system.reflection.4.3.0.nupkg.sha512" + }, + "System.Reflection.Emit/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==", + "path": "system.reflection.emit/4.3.0", + "hashPath": "system.reflection.emit.4.3.0.nupkg.sha512" + }, + "System.Reflection.Emit.ILGeneration/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==", + "path": "system.reflection.emit.ilgeneration/4.3.0", + "hashPath": "system.reflection.emit.ilgeneration.4.3.0.nupkg.sha512" + }, + "System.Reflection.Emit.Lightweight/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==", + "path": "system.reflection.emit.lightweight/4.3.0", + "hashPath": "system.reflection.emit.lightweight.4.3.0.nupkg.sha512" + }, + "System.Reflection.Extensions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==", + "path": "system.reflection.extensions/4.3.0", + "hashPath": "system.reflection.extensions.4.3.0.nupkg.sha512" + }, + "System.Reflection.Primitives/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "path": "system.reflection.primitives/4.3.0", + "hashPath": "system.reflection.primitives.4.3.0.nupkg.sha512" + }, + "System.Reflection.TypeExtensions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==", + "path": "system.reflection.typeextensions/4.3.0", + "hashPath": "system.reflection.typeextensions.4.3.0.nupkg.sha512" + }, + "System.Resources.ResourceManager/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==", + "path": "system.resources.resourcemanager/4.3.0", + "hashPath": "system.resources.resourcemanager.4.3.0.nupkg.sha512" + }, + "System.Runtime/4.3.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", + "path": "system.runtime/4.3.1", + "hashPath": "system.runtime.4.3.1.nupkg.sha512" + }, + "System.Runtime.Extensions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==", + "path": "system.runtime.extensions/4.3.0", + "hashPath": "system.runtime.extensions.4.3.0.nupkg.sha512" + }, + "System.Runtime.Handles/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==", + "path": "system.runtime.handles/4.3.0", + "hashPath": "system.runtime.handles.4.3.0.nupkg.sha512" + }, + "System.Runtime.InteropServices/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==", + "path": "system.runtime.interopservices/4.3.0", + "hashPath": "system.runtime.interopservices.4.3.0.nupkg.sha512" + }, + "System.Runtime.InteropServices.RuntimeInformation/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==", + "path": "system.runtime.interopservices.runtimeinformation/4.3.0", + "hashPath": "system.runtime.interopservices.runtimeinformation.4.3.0.nupkg.sha512" + }, + "System.Runtime.Numerics/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==", + "path": "system.runtime.numerics/4.3.0", + "hashPath": "system.runtime.numerics.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.Algorithms/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "path": "system.security.cryptography.algorithms/4.3.0", + "hashPath": "system.security.cryptography.algorithms.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.Cng/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==", + "path": "system.security.cryptography.cng/4.3.0", + "hashPath": "system.security.cryptography.cng.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.Csp/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==", + "path": "system.security.cryptography.csp/4.3.0", + "hashPath": "system.security.cryptography.csp.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.Encoding/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==", + "path": "system.security.cryptography.encoding/4.3.0", + "hashPath": "system.security.cryptography.encoding.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.OpenSsl/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==", + "path": "system.security.cryptography.openssl/4.3.0", + "hashPath": "system.security.cryptography.openssl.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.Primitives/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==", + "path": "system.security.cryptography.primitives/4.3.0", + "hashPath": "system.security.cryptography.primitives.4.3.0.nupkg.sha512" + }, + "System.Security.Cryptography.X509Certificates/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "path": "system.security.cryptography.x509certificates/4.3.0", + "hashPath": "system.security.cryptography.x509certificates.4.3.0.nupkg.sha512" + }, + "System.Text.Encoding/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "path": "system.text.encoding/4.3.0", + "hashPath": "system.text.encoding.4.3.0.nupkg.sha512" + }, + "System.Text.Encoding.Extensions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==", + "path": "system.text.encoding.extensions/4.3.0", + "hashPath": "system.text.encoding.extensions.4.3.0.nupkg.sha512" + }, + "System.Text.RegularExpressions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==", + "path": "system.text.regularexpressions/4.3.0", + "hashPath": "system.text.regularexpressions.4.3.0.nupkg.sha512" + }, + "System.Threading/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==", + "path": "system.threading/4.3.0", + "hashPath": "system.threading.4.3.0.nupkg.sha512" + }, + "System.Threading.Tasks/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "path": "system.threading.tasks/4.3.0", + "hashPath": "system.threading.tasks.4.3.0.nupkg.sha512" + }, + "System.Threading.Tasks.Extensions/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-npvJkVKl5rKXrtl1Kkm6OhOUaYGEiF9wFbppFRWSMoApKzt2PiPHT2Bb8a5sAWxprvdOAtvaARS9QYMznEUtug==", + "path": "system.threading.tasks.extensions/4.3.0", + "hashPath": "system.threading.tasks.extensions.4.3.0.nupkg.sha512" + }, + "System.Threading.Timer/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==", + "path": "system.threading.timer/4.3.0", + "hashPath": "system.threading.timer.4.3.0.nupkg.sha512" + }, + "System.Xml.ReaderWriter/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==", + "path": "system.xml.readerwriter/4.3.0", + "hashPath": "system.xml.readerwriter.4.3.0.nupkg.sha512" + }, + "System.Xml.XDocument/4.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==", + "path": "system.xml.xdocument/4.3.0", + "hashPath": "system.xml.xdocument.4.3.0.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/MultiboxMutexer/MultiboxMutexer.dll b/.recovery/extract/MultiboxMutexer/MultiboxMutexer.dll new file mode 100644 index 0000000..2319e18 Binary files /dev/null and b/.recovery/extract/MultiboxMutexer/MultiboxMutexer.dll differ diff --git a/.recovery/extract/MultiboxMutexer/MultiboxMutexer.json b/.recovery/extract/MultiboxMutexer/MultiboxMutexer.json new file mode 100644 index 0000000..edad241 --- /dev/null +++ b/.recovery/extract/MultiboxMutexer/MultiboxMutexer.json @@ -0,0 +1,16 @@ +{ + "Author": "aRkker", + "Name": "Multibox Mutexer", + "InternalName": "MultiboxMutexer", + "AssemblyVersion": "1.0.1.2", + "Description": "This plugin does magic to release the mutexes held by XIV to prevent more than 2 game instances launching", + "ApplicableVersion": "any", + "Tags": [ + "other", + "social" + ], + "DalamudApiLevel": 8, + "LoadPriority": 0, + "Punchline": "Let there be more than 2 instances of game", + "Changelog": "0.0.0.1 Initial release" +} \ No newline at end of file diff --git a/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.deps.json b/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.deps.json new file mode 100644 index 0000000..b80d238 --- /dev/null +++ b/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "OmicronMountMusicFixer/1.0.0": { + "runtime": { + "OmicronMountMusicFixer.dll": {} + } + } + } + }, + "libraries": { + "OmicronMountMusicFixer/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.dll b/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.dll new file mode 100644 index 0000000..00b29ed Binary files /dev/null and b/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.dll differ diff --git a/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.json b/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.json new file mode 100644 index 0000000..14648e4 --- /dev/null +++ b/.recovery/extract/OmicronMountMusicFixer/OmicronMountMusicFixer.json @@ -0,0 +1,20 @@ +{ + "Author": "aRkker", + "Name": "Omicron music enabler", + "InternalName": "OmicronMountMusicFixer", + "AssemblyVersion": "1.0.7.0", + "Description": "This plugin swaps the Miiw Miisv mount music to the Elysion theme from the Omicron beast tribe dailies. I found that this should have been the music from the get-go, but alas it wasnt. Now, with this plugin, it can be so", + "ApplicableVersion": "any", + "Tags": [ + "other", + "social" + ], + "DalamudApiLevel": 14, + "LoadRequiredState": 0, + "LoadSync": false, + "CanUnloadAsync": false, + "LoadPriority": 0, + "Punchline": "Swap the Miiw Miisv music for Cradle of Hope", + "Changelog": "1.0.4.2\nPVP stuff\n1.0.2.0\n6.4 fixes\n1.0.1.0\nPreliminary version for 6.3. Probably broken", + "AcceptsFeedback": true +} \ No newline at end of file diff --git a/.recovery/extract/OmicronMountMusicFixer/xiv_bgm.csv b/.recovery/extract/OmicronMountMusicFixer/xiv_bgm.csv new file mode 100644 index 0000000..4508e09 --- /dev/null +++ b/.recovery/extract/OmicronMountMusicFixer/xiv_bgm.csv @@ -0,0 +1,1150 @@ +"ID","Title","Alt Title","Special Mode Title","Locations","Comments" +"0","None","","","","" +"1","None","","","","Empty sound" +"2","Prelude - Rebirth","","","A Realm Reborn title","" +"3","Dreams Aloft","","","Cid cutscenes","Old launcher theme, from 1.0" +"4","Prelude - Discoveries","","","Character Select & Creation","" +"5","Behind Closed Doors","","","Inn theme","" +"6","Wailers and Waterwheels","","","Gridania (day)","" +"7","Dance of the Fireflies","","","Gridania (night)","" +"8","Serenity","","","Central/North Shroud","" +"9","Serenity","","","Black Shroud sanctuaries","" +"10","Serenity","","","The Black Shroud","" +"11","Serenity","","","South Shroud","" +"12","Serenity","","","Sanctum of the Twelve","" +"13","The Land Bends","","","The Black Shroud combat","" +"14","Tenacity","","","Leves","" +"15","Slumber Disturbed","","","The Tam-Tara Deepcroft","" +"16","The Promise of Plunder","","","Early ARR Dungeons","" +"17","The Dark's Embrace","","The Dark's Kiss","ARR HM Dungeons","" +"18","Victory!","","","End of most instances","" +"19","","","","","" +"20","Victory!","","","End of most instances","No vocals 21" +"21","Victory!","","","End of most instances","" +"22","???","","","Frontlines","Gate open theme" +"23","The Hero of Hatchingtide","","","","Chiptune version of 21 (Victory)" +"24","Greenwrath","","","East Shroud","" +"25","I Am the Sea","","","Limsa Lominsa (day)","" +"26","A Sailor Never Sleeps","","","Limsa Lominsa","" +"27","On Westerly Winds","","","Middle/Lower La Noscea","" +"28","On Westerly Winds","","","La Noscea","" +"29","On Westerly Winds","","","Eastern La Noscea","" +"30","On Westerly Winds","","","Eastern La Noscea","" +"31","On Westerly Winds","","","La Noscean sanctuaries","" +"32","Currents","","","La Noscea","" +"33","The Land Breathes","","","La Noscea combat","" +"34","","","","","" +"35","From the Depths","","","Sastasha","" +"36","Torn from the Heavens","","","Various","" +"37","A Fine Death","","","ARR Dungeon bosses","" +"38","Nemesis","","","ARR Dungeon final bosses","" +"39","Pennons Aloft","","","Instanced battles","" +"40","Brothers in Arms","","","Guildhests","" +"41","The Maiden's Lament","","","Haukke Manor","" +"42","A Thousand Screams","","","The Thousand Maws of Toto-Rak","" +"43","Lipflaps on Longstops","","","Brayflox's Longstop","" +"44","A New Hope","","","Ul'dah (day)","" +"45","Sultana Dreaming","","","Ul'dah (night)","" +"46","To the Sun","","","Western/Central Thanalan","" +"47","To the Sun","","","Thanalan","" +"48","To the Sun","","","Southern Thanalan","" +"49","To the Sun","","","Thanalan sanctuaries","" +"50","To the Sun","","","Thanalan","" +"51","Fleeting Rays","","","Eastern Thanalan","" +"52","The Land Burns","","","Thanalan combat","" +"53","Below","","","Copperbell Mines","" +"54","The Ludus","","","Halatali","" +"55","The Gift of Life","","","ARR Sanctuaries","" +"56","Calling","","","","" +"57","Discordance","","","Northern Thanalan","" +"58","Beyond the Unknown","","","Cutscene (Edda)","Very short" +"59","Slither","","","Northern Thanalan outskirts","Very short and sounds similar to Discordance" +"60","Intertwined","","","Mor Dhona","" +"61","Bo-down","","","Chocobo porters","" +"62","Eorzea de Chocobo","Born to Ride","","Chocobo mounts","" +"63","Into the Adder's Den","","","Twin Adder command","" +"64","Maelstrom Command","","","Maelstrom command","" +"65","The Hall of Flames","","","Immortal Flames command","" +"66","The Waking Sands","","","Western Thanalan","" +"67","When a Tree Falls","","","Leves","" +"68","The Tug of Fate","","","Certain FATEs","" +"69","To the Fore","","","Certain FATEs/Boss battles","" +"70","Whisper of the Land","","","Cutscenes (1.0)","" +"71","On Windy Meadows","","","Cutscenes (1.0)","" +"72","Twilight Over Thanalan","","","Cutscenes (1.0)","" +"73","Dewdrops & Moonbeams","","","The Lotus Stand (Kan-E-Senna)","" +"74","The Sands' Secrets","","","Eorzean Alliance (Raubahn)","" +"75","Ripples in the Sea","","","Eorzean Alliance (Merlwyb)","" +"76","Imperial Will","","","Cutscenes (Empire)","" +"77","Defender of the Realm","","","Cutscenes (Heroic)","" +"78","Fracture","","","Cutscenes (Suspense)","" +"79","One Blood","","","Cutscenes (Tension)","" +"80","Conundrum","","","Cutscenes (Mysterious/Hildibrand)","" +"81","Prelude - Rebirth","","","Cutscenes","Remix with a slightly different harp" +"82","Return of the Hero","","","Cutscenes (Resolution)","" +"83","Kiss of Chaos","","","Cutscenes (Tension)","" +"84","Forever Lost","","","Cutscenes (Sad)","" +"85","Machinations","","","Wolves' Den / Northern Thanalan Sanctuaries","" +"86","The Only Path","","","Cutscenes (Positive)","" +"87","Daring Dalliances","","","Cutscenes (Positive)","" +"88","Bliss","","","Cutscenes (Comedic)","" +"89","A World Apart","","","Cutscenes (Heroic)","" +"90","Relics","","","Cutscenes (esp. Job quests)","" +"91","Breaking Boundaries","","","Job quest battles","" +"92","The Echo","","","Cutscenes","" +"93","Tranquility","","","Cutscenes (Resolution)","" +"94","Without Shadow","","","Cutscenes (Ascians)","" +"95","The Seventh Sun / Dawn of a New Era","","","Cutscenes","Opens with The Seventh Sun, transitions to Dawn of a New Era" +"96","Sacred Bonds","","","Cutscenes (Sad)","" +"97","Canticle","","","Cutscenes (Exposition)","" +"98","Where the Heart Is","","","Cutscenes (Resolution)","1.0 track" +"99","Dreams Aloft","","","Cutscenes (Resolution)","" +"100","Supply & Demand","","","Cutscenes (Comedic)","1.0 track" +"101","By Design","","","Cutscenes (Comedic)","1.0 track" +"102","Decisions","","","Cutscenes (Mysterious), Little Ladies' Day","1.0 track" +"103","Agent of Inquiry","","","Hildibrand Theme","" +"104","","","","","" +"105","Nature's Bounty","","","Cutscenes, Eternal Bonding","1.0 track" +"106","Falling Shards","","","Various, Eternal Bonding","Harp-only version of Prelude" +"107","Pennons Aloft","","","Instanced battles, Fenrir battle","1.0 track" +"108","Battle Theme 1.x","","","Hildibrand FATEs/Hall of the Novice/B-ranks","" +"109","","","","","" +"110","Salt Swept","","","Aleport/Moraby Drydocks","" +"111","???","","","","Needs location & name, is an early unused version of A Reason To Live" +"112","My Soul to Keep","","","Haukke Manor/Tam-Tara HM","" +"113","From Fear to Fortitude","","","Instanced battles","" +"114","Damnation","","","Cutscenes (Suspense)","" +"115","Hard to Miss","","","Boss FATEs","" +"116","A Fell Air Falleth","","","Later ARR Dungeons","" +"117","Skullduggery","","","Instanced battles/Qarn HM","" +"118","Another Round","","","Bars and Taverns","" +"119","Ruby Sunrise","","","Costa del Sol","" +"120","Primal Judgement","","","The Bowl of Embers","" +"121","The Rider's Boon","","","ARR mounts","" +"122","Cracks in the Wall","","","Amdapor Keep","" +"123","A Tonberry's Tears","","","The Wanderer's Palace","" +"124","Echoes of Ages Past","","","The Sunken Temple of Qarn","" +"125","Abomination","","","Cutter's Cry","" +"126","Cold Salvation","","","The Stone Vigil","" +"127","The Darkhold","","","Dzemael Darkhold","" +"128","Miser's Folly","","","The Aurum Vale","" +"129","Engage","","","The Enterprise","" +"130","Fever Dream","","","Cutscenes (Tension)","Excerpt from a longer 1.0 track" +"131","Serving the Light","","","Warrior of Light","" +"132","Answers","","","ARR End Credits","" +"133","Opening Theme","","","ARR End Credits Special/1.0 players","1.0 ending" +"134","A Curious Breed of Botherment","","","East Shroud (Sylphs)","" +"135","Flightless Wings","","","North Shroud (Ixals)","" +"136","Quick as Silver, Hard as Stone","","","Outer La Noscea (Kobolds)","" +"137","Battle Drums","","","Western La Noscea (Sahagin)","1.0 track" +"138","Pitfire","","","Southern Thanalan (Amal'jaa)","1.0 track" +"139","","","","","" +"140","","","","","" +"141","Fealty","","","Coerthas Central Highlands","" +"142","The Dragon's Dirge","","","Coerthas Central Highlands (Whitebrim)","" +"143","Undying Faith","","","Coerthas Central Highlands (Observatorium)","" +"144","The Land Breaks","","","Coerthas Central Highlands battle","" +"145","The Land Bleeds","","","Mor Dhona battle","" +"146","Primal Timbre","","Spiral","The Binding Coil of Bahamut","" +"147","Calamity Unbound","","","The Binding Coil of Bahamut bosses","" +"148","The Emperor's Wont","","","Imperial Castrums","" +"149","Penitus","","","The Praetorium","" +"150","Ultima","","","Ultima Weapon Phase 2","" +"151","Steel Reason","","","Cape Westwind/Garlean boss fights","" +"152","Bite of the Black Wolf","","","Gaius van Baelsar theme","Rise of the White Raven (199) with no vocals" +"153","The Corpse Hall","","","Odin FATE","" +"154","Thunderer","","","Special FATEs","" +"155","Fallen Angel","","","The Howling Eye","" +"156","Under the Weight","","","The Navel (Titan) phase 5","" +"157","Weight of a Whisper","","","The Navel (Titan) phase 1","" +"158","Weight of His Will","","","The Navel (Titan) phase 2","" +"159","Weight of the World","","","The Navel (Titan) phase 3","" +"160","Heartless","","","The Navel (Titan) phase 4","" +"161","Flight","","","Ultima Escape","" +"162","The Maker's Ruin","","","Ultima Weapon Phase 1","" +"163","Blinded by Light","","","FFXIII crossover FATEs","Directly from FFXIII" +"164","Saber's Edge","","","FFXIII crossover FATEs","Directly from FFXIII" +"165","Torn from the Heavens","","","ARR Zone special FATEs/ARR Relic duties","1.0 Track" +"166","Ruby Moonrise","","","Costa del Sol events","Fast ""Costa Del Sol"" music" +"167","Serenity","","","The Shroud","" +"168","On Westerly Winds","","","La Noscea","" +"169","To the Sun","","","Thanalan","" +"170","Crystal Rain","","","Mor Dhona","" +"171","To the Fore","","","Heavensward dungeon boss theme","The filename seems to imply this is from a FATE" +"172","The Rider's Boon","","","Generic ARR Mounts","Also the 1.0 Goobbue theme" +"173","Thunderer","","","Ascian battles, Twintania","" +"174","All Saints' Wake","","","Seasonal event BGM areas","" +"175","Starlight Celebration","","","Seasonal event BGM areas","" +"176","Heavensturn","","","Seasonal event BGM areas","" +"177","Reign of Pain","","","Shantotto theme (FFXI event)","" +"178","The Seven Jesters","","","Thornmarch Phase 1","" +"179","Good King Moggle Mog XII","","","Thornmarch Phase 2","" +"180","Hubris","","Ever Upwards","Labyrinth of the Ancients","" +"181","Tumbling Down","","","Labyrinth of the Ancients boss theme","" +"182","Agent of Inquiry","","","Hildibrand episode theme","" +"183","Frontiers Within","","","Revenant's Toll (day)","" +"184","Reflections","","","Revenant's Toll (night)","" +"185","A Light in the Storm","","","Pharos Sirius","" +"186","Where the Heart Is","","","The Mist, The Lavender Beds, The Goblet (day)","" +"187","Where the Hearth Is","","","The Mist, The Lavender Beds, The Goblet (night)","" +"188","Flibbertigibbet","","","East Shroud (Friendly Sylph area)","" +"189","Smoulder","","","Southern Thanalan (Friendly Amalj'aa area)","" +"190","Discordance","","","Cutscenes (Mysterious)","Loops. See track 57, Discordance" +"191","Starlight and Sellswords","","","Aesthetician","1.0 track" +"192","Battle Theme 1.x","","","Hildibrand FATEs/Hall of the Novice/B-ranks","" +"193","Big-Boned","","","Fat Chocobo Theme","" +"194","Gluppity-Schlopp","","","Outer La Noscea (Friendly Kobold area)","" +"195","Breathless","","","Western La Noscea (Friendly Sahagin area)","" +"196","Pa-Paya","","","Seasonal event BGM areas (Hatching-tide)","" +"197","The Scars of Battle","","","Lost City of Amdapor","" +"198","Tempest","","","The Second Coil of Bahamut (Turn 4) (Nael deus Darnus) phase 1","" +"199","Rise of the White Raven","","","The Second Coil of Bahamut (Turn 4) (Nael deus Darnus) phase 2","" +"200","Good King Moggle Mog XII","","","Thornmarch (Good King Moggle Mog XII) phase 2","" +"201","Battle on the Big Bridge","","","Battle on the Big Bridge (Gilgamesh)","" +"202","Blades","","Spiral","Second Coil/Final Coil trash music","" +"203","Wreck to the Seaman","","","The Whorleater (Leviathan) phase 1","" +"204","Through The Maelstrom","","","The Whorleater (Leviathan) phase 2","" +"205","Meteor","","","Cutscenes (Nael)","" +"206","Persistence","","","ARR mid-dungeon boss theme","" +"207","Wrath of the Eikons","","","The Lost City of Amdapor final boss / Dun Scaith final boss (Diabolos / Diabolos Hollow)","" +"208","Fury","","","Brayflox's Longstop (Hard) boss","1.0 track" +"209","Beneath Bloodied Banners","","","Hard mode dungeon final bosses","" +"210","Birds of a Feather","","","Halatali (Hard)","1.0 track" +"211","Thicker Than a Knife's Blade","","","Various cutscenes, Foundation (The Forgotten Knight)","" +"212","Now I Know the Truth","","","Unei and Doga theme","" +"213","???","","","Seasonal event BGM areas","China lunar new year theme, needs name" +"214","Moonfire Faire","","","Moonfire Faire","" +"215","Far from Home","","","Ixal theme","" +"216","Horizons Calling","","","Hullbreaker Isle","" +"217","Dark Vows","","","Tam-Tara Deepcroft (Hard)","" +"218","Out of the Labyrinth","","Shattered","The Syrcus Tower","" +"219","The War Room","","","Frontlines","Gate waiting theme" +"220","Rouse Out!","","Blood for Blood","Frontlines","" +"221","Thunder Rolls","","","The Striking Tree (Ramuh)","" +"222","Game Theory","","","Puzzles/Minigames Theme","" +"223","Loss of Time","","","Cutscenes (Crystal tower)","" +"224","Or the Egg","","","Chocobo training montage","" +"225","His Holiness","The Dragon's Dirge","","Cutscenes (Thordan)","" +"226","Answers - Reprise","","","Ul'dah (The Rising)","" +"227","The Corpse Hall","","","Urth's Fount","" +"228","Everbinding Oath","","","Eternal Bond ceremony","" +"229","The Edge","","","Ninja trainer hideout","" +"230","Footsteps in the Snow","","","Akh Afah Amphitheatre (Shiva) phase 1, Eden's Verse: Refulgence (Savage) (Shiva) phase 1","" +"231","Oblivion","","","Akh Afah Amphitheatre (Shiva) phase 2","" +"232","The Decisive Battle","","","The Dragon's Neck","Directly from FFVI" +"233","The Warrens","","","Snowcloak","" +"234","Forgotten by the Sun","","","The Sunken Temple of Qarn (Hard)","" +"235","Riptide","","","Sastasha (Hard)","" +"236","From the Ashes","","","The Final Coil of Bahamut (Turn 3) (Phoenix)","" +"237","Answers","","","The Final Coil of Bahamut (Turn 4) (Bahamut Prime)","Harp / vocals portion" +"238","Answers","","","The Final Coil of Bahamut (Turn 4) (Bahamut Prime)","Band / vocals portion" +"239","The Coil Tightens","","","Cutscenes (The Binding Coil of Bahamut)","" +"240","Answers","","","The Final Coil of Bahamut (Turn 4) (Bahamut Prime)","Chorus portion" +"241","Eternal Wind","","","Cutscenes (Crystal tower)","" +"242","Battle on the Big Bridge","","","Battle in the Big Keep Phase 1","Directly from FFV" +"243","Silver Tears","","","The Keeper of the Lake","" +"244","Primogenitor","","","The Keeper of the Lake final boss (Midgardsormr), Alphascape v2.0 (Midgardsormr)","Generally just Midgardsormr's theme" +"245","Tricksome","","","Wanderer's Palace (Hard)","" +"246","Aftermath","","","Amdapor Keep (Hard)","" +"247","Blind to the Dark","","Hamartomania","The World of Darkness","" +"248","Tumbling Down","","","The World of Darkness (Cerberus Stomach)","Muffled" +"249","Hunger / The Reach of Darkness","","","The World of Darkness","Hunger into ""The Reach of Darkness""" +"250","Four-Sided Circle","","","Manderville Gold Saucer","" +"251","Gateway to Paradise","","","Chocobo racing 1","" +"252","Sport of Kings","","","Chocobo racing 2","" +"253","Shuffle or Boogie","","","Triple Triad","Directly from FFVIII" +"254","Faith in Her Fury","","","The Steps of Faith","" +"255","Unworthy","","","The Steps of Faith final gate theme","" +"256","The Tug of Fate","","","The Wanderer's Palace (Hard) bosses","1.0 Hamlet defense track" +"257","To the Fore","","","The Wanderer's Palace (Hard) final boss","" +"258","Chocobo Victory 1","","","Chocobo racing","" +"259","Chocobo Victory 2","","","Chocobo racing","" +"260","Chocobo Victory 3","","","Chocobo racing","" +"261","Drum Roll","","","Chocobo racing","" +"262","Magiteknical Difficulties","","","Magitek Armor mount","Terra's Theme (FFVI) remix" +"263","The Corpse Hall","","","Sleipnir mount","" +"264","Oblivion","","","Akh Afah Amphitheatre (Extreme) (Shiva) mount","" +"265","Thunder Rolls","","","The Striking Tree (Extreme) (Ramuh) mount","" +"266","Through The Maelstorm","","","The Whorleater (Extreme) (Leviathan) mount","" +"267","Under the Weight","","","The Navel (Extreme) (Titan) mount","" +"268","Fallen Angel","","","The Howling Eye (Extreme) (Garuda) mount","" +"269","Primal Judgement","","","The Bowl of Embers (Extreme) (Ifrit) mount","" +"270","Null BGM","","","","Empty sound" +"271","A Cold Wind","","","Heavensward title screen","" +"272","Dragonsong","","","Heavensward credits","" +"273","Shelter","","","Heavensward sanctuary music","" +"274","Safety In Numbers","","","Heavensward sanctuary music 2","" +"275","Nobility Obliges","","","The Pillars (day)","" +"276","Nobility Sleeps","","","The Pillars (night)","" +"277","Solid","","","The Foundation (day)","" +"278","Night in the Brume","","","The Foundation (night)","" +"279","Against the Wind","","","Coerthas Western Highlands (day)","" +"280","Black and White","","","Coerthas Western Highlands (night)","" +"281","Melt","","","Coerthas Western Highlands combat","All ""Melt"" are the same track" +"282","Painted Foothills","","","Dravanian Forelands (day)","" +"283","Painted Skies","","","Dravanian Forelands (night)","" +"284","Melt","","","Dravanian Forelands combat","All ""Melt"" are the same track" +"285","Missing Pages","","","Dravanian Hinterlands (day)","" +"286","The Silent Regard of Stars","","","Dravanian Hinterlands (night)","" +"287","Melt","","","Dravanian Hinterlands combat","All ""Melt"" are the same track" +"288","Landlords","","","Churning Mists (day)","" +"289","Skylords","","","Churning Mists (night)","" +"290","Melt","","","Churning Mists combat","All ""Melt"" are the same track" +"291","Lost in the Clouds","","","Sea of Clouds (day)","" +"292","Close to the Heavens","","","Sea of Clouds (night)","" +"293","Melt","","","Sea of Clouds combat","All ""Melt"" are the same track" +"294","Order Yet Undeciphered","","","Azys Lla","" +"295","Melt","","","Azys Lla combat","All ""Melt"" are the same track" +"296","Paradise Found","","","Idyllshire (day)","" +"297","Homestead","","","Idyllshire (night)","" +"298","The Mushroomery","","","Matoya's Cave","" +"299","Descent","","","Dusk Vigil","" +"300","Like a Summer Rain","","","Neverreap","" +"301","Slumber Eternal","","","Sohm Al","" +"302","Roar of the Wyrm","","","The Aery","" +"303","Ink Long Dry","","","Great Gubal Library","" +"304","Imagination","","","Aetherochemical Research Facility","" +"305","Hallowed Halls","","","The Vault","" +"306","Hallowed Halls","","","The Vault","Slightly muffled" +"307","Hallowed Halls","","","The Vault","Slightly more muffled" +"308","Unbreakable","","","Fractal Continuum","" +"309","Ominous Prognisticks","","","Heavensward boss theme","" +"310","The Hand That Gives The Rose","","","Thok ast Thok (Ravana) phase 1","" +"311","Limitless Blue","","","The Limitless Blue (Bismarck) phase 1","" +"312","Heroes","","","The Singularity Reactor, The Minstrel's Ballad: Thordan's Reign phase 2","" +"313","Contention","","","Heavensward cutscenes, Churning Mists (Zenith)","" +"314","Misconception","","","Heavensward cutscenes","" +"315","The Heavens' Ward","","","Vault final boss (Ser Charibert)","" +"316","Stone and Steel","","","Heavensward cutscenes (Heroic)","" +"317","For the Sky","","","Heavensward cutscenes","" +"318","Inception","","","Heavensward cutscenes","" +"319","Borderless","","","Default flying mount theme","" +"320","The Dragon's Dirge","","","Heavensward cutscenes","This version loops" +"321","Ultima","","","Proto Ultima FATE, Proto Ultima battle (Dun Scaith)","" +"322","What is Love?","","","The Churning Mists (Moogles)","" +"323","Sins of the Father, Sins of the Son","","","Alexander trash theme","" +"324","Locus","","","Alexander boss theme","" +"325","Unbending Steel","","","Thok ast Thok phase 2","" +"326","Woe That Is Madness","","","The Limitless Blue phase 2","" +"327","Metal","","Metal","Alexander - Fist of the Father","Instrumental, vocals begin when in combat" +"328","When a Tree Falls","","","FC workshop/leves","1.0 track" +"329","Toll of the Bells","","","The Vault","Seems to be bells from The Vault judging by filename" +"330","All Saint's Wake","","","Witch's Broom mount","" +"331","Steel Reason","","","Red Baron / White Devil mounts","" +"332","Battle Theme","","","The Maiden's Rhapsody (FFXI)","" +"333","Battle Theme #2","","","The Maiden's Rhapsody (FFXI)","" +"334","Recollection","","","The Maiden's Rhapsody (FFXI)","" +"335","The Kingdom of San d'Oria","","","The Maiden's Rhapsody (FFXI)","" +"336","The Republic of Bastok","","","The Maiden's Rhapsody (FFXI)","" +"337","The Federation of Windurst","","","The Maiden's Rhapsody (FFXI)","" +"338","The Merry Wanderer Waltz","","","","Same as 399, but the filename seems to imply this is a Hildibrand theme" +"339","Heavy Rain","","","Sea of Clouds (Hostile Vanu area)","" +"340","Coming Home","","","Sea of Clouds (Friendly Vanu area)","" +"341","Heroes Never Die","","","The Minstrel's Ballad: Thordan's Reign phase 1","" +"342","Engage","","","The Diadem","" +"343","Jewel","","","The Diadem combat","" +"344","Torn from The Heavens","","","The Diadem Notorious Monster battle","Loops at the same point as 36, but is different" +"345","Poison Ivy","","","Saint Mocianne's Arboretum","" +"346","Upon the Rocks","","","Pharos Sirius (Hard)","" +"347","Aetherpause","Aetherosphere","In Darkness, There Is One","Void Ark","" +"348","Voidal Manifest","Six Fulms Under","","Void Ark (Echidna), The Weeping City of Mhach (Calofisteri) final bosses","" +"349","???","","","Lords of Verminion","Needs name" +"350","Brothers in Arms","","","Lords of Verminion","File is specific to LoV" +"351","Nemesis","","","Lords of Verminion","File is specific to LoV" +"352","The Dark's Kiss","","","Lords of Verminion","File is specific to LoV" +"353","Aftermath","","","Lords of Verminion","File is specific to LoV" +"354","The Corpse Hall","","","Lords of Verminion","File is specific to LoV" +"355","Battle on the Big Bridge","","","Lords of Verminion","File is specific to LoV" +"356","Spiral","","","Lords of Verminion","File is specific to LoV" +"357","Calamity Unbound","","","Lords of Verminion","File is specific to LoV" +"358","Prelude - Rebirth (2nd ver)","","","Kirin mount","81 that plays on Kirin" +"359","The Kiss","","","Valentione's Day","" +"360","test","","","","Likely test or filler audio" +"361","Down the Up Staircase","","","The Antitower","" +"362","Dancing Calcabrina","","","The Antitower","" +"363","No Sound, No Scutter","","","The Dravanian Forelands (Vath, hostile)","" +"364","Piece of Mind","","","The Dravanian Forelands (Vath, friendly)","" +"365","Battle to the Death - Heavensward","","","Containment Bay S1T7 (Sephirot) / Containment Bay P1T6 (Sophia) / Containment Bay Z1T9 (Zurvan) phase 1","" +"366","Fiend","","","Containment Bay S1T7 (Sephirot) phase 2","" +"367","Starved","","Dangertek","The Feast","Transitions to ""Dangertek"" during ""Culling Time""" +"368","The Ancient City","","","The Lost City of Amdapor (Hard)","" +"369","Metal - Brute Justice Mode","","","Alexander - The Burden of the Son (Brute Justice) phase 2","" +"370","test","","","","Likely test or filler audio" +"371","Woe That is Madness","","","The Limitless Blue (Extreme) (Bismarck) mount / White Lanner","" +"372","Unbending Steel","","","Thok ast Thok (Extreme) (Ravana) mount / Rose Lanner","" +"373","Heroes","","","The Minstrel's Ballad: Thordan's Reign (Thordan) mount / Round Lanner","" +"374","Battle to the Death - Heavensward","","","Containment Bay S1T7 (Sephirot) mount / Warring Lanner","" +"375","Tenacity","","","Guildhests","" +"376","From the Ashes","","","Bennu mount","" +"377","Faith in Her Fury","","","Heavensward cutscenes","Shorter/quick start version" +"378","Stone and Steel","","","Heavensward cutscenes","Shorter/quick start version" +"379","Primogenitor","","","Heavensward cutscenes","Shorter/quick start version" +"380","Hyper Rainbow Z","","","Go Go Posing Rangers Theme","Also plays in PotD occasionally" +"381","Freedom","","","The Parrock","A 1.0 La Noscea theme" +"382","Dragonsong","","","The Final Steps of Faith (Nidhogg) / The Minstrel's Ballad: Nidhogg's Rage (Nidhogg) phase 1","" +"383","Freefall","","","The Final Steps of Faith (Nidhogg) / The Minstrel's Ballad: Nidhogg's Rage (Nidhogg) phase 2","" +"384","Revenge of the Horde","","","The Final Steps of Faith (Nidhogg) / The Minstrel's Ballad: Nidhogg's Rage (Nidhogg) phase 3","" +"385","He Who Continues the Attack","","","Regula van Hydrus's Theme","" +"386","Apologies","","","Sohr Khai","" +"387","Holy Consult","","","Hullbreaker Isle (Hard)","1.0 track" +"388","Bathed in Woodsin","","","","1.0 track" +"389","Emerald Labyrinth","","","PotD","1.0 track" +"390","Enraptured","","","PotD","1.0 track" +"391","Tears for Mor Dhona","","","PotD","1.0 track" +"392","Blackbosom","","","PotD Floor 50 boss/Edda Blackbosom theme","" +"393","Teardrops in the Rain","","Torrent","Weeping City of Mhach","" +"394","A Thousand Faces","","","Weeping City of Mhach (Ozma add phase)","" +"395","Freefall","","","The Minstrel's Ballad: Nidhogg's Rage (Nidhogg) mount / Dark Lanner","" +"396","Good King Moggle Mog XII","","","Fat Moogle Mount","" +"397","Locus","","","Gobwalker Mount","" +"398","Night in the Brume","","","Heavensward cutscenes","Variant of 278" +"399","The Merry Wanderer Waltz","","","Palace of the Dead inter-floor theme","" +"400","Fragments of Forever","","","Alisaie Theme","1.0 track" +"401","Notice of Death","","","PotD pre-floor 100 cutscenes","" +"402","Equilibrium","","","Containment Bay P1T6 (Sophia) phase 2","" +"403","The Gauntlet","","","Duel / Lost Canals of Uznair / Palace of the Dead","" +"404","Ultima","","","Dun Scaith (Proto Ultima)","Quick start" +"405","Grounded","","","Xelphatol","" +"406","Revenge Twofold","","","Heavensward boss theme 2","" +"407","Bibliophobia","","","The Great Gubal Library (Hard)","" +"408","Up at Dawn","","","The Haunted Manor (All Saint's Wake)","" +"409","Fog of Phantom","","","PotD 91-100 theme","" +"410","Blasphemous Experiment","","","PotD floor 100 boss theme","" +"411","Exponential Entropy","","","Alexander - The Heart of the Creator (Cruise Chaser)","" +"412","Mobius","","","Alexander - The Soul of the Creator (Alexander Prime) phase 1","" +"413","Rise","","Stasis Loop","Alexander - The Soul of the Creator (Alexander Prime) phase 2","""Stasis Loop"" on another channel, used during time-stop mechanic" +"414","Out of Time","","","Alexander - The Soul of the Creator (Alexander Prime) timegate theme","Muffled, slow Exponential Entropy" +"415","Equilibrium","","","Containment Bay P1T6 (Extreme) (Sophia) mount / Sophic Lanner","" +"416","Mobius","","","Alexander - The Soul of the Creator (Savage) mount / Arrhidaeus","" +"417","Infinity","","","Containment Bay Z1T9 (Zurvan) phase 3","" +"418","test","","","","Likely test or filler audio" +"419","Penultimania","","","Containment Bay Z1T9 / Zurvan Phase 2","" +"420","Another Brick","","","Baelsar's Wall","" +"421","Quicksand","","","Sohm Al (Hard)","" +"422","Promises","","","Dun Scaith / Deathgaze Hollow","" +"423","Shadow of the Body","","","Dun Scaith","" +"424","Infinity","","","Containment Bay Z1T9 (Extreme) (Zurvan) mount / Demonic Lanner","" +"425","Prelude - Discoveries","","","Firebird mount","3 that plays on Firebird" +"426","Answers - Reprise","","","Ul'dah (The Rising)","" +"427","Null BGM","","","","Empty sound" +"428","Prelude - Long March Home","","","Stormblood title screen","" +"429","Revolutions / A Father's Pride / The Measure of Our Reach","","","Stormblood credits","Revolutions excerpt into A Father's Pride into The Measure of Our Reach" +"430","Harmony","","","Stormblood sanctuaries","" +"431","With Giants Watching","","","Stormblood sanctuaries","" +"432","Cradle","","","Stormblood sanctuaries","" +"433","Impact","","","Rhalgr's Reach","" +"434","Afterglow","","","Rhalgr's Reach","" +"435","Looping in the Deepest Fringes","","","Gyr Abania combat","All ""Looping in the Deepest Fringes"" are the same track" +"436","Crimson Sunrise","","","Kugane (day)","" +"437","Crimson Sunset","","","Kugane (night)","" +"438","Looping in the Deepest Fringes","","","Othard combat","All ""Looping in the Deepest Fringes"" are the same track" +"439","Beyond The Wall","","","The Fringes (day)","" +"440","Hope Forgotten","","","The Fringes (night)","" +"441","Looping in the Deepest Fringes","","","The Fringes combat","All ""Looping in the Deepest Fringes"" are the same track" +"442","On High","","","The Peaks (day)","" +"443","The Stone Remembers","","","The Peaks (night)","" +"444","Looping in the Deepest Fringes","","","The Peaks combat","All ""Looping in the Deepest Fringes"" are the same track" +"445","Songs of Salt and Suffering","","","The Lochs (day)","" +"446","Old Wounds","","","The Lochs (night)","" +"447","Looping in the Deepest Fringes","","","The Lochs combat","All ""Looping in the Deepest Fringes"" are the same track" +"448","Liquid Flame","","","The Ruby Sea (day)","" +"449","Westward Tide","","","The Ruby Sea (night)","" +"450","Looping in the Deepest Fringes","","","Othard combat","All ""Looping in the Deepest Fringes"" are the same track" +"451","A Father's Pride","","","Yanxia (day)","" +"452","A Mother's Pride","","","Yanxia (night)","" +"453","Looping in the Deepest Fringes","","","Yanxia combat","All ""Looping in the Deepest Fringes"" are the same track" +"454","Drowning in the Horizon","","","The Azim Steppe (day)","" +"455","He Rises Above","","","The Azim Steppe (night)","" +"456","Looping in the Deepest Fringes","","","The Azim Steppe combat","All ""Looping in the Deepest Fringes"" are the same track" +"457","Revolutions","","","Stormblood cutscenes","No vocals intro excerpt" +"458","Revolutions","","","Stormblood cutscenes","No vocals directly post-intro excerpt" +"459","Heroes of Stormblood","","","Stormblood cutscenes","" +"460","The Measure of Our Reach","","","Stormblood cutscenes","" +"461","The Measure of His Reach","","","Stormblood cutscenes","No vocals" +"462","test","","","","Likely test or filler audio" +"463","Revolutions","","","Stormblood cutscenes","No vocals late-song excerpt" +"464","Cyan's Theme","","","Stormblood cutscenes, The Doman Enclave","Arrangement of Cyan's Theme from Final Fantasy VI" +"465","Far East of Eorzea","","","Stormblood cutscenes","" +"466","Revelation","","","The Pool of Tribute (Susano) phase 1","" +"467","Beauty's Wicked Wiles","","","Emanation (Lakshmi)","" +"468","The Worm's Head","Scale and Steel","","The Royal Menagerie (Shinryu) phase 1","" +"469","The Worm's Tail","","","The Royal Menagerie (Shinryu) phase 2","" +"470","Triumph","","","Stormblood boss theme","" +"471","Dawnbound","","","The Sirensong Sea","" +"472","The Open Box","","","The Shisui of the Violet Tides","" +"473","Most Unworthy","","","Bardam's Mettle","" +"474","Gates of the Moon","","","Doma Castle","" +"475","Alienus","","","Castrum Abania","" +"476","Liberty or Death","","","Ala Mhigo","" +"477","Their Deadly Mission","","","The Temple of the Fist","" +"478","Deception","","","Kugane Castle","" +"479","Deltascape","","","The Interdimensional Rift","" +"480","Omega^2","","","Deltascape boss theme","" +"481","Decisions","","","Deltascape v4.0 (Exdeath)","Remix of The Decisive Battle from FFV" +"482","Final, Not Final","","","Deltascape v4.0 (Savage) (Neo-Exdeath)","Remix of The Last Battle from FFV" +"483","Wing and a Prayer","","","Falcon porters","" +"484","Wing and a Prayer","","","Stormblood cutscenes, Doman Enclave quests","" +"485","Revolutions","","","Stormblood cutscenes","Instrumental mid-song excerpt" +"486","Prelude - Long March Home","","","Stormblood title screen","Quick start ver - starts 19 secs in" +"487","Prelude - Long March Home / Measure of His Reach","","","Stormblood cutscenes","Slightly different 428 with more Prelude strings, transitions to ""The Measure of His Reach""" +"488","Shell-Shocked","","","The Ruby Sea (Hostile Kojin area)","" +"489","Parting Ways","","","Stormblood cutscenes","" +"490","Meteor","","","Stormblood cutscenes (Zenos)","" +"491","Riot","","","The Pool of Tribute (Susano) phase 2","" +"492","At Both Ends","","","The Pool of Tribute (Susano) phase 3","" +"493","Riot","","","The Pool of Tribue (Extreme) (Susano) mount / Reveling Kamuy","" +"494","Beauty's Wicked Wiles","","","Emanation (Extreme) (Lakshmi) mount / Blissful Kamuy","" +"495","Procedamus in Peace","","","Rhalgr's Reach","Plays while Rhalgr's is destroyed" +"496","Wizardly","","","Cheap Dungeon","Order Yet Undeciphered (294) Chiptune" +"497","Victory","","","Choco Racing Victory","" +"498","Indomitable","","","Ruby Sea (Friendly Kojin area)","" +"499","Beyond Redemption","","","Unending Coil of Bahamut (Ultimate) phase 4","Golden Bahamut theme" +"500","Rival Wings","","Birds of Prey","Rival Wings","" +"501","Locus","","","Rival Wings","Piloting Manipulator" +"502","Exponential Entropy","","","Rival Wings","Piloting Cruise Chaser" +"503","Metal - Brute Justice Mode","","","Rival Wings","Piloting Brute Justice" +"504","Far From Home","","","The Drowned City Of Skalla","" +"505","The Worm's Tail","","","The Minstrel's Ballad: Shinryu's Domain mount / Legendary Kamuy","" +"506","Trisection","","","Royal City of Rabanastre","" +"507","Precipitous Combat","","","Royal City of Rabanastre bosses","" +"508","Ultima's Transformation","","","Royal City of Rabanastre final boss (Argath Thadulfus)","" +"509","Victory","","","Royal City of Rabanastre post-final boss","" +"510","Save / Load Screen","","","Return to Ivalice cutscenes","" +"511","Character Creation","","","Return to Ivalice cutscenes","" +"512","Protagonist's Theme","","","Return to Ivalice cutscenes","" +"513","Decisive Battle","","","Royal City of Rabanastre","From FF Tactics" +"514","Background Story","","","Return to Ivalice cutscenes","" +"515","The Enemy Approaches","","","Return to Ivalice cutscenes","" +"516","Starlit Gateway","","","Seasonal event BGM areas","Starlight 2017" +"517","Forever in Flames","","","","The Coil Tightens (239) shortened" +"518","Keepers of the Lock","","","The Fringes (Friendly Ananta area)","" +"519","Iroha","","","Reisen Temple","" +"520","Siren Song","","","Seasonal event BGM areas","Little Ladies' Day" +"521","Answer on High","","","The Jade Stoa (Byakko) / Hell's Kier (Suzaku) / The Wreath of Snakes (Seiryu) phase 1","" +"522","Todoroki","","","The Jade Stoa (Byakko) phase 2","" +"523","Amatsu Kaze","","","The Jade Stoa (Byakko) phase 3","" +"524","Wicked Winds Whisper","","Magicked Skulls","Eureka Anemos, Eureka Pagos, Eureka Pyros","" +"525","No Quarter","","","Eureka Notorious Monster theme","" +"526","Down Where Daemons Dwell","","","Hells' Lid","" +"527","Unbreakable - Duality","","","The Fractal Continuum (Hard)","" +"528","The Phantom Train to Sigmascape","","","Sigmascape v1.0 (Phantom Train) opening cutscene","" +"529","The Decisive Battle","","","Sigmascape v1.0 (Phantom Train), Sigmascape v2.0 (Demon Chadarnook), Sigmascape v3.0 (Guardian)","" +"530","Dancing Mad - Movement I","","","Sigmascape v4.0 (Kefka) phase 1","" +"531","Dancing Mad - Movement II","","","Sigmascape v4.0 (Kefka) phase 2","" +"532","Dancing Mad - Movement III","","","Sigmascape v4.0 (Kefka) phase 3","" +"533","Dancing Mad - Movement IV","","","Sigmascape v4.0 (Savage) (God Kefka)","" +"534","Final, Not Final","","","Deltascape v4.0 (Savage) (Neo-Exdeath) mount / Alte Roite","" +"535","Dancing Mad IV Hushed","","","Sigmascape v4.0 (Savage) (God Kefka) mount / Air Force","" +"536","Amatsu Kaze","","","The Jade Stoa (Extreme) (Byakko) mount / Auspicious Kamuy","" +"537","Calling","","","Eureka","Same file as 56" +"538","Pa-Paya Demastered","","","Egg Hunter Riggy minigame","Easter 2018" +"539","Freedom","","","Seasonal event BGM areas","Needs name. Allegedly Valentione's related" +"540","Seven Hundred Seventy-Seven Whiskers","","","The Azim Steppe (Namazu)","" +"541","Nightbloom","","","Castrum Fluminis (Tsukuyomi) phase 1, The Minstrel's Ballad: Tsukuyomi's Pain (Tsukuyomi) phase 1","" +"542","Lunacy","","","Castrum Fluminis (Tsukuyomi) phase 2, The Minstrel's Ballad: Tsukuyomi's Pain (Tsukuyomi) phase 2","" +"543","Wayward Daughter","","","Castrum Fluminis (Tsukuyomi) phase 3, The Minstrel's Ballad: Tsukuyomi's Pain (Tsukuyomi) phase 3","" +"544","Fallen Angel (From Astral to Umbral)","","","The Weapon's Refrain (Ultimate) phase 1 (Garuda)","" +"545","Primal Judgment (From Astral to Umbral)","","","The Weapon's Refrain (Ultimate) phase 2 (Ifrit)","" +"546","Under the Weight (From Astral to Umbral)","","","The Weapon's Refrain (Ultimate) phase 3 (Titan), Eden's Gate: Sepulture (Savage) phase 3 (Titan)","" +"547","Ultima (Orchestral Version)","","","The Weapon's Refrain (Ultimate) phase 5","" +"548","Savage of the Ancient Forest","","","The Great Hunt (Rathalos) Phase 1","" +"549","Proof of a Hero - Monster Hunter: World version","","","The Great Hunt (Rathalos) Phase 2","" +"550","Quest Complete! - Proof of a Hero version","","","The Great Hunt (Rathalos) post-fight","" +"551","Earth Wind and Water","","","The Swallow's Compass","" +"552","Wayward Daughter","","","The Minstrel's Ballad: Tsukuyomi's Pain mount / Lunar Kamuy mount","" +"553","World Map","","","Needs location","Directly from FFT" +"554","A Chapel","","","Needs location","Directly from FFT" +"555","Ascent","","","The Ridorana Lighthouse pre 2nd-boss (Belias)","Directly from FFXII" +"556","The Mystery of Giruvegan","","","The Ridorana Lighthouse post 2nd-boss (Belias)","Directly from FFXII" +"557","Boss Theme","","","The Ridorana Lighthouse boss 1 (Famfrit), The Ridorana Lighthouse boss 2 (Belias)","Directly from FFXII" +"558","Apoplexy","","","The Ridorana Lighthouse boss 3 (Construct 7)","Directly from FFT" +"559","Flash of Steel","","","Ridorana Lighthouse final boss (Yiazmat)","Directly from FFXII" +"560","Victory","","","Ridorana Lighthouse final boss (Yiazmat) post-battle","Directly from FFXII" +"561","Cornerstone of the New World - Astera","","","Monster Hunter: World crossover cutscenes","Day theme, 1st half of MHW OST track" +"562","Cornerstone of the New World - Astera","","","Monster Hunter: World crossover cutscenes","Night theme, 2nd half of MHW OST track" +"563","Crown of the Ancient Tree","","","Monster Hunter: World crossover Rathalos intro cutscene","" +"564","Proof of a Hero - Monster Hunter: World version","","","The Great Hunt (Extreme) (Rathalos) Mount","" +"565","Deception","","","HoH mount / Juedi","" +"566","Crimson Sunrise","","","Shirogane (day)","" +"567","Crimson Sunset","","","Shirogane (night)","" +"568","Looping in the Deepest Fringes","","","Shirogane combat","All ""Looping in the Deepest Fringes"" are the same track" +"569","???","","","The Weapon's Refrain (Ultimate) phase 4","" +"570","Wasshoi, Wasshoi!","","","Mikoshi mount","" +"571","Second Council Meeting - Tension","","","Monster Hunter: World crossover cutscenes","" +"572","Quest Failed","","","The Great Hunt (Rathalos) duty failed","" +"573","Everywhere and Nowhere","","","Stormblood cutscenes (Alphascape)","" +"574","A Dream in Flight","","","Stormblood cutscenes (Alphascape)","" +"575","A Dream in Flight (2nd movement)","","","Stormblood cutscenes (Alphascape)","" +"576","Ending","","","Stormblood cutscenes (Alphascape)","" +"577","Unspoken","","","Cutscenes","1.0 Coerthas" +"578","Inner Recess","","","Stormblood cutscenes (Omega)","1.0 track" +"579","Neverborn","","","Cutscenes","" +"580","Starlight, Starbright","","Starlight, Not Right","Theatrhythm minigame","" +"581","Sunset","","","Hells' Kier (Suzaku) phase 2","DDR" +"582","Sunrise","","","Hells' Kier (Suzaku) phase 3","" +"583","A Land Long Dead","","","The Burn","" +"584","From Mud","","","Saint Mocianne's Arboretum (Hard)","" +"585","Battle","","","Alphascape v1.0 (Chaos)","FF1 battle theme remix" +"586","eScape","","","Alphascape v3.0 (Omega)","" +"587","Heartless","","","Alphascape v4.0 (Omega M/F)","" +"588","Sunrise","","","Suzaku mount","" +"589","From the Heavens","","","Alphascape v4.0 (Savage) (Final Omega) mount / Omega","" +"590","Bedlam's Brink","","","Solus zos Galvus theme","" +"591","From the Heavens","","","Alphascape v4.0 (Savage) (Final Omega) phase 2","" +"592","The Chase/Crazy Motorcycle","","","SDS Fenrir mount","Directly from FF7" +"593","Dangertek","","","The Shifting of Altars of Uznair, Feast (Culling time)","" +"594","","","","","" +"595","","","","","" +"596","","","","","" +"597","","","","","" +"598","","","","","" +"599","","","","","" +"600","","","","","" +"601","","","","","" +"602","","","","","" +"603","","","","","" +"604","Broken Down","","","Final Fantasy XV crossover cutscenes & events","" +"605","Hammerhead","","","Final Fantasy XV crossover cutscenes & events","Guitar comes in at the end, not the beginning like in FFXV OST" +"606","Valse di Fantastica","","","Final Fantasy XV crossover cutscenes & events","" +"607","Relax and Reflect","","","Final Fantasy XV crossover cutscenes & events","" +"608","Daemons","","","Final Fantasy XV crossover cutscenes & events","" +"609","Prayer de LUNA","","","Final Fantasy XV crossover cutscenes & events","Slightly different from the OST" +"610","Safe Haven","","","Final Fantasy XV crossover cutscenes & events","" +"611","Veiled in Black","","","Final Fantasy XV crossover cutscenes & events","" +"612","Horrors of the Night","","","Final Fantasy XV crossover cutscenes & events","" +"613","Apocalypsis Noctis","","","Final Fantasy XV crossover cutscenes & events","" +"614","A Quick Pit Stop","","","FFXV crossover mount / Regalia Type-G","" +"615","Saint Ajora's Theme","","","The Orbonne Monastery cutscene before final boss (Ultima)","Directly from FFT" +"616","Poachers' Den","","","Return to Ivalice quest cutscenes","Directly from FFT" +"617","Epilogue","","","Return to Ivalice quest cutscenes","Directly from FFT" +"618","Staff Credits","","","Return to Ivalice quest cutscenes","Directly from FFT" +"619","Brave Story","","","Return to Ivalice quest cutscenes","Directly from FFT" +"620","Alma's Theme","","","Return to Ivalice quest cutscenes","Directly from FFT" +"621","Intrigue","","","Return to Ivalice quest cutscenes","Directly from FFT" +"622","Under the Stars","","","The Orbonne Monastery pre 2nd-boss (Agrias)","Directly from FFT" +"623","Bloody Excrement","","","The Orbonne Monastery post 2nd-boss (Agrias)","Directly from FFT" +"624","Pressure (No. 1)","","","The Orbonne Monastery boss 1 (Mustadio)","Directly from FFT" +"625","Antipyretic","","","The Orbonne Monastery boss 2 (Agrias)","Directly from FFT" +"626","A Man Consumed","","","The Orbonne Monastery boss 3 (The Thunder God)","""Grotesque Creature"" from Final Fantasy Vagrant Story" +"627","Descent","","","The Orbonne Monastery final boss (Ultima) phase 2","Directly from FFT" +"628","Ultima's Perfection","","","The Orbonne Monastery final boss (Ultima) phase 3","Directly from FFT" +"629","Final Struggle / Hall of Worship","","","The Orbonne Monastery final boss (Ultima) victory theme","Opens with Final Struggle, transitions to Hall of Worship" +"630","Nail of the Heavens","","","The Masked Carnivale","1.0 track" +"631","Imperium","","","The Masked Carnivale","" +"632","The Garden of Ru'Hmet","","","Baldesion Arsenal","Directly from FFXI" +"633","Onslaught","","","Baldesion Arsenal boss theme","Directly from FFXI" +"634","Turmoil","","","Baldesion Arsenal final boss (Proto Ozma) theme","Directly from FFXI" +"635","From the Dragon's Wake","","","Seiryu mount","" +"636","Prelude - Long March Home","","","Kyubi mount","No title logo slice, no flag cheering" +"637","Horizons Calling","","","Nezha Chariot / Red Hare / Magicked Carpet / Sunspun Cumulus mounts","" +"638","The Merry Wanderer Waltz","","","Mystic Panda / Aquamarine+Citrine+Rubellite Carbuncle / Indigo Whale / Fatter Cat / Spriggan Stonecarrier / Kingly Peacock mounts","" +"639","A Pall Most Murderous","","","The Ghimlyt Dark","" +"640","From the Dragon's Wake","","","The Wreath of Snakes (Seiryu) phase 2","" +"641","Doman Distractions","","","Doman Mahjong","" +"642","Air Force One Victory","","","Air Force One","" +"643","Air Force One Fail","","","Air Force One","" +"644","Battle Theme 1.x","","","Air Force One","" +"645","Revolutions / The Measure of Our Reach","","","Stormblood end credits 2","" +"646","Tomorrow and Tomorrow","","","Shadowbringers title cutscene","" +"647","Tomorrow and Tomorrow - Reprise","","","Shadowbringers cutscenes","" +"648","A Better Tomorrow","","","Shadowbringers cutscenes","" +"649","Tears in the Rain","","","Shadowbringers cutscenes","" +"650","Dangerous Words","","","Shadowbringers cutscenes / Overworld theme","Can be overworld theme based on quest progression" +"651","High Treason","","","Shadowbringers cutscenes / Overworld theme / Quest battles","Can be overworld theme based on quest progression" +"652","More than Truth","","","Shadowbringers cutscenes","" +"653","Paradisaical Predicaments","","","Shadowbringers cutscenes","" +"654","Tomorrow and Tomorrow","","","Shadowbringers cutscenes","Reverb piano version" +"655","Tomorrow and Tomorrow","","","Shadowbringers cutscenes","Reverb vocals + piano version" +"656","Vamo' alla Flamenco","","","Shadowbringers cutscenes (Dancer cutscenes)","" +"657","???","","","Level 80 Bard quest, ""A Harmony from the Heavens""","Needs name" +"658","The Lute","","","","" +"659","The Dark Which Illuminates the World","","","Crystarium (day)","" +"660","Knowledge Never Sleeps","","","Crystarium (night)","" +"661","Indulgence","","","Eulmore (day)","" +"662","Masquerade","","","Eulmore (night)","" +"663","The Source","","","Lakeland (day)","" +"664","Unchanging, Everchanging","","","Lakeland (night)","" +"665","A World Divided","","","Kholusia (day)","" +"666","The Quick Way","","","Kholusia (night)","" +"667","Sands of Amber","","","Amh Araeng (day)","" +"668","Sands of Blood","","","Amh Araeng (night)","" +"669","Fierce and Free","","","Il Mheg (day)","" +"670","The Faerie Ring","","","Il Mheg (night)","" +"671","Civilizations","","","Rak'tika Greatwood (day)","" +"672","A Hopeless Race","","","Rak'tika Greatwood (night)","" +"673","Full Fathom Five","","","The Tempest","" +"674","Neath Dark Waters","","","The Tempest (Amaurot)","" +"675","A Reason to Live","","","Shadowbringers sanctuaries","" +"676","No Greater Sorrow","","","Shadowbringers sanctuaries","" +"677","Rencounter","","","Lakeland combat","All ""Rencounter"" are the same track" +"678","Rencounter","","","Kholusia combat","All ""Rencounter"" are the same track" +"679","Rencounter","","","Amh Araeng combat","All ""Rencounter"" are the same track" +"680","Rencounter","","","Il Mheg combat","All ""Rencounter"" are the same track" +"681","Rencounter","","","Rak'tika Greatwood combat","All ""Rencounter"" are the same track" +"682","","","","The Tempest combat","Empty track, but it seems XIV needs to have zone combat themes for everything" +"683","What Angel Wakes Me","","","The Dancing Plague (Titania)","" +"684","Insanity","","","The Crown of the Immaculate (Innocence)","" +"685","Who Brings Shadow","","","The Dying Gasp (Hades) phase 1","" +"686","Invincible","","","The Dying Gasp (Hades) phase 2","" +"687","To Fire And Sword","","","The Holminister Switch","" +"688","Figments","","","Dohn Mheg","" +"689","Unwound","","","Qitana Ravel","" +"690","Deep Down","","","Malikah's Well","" +"691","In The Belly Of The Beast","","","Mt. Gulg","" +"692","Mortal Instants","","","Amaurot","" +"693","Shadows Withal","","","Akadaemia Anyder","" +"694","A Long Fall","","","The Twinning","" +"695","Insatiable","","","Shadowbringers boss theme","" +"696","Blue Fields","","","The Empty (unfinished)","" +"697","Force Your Way","","","Eden's Gate: Resurrection (Eden Prime), Descent (Voidwalker), Eden's Verse: Iconoclasm (Idol of Darkness)","" +"698","Landslide","","","Eden's Gate: Sepulture (Titan)","" +"699","On Our Fates Alight","","","Amaro porter","" +"700","What Angel Wakes Me","","","The Dancing Plague (Extreme) (Titania) mount / Fae Gwiber","(Mount)" +"701","Insanity","","","The Crown of the Immaculate (Extreme) (Innocence) mount / Innocent Gwiber","(Mount)" +"702","Landslide","","","Eden's Gate: Sepulture (Savage) (Titan) mount / Skyslipper","(Mount)" +"703","Four-sided Circle","","","Sabotender Emperador mount","" +"704","Four-fold Knowing","","","Shadowbringers title screen","" +"705","Who Brings Shadow / Tomorrow and Tomorrow / Masquerade / High Treason / Knowledge Never Sleeps / The Dark Which Illuminates the World","","","Shadowbringers credits","Transitions directly into each song" +"706","Locus (The Primals)","","","The Twinning, The Epic of Alexander (Ultimate) phase 1","" +"707","Tomorrow and Tomorrow","","","Shadowbringers cutscenes","Part 1 of full track" +"708","Tomorrow and Tomorrow","","","Shadowbringers cutscenes","Part 2 of full track" +"709","Tomorrow and Tomorrow","","","Shadowbringers cutscenes","No vocals" +"710","Shattered","","","","2nd channel of 218, Syrcus Tower combat music" +"711","Pain in Pleasure","","","Eulmore","A 2nd Eulmore day theme" +"712","Such as it Is","","","Shadowbringers sanctuaries","" +"713","Null BGM","","","","Empty sound" +"714","The Darks' Kiss","","","","2nd channel of 17, ARR Hard dungeon combat music" +"715","On Our Fates Alight","","","Amaro mount","" +"716","Unmatching Pieces","","","Kholusia","Alt theme (Everlasting light?)" +"717","Blinding Indigo","","","Eden's Gate: Inundation (Leviathan)","" +"718","Starlight, de Chocobo","","Starlight, de Chocobo (?)","Theatrhythm minigame","Transitions to an unnamed off-key version when failing the minigame" +"719","The Garden's Gates","","","Lyhe Mheg","" +"720","The Mendicant's Relish","","","The Firmament","" +"721","Siren Song","","","Eulmore (The Beehive)","" +"722","A Fine Air Forbiddeth","","A Fierce Air Forceth","Onsal Hakair","" +"723","Metal - Brute Justice Mode (The Primals)","","","The Epic of Alexander (Ultimate) phase 2","" +"724","Stasis Loop","","","The Epic of Alexander (Ultimate) phase 2 to 3","A12 timestop" +"725","Rise (The Primals)","","Stasis Loop","The Epic of Alexander (Ultimate) phase 3","" +"726","Moebius (Orchestral Version)","","","The Epic of Alexander (Ultimate) phase 4","" +"727","The Grand Cosmos","","","The Grand Cosmos","" +"728","Invincible","","","The Minstrel's Ballad: Hades' Elegy mount / Shadow Gwiber","" +"729","A Fierce Air Forceth","","","Construct VII mount","" +"730","Starved","","","Epimetheus, Menoetius mounts","" +"731","Imperium","","","Morbol mount","" +"732","Significance (Nothing)","","","The Copied Factory solo exploration","FFXIV x NieR crossover" +"733","City Ruins - Rays of Light","","","The Copied Factory","FFXIV x NieR crossover" +"734","Vague Hope","","","The Copied Factory - (Quest Area)","FFXIV x NieR crossover" +"735","","","","","" +"736","Voice of no Return (Guitar)","","","Need location","FFXIV x NieR crossover" +"737","Alien Manifestation","","","The Copied Factory","FFXIV x NieR crossover" +"738","Song of the Ancients - Atonement","","","The Copied Factory boss 1 (Serial-jointed Command Model), The Copied Factory boss 2 (Hobbes), The Tower at Paradigm's Breach boss 2 (Hansel & Gretel)","FFXIV x NieR crossover" +"739","Bipolar Nightmare","","","The Copied Factory boss 3 (Engels), The Puppet's Bunker boss 2 (767P-operated Superior Flight Unit(s))","FFXIV x NieR crossover" +"740","Weight of the World - Prelude Version","","","The Copied Factory boss 4 (9S-operated Walking Fortress)","FFXIV x NieR crossover" +"741","Crumbling Lies (Front)","","","Shadowbringers cutscenes (FFXIV x NieR crossover)","FFXIV x NieR crossover" +"742","Ami","","","Eden cutscenes / The Empty (finished)","FFVIII" +"743","Hopl's Dropple","","","Rak'tika Greatwood (Friendly Qitari area)","" +"744","Gangos","","","Gangos","" +"745","Pa-Paya Demastered","","","Egg Hunter Riggy minigame","Easter 2020" +"746","Ultima (The Primals)","","","Cinder Drift (The Ruby Weapon) phase 1","" +"747","Hearthward","","","The Firmament","" +"748","Insatiable (The Primals)","","","Shadowbringers mid-dungeon bosses","" +"749","Floundering in the Depths","","","Anamnesis Anyder","" +"750","Twice Stricken","","","Eden's Verse: Fulmination (Ramuh)","" +"751","Primal Angel","","","Eden's Verse: Furor (Garuda & Ifrit, Raktapaksa)","" +"752","Return to Oblivion","","","Eden's Verse: Refulgence (Shiva) phase 1","" +"753","Ultima (The Primals)","","","The Cinder Drift (Extreme) mount / Ruby Gwiber","" +"754","Twice Stricken","","","Eden's Verse: Fulmination (Savage) (Ramuh) mount / Ramuh","" +"755","Rise of The White Raven (Orchestral Version)","","","The Cinder Drift (2nd Phase) / The Unending Coil of Bahamut Phase 2 (Nael Deus Darnus)","This version has far more prominent vocals" +"756","Horizons Calling","","","Ocean Fishing","" +"757","Holy Consult","","","Ocean Fishing","" +"758","When a Tree Falls","","","Ocean Fishing","" +"759","A Sundering of Light","","","Eden's Verse: Refulgence (Shiva) add phase","" +"760","Eternal Wind - Shadowbringers","","","","" +"761","Shadowbringers","","","Shadowbringers cutscenes (Hope's Confluence, cutscene 5)","Short portion of Shadowbringers" +"762","Tomorrow and Tomorrow","","","Shadowbringers cutscenes","Full song" +"763","Dawn of a New Era","","","Shadowbringers cutscenes","" +"764","Forever at Your Side","","","Shadowbringers cutscenes","" +"765","The Isle of Endless Summer","","","Eastern La Noscea Moonfire Faire","" +"766","Watts's Anvil","","","Lakeland (Friendly Dwarf area)","" +"767","And Love You Shall Find","","","Terncliff","" +"768","To The Edge","","","The Seat of Sacrifice phase 1, The Seat of Sacrifice (Extreme) (Warrior of Light)","" +"769","Echoes in the Dark","","","The Seat of Sacrifice (Warrior of Light)","Active time maneuver mid-normal mode" +"770","","","","","" +"771","To The Edge","","","The Seat of Sacrifice (Warrior of Light)","" +"772","Wind on the Plains","","Blood on the Wind","The Bozjan Southern Front","" +"773","Discord: Imperial (Zodiac Age Version)","","","The Bozjan Southern Front (certain critical engagements)","" +"774","Into the Fortress (Zodiac Age Version)","","","The Bozjan Southern Front (Castrum Lacus Litore between 1st boss and 2nd boss, Hostage phase)","" +"775","Battle with an Esper (Zodiac Age Version)","","","The Bozjan Southern Front (Castrum Lacus Litore boss theme)","" +"776","Life and Death (Zodiac Age Version)","","","The Bozjan Southern Front (Castrum Lacus Litore final boss (Dawon & Lyon))","" +"777","Where All Roads Lead","","","The Heroes Gauntlet","" +"778","To The Edge","","","The Seat of Sacrifice (Extreme) mount / Gwiber of Light","" +"779","Discord: Imperial (Zodiac Age Version)","","","The Bozjan Southern Front lockbox mount / Gabriel α","" +"780","Broken Heart","","","YoRHa: Dark Apocalypse cutscenes","From FFXIV x NieR crossover" +"781","City Ruins (Rays of Light) (Instrumental)","","","YoRHa: Dark Apocalypse cutscenes","From FFXIV x NieR crossover" +"782","Amusement Park","","","Temporarily plays in Komra during the YoRHa: Dark Apocalypse questline, after unlocking The Puppet's Bunker","From FFXIV x NieR crossover" +"783","Fortress of Lies","","","The Puppet's Bunker","From FFXIV x NieR crossover" +"784","Grandma (Destruction)","","","The Puppet's Bunker boss 1 (813P-operated Aegis Unit), The Puppet's Bunker final boss (The Compound) phase 1","From FFXIV x NieR crossover" +"785","End of the Unknown","","","The Puppet's Bunker boss 3 (905P-operated Heavy Artillery Unit)","From FFXIV x NieR crossover" +"786","Torn From the Heavens/The Dark Colossus Destroys All (Medley)","","","The Puppet's Bunker final boss (Compound 2P) phase 2","From FFXIV x NieR crossover" +"787","Unrest (Zodiac Age Version)","","","The Bozjan Southern Front","" +"788","Hearthward","","","The Firmament mount / Pteradon","" +"789","Heavensward","","","City of Giants (Solo Instance)","" +"790","Nightbloom","","","City of Giants (Solo Instance)","" +"791","New Foundations","","New Foundations (Groundbreaking)","The Firmament","" +"792","The Black Wolf Stalks Again","","","Castrum Marinum (Emerald Weapon) phase 2","" +"793","Gogo's Theme","","","The Masked Carnivale (31 act 1)","" +"794","The Sochen Cave Palace (Zodiac Age Version)","","","Delubrum Reginae","" +"795","Giving Chase (Zodiac Age Edition)","","","Delubrum Reginae combat theme","" +"796","The Queen Awakens","","","Delubrum Reginae final boss (The Queen)","" +"797","Shuffle or Boogie","","","Triple Triad tournaments","" +"798","Freshly Glazed Porxie","","","Matoya's Relict","" +"799","Don't Be Afraid","","","Eden's Promise: Umbra (Cloud of Darkness), Eden's Promise: Litany (Shadowkeeper)","" +"800","The Legendary Beast","","","Eden's Promise: Anamorphosis (Fatebreaker)","" +"801","Promises to Keep","","","Eden's Promise: Eternity (Eden's Promise)","" +"802","The Extreme","","","Eden's Promise: Eternity (Savage) (Oracle of Darkness)","" +"803","The Black Wolf Stalks Again","","","Castrum Marinum (Extreme) (Emerald Weapon) / Emerald Gwiber","" +"804","Promises to Keep","","","Eden's Promise: Eternity (Savage) mount / Eden","" +"805","Lunar Whale (Shadowbringers)","","","Fanfest 2021 mount / Lunar Whale","XIV version of Magical Ship from FFIV" +"806","Treasured Memory","","","Eden's Promise: Eternity phase 2","" +"807","In the Arms of War","","","The Cloud Deck, The Cloud Deck (Extreme) (Diamond Weapon)","" +"808","Wrath of the Harrier","","","Dalriada final boss (The Diablo Armament)","" +"809","Skyrise","","","Ishgard Fetes","" +"810","Seven Flames","","","Paglth'an","" +"811","In the Arms of War","","","The Cloud Deck (Extreme) (Diamond Weapon) mount / Diamond Gwiber","" +"812","Exponential Entropy","","","Cruise Chaser mount","" +"813","Four-fold Knowing","","","All Gwiber mount / Landerwaffe","" +"814","Shuffle or Boogie","","","Triple Triad card 1-312 collection mount / Magicked Card","" +"815","Torn from the Heavens","","","Golden mount theme / Gilded Mikoshi / Resplendent Vessel of Ronka","Eorzean Symphony version of 36" +"816","Mourning","","","The Tower at Paradigm's Breach between boss ambient theme","From FFXIV x NieR crossover" +"817","Emil (Despair)","","","The Tower at Paradigm's Breach pre boss 1 ambient theme, The Tower at Paradigm's Breach boss 1 (Knave of Hearts)","From FFXIV x NieR crossover" +"818","","","","","" +"819","The Sound of the End","","","The Tower at Paradigm's Breach boss 3 (Red Girl)","From FFXIV x NieR crossover" +"820","The Sound of the End: 8bit","","","The Tower at Paradigm's Breach boss 3 (Red Girl) (phase 2)","From FFXIV x NieR crossover. ""chiptune"" / ""8 bit"" version" +"821","Kainé (Final Fantasy Main Theme Version)","","","The Tower at Paradigm's Breach final boss (phase 2)","From FFXIV x NieR crossover" +"822","Weight of the World","","","Shadowbringers cutscenes (FFXIV x NieR crossover)","From FFXIV x NieR crossover, instrumental" +"823","Voice of no Return","","","Shadowbringers cutscenes (FFXIV x NieR crossover)","From FFXIV x NieR crossover" +"824","The Color of Depression","","","Shadowbringers cutscenes (FFXIV x NieR crossover)","From FFXIV x NieR crossover" +"825","Widespread Illness","","","Shadowbringers cutscenes (FFXIV x NieR crossover)","From FFXIV x NieR crossover" +"826","Possessed by Disease","","","The Tower At Paradigm's Breach boss 4 (False Idol)","From FFXIV x NieR crossover" +"827","Faltering Prayer (Dawn Breeze)","","","Shadowbringers cutscenes (FFXIV x NieR crossover)","From FFXIV x NieR crossover" +"828","","","","","Empty BGM" +"829","Endwalker","","","Endwalker (Solo Instance)","Heavy start" +"830","Flow","","","Endwalker cutscenes","" +"831","Flow (instrumental)","","","","" +"832","Each Drop","","","","" +"833","Answers (Piano Version)","","","Endwalker cutscenes","" +"834","The Last Stand","","","","" +"835","Heroes Forge Ahead","","","","" +"836","Dynamis","","","Endwalker cutscenes","Meteion's theme" +"837","Spoken without End","","","","" +"838","What Comes of Despair","","","Endwalker cutscenes","" +"839","Shade's Delight","","","Lemure Headquarters, Endwalker cutscenes","" +"840","Home Beyond the Horizon","","","Garlemald radio","Muffled version" +"841","The Tale of the Star","","","","" +"842","Neath Dark Waters (Scions & Sinners)","","","","" +"843","Imagination (Duality)","","","","From Piano Collections FINAL FANTASY XIV by Keiko" +"844","Answers","","","Endwalker MSQ ""Thou Must Live, Die, and Know"" cutscene 2","" +"845","The Ewer Brimmeth","","","Old Sharlayan (day)","" +"846","The Nautilus Knoweth","","","Old Sharlayan (night)","" +"847","The Day Will Come (Endwalker)","","","Sharlayan Main Hall","" +"848","Vibrant Voices","","","Radz-at-Han (day)","" +"849","Perfumed Eves","","","Radz-at-Han (night)","" +"850","Twilit Terraces","","","Radz-at-Han (day)","" +"851","The Labyrinth","","","Labyrinthos (day)","" +"852","Dreams of Man","","","Labyrinthos (night)","" +"853","Divine Words","","","Thavnair (day)","" +"854","Prayers Repeated","","","Thavnair (night)","" +"855","White Snow, Black Steel","","","Garlemald (day)","" +"856","Black Steel, Cold Embers","","","Garlemald (night)","" +"857","One Small Step","","","Mare Lamentorum (day)","" +"858","Sky Unsundered","","","Elpis (day)","" +"859","Stars Long Dead","","","Elpis (night)","" +"860","Echoes in the Distance","","","Ultima Thule MSQ stage 1","Muffled, instrumental version" +"861","Close in the Distance (Instrumental)","","","Ultima Thule MSQ stage 2","" +"862","Close in the Distance","","","Ultima Thule MSQ stage 3","" +"863","Those We Can Yet Save","","","Endwalker sanctuaries","" +"864","Welcome to Our Town! (Endwalker)","","","Bestways Burrow","New version of the FFIV track" +"865","Unbowed","","","Labyrinthos combat","All ""Unbowed"" are the same track" +"866","Unbowed","","","Thavnair combat","All ""Unbowed"" are the same track" +"867","Unbowed","","","Garlemald combat","All ""Unbowed"" are the same track" +"868","Unbowed","","","Elpis combat","All ""Unbowed"" are the same track" +"869","Battle 1 from FINAL FANTASY IV","","","Mare Lamentorum combat (The Carrotorium, Greatest Endsvale)","Directly from FFIV" +"870","Endcaller","","","The Dark Inside / The Minstrel's Ballad: Zodiark's Fall (Zodiark)","" +"871","Your Answer","","","The Mothercrystal / The Minstrel's Ballad: Hydaelyn's Call (Hydaelyn)","" +"872","The Final Day","","","The Final Day (phase 1) (Endsinger)","" +"873","With Hearts Aligned","","","The Final Day (phase 2) (Endsinger)","Heavy start like 829, no male vocals" +"874","Tower of Zot (Endwalker)","","","Tower of Zot","New version of the FFIV track" +"875","Garlemald Express","","","Tower of Babil","" +"876","As the Sky Burns","","","Vanaspati","" +"877","Miracle Works","","","Ktisis Hyperboreia","" +"878","The Aetherial Sea","","","The Aitiascope","" +"879","Of Countless Stars","","","The Dead Ends","" +"880","Carrots of Happiness","","","Smileton","" +"881","eScape (Journeys Version)","","","The Stigma Dreamscape","" +"882","On Blade's Edge","","","Endwalker mid-dungeon bosses","" +"883","Finality","","","Endwalker dungeon final bosses","" +"884","Where Dæmons Abide","","","The Gates of Pandæmonium","" +"885","Ancient Shackles","","","Asphodelos: The First Circle (Erichthonios), Asphodelos: The Second Circle (Hippokampos), Asphodelos: The Third Circle (Phoinix)","" +"886","Hic Svnt Leones","","","Asphodelos: The Fourth Circle (Hesperos)","" +"887","Prelude - Tales","","","Endwalker title screen","" +"888","???","","","Endwalker credits","38 minute medley of songs through ARR to EW" +"889","Endcaller","","","The Minstrel's Ballad: Zodiark's Fall mount / Lynx of Darkness","" +"890","Your Answer","","","The Minstrel's Ballad: Hydaelyn's Call mount / Lynx of Light","" +"891","Hic Svnt Leones","","","Asphodelos: The Fourth Circle (Hesperos) mount / Phoinix","" +"892","Roads Less Traveled","","","Endwalker mounts","" +"893","Tremble","","","","" +"894","Home Beyond the Horizon","","","Garlemald radio","" +"895","Roads Less Traveled","","","","Same as 892" +"896","Endwalker - Footfalls (Instrumental)","","","","Short ver, only 1:27" +"897","From Below","","","Labyrinthos (MSQ based)","" +"898","Answers","","","Endwalker cutscenes","Band version, 238 without the opening" +"899","Flow Together","","","Worthy of His Back (Solo Instance)","Band version" +"900","Down the Up Staircase","","","Labyrinthos sanctuaries","No different than the standard version" +"901","Defender of the Realm","","","Thaumazein, Labyrinthos","" +"902","Endwalker (short)","","","","" +"903","A Gentleman to Walk with Me","","","","" +"904","Somewhere in the World (Ambitions Writhe)","","","Endwalker cutscenes (Void/Thirteenth)","" +"905","Ink Long Dry (Piano Collections)","","","Restricted Archives","" +"906","Hippo Ridin'","","","Thavnair (Arkasodara)","" +"907","Revenge Twofold (Orchestral Version)","","","Dragonsong's Reprise (Ultimate) phase 7 (Dragon-king Thordan)","" +"908","Warming Up","","","Crystalline Conflict","Before match starts" +"909","Festival of the Hunt (Endwalker)","","","Crystalline Conflict","During match" +"910","Run! (Endwalker)","","","Crystalline Conflict","Overtime" +"911","The Map Unfolds","","","Alzadaal's Legacy","" +"912","One Among Wonders","","","The Omphalos","" +"913","Pilgrimage","","","Aglaia","" +"914","Radiance","","","Aglaia Boss 1 (Byregot) / Aglaia Boss 2 (Rhalgr) / Aglaia Boss 3 (Azeyma)","" +"915","In the Balance","","","Aglaia Final Boss (Nald'thal)","" +"916","","","","","" +"917","The Final Day","","","Bluefeather Lynx / The Minstrel's Ballad: Endsinger's Aria mount","" +"918","Thus Spoke Master PuPu","","","","" +"919","Weight of the World (Prelude Version)","","","Pod mount","" +"920","The Heavens' Ward","","","Dragonsong's Reprise (Ultimate) phase 1 (Ser Charibert, Ser Adelphel, Ser Grinnaux)","" +"921","Heroes","","","Dragonsong's Reprise (Ultimate) phase 2 (King Thordan)","" +"922","Freefall","","","Dragonsong's Reprise (Ultimate) phase 3 (Niddhogg, Estinien form)","" +"923","Contention","","","Dragonsong's Reprise (Ultimate) phase 4 (Eyes phase)","" +"924","Hallowed Halls","","","Dragonsong's Reprise (Ultimate) intro phase revisit","" +"925","Heavensward","","","Dragonsong's Reprise (Ultimate) phase 5 (King Thordan, alternate timeline)","" +"926","Dragonsong","","","Dragonsong's Reprise (Ultimate) phase 6 (Nidhogg and Hraesvelgr)","" +"927","Primogenitor","","","Dragonsong's Reprise (Ultimate) phase 4 (Eyes phase) enrage scene","" +"928","Sorrow and Loss (Endwalker)","","","Zero's Domain","" +"929","Cradle of Hope","","","Ultima Thule (Omicrons)","" +"930","Battle with the Four Fiends (Buried Memory)","","","Storm's Crown / Storm's Crown (Extreme) (Barbariccia)","" +"931","A Quiet Moment","","","Island Sanctuary Hideaway","" +"932","Island Paradise","","","Island Sanctuary Non-Hideaway","" +"933","Troian Beauty (Endwalker)","","","The Fell Court of Troia","" +"934","FINAL FANTASY IV Battle 2 (Endwalker)","","","The Fell Court of Troia final boss (Scarmiglione), Lapis Manalis final boss (Cagnazzo)","" +"935","To the Sun (Piano Collections)","","","The Sil'dihn Subterrane","" +"936","Desert Sun","","","Another Sil'dihn Subterrane / Another Sil'dihn Subterrane (Savage)","" +"937","Silent Scream","","","Abyssos: The Fifth Circle (Proto-Carbuncle)","" +"938","Scream","","","Abyssos: The Sixth Circle (Hegemone), Abyssos: The Seventh Circle (Agdistis)","" +"939","Embers","","","Abyssos: The Eighth Circle (Hephaistos) phase 1","" +"940","White Stone Black","","","Abyssos: The Eighth Circle (Hephaistos) phase 2","" +"941","Battle with the Four Fiends (Buried Memory)","","","Lynx of Imperial Wind / Storm's Crown (Extreme) mount","" +"942","White Stone Black","","","Sunforged / Abyssos: The Eighth Circle (Savage) (Hephaistos) mount","" +"943","Island Paradise","","","Island Mandragora mount / Island Onion Prince mount / Island Eggplant Knight mount","" +"944","To the Sun (Piano Collections)","","","Silkie mount","" +"945","Desert Sun","","","Sil'dihn Throne mount","" +"946","Inexorable","","","","" +"947","Polygons of Inquiry","","","","" +"948","Dreamwalker","","","Loporrit Tribal Area","" +"949","Forged in Crimson","","","Mount Ordeals (Rubicante) / Mount Ordeals (Extreme) (Rubicante)","" +"950","From The Heavens (Orchestral Version)","","","The Omega Protocol (Ultimate) Phase 3 (Omega)","" +"951","Torn from the Heavens (Orchestral Version)","","","The Omega Protocol (Ultimate) Phase 6 (Alpha Omega)","" +"952","Deep Blue","","","Lapis Manalis","" +"953","Forbidden Land (Endwalker)","","","Eureka Orthos","" +"954","Equilibrium (Pulse)","","","Eureka Orthos","" +"955","Oblivion (Pulse)","","","Eureka Orthos","" +"956","A Long Fall (Pulse)","","","Eureka Orthos","" +"957","Neath Dark Waters (Pulse)","","","Eureka Orthos","" +"958","Favor","","","Euphrosyne","" +"959","Rhythm of the Realm","","","Euphrosyne Boss 1 (Nophica), Boss 2 (Althyk & Nymeia), Boss 3 (Halone)","" +"960","Dedicated to Moonlight","","","Euphrosyne Boss final boss (Menphina)","" +"961","Forged in Crimson","","","Lynx of Righteous Fire / Mount Ordeals (Extreme) mount","" +"962","Deltascape","","","The Omega Protocol (Ultimate) Phase 1 (Omega)","" +"963","Heartless","","","The Omega Protocol (Ultimate) Phase 2 (Omega M + Omega F)","" +"964","eScape","","","The Omega Protocol (Ultimate) Phase 5 (Omega M + Omega F)","" +"965","Another Moon","","","Endwalker Thirteenth's Moon theme","" +"966","Voidcast Savior","","","The Voidcast Dais (Golbez)","" +"967","Battle 2 from FINAL FANTASY III","","","","" +"968","Subterranean Sanctuary","","","","" +"969","The Land Reborn","","","Kupo Kupo Adventure (the Rising 2023 minigame) level theme","" +"970","Pom from the Heavens","","","Kupo Kupo Adventure (the Rising 2023 minigame) boss theme","" +"971","Starsbreath","","","The Aetherfont","" +"972","Crimson Sunset","","","Mount Rokkon","" +"973","Storm of Blood","","","Mount Rokkon final boss ()","" +"974","Crimson Rise","","","Another Mount Rokkon","" +"975","One Amongst the Weary","","","Anabaseios: The Ninth Circle / Anabaseios: The Ninth Circle: Savage (Kokytos) / Anabaseios: The Tenth Circle / Anabaseios: The Tenth Circle: Savage (Pandæmonium)","" +"976","Fleeting Moment","","","Anabaseios: The Eleventh Circle / Anabaseios: The Eleventh Circle: Savage (Themis)","" +"977","Athena, the Tireless One","","","Anabaseios: The Twelfth Circle / Anabaseios: The Twelfth Circle: Savage (Athena)","" +"978","Ultima's Perfection (Endwalker)","","","Anabaseios: The Twelfth Circle / Anabaseios: The Twelfth Circle: Savage Phase 2 (Athena)","" +"979","Voidcast Savior","","","Lynx of Fallen Shadow mount / The Voidcast Dais (Golbez) mount","" +"980","Athena, the Tireless One","","","Axolotl mount / Anabaseios: The Twelfth Circle / Anabaseios: The Twelfth Circle: Savage Phase 2 (Athena) mount","" +"981","Crimson Sunset","","","Burabura Chochin / Mount Rokkon mount","" +"982","Crimson Rise","","","Shishioji / Another Mount Rokkon mount","" +"983","The Land Reborn","","","Kupo Kupo Adventure - Title Screen","" +"984","Pom from the Heavens","","","Kupo Kupo Adventure - Gameplay","" +"985","Dreams Aloft","","","Garlond GL-IS mount","" +"986","A Gentleman to Walk with Me","","","Somehow Further Hildibrand Adventures ending","" +"987","FINAL FANTASY IV: The Final Battle (Endwalker)","","","The Abyssal Fracture (Zeromus) phase 1","" +"988","The Red Wings (Endwalker)","","","The Abyssal Fracture (Zeromus) phase 2","" +"989","Kingdom of Baron (Endwalker)","","","The Lunar Subterrane","" +"990","O Speaker, Slumber","","","","" +"991","O Hunter, Rejoice","","","","" +"992","Fair Winds to Guide","","","Thaleia between bosses","" +"993","Course Uncharted","","","Thaleia Boss 1 (Thaliak), Boss 2 (Llymlaen), Boss 3 (Oschon)","" +"994","Myths of the Realm","","","Thaleia final boss (Eulogia)","" +"995","FINAL FANTASY IV: The Final Battle (Endwalker)","","","Lynx of Abyssal Grief mount / The Abyssal Fracture (Zeromus) mount","" +"996","O Speaker, Slumber","","","","" +"997","O Hunter, Rejoice","","","","" +"998","Prelude - Tales","","","Apocryphal Bahamut / all Lynx mount","" +"999","Endwalker - Footfalls/Vibrant Voices/Troian Beauty (Endwalker)/Forged in Crimson/Another Moon/???/The Ewer Brimmeth","","","Patch 6.56 credits","" +"1000","","","","","" +"20000","","","","","" +"20001","Tonitrua ex Machina","","","FFXVI Crossover","" +"20002","Idylls of the Empire","","","FFXVI Crossover","" +"20003","Forevermore - The Grand Duchy of Rosaria","","","FFXVI Crossover","" +"20004","Before the Storm - Caer Norvent","","","FFXVI Crossover","" +"20005","The State of the Realm","","","FFXVI Crossover","" +"20006","Who I Really Am","","","FFXVI Crossover","" +"20007","Away (Refrain)","","","FFXVI Crossover","" +"20008","To Sail Forbidden Seas","","","FFXVI Crossover","" +"20009","Find the Flame","","","FFXVI Crossover","" +"20010","Land of Eikons","","","FFXVI Crossover","" +"20011","Find the Flame","","","Torgal / FFXVI Crossover Mount","" +"20012","Everybody Falls (Fall Guys Theme)","","","","" +"20013","Sir Falls-A-Lot (William Fell)","","","","" +"20014","Fall 'N' Roll","","","","" +"20015","Clumsy Shuffle","","","","" +"20016","Fall for the Queen Bean","","","","" +"20017","Final Fall","","","","" +"20018","???","","","Commonly called 'Loading'","" +"20019","???","","","Commonly called 'Round Introduction'","" +"20020","Didn't Fall! (You Win)","","","","" +"20021","Everybody Falls (Fall Guys Theme)","","","","" +"20022","","","","","" +"20023","Dawntrail","","","","" +"20024","Dawntrail","","","Instrumental","" +"20025","Smile","","","","" +"20026","???","","","","" +"20027","???","","","","" +"20028","???","","","","" +"20029","???","","","","" +"20030","???","","","","" +"20031","???","","","","" +"20032","???","","","","" +"20033","???","","","","" +"20034","???","","","","" +"20035","???","","","","" +"20036","???","","","","" +"20037","???","","","","" +"20038","???","","","","" +"20039","???","","","","" +"20040","???","","","","" +"20041","Swords of Fury (FFIX)","","","Living Memory cutscenes","" +"20042","???","","","","" +"20043","Something to Protect (FFIX)","","","Living Memory cutscenes","" +"20044","???","","","","" +"20045","Morrow's Might","","","Tuliyollal Day","" +"20046","???","","","Tuliyollal Night","" +"20047","Starless Skyline","","","Solution Nine Day and Night","" +"20048","Windswept Echoes","","","Urqopacha Day","" +"20049","???","","","Urqopacha Night","" +"20050","Of Glittering Wings","","","Kozama'uka Day","" +"20051","???","","","Kozama'uka Night","" +"20052","Emerald under Sapphire","","","Yak T'el Day","" +"20053","???","","","Yak T'el Night","" +"20054","Ceruleum Smoke at High Noon","","","Shaaloani Day","" +"20055","???","","","Shaaloani Night","" +"20056","Flash in the Dark","","","Heritage Found Day","" +"20057","???","","","Heritage Found Night","" +"20058","Bygone Serenity","","","Living Memory (during MSQ)","" +"20059","Bygone Serenity","","","Living Memory (post-MSQ, faded/distant version)","" +"20060","???","","","","" +"20061","???","","","The Backroom","" +"20062","Pastoral Pleasures","","","Kozama'uka & Urqopacha sanctuaries","" +"20063","Life Bound by Honor","","","Yok Tural sanctuaries","" +"20064","Desertwalkers","","","Xak Tural sanctuaries (excl Heritage Found 1st aetheryte)","" +"20065","Blade's Exaltation","","","Urqopacha battle","" +"20066","Blade's Exaltation","","","Kozama'uka battle","" +"20067","Blade's Exaltation","","","Yak T'el battle","" +"20068","Blade's Exaltation","","","Shaaloani battle","" +"20069","Blade's Exaltation","","","Heritage Found battle","" +"20070","???","","","","" +"20071","???","","","","" +"20072","The Skyruin","","","Worqor Lar Dor / Worqor Lar Dor Extreme (Valigarmanda)","" +"20073","Seeking Purpose","","","Everkeep / Everkeep Extreme (Zoraal Ja)","" +"20074","???","","","The Interphos (Queen Eternal) phase 1","" +"20075","???","","","The Interphos (Queen Eternal) phase 2","" +"20076","Punuitiy Crossing","","","Ihuykatumu","" +"20077","Empyrean Peak","","","Worqor Zormor","" +"20078","Lost in the Deep","","","The Skydeep Cenote","" +"20079","In Fulgur and Fire","","","Vanguard","" +"20080","Anatomy of Existence","","","Origenics","" +"20081","A Trail Unending","","","Alexandria","" +"20082","Blessings on the Bluffs","","","Tender Valley","" +"20083","Court Jesters (Dawntrail)","","","The Strayborough Deadwalk","" +"20084","Roads Forsaken","","","Dawntrail dungeon bosses","" +"20085","???","","","Dawntrail final dungeon boss","" +"20086","???","","","","" +"20087","","","","","" +"20088","","","","","" +"20089","","","","","" +"20090","","","","","" +"20091","","","","","" +"20092","","","","","" +"20093","","","","","" +"20094","???","","","","" +"20095","The Skyruin","","","Wings of Ruin mount / Worqor Lar Dor Extreme (Valigarmanda) mount","" +"20096","Seeking Purpose","","","Wings of Resolve mount / Everkeep Extreme (Zoraal Ja) mount","" +"20097","Battle 1 from FINAL FANTASY IX","","","Ark Mount","" +"20098","","","","","" +"20099","","","","","" +"20100","???","","","","" +"20101","???","","","Mascot March, Mascot Mayhem, and Mascot Murder FATEs / Mica the Magical Mu","" +"20102","???","","","","" +"20103","???","","","","" +"20104","","","","","" +"20105","","","","","" +"20106","","","","","" +"20107","","","","","" +"20108","","","","","" +"20109","","","","","" +"20110","","","","","" +"20111","","","","","" +"20112","","","","","" +"20113","","","","","" +"20114","","","","","" +"20115","","","","","" +"20116","","","","","" +"20117","","","","","" +"20118","","","","","" +"20119","","","","","" +"20120","","","","","" +"20121","","","","","" +"20122","","","","","" +"20123","","","","","" +"20124","","","","","" +"20125","","","","","" +"20126","","","","","" +"20127","","","","","" +"20128","","","","","" +"20129","","","","","" +"20130","","","","","" +"20131","","","","","" +"20132","","","","","" +"20133","","","","","" +"20134","","","","","" +"20135","","","","","" +"20136","","","","","" +"20137","","","","","" +"20138","","","","","" +"20139","","","","","" +"20140","","","","","" +"20141","","","","","" +"20142","","","","","" +"20143","","","","","" +"20144","","","","","" +"20145","","","","","" +"20146","","","","","" +"20147","","","","","" \ No newline at end of file diff --git a/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.deps.json b/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.deps.json new file mode 100644 index 0000000..f8e9bbe --- /dev/null +++ b/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "WorldMapEnhancer/1.0.6.2": { + "runtime": { + "WorldMapEnhancer.dll": {} + } + } + } + }, + "libraries": { + "WorldMapEnhancer/1.0.6.2": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.dll b/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.dll new file mode 100644 index 0000000..d96b0d4 Binary files /dev/null and b/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.dll differ diff --git a/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.json b/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.json new file mode 100644 index 0000000..f7d3535 --- /dev/null +++ b/.recovery/extract/WorldMapEnhancer/WorldMapEnhancer.json @@ -0,0 +1,23 @@ +{ + "Author": "aRkker", + "Name": "World Map Enhancer", + "InternalName": "WorldMapEnhancer", + "AssemblyVersion": "1.0.6.2", + "Description": "Simply zoom out by right clicking the world map, like God intended it", + "ApplicableVersion": "any", + "Tags": [ + "world", + "map", + "enhance", + "rightclick", + "zoom" + ], + "DalamudApiLevel": 14, + "LoadRequiredState": 0, + "LoadSync": false, + "CanUnloadAsync": false, + "LoadPriority": 0, + "Punchline": "Right click to zoom out the big map", + "Changelog": "1.0.3.0\nDawntrail support 2.0\n\n1.0.1.0\nAPI 8, NET7", + "AcceptsFeedback": true +} \ No newline at end of file diff --git a/.recovery/inventory.csv b/.recovery/inventory.csv new file mode 100644 index 0000000..d0cae4d --- /dev/null +++ b/.recovery/inventory.csv @@ -0,0 +1,6 @@ +"PluginFolder","AssemblyName","RuntimeTarget","ZipPath","DllPath","HasPdb","ExtractPath","ProjectPath" +"AntiDickheadChatmodule","AntiDickheadChatmodule",".NETCoreApp,Version=v10.0","H:\src\aRkker-XIV-Plugins\plugins\AntiDickheadChatmodule\latest.zip","H:\src\aRkker-XIV-Plugins\.recovery\extract\AntiDickheadChatmodule\AntiDickheadChatmodule.dll","False","H:\src\aRkker-XIV-Plugins\.recovery\extract\AntiDickheadChatmodule","H:\src\aRkker-XIV-Plugins\.recovery\decompiled\AntiDickheadChatmodule" +"CrystallineConflictWinsTracker","CrystallineConflictWinsTracker",".NETCoreApp,Version=v7.0","H:\src\aRkker-XIV-Plugins\plugins\CrystallineConflictWinsTracker\latest.zip","H:\src\aRkker-XIV-Plugins\.recovery\extract\CrystallineConflictWinsTracker\CrystallineConflictWinsTracker.dll","True","H:\src\aRkker-XIV-Plugins\.recovery\extract\CrystallineConflictWinsTracker","H:\src\aRkker-XIV-Plugins\.recovery\decompiled\CrystallineConflictWinsTracker" +"MultiboxMutexer","MultiboxMutexer",".NETCoreApp,Version=v7.0","H:\src\aRkker-XIV-Plugins\plugins\MultiboxMutexer\latest.zip","H:\src\aRkker-XIV-Plugins\.recovery\extract\MultiboxMutexer\MultiboxMutexer.dll","True","H:\src\aRkker-XIV-Plugins\.recovery\extract\MultiboxMutexer","H:\src\aRkker-XIV-Plugins\.recovery\decompiled\MultiboxMutexer" +"OmicronMountMusicFixer","OmicronMountMusicFixer",".NETCoreApp,Version=v10.0","H:\src\aRkker-XIV-Plugins\plugins\OmicronMountMusicFixer\latest.zip","H:\src\aRkker-XIV-Plugins\.recovery\extract\OmicronMountMusicFixer\OmicronMountMusicFixer.dll","False","H:\src\aRkker-XIV-Plugins\.recovery\extract\OmicronMountMusicFixer","H:\src\aRkker-XIV-Plugins\.recovery\decompiled\OmicronMountMusicFixer" +"WorldMapEnhancer","WorldMapEnhancer",".NETCoreApp,Version=v10.0","H:\src\aRkker-XIV-Plugins\plugins\WorldMapEnhancer\latest.zip","H:\src\aRkker-XIV-Plugins\.recovery\extract\WorldMapEnhancer\WorldMapEnhancer.dll","False","H:\src\aRkker-XIV-Plugins\.recovery\extract\WorldMapEnhancer","H:\src\aRkker-XIV-Plugins\.recovery\decompiled\WorldMapEnhancer" diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/.nupkg.metadata b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/.nupkg.metadata new file mode 100644 index 0000000..cda32a6 --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/.nupkg.metadata @@ -0,0 +1,4 @@ +{ + "version": 2, + "contentHash": "E8/f/CbiQ5PAbb69NyKd946yAc/Ru2cI5IUBdRVQesf+GY68/VF8QM/wCzFhsXCasTwWk+lmnc4n4h6sQw0UdA==" +} \ No newline at end of file diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/.signature.p7s b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/.signature.p7s new file mode 100644 index 0000000..b34e80a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/.signature.p7s differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ILSpyCmdNuGetPackageIcon.png b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ILSpyCmdNuGetPackageIcon.png new file mode 100644 index 0000000..48841d7 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ILSpyCmdNuGetPackageIcon.png differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/README.md b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/README.md new file mode 100644 index 0000000..14cd705 --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/README.md @@ -0,0 +1,195 @@ +# ilspycmd .NET Tool + +To install: + +``` +dotnet tool install --global ilspycmd +``` + +Help output (`ilspycmd --help`): + +``` +ilspycmd: 9.0.0.7847 +ICSharpCode.Decompiler: 9.0.0.7847 + +dotnet tool for decompiling .NET assemblies and generating portable PDBs + +Usage: ilspycmd [options] + +Arguments: + Assembly file name(s) The list of assemblies that is being decompiled. This argument is mandatory. + +Options: + -v|--version Show version of ICSharpCode.Decompiler used. + -h|--help Show help information. + -o|--outputdir The output directory, if omitted decompiler output is written to standard out. + -p|--project Decompile assembly as compilable project. This requires the output directory + option. + -t|--type The fully qualified name of the type to decompile. + -il|--ilcode Show IL code. + --il-sequence-points Show IL with sequence points. Implies -il. + -genpdb|--generate-pdb Generate PDB. + -usepdb|--use-varnames-from-pdb Use variable names from PDB. + -l|--list Lists all entities of the specified type(s). Valid types: c(lass), + i(nterface), s(truct), d(elegate), e(num) + -lv|--languageversion C# Language version: CSharp1, CSharp2, CSharp3, CSharp4, CSharp5, CSharp6, + CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, CSharp10_0, + Preview or Latest + Allowed values are: CSharp1, CSharp2, CSharp3, CSharp4, CSharp5, CSharp6, + CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, CSharp10_0, + CSharp11_0, Preview, CSharp12_0, Latest. + Default value is: Latest. + -r|--referencepath Path to a directory containing dependencies of the assembly that is being + decompiled. + --no-dead-code Remove dead code. + --no-dead-stores Remove dead stores. + -d|--dump-package Dump package assemblies into a folder. This requires the output directory + option. + --nested-directories Use nested directories for namespaces. + --disable-updatecheck If using ilspycmd in a tight loop or fully automated scenario, you might want + to disable the automatic update check. + --generate-diagrammer Generates an interactive HTML diagrammer app from selected types in the target + assembly - to the --outputdir or in a 'diagrammer' folder next to to the + assembly by default. + --generate-diagrammer-include An optional regular expression matching Type.FullName used to whitelist types + to include in the generated diagrammer. + --generate-diagrammer-exclude An optional regular expression matching Type.FullName used to blacklist types + to exclude from the generated diagrammer. + --generate-diagrammer-report-excluded Outputs a report of types excluded from the generated diagrammer - whether by + default because compiler-generated, explicitly by + '--generate-diagrammer-exclude' or implicitly by + '--generate-diagrammer-include'. You may find this useful to develop and debug + your regular expressions. + --generate-diagrammer-docs The path or file:// URI of the XML file containing the target assembly's + documentation comments. You only need to set this if a) you want your diagrams + annotated with them and b) the file name differs from that of the assmbly. To + enable XML documentation output for your assmbly, see + https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/#create-xml-documentation-output + --generate-diagrammer-strip-namespaces Optional space-separated namespace names that are removed for brevity from XML + documentation comments. Note that the order matters: e.g. replace + 'System.Collections' before 'System' to remove both of them completely. + +Remarks: + -o is valid with every option and required when using -p. + +Examples: + Decompile assembly to console out. + ilspycmd sample.dll + + Decompile assembly to destination directory (single C# file). + ilspycmd -o c:\decompiled sample.dll + + Decompile assembly to destination directory, create a project file, one source file per type. + ilspycmd -p -o c:\decompiled sample.dll + + Decompile assembly to destination directory, create a project file, one source file per type, + into nicely nested directories. + ilspycmd --nested-directories -p -o c:\decompiled sample.dll + + Generate a HTML diagrammer containing all type info into a folder next to the input assembly + ilspycmd sample.dll --generate-diagrammer + + Generate a HTML diagrammer containing filtered type info into a custom output folder + (including types in the LightJson namespace while excluding types in nested LightJson.Serialization namespace) + ilspycmd sample.dll --generate-diagrammer -o c:\diagrammer --generate-diagrammer-include LightJson\\..+ --generate-diagrammer-exclude LightJson\\.Serialization\\..+ +``` + +## Generate HTML diagrammers + +Once you have an output folder in mind, you can adopt either of the following strategies +to generate a HTML diagrammer from a .Net assembly using the console app. + +### Manually before use + +**Create the output folder** in your location of choice and inside it **a new shell script**. + +Using the CMD shell in a Windows environment for example, you'd create a `regenerate.cmd` looking somewhat like this: + +
+..\..\path\to\ilspycmd.exe ..\path\to\your\assembly.dll --generate-diagrammer --outputdir .
+
+ +With this script in place, run it to (re-)generate the HTML diagrammer at your leisure. Note that `--outputdir .` directs the output to the current directory. + +### Automatically + +If you want to deploy an up-to-date HTML diagrammer as part of your live documentation, +you'll want to automate its regeneration to keep it in sync with your code base. + +For example, you might like to share the diagrammer on a web server or - in general - with users +who cannot or may not regenerate it; lacking either access to the ilspycmd console app or permission to use it. + +In such cases, you can dangle the regeneration off the end of either your build or deployment pipeline. +Note that the macros used here apply to [MSBuild](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild) for [Visual Studio](https://learn.microsoft.com/en-us/visualstudio/ide/reference/pre-build-event-post-build-event-command-line-dialog-box) and your mileage may vary with VS for Mac or VS Code. + +#### After building + +To regenerate the HTML diagrammer from your output assembly after building, +add something like the following to your project file. +Note that the `Condition` here is optional and configures this step to only run after `Release` builds. + +```xml + + + +``` + +#### After publishing + +If you'd rather regenerate the diagram after publishing instead of building, all you have to do is change the `AfterTargets` to `Publish`. +Note that the `Target` `Name` doesn't matter here and that the diagrammer is generated into a folder in the `PublishDir` instead of the `ProjectDir`. + +```xml + + + +``` + +### Usage tips + +**Compiler-generated** types and their nested types are **excluded by default**. + +Consider sussing out **big source assemblies** using [ILSpy](https://github.com/icsharpcode/ILSpy) first to get an idea about which subdomains to include in your diagrammers. Otherwise you may experience long build times and large file sizes for the diagrammer as well as a looong type selection opening it. At some point, mermaid may refuse to render all types in your selection because their definitions exceed the maximum input size. If that's where you find yourself, you may want to consider +- using `--generate-diagrammer-include` and `--generate-diagrammer-exclude` to **limit the scope of the individual diagrammer to a certain subdomain** +- generating **multiple diagrammers for different subdomains**. + +### Advanced configuration examples + +Above examples show how the most important options are used. Let's have a quick look at the remaining ones, which allow for customization in your project setup and diagrams. + +#### Filter extracted types + +Sometimes the source assembly contains way more types than are sensible to diagram. Types with metadata for validation or mapping for example. Or auto-generated types. +Especially if you want to tailor a diagrammer for a certain target audience and hide away most of the supporting type system to avoid noise and unnecessary questions. + +In these scenarios you can supply Regular Expressions for types to `--generate-diagrammer-include` (white-list) and `--generate-diagrammer-exclude` (black-list). +A third option `--generate-diagrammer-report-excluded` will output a `.txt` containing the list of effectively excluded types next to the HTML diagrammer containing the effectively included types. + +
+ilspycmd.exe --generate-diagrammer-include Your\.Models\..+ --generate-diagrammer-exclude .+\+Metadata|.+\.Data\..+Map --generate-diagrammer-report-excluded ..\path\to\your\assembly.dll --generate-diagrammer --outputdir .
+
+ +This example +- includes all types in the top-level namespace `Your.Models` +- while excluding + - nested types called `Metadata` and + - types ending in `Map` in descendant `.Data.` namespaces. + +#### Strip namespaces from XML comments + +You can reduce the noise in the XML documentation comments on classes on your diagrams by supplying a space-separated list of namespaces to omit from the output like so: + +
+ilspycmd.exe --generate-diagrammer-strip-namespaces System.Collections.Generic System ..\path\to\your\assembly.dll --generate-diagrammer --output-folder .
+
+ +Note how `System` is replaced **after** other namespaces starting with `System.` to achieve complete removal. +Otherwise `System.Collections.Generic` wouldn't match the `Collections.Generic` left over after removing `System.`, resulting in partial removal only. + +#### Adjust for custom XML documentation file names + +If - for whatever reason - you have customized your XML documentation file output name, you can specify a custom path to pick it up from. + +
+ilspycmd.exe --generate-diagrammer-docs ..\path\to\your\docs.xml ..\path\to\your\assembly.dll --generate-diagrammer --output-folder .
+
diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.10.0.1.8346.nupkg b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.10.0.1.8346.nupkg new file mode 100644 index 0000000..3bbdd39 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.10.0.1.8346.nupkg differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.10.0.1.8346.nupkg.sha512 b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.10.0.1.8346.nupkg.sha512 new file mode 100644 index 0000000..ecfc1a6 --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.10.0.1.8346.nupkg.sha512 @@ -0,0 +1 @@ +oTQvPJnDlVh4dqXAAiWPft700WXXkXoePmRPNN9fMqcbEqrfwEhmq6gz1yFWpAjbVgHAbSsRmxJXO8f9cuQ6ag== \ No newline at end of file diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.nupkg b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.nupkg new file mode 100644 index 0000000..3bbdd39 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.nupkg differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.nuspec b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.nuspec new file mode 100644 index 0000000..aa7284d --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/ilspycmd.nuspec @@ -0,0 +1,19 @@ + + + + ilspycmd + 10.0.1.8346 + ILSpy Team + MIT + https://licenses.nuget.org/MIT + ILSpyCmdNuGetPackageIcon.png + README.md + https://github.com/icsharpcode/ILSpy/ + Command-line decompiler using the ILSpy decompilation engine + Copyright 2011-2026 AlphaSierraPapa + + + + + + \ No newline at end of file diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/DotnetToolSettings.xml b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/DotnetToolSettings.xml new file mode 100644 index 0000000..61d5a48 --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/DotnetToolSettings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.Decompiler.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.Decompiler.dll new file mode 100644 index 0000000..7aa4d4f Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.Decompiler.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.Decompiler.xml b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.Decompiler.xml new file mode 100644 index 0000000..ff85fbd --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.Decompiler.xml @@ -0,0 +1,17611 @@ + + + + ICSharpCode.Decompiler + + + + + Currently unused; we'll probably use the LdToken ILInstruction as annotation instead when LdToken + support gets reimplemented. + + + + + Retrieves the associated with this AstNode, or null if no symbol + is associated with the node. + + + + + Retrieves the associated with this , + or if no resolve result is associated with the node. + + + + + Retrieves the associated with this , + or null if no variable is associated with this identifier. + + + + + Retrieves the associated with this , + or null if no variable is associated with this initializer. + + + + + Retrieves the associated with this , + or null if no variable is associated with this foreach statement. + + + + + Adds an to this initializer. + + + + + Adds an to this foreach statement. + + + + + Copies all annotations from to . + + + + + Copies all annotations from + to . + + + + + Represents a reference to a local variable. + + + + + Annotates a with the instructions for the GetEnumerator, MoveNext + and get_Current calls. + + + + + Annotates the top-level block statement of a function + with the implicitly executed return/yield break. + + + + + Annotates an expression when an implicit user-defined conversion was omitted. + + + + + Annotates a QueryGroupClause with the ILFunctions of each (implicit lambda) expression. + + + + + Annotates a QueryJoinClause with the ILFunctions of each (implicit lambda) expression. + + + + + Annotates an out DirectionExpression if the out variable can be declared implicitly typed. + + + + + Converts a call to an Add method to a collection initializer expression. + + + + + Add calls to AsRefReadOnly for in parameters that did not have an explicit DirectionExpression yet. + + + + + TypeName VariableDesignation + + + + + Expression switch { SwitchSections } + + + + + Pattern => Expression + + + + + Expression with Initializer + + + + + BaseType "(" Argument { "," Argument } ")" + + + + + Identifier + + + + + ( VariableDesignation (, VariableDesignation)* ) + + + + + Gets the ancestors of this node (excluding this node itself) + + + + + Gets the ancestors of this node (including this node itself) + + + + + Gets all descendants of this node (excluding this node itself) in pre-order. + + + + + Gets all descendants of this node (including this node itself) in pre-order. + + + + + Gets the first child with the specified role. + Returns the role's null object if the child is not found. + + + + + Adds a child without performing any safety checks. + + + + + Removes this node from its parent. + + + + + Replaces this node with the new node. + + + + + Clones the whole subtree starting at this AST node. + + Annotations are copied over to the new nodes; and any annotations implementing ICloneable will be cloned. + + + + Gets the next node which fullfills a given predicate + + The next node. + The predicate. + + + + Gets the previous node which fullfills a given predicate + + The next node. + The predicate. + + + + Gets the next sibling which fullfills a given predicate + + The next node. + The predicate. + + + + Gets the next sibling which fullfills a given predicate + + The next node. + The predicate. + + + + Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End exclusive) + + + + + Gets the node specified by pred at location. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End exclusive) + + + + + Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End exclusive) + + + + + Gets the node specified by T at location. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End exclusive) + + + + + Gets the node specified by pred at the location line, column. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End inclusive) + + + + + Gets the node specified by pred at location. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End inclusive) + + + + + Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End inclusive) + + + + + Gets the node specified by T at location. This is useful for getting a specific node from the tree. For example searching + the current method declaration. + (End inclusive) + + + + + Gets the node that fully contains the range from startLocation to endLocation. + + + + + Returns the root nodes of all subtrees that are fully contained in the specified region. + + + + + Returns the root nodes of all subtrees that are fully contained between and (inclusive). + + + + + Gets the node as formatted C# output. + + + Formatting options. + + + + + Returns true, if the given coordinates (line, column) are in the node. + + + True, if the given coordinates are between StartLocation and EndLocation (exclusive); otherwise, false. + + + + + Returns true, if the given coordinates are in the node. + + + True, if location is between StartLocation and EndLocation (exclusive); otherwise, false. + + + + + Returns true, if the given coordinates (line, column) are in the node. + + + True, if the given coordinates are between StartLocation and EndLocation (inclusive); otherwise, false. + + + + + Returns true, if the given coordinates are in the node. + + + True, if location is between StartLocation and EndLocation (inclusive); otherwise, false. + + + + + Represents the children of an AstNode that have a specific role. + + + + + Returns the first element for which the predicate returns true, + or the null node (AstNode with IsNull=true) if no such object is found. + + + + + Returns the last element for which the predicate returns true, + or the null node (AstNode with IsNull=true) if no such object is found. + + + + + Applies the to all nodes in this collection. + + + + + A type reference in the C# AST. + + + + + Gets whether this type is a SimpleType "var". + + + + + Gets the name lookup mode from the context (looking at the ancestors of this ). + + + + + Creates a pointer type from this type by nesting it in a . + If this type already is a pointer type, this method just increases the PointerRank of the existing pointer type. + + + + + Creates an array type from this type by nesting it in a . + If this type already is an array type, the additional rank is prepended to the existing array specifier list. + Thus, new SimpleType("T").MakeArrayType(1).MakeArrayType(2) will result in "T[,][]". + + + + + Creates a nullable type from this type by nesting it in a . + + + + + Creates a C# 7 ref type from this type by nesting it in a . + + + + + Builds an expression that can be used to access a static member on this type. + + + + + Builds an expression that can be used to access a static member on this type. + + + + + Creates a simple AstType from a dotted name. + Does not support generics, arrays, etc. - just simple dotted names, + e.g. namespace names. + + + + + Gets/sets whether this type has a 'ref' specifier. + This is used for C# 7 ref locals/ref return. + Parameters use ParameterDeclaration.ParameterModifier instead. + + + + + Gets/sets whether this type has a 'readonly' specifier. + This is used for C# 7.2 'ref readonly' locals/ref return. + Parameters use ParameterDeclaration.ParameterModifier instead. + + + + + [,,,] + + + + + Represents a token in C#. Note that the type of the token is defined through the TokenRole. + + + In all non null c# token nodes the Role of a CSharpToken must be a TokenRole. + + + + + AST visitor with a default implementation that visits all node depth-first. + + + + + AST visitor with a default implementation that visits all node depth-first. + + + + + AST visitor with a default implementation that visits all node depth-first. + + + + + Represents a 'cref' reference in XML documentation. + + + + + Gets/Sets the entity type. + Possible values are: + SymbolKind.Operator for operators, + SymbolKind.Indexer for indexers, + SymbolKind.TypeDefinition for references to primitive types, + and SymbolKind.None for everything else. + + + + + Gets/Sets the operator type. + This property is only used when SymbolKind==Operator. + + + + + Gets/Sets whether a parameter list was provided. + + + + + Gets/Sets the declaring type. + + + + + Gets/sets the member name. + This property is only used when SymbolKind==None. + + + + + Gets/Sets the return type of conversion operators. + This property is only used when SymbolKind==Operator and OperatorType is explicit or implicit. + + + + + [async] delegate(Parameters) {Body} + + + + + new { [ExpressionList] } + + + + + new Type[Dimensions] + + + + + Gets additional array ranks (those without size info). + Empty for "new int[5,1]"; will contain a single element for "new int[5][]". + + + + + { Elements } + + + + + For ease of use purposes in the resolver the ast representation + of { a, b, c } is { {a}, {b}, {c} }. + If IsSingleElement is true then this array initializer expression is a generated one. + That has no meaning in the source code (and contains no brace tokens). + + + + + Single elements in array initializers are represented with this special class. + + + + + Expression as TypeReference + + + + + Left Operator= Right + + + + + Gets the binary operator for the specified compound assignment operator. + Returns null if 'op' is not a compound assignment. + + + + left = right + + + left += right + + + left -= right + + + left *= right + + + left /= right + + + left %= right + + + left <<= right + + + left >>= right + + + left >>>= right + + + left &= right + + + left |= right + + + left ^= right + + + Any operator (for pattern matching) + + + + base + + + + + Left Operator Right + + + + + Any binary operator (used in pattern matching) + + + + left & right + + + left | right + + + left && right + + + left || right + + + left ^ right + + + left > right + + + left >= right + + + left == right + + + left != right + + + left < right + + + left <= right + + + left + right + + + left - right + + + left * right + + + left / right + + + left % right + + + left << right + + + left >> right + + + left >>> right + + + left ?? right + + + left .. right + left and right are optional = may be Expression.Null + + + left is right + right must be a pattern + + + + (CastTo)Expression + + + + + checked(Expression) + + + + + Condition ? TrueExpression : FalseExpression + + + + + default(Type) + + + + + ref Expression + + + + + Base class for expressions. + + + This class is useful even though it doesn't provide any additional functionality: + It can be used to communicate more information in APIs, e.g. "this subnode will always be an expression" + + + + + Target[Arguments] + + + + + { Expression , Alignment : Suffix } + + + + + Target(Arguments) + + + + + Expression is Type + + + + + [async] Parameters => Body + + + + + Target.MemberName + + + + + Represents a named argument passed to a method or attribute. + name: expression + + + + + name = expression + This isn't the same as 'assign' even though it has the same syntax. + This expression is used in object initializers and for named attribute arguments [Attr(FieldName = value)]. + + + + + null + + + + + new Type(Arguments) { Initializer } + + + + + out type expression + + + + + ( Expression ) + + + + + Gets whether the expression acts like a parenthesized expression, + i.e. whether information about the expected type (for lambda type inference) flows + into the inner expression. + + Returns true for ParenthesizedExpression, CheckedExpression or UncheckedExpression; false otherwise. + + + + Unpacks the given expression if it is a ParenthesizedExpression, CheckedExpression or UncheckedExpression. + + + + + Target->MemberName + + + + + Form of a C# literal. + + + + + Represents a literal value. + + + + + Represents a query continuation. + "(from .. select ..) into Identifier" or "(from .. group .. by ..) into Identifier" + Note that "join .. into .." is not a query continuation! + + This is always the first(!!) clause in a query expression. + The tree for "from a in b select c into d select e" looks like this: + new QueryExpression { + new QueryContinuationClause { + PrecedingQuery = new QueryExpression { + new QueryFromClause(a in b), + new QuerySelectClause(c) + }, + Identifier = d + }, + new QuerySelectClause(e) + } + + + + + Represents a join or group join clause. + + + + + sizeof(Type) + + + + + stackalloc Type[Count] + + + + + this + + + + + throw Expression + + + + + typeof(Type) + + + + + Represents an AstType as an expression. + This is used when calling a method on a primitive type: "int.Parse()" + + + + + Operator Expression + + + + + Any unary operator (used in pattern matching) + + + + Logical not (!a) + + + Bitwise not (~a) + + + Unary minus (-a) + + + Unary plus (+a) + + + Pre increment (++a) + + + Pre decrement (--a) + + + Post increment (a++) + + + Post decrement (a--) + + + Dereferencing (*a) + + + Get address (&a) + + + C# 5.0 await + + + C# 6 null-conditional operator. + Occurs as target of member reference or indexer expressions + to indicate ?. or ?[]. + Corresponds to nullable.unwrap in ILAst. + + + + + Wrapper around a primary expression containing a null conditional operator. + Corresponds to nullable.rewrap in ILAst. + This has no syntax in C#, but the node is used to ensure parentheses are inserted where necessary. + + + + + Implicit call of "operator true". + + + + + C# 8 postfix ! operator (dammit operator) + + + + + C# 8 prefix ^ operator + + + + + C# 9 not pattern + + + + + C# 9 relational pattern + + + + + C# 9 relational pattern + + + + + C# 9 relational pattern + + + + + C# 9 relational pattern + + + + + unchecked(Expression) + + + + + Represents undocumented expressions. + + + + + Attribute(Arguments) + + + + + [AttributeTarget: Attributes] + + + + + "//" comment + + + + + "/* */" comment + + + + + "///" comment + + + + + Inactive code (code in non-taken "#if") + + + + + "/** */" comment + + + + + Returns true if the is Documentation or MultiLineDocumentation. + + + + + where TypeParameter : BaseTypes + + + new(), struct and class constraints are represented using a PrimitiveType "new", "struct" or "class" + + + + + delegate ReturnType Name<TypeParameters>(Parameters) where Constraints; + + + + + extern alias IDENTIFIER; + + + + + namespace Name { Members } + + + + + Gets the full namespace name (including any parent namespaces) + + + + + For an '#if' directive, specifies whether the condition evaluated to true. + + + + + C# 9 'record class' + + + + + C# 10 'record struct' + + + + + class Name<TypeParameters> : BaseTypes where Constraints; + + + + + [in|out] Name + + Represents a type parameter. + Note: mirroring the C# syntax, constraints are not part of the type parameter declaration, but belong + to the parent type or method. + + + + + using Alias = Import; + + + + + using Import; + + + + + AST visitor. + + + + + AST visitor. + + + + + AST visitor. + + + + + Matches identifier expressions that have the same identifier as the referenced variable/type definition/method definition. + + + + + Special value used to match any modifiers during pattern matching. + + + + + AstType + + + + + Type or delegate declaration + + + + + Comment or whitespace or pre-processor directive + + + + + Placeholder for a pattern + + + + + Matches any node. + + Does not match null nodes. + + + + Matches any node. + + Does not match null nodes. + + + + Matches the last entry in the specified named group. + + + + + Container for the backtracking info. + + + + + Matches one of several alternatives. + + + + + AST node that supports pattern matching. + + + + + Performs a pattern matching operation. + this is the pattern, is the AST that is being matched. + + + A match object. Check to see whether the match was successful. + + + Patterns are ASTs that contain special pattern nodes (from the PatternMatching namespace). + However, it is also possible to match two ASTs without any pattern nodes - + doing so will produce a successful match if the two ASTs are structurally identical. + + + + + Represents the result of a pattern matching operation. + + + + + Represents a named node within a pattern. + + + + + Base class for all patterns. + + + + + Gets the string that matches any string. + + + + + Represents an optional node. + + + + + Represents the role a node plays within its parent. + + + + + Gets whether the specified node is valid in this role. + + + + + Gets the role with the specified index. + + + + + Represents the role a node plays within its parent. + All nodes with this role have type T. + + + + + Gets the null object used when there's no node with this role. + Not every role has a null object; this property returns null for roles without a null object. + + + Roles used for non-collections should always have a null object, so that no AST property returns null. + However, if a role used for collections only, it may leave out the null object. + + + + + { Statements } + + + + + break; + + + + + checked BodyBlock + + + + + continue; + + + + + "do EmbeddedStatement while(Condition);" + + + + + ; + + + + + Expression; + + + + + fixed (Type Variables) EmbeddedStatement + + + + + foreach (Type VariableName in InExpression) EmbeddedStatement + + + + + for (Initializers; Condition; Iterators) EmbeddedStatement + + + + + Gets the list of initializer statements. + Note: this contains multiple statements for "for (a = 2, b = 1; a > b; a--)", but contains + only a single statement for "for (int a = 2, b = 1; a > b; a--)" (a single VariableDeclarationStatement with two variables) + + + + + "goto Label;" + + + + + or "goto case LabelExpression;" + + + + + Used for "goto case LabelExpression;" + + + + + or "goto default;" + + + + + if (Condition) TrueStatement else FalseStatement + + + + + Label: + + + + + lock (Expression) EmbeddedStatement; + + + + + return Expression; + + + + + Base class for statements. + + + This class is useful even though it doesn't provide any additional functionality: + It can be used to communicate more information in APIs, e.g. "this subnode will always be a statement" + + + + + switch (Expression) { SwitchSections } + + + + + Gets or sets the expression. The expression can be null - if the expression is null, it's the default switch section. + + + + + throw Expression; + + + + + try TryBlock CatchClauses finally FinallyBlock + + + + + catch (Type VariableName) { Body } + + + + + unchecked BodyBlock + + + + + unsafe { Body } + + + + + [ await ] using (ResourceAcquisition) EmbeddedStatement + + + + + Either a VariableDeclarationStatement, or an Expression. + + + + + "while (Condition) EmbeddedStatement" + + + + + yield break; + + + + + yield return Expression; + + + + + Extension methods for the syntax tree. + + + + + Returns true if is bitwise and, bitwise or, or exclusive or. + + + + + Gets/Sets the file name of this syntax tree. + + + + + Gets the conditional symbols used to parse the source file. Note that this list contains + the conditional symbols at the start of the first token in the file - including the ones defined + in the source file. + + + + + Gets the expression that was on top of the parse stack. + This is the only way to get an expression that isn't part of a statment. + (eg. when an error follows an expression). + + This is used for code completion to 'get the expression before a token - like ., <, ('. + + + + + Gets all defined types in this syntax tree. + + + A list containing or nodes. + + + + + A line/column position. + Text editor lines/columns are counted started from one. + + + + + Represents no text location (0, 0). + + + + + Constant of the minimum line. + + + + + Constant of the minimum column. + + + + + Creates a TextLocation instance. + + + + + Gets the line number. + + + + + Gets the column number. + + + + + Gets whether the TextLocation instance is empty. + + + + + Gets a string representation for debugging purposes. + + + + + Gets a hash code. + + + + + Equality test. + + + + + Equality test. + + + + + Equality test. + + + + + Inequality test. + + + + + Compares two text locations. + + + + + Compares two text locations. + + + + + Compares two text locations. + + + + + Compares two text locations. + + + + + Compares two text locations. + + + + + A specific role only used for C# tokens + + + + + Gets the token as string. Note that the token Name and Token value may differ. + + + + + Gets the char length of the token. + + + + + get/set/init/add/remove + + + + + Gets the 'get'/'set'/'init'/'add'/'remove' keyword + + + + + Gets/Sets the type reference of the interface that is explicitly implemented. + Null node if this member is not an explicit interface implementation. + + + + + Name [ CountExpression ] + + + + + Gets/Sets the type reference of the interface that is explicitly implemented. + Null node if this member is not an explicit interface implementation. + + + + + Gets/Sets the type reference of the interface that is explicitly implemented. + Null node if this member is not an explicit interface implementation. + + + + + Gets/Sets the type reference of the interface that is explicitly implemented. + Null node if this member is not an explicit interface implementation. + + + + + Gets the operator type from the method name, or null, if the method does not represent one of the known operator types. + + + + + Gets the method name for the operator type. ("op_Addition", "op_Implicit", etc.) + + + + + Gets whether the operator type is a C# 11 "operator checked". + + + + + Gets the token for the operator type ("+", "implicit", etc.). + Does not include the "checked" modifier. + + + + + Gets/Sets the type reference of the interface that is explicitly implemented. + Null node if this member is not an explicit interface implementation. + + + + + Converts from type system to the C# AST. + + + + + Creates a new TypeSystemAstBuilder. + + + A resolver initialized for the position where the type will be inserted. + + + + + Creates a new TypeSystemAstBuilder. + + + + + Specifies whether the ast builder should add annotations to type references. + The default value is . + + + + + Specifies whether the ast builder should add ResolveResult annotations to AST nodes. + The default value is . + + + + + Controls whether accessibility modifiers are shown. + The default value is . + + + + + Controls whether "private protected" accessibility modifiers are shown. + The default value is . + + + + + Controls whether non-accessibility modifiers are shown. + The default value is . + + + + + Controls whether base type references are shown. + The default value is . + + + + + Controls whether type parameter declarations are shown. + The default value is . + + + + + Controls whether type parameter names are shown for unbound types. + The default value is . + + + + + Controls whether constraints on type parameter declarations are shown. + Has no effect if ShowTypeParameters is false. + The default value is . + + + + + Controls whether the names of parameters are shown. + The default value is . + + + + + Controls whether to show default values of optional parameters, and the values of constant fields. + The default value is . + + + + + Controls whether to show attributes. + The default value is . + + + + + Controls whether to sort attributes, if set to attributes are shown in metadata order. + The default value is . + + + + + Controls whether to use fully-qualified type names or short type names. + The default value is . + + + + + Controls whether to use keywords for builtin types. + The default value is . + + + + + Controls whether to use T? or Nullable<T> for nullable value types. + The default value is . + + + + + Determines the name lookup mode for converting a type name. + + The default value is NameLookupMode.Expression, which means the name is disambiguated + for use in expression context. + + + + + Controls whether to generate a body that throws a System.NotImplementedException. + The default value is . + + + + + Controls whether to generate custom events. + The default value is . + + + + + Controls whether unbound type argument names are inserted in the ast or not. + The default value is . + + + + + Controls whether aliases should be used inside the type name or not. + The default value is . + + + + + Controls whether constants like int.MaxValue are converted to a or . + The default value is . + + + + + Controls whether integral constants should be printed in hexadecimal format. + The default value is . + + + + + Controls whether C# 9 "init;" accessors are supported. + If disabled, emits "set /*init*/;" instead. + + + + + Controls whether C# 9 "record" class types are supported. + + + + + Controls whether C# 10 "record" struct types are supported. + + + + + Controls whether C# 11 "operator >>>" is supported. + + + + + Controls whether C# 11 "operator checked" is supported. + + + + + Controls whether all fully qualified type names should be prefixed with "global::". + + + + + Controls whether C# 14 "extension" declarations are supported. + + + + + Gets whether 'type' is the same as 'typeDef' parameterized with the given type arguments. + + + + + Adds type arguments to the result type. + + The result AST node (a SimpleType or MemberType) + The type parameters + The list of type arguments + Index of first type argument to add + Index after last type argument to add + + + + Creates an Expression for the given constant value. + + Note: the returned expression is not necessarily of the desired type. + However, the returned expression will always be implicitly convertible to rr.Type, + and will have the correct value when being converted in this way. + + + + + Creates an Expression for the given constant value. + + Note: the returned expression is not necessarily of the specified : + For example, ConvertConstantValue(typeof(string), null) results in a null literal, + without a cast to string. + Similarly, ConvertConstantValue(typeof(short), 1) results in the literal 1, + which is of type int. + However, the returned expression will always be implicitly convertible to . + + + + + Creates an Expression for the given constant value. + + + + + Provides an interface to handle annotations in an object. + + + + + Gets all annotations stored on this IAnnotatable. + + + + + Gets the first annotation of the specified type. + Returns null if no matching annotation exists. + + + The type of the annotation. + + + + + Gets the first annotation of the specified type. + Returns null if no matching annotation exists. + + + The type of the annotation. + + + + + Adds an annotation to this instance. + + + The annotation to add. + + + + + Removes all annotations of the specified type. + + + The type of the annotations to remove. + + + + + Removes all annotations of the specified type. + + + The type of the annotations to remove. + + + + + Base class used to implement the IAnnotatable interface. + This implementation is thread-safe. + + + + + Clones all annotations. + This method is intended to be called by Clone() implementations in derived classes. + + AstNode copy = (AstNode)MemberwiseClone(); + copy.CloneAnnotations(); + + + + + + Gets all annotations stored on this AstNode. + + + + + An interface for a service that creates and writes a project file structure + for a specific module being decompiled. + + + + + Writes the content of a new project file for the specified being decompiled. + + The target to write to. + The information about the project being created. + A collection of source files to be included into the project. + The module being decompiled. + + + + An interface that provides common information for a project being decompiled to. + + + + + Gets the assembly resolver active for the project. + + + + + Gets the C# language version of the project. + + + + + Check for overflow and underflow in operators. + + + + + Gets the unique ID of the project. + + + + + Gets the target directory of the project + + + + + Gets the name of the key file being used for strong name signing. Can be null if no file is available. + + + + + A implementation that creates the projects in the SDK style format. + + + + + Creates a new instance of the class. + + A new instance of the class. + + + + + + + A implementation that creates the projects in the default format. + + + + + Creates a new instance of the class. + + A new instance of the class. + + + + + + + A class describing the target framework of a module. + + + + + Initializes a new instance of the class. + + The framework identifier string. Can be null. + The framework version string. Must be greater than 100 (where 100 corresponds to v1.0). + The framework profile. Can be null. + + + + Gets the target framework identifier. Can be null if not defined. + + + + + Gets the target framework moniker. Can be null if not supported. + + + + + Gets the target framework version, e.g. "v4.5". + + + + + Gets the target framework version as integer (multiplied by 100), e.g. 450. + + + + + Gets the target framework profile. Can be null if not set or not available. + + + + + Gets a value indicating whether the target is a portable class library (PCL). + + + + + Helper services for determining the target framework and platform of a module. + + + + + Gets the for the specified . + + The module to get the target framework description for. Cannot be null. + A new instance of the class that describes the specified . + + + + + Gets the string representation (name) of the target platform of the specified . + + The module to get the target framework description for. Cannot be null. + The platform name, e.g. "AnyCPU" or "x86". + + + + Gets exact if is + + + + + Decompiles an assembly into a visual studio project file. + + + + + Gets the setting this instance uses for decompiling. + + + + + The MSBuild ProjectGuid to use for the new project. + + + + + The target directory that the decompiled files are written to. + + + This property is set by DecompileProject() and protected so that overridden protected members + can access it. + + + + + Path to the snk file to use for signing. + null to not sign. + + + + + Cleans up a node name for use as a file name. + + + + + Removes invalid characters from file names and reduces their length, + but keeps file extensions and path structure intact. + + + + + Cleans up a node name for use as a file system name. If is active, + dots are seen as segment separators. Each segment is limited to maxSegmentLength characters. + If is active, we check for file a extension and try to preserve it, + if it's valid. + + + + + Cleans up a node name for use as a directory name. + + + + + Used to test for the "F(G<A,B>(7));" grammar ambiguity. + + + + + Resolves ambiguities in the specified syntax tree. + This method must be called after the InsertParenthesesVisitor, because the ambiguity depends on whether the + final `>` in the possible-type-argument is followed by an opening parenthesis. + + + + + C# ambience. Used to convert type system symbols to text (usually for displaying the symbol to the user; e.g. in editor tooltips) + + + + + Outputs the AST. + + + + + Writes a comma. + + The next node after the comma. + When set prevents printing a space after comma. + + + + Writes an optional comma, e.g. at the end of an enum declaration or in an array initializer + + + + + Writes an optional semicolon, e.g. at the end of a type or namespace declaration. + + + + + Writes a keyword, and all specials up to + + + + + Marks the end of a statement + + + + + Writes a space depending on policy. + + + + + Determines whether the specified identifier is a keyword in the given context. + If is all keywords are treated as unconditional. + + + + + Writes an embedded statement. + + The statement to write. + Determines whether a trailing newline should be written following a block. + Non-blocks always write a trailing newline. + + Blocks may or may not write a leading newline depending on StatementBraceStyle. + Non-blocks always write a leading newline. + + + + + Writes a block statement. + Similar to VisitBlockStatement() except that: + 1) it allows customizing the BraceStyle + 2) it does not write a trailing newline after the '}' (this job is left to the caller) + + + + + Converts special characters to escape sequences within the given string. + + + + + The formatting options factory creates pre defined formatting option styles. + + + + + Creates empty CSharpFormatting options. + + + + + Creates mono indent style CSharpFormatting options. + + + + + Creates sharp develop indent style CSharpFormatting options. + + + + + The K&R style, so named because it was used in Kernighan and Ritchie's book The C Programming Language, + is commonly used in C. It is less common for C++, C#, and others. + + + + + Creates allman indent style CSharpFormatting options used in Visual Studio. + + + + + The Whitesmiths style, also called Wishart style to a lesser extent, is less common today than the previous three. It was originally used in the documentation for the first commercial C compiler, the Whitesmiths Compiler. + + + + + Like the Allman and Whitesmiths styles, GNU style puts braces on a line by themselves, indented by 2 spaces, + except when opening a function definition, where they are not indented. + In either case, the contained code is indented by 2 spaces from the braces. + Popularised by Richard Stallman, the layout may be influenced by his background of writing Lisp code. + In Lisp the equivalent to a block (a progn) + is a first class data entity and giving it its own indent level helps to emphasize that, + whereas in C a block is just syntax. + Although not directly related to indentation, GNU coding style also includes a space before the bracketed + list of arguments to a function. + + + + + Inserts the parentheses into the AST that are needed to ensure the AST can be printed correctly. + For example, if the AST contains + BinaryOperatorExpresson(2, Mul, BinaryOperatorExpression(1, Add, 1))); printing that AST + would incorrectly result in "2 * 1 + 1". By running InsertParenthesesVisitor, the necessary + parentheses are inserted: "2 * (1 + 1)". + + + + + Gets/Sets whether the visitor should insert parentheses to make the code better looking. + If this property is false, it will insert parentheses only where strictly required by the language spec. + + + + + Gets the row number in the C# 4.0 spec operator precedence table. + + + + + Parenthesizes the expression if it does not have the minimum required precedence. + + + + + Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written. + + + + + Writes all specials from start to end (exclusive). Does not touch the positionStack. + + + + + Writes all specials between the current position (in the positionStack) and the next + node with the specified role. Advances the current position. + + + + + Writes all specials between the current position (in the positionStack) and the specified node. + Advances the current position. + + + + + Writes an identifier. + + + + + Writes a keyword to the output. + + + + + Writes a token to the output. + + + + + Writes a primitive/literal value + + + + + Write a piece of text in an interpolated string literal. + + + + + Writes C# code into a TextWriter. + + + + + Gets the escape sequence for the specified character within a char literal. + Does not include the single quotes surrounding the char literal. + + + + + Gets the escape sequence for the specified character. + + This method does not convert ' or ". + + + + Converts special characters to escape sequences within the given string. + + + + + Gets the fields and properties of the record type, interleaved as necessary to + maintain Equals/ToString/etc. semantics. + + + + + Gets the detected primary constructor. Returns null, if there was no primary constructor detected. + + + + + Gets whether the member of the record type will be automatically generated by the compiler. + + + + + Given a SyntaxTree that was output from the decompiler, constructs the list of sequence points. + + + + + Main AST node associated with this sequence point. + + + + + List of IL intervals that are associated with this sequence point. + + + + + The function containing this sequence point. + + + + + Start a new C# statement = new sequence point. + + + + + Add the ILAst instruction associated with the AstNode to the sequence point. + Also add all its ILAst sub-instructions (unless they were already added to another sequence point). + + + + + Called after the visitor is done to return the results. + + + + + Represents a namespace resolve result that's resolved using an alias. + + + + + The alias used. + + + + + Represents a type resolve result that's resolved using an alias. + + + + + The alias used. + + + + + Represents the result of an await expression. + + + + + The method representing the GetAwaiter() call. Can be an or a . + + + + + Awaiter type. Will not be null (but can be UnknownType). + + + + + Property representing the IsCompleted property on the awaiter type. Can be null if the awaiter type or the property was not found, or when awaiting a dynamic expression. + + + + + Method representing the OnCompleted method on the awaiter type. Can be null if the awaiter type or the method was not found, or when awaiting a dynamic expression. + This can also refer to an UnsafeOnCompleted method, if the awaiter type implements System.Runtime.CompilerServices.ICriticalNotifyCompletion. + + + + + Method representing the GetResult method on the awaiter type. Can be null if the awaiter type or the method was not found, or when awaiting a dynamic expression. + + + + + Contains logic that determines whether an implicit conversion exists between two types. + + + This class is thread-safe. + + + + + Gets the Conversions instance for the specified . + This will make use of the context's cache manager to reuse the Conversions instance. + + + + + Gets whether the type 'fromType' is convertible to 'toType' + using one of the conversions allowed when satisfying constraints (§4.4.4) + + + + + Gets whether there is an identity conversion from to + + + + + For , , and , returns T. + Otherwise, returns null. + + + + + Gets whether the conversion from fromType to toType is a boxing conversion, + or an implicit conversion involving a type parameter that might be + a boxing conversion when instantiated with a value type. + + + + + Implicit conversions involving type parameters. + + + + + Gets whether type A is encompassed by type B. + + + + + Gets whether a is compatible with a delegate type. + §15.2 Delegate compatibility + + The method to test for compatibility + The delegate type + + + + Gets whether a method is compatible with a delegate type. + + The method to test for compatibility + The invoke method of the delegate + Gets whether m is accessed using extension method syntax. + If this parameter is true, the first parameter of will be ignored. + + + + Gets the better conversion (from expression) (C# 8.0 spec, §12.6.4.5) + + 0 = neither is better; 1 = t1 is better; 2 = t2 is better + + + + Gets whether an expression E exactly matches a type T (C# 8.0 spec, §12.6.4.6) + + + + + Unpacks the generic TaskType[T]. Returns null if the input is not TaskType[T]. + + + + + Gets the better conversion (from type) (C# 4.0 spec, §7.5.3.4) + + 0 = neither is better; 1 = t1 is better; 2 = t2 is better + + + + Gets the better conversion target (C# 9.0 spec, §12.6.4.7) + + 0 = neither is better; 1 = t1 is better; 2 = t2 is better + + + + Represents the result of a method, constructor or indexer invocation. + Provides additional C#-specific information for InvocationResolveResult. + + + + + Gets whether this invocation is calling an extension method using extension method syntax. + + + + + Gets whether this invocation is calling a delegate (without explicitly calling ".Invoke()"). + + + + + Gets whether a params-Array is being used in its expanded form. + + + + + Gets an array that maps argument indices to parameter indices. + For arguments that could not be mapped to any parameter, the value will be -1. + + parameterIndex = ArgumentToParameterMap[argumentIndex] + + + + + Gets the CSharpOperators instance for the specified . + This will make use of the context's cache manager (if available) to reuse the CSharpOperators instance. + + + + + Implement this interface to give overload resolution a hint that the member represents a lifted operator, + which is used in the tie-breaking rules. + + + + + Contains the main resolver logic. + + + This class is thread-safe. + + + + + Gets the compilation used by the resolver. + + + + + Gets the current type resolve context. + + + + + Gets whether the current context is checked. + + + + + Sets whether the current context is checked. + + + + + Gets whether the resolver is currently within a lambda expression or anonymous method. + + + + + Sets whether the resolver is currently within a lambda expression. + + + + + Gets the current member definition that is used to look up identifiers as parameters + or type parameters. + + + + + Sets the current member definition. + + Don't forget to also set CurrentTypeDefinition when setting CurrentMember; + setting one of the properties does not automatically set the other. + + + + Gets the current using scope that is used to look up identifiers as class names. + + + + + Sets the current using scope that is used to look up identifiers as class names. + + + + + Gets the current type definition. + + + + + Sets the current type definition. + + + + + Adds new variableŝ or lambda parameters to the current block. + + + + + Gets all currently visible local variables and lambda parameters. + Does not include method parameters. + + + + + Pushes the type of the object that is currently being initialized. + + + + + Gets whether this context is within an object initializer. + + + + + Gets the current object initializer. This usually is an + or (for nested initializers) a semantic tree based on an . + Returns ErrorResolveResult if there is no object initializer. + + + + + Gets the type of the object currently being initialized. + Returns SharedTypes.Unknown if no object initializer is currently open (or if the object initializer + has unknown type). + + + + + Handle the case where an enum value is compared with another enum value + bool operator op(E x, E y); + + + + + Handle the case where an enum value is subtracted from another enum value + U operator –(E x, E y); + + + + + Handle the following enum operators: + E operator +(E x, U y); + E operator +(U x, E y); + E operator –(E x, U y); + E operator &(E x, E y); + E operator |(E x, E y); + E operator ^(E x, E y); + + + + + + + The input resolve result that should be converted. + If a conversion exists, it is applied to the resolve result + The target type that we should convert to + Whether we are dealing with a lifted operator + The resolve result that is enum-typed. + If necessary, a nullable conversion is applied. + + Whether the conversion from the constant zero is allowed. + + True if the conversion is successful; false otherwise. + If the conversion is not successful, the ref parameters will not be modified. + + + + Looks up an alias (identifier in front of :: operator) + + + + + Creates a MemberLookup instance using this resolver's settings. + + + + + Creates a MemberLookup instance using this resolver's settings. + + + + + Gets all extension methods that are available in the current context. + + Name of the extension method. Pass null to retrieve all extension methods. + Explicitly provided type arguments. + An empty list will return all matching extension method definitions; + a non-empty list will return s for all extension methods + with the matching number of type parameters. + + The results are stored in nested lists because they are grouped by using scope. + That is, for "using SomeExtensions; namespace X { using MoreExtensions; ... }", + the return value will be + new List { + new List { all extensions from MoreExtensions }, + new List { all extensions from SomeExtensions } + } + + + + + Gets the extension methods that are called 'name' + and are applicable with a first argument type of 'targetType'. + + Type of the 'this' argument + Name of the extension method. Pass null to retrieve all extension methods. + Explicitly provided type arguments. + An empty list will return all matching extension method definitions; + a non-empty list will return s for all extension methods + with the matching number of type parameters. + + Specifies whether to produce a + when type arguments could be inferred from . This parameter + is only used for inferred types and has no effect if is non-empty. + + + The results are stored in nested lists because they are grouped by using scope. + That is, for "using SomeExtensions; namespace X { using MoreExtensions; ... }", + the return value will be + new List { + new List { all extensions from MoreExtensions }, + new List { all extensions from SomeExtensions } + } + + + + + Checks whether the specified extension method is eligible on the target type. + + Target type that is passed as first argument to the extension method. + The extension method. + Whether to perform type inference for the method. + Use false if is already parameterized (e.g. when type arguments were given explicitly). + Otherwise, use true. + + If the method is generic and is true, + and at least some of the type arguments could be inferred, this parameter receives the inferred type arguments. + Since only the type for the first parameter is considered, not all type arguments may be inferred. + If an array is returned, any slot with an uninferred type argument will be set to the method's + corresponding type parameter. + + + + + Gets all extension methods available in the current using scope. + This list includes inaccessible methods. + + + + + Resolves an invocation. + + The target of the invocation. Usually a MethodGroupResolveResult. + + Arguments passed to the method. + The resolver may mutate this array to wrap elements in s! + + + The argument names. Pass the null string for positional arguments. + + InvocationResolveResult or UnknownMethodResolveResult + + + + Resolves an indexer access. + + Target expression. + + Arguments passed to the indexer. + The resolver may mutate this array to wrap elements in s! + + + The argument names. Pass the null string for positional arguments. + + ArrayAccessResolveResult, InvocationResolveResult, or ErrorResolveResult + + + + Converts all arguments to int,uint,long or ulong. + + + + + Resolves an object creation. + + Type of the object to create. + + Arguments passed to the constructor. + The resolver may mutate this array to wrap elements in s! + + + The argument names. Pass the null string for positional arguments. + + + Whether to allow calling protected constructors. + This should be false except when resolving constructor initializers. + + + Statements for Objects/Collections initializer. + + + InvocationResolveResult or ErrorResolveResult + + + + Resolves 'sizeof(type)'. + + + + + Resolves 'this'. + + + + + Resolves 'base'. + + + + + Converts the input to bool using the rules for boolean expressions. + That is, operator true is used if a regular conversion to bool is not possible. + + + + + Converts the negated input to bool using the rules for boolean expressions. + Computes !(bool)input if the implicit cast to bool is valid; otherwise + computes input.operator false(). + + + + + Resolves an array creation. + + + The array element type. + Pass null to resolve an implicitly-typed array creation. + + + The size arguments. + The length of this array will be used as the number of dimensions of the array type. + Negative values will be treated as errors. + + + The initializer elements. May be null if no array initializer was specified. + The resolver may mutate this array to wrap elements in s! + + + + + Resolves an array creation. + + + The array element type. + Pass null to resolve an implicitly-typed array creation. + + + The size arguments. + The length of this array will be used as the number of dimensions of the array type. + The resolver may mutate this array to wrap elements in s! + + + The initializer elements. May be null if no array initializer was specified. + The resolver may mutate this array to wrap elements in s! + + + + + The invocation is a normal invocation ( 'a(b)' ). + + + + + The invocation is an indexing ( 'a[b]' ). + + + + + The invocation is an object creation ( 'new a(b)' ). + + + + + Represents the result of an invocation of a member of a dynamic object. + + + + + Target of the invocation. Can be a dynamic expression or a . + + + + + Type of the invocation. + + + + + Arguments for the call. Named arguments will be instances of . + + + + + Gets the list of initializer statements that are appplied to the result of this invocation. + This is used to represent object and collection initializers. + With the initializer statements, the is used + to refer to the result of this invocation. + Initializer statements can only exist if the is . + + + + + Represents the result of an access to a member of a dynamic object. + + + + + Target of the member access (a dynamic object). + + + + + Name of the accessed member. + + + + + Represents an anonymous method or lambda expression. + Note: the lambda has no type. + To retrieve the delegate type, look at the anonymous function conversion. + + + + + Gets whether there is a parameter list. + This property always returns true for C# 3.0-lambdas, but may return false + for C# 2.0 anonymous methods. + + + + + Gets whether this lambda is using the C# 2.0 anonymous method syntax. + + + + + Gets whether the lambda parameters are implicitly typed. + + This property returns false for anonymous methods without parameter list. + + + + Gets whether the lambda is async. + + + + + Gets the return type inferred when the parameter types are inferred to be + + + This method determines the return type inferred from the lambda body, which is used as part of C# type inference. + Use the property to retrieve the actual return type as determined by the target delegate type. + + + + + Gets the list of parameters. + + + + + Gets the return type of the lambda. + + If the lambda is async, the return type includes Task<T> + + + + + Gets whether the lambda body is valid for the given parameter types and return type. + + + Produces a conversion with =true if the lambda is valid; + otherwise returns . + + + + + Gets the resolve result for the lambda body. + Returns a resolve result for 'void' for statement lambdas. + + + + + The inferred return type. + Can differ from ReturnType if a return statement + performs an implicit conversion. + + + + + Resolver logging helper. + Wraps System.Diagnostics.Debug so that resolver-specific logging can be enabled/disabled on demand. + (it's a huge amount of debug spew and slows down the resolver quite a bit) + + + + + Implementation of member lookup (C# 4.0 spec, §7.4). + + + + + Gets whether the member is considered to be invocable. + + + + + Gets whether access to protected instance members of the target expression is possible. + + + + + Gets whether access to protected instance members of the target type is possible. + + + This method does not consider the special case of the 'base' reference. If possible, use the + IsProtectedAccessAllowed(ResolveResult) overload instead. + + + + + Gets whether is accessible in the current class. + + The entity to test + + Whether protected access to instance members is allowed. + True if the type of the reference is derived from the current class. + Protected static members may be accessible even if false is passed for this parameter. + + + + + Retrieves all members that are accessible and not hidden (by being overridden or shadowed). + Returns both members and nested type definitions. Does not include extension methods. + + + + + Performs a member lookup. + + + + + Looks up the indexers on the target type. + + + + + Adds the nested types to 'newNestedTypes' and removes any hidden members from the existing lookup groups. + + Declaring type of the nested types + List of nested types to add. + The number of type arguments - used for hiding types from the base class + List of existing lookup groups + The base types of 'type' (initialized on demand) + The target list (created on demand). + + + + Adds members to 'newMethods'/'newNonMethod'. + Removes any members in the existing lookup groups that were hidden by added members. + Substitutes 'virtual' members in the existing lookup groups for added 'override' members. + + Declaring type of the members + List of members to add. + Whether protected members are accessible + List of existing lookup groups + Whether to treat properties as methods + The base types of 'type' (initialized on demand) + The target list for methods (created on demand). + The target variable for non-method members. + + + + A method list that belongs to a declaring type. + + + + + The declaring type. + + + Not all methods in this list necessarily have this as their declaring type. + For example, this program: + + class Base { + public virtual void M() {} + } + class Derived : Base { + public override void M() {} + public void M(int i) {} + } + + results in two lists: + new MethodListWithDeclaringType(Base) { Derived.M() }, + new MethodListWithDeclaringType(Derived) { Derived.M(int) } + + + + + Represents a group of methods. + A method reference used to create a delegate is resolved to a MethodGroupResolveResult. + The MethodGroupResolveResult has no type. + To retrieve the delegate type or the chosen overload, look at the method group conversion. + + + + + Gets the resolve result for the target object. + + + + + Gets the type of the reference to the target object. + + + + + Gets the name of the methods in this group. + + + + + Gets the methods that were found. + This list does not include extension methods. + + + + + Gets the methods that were found, grouped by their declaring type. + This list does not include extension methods. + Base types come first in the list. + + + + + Gets the type arguments that were explicitly provided. + + + + + List of extension methods, used to avoid re-calculating it in ResolveInvocation() when it was already + calculated by ResolveMemberAccess(). + + + + + Gets the method that was chosen for this group. + + Only set for MethodGroupResolveResults found in ILSpy AST annotations. + + + + + Gets all candidate extension methods. + Note: this includes candidates that are not eligible due to an inapplicable + this argument. + The candidates will only be specialized if the type arguments were provided explicitly. + + + The results are stored in nested lists because they are grouped by using scope. + That is, for "using SomeExtensions; namespace X { using MoreExtensions; ... }", + the return value will be + new List { + new List { all extensions from MoreExtensions }, + new List { all extensions from SomeExtensions } + } + + + + + Gets the eligible extension methods. + + + Specifies whether to produce a SpecializedMethod + when type arguments could be inferred from . + This setting is only used for inferred types and has no effect if the type parameters are + specified explicitly. + + + The results are stored in nested lists because they are grouped by using scope. + That is, for "using SomeExtensions; namespace X { using MoreExtensions; ... }", + the return value will be + new List { + new List { all extensions from MoreExtensions }, + new List { all extensions from SomeExtensions } + } + + + + + Normal name lookup in expressions + + + + + Name lookup in expression, where the expression is the target of an invocation. + Such a lookup will only return methods and delegate-typed fields. + + + + + Normal name lookup in type references. + + + + + Name lookup in the type reference inside a using declaration. + + + + + Name lookup for base type references. + + + + + C# overload resolution (C# 4.0 spec: §7.5). + + + + + Returns the normal form candidate, if this is an expanded candidate. + + + + + Gets the parameter types. In the first step, these are the types without any substitution. + After type inference, substitutions will be performed. + + + + + argument index -> parameter index; -1 for arguments that could not be mapped + + + + + Gets the original member parameters (before any substitution!) + + + + + Gets the original method type parameters (before any substitution!) + + + + + Conversions applied to the arguments. + This field is set by the CheckApplicability step. + + + + + Gets the type of the collection that is used for the 'params' parameter (before any substitution!). + Otherwise returns SpecialType.UnknownType. + + + + + Gets/Sets whether the methods are extension methods that are being called using extension method syntax. + + + Setting this property to true restricts the possible conversions on the first argument to + implicit identity, reference, or boxing conversions. + + + + + Gets/Sets whether expanding 'params' into individual elements is allowed. + The default value is true. + + + + + Gets/Sets whether optional parameters may be left at their default value. + The default value is true. + If this property is set to false, optional parameters will be treated like regular parameters. + + + + + Gets/Sets whether a value argument can be passed to an `in` reference parameter. + + + + + Gets/Sets whether ConversionResolveResults created by this OverloadResolution + instance apply overflow checking. + The default value is false. + + + + + Gets the arguments for which this OverloadResolution instance was created. + + + + + Adds a candidate to overload resolution. + + The candidate member to add. + The errors that prevent the member from being applicable, if any. + Note: this method does not return errors that do not affect applicability. + + + + Adds a candidate to overload resolution. + + The candidate member to add. + Additional errors that apply to the candidate. + This is used to represent errors during member lookup (e.g. OverloadResolutionErrors.Inaccessible) + in overload resolution. + The errors that prevent the member from being applicable, if any. + Note: this method does not return errors that do not affect applicability. + + + + Calculates applicability etc. for the candidate. + + True if the calculation was successful, false if the candidate should be removed without reporting an error + + + + Adds all candidates from the method lists. + + This method implements the logic that causes applicable methods in derived types to hide + all methods in base types. + + The methods, grouped by declaring type. Base types must come first in the list. + + + + Validates whether the given type argument satisfies the constraints for the given type parameter. + + The type parameter. + The type argument. + The substitution that defines how type parameters are replaced with type arguments. + The substitution is used to check constraints that depend on other type parameters (or recursively on the same type parameter). + May be null if no substitution should be used. + True if the constraints are satisfied; false otherwise. + + + + Returns whether a candidate with the given errors is still considered to be applicable. + + + + + Returns 1 if c1 is better than c2; 2 if c2 is better than c1; or 0 if neither is better. + + + + + Returns the errors that apply to the best candidate. + This includes additional errors that do not affect applicability (e.g. AmbiguousMatch, MethodConstraintsNotSatisfied) + + + + + Gets the implicit conversions that are being applied to the arguments. + + + + + Gets an array that maps argument indices to parameter indices. + For arguments that could not be mapped to any parameter, the value will be -1. + + parameterIndex = GetArgumentToParameterMap()[argumentIndex] + + + + + Returns the arguments for the method call in the order they were provided (not in the order of the parameters). + Arguments are wrapped in a if an implicit conversion is being applied + to them when calling the method. + + + + + Returns the arguments for the method call in the order they were provided (not in the order of the parameters). + Arguments are wrapped in a if an implicit conversion is being applied + to them when calling the method. + For arguments where an explicit argument name was provided, the argument will + be wrapped in a . + + + + + Creates a ResolveResult representing the result of overload resolution. + + + The target expression of the call. May be null for static methods/constructors. + + + Statements for Objects/Collections initializer. + + + + If not null, use this instead of the ReturnType of the member as the type of the created resolve result. + + + + + Too many positional arguments (some could not be mapped to any parameter). + + + + + A named argument could not be mapped to any parameter + + + + + Type inference failed for a generic method. + + + + + Type arguments were explicitly specified, but did not match the number of type parameters. + + + + + After substituting type parameters with the inferred types; a constructed type within the formal parameters + does not satisfy its constraint. + + + + + No argument was mapped to a non-optional parameter + + + + + Several arguments were mapped to a single (non-params-array) parameter + + + + + 'ref'/'out' passing mode doesn't match for at least 1 parameter + + + + + Argument type cannot be converted to parameter type + + + + + There is no unique best overload. + This error does not apply to any single candidate, but only to the overall result of overload resolution. + + + This error does not prevent a candidate from being applicable. + + + + + The member is not accessible. + + + This error is generated by member lookup; not by overload resolution. + + + + + A generic method + + + This error does not prevent a candidate from being applicable. + + + + + Using 'out var' instead of 'out T' would result in loss of type information. + + + + + C# 4.0 type inference. + + + + + Improved algorithm (not part of any specification) using FindTypeInBounds for fixing. + + + + + Improved algorithm (not part of any specification) using FindTypeInBounds for fixing; + uses to report all results (in case of ambiguities). + + + + + Implements C# 4.0 Type Inference (§7.5.2). + + + + + Gets/Sets the type inference algorithm used. + + + + + Performs type inference. + + The method type parameters that should be inferred. + The arguments passed to the method. + The parameter types of the method. + Out: whether type inference was successful + + Class type arguments. These are substituted for class type parameters in the formal parameter types + when inferring a method group or lambda. + + The inferred type arguments. + + + + Infers type arguments for the occurring in the + so that the resulting type (after substition) satisfies the given bounds. + + + + + Make exact inference from U to V. + C# 4.0 spec: §7.5.2.8 Exact inferences + + + + + Make lower bound inference from U to V. + C# 4.0 spec: §7.5.2.9 Lower-bound inferences + + + + + Make upper bound inference from U to V. + C# 4.0 spec: §7.5.2.10 Upper-bound inferences + + + + + Gets the best common type (C# 4.0 spec: §7.5.2.14) of a set of expressions. + + + + + Finds a type that satisfies the given lower and upper bounds. + + + + + Combines query expressions and removes transparent identifiers. + + + + + Removes all occurrences of transparent identifiers + + + + + Converts extension method calls into infix syntax. + + + + + Decompiles query expressions. + Based on C# 4.0 spec, §7.16.2 Query expression translation + + + + + This fixes #437: Decompilation of query expression loses material parentheses + We wrap the expression in parentheses if: + - the Select-call is explicit (see caller(s)) + - the expression is a plain identifier matching the parameter name + + + + + Ensure that all ThenBy's are correct, and that the list of ThenBy's is terminated by an 'OrderBy' invocation. + + + + Matches simple lambdas of the form "a => b" + + + + Modifiers that are emitted on accessors, but can be moved to the property declaration. + + + + + Simplifies "x = x op y" into "x op= y" where possible. + + + Because the two "x" in "x = x op y" may refer to different ILVariables, + this transform must run after DeclareVariables. + + It must also run after ReplaceMethodCallsWithOperators (so that it can work for custom operator, too); + and after AddCheckedBlocks (because "for (;; x = unchecked(x op y))" cannot be transformed into "x += y"). + + + + + This transform is used to remove CLSCompliant attributes added by the compiler. We remove them in order to get rid of many warnings. + + This transform is only enabled, when exporting a full assembly as project. + + + + Base class for AST visitors that need the current type/method context info. + + + + + Insert variable declarations. + + + + + Represents a position immediately before nextNode. + nextNode is either an ExpressionStatement in a BlockStatement, or an initializer in a for-loop. + + + + + The nesting level of `nextNode` within the AST. + Used to speed up FindCommonParent(). + + + + Go up one level + + + + Whether the variable needs to be default-initialized. + + + + + Integer value that can be used to compare to VariableToDeclare instances + to determine which variable was used first in the source code. + + The variable with the lower SourceOrder value has the insertion point + that comes first in the source code. + + + + + The insertion point, i.e. the node before which the variable declaration should be inserted. + + + + + The first use of the variable. + + + + + Analyze the input AST (containing undeclared variables) + for where those variables would be declared by this transform. + Analysis does not modify the AST. + + + + + Get the position where the declaration for the variable will be inserted. + + + + + Determines whether a variable was merged with other variables. + + + + + Finds insertion points for all variables used within `node` + and adds them to the variableDict. + + `level` == nesting depth of `node` within root node. + + + Insertion point for a variable = common parent of all uses of that variable + = smallest possible scope that contains all the uses of the variable + + + + + Finds an insertion point in a common parent instruction. + + + + + Some variable declarations in C# are illegal (colliding), + even though the variable live ranges are not overlapping. + + Multiple declarations in same block: + + int i = 1; use(1); + int i = 2; use(2); + + + "Hiding" declaration in nested block: + + int i = 1; use(1); + if (...) { + int i = 2; use(2); + } + + + Nested blocks are illegal even if the parent block + declares the variable later: + + if (...) { + int i = 1; use(i); + } + int i = 2; use(i); + + + ResolveCollisions() detects all these cases, and combines the variable declarations + to a single declaration that is usable for the combined scopes. + + + + + Update ILVariableResolveResult annotations of all ILVariables that have been replaced by ResolveCollisions. + + + + + Escape invalid identifiers. + + + This transform is not enabled by default. + + + + + This transform is used to remove assembly-attributes that are generated by the compiler, + thus don't need to be declared. (We have to remove them, in order to avoid conflicts while compiling.) + + This transform is only enabled, when exporting a full assembly as project. + + + + This transform is used to remove attributes that are embedded + + + + + Rename entities to solve name collisions that make the code uncompilable. + + + Currently, we only rename private fields that collide with property or event names. + This helps especially with compiler-generated events that were not detected as a pattern. + + + + + Introduces using declarations. + + + + + Finds the expanded form of using statements using pattern matching and replaces it with a UsingStatement. + + + + + $variable = $initializer; + + + + + $variable = $collection.GetUpperBound($index); + + + + + $variable = $collection.GetLowerBound($index); + + + + + $variable = $collection[$index1, $index2, ...]; + + + + + This matches the following patterns + + <Property>k__BackingField (used by C#) + _Property (used by VB) + + + + + + Simplify nested 'try { try {} catch {} } finally {}'. + This transformation must run after the using/lock tranformations. + + + + + Use associativity of logic operators to avoid parentheses. + + + + + Parameters for IAstTransform. + + + + + Returns the current member; or null if a whole type or module is being decompiled. + + + + + Returns the current type definition; or null if a module is being decompiled. + + + + + Returns the module that is being decompiled. + + + + + Returns the max possible set of namespaces that will be used during decompilation. + + + + + Add checked/unchecked blocks. + + + + + true=checked, false=unchecked + + + + + Require an explicit unchecked block (can't rely on the project-level unchecked context) + + + + + Gets the new cost if an expression with this cost is wrapped in a checked/unchecked expression. + + + + + Holds the blocks and expressions that should be inserted + + + + + Holds the result of an insertion operation. + + + + + This transform moves field initializers at the start of constructors to their respective field declarations + and transforms this-/base-ctor calls in constructors to constructor initializers. + + + + + Pattern for reference types: + this..ctor(...); + + + + + Pattern for value types: + this = new TSelf(...); + + + + + Evaluates a call to the decimal-ctor. + + + + + typeof-Pattern that applies on the expanded form of typeof (prior to ReplaceMethodCallsWithOperators) + + + + + Replaces method calls with the appropriate operator expressions. + + + + + Adds XML documentation for member definitions. + + + + + Context struct passed in to ExpressionBuilder.Visit() methods. + + + + + The expected type during ILAst->C# translation; or SpecialType.Unknown + if no specific type is expected. + + + + + Represents a scope that contains "using" statements. + This is either the mo itself, or a namespace declaration. + + + + + Gets whether this using scope has an alias (either using or extern) + with the specified name. + + + + + Helper struct so that the compiler can ensure we don't forget both the ILInstruction annotation and the ResolveResult annotation. + Use '.WithILInstruction(...)' or '.WithoutILInstruction()' to create an instance of this struct. + + + + + Helper struct so that the compiler can ensure we don't forget both the ILInstruction annotation and the ResolveResult annotation. + Use '.WithRR(...)'. + + + + + Output of C# ExpressionBuilder -- a decompiled C# expression that has both a resolve result and ILInstruction annotation. + + + The resolve result is also always available as annotation on the expression, but having + TranslatedExpression as a separate type is still useful to ensure that no case in the expression builder + forgets to add the annotation. + + + + + Returns a new TranslatedExpression that represents the specified descendant expression. + All ILInstruction annotations from the current expression are copied to the descendant expression. + The descendant expression is detached from the AST. + + + + + Adds casts (if necessary) to convert this expression to the specified target type. + + + If the target type is narrower than the source type, the value is truncated. + If the target type is wider than the source type, the value is sign- or zero-extended based on the + sign of the source type. + This fits with the ExpressionBuilder's post-condition, so e.g. an assignment can simply + call Translate(stloc.Value).ConvertTo(stloc.Variable.Type) and have the overall C# semantics match the IL semantics. + + From the caller's perspective, IntPtr/UIntPtr behave like normal C# integers except that they have native int size. + All the special cases necessary to make IntPtr/UIntPtr behave sanely are handled internally in ConvertTo(). + + Post-condition: + The "expected evaluation result" is the value computed by this.Expression, + converted to targetType via an IL conv instruction. + + ConvertTo(targetType, allowImplicitConversion=false).Type must be equal to targetType (modulo identity conversions). + The value computed by the converted expression must match the "expected evaluation result". + + ConvertTo(targetType, allowImplicitConversion=true) must produce an expression that, + when evaluated in a context where it will be implicitly converted to targetType, + evaluates to the "expected evaluation result". + + + + + Gets whether an implicit conversion from 'inputType' to 'newTargetType' + would have the same semantics as the existing cast from 'inputType' to 'oldTargetType'. + The existing cast is classified in 'conversion'. + + + + + In conditional contexts, remove the bool-cast emitted when converting + an "implicit operator bool" invocation. + + + + + Converts this expression to a boolean expression. + + Expects that the input expression is an integer expression; produces an expression + that returns true iff the integer value is not 0. + + If negate is true, instead produces an expression that returns true iff the integer value is 0. + + + + + Main class of the C# decompiler engine. + + + Instances of this class are not thread-safe. Use separate instances to decompile multiple members in parallel. + (in particular, the transform instances are not thread-safe) + + + + + Pre-yield/await transforms. + + + + + Returns all built-in transforms of the ILAst pipeline. + + + + + Returns all built-in transforms of the C# AST pipeline. + + + + + Token to check for requested cancellation of the decompilation. + + + + + The type system created from the main module and referenced modules. + + + + + Gets or sets the optional provider for debug info. + + + + + Gets or sets the optional provider for XML documentation strings. + + + + + IL transforms. + + + + + C# AST transforms. + + + + + Creates a new instance from the given using the given . + + + + + Creates a new instance from the given using the given and . + + + + + Creates a new instance from the given using the given and . + + + + + Creates a new instance from the given and the given . + + + + + Determines whether a should be hidden from the decompiled code. This is used to exclude compiler-generated code that is handled by transforms from the output. + + The module containing the member. + The metadata token/handle of the member. Can be a TypeDef, MethodDef or FieldDef. + The settings used to determine whether code should be hidden. E.g. if async methods are not transformed, async state machines are included in the decompiled code. + + + + Determines whether a given type requires that its methods be ordered precisely as they were originally defined. + + The type whose members may need native ordering. + + + + Compare handles with the method definition ordering intact by using the underlying method's MetadataToken, + which is defined as the index into a given metadata table. This should equate to the original order that + methods and properties were defined by the author. + + The type whose members to order using their method's MetadataToken + A sequence of all members ordered by MetadataToken + + + + Decompile assembly and module attributes. + + + + + Decompile assembly and module attributes. + + + + + Decompiles the whole module into a single syntax tree. + + + + + Decompiles the whole module into a single syntax tree. + + If true, top-level-types are emitted sorted by namespace/name. + If false, types are emitted in metadata order. + + + + Creates an for the given . + + + + + Determines the "code-mappings" for a given TypeDef or MethodDef. See for more information. + + + + + Decompiles the whole module into a single string. + + + + + Decompile the given types. + + + Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definitions. + + + + + Decompile the given types. + + + Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definitions. + + + + + Decompile the given type. + + + Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definition. + Note that decompiling types from modules other than the main module is not supported. + + + + + Decompile the given type. + + + Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definition. + + + + + Decompile the specified types and/or members. + + + + + Decompile the specified types and/or members. + + + + + Decompile the specified types and/or members. + + + + + Decompile the specified types and/or members. + + + + + Sets new modifier if the member hides some other member from a base type. + + The node of the member which new modifier state should be determined. + + + + Creates sequence points for the given syntax tree. + + This only works correctly when the nodes in the syntax tree have line/column information. + + + + + Translates from ILAst to C# expressions. + + + Every translated expression must have: + * an ILInstruction annotation + * a ResolveResult annotation + Post-condition for Translate() calls: + * The type of the ResolveResult must match the StackType of the corresponding ILInstruction, + except that the width of integer types does not need to match (I4, I and I8 count as the same stack type here) + * Evaluating the resulting C# expression shall produce the same side effects as evaluating the ILInstruction. + * If the IL instruction has ResultType == StackType.Void, the C# expression may evaluate to an arbitrary type and value. + * Otherwise, evaluating the resulting C# expression shall produce a similar value as evaluating the ILInstruction. + * If the IL instruction evaluates to an integer stack type (I4, I, or I8), + the C# type of the resulting expression shall also be an integer (or enum/pointer/char/bool) type. + * If sizeof(C# type) == sizeof(IL stack type), the values must be the same. + * If sizeof(C# type) > sizeof(IL stack type), the C# value truncated to the width of the IL stack type must equal the IL value. + * If sizeof(C# type) < sizeof(IL stack type), the C# value (sign/zero-)extended to the width of the IL stack type + must equal the IL value. + Whether sign or zero extension is used depends on the sign of the C# type (as determined by IType.GetSign()). + * If the IL instruction is a lifted nullable operation, and the underlying operation evaluates to an integer stack type, + the C# type of the resulting expression shall be Nullable{T}, where T is an integer type (as above). + The C# value shall be null iff the IL-level value evaluates to null, and otherwise the values shall correspond + as with non-lifted integer operations. + * If the IL instruction evaluates to a managed reference (Ref) created by starting tracking of an unmanaged reference, + the C# instruction may evaluate to any integral/enum/pointer type that when converted to pointer type + is equivalent to the managed reference. + * Otherwise, the C# type of the resulting expression shall match the IL stack type, + and the evaluated values shall be the same. + + + + + Translates the equality comparison between left and right. + + + + + Handle Comp instruction, operators other than equality/inequality. + + + + + Translates pointer arithmetic: + ptr + int + int + ptr + ptr - int + Returns null if 'inst' is not performing pointer arithmetic. + 'ptr - ptr' is not handled here, but in HandlePointerSubtraction()! + + + + + Translates pointer arithmetic with managed pointers: + ref + int + int + ref + ref - int + ref - ref + + + + + Called for divisions, detect and handles the code pattern: + div(sub(a, b), sizeof(T)) + when a,b are of type T*. + This is what the C# compiler generates for pointer subtraction. + + + + + Gets a type matching the stack type and sign. + + + + + Gets a type used for performing arithmetic with the stack type and sign. + + This may result in a larger type than requested when the selected C# version + doesn't support native integers. + Should only be used after a call to PrepareArithmeticArgument() + to ensure that we're not preserving extra bits from an oversized TranslatedExpression. + + + + + Handle oversized arguments needing truncation; and avoid IntPtr/pointers in arguments. + + + + + Gets whether has the specified . + If is None, always returns true. + + + + + Gets whether the ResolveResult computes a value that might be oversized for the specified stack type. + + + + + If expr is a constant integer expression, and its value fits into type, + convert the expression into the target type. + Otherwise, returns the expression unmodified. + + + + Target block that a 'continue;' statement would jump to + + + Number of ContinueStatements that were created for the current continueTarget + + + Maps blocks to cases. + + + Target container that a 'break;' statement would break out of + + + Dictionary from BlockContainer to label name for 'goto of_container'; + + + + Unwraps a nested BlockContainer, if container contains only a single block, + and that single block contains only a BlockContainer followed by a Leave instruction. + If the leave instruction is a return that carries a value, the container is unwrapped only + if the value has no side-effects. + Otherwise returns the unmodified container. + + If the leave is a return/break and has no side-effects, we can move the return out of the using-block and put it after the loop, otherwise returns null. + + + + Foreach transformation not possible. + + + + + Uninline the stloc foreachVar(call get_Current()) and insert it as first statement in the loop body. + + ... (stloc foreachVar(call get_Current()) ... + => + stloc foreachVar(call get_Current()) + ... (ldloc foreachVar) ... + + + + + + No store was found, thus create a new variable and use it as foreach variable. + + ... (call get_Current()) ... + => + stloc foreachVar(call get_Current()) + ... (ldloc foreachVar) ... + + + + + + No store was found, thus create a new variable and use it as foreach variable. + Additionally it is necessary to copy the value of the foreach variable to another local + to allow safe modification of its value. + + ... addressof(call get_Current()) ... + => + stloc foreachVar(call get_Current()) + stloc copy(ldloc foreachVar) + ... (ldloca copy) ... + + + + + + call get_Current() is the tested operand of a deconstruct instruction. + and the deconstruct instruction is the first statement in the loop body. + + + + + Determines whether is only used once inside for accessing the Current property. + + The using body container. This is only used for variable usage checks. + The loop body. The first statement of this block is analyzed. + The current enumerator. + The call MoveNext(ldloc enumerator) pattern. + Returns the call instruction invoking Current's getter. + Returns the the foreach variable, if a suitable was found. This variable is only assigned once and its assignment is the first statement in . + for details. + + + + Determines whether storeInst.Variable is only assigned once and used only inside . + Loads by reference (ldloca) are only allowed in the context of this pointer in call instructions, + or as target of ldobj. + (This only applies to value types.) + + + + + Returns true if singleGetter is a value type and its address is used as setter target. + + + + + Information used for (optional) progress reporting by the decompiler. + + + + + The total number of units to process. If set to a value <= 0, an indeterminate progress bar is displayed. + + + + + The number of units currently completed. Should be a positive number. + + + + + Optional information displayed alongside the progress bar. + + + + + Optional custom title for the operation. + + + + + class/valuetype + TypeName (built-in types use keyword syntax) + + + + + Like signature, but always refers to type parameters using their position + + + + + [assembly]Full.Type.Name (even for built-in types) + + + + + Name (but built-in types use keyword syntax) + + + + + Specifies the type of an IL structure. + + + + + The root block of the method + + + + + A nested control structure representing a loop. + + + + + A nested control structure representing a try block. + + + + + A nested control structure representing a catch, finally, or fault block. + + + + + A nested control structure representing an exception filter block. + + + + + An IL structure. + + + + + Start position of the structure. + + + + + End position of the structure. (exclusive) + + + + + The exception handler associated with the Try, Filter or Handler block. + + + + + The loop's entry point. + + + + + The list of child structures. + + + + + Finds all branches. Returns list of source offset->target offset mapping. + Multiple entries for the same source offset are possible (switch statements). + The result is sorted by source offset. + + + + + Gets the innermost structure containing the specified offset. + + + + + Disassembles a method body. + + + + + Show .try/finally as blocks in IL code; indent loops. + + + + + Show sequence points if debug information is loaded in Cecil. + + + + + Show metadata tokens for instructions with token operands. + + + + + Show metadata tokens for instructions with token operands in base 10. + + + + + Show raw RVA offset and bytes before each instruction. + + + + + Optional provider for sequence points. + + + + + Disassembles type and member definitions. + + + + + Gets or sets whether custom attribute blobs should be decoded or dumped as raw bytes. Default is . + Setting this value to (roughly) corresponds to the /CAVERBAL switch of ildasm. + + + + + Escape characters that cannot be displayed in the UI. + + + + + Escape characters that cannot be displayed in the UI. + + + + + Matches call get_Item(addressof System.(ReadOnly)Span[[T]](call InlineArrayAs(ReadOnly)Span(addr, length)), index) + + + + + Matches call InlineArrayElementRef(ReadOnly)(addr, index) + + + + + [stloc address(...)] + stloc temp(default.value ``0) + if (comp.o(ldloc temp == ldnull)) Block IL_002a { + stloc temp(ldobj ``0(ldloc address)) + stloc address(ldloca temp) + } + stloc V_i(expr_i) + ...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), ldloc V_i ...))... + + => + + [stloc address(...)] + stloc address(ldobj.if.ref(ldloc address)) + stloc V_i(expr_i) + ...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), ldloc V_i ...))... + + Then ldobj.if.ref in the call is redundant because any object reference was already loaded into an immutable temporary. + So we can removed and inlining of the arguments (V_i) becomes possible. + + Finally the newly created ldobj.if.ref is inlined into the place where the old ldobj.if.ref was. + + => + + [stloc address(...)] + ...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), expr_i ...))... + + + + + + + + + + + Get index of deconstruction result or tuple element + Returns -1 on failure. + + + + + stloc v(value) + expr(..., deconstruct { ... }, ...) + => + expr(..., deconstruct { init: stloc v(value) ... }, ...) + + + + + Transform for the C# 8 System.Index / System.Range feature + + + + + Called by expression transforms. + Handles the `array[System.Index]` cases. + + + + + Check that the number of uses of the containerLengthVar variable matches those expected in the pattern. + + + + + Matches 'addressof System.Index(call get_Start/get_End(ldloca rangeVar))' + + + + + Gets whether the C# compiler will call `container[int]` when using `container[Index]`. + + + + + Matches the instruction: + stloc containerLengthVar(call get_Length/get_Count(ldloc containerVar)) + + + + + If lengthVar is non-null, matches 'ldloc lengthVar'. + + Otherwise, matches the instruction: + call get_Length/get_Count(ldloc containerVar) + + + + + indexLoad is an integer, from the start of the container + + + + + indexLoad is loading the address of a System.Index struct + + + + + indexLoad is an integer, from the end of the container + + + + + Always equivalent to `0`, used for the start-index when slicing without a startpoint `a[..end]` + + + + + Always equivalent to `^0`, used for the end-index when slicing without an endpoint `a[start..]` + + + + + Matches an instruction computing an offset: + call System.Index.GetOffset(indexLoad, ldloc containerLengthVar) + or + binary.sub.i4(ldloc containerLengthVar, indexLoad) + + Anything else not matching these patterns is interpreted as an `int` expression from the start of the container. + + + + + Matches an instruction computing a slice length: + binary.sub.i4(call GetOffset(endIndexLoad, ldloc length), ldloc startOffset)) + + + + Block { + ... + stloc V(isinst T(testedOperand)) + if (comp.o(ldloc V == ldnull)) br falseBlock + br trueBlock + } + + All other uses of V are in blocks dominated by trueBlock. + => + Block { + ... + if (match.type[T].notnull(V = testedOperand)) br trueBlock + br falseBlock + } + + - or - + + Block { + stloc s(isinst T(testedOperand)) + stloc v(ldloc s) + if (logic.not(comp.o(ldloc s != ldnull))) br falseBlock + br trueBlock + } + => + Block { + ... + if (match.type[T].notnull(V = testedOperand)) br trueBlock + br falseBlock + } + + All other uses of V are in blocks dominated by trueBlock. + + + Block { + ... + [stloc temp(ldloc testedOperand)] + if (comp.o(isinst T(ldloc testedOperand) == ldnull)) br falseBlock + br unboxBlock + } + + Block unboxBlock (incoming: 1) { + stloc V(unbox.any T(ldloc temp)) + ... + } + => + Block { + ... + if (match.type[T].notnull(V = testedOperand)) br unboxBlock + br falseBlock + } + + + ... + if (comp.o(isinst T(ldloc testedOperand) == ldnull)) br falseBlock + br unboxBlock + - or - + ... + if (comp.o(isinst T(box ``0(ldloc testedOperand)) == ldnull)) br falseBlock + br unboxBlock + + + Block unboxBlock (incoming: 1) { + stloc V(unbox.any T(ldloc testedOperand)) + ... + - or - + stloc V(unbox.any T(isinst T(box ``0(ldloc testedOperand)))) + ... + } + + + + Block IL_0018 (incoming: *) { + stloc s(ldc.i4 1) + br IL_0019 + } + + Block IL_0019 (incoming: > 1) { + if (logic.not(ldloc s)) br IL_0027 + br IL_001d + } + + replace br IL_0019 with br IL_0027 + + + + + Context object for the ILInstruction.Extract() operation. + + + + + Nearest function, used for registering the new locals that are created by extraction. + + + + + Combined flags of all instructions being moved. + + + + + List of actions to be executed when performing the extraction. + + Each function in this list has the side-effect of replacing the instruction-to-be-moved + with a load of a fresh temporary variable; and returns the the store to the temporary variable, + which will be inserted at block-level. + + + + + Currently, predecessor is evaluated before the instructions being moved. + If this function returns true, predecessor can stay as-is, despite the move changing the evaluation order. + If this function returns false, predecessor will need to also move, to ensure the evaluation order stays unchanged. + + + + + Extracts the specified instruction: + The instruction is replaced with a load of a new temporary variable; + and the instruction is moved to a store to said variable at block-level. + + May return null if extraction is not possible. + + + + stloc V_1(dynamic.isevent (target)) + if (logic.not(ldloc V_1)) Block IL_004a { + stloc V_2(dynamic.getmember B(target)) + } + [stloc copyOfValue(value)] + if (logic.not(ldloc V_1)) Block IL_0149 { + dynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(ldloc V_2, value)) + } else Block IL_0151 { + dynamic.invokemember.invokespecial.discard add_B(target, value) + } + => + if (logic.not(dynamic.isevent (target))) Block IL_0149 { + dynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(dynamic.getmember B(target), value)) + } else Block IL_0151 { + dynamic.invokemember.invokespecial.discard add_B(target, value) + } + + + + if (logic.not(ldloc V_1)) Block IL_0149 { + dynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(ldloc V_2, value)) + } else Block IL_0151 { + dynamic.invokemember.invokespecial.discard add_B(target, value) + } + + + + + if (logic.not(ldloc V_1)) Block IL_004a { + stloc V_2(dynamic.getmember B(target)) + } + + + + + Decompiler step for C# 7.0 local functions + + + + + Used to store all synthesized call-site arguments grouped by the parameter index. + We use a dictionary instead of a simple array, because -1 is used for the this parameter + and there might be many non-synthesized arguments in between. + + + + + The transform works like this: + + + local functions can either be used in method calls, i.e., call and callvirt instructions, + or can be used as part of the "delegate construction" pattern, i.e., + newobj Delegate(<target-expression>, ldftn <method>). + + As local functions can be declared practically anywhere, we have to take a look at + all use-sites and infer the declaration location from that. Use-sites can be call, + callvirt and ldftn instructions. + After all use-sites are collected we construct the ILAst of the local function + and add it to the parent function. + Then all use-sites of the local-function are transformed to a call to the + LocalFunctionMethod or a ldftn of the LocalFunctionMethod. + In a next step we handle all nested local functions. + After all local functions are transformed, we move all local functions that capture + any variables to their respective declaration scope. + + + + + Newer Roslyn versions use the format "<callerName>g__functionName|x_y" + Older versions use "<callerName>g__functionNamex_y" + + + + + Transforms closure fields to local variables. + + This is a post-processing step of , + and . + + In general we can perform SROA (scalar replacement of aggregates) on any variable that + satisfies the following conditions: + 1) It is initialized by an empty/default constructor call. + 2) The variable is never passed to another method. + 3) The variable is never the target of an invocation. + + Note that 2) and 3) apply because declarations and uses of lambdas and local functions + are already transformed by the time this transform is applied. + + + + + Resolves references to variables that can be propagated. + If a value does not match either LdLoc or a LdObj LdLdFlda* LdLoc chain, null is returned. + The if any of the variables/fields in the chain cannot be propagated, null is returned. + + + + + mcs likes to optimize closures in yield state machines away by moving the captured variables' fields into the state machine type, + We construct a that spans the whole method body. + + + + + if (call op_False(ldloc lhsVar)) ldloc lhsVar else call op_BitwiseAnd(ldloc lhsVar, rhsInst) + -> user.logic op_BitwiseAnd(ldloc lhsVar, rhsInst) + or + if (call op_True(ldloc lhsVar)) ldloc lhsVar else call op_BitwiseOr(ldloc lhsVar, rhsInst) + -> user.logic op_BitwiseOr(ldloc lhsVar, rhsInst) + + + + + Transforms the "callsite initialization pattern" into DynamicInstructions. + + + + + If possible, transforms plain ILAst loops into while (condition), do-while and for-loops. + For the invariants of the transforms . + + + + + Matches a do-while loop and performs the following transformations: + - combine all compatible conditions into one IfInstruction. + - extract conditions into a condition block, or move the existing condition block to the end. + + + + + Returns a list of all IfInstructions that can be used as loop conditon, i.e., + that have no false-instruction and have leave loop (if swapped) or branch entry-point as true-instruction. + + + + + Returns true if the instruction is stloc v(add(ldloc v, arg)) + or compound.assign(ldloca v, arg) + + + + + Gets whether the statement is 'simple' (usable as for loop iterator): + Currently we only accept calls and assignments. + + + + + Introduce a named argument for 'arg' and evaluate it before the other arguments + (except for the "this" pointer) + + + + + Transform that converts code patterns like "v != null ? v.M() : null" to "v?.M()" + + + + + reference type or generic type (comparison is 'comp(ldloc(testedVar) == null)') + + + + + nullable type, used by value (comparison is 'call get_HasValue(ldloca(testedVar))') + + + + + nullable type, used by reference (comparison is 'call get_HasValue(ldloc(testedVar))') + + + + + unconstrained generic type (see the pattern described in TransformNullPropagationOnUnconstrainedGenericExpression) + + + + + Check if "condition ? trueInst : falseInst" can be simplified using the null-conditional operator. + Returns the replacement instruction, or null if no replacement is possible. + + + + + testedVar != null ? nonNullInst : nullInst + + + + + if (x != null) x.AccessChain(); + => x?.AccessChain(); + + + + + This transform duplicates return blocks if they return a local variable that was assigned right before the return. + + + + + Determines a list of all store instructions that write to a given . + Returns false if any of these instructions does not meet the following criteria: + - must be a stloc + - must be a direct child of a block + - must be the penultimate instruction + - must be followed by a branch instruction to + - must have a BlockContainer as ancestor. + Returns true, if all instructions meet these criteria, and contains a list of 3-tuples. + Each tuple consists of the target block container, the leave block, and the branch instruction that should be modified. + + + + + Detects switch-on-nullable patterns employed by the C# compiler and transforms them to an ILAst-switch-instruction. + + + + + Matches legacy C# switch on nullable. + + + + + Matches Roslyn C# switch on nullable. + + + + + Detects switch-on-string patterns employed by the C# compiler and transforms them to an ILAst-switch-instruction. + + + + + Each case consists of two blocks: + 1. block: + if (call op_Equality(ldloc switchVariable, ldstr value)) br caseBlock + br nextBlock + -or- + if (comp(ldloc switchValueVar == ldnull)) br nextBlock + br caseBlock + 2. block is caseBlock + This method matches the above pattern or its inverted form: + the call to ==(string, string) is wrapped in logic.not and the branch targets are reversed. + Returns the next block that follows in the block-chain. + The is updated if the value gets copied to a different variable. + See comments below for more info. + + + + + Matches the C# 2.0 switch-on-string pattern, which uses Dictionary<string, int>. + + + + + Matches 'volatile.ldobj dictionaryType(ldsflda dictField)' + + + + + Matches and extracts values from Add-call sequences. + + + + + call Add(ldloc dictVar, ldstr value, ldc.i4 index) + -or- + call Add(ldloc dictVar, ldstr value, box System.Int32(ldc.i4 index)) + + + + + Matches: + Block oldDefaultBlock (incoming: 1) { + if (comp.o(ldloc switchVar == ldnull)) br nullValueCaseBlock + br newDefaultBlock + } + + + + + Matches (and the negated version): + if (call op_Equality(ldloc switchValueVar, stringValue)) br body + br exit + + + + + Block target(incoming: 1) { + if (comp.o(ldloc switchValueVar == ldnull)) br exit + br lengthCheckBlock + } + + Block lengthCheckBlock(incoming: 1) { + if (logic.not(call get_Length(ldloc switchValueVar))) br body + br exit + } + + + + + call get_Length(ldloc switchValueVar) + + + + + Matches + 'stloc(targetVar, call ComputeStringHash(ldloc switchValue))' + - or - + 'stloc(targetVar, call ComputeSpanHash(ldloc switchValue))' + - or - + 'stloc(targetVar, call ComputeReadOnlySpanHash(ldloc switchValue))' + + + + + Matches 'call string.op_Equality(ldloc(variable), ldstr stringValue)' + or 'comp(ldloc(variable) == ldnull)' + or 'call SequenceEqual(ldloc variable, call AsSpan(ldstr stringValue))' + + + + + Matches 'call string.op_Equality(ldloc(variable), ldstr stringValue)' + or 'comp(ldloc(variable) == ldnull)' + or 'call SequenceEqual(ldloc variable, call AsSpan(ldstr stringValue))' + + + + + Converts LINQ Expression Trees to ILFunctions/ILAst instructions. + + We build a tree of Func{ILInstruction}s, which are only executed, if the whole transform succeeds. + + + + + Returns true if the instruction matches the pattern for Expression.Lambda calls. + + + + + Converts a Expression.Lambda call into an ILFunction. + If the conversion fails, null is returned. + + + + + stloc obj(resourceExpression) + .try BlockContainer { + Block IL_0003(incoming: 1) { + call WriteLine(ldstr "using (null)") + leave IL_0003(nop) + } + } finally BlockContainer { + Block IL_0012(incoming: 1) { + if (comp(ldloc obj != ldnull)) Block IL_001a { + callvirt Dispose(ldnull) + } + leave IL_0012(nop) + } + } + leave IL_0000(nop) + => + using (resourceExpression) { + BlockContainer { + Block IL_0003(incoming: 1) { + call WriteLine(ldstr "using (null)") + leave IL_0003(nop) + } + } + } + + + + + .try BlockContainer { + Block IL_0003(incoming: 1) { + stloc obj(resourceExpression) + call WriteLine(ldstr "using (null)") + leave IL_0003(nop) + } + } finally BlockContainer { + Block IL_0012(incoming: 1) { + if (comp(ldloc obj != ldnull)) Block IL_001a { + callvirt Dispose(ldnull) + } + leave IL_0012(nop) + } + } + leave IL_0000(nop) + => + using (resourceExpression) { + BlockContainer { + Block IL_0003(incoming: 1) { + call WriteLine(ldstr "using (null)") + leave IL_0003(nop) + } + } + } + + + + finally BlockContainer { + Block IL_0012(incoming: 1) { + if (comp(ldloc obj != ldnull)) Block IL_001a { + callvirt Dispose(obj) + } + leave IL_0012(nop) + } + } + + + + stloc test(resourceExpression) + .try BlockContainer { + Block IL_002b (incoming: 1) { + call Use(ldloc test) + leave IL_002b (nop) + } + + } finally BlockContainer { + Block IL_0045 (incoming: 1) { + if (comp.o(ldloc test == ldnull)) leave IL_0045 (nop) + br IL_00ae + } + + Block IL_00ae (incoming: 1) { + await(addressof System.Threading.Tasks.ValueTask(callvirt DisposeAsync(ldloc test))) + leave IL_0045 (nop) + } + + } + + + + + Must be in sync with . + + + + + catch E_189 : 0200007C System.Exception when (BlockContainer { + Block IL_0079 (incoming: 1) { + stloc S_30(ldloc E_189) + br IL_0085 + } + + Block IL_0085 (incoming: 1) { + stloc I_1(ldloc S_30) + where S_30 and I_1 are single definition + => + copy-propagate E_189 to replace all uses of S_30 and I_1 + + + + + Block entryPoint (incoming: 1) { + stloc temp(isinst exceptionType(ldloc exceptionVar)) + if (comp(ldloc temp != ldnull)) br whenConditionBlock + br falseBlock + } + + + + + Block falseBlock (incoming: 1) { + stloc returnVar(ldc.i4 0) + br exitBlock + } + + + + + Block exitBlock(incoming: 2) { + leave container(ldloc returnVar) + } + + + + + stloc lockObj(lockExpression) + call Enter(ldloc lockObj) + .try BlockContainer { + Block lockBlock (incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + + } finally BlockContainer { + Block exitBlock (incoming: 1) { + call Exit(ldloc lockObj) + leave exitBlock (nop) + } + + } + => + .lock (lockExpression) BlockContainer { + Block lockBlock (incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + } + + + + + stloc lockObj(ldloc tempVar) + call Enter(ldloc tempVar) + .try BlockContainer { + Block lockBlock(incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + } finally BlockContainer { + Block exitBlock(incoming: 1) { + call Exit(ldloc lockObj) + leave exitBlock (nop) + } + } + => + .lock (lockObj) BlockContainer { + Block lockBlock (incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + } + + + + + stloc flag(ldc.i4 0) + .try BlockContainer { + Block lockBlock (incoming: 1) { + call Enter(stloc obj(lockObj), ldloca flag) + call WriteLine() + leave lockBlock (nop) + } + } finally BlockContainer { + Block (incoming: 1) { + if (ldloc flag) Block { + call Exit(ldloc obj) + } + leave lockBlock (nop) + } + } + => + .lock (lockObj) BlockContainer { + Block lockBlock (incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + } + + + + + stloc flag(ldc.i4 0) + .try BlockContainer { + Block lockBlock (incoming: 1) { + stloc obj1(stloc obj2(lockObj)) + call Enter(ldloc obj2, ldloca flag) + call WriteLine() + leave lockBlock (nop) + } + } finally BlockContainer { + Block (incoming: 1) { + if (ldloc flag) Block { + call Exit(ldloc obj1) + } + leave lockBlock (nop) + } + } + => + .lock (lockObj) BlockContainer { + Block lockBlock (incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + } + + + + + stloc obj(lockObj) + stloc flag(ldc.i4 0) + .try BlockContainer { + Block lockBlock (incoming: 1) { + call Enter(ldloc obj, ldloca flag) + call WriteLine() + leave lockBlock (nop) + } + } finally BlockContainer { + Block (incoming: 1) { + if (ldloc flag) Block { + call Exit(ldloc obj) + } + leave lockBlock (nop) + } + } + => + .lock (lockObj) BlockContainer { + Block lockBlock (incoming: 1) { + call WriteLine() + leave lockBlock (nop) + } + } + + + + + Nullable lifting gets run in two places: + * the usual form looks at an if-else, and runs within the ExpressionTransforms. + * the NullableLiftingBlockTransform handles the cases where Roslyn generates + two 'ret' statements for the null/non-null cases of a lifted operator. + + The transform handles the following languages constructs: + * lifted conversions + * lifted unary and binary operators + * lifted comparisons + * the ?? operator with type Nullable{T} on the left-hand-side + * the ?. operator (via NullPropagationTransform) + + + + + Main entry point into the normal code path of this transform. + Called by expression transform. + + + + + VS2017.8 / Roslyn 2.9 started optimizing some cases of + "a.GetValueOrDefault() == b.GetValueOrDefault() && (a.HasValue & b.HasValue)" + to + "(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)" + so this secondary entry point analyses logic.and as-if it was a short-circuiting &&. + + + + + VS2022.10 / Roslyn 4.10.0 adds an optimization that turns + a == 42 into a.GetValueOrDefault() == 42 without any HasValue check. + + + + + Main entry point for lifting; called by both the expression-transform + and the block transform. + + + + + Represents either non-lifted IL `Comp` or a call to one of the (non-lifted) 6 comparison operators on `System.Decimal`. + + + + + Lift a C# comparison. + This method cannot be used for (in)equality comparisons where both sides are nullable + (these special cases are handled in LiftCSharpEqualityComparison instead). + + The output instructions should evaluate to false when any of the nullableVars is null + (except for newComparisonKind==Inequality, where this case should evaluate to true instead). + Otherwise, the output instruction should evaluate to the same value as the input instruction. + The output instruction should have the same side-effects (incl. exceptions being thrown) as the input instruction. + This means unlike LiftNormal(), we cannot rely on the input instruction not being evaluated if + a variable is null. + + + + + Performs nullable lifting. + + Produces a lifted instruction with semantics equivalent to: + (v1 != null && ... && vn != null) ? trueInst : falseInst, + where the v1,...,vn are the this.nullableVars. + If lifting fails, returns null. + + + + + Recursive function that lifts the specified instruction. + The input instruction is expected to a subexpression of the trueInst + (so that all nullableVars are guaranteed non-null within this expression). + + Creates a new lifted instruction without modifying the input instruction. + On success, returns (new lifted instruction, bitset). + If lifting fails, returns (null, null). + + The returned bitset specifies which nullableVars were considered "relevant" for this instruction. + bitSet[i] == true means nullableVars[i] was relevant. + + The new lifted instruction will have equivalent semantics to the input instruction + if all relevant variables are non-null [except that the result will be wrapped in a Nullable{T} struct]. + If any relevant variable is null, the new instruction is guaranteed to evaluate to null + without having any other effect. + + + + + Matches 'call get_HasValue(arg)' + + + + + Matches 'call get_HasValue(ldloca v)' + + + + + Matches 'call get_HasValue(ldloca v)' + + + + + Matches 'logic.not(call get_HasValue(ldloca v))' + + + + + Matches 'newobj Nullable{underlyingType}.ctor(arg)' + + + + + Matches 'call Nullable{T}.GetValueOrDefault(arg)' + + + + + Matches 'call nullableValue.GetValueOrDefault(fallback)' + + + + + Matches 'call Nullable{T}.GetValueOrDefault(ldloca v)' + + + + + Matches 'call Nullable{T}.GetValueOrDefault(ldloca v)' + + + + + Transform for constructing the NullCoalescingInstruction (if.notnull(a,b), or in C#: ??) + Note that this transform only handles the case where a,b are reference types. + + The ?? operator for nullable value types is handled by NullableLiftingTransform. + + + + + Handles NullCoalescingInstruction case 1: reference types. + + + + + stloc v(value) + if (logic.not(call get_HasValue(ldloca v))) throw(...) + ... Call(arg1, arg2, call GetValueOrDefault(ldloca v), arg4) ... + => + ... Call(arg1, arg2, if.notnull(value, throw(...)), arg4) ... + + + + + IL transform that runs on a sequence of statements within a block. + + + Interleaving different statement-combining transforms on a per-statement level + improves detection of nested constructs. + For example, array initializers can assume that each element assignment was already + reduced to a single statement, even if the element contains a high-level construct + detected by a different transform (e.g. object initializer). + + + + + Runs the transform on the statements within a block. + + Note: the transform may only modify block.Instructions[pos..]. + The transform will be called repeatedly for pos=block.Instructions.Count-1, pos=block.Instructions.Count-2, ..., pos=0. + + The current block. + The starting position where the transform is allowed to work. + Additional parameters. + + Instructions prior to block.Instructions[pos] must not be modified. + It is valid to read such instructions, but not recommended as those have not been transformed yet. + + This function is only called on control-flow blocks with unreachable end-point. + Thus, the last instruction in the block always must have the EndPointUnreachable flag. + ==> Instructions with reachable end can't be last. Some transforms use this to save some bounds checks. + + + + + Parameter class holding various arguments for . + + + + + Gets the block on which the transform is running. + + + + + After the current statement transform has completed, + do not continue with the next statement transform at the same position. + Instead, re-run all statement transforms (including the current transform) starting at the specified position. + + + + + After the current statement transform has completed, + repeat all statement transforms on the current position. + + + + + Block transform that runs a list of statement transforms. + + + + + Transforms collection and object initialization patterns. + + + + + Per-block IL transform. + + + + + Runs the transform on the specified block. + + Note: the transform may only modify the specified block and its descendants, + as well as any sibling blocks that are dominated by the specified block. + + + + + Parameter class holding various arguments for . + + + + + The block to process. + + + Should be identical to the block parameter to IBlockTransform.Run. + + + + + The control flow node corresponding to the block being processed. + + + Identical to ControlFlowGraph.GetNode(Block). + Note: the control flow graph is not up-to-date, but was created at the start of the + block transforms (before loop detection). + + + + + Gets the control flow graph. + + Note: the control flow graph is not up-to-date, but was created at the start of the + block transforms (before loop detection). + + + + + Initially equal to Block.Instructions.Count indicating that nothing has been transformed yet. + Set by when another already transformed block is merged into + the current block. Subsequent s must update this value, for example, + by resetting it to Block.Instructions.Count. will use this value to + skip already transformed instructions. + + + + + IL transform that runs a list of per-block transforms. + + + + + Walks the dominator tree rooted at entryNode, calling the transforms on each block. + + + + + if (comp(ldsfld CachedAnonMethodDelegate == ldnull)) { + stsfld CachedAnonMethodDelegate(DelegateConstruction) + } + ... one usage of CachedAnonMethodDelegate ... + => + ... one usage of DelegateConstruction ... + + + + + if (comp(ldloc v == ldnull)) { + stloc v(DelegateConstruction) + } + => + stloc v(DelegateConstruction) + + + + + stloc s(ldobj(ldsflda(CachedAnonMethodDelegate)) + if (comp(ldloc s == null)) { + stloc s(stobj(ldsflda(CachedAnonMethodDelegate), DelegateConstruction)) + } + => + stloc s(DelegateConstruction) + + + + + stloc s(ldobj(ldflda(CachedAnonMethodDelegate)) + if (comp(ldloc s == null)) { + stloc s(stobj(ldflda(CachedAnonMethodDelegate), DelegateConstruction)) + } + => + stloc s(DelegateConstruction) + + + + + if (comp.i4(comp.o(ldobj delegateType(ldsflda CachedAnonMethodDelegate) != ldnull) == ldc.i4 0)) Block { + stloc s(stobj(ldflda(CachedAnonMethodDelegate), DelegateConstruction)) + } else Block { + stloc s(ldobj System.Action(ldsflda $I4-1)) + } + => + stloc s(DelegateConstruction) + + + + + if (comp.o(ldsfld CachedAnonMethodDelegate != ldnull)) { + leave IL_0005 (ldsfld CachedAnonMethodDelegate) + } + leave IL_0005 (stsfld CachedAnonMethodDelegate(DelegateConstruction)) + => + leave IL_0005 (DelegateConstruction) + + + + + if (comp.o(ldobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure)) != ldnull)) Block { + stloc s(ldobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure))) + } else Block { + stloc s(stobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure), DelegateConstruction)) + } + => + stloc s(DelegateConstruction) + + + + + Runs a very simple form of copy propagation. + Copy propagation is used in two cases: + 1) assignments from arguments to local variables + If the target variable is assigned to only once (so always is that argument) and the argument is never changed (no ldarga/starg), + then we can replace the variable with the argument. + 2) assignments of address-loading instructions to local variables + + + + + Per-function IL transform. + + + + + Parameter class holding various arguments for . + + + + + Creates a new ILReader instance for decompiling another method in the same assembly. + + + + + Call this method immediately before performing a transform step. + Unlike context.Stepper.Step(), calls to this method are only compiled in debug builds. + + + + + Performs inlining transformations. + + + + + Inlines instructions before pos into block.Instructions[pos]. + + The number of instructions that were inlined. + + + + Aggressively inlines the stloc instruction at block.Body[pos] into the next instruction, if possible. + + + + + Inlines the stloc instruction at block.Instructions[pos] into the next instruction, if possible. + + + + + Inlines the stloc instruction at block.Instructions[pos] into the next instruction. + + Note that this method does not check whether 'v' has only one use; + the caller is expected to validate whether inlining 'v' has any effects on other uses of 'v'. + + + + + Inlines 'expr' into 'next', if possible. + + Note that this method does not check whether 'v' has only one use; + the caller is expected to validate whether inlining 'v' has any effects on other uses of 'v'. + + + + + Is this a temporary variable generated by the C# compiler for instance method calls on value type values + + The load instruction (a descendant within 'next') + The variable being inlined. + + + + Gets whether the instruction, when converted into C#, turns into an l-value that can + be used to mutate a value-type. + If this function returns false, the C# compiler would introduce a temporary copy + when calling a method on a value-type (and any mutations performed by the method will be lost) + + + + + Gets whether the ILInstruction will turn into a C# expresion that is considered readonly by the C# compiler. + + + + + Determines whether a variable should be inlined in non-aggressive mode, even though it is not a generated variable. + + The next top-level expression + The variable being eliminated by inlining. + The expression being inlined + + + + Gets whether 'expressionBeingMoved' can be inlined into 'expr'. + + + + + Found a load; inlining is possible. + + + + + Load not found and re-ordering not possible. Stop the search. + + + + + Load not found, but the expressionBeingMoved can be re-ordered with regards to the + tested expression, so we may continue searching for the matching load. + + + + + Found a load in call, but re-ordering not possible with regards to the + other call arguments. + Inlining is not possible, but we might convert the call to named arguments. + Only used with . + + + + + Found a deconstruction. + Only used with . + + + + + Finds the position to inline to. + + true = found; false = cannot continue search; null = not found + + + + Determines whether it is safe to move 'expressionBeingMoved' past 'expr' + + + + + Finds the first call instruction within the instructions that were inlined into inst. + + + + + Gets whether 'expressionBeingMoved' can be moved from somewhere before 'stmt' to become the replacement of 'targetLoad'. + + + + + Gets whether 'expressionBeingMoved' can be moved from somewhere before 'stmt' to become the replacement of 'targetLoad'. + + + + + Gets whether arg can be un-inlined out of stmt. + + + + + + Collection of transforms that detect simple expression patterns + (e.g. 'cgt.un(..., ld.null)') and replace them with different instructions. + + + Should run after inlining so that the expression patterns can be detected. + + + + + newobj Delegate..ctor(target, ldvirtftn TargetMethod(target)) + => + ldvirtdelegate System.Delegate TargetMethod(target) + + + + + newobj Span..ctor(localloc(conv i4->u <zero extend>(ldc.i4 sizeInBytes)), numberOfElementsExpr) + => + localloc.span T(numberOfElementsExpr) + + -or- + + newobj Span..ctor(Block IL_0000 (StackAllocInitializer) { + stloc I_0(localloc(conv i4->u<zero extend>(ldc.i4 sizeInBytes))) + ... + final: ldloc I_0 + }, numberOfElementsExpr) + => + Block IL_0000 (StackAllocInitializer) { + stloc I_0(localloc.span T(numberOfElementsExpr)) + ... + final: ldloc I_0 + } + + + + + op is either add or remove/subtract: + if (dynamic.isevent (target)) { + dynamic.invokemember.invokespecial.discard op_Name(target, value) + } else { + dynamic.compound.op (dynamic.getmember Name(target), value) + } + => + dynamic.compound.op (dynamic.getmember Name(target), value) + + + + + dynamic.setmember.compound Name(target, dynamic.binary.operator op(dynamic.getmember Name(target), value)) + => + dynamic.compound.op (dynamic.getmember Name(target), value) + + + + + dynamic.setindex.compound(target, index, dynamic.binary.operator op(dynamic.getindex(target, index), value)) + => + dynamic.compound.op (dynamic.getindex(target, index), value) + + + + + catch ex : TException when (...) BlockContainer { + Block entryPoint (incoming: 1) { + stloc v(ldloc ex) + ... + } + } + => + catch v : TException when (...) BlockContainer { + Block entryPoint (incoming: 1) { + ... + } + } + + + + + Inline condition from catch-when condition BlockContainer, if possible. + + + + + Transforms anonymous methods and lambdas by creating nested ILFunctions. + + + + + Replaces loads of 'this' with the target expression. + Async delegates use: ldobj(ldloca this). + + + + + Remove HasInitialValue from locals that are definitely assigned before every use + (=the initial value is a dead store). + + In yield return generators, additionally removes dead 'V = null;' assignments. + + Additionally infers IType of stack slots that have StackType.Ref + + + + + Live range splitting for IL variables. + + + + + Address is immediately used for reading and/or writing, + without the possibility of the variable being directly stored to (via 'stloc') + in between the 'ldloca' and the use of the address. + + + + + We support some limited form of ref locals referring to a target variable, + without giving up splitting of the target variable. + Requirements: + * the ref local is single-assignment + * the ref local is initialized directly with 'ldloca target; stloc ref_local', + not a derived pointer (e.g. 'ldloca target; ldflda F; stloc ref_local'). + * all uses of the ref_local are immediate. + There may be stores to the target variable in between the 'stloc ref_local' and its uses, + but we handle that case by treating each use of the ref_local as an address access + of the target variable (as if the ref_local was eliminated via copy propagation). + + + + + Given 'ldloc ref_local' and 'ldloca target; stloc ref_local', returns the ldloca. + This function must return a non-null LdLoca for every use of a SupportedRefLocal. + + + + + Use the union-find structure to merge + + + Instructions in a group are stores to the same variable that must stay together (cannot be split). + + + + + For each uninitialized variable, one representative instruction that + potentially observes the unintialized value of the variable. + Used to merge together all such loads of the same uninitialized value. + + + + + Gets the new variable for a LdLoc, StLoc or TryCatchHandler instruction. + + + + + Exception thrown when an IL transform runs into the . + + + + + Helper class that manages recording transform steps. + + + + + Gets whether stepping of built-in transforms is supported in this build of ICSharpCode.Decompiler. + Usually only debug builds support transform stepping. + + + + + BeginStep is inclusive. + + + + + EndStep is exclusive. + + + + + Call this method immediately before performing a transform step. + Used for debugging the IL transforms. Has no effect in release mode. + + May throw in debug mode. + + + + + Transforms array initialization pattern of System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray. + For collection and object initializers see + + + + + Handle simple case where RuntimeHelpers.InitializeArray is not used. + + + + + call InitializeArray(newarr T(size), ldmembertoken fieldToken) + => + Block (ArrayInitializer) { + stloc i(newarr T(size)) + stobj T(ldelema T(... indices ...), value) + final: ldloc i + } + + + + + Constructs compound assignments and inline assignments. + + + This is a statement transform; + but some portions are executed as an expression transform instead + (with HandleCompoundAssign() as entry point) + + + + + stloc s(value) + stloc l(ldloc s) + stobj(..., ldloc s) + where ... is pure and does not use s or l, + and where neither the 'stloc s' nor the 'stobj' truncates + --> + stloc l(stobj (..., value)) + + e.g. used for inline assignment to instance field + + -or- + + + stloc s(value) + stobj (..., ldloc s) + where ... is pure and does not use s, and where the 'stobj' does not truncate + --> + stloc s(stobj (..., value)) + + e.g. used for inline assignment to static field + + -or- + + + stloc s(value) + call set_Property(..., ldloc s) + where the '...' arguments are pure and not using 's' + --> + stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i }) + new temporary 'i' has type of the property; transform only valid if 'stloc i' doesn't truncate + + + + + Transform compound assignments where the return value is not being used, + or where there's an inlined assignment within the setter call. + + Patterns handled: + 1. + callvirt set_Property(ldloc S_1, binary.op(callvirt get_Property(ldloc S_1), value)) + ==> compound.op.new(callvirt get_Property(ldloc S_1), value) + 2. + callvirt set_Property(ldloc S_1, stloc v(binary.op(callvirt get_Property(ldloc S_1), value))) + ==> stloc v(compound.op.new(callvirt get_Property(ldloc S_1), value)) + 3. + stobj(target, binary.op(ldobj(target), ...)) + where target is pure + => compound.op(target, ...) + + + Called by ExpressionTransforms, or after the inline-assignment transform for setters. + + + + + stloc s(value) + stloc l(ldloc s) + where neither 'stloc s' nor 'stloc l' truncates the value + --> + stloc s(stloc l(value)) + + + + + The value is not implicitly truncated. + + + + + The value is implicitly truncated. + + + + + The value is implicitly truncated, but the sign of the target type can be changed to remove the truncation. + + + + + Gets whether 'stobj type(..., value)' would evaluate to a different value than 'value' + due to implicit truncation. + + + + + Gets whether 'inst' is a possible store for use as a compound store. + + + Output parameters: + storeType: The type of the value being stored. + value: The value being stored (will be analyzed further to detect compound assignments) + + Every IsCompoundStore() call should be followed by an IsMatchingCompoundLoad() call. + + + + + Checks whether 'load' and 'store' both access the same store, and can be combined to a compound assignment. + + The load instruction to test. + The compound store to test against. Must have previously been tested via IsCompoundStore() + The target to use for the compound assignment instruction. + The target kind to use for the compound assignment instruction. + If set to a non-null value, call this delegate to fix up minor mismatches between getter and setter. + + If given a non-null value, this function returns false if the forbiddenVariable is used in the load/store instructions. + Some transforms effectively move a store around, + which is only valid if the variable stored to does not occur in the compound load/store. + + + Instruction preceding the load. + + + + + stloc l(stloc target(binary.add(ldloc target, ldc.i4 1))) + + + + + stobj(target, binary.add(stloc l(ldobj(target)), ldc.i4 1)) + where target is pure and does not use 'l', and the 'stloc l' does not truncate + --> + stloc l(compound.op.old(ldobj(target), ldc.i4 1)) + + -or- + + call set_Prop(args..., binary.add(stloc l(call get_Prop(args...)), ldc.i4 1)) + where args.. are pure and do not use 'l', and the 'stloc l' does not truncate + --> + stloc l(compound.op.old(call get_Prop(target), ldc.i4 1)) + + + This pattern is used for post-increment by legacy csc. + + Even though this transform operates only on a single expression, it's not an expression transform + as the result value of the expression changes (this is OK only for statements in a block). + + + + + stloc tmp(ldobj(target)) + stobj(target, binary.op(ldloc tmp, ldc.i4 1)) + target is pure and does not use 'tmp', 'stloc does not truncate' + --> + stloc tmp(compound.op.old(ldobj(target), ldc.i4 1)) + + This is usually followed by inlining or eliminating 'tmp'. + + Local variables use a similar pattern, also detected by this function: + + stloc tmp(ldloc target) + stloc target(binary.op(ldloc tmp, ldc.i4 1)) + --> + stloc tmp(compound.op.old(ldloca target, ldc.i4 1)) + + + This pattern occurs with legacy csc for static fields, and with Roslyn for most post-increments. + + + + + Similar to , but acts only on leave instructions + leaving the whole function (return/yield break) that can be made implicit + without using goto. + + + + + Decompiler step for C# 5 async/await. + + + + + Matches a (potentially virtual) instance method call. + + + + + Matches a store to the state machine. + + + + + First peek into MoveNext(); analyzes everything outside the big try-catch. + + + + + Analyse the DisposeAsync() method in order to find the disposeModeField. + + + + + Analyze the the state machine; and replace 'leave IL_0000' with await+jump to block that gets + entered on the next MoveNext() call. + + + + + Eliminates usage of doFinallyBodies + + + + + Analyzes all catch handlers and returns every handler that follows the await catch handler pattern. + + + + + Matches the await catch handler pattern: + [stloc V_3(ldloc E_100) - copy exception variable to a temporary] + stloc V_6(ldloc V_3) - store exception in 'global' object variable + stloc V_5(ldc.i4 2) - store id of catch block in 'identifierVariable' + br IL_0075 - jump out of catch block to the head of the catch-handler jump table + + + + The type that contains the function being decompiled. + + + The compiler-generated enumerator class. + Set in MatchEnumeratorCreationPattern() + + + The constructor of the compiler-generated enumerator class. + Set in MatchEnumeratorCreationPattern() + + + Set in MatchEnumeratorCreationPattern() + + + Set in MatchEnumeratorCreationPattern() or ConstructExceptionTable() + + + Set in MatchEnumeratorCreationPattern() + If this is true, then isCompiledWithVisualBasic is also true. + + + The dispose method of the compiler-generated enumerator class. + Set in ConstructExceptionTable() + + + The field in the compiler-generated class holding the current state of the state machine + Set in AnalyzeCtor() for MS, MatchEnumeratorCreationPattern() or AnalyzeMoveNext() for Mono + + + The backing field of the 'Current' property in the compiler-generated class + Set in AnalyzeCurrentProperty() + + + The disposing field of the compiler-generated enumerator class. + Set in ConstructExceptionTable() for assembly compiled with Mono + + + Maps the fields of the compiler-generated class to the original parameters. + Set in MatchEnumeratorCreationPattern() and ResolveIEnumerableIEnumeratorFieldMapping() + + + This dictionary stores the information extracted from the Dispose() method: + for each "Finally Method", it stores the set of states for which the method is being called. + Set in ConstructExceptionTable() + + + + For each finally method, stores the target state when entering the finally block, + and the decompiled code of the finally method body. + + + + + Temporary stores for 'yield break'. + + + + + Local bool variable in MoveNext() that signifies whether to skip finally bodies. + + + + + Local bool variable in MoveNext() that signifies whether to execute finally bodies. + + + + + Set of variables might hold copies of the generated state field. + + + + + Matches the body of a method as a single basic block. + + + + + Matches the newobj instruction that creates an instance of the compiler-generated enumerator helper class. + + + + + Looks at the enumerator's ctor and figures out which of the fields holds the state. + + + + + Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step. + + + + + Looks at the enumerator's get_Current method and figures out which of the fields holds the current value. + + + + + Convert the old body (of MoveNext function) to the new body (of decompiled iterator method). + + * Replace the sequence + this.currentField = expr; + this.state = N; + return true; + with: + yield return expr; + goto blockForState(N); + * Replace the sequence: + this._finally2(); + this._finally1(); + return false; + with: + yield break; + * Reconstruct try-finally blocks from + (on enter) this.state = N; + (on exit) this._finallyX(); + + + + + Translates all field accesses in `function` to local variable accesses. + + + + + Reconstruct try-finally blocks. + * The stateChanges (iterator._state = N;) tell us when to open a try-finally block + * The calls to the finally method tell us when to leave the try block. + + There might be multiple stateChanges for a given try-finally block, e.g. + both the original entry point, and the target when leaving a nested block. + In proper C# code, the entry point of the try-finally will dominate all other code + in the try-block, so we can use dominance to find the proper entry point. + + Precondition: the blocks in newBody are topologically sorted. + + + + + Eliminates usage of doFinallyBodies + + + + + Holds the control flow graph. + A separate graph is computed for each BlockContainer at the start of the block transforms + (before loop detection). + + + + + The container for which the ControlFlowGraph was created. + + This may differ from the container currently holding a block, + because a transform could have moved the block since the CFG was created. + + + + + Nodes array, indexed by original block index. + + Originally cfg[i].UserData == container.Blocks[i], + but the ILAst blocks may be moved/reordered by transforms. + + + + + + + + Dictionary from Block to ControlFlowNode. + Unlike the cfg array, this can be used to discover control flow nodes even after + blocks were moved/reordered by transforms. + + + + + nodeHasDirectExitOutOfContainer[i] == true iff cfg[i] directly contains a + branch/leave instruction leaving the container. + + + + + nodeHasReachableExit[i] == true iff there is a path from cfg[i] to a node not dominated by cfg[i], + or if there is a path from cfg[i] to a branch/leave instruction leaving the container. + + + + + Constructs a control flow graph for the blocks in the given block container. + + Return statements, exceptions, or branches leaving the block container are not + modeled by the control flow graph. + + + + + Gets the ControlFlowNode for the block. + + Precondition: the block belonged to the container at the start of the block transforms + (when the control flow graph was created). + + + + + Returns true iff there is a control flow path from node to one of the following: + * branch or leave instruction leaving this.Container + * branch instruction within this container to another node that is not dominated by node. + + If this function returns false, the only way control flow can leave the set of nodes + dominated by node is by executing a return or throw instruction. + + + + + Gets whether the control flow node directly contains a branch/leave instruction + exiting the container. + + + + + Symbolically executes code to determine which blocks are reachable for which values + of the 'state' field. + + + Assumption: there are no loops/backward jumps + We 'run' the code, with "state" being a symbolic variable + so it can form expressions like "state + x" (when there's a sub instruction) + + For each block, we maintain the set of values for state for which the block is reachable. + This is (int.MinValue, int.MaxValue) for the first instruction. + These ranges are propagated depending on the conditional jumps performed by the code. + + + + + Creates a new StateRangeAnalysis with the same settings, including any cached state vars + discovered by this analysis. + However, the new analysis has a fresh set of result ranges. + + + + + Assign state ranges for all blocks within 'inst'. + + + The set of states for which the exit point of the instruction is reached. + This must be a subset of the input set. + + Returns an empty set for unsupported instructions. + + + + + Gets a mapping from states to blocks. + + Within the given container (which should be the container that was analyzed), + the mapping prefers the last block. + Blocks outside of the given container are preferred over blocks within the container. + + + + + This exception is thrown when we find something else than we expect from the C# compiler. + This aborts the analysis and makes the whole transform fail. + + + + + Unknown value + + + + + int: Constant (result of ldc.i4) + + + + + int: State + Constant + + + + + This pointer (result of ldarg.0) + + + + + bool: ValueSet.Contains(State) + + + + + Detects 'if' structure and other non-loop aspects of control flow. + + + Order dependency: should run after loop detection. + Blocks should be basic blocks prior to this transform. + After this transform, they will be extended basic blocks. + + + + + Builds structured control flow for the block associated with the control flow node. + + + After a block was processed, it should use structured control flow + and have just a single 'regular' exit point (last branch instruction in the block) + + + + + Repeatedly inlines and simplifies, maintaining a good block exit and then attempting to match IL order + + + + + if (...) br trueBlock; + -> + if (...) { trueBlock... } + + Only inlines branches that are strictly dominated by this block (incoming edge count == 1) + + + + + ...; br nextBlock; + -> + ...; { nextBlock... } + + Only inlines branches that are strictly dominated by this block (incoming edge count == 1) + + + + + Gets whether potentialBranchInstruction is a branch to a block that is dominated by cfgNode. + If this function returns true, we replace the branch instruction with the block itself. + + + + + Looks for common exits in the inlined then and else branches of an if instruction + and performs inversions and simplifications to merge them provided they don't + isolate a higher priority block exit + + + + + Finds all exits which could be brought to the block root via inversion + + + + + Recursively performs inversions to bring a desired exit to the root of the block + for example: + if (a) { + ...; + if (b) { + ...; + targetExit; + } + ...; + exit1; + } + ...; + exit2; + -> + if (!a) { + ...; + exit2; + } + ...; + if (!b) { + ...; + exit1; + } + ...; + targetExit; + + + + + Anticipates the introduction of an || operator when merging ifInst and elseExit + + if (cond) commonExit; + if (cond2) commonExit; + ...; + blockExit; + will become: + if (cond || cond2) commonExit; + ...; + blockExit; + + + + + if (cond) { then... } + else...; + exit; + -> + if (!cond) { else...; exit } + then...; + + Assumes ifInst does not have an else block + + + + + if (cond) { } else { ... } + -> + if (!cond) { ... } + + + + + if (cond) { if (nestedCond) { nestedThen... } } + -> + if (cond && nestedCond) { nestedThen... } + + + + + if (cond) { lateBlock... } else { earlyBlock... } + -> + if (!cond) { earlyBlock... } else { lateBlock... } + + + + + Compares the current block exit, and the exit of ifInst.ThenInst + and inverts if necessary to pick the better exit + + Does nothing when ifInst has an else block (because inverting wouldn't affect the block exit) + + + + + Compares two exit instructions for block exit priority + A higher priority exit should be kept as the last instruction in a block + even if it prevents the merging of a two compatible lower priority exits + + leave from try containers must always be the final instruction, or a goto will be inserted + loops will endeavour to leave at least one continue branch as the last instruction in the block + + The priority is: + leave > branch > other-keyword > continue > return > break + + non-keyword leave instructions are ordered with the outer container having higher priority + + if the exits have equal priority, and the strongly flag is not provided + then the exits are sorted by IL order (target block for branches) + + break has higher priority than other keywords in a switch block (for aesthetic reasons) + + {-1, 0, 1} if exit1 has {lower, equal, higher} priority an exit2 + + + + Determines if an exit instruction has a corresponding keyword and thus doesn't strictly need merging + Branches can be 'continue' or goto (non-keyword) + Leave can be 'return', 'break' or a pinned container exit (try/using/lock etc) + All other instructions (throw, using, etc) are returned as Keyword.Other + + + + + Determine if the specified instruction necessarily exits (EndPointUnreachable) + and if so return last (or single) exit instruction + + + + + Gets the final instruction from a block (or a single instruction) assuming that all blocks + or instructions in this position have unreachable endpoints + + + + + Returns true if inst is Nop or a Block with no instructions. + + + + + Import some pattern matching from HighLevelLoopTransform to guess the continue block of loop containers. + Used to identify branches targetting this block as continue statements, for ordering priority. + + + + + + Removes a subrange of instructions from a block and returns them in a new Block + + + + + This transform 'optimizes' the control flow logic in the IL code: + it replaces constructs that are generated by the C# compiler in debug mode + with shorter constructs that are more straightforward to analyze. + + + The transformations performed are: + * 'nop' instructions are removed + * branches that lead to other branches are replaced with branches that directly jump to the destination + * branches that lead to a 'return block' are replaced with a return instruction + * basic blocks are combined where possible + + + + + Returns true if the last two instructions before the branch are storing the value 'true' into an unused variable. + + + + + IL uses 'pinned locals' to prevent the GC from moving objects. + + C#: + + fixed (int* s = &arr[index]) { use(s); use(s); } + + + Gets translated into IL: + + pinned local P : System.Int32& + + stloc(P, ldelema(arr, index)) + call use(conv ref->i(ldloc P)) + call use(conv ref->i(ldloc P)) + stloc(P, conv i4->u(ldc.i4 0)) + + + In C#, the only way to pin something is to use a fixed block + (or to mess around with GCHandles). + But fixed blocks are scoped, so we need to detect the region affected by the pin. + To ensure we'll be able to collect all blocks in that region, we perform this transform + early, before building any other control flow constructs that aren't as critical for correctness. + + This means this transform must run before LoopDetection. + To make our detection job easier, we must run after variable inlining. + + + + + Ensures that every write to a pinned local is followed by a branch instruction. + This ensures the 'pinning region' does not involve any half blocks, which makes it easier to extract. + + + + + After a pinned region was detected; process its body; replacing the pin variable + with a native pointer as far as possible. + + + + + Modifies a pinned region to eliminate an extra local variable that roslyn tends to generate. + + + + + Detect suitable exit points for BlockContainers. + + An "exit point" is an instruction that causes control flow + to leave the container (a branch or leave instruction). + + If an "exit point" instruction is placed immediately following a + block container, each equivalent exit point within the container + can be replaced with a "leave container" instruction. + + This transform performs this replacement: any exit points + equivalent to the exit point following the container are + replaced with a leave instruction. + Additionally, if the container is not yet followed by an exit point, + but has room to introduce such an exit point (i.e. iff the container's + end point is currently unreachable), we pick one of the non-return + exit points within the container, move it to the position following the + container, and replace all instances within the container with a leave + instruction. + + This makes it easier for the following transforms to construct + control flow that falls out of blocks instead of using goto/break statements. + + + + + Gets the next instruction after is executed. + Returns NoExit when the next instruction cannot be identified; + returns null when the end of a Block is reached (so that we could insert an arbitrary instruction) + + + + + Returns true iff exit1 and exit2 are both exit instructions + (branch or leave) and both represent the same exit. + + + + + The instruction that will be executed next after leaving the Container. + ExitNotYetDetermined means the container is last in its parent block, and thus does not + yet have any leave instructions. This means we can move any exit instruction of + our choice our of the container and replace it with a leave instruction. + + + + + If currentExit==ExitNotYetDetermined, holds the list of potential exit instructions. + After the currentContainer was visited completely, one of these will be selected as exit instruction. + + + + + Detect loops in IL AST. + + + Transform ordering: + * LoopDetection should run before other control flow structures are detected. + * Blocks should be basic blocks (not extended basic blocks) so that the natural loops + don't include more instructions than strictly necessary. + * Loop detection should run after the 'return block' is duplicated (ControlFlowSimplification). + + + + Block container corresponding to the current cfg. + + + + Enabled during DetectSwitchBody, used by ExtendLoop and children + + + + + Used when isSwitch == true, to determine appropriate exit points within loops + + + + + Check whether 'block' is a loop head; and construct a loop instruction + (nested BlockContainer) if it is. + + + + + For each block in the input loop that is the head of a nested loop or switch, + include all blocks from the nested container into the loop. + + This ensures that all blocks that were included into inner loops are also + included into the outer loop, thus keeping our loops well-nested. + + + More details for why this is necessary are here: + https://github.com/icsharpcode/ILSpy/issues/915 + + Pre+Post-Condition: node.Visited iff loop.Contains(node) + + + + + Given a natural loop, add additional CFG nodes to the loop in order + to reduce the number of exit points out of the loop. + We do this because C# only allows reaching a single exit point (with 'break' + statements or when the loop condition evaluates to false), so we'd have + to introduce 'goto' statements for any additional exit points. + + + Definition: + A "reachable exit" is a branch/leave target that is reachable from the loop, + but not dominated by the loop head. A reachable exit may or may not have a + corresponding CFG node (depending on whether it is a block in the current block container). + -> reachable exits are leaving the code region dominated by the loop + + Definition: + A loop "exit point" is a CFG node that is not itself part of the loop, + but has at least one predecessor which is part of the loop. + -> exit points are leaving the loop itself + + Nodes can only be added to the loop if they are dominated by the loop head. + When adding a node to the loop, we must also add all of that node's predecessors + to the loop. (this ensures that the loop keeps its single entry point) + + Goal: If possible, find a set of nodes that can be added to the loop so that there + remains only a single exit point. + Add as little code as possible to the loop to reach this goal. + + This means we need to partition the set of nodes dominated by the loop entry point + into two sets (in-loop and out-of-loop). + Constraints: + * the loop head itself is in-loop + * there must not be any edge from an out-of-loop node to an in-loop node + -> all predecessors of in-loop nodes are also in-loop + -> all nodes in a cycle are part of the same partition + Optimize: + * use only a single exit point if at all possible + * minimize the amount of code in the in-loop partition + (thus: maximize the amount of code in the out-of-loop partition) + + Observations: + * If a node is in-loop, so are all its ancestors in the dominator tree (up to the loop entry point) + * If there are no exits reachable from a node (i.e. all paths from that node lead to a return/throw instruction), + it is valid to put the group of nodes dominated by that node into either partition independently of + any other nodes except for the ancestors in the dominator tree. + (exception: the loop head itself must always be in-loop) + + There are two different cases we need to consider: + 1) There are no exits reachable at all from the loop head. + -> it is possible to create a loop with zero exit points by adding all nodes + dominated by the loop to the loop. + -> the only way to exit the loop is by "return;" or "throw;" + 2) There are some exits reachable from the loop head. + + In case 1, we can pick a single exit point freely by picking any node that has no reachable exits + (other than the loop head). + All nodes dominated by the exit point are out-of-loop, all other nodes are in-loop. + See PickExitPoint() for the heuristic that picks the exit point in this case. + + In case 2, we need to pick our exit point so that all paths from the loop head + to the reachable exits run through that exit point. + + This is a form of postdominance where the reachable exits are considered exit nodes, + while "return;" or "throw;" instructions are not considered exit nodes. + + Using this form of postdominance, we are looking for an exit point that post-dominates all nodes in the natural loop. + --> a common ancestor in post-dominator tree. + To minimize the amount of code in-loop, we pick the lowest common ancestor. + All nodes dominated by the exit point are out-of-loop, all other nodes are in-loop. + (using normal dominance as in case 1, not post-dominance!) + + If it is impossible to use a single exit point for the loop, the lowest common ancestor will be the fake "exit node" + used by the post-dominance analysis. In this case, we fall back to the old heuristic algorithm. + + Requires and maintains the invariant that a node is marked as visited iff it is contained in the loop. + + + + + Special control flow node (not part of any graph) that signifies that we want to construct a loop + without any exit point. + + + + + Finds a suitable single exit point for the specified loop. + + + 1) If a suitable exit point was found: the control flow block that should be reached when breaking from the loop + 2) If the loop should not have any exit point (extend by all dominated blocks): NoExitPoint + 3) otherwise (exit point unknown, heuristically extend loop): null + + This method must not write to the Visited flags on the CFG. + + + + Validates an exit point. + + An exit point is invalid iff there is a node reachable from the exit point that + is dominated by the loop head, but not by the exit point. + (i.e. this method returns false iff the exit point's dominance frontier contains + a node dominated by the loop head. but we implement this the slow way because + we don't have dominance frontiers precomputed) + + + We need this because it's possible that there's a return block (thus reverse-unreachable node ignored by post-dominance) + that is reachable both directly from the loop, and from the exit point. + + + + + Extension of ControlFlowGraph.HasReachableExit + Uses loopContext.GetBreakTargets().Any() when analyzing switches to avoid + classifying continue blocks as reachable exits. + + + + + Returns the children in a loop dominator tree, with an optional exit point + Avoids returning continue statements when analysing switches (because increment blocks can be dominated) + + + + + Pick exit point by picking any node that has no reachable exits. + + In the common case where the code was compiled with a compiler that emits IL code + in source order (like the C# compiler), we can find the "real" exit point + by simply picking the block with the highest IL offset. + So let's do that instead of maximizing amount of code. + + Code amount in and its dominated nodes. + This method must not write to the Visited flags on the CFG. + + + + Constructs a new control flow graph. + Each node cfg[i] has a corresponding node rev[i]. + Edges are only created for nodes dominated by loopHead, and are in reverse from their direction + in the primary CFG. + An artificial exit node is used for edges that leave the set of nodes dominated by loopHead, + or that leave the block Container. + + Entry point of the loop. + out: The number of different CFG nodes. + Possible values: + 0 = no CFG nodes used as exit nodes (although edges leaving the block container might still be exits); + 1 = a single CFG node (not dominated by loopHead) was used as an exit node; + 2 = more than one CFG node (not dominated by loopHead) was used as an exit node. + + + + + + This function implements a heuristic algorithm that tries to reduce the number of exit + points. It is only used as fall-back when it is impossible to use a single exit point. + + + This heuristic loop extension algorithm traverses the loop head's dominator tree in pre-order. + For each candidate node, we detect whether adding it to the loop reduces the number of exit points. + If it does, the candidate is added to the loop. + + Adding a node to the loop has two effects on the the number of exit points: + * exit points that were added to the loop are no longer exit points, thus reducing the total number of exit points + * successors of the newly added nodes might be new, additional exit points + + Requires and maintains the invariant that a node is marked as visited iff it is contained in the loop. + + + + + Gets whether 'node' is an exit point for the loop marked by the Visited flag. + + + + + Move the blocks associated with the loop into a new block container. + + + + + C# switch statements are not necessarily compiled into IL switch instructions. + For example, when the label values are not contiguous, the C# compiler + will generate if statements similar to a binary search. + + This class analyses such sequences of if statements to reconstruct the original switch. + + + This analysis expects to be run on basic blocks (not extended basic blocks). + + + + + The variable that is used to represent the switch expression. + null while analyzing the first block. + + + + + The variable to be used as the argument of the switch instruction. + + + + + Whether at least one of the analyzed blocks contained an IL switch constructors. + + + + + Gets the sections that were detected by the previous AnalyzeBlock() call. + + + + + Used to de-duplicate sections with a branch instruction. + Invariant: (Sections[targetBlockToSectionIndex[branch.TargetBlock]].Instruction as Branch).TargetBlock == branch.TargetBlock + + + + + Used to de-duplicate sections with a value-less leave instruction. + Invariant: (Sections[targetBlockToSectionIndex[leave.TargetContainer]].Instruction as Leave).TargetContainer == leave.TargetContainer + + + + + Blocks that can be deleted if the tail of the initial block is replaced with a switch instruction. + + + + + Gets/sets whether to allow unreachable cases in switch instructions. + + + + + Analyze the last two statements in the block and see if they can be turned into a + switch instruction. + + true if the block could be analyzed successfully; false otherwise + + + + Analyzes the tail end (last two instructions) of a block. + + + Sets switchVar and defaultInstruction if they are null, + and adds found sections to sectionLabels and sectionInstructions. + + If the function returns false, sectionLabels and sectionInstructions are unmodified. + + The block to analyze. + The possible values of the "interesting" variable + when control flow reaches this block. + If true, analyze only the tail (last two instructions). + If false, analyze the whole block. + + + + Adds a new section to the Sections list. + + If the instruction is a branch instruction, unify the new section with an existing section + that also branches to the same target. + + + + + Analyzes the boolean condition, returning the set of values of the interesting + variable for which the condition evaluates to true. + + + + + Create the LongSet that contains a value x iff x compared with value is true. + + + + + C# switch statements are not necessarily compiled into + IL switch instructions (e.g. when the integer values are non-contiguous). + + Detect sequences of conditional branches that all test a single integer value, + and simplify them into a ILAst switch instruction (which like C# does not require contiguous values). + + + + + When detecting a switch, it is important to distinguish Branch instructions which will + eventually decompile to continue; statements. + + A LoopContext is constructed for a node and its dominator tree, as for a Branch to be a continue; + statement, it must be contained within the target-loop + + This class also supplies the depth of the loop targetted by a continue; statement relative to the + context node, to avoid (or eventually support) labelled continues to outer loops + + + + + Lists all potential targets for break; statements from a domination tree, + assuming the domination tree must be exited via either break; or continue; + + First list all nodes in the dominator tree (excluding continue nodes) + Then return the all successors not contained within said tree. + + Note that node will be returned once for each outgoing edge. + Labelled continue statements (depth > 1) are counted as break targets + + + + + Tests whether we should prefer a switch statement over an if statement. + + + + + stloc switchValueVar(call ComputeStringHash(switchValue)) + + + + + Builds the control flow graph for the current container (if necessary), establishes loopContext + and returns the ControlFlowNodes corresponding to the inner flow and case blocks of the potential switch + + + + + Determines if the analysed switch can be constructed without any gotos + + + + + Does some of the analysis of SwitchOnNullableTransform to add the null case control flow + to the results of SwitchAnalysis + + + + + Pattern matching for short circuit expressions + p + |\ + | n + |/ \ + s c + + where + p: if (a) goto n; goto s; + n: if (b) goto c; goto s; + + Can simplify to + p|n + / \ + s c + + where: + p|n: if (a && b) goto c; goto s; + + Note that if n has only 1 successor, but is still a flow node, then a short circuit expression + has a target (c) with no corresponding block (leave) + + A node with 2 successors + The successor index to consider n (the other successor will be the common sibling) + + + + A flow node contains only two instructions, the first of which is an IfInstruction + A short circuit expression is comprised of a root block ending in an IfInstruction and one or more flow nodes + + + + + Determines whether the flowNodes are can be reduced to a single condition via short circuit operators + + + + Deconstruction statement + + + Represents a deconstructed value + + + ILAst representation of C# patterns + + + + Checks whether the input instruction can represent a pattern matching operation. + + Any pattern matching instruction will first evaluate the `testedOperand` (a descendant of `inst`), + and then match the value of that operand against the pattern encoded in the instruction. + The matching may have side-effects on the newly-initialized pattern variables + (even if the pattern fails to match!). + The pattern matching instruction evaluates to 1 (as I4) if the pattern matches, or 0 otherwise. + + + + Returns the method operand. + + + + Improves code quality by duplicating keyword exits to reduce nesting and restoring IL order. + + + ConditionDetection and DetectSwitchBody both have aggressive inlining policies for else blocks and default cases respectively. + This can lead to excessive indentation when the entire rest of the method/loop is included in the else block/default case. + When an If/SwitchInstruction is followed immediately by a keyword exit, the exit can be moved into the child blocks + allowing the else block or default case to be moved after the if/switch as all prior cases exit. + Most importantly, this transformation does not change the IL order of any code. + + ConditionDetection also has a block exit priority system to assist exit point reduction which in some cases ignores IL order. + After HighLevelLoopTransform has run, all structures have been detected and preference can be returned to maintaining IL ordering. + + + + + Visits a block in context + + + Marks the target block of continue statements. + The instruction following the end point of the block. Can only be null if the end point is unreachable. + + + + For an if statement with an unreachable end point and no else block, + inverts to match IL order of the first statement of each branch + + + + + Reduce Nesting in if/else statements by duplicating an exit instruction. + Does not affect IL order + + + + + Reduce Nesting in switch statements by replacing break; in cases with the block exit, and extracting the default case + Does not affect IL order + + + + + Checks if an exit is a duplicable keyword exit (return; break; continue;) + + + + + Ensures the end point of a block is unreachable by duplicating and appending the [exit] instruction following the end point + + The instruction/block of interest + The next instruction to be executed (provided inst does not exit) + + + + Removes a redundant block exit instruction. + + + + + Determines if an IfInstruction is an else-if and returns the preceeding (parent) IfInstruction + + [else-]if (parent-cond) else { ifInst } + + + + + Adds a code path to the current heuristic tally + + + + + Recursively computes the number of statements and maximum nested depth of an instruction + + + + + Heuristic to determine whether it is worth duplicating exits into the preceeding sibling blocks (then/else-if/case) + in order to reduce the nesting of inst by 1 + + The instruction heading the nested candidate block + The number of statements in the largest sibling block + The relative depth of the most nested statement in the sibling blocks + + + + + if (cond) { ...; exit; } else { ... } + ...; + -> + if (cond) { ...; exit; } + ...; + ...; + + + + + Instruction representing a dynamic call site. + + + ILAst representation of a cast inside a dynamic expression (maps to Binder.Convert). + + + Returns the type operand. + + + ILAst representation of a method call inside a dynamic expression (maps to Binder.InvokeMember). + + + ILAst representation of a property get method call inside a dynamic expression (maps to Binder.GetMember). + + + ILAst representation of a property set method call inside a dynamic expression (maps to Binder.SetMember). + + + ILAst representation of an indexer get method call inside a dynamic expression (maps to Binder.GetIndex). + + + ILAst representation of an indexer set method call inside a dynamic expression (maps to Binder.SetIndex). + + + ILAst representation of a constuctor invocation inside a dynamic expression (maps to Binder.InvokeConstructor). + + + ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation). + + + ILAst representation of a short-circuiting binary operator inside a dynamic expression. + + + ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation). + + + ILAst representation of a delegate invocation inside a dynamic expression (maps to Binder.Invoke). + + + ILAst representation of a call to the Binder.IsEvent method inside a dynamic expression. + + + + Analyses the RHS of a 'ptr + int' or 'ptr - int' operation. + + + + + Given an instruction that computes a pointer arithmetic offset in bytes, + returns an instruction that computes the same offset in number of elements. + + Returns null if no such instruction can be found. + + Input instruction. + The target type of the pointer type. + Whether the pointer arithmetic operation checks for overflow. + Whether to allow zero extensions in the mul argument. + + + + Returns true if inst computes the address of a fixed variable; false if it computes the address of a moveable variable. + (see "Fixed and moveable variables" in the C# specification) + + + + + Sugar for logic.not/and/or. + + + + + Sugar for ldfld/stfld. + + + + + Show IL ranges in ILAst output. + + + + + Show the child index of the instruction in ILAst output. + + + + Load address of instance field + + + Returns the field operand. + + + Indirect store (store to ref/pointer). + Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign()) + + + + called as part of CheckInvariant() + + + + Returns the type operand. + + + Gets/Sets whether the memory access is volatile. + + + Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix. + + + + For a nullable input, gets the underlying value. + + There are three possible input types: + * reference type: if input!=null, evaluates to the input + * nullable value type: if input.Has_Value, evaluates to input.GetValueOrDefault() + * generic type: behavior depends on the type at runtime. + If non-nullable value type, unconditionally evaluates to the input. + + If the input is null, control-flow is tranferred to the nearest surrounding nullable.rewrap + instruction. + + The input operand must be one of: + 1. a nullable value type + 2. a reference type + 3. a managed reference to a type parameter. + If the input is non-null, evaluates to the (unwrapped) input. + If the input is null, jumps to the innermost nullable.rewrap instruction that contains this instruction. + In case 3 (managed reference), the dereferenced value is the input being tested, and the nullable.unwrap instruction returns the managed reference unmodified (if the value is non-null). + + + + Whether the argument is dereferenced before checking for a null input. + If true, the argument must be a managed reference to a valid input type. + + + This mode exists because the C# compiler sometimes avoids copying the whole Nullable{T} struct + before the null-check. + The underlying struct T is still copied by the GetValueOrDefault() call, but only in the non-null case. + + + + + Consider the following code generated for t?.Method() on a generic t: + if (comp(box ``0(ldloc t) != ldnull)) newobj Nullable..ctor(constrained[``0].callvirt Method(ldloca t)) else default.value Nullable + Here, the method is called on the original reference, and any mutations performed by the method will be visible in the original variable. + + To represent this, we use a nullable.unwrap with ResultType==Ref: instead of returning the input value, + the input reference is returned in the non-null case. + Note that in case the generic type ends up being Nullable{T}, this means methods will end up being called on + the nullable type, not on the underlying type. However, this ends up making no difference, because the only methods + that can be called that way are those on System.Object. All the virtual methods are overridden in Nullable{T} + and end up forwarding to T; and the non-virtual methods cause boxing which strips the Nullable{T} wrapper. + + RefOutput can only be used if RefInput is also used. + + + + Serves as jump target for the nullable.unwrap instruction. + If the input evaluates normally, evaluates to the input value (wrapped in Nullable<T> if the input is a non-nullable value type).If a nullable.unwrap instruction encounters a null input and jumps to the (endpoint of the) nullable.rewrap instruction,the nullable.rewrap instruction evaluates to null. + + + Stores a value into a local variable. (IL: starg/stloc) + Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign()) + + + + If true, this stloc represents a stack type adjustment. + This field is only used in ILReader and BlockBuilder, and should be ignored by ILAst transforms. + + + + + Gets whether the IL stack was empty after this store. + Only set for store instructions from the IL; not for stores to the stack + or other stores generated by transforms. + + + + Test if object is instance of class or interface. + + + Returns the type operand. + + + Unsafe function pointer call. + + + Returns the default value for a type. + + + + Gets whether the IL stack was empty at the point of this instruction. + (not counting the argument of the instruction itself) + + + + Returns the type operand. + + + ILAst representation of Expression.Convert. + + + Returns the type operand. + + + + Infer ref readonly type from usage: + An ILVariable should be marked as readonly, + if it's a "by-ref-like" type and the initialized value is known to be readonly. + + + + Maps a string value to an integer. This is used in switch(string). + + + + IL using instruction. + Equivalent to: + + stloc v(resourceExpression) + try { + body + } finally { + v?.Dispose(); + } + + + + The value of v is undefined after the end of the body block. + + Using statement + + + + Matches an 'ldflda' instruction accessing a tuple element. + + E.g. matches: + ldflda Item1(ldflda Rest(target)) + + + + + Matches 'newobj TupleType(...)'. + Takes care of flattening long tuples. + + + + C# await operator. + + + + The collection of variables in a ILFunction. + + + + + Gets a variable given its IndexInFunction. + + + + + Remove variables that have StoreCount == LoadCount == AddressCount == 0. + + + + Lock statement + + + + Kind of null-coalescing operator. + ILAst: if.notnull(valueInst, fallbackInst) + C#: value ?? fallback + + + + + Both ValueInst and FallbackInst are of reference type. + + Semantics: equivalent to "valueInst != null ? valueInst : fallbackInst", + except that valueInst is evaluated only once. + + + + + Both ValueInst and FallbackInst are of type Nullable{T}. + + Semantics: equivalent to "valueInst.HasValue ? valueInst : fallbackInst", + except that valueInst is evaluated only once. + + + + + ValueInst is Nullable{T}, but FallbackInst is non-nullable value type. + + Semantics: equivalent to "valueInst.HasValue ? valueInst.Value : fallbackInst", + except that valueInst is evaluated only once. + + + + Null coalescing operator expression. if.notnull(valueInst, fallbackInst) + + + Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior. + + + Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior. + + + Use of user-defined && or || operator. + + + Returns the method operand. + + + Base class for pattern matching in ILAst. + + + Matches any node + + + + Data holder for a single list matching operation. + + + Notes on backtracking: + PerformMatch() may save backtracking-savepoints to the ListMatch instance. + Each backtracking-savepoints is a Stack{int} with instructions of how to restore the saved state. + When a savepoint is created by a PerformMatch() call, that call may be nested in several other PerformMatch() calls that operate on + the same list. + When leaving those calls (whether with a successful match or not), the outer PerformMatch() calls may push additional state onto + all of the added backtracking-savepoints. + When the overall list match fails but savepoints exists, the most recently added savepoint is restored by calling PerformMatch() + with listMatch.restoreStack set to that savepoint. Each PerformMatch() call must pop its state from that stack before + recursively calling its child patterns. + + + + + The main list matching logic. + + Returns whether the list match was successful. + If the method returns true, it adds the capture groups (if any) to the match. + If the method returns false, the match object remains in a partially-updated state and needs to be restored + before it can be reused. + + + + PerformMatch() for a sequence of patterns. + + List of patterns to match. + Stores state about the current list match. + The match object, used to store global state during the match (such as the results of capture groups). + Returns whether all patterns were matched successfully against a part of the list. + If the method returns true, it updates listMatch.SyntaxIndex to point to the next node that was not part of the match, + and adds the capture groups (if any) to the match. + If the method returns false, the listMatch and match objects remain in a partially-updated state and need to be restored + before they can be reused. + + + + A savepoint that the list matching operation can be restored from. + + + + + The syntax list we are matching against. + + + + + The current index in the syntax list. + + + + + Restores the listmatch state from a savepoint. + + Returns whether a savepoint exists + + + + Data holder for the overall pattern matching operation. + + + This type is a struct in order to prevent unnecessary memory allocations during pattern matching. + The default value default(Match) represents an unsuccessful match. + + + + + Gets whether the match was successful. + + + + + Gets whether the match was successful. + + + + + Gets whether the match failed. + + + + + Enum representing the type of an . + + + + Represents invalid IL. Semantically, this instruction is considered to throw some kind of exception. + + + Represents invalid IL. Semantically, this instruction is considered to produce some kind of value. + + + No operation. Takes 0 arguments and returns void. + + + A container of IL blocks. + + + A container of IL blocks. + + + A block of IL instructions. + + + A region where a pinned variable is used (initial representation of future fixed statement). + + + Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr. + + + Common instruction for numeric compound assignments. + + + Common instruction for user-defined compound assignments. + + + Common instruction for dynamic compound assignments. + + + Bitwise NOT + + + Retrieves the RuntimeArgumentHandle. + + + Unconditional branch. goto target; + + + Unconditional branch to end of block container. Return is represented using IsLeavingFunction and an (optional) return value. The block container evaluates to the value produced by the argument of the leave instruction. + + + If statement / conditional expression. if (condition) trueExpr else falseExpr + + + Null coalescing operator expression. if.notnull(valueInst, fallbackInst) + + + Switch statement + + + Switch section within a switch statement + + + Try-catch statement. + + + Catch handler within a try-catch statement. + + + Try-finally statement + + + Try-fault statement + + + Lock statement + + + Using statement + + + Breakpoint instruction + + + Comparison. The inputs must be both integers; or both floats; or both object references. Object references can only be compared for equality or inequality. Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which evaluates to 1 (true). + + + Non-virtual method call. + + + Virtual method call. + + + Unsafe function pointer call. + + + Checks that the input float is not NaN or infinite. + + + Numeric cast. + + + Loads the value of a local variable. (ldarg/ldloc) + + + Loads the address of a local variable. (ldarga/ldloca) + + + Stores a value into a local variable. (IL: starg/stloc) + Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign()) + + + Stores the value into an anonymous temporary variable, and returns the address of that variable. + + + Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior. + + + Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior. + + + The input operand must be one of: + 1. a nullable value type + 2. a reference type + 3. a managed reference to a type parameter. + If the input is non-null, evaluates to the (unwrapped) input. + If the input is null, jumps to the innermost nullable.rewrap instruction that contains this instruction. + In case 3 (managed reference), the dereferenced value is the input being tested, and the nullable.unwrap instruction returns the managed reference unmodified (if the value is non-null). + + + Serves as jump target for the nullable.unwrap instruction. + If the input evaluates normally, evaluates to the input value (wrapped in Nullable<T> if the input is a non-nullable value type).If a nullable.unwrap instruction encounters a null input and jumps to the (endpoint of the) nullable.rewrap instruction,the nullable.rewrap instruction evaluates to null. + + + Loads a constant string. + + + Loads a constant byte string (as ReadOnlySpan<byte>). + + + Loads a constant 32-bit integer. + + + Loads a constant 64-bit integer. + + + Loads a constant 32-bit floating-point number. + + + Loads a constant 64-bit floating-point number. + + + Loads a constant decimal. + + + Loads the null reference. + + + Load method pointer + + + Load method pointer + + + Virtual delegate construction + + + Loads runtime representation of metadata token + + + Loads runtime representation of metadata token + + + Allocates space in the stack frame + + + Allocates space in the stack frame and wraps it in a Span + + + memcpy(destAddress, sourceAddress, size); + + + memset(address, value, size) + + + Load address of instance field + + + Load static field address + + + Casts an object to a class. + + + Test if object is instance of class or interface. + + + Indirect load (ref/pointer dereference). + + + If argument is a ref to a reference type, loads the object reference, stores it in a temporary, and evaluates to the address of that temporary (address.of(ldobj(arg))). Otherwise, returns the argument ref as-is.This instruction represents the memory-load semantics of callvirt with a generic type as receiver (where the IL always takes a ref, but only methods on value types expect one, for method on reference types there's an implicit ldobj, which this instruction makes explicit in order to preserve the order-of-evaluation). + + + Indirect store (store to ref/pointer). + Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign()) + + + Boxes a value. + + + Compute address inside box. + + + Unbox a value. + + + Creates an object instance and calls the constructor. + + + Creates an array instance. + + + Returns the default value for a type. + + + Throws an exception. + + + Rethrows the current exception. + + + Gets the size of a type in bytes. + + + Returns the length of an array as 'native unsigned int'. + + + Load address of array element. + + + Load address of inline array element. + + + Retrieves a pinnable reference for the input object. + The input must be an object reference (O). + If the input is an array/string, evaluates to a reference to the first element/character, or to a null reference if the array is null or empty. + Otherwise, uses the GetPinnableReference method to get the reference, or evaluates to a null reference if the input is null. + + + + Maps a string value to an integer. This is used in switch(string). + + + ILAst representation of Expression.Convert. + + + Use of user-defined && or || operator. + + + ILAst representation of a short-circuiting binary operator inside a dynamic expression. + + + ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation). + + + ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation). + + + ILAst representation of a cast inside a dynamic expression (maps to Binder.Convert). + + + ILAst representation of a property get method call inside a dynamic expression (maps to Binder.GetMember). + + + ILAst representation of a property set method call inside a dynamic expression (maps to Binder.SetMember). + + + ILAst representation of an indexer get method call inside a dynamic expression (maps to Binder.GetIndex). + + + ILAst representation of an indexer set method call inside a dynamic expression (maps to Binder.SetIndex). + + + ILAst representation of a method call inside a dynamic expression (maps to Binder.InvokeMember). + + + ILAst representation of a constuctor invocation inside a dynamic expression (maps to Binder.InvokeConstructor). + + + ILAst representation of a delegate invocation inside a dynamic expression (maps to Binder.Invoke). + + + ILAst representation of a call to the Binder.IsEvent method inside a dynamic expression. + + + ILAst representation of C# patterns + + + Push a typed reference of type class onto the stack. + + + Push the type token stored in a typed reference. + + + Push the address stored in a typed reference. + + + Yield an element from an iterator. + + + C# await operator. + + + Deconstruction statement + + + Represents a deconstructed value + + + Matches any node + + + Instruction without any arguments + + A simple instruction that does not have any arguments. + + + + Instruction with a single argument + + + Instruction with two arguments: Left and Right + + + Instruction with a list of arguments. + + + + Gets/Sets whether the call has the 'tail.' prefix. + + + + + Gets/Sets the type specified in the 'constrained.' prefix. + Returns null if no 'constrained.' prefix exists for this call. + + + + + Gets whether the IL stack was empty at the point of this call. + (not counting the arguments/return value of the call itself) + + + + + Gets whether this is an instance call (i.e. whether the first argument is the 'this' pointer). + + + + + Gets the parameter for the argument with the specified index. + Returns null for the this parameter. + + + + + Gets the expected stack type for passing the this pointer in a method call. + Returns StackType.Ref if constrainedTo is not null, + StackType.O for reference types (this pointer passed as object reference), + and StackType.Ref for type parameters and value types (this pointer passed as managed reference). + + Returns StackType.Unknown if the input type is unknown. + + + + Common instruction for compound assignments. + + + + If TargetIsProperty is true, the Target must be a call to a property getter, + and the compound.assign will implicitly call the corresponding property setter. + Otherwise, the Target can be any instruction that evaluates to an address, + and the compound.assign will implicit load and store from/to that address. + + + + Represents invalid IL. Semantically, this instruction is considered to throw some kind of exception. + + + Represents invalid IL. Semantically, this instruction is considered to produce some kind of value. + + + No operation. Takes 0 arguments and returns void. + + + A container of IL blocks. + + + + Gets the method definition from metadata. + May be null for functions that were not constructed from metadata, + e.g., expression trees. + + + + + Gets the generic context of this function. + + + + + Gets the name of this function, usually this returns the name from metadata. + + For local functions: + This is the name that is used to declare and use the function. + It may not conflict with the names of local variables of ancestor functions + and may be overwritten by the AssignVariableNames step. + + For top-level functions, delegates and expressions trees modifying this usually + has no effect, as the name should not be used in the final AST construction. + + + + + + Size of the IL code in this function. + Note: after async/await transform, this is the code size of the MoveNext function. + + + + + List of ILVariables used in this function. + + + + + Gets + + + + + Gets the scope in which the local function is declared. + Returns null, if this is not a local function. + + + + + Gets the set of captured variables by this ILFunction. + + This is populated by the step. + + + + List of warnings of ILReader. + + + + + Gets whether this function is a decompiled iterator (is using yield). + This flag gets set by the YieldReturnDecompiler. + + If set, the 'return' instruction has the semantics of 'yield break;' + instead of a normal return. + + + + + Gets whether the YieldReturnDecompiler determined that the Mono C# compiler was used to compile this function. + + + + + Gets whether the YieldReturnDecompiler determined that the Legacy VB compiler was used to compile this function. + + + + + Gets whether this function is async. + This flag gets set by the AsyncAwaitDecompiler. + + + + + Return element type -- if the async method returns Task{T}, this field stores T. + If the async method returns Task or void, this field stores void. + + + + + If this function is an iterator/async, this field stores the compiler-generated MoveNext() method. + + + + + If this function is a local function, this field stores the reduced version of the function. + + + + + Returns the IL offset of the constructor call, -1 if this is not a constructor or no chained constructor call was found. + + + + + If this is an expression tree or delegate, returns the expression tree type Expression{T} or T. + T is the delegate type that matches the signature of this method. + Otherwise this must be null. + + + + + Gets which kind of function this is. + + + + + Return type of this function. + + + + + List of parameters of this function. + + + + + List of candidate locations for sequence points. Includes any offset + where the stack is empty, nop instructions, and the instruction following + a call instruction + + + + + Constructs a new ILFunction from the given metadata and with the given ILAst body. + + + Use to create ILAst. + + + + + This constructor is only to be used by the TransformExpressionTrees step. + + + + + Apply a list of transforms to this function. + + + + + Recombine split variables by replacing all occurrences of variable2 with variable1. + + + + A container of IL blocks. + + A container of IL blocks. + Each block is an extended basic block (branches may only jump to the beginning of blocks, not into the middle), + and only branches within this container may reference the blocks in this container. + That means that viewed from the outside, the block container has a single entry point (but possibly multiple exit points), + and the same holds for every block within the container. + + All blocks in the container must perform unconditional control flow (falling through to the block end is not allowed). + To exit the block container, use the 'leave' instruction. + + + + + Gets the number of 'leave' instructions that target this BlockContainer. + + + + + Gets the container's entry point. This is the first block in the Blocks collection. + + + + + Topologically sort the blocks. + The new order is returned without modifying the BlockContainer. + + If true, unreachable blocks are not included in the new order. + + + + Topologically sort the blocks. + + If true, delete unreachable blocks. + + + + If the container consists of a single block with a single instruction, + returns that instruction. + Otherwise returns the block, or the container itself if it has multiple blocks. + + + + A block of IL instructions. + + A block consists of a list of IL instructions. + + + Note: if execution reaches the end of the instruction list, + the FinalInstruction (which is not part of the list) will be executed. + The block returns returns the result value of the FinalInstruction. + For blocks returning void, the FinalInstruction will usually be 'nop'. + + + There are three different uses for blocks: + 1) Blocks in block containers. Used as targets for Branch instructions. + 2) Blocks to group a bunch of statements, e.g. the TrueInst of an IfInstruction. + 3) Inline blocks that evaluate to a value, e.g. for array initializers. + + + + + For blocks in a block container, this field holds + the number of incoming control flow edges to this block. + + + This variable is automatically updated when adding/removing branch instructions from the ILAst, + or when adding the block as an entry point to a BlockContainer. + + + + + A 'final instruction' that gets executed after the Instructions collection. + Provides the return value for the block. + + + Blocks in containers must have 'Nop' as a final instruction. + + Note that the FinalInstruction is included in Block.Children, + but not in Block.Instructions! + + + + + Gets the name of this block. + + + + + Deletes this block from its parent container. + This may cause the indices of other blocks in that container to change. + + It is an error to call this method on blocks that are not directly within a container. + It is also an error to call this method on the entry-point block. + + + + + Apply a list of transforms to this function. + + + + + Gets the predecessor of the given instruction. + Returns null if inst.Parent is not a block. + + + + + If inst is a block consisting of a single instruction, returns that instruction. + Otherwise, returns the input instruction. + + + + + Gets the closest parent Block. + Returns null, if the instruction is not a descendant of a Block. + + + + + Gets the closest ancestor that is child of a control-flow (top-level) Block. + Returns null, if the instruction is not a descendant of a Block. + + + + A region where a pinned variable is used (initial representation of future fixed statement). + + + Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr. + + + + Gets whether the instruction checks for overflow. + + + + + For integer operations that depend on the sign, specifies whether the operation + is signed or unsigned. + For instructions that produce the same result for either sign, returns Sign.None. + + + + + The operator used by this binary operator instruction. + + + + + Gets whether this is a lifted nullable operation. + + + A lifted binary operation allows its arguments to be a value of type Nullable{T}, where + T.GetStackType() == [Left|Right]InputType. + If both input values are non-null: + * they are sign/zero-extended to the corresponding InputType (based on T's sign) + * the underlying numeric operator is applied + * the result is wrapped in a Nullable{UnderlyingResultType}. + If either input is null, the instruction evaluates to default(UnderlyingResultType?). + (this result type is underspecified, since there may be multiple C# types for the stack type) + + + + Common instruction for numeric compound assignments. + + + Returns the type operand. + + + + Gets whether the instruction checks for overflow. + + + + + For integer operations that depend on the sign, specifies whether the operation + is signed or unsigned. + For instructions that produce the same result for either sign, returns Sign.None. + + + + + The operator used by this assignment operator instruction. + + + + + Gets whether the specific binary instruction is compatible with a compound operation on the specified type. + + + + Common instruction for user-defined compound assignments. + + + Common instruction for dynamic compound assignments. + + + Bitwise NOT + + + Retrieves the RuntimeArgumentHandle. + + + Unconditional branch. goto target; + + Unconditional branch. goto target; + + + When jumping to the entrypoint of the current block container, the branch represents a continue statement. + + + + + Gets the BlockContainer that contains the target block. + + + + + Gets whether this branch executes at least one finally block before jumping to the target block. + + + + Unconditional branch to end of block container. Return is represented using IsLeavingFunction and an (optional) return value. The block container evaluates to the value produced by the argument of the leave instruction. + + Unconditional branch. goto target; + + + When jumping to the entrypoint of the current block container, the branch represents a continue statement. + + Phase-1 execution of a branch is a no-op. + Phase-2 execution removes PopCount elements from the evaluation stack + and jumps to the target block. + + + + + Gets whether the leave instruction is directly leaving the whole ILFunction. + (TargetContainer == main container of the function). + + This is only valid for functions returning void (representing value-less "return;"), + and for iterators (representing "yield break;"). + + Note: returns false for leave instructions that indirectly leave the function + (e.g. leaving a try block, and the try-finally construct is immediately followed + by another leave instruction) + + + + + Gets whether this branch executes at least one finally block before jumping to the end of the target block container. + + + + If statement / conditional expression. if (condition) trueExpr else falseExpr + If statement / conditional expression. if (condition) trueExpr else falseExpr + + The condition must return StackType.I4, use comparison instructions like Ceq to check if other types are non-zero. + + If the condition evaluates to non-zero, the TrueInst is executed. + If the condition evaluates to zero, the FalseInst is executed. + The return value of the IfInstruction is the return value of the TrueInst or FalseInst. + + IfInstruction is also used to represent logical operators: + "a || b" ==> if (a) (ldc.i4 1) else (b) + "a && b" ==> if (a) (b) else (ldc.i4 0) + "a ? b : c" ==> if (a) (b) else (c) + + + + + Gets whether the input instruction occurs in a context where it is being compared with 0. + + + + Switch statement + + Generalization of IL switch-case: like a VB switch over integers, this instruction + supports integer value ranges as labels. + + The section labels are using 'long' as integer type. + If the Value instruction produces StackType.I4 or I, the value is implicitly sign-extended to I8. + + + + + If the switch instruction is lifted, the value instruction produces a value of type Nullable{T} for some + integral type T. The section with SwitchSection.HasNullLabel is called if the value is null. + + + + + Additional type information used to interpret the value instruction. + Set by ILInlining to preserve stack information that would otherwise be lost. + + + + Switch section within a switch statement + + + + If true, serves as 'case null' in a lifted switch. + + + + + The set of labels that cause execution to jump to this switch section. + + + + Try-catch statement. + + Try-catch statement. + + + The return value of the try or catch blocks is ignored, the TryCatch always returns void. + + + + Catch handler within a try-catch statement. + + Catch handler within a try-catch statement. + + When an exception occurs in the try block of the parent try.catch statement, the runtime searches + the nearest enclosing TryCatchHandler with a matching variable type and + assigns the exception object to the , and executes the . + If the filter evaluates to 0, the exception is not caught and the runtime looks for the next catch handler. + If the filter evaluates to 1, the stack is unwound, the exception caught and assigned to the , + and the is executed. + + + + + Gets the ILRange of the instructions at the start of the catch-block, + that take the exception object and store it in the exception variable slot. + Note: This range is empty, if Filter is not empty, i.e., ldloc 1. + + + + Try-finally statement + + + Try-fault statement + + + Breakpoint instruction + + + Comparison. The inputs must be both integers; or both floats; or both object references. Object references can only be compared for equality or inequality. Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which evaluates to 1 (true). + + + + Gets the stack type of the comparison inputs. + For lifted comparisons, this is the underlying input type. + + + + + If this is an integer comparison, specifies the sign used to interpret the integers. + + + + Non-virtual method call. + + + + Calls can only be lifted when calling a lifted operator. + Note that the semantics of such a lifted call depend on the type of operator: + we follow C# semantics here. + + + + Virtual method call. + + + Checks that the input float is not NaN or infinite. + + + Numeric cast. + + + + Gets the conversion kind. + + + + + Gets whether the conversion performs overflow-checking. + + + + + Gets whether this conversion is a lifted nullable conversion. + + + A lifted conversion expects its argument to be a value of type Nullable{T}, where + T.GetStackType() == conv.InputType. + If the value is non-null: + * it is sign/zero-extended to InputType (based on T's sign) + * the underlying conversion is performed + * the result is wrapped in a Nullable{TargetType}. + If the value is null, the conversion evaluates to default(TargetType?). + (this result type is underspecified, since there may be multiple C# types for the TargetType) + + + + + Gets the stack type of the input type. + + + For non-lifted conversions, this is equal to Argument.ResultType. + For lifted conversions, corresponds to the underlying type of the argument. + + + + + Gets the sign of the input type. + + For conversions to integer types, the input Sign is set iff overflow-checking is enabled. + For conversions to floating-point types, the input sign is always set. + + + The input sign does not have any effect on whether the conversion zero-extends or sign-extends; + that is purely determined by the TargetType. + + + + + The target type of the conversion. + + + For lifted conversions, corresponds to the underlying target type. + + Target type == PrimitiveType.None can happen for implicit conversions to O in invalid IL. + + + + + Implements Ecma-335 Table 8: Conversion Operators. + + + + Loads the value of a local variable. (ldarg/ldloc) + + + Loads the address of a local variable. (ldarga/ldloca) + + + Stores the value into an anonymous temporary variable, and returns the address of that variable. + + + Returns the type operand. + + + Loads a constant string. + + + Loads a constant byte string (as ReadOnlySpan<byte>). + + + Loads a constant 32-bit integer. + + + Loads a constant 64-bit integer. + + + Loads a constant 32-bit floating-point number. + + + Loads a constant 64-bit floating-point number. + + + Loads a constant decimal. + + + Loads the null reference. + + + Load method pointer + + + Returns the method operand. + + + Load method pointer + + + Returns the method operand. + + + Virtual delegate construction + + + Returns the type operand. + + + Returns the method operand. + + + Loads runtime representation of metadata token + + + Returns the type operand. + + + Loads runtime representation of metadata token + + + Returns the token operand. + + + Allocates space in the stack frame + + + Allocates space in the stack frame and wraps it in a Span + + + Returns the type operand. + + + memcpy(destAddress, sourceAddress, size); + + + Gets/Sets whether the memory access is volatile. + + + Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix. + + + memset(address, value, size) + + + Gets/Sets whether the memory access is volatile. + + + Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix. + + + Load static field address + + + Returns the field operand. + + + Casts an object to a class. + + + Returns the type operand. + + + Indirect load (ref/pointer dereference). + + + Returns the type operand. + + + Gets/Sets whether the memory access is volatile. + + + Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix. + + + If argument is a ref to a reference type, loads the object reference, stores it in a temporary, and evaluates to the address of that temporary (address.of(ldobj(arg))). Otherwise, returns the argument ref as-is.This instruction represents the memory-load semantics of callvirt with a generic type as receiver (where the IL always takes a ref, but only methods on value types expect one, for method on reference types there's an implicit ldobj, which this instruction makes explicit in order to preserve the order-of-evaluation). + + + Returns the type operand. + + + Boxes a value. + + + Returns the type operand. + + + Compute address inside box. + + + Returns the type operand. + + + Unbox a value. + + + Returns the type operand. + + + Creates an object instance and calls the constructor. + + + Creates an array instance. + + + Returns the type operand. + + + Throws an exception. + + + Rethrows the current exception. + + + Gets the size of a type in bytes. + + + Returns the type operand. + + + Returns the length of an array as 'native unsigned int'. + + Description of LdLen. + + + + Load address of array element. + + + Returns the type operand. + + + Gets whether the 'readonly' prefix was applied to this instruction. + + + Load address of inline array element. + + + Returns the type operand. + + + Gets whether the 'readonly' prefix was applied to this instruction. + + + Retrieves a pinnable reference for the input object. + The input must be an object reference (O). + If the input is an array/string, evaluates to a reference to the first element/character, or to a null reference if the array is null or empty. + Otherwise, uses the GetPinnableReference method to get the reference, or evaluates to a null reference if the input is null. + + + + Returns the method operand. + + + Push a typed reference of type class onto the stack. + + + Returns the type operand. + + + Push the type token stored in a typed reference. + + + Push the address stored in a typed reference. + + + Returns the type operand. + + + Yield an element from an iterator. + + + + Base class for visitor pattern. + + + + Called by Visit*() methods that were not overridden + + + + Base class for visitor pattern. + + + + Called by Visit*() methods that were not overridden + + + + Base class for visitor pattern. + + + + Called by Visit*() methods that were not overridden + + + + Represents a decoded IL instruction + + + + + Gets whether this node is a descendant of . + Also returns true if this==. + + + This method uses the Parent property, so it may produce surprising results + when called on orphaned nodes or with a possibleAncestor that contains stale positions + (see remarks on Parent property). + + + + + Returns whether this appears before other in a post-order walk of the whole tree. + + + + + Gets the stack type of the value produced by this instruction. + + + + + Gets the flags describing the behavior of this instruction. + This property computes the flags on-demand and caches them + until some change to the ILAst invalidates the cache. + + + Flag cache invalidation makes use of the Parent property, + so it is possible for this property to return a stale value + if the instruction contains "stale positions" (see remarks on Parent property). + + + + + Returns whether the instruction (or one of its child instructions) has at least one of the specified flags. + + + + + Returns whether the instruction (without considering child instructions) has at least one of the specified flags. + + + + + Gets the flags for this instruction only, without considering the child instructions. + + + + + Gets the ILRange for this instruction alone, ignoring the operands. + + + + + Writes the ILAst to the text output. + + + + + Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction. + + + + + Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction. + + + + + Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction. + + + + + Gets the child nodes of this instruction. + + + The ChildrenCollection does not actually store the list of children, + it merely allows accessing the children stored in the various slots. + + + + + Enumerator over the children of an ILInstruction. + Warning: even though this is a struct, it is invalid to copy: + the number of constructor calls must match the number of dispose calls. + + + + + Replaces this ILInstruction with the given replacement instruction. + + + It is temporarily possible for a node to be used in multiple places in the ILAst, + this method only replaces this node at its primary position (see remarks on ). + + This means you cannot use ReplaceWith() to wrap an instruction in another node. + For example, node.ReplaceWith(new BitNot(node)) will first call the BitNot constructor, + which sets node.Parent to the BitNot instance. + The ReplaceWith() call then attempts to set BitNot.Argument to the BitNot instance, + which creates a cyclic ILAst. Meanwhile, node's original parent remains unmodified. + + The solution in this case is to avoid using ReplaceWith. + If the parent node is unknown, the following trick can be used: + + node.Parent.Children[node.ChildIndex] = new BitNot(node); + + Unlike the ReplaceWith() call, this will evaluate node.Parent and node.ChildIndex + before the BitNot constructor is called, thus modifying the expected position in the ILAst. + + + + + Returns all descendants of the ILInstruction in post-order. + (including the ILInstruction itself) + + + Within a loop 'foreach (var node in inst.Descendants)', it is illegal to + add or remove from the child collections of node's ancestors, as those are + currently being enumerated. + Note that it is valid to modify node's children as those were already previously visited. + As a special case, it is also allowed to replace node itself with another node. + + + + + Gets the ancestors of this node (including the node itself as first element). + + + + + Number of parents that refer to this instruction and are connected to the root. + Usually is 0 for unconnected nodes and 1 for connected nodes, but may temporarily increase to 2 + when the ILAst is re-arranged (e.g. within SetChildInstruction), + or possibly even more (re-arrangement with stale positions). + + + + + Gets whether this ILInstruction is connected to the root node of the ILAst. + + + This property returns true if the ILInstruction is reachable from the root node + of the ILAst; it does not make use of the Parent field so the considerations + about orphaned nodes and stale positions don't apply. + + + + + Called after the ILInstruction was connected to the root node of the ILAst. + + + + + Called after the ILInstruction was disconnected from the root node of the ILAst. + + + + + Gets the parent of this ILInstruction. + + + It is temporarily possible for a node to be used in multiple places in the ILAst + (making the ILAst a DAG instead of a tree). + The Parent and ChildIndex properties are written whenever + a node is stored in a slot. + The node's occurrence in that slot is termed the "primary position" of the node, + and all other (older) uses of the nodes are termed "stale positions". + + A consistent ILAst must not contain any stale positions. + Debug builds of ILSpy check the ILAst for consistency after every IL transform. + + If a slot containing a node is overwritten with another node, the Parent + and ChildIndex of the old node are not modified. + This allows overwriting stale positions to restore consistency of the ILAst. + + If a "primary position" is overwritten, the Parent of the old node also remains unmodified. + This makes the old node an "orphaned node". + Orphaned nodes may later be added back to the ILAst (or can just be garbage-collected). + + Note that is it is possible (though unusual) for a stale position to reference an orphaned node. + + + + + Gets the index of this node in the Parent.Children collection. + + + It is temporarily possible for a node to be used in multiple places in the ILAst, + this property returns the index of the primary position of this node (see remarks on ). + + + + + Gets information about the slot in which this instruction is stored. + (i.e., the relation of this instruction to its parent instruction) + + + It is temporarily possible for a node to be used in multiple places in the ILAst, + this property returns the slot of the primary position of this node (see remarks on ). + + Precondition: this node must not be orphaned. + + + + + Replaces a child of this ILInstruction. + + Reference to the field holding the child + New child + Index of the field in the Children collection + + + + Called when a new child is added to a InstructionCollection. + + + + + Called when a child is removed from a InstructionCollection. + + + + + Called when a series of add/remove operations on the InstructionCollection is complete. + + + + + Creates a deep clone of the ILInstruction. + + + It is valid to clone nodes with stale positions (see remarks on Parent); + the result of such a clone will not contain any stale positions (nodes at + multiple positions will be cloned once per position). + + + + + Creates a shallow clone of the ILInstruction. + + + Like MemberwiseClone(), except that the new instruction starts as disconnected. + + + + + Attempts to match the specified node against the pattern. + + this: The syntactic pattern. + The syntax node to test against the pattern. + + Returns a match object describing the result of the matching operation. + Check the property to see whether the match was successful. + For successful matches, the match object allows retrieving the nodes that were matched with the captured groups. + + + + + Attempts matching this instruction against the other instruction. + + The instruction to compare with. + The match object, used to store global state during the match (such as the results of capture groups). + Returns whether the (partial) match was successful. + If the method returns true, it adds the capture groups (if any) to the match. + If the method returns false, the match object may remain in a partially-updated state and + needs to be restored before it can be reused. + + + + Attempts matching this instruction against a list of other instructions (or a part of said list). + + Stores state about the current list match. + The match object, used to store global state during the match (such as the results of capture groups). + Returns whether the (partial) match was successful. + If the method returns true, it updates listMatch.SyntaxIndex to point to the next node that was not part of the match, + and adds the capture groups (if any) to the match. + If the method returns false, the listMatch and match objects remain in a partially-updated state and need to be restored + before they can be reused. + + + + Extracts the this instruction. + The instruction is replaced with a load of a new temporary variable; + and the instruction is moved to a store to said variable at block-level. + Returns the new variable. + + If extraction is not possible, the ILAst is left unmodified and the function returns null. + May return null if extraction is not possible. + + + + + Prepares "extracting" a descendant instruction out of this instruction. + This is the opposite of ILInlining. It may involve re-compiling high-level constructs into lower-level constructs. + + True if extraction is possible; false otherwise. + + + + Gets whether the expressionBeingMoved, which previously executes prior to `this`, + may be moved into a descendant of the specified slot. + (i.e. this controls whether FindLoadInNext may descent into the specified slot) + + Note: this does not check whether reordering with the previous slots is valid; only whether the target slot supports inlining at all! + + + + + Some slots in the ILAst have restrictions on which instructions can appear in them. + Used to suppress inlining if the new child does not satisfy the restrictions. + Unlike `CanInlineIntoSlot`, this is not about descendants of the slot, only about + whether SetChild(childIndex, newChild) is valid. + (i.e. this controls whether FindLoadInNext may return the specified slot as a final result) + + Warning: after newChild is inlined, other nodes may be inlined into newChild's sub-instructions + without asking this function again. This means this function is not suitable for protecting + a slot from having side effects, use `CanInlineIntoSlot` for that. + + + + + Matches ldc.i4, ldc.i8, and extending conversions. + + + + + Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). + + + + + Matches either ldloc (if the variable is a reference type), or ldloca (otherwise). + + + + + Matches an if instruction where the false instruction is a nop. + + + + + Matches a 'logic and' instruction ("if (a) b else ldc.i4 0"). + Note: unlike C# '&&', this instruction is not limited to booleans, + but allows passing through arbitrary I4 values on the rhs (but not on the lhs). + + + + + Matches a 'logic or' instruction ("if (a) ldc.i4 1 else b"). + Note: unlike C# '||', this instruction is not limited to booleans, + but allows passing through arbitrary I4 values on the rhs (but not on the lhs). + + + + + Matches an logical negation. + + + + + Matches comp(left == right) or logic.not(comp(left != right)). + + + + + Matches 'comp(arg == ldnull)' + + + + + Matches 'comp(arg != ldnull)' + + + + + Matches comp(left != right) or logic.not(comp(left == right)). + + + + + If this instruction is a conversion of the specified kind, return its argument. + Otherwise, return the instruction itself. + + + Does not unwrap lifted conversions. + + + + + Not a lifted comparison. + + + + + C#-style lifted comparison: + * operands that have a ResultType != this.InputType are expected to return a value of + type Nullable{T}, where T.GetStackType() == this.InputType. + * if both operands are null, equality comparisons evaluate to 1, all other comparisons to 0. + * if one operand is null, inequality comparisons evaluate to 1, all other comparisons to 0. + * if neither operand is null, the underlying comparison is performed. + + Note that even though C#-style lifted comparisons set IsLifted=true, + the ResultType remains I4 as with normal comparisons. + + + + + SQL-style lifted comparison: works like a lifted binary numeric instruction, + that is, if any input operand is null, the comparison evaluates to null. + + + This lifting kind is currently only used for operator! on bool?. + + + + + Block is used for control flow. + All blocks in block containers must have this type. + Control flow blocks cannot evaluate to a value (FinalInstruction must be Nop). + + + + + Block is used for array initializers, e.g. `new int[] { expr1, expr2 }`. + + + + + Block is used for using the result of a property setter inline. + Example: Use(this.Property = value); + This is only for inline assignments to property or indexers; other inline assignments work + by using the result value of the stloc/stobj instructions. + + Constructed by TransformAssignment. + Can be deconstructed using Block.MatchInlineAssignBlock(). + + + Block { + call setter(..., stloc s(...)) + final: ldloc s + } + + + + + Call using named arguments. + + + Each instruction is assigning to a new local. + The final instruction is a call. + The locals for this block have exactly one store and + exactly one load, which must be an immediate argument to the call. + + + Block { + stloc arg0 = ... + stloc arg1 = ... + final: call M(..., arg1, arg0, ...) + } + + + + + + + + + + + + + + + String interpolation using DefaultInterpolatedStringHandler. + + + Block { + stloc I_0 = newobj DefaultInterpolatedStringHandler(...) + call AppendXXX(I_0, ...) + ... + final: call ToStringAndClear(ldloc I_0) + } + + + + + Normal container that contains control-flow blocks. + + + + + A while-true loop. + Continue is represented as branch to entry-point. + Return/break is represented as leave. + + + + + Container that has a switch instruction as entry-point. + Goto case is represented as branch. + Break is represented as leave. + + + + + while-loop. + The entry-point is a block consisting of a single if instruction + that if true: jumps to the head of the loop body, + if false: leaves the block. + Continue is a branch to the entry-point. + Break is a leave. + + + + + do-while-loop. + The entry-point is a block that is the head of the loop body. + The last block consists of a single if instruction + that if true: jumps to the head of the loop body, + if false: leaves the block. + Only the last block is allowed to jump to the entry-point. + Continue is a branch to the last block. + Break is a leave. + + + + + for-loop. + The entry-point is a block consisting of a single if instruction + that if true: jumps to the head of the loop body, + if false: leaves the block. + The last block is the increment block. + Only the last block is allowed to jump to the entry-point. + Continue is a branch to the last block. + Break is a leave. + + + + + The compound.assign instruction will evaluate to the old value. + This mode is used only for post-increment/decrement. + + + + + The compound.assign instruction will evaluate to the new value. + This mode is used for compound assignments and pre-increment/decrement. + + + + + The target is an instruction computing an address, + and the compound.assign will implicitly load/store from/to that address. + + + + + The Target must be a call to a property getter, + and the compound.assign will implicitly call the corresponding property setter. + + + + + The target is a dynamic call. + + + + + Semantic meaning of a Conv instruction. + + + + + Invalid conversion. + + + + + Conversion between two types of same size. + Can be used to change the sign of integer types, which may involve overflow-checking. + + + + + Integer-to-float conversion. + Uses InputSign to decide whether the integer should be treated as signed or unsigned. + + + + + Float-to-integer conversion. + Truncates toward zero; may perform overflow-checking. + + + + + Converts from the current precision available on the evaluation stack to the precision specified by + the TargetType. + Uses "round-to-nearest" mode if the precision is reduced. + + + + + Conversion of integer type to larger signed integer type. + May involve overflow checking (when converting from U4 to I on 32-bit). + + + + + Conversion of integer type to larger unsigned integer type. + May involve overflow checking (when converting from a signed type). + + + + + Conversion to smaller integer type. + + May involve overflow checking. + + + If the target type is smaller than the minimum stack width of 4 bytes, + then the result of the conversion is zero extended (if the target type is unsigned) + or sign-extended (if the target type is signed). + + + + + Used to convert managed references/objects to unmanaged pointers. + + + + + Used to convert unmanaged pointers to managed references. + + + + + Converts from an object reference (O) to an interior pointer (Ref) pointing to the start of the object. + + + C++/CLI emits "ldarg.1; stloc.0" where arg1 is a string and loc0 is "ref byte" (e.g. as part of the PtrToStringChars codegen); + we represent this type conversion explicitly in the ILAst. + + + + + ILFunction is a "top-level" function, i.e., method, accessor, constructor, destructor or operator. + + + + + ILFunction is a delegate or lambda expression. + + + This kind is introduced by the DelegateConstruction and TransformExpressionTrees steps in the decompiler pipeline. + + + + + ILFunction is an expression tree lambda. + + + This kind is introduced by the TransformExpressionTrees step in the decompiler pipeline. + + + + + ILFunction is a C# 7.0 local function. + + + This kind is introduced by the LocalFunctionDecompiler step in the decompiler pipeline. + + + + + Reading the individual instructions. + * Variables don't have scopes yet as the ILFunction is not created yet. + * Branches point to IL offsets, not blocks. + + + + + The usual invariants are established. + + + + + Special phase within the async-await decompiler, where a few selected invariants + are temporarily suspended. (see Leave.CheckInvariant) + + + + + Gets whether the instruction was lifted; that is, whether is accepts + potentially nullable arguments. + + + + + If the instruction is lifted and returns a nullable result, + gets the underlying result type. + + Note that not all lifted instructions return a nullable result: + C# comparisons always return a bool! + + + + + Custom enumerator for InstructionCollection. + Unlike List{T}.Enumerator, this enumerator allows replacing an item during the enumeration. + Adding/removing items from the collection still is invalid (however, such + invalid actions are only detected in debug builds). + + Warning: even though this is a struct, it is invalid to copy: + the number of constructor calls must match the number of dispose calls. + + + + + Gets the index of the instruction in this collection. + Returns -1 if the instruction does not exist in the collection. + + + Runs in O(1) if the item can be found using the Parent/ChildIndex properties. + Otherwise, runs in O(N). + + + + + Gets whether the item is in this collection. + + + This method searches the list. + Usually it's more efficient to test item.Parent instead! + + + + + Replaces all entries in the InstructionCollection with the newList. + + + Equivalent to Clear() followed by AddRange(newList), but slightly more efficient. + + + + + Remove item at index index in O(1) by swapping it with the last element in the collection. + + + + + Removes all elements for which the predicate returns true. + + + This method runs in O(N), which is more efficient than calling RemoveAt() in a loop. + The collection may be in an invalid state during the invocation of the predicate. + + + + + Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix. + + + + + Gets/Sets whether the memory access is volatile. + + + + + Holds information about the role of an instruction within its parent instruction. + + + + + Gets the name of the slot. + + + + + Gets whether it is possible to inline into this slot. + + + + + Gets whether this slot belongs to a collection. + + + + + Gets whether instruction is pure: + * must not have side effects + * must not throw exceptions + * must not branch + + + + + Gets whether the instruction sequence 'inst1; inst2;' may be ordered to 'inst2; inst1;' + + + + + Converts the list of basic blocks from ILReader into a BlockContainer structure. + This involves creating nested block containers for exception handlers, and creating + branches between the blocks. + + + + + Gets/Sets whether to create extended basic blocks instead of basic blocks. + The default is false. + + + + Create a new block that sets a helper variable and then branches to the start of the try-catch + + + New variables introduced for the "on error" dispatchers + + + + Reads IL bytecodes and converts them into ILAst instructions. + + + Instances of this class are not thread-safe. Use separate instances to decompile multiple members in parallel. + + + + + Represents a block of IL instructions. + + + + True if the import is in progress or completed. + + + + Compares stack types and update InputStack if necessary. + Returns true if InputStack was updated, making a reimport necessary. + + + + + Creates a new ILReader instance. + + + The module used to resolve metadata tokens in the type system. + + + + + Warn when invalid IL is detected. + ILSpy should be able to handle invalid IL; but this method can be helpful for debugging the ILReader, + as this method should not get called when processing valid IL. + + + + + Check control flow edges for compatible stacks. + Returns union find data structure for unifying the different variables for the same stack slot. + Also inserts stack adjustments where necessary. + + + + + Inserts a copy from varA to varB (with conversion) at the end of . + If the block ends with a branching instruction, the copy is inserted before the branching instruction. + + + + + Stores the given stack for a branch to `offset`. + + + + + Debugging helper: writes the decoded instruction stream interleaved with the inferred evaluation stack layout. + + + + + Decodes the specified method body and returns an ILFunction. + + + + + Pops a value/instruction from the evaluation stack. + Note that instructions popped from the stack must be evaluated in the order they + were pushed (so in reverse order of the pop calls!). + + For instructions like 'conv' that pop a single element and then push their result, + it's fine to pop just one element as the instruction itself will end up on the stack, + thus maintaining the evaluation order. + For instructions like 'call' that pop multiple arguments, it's critical that + the evaluation order of the resulting ILAst will be reverse from the order of the push + calls. + For instructions like 'brtrue', it's fine to pop only a part of the stack because + ReadInstructions() will flush the evaluation stack before outputting the brtrue instruction. + + Use FlushExpressionStack() to ensure that following Pop() calls do not return + instructions that involve side-effects. This way evaluation order is preserved + no matter which order the ILAst will execute the popped instructions in. + + + + + Like PopFieldTarget, but supports ldfld's special behavior for fields of temporary value types. + + + + + The expression stack holds ILInstructions that might have side-effects + that should have already happened (in the order of the pushes). + This method forces these instructions to be added to the instructionBuilder. + This is used e.g. to avoid moving side-effects past branches. + + + + + Gets the size in bytes of the primitive type. + + Returns 0 for non-primitive types. + Returns NativeIntSize for native int/references. + + + + + Gets whether the type is a small integer type. + Small integer types are: + * bool, sbyte, byte, char, short, ushort + * any enums that have a small integer type as underlying type + + + + + Infers the C# type for an IL instruction. + + Returns SpecialType.UnknownType for unsupported instructions. + + + + + A local variable. + + + + + A pinned local variable (not associated with a pinned region) + + + + + A pinned local variable (associated with a pinned region) + + + + + A local variable used as using-resource variable. + + + + + A local variable used as foreach variable. + + + + + A local variable used inside an array, collection or + object initializer block to denote the object being initialized. + + + + + A parameter. + + + + + Variable created for exception handler. + + + + + Local variable used in a catch block. + + + + + Variable created from stack slot. + + + + + Variable in BlockKind.CallWithNamedArgs + + + + + Local variable that holds the display class used for lambdas within this function. + + + + + Local variable declared within a pattern match. + + + + + Temporary variable declared in a deconstruction init section. + + + + + This variable is either a C# 7 'in' parameter or must be declared as 'ref readonly'. + + + + + The index of the local variable or parameter (depending on Kind) + + For VariableKinds with "Local" in the name: + * if non-null, the Index refers to the LocalVariableSignature. + * index may be null for variables that used to be fields (captured by lambda/async) + For Parameters, the Index refers to the method's list of parameters. + The special "this" parameter has index -1. + For ExceptionStackSlot, the index is the IL offset of the exception handler. + For other kinds, the index has no meaning, and is usually null. + + + + + Gets the function in which this variable is declared. + + + This property is set automatically when the variable is added to the ILFunction.Variables collection. + + + + + Gets the block container in which this variable is captured. + For captured variables declared inside the loop, the capture scope is the BlockContainer of the loop. + For captured variables declared outside of the loop, the capture scope is the BlockContainer of the parent function. + + + This property returns null for variables that are not captured. + + + + + Gets the index of this variable within the Function.Variables collection. + + + This property is set automatically when the variable is added to the VariableScope.Variables collection. + It may change if an item with a lower index is removed from the collection. + + + + + Number of ldloc instructions referencing this variable. + + + This variable is automatically updated when adding/removing ldloc instructions from the ILAst. + + + + + List of ldloc instructions referencing this variable. + + + This list is automatically updated when adding/removing ldloc instructions from the ILAst. + + + + + Number of store instructions referencing this variable, + plus 1 if HasInitialValue. + + Stores are: + + stloc + TryCatchHandler (assigning the exception variable) + PinnedRegion (assigning the pointer variable) + initial values () + + + + This variable is automatically updated when adding/removing stores instructions from the ILAst. + + + + + List of store instructions referencing this variable. + + Stores are: + + stloc + TryCatchHandler (assigning the exception variable) + PinnedRegion (assigning the pointer variable) + initial values () -- however, there is no instruction for + the initial value, so it is not contained in the store list. + + + + This list is automatically updated when adding/removing stores instructions from the ILAst. + + + + + Number of ldloca instructions referencing this variable. + + + This variable is automatically updated when adding/removing ldloca instructions from the ILAst. + + + + + List of ldloca instructions referencing this variable. + + + This list is automatically updated when adding/removing ldloca instructions from the ILAst. + + + + + Gets/Sets whether the variable's initial value is initialized. + This is always true for parameters (incl. this). + + Normal variables have an initial value if the function uses ".locals init". + + + + + Gets/Sets whether the initial value of the variable is used. + This is always true for parameters (incl. this). + + Normal variables use the initial value, if no explicit initialization is done. + + + The following table shows the relationship between + and . + + + + + Meaning + + + + + This variable's initial value is zero-initialized (.locals init) and the initial value is used. + From C#'s point of view a the value default(T) is assigned at the site of declaration. + + + + + This variable's initial value is zero-initialized (.locals init) and the initial value is not used. + From C#'s point of view no implicit initialization occurs, because the code assigns a value + explicitly, before the variable is first read. + + + + + This variable's initial value is uninitialized (.locals without init) and the + initial value is used. + From C#'s point of view a call to System.Runtime.CompilerServices.Unsafe.SkipInit(out T) + is generated after the declaration. + + + + + This variable's initial value is uninitialized (.locals without init) and the + initial value is not used. + From C#'s point of view no implicit initialization occurs, because the code assigns a value + explicitly, before the variable is first read. + + + + + + + Gets whether the variable is in SSA form: + There is exactly 1 store, and every load sees the value from that store. + + + Note: the single store is not necessary a store instruction, it might also + be the use of the implicit initial value. + For example: for parameters, IsSingleDefinition will only return true if + the parameter is never assigned to within the function. + + + + + Gets whether the variable is dead - unused. + + + + + The field which was converted to a local variable. + Set when the variable is from a 'yield return' or 'async' state machine. + + + + + If enabled, remove dead stores to this variable as if the "Remove dead code" option is enabled. + + + + + Gets whether this variable occurs within the specified instruction. + + + + + The instruction may read from local variables. + + + + + The instruction may write to local variables. + + + This flag is not set for indirect writes to local variables through pointers. + Ensure you also check the SideEffect flag when checking for instructions that might write to locals. + + + + + The instruction may have side effects, such as accessing heap memory, + performing system calls, writing to local variables through pointers, etc. + + + Throwing an exception or directly writing to local variables + is not considered a side effect, and is modeled by separate flags. + + + + + The instruction may throw an exception. + + + + + The instruction may exit with a branch or leave. + + + + + The instruction may jump to the closest containing nullable.rewrap instruction. + + + + + The instruction performs unconditional control flow, so that its endpoint is unreachable. + + + If EndPointUnreachable is set, either MayThrow or MayBranch should also be set + (unless the instruction represents an infinite loop). + + + + + The instruction contains some kind of internal control flow. + + + If this flag is not set, all descendants of the instruction are fully evaluated (modulo MayThrow/MayBranch/MayUnwrapNull) + in left-to-right pre-order. + + Note that branch instructions don't have this flag set, because their control flow is not internal + (and they don't have any unusual argument evaluation rules). + + + + Managed reference + + + Floating point type of unspecified size: + usually 80 bits on x86 (when the runtime uses x87 instructions); + but only 64-bit on x64. + This only occurs for "conv.r.un" instructions. The C# compiler usually follows those + with a "conv.r4" or "conv.r8" instruction to indicate the desired float type, so + we only use this as conversion target type and don't bother tracking it as its own stack type: + basically everything treats R identical to R8, except for the (conv.r.un + conv.r[48] => conv.r[48].un) + combining logic which should not combine (conv.r.un + conv.r8 + conv.r4) into a single conv.r4.un. + + + + + A type for the purpose of stack analysis. + + + + + The stack type is unknown; for example a call returning an unknown type + because an assembly reference isn't loaded. + Can also occur with invalid IL. + + + + 32-bit integer + + Used for C# int, uint, + C# small integer types byte, sbyte, short, ushort, + bool and char, + and any enums with one of the above as underlying type. + + + + native-size integer, or unmanaged pointer + + Used for C# IntPtr, UIntPtr and any native pointer types (void* etc.) + Also used for IL function pointer types. + + + + 64-bit integer + + Used for C# long, ulong, + and any enums with one of the above as underlying type. + + + + 32-bit floating point number + + Used for C# float. + + + + 64-bit floating point number + + Used for C# double. + + + + Another stack type. Includes objects, value types, ... + + + A managed pointer + + + Represents the lack of a stack slot + + + + MetadataFile is the main class the decompiler uses to represent a metadata assembly/module. + Every file on disk can be loaded into a standalone MetadataFile instance. + + A MetadataFile can be combined with its referenced assemblies/modules to form a type system, + in that case the class is used instead. + + + In addition to wrapping a System.Reflection.Metadata.MetadataReader, this class + contains a few decompiler-specific caches to allow efficiently constructing a type + system from multiple MetadataFiles. This allows the caches to be shared across multiple + decompiled type systems. + + + + + Finds the top-level-type with the specified name. + + + + + Finds the type forwarder with the specified name. + + + + + Gets the CLI header or null if the image does not have one. + + + + + Abstraction over PEMemoryBlock + + + + + Constructs a FindTypeDecoder that finds uses of a specific type-definition handle. + This assumes that the module we are search in is the same as the module containing the type-definiton. + + + + + Constructs a FindTypeDecoder that can be used to find in signatures from . + + + + + For GAC assembly references, the WholeProjectDecompiler will omit the HintPath in the + generated .csproj file. + + + + + For .NET Core framework references, the WholeProjectDecompiler will omit the + assembly reference if the runtimePack is already included as an SDK. + + + + + Convenience wrapper for and . + + + + + Convenience wrapper for and . + + + + + Describes which parts of the (compiler-generated) code belong to which user code. + A part could be: + - the body (method) of a lambda. + - the MoveNext method of async/yield state machines. + + + + + The module containing the code. + + + + + The (parent) TypeDef containing the code. + + + + + Creates a instance using the given and . + + + + + Returns all parts of a method. + A method has at least one part, that is, the method itself. + If no parts are found, only the method itself is returned. + + + + + Returns the parent of a part. + The parent is usually the "calling method" of lambdas, async and yield state machines. + The "calling method" has itself as parent. + If no parent is found, the method itself is returned. + + + + + Adds a bidirectional mapping between and . + + + + + Decodes custom attribute blobs. + + + + + Lookup structure that, for an accessor, can find the associated property/event. + + + + + Used to resolve assemblies referenced by an assembly. + + + + + Creates a new instance of the . + + + The full path to the "main assembly" (i.e., the assembly being decompiled). This is used to + resolve assemblies that are located next the main assembly. If no full path is used, the resolver + falls back to using . + + + If an is thrown, in case the + assembly reference cannot be resolved. + + + The target framework name as used by . + That is, "{framework},Version={version}": currently it supports ".NETCoreApp", ".NETStandard" and + "Silverlight", if the string doesn't match any of these, the resolver falls back to ".NET Framework", + which is "classic" .NET <= 4.8. + + + Identifier of the runtime pack this assembly was compiled for. + If omitted, falling back to "Microsoft.NETCore.App" and this is ignored in case of classic .NET + Options used for the . + Options used for the . + + + + This only works on Windows + + + + + Gets the names of all assemblies in the GAC. + + + + + An attribute type provider that can be used to decode attribute signatures + that only mention built-in types. + + + + + Converts to . + Returns 0 for known types that are not primitive types (such as ). + + + + + Visitor that generates debug information. + + The intended usage is to create a new instance for each source file, + and call syntaxTree.AcceptVisitor(debugInfoGenerator) to fill the internal debug info tables. + This can happen concurrently for multiple source files. + Then the main thread calls Generate() to write out the results into the PDB. + + + + + Gets all functions with bodies that were seen by the visitor so far. + + + + + A sequence point read from a PDB file or produced by the decompiler. + + + + + IL start offset. + + + + + IL end offset. + + + This does not get stored in debug information; + it is used internally to create hidden sequence points + for the IL fragments not covered by any sequence point. + + + + + Represents an element in the XML documentation. + Any occurrences of "<inheritdoc/>" are replaced with the inherited documentation. + + + + + Inheritance level; used to prevent cyclic doc inheritance. + + + + + Creates a new documentation element. + + + + + Creates a new documentation element. + + + + + Gets the entity on which this documentation was originally declared. + May return null. + + + + + Gets the entity referenced by the 'cref' attribute. + May return null. + + + + + Gets the element name. + + + + + Gets the attribute value. + + + + + Gets whether this is a pure text node. + + + + + Gets the text content. + + + + + Gets the child elements. + + + + + + + + A type reference of the form 'Some.Namespace.TopLevelType.NestedType`n'. + We do not know the boundary between namespace name and top level type, so we have to try + all possibilities. + The type parameter count only applies to the innermost type, all outer types must be non-generic. + + + + + Resolves the type reference within the context of the given PE file. + + Either TypeDefinitionHandle, if the type is defined in the module or ExportedTypeHandle, + if the module contains a type forwarder. Returns a nil handle, if the type was not found. + + + + Provides ID strings for entities. (C# 4.0 spec, §A.3.1) + ID strings are used to identify members in XML documentation files. + + + + + Gets the ID string (C# 4.0 spec, §A.3.1) for the specified entity. + + + + + Parse the ID string into a member reference. + + The ID string representing the member (with "M:", "F:", "P:" or "E:" prefix). + A member reference that represents the ID string. + The syntax of the ID string is invalid + + The member reference will look in first, + and if the member is not found there, + it will look in all other assemblies of the compilation. + + + + + Parse the ID string type name into a type reference. + + The ID string representing the type (the "T:" prefix is optional). + A type reference that represents the ID string. + The syntax of the ID string is invalid + + + The type reference will look in first, + and if the type is not found there, + it will look in all other assemblies of the compilation. + + + If the type is open (contains type parameters '`0' or '``0'), + an with the appropriate CurrentTypeDefinition/CurrentMember is required + to resolve the reference to the ITypeParameter. + + + + + + Finds the entity in the given type resolve context. + + ID string of the entity. + Type resolve context + Returns the entity, or null if it is not found. + The syntax of the ID string is invalid + + + + Helps finding and loading .xml documentation. + + + + + Given the assembly file name, looks up the XML documentation file name. + Returns null if no XML documentation file is found. + + + + + Provides XML documentation for type and member definitions in source code. + + + + + Returns the XML documentation for the given . + May return null, if no documentation is present for the entity. + + is null. + + + + Provides documentation from an .xml file (as generated by the Microsoft C# compiler). + + + This class first creates an in-memory index of the .xml file, and then uses that to read only the requested members. + This way, we avoid keeping all the documentation in memory. + The .xml file is only opened when necessary, the file handle is not kept open all the time. + If the .xml file is changed, the index will automatically be recreated. + + + + + Hash code of the documentation tag + + + + + Position in the .xml file where the documentation starts + + + + + Creates a new XmlDocumentationProvider. + + Name of the .xml file. + Error reading from XML file (or from redirected file) + Invalid XML file + + + + Hash algorithm used for the index. + This is a custom implementation so that old index files work correctly + even when the .NET string.GetHashCode implementation changes + (e.g. due to .NET 4.5 hash randomization) + + + + + Get the documentation for the member with the specified documentation key. + + + + + Get the documentation for the specified member. + + + + + Metadata-only method called '<Extension>$'. Has the C# signature for the extension declaration. + + extension(ReceiverType name) {} -> void <Extension>$(ReceiverType name) {} + + + + + Metadata-only method with a signature as declared in C# within the extension declaration. + This could also be an accessor of an extension property. + + + + + The actual implementation method in the outer class. The signature is a concatenation + of the extension marker and the extension member's signatures. + + + + + This is the array of type parameters for the extension declaration. + + + + + This is the enclosing static class. + + + + + This is the compiler-generated class containing the extension members. Has type parameters + from the extension declaration with minimal constraints. + + + + + This class holds the type parameters for the extension declaration with full fidelity of C# constraints. + + + + + Represents a class, enum, interface, struct, delegate, record or unknown type. + For partial classes, this represents the whole class. + + + + + Gets the full name of this type. + + + + + A local function has zero or more compiler-generated parameters added at the end. + + + + + We consider local functions as always static, because they do not have a "this parameter". + Even local functions in instance methods capture this. + + + + + Add a builtin attribute without any arguments. + + + + + Construct a builtin attribute with a single positional argument of known type. + + + + + Construct a builtin attribute with a single positional argument of known type. + + + + + Construct a builtin attribute. + + + + + Custom attribute loaded from metadata. + + + + + Base class for fake members. + + + + + Field definition backed by System.Reflection.Metadata + + + + + Type definition backed by System.Reflection.Metadata + + + + + Synthetic method representing a compiler-generated indexer + with the signature 'get_Item(System.Index)' or 'get_Item(System.Range)'. + Can also be a setter. + Used for the "Implicit Index support"/"Implicit Range support" for the C# 8 ranges feature. + + + + + The underlying method: `get_Item(int)`, `set_Item(int, T)` or `Slice(int, int)`. + + + + + Constants used instead of bool? + in multithreaded code, as bool? might produce torn reads. + + + + + Represents a modopt or modreq type. + + + + + A decorator that annotates the nullability status for a type. + Note: ArrayType does not use a decorator, but has direct support for nullability. + + + + + If the item is not frozen, this method creates and returns a frozen clone. + If the item is already frozen, it is returned without creating a clone. + + + + + Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe. + + + + + Freezes this instance. + + + + + Default implementation for IType interface. + + + + + Helper class for the GetAllBaseTypes() implementation. + + + + + If this option is enabled, the list will not contain interfaces when retrieving the base types + of a class. + + + + + References an existing assembly by name. + + + + + IAttribute implementation for already-resolved attributes. + + + + + Default implementation of . + + + + + Default implementation of . + + + + + Gets a list filled with dummy type parameters. + + + + + Provides helper methods for implementing GetMembers() on IType-implementations. + Note: GetMembersHelper will recursively call back into IType.GetMembers(), but only with + both GetMemberOptions.IgnoreInheritedMembers and GetMemberOptions.ReturnMemberDefinitions set, + and only the 'simple' overloads (not taking type arguments). + + Ensure that your IType implementation does not use the GetMembersHelper if both flags are set, + otherwise you'll get a StackOverflowException! + + + + + Cache for KnownTypeReferences. + + + + + A merged namespace. + + + + + Creates a new merged root namespace. + + The main compilation. + The individual namespaces being merged. + The extern alias for this namespace. + + + + Creates a new merged child namespace. + + The parent merged namespace. + The individual namespaces being merged. + + + + An artificial "assembly" that contains all known types () and no other types. + It does not contain any members. + + + + + Minimal corlib instance containing all known types. + + + + + Type reference used to reference nested types. + + + + + Creates a new NestedTypeReference. + + Reference to the declaring type. + Name of the nested class + Number of type parameters on the inner class (without type parameters on baseTypeRef) + + must be exactly the (unbound) declaring type, not a derived type, not a parameterized type. + NestedTypeReference thus always resolves to a type definition, never to (partially) parameterized types. + + + + + Simple compilation implementation. + + + + + Represents a specialized IEvent (event after type substitution). + + + + + Represents a specialized IField (field after type substitution). + + + + + Represents a SpecializedMember (a member on which type substitution has been performed). + + + + + Performs a substitution. This method may only be called by constructors in derived classes. + + + + + Gets the substitution belonging to this specialized member. + + + + + Represents a specialized IMethod (e.g. after type substitution). + + + + + Represents a specialized IProperty (property after type substitution). + + + + + Creates a type parameter reference. + For common type parameter references, this method may return a shared instance. + + + + + An unknown type where (part) of the name is known. + + + + + Creates a new unknown type. + + Namespace name, if known. Can be null if unknown. + Name of the type, must not be null. + Type parameter count, zero if unknown. + + + + Creates a new unknown type. + + Full name of the unknown type. + + + + Introduces 'dynamic' and tuple types based on attribute values. + + + + + Not a known attribute + + + + + Marks a method as extension method; or a class as containing extension methods. + + + + + Type system implementation for Metadata.PEFile. + + + + + Gets all types in the assembly, including nested types. + + + + + Resolves a method reference. + + + Class type arguments are provided by the declaring type stored in the memberRef. + Method type arguments are provided by the caller. + + + + + Create a dummy IMethod from the specified MethodReference + + + + + Resolves a symbol. + + + * Types are resolved to their definition, as IType does not implement ISymbol. + * types without definition will resolve to null + * use ResolveType() to properly resolve types + * When resolving methods, varargs signatures are not expanded. + * use ResolveMethod() instead to get an IMethod instance suitable for call-sites + * May return specialized members, where generics are involved. + * Other types of handles that don't correspond to TS entities, will return null. + + + + + Gets the list of all assembly attributes in the project. + + + + + Gets the list of all module attributes in the project. + + + + + Cache for parameterless known attribute types. + + + + + Cache for parameterless known attributes. + + + + + Construct a builtin attribute. + + + + + NormalizeTypeVisitor that does not normalize type parameters, + but performs type erasure (object->dynamic; tuple->underlying type). + + + + + Gets the underlying System.ValueType type. + + + + + Gets the tuple elements. + + + + + Gets the cardinality of the tuple. + + + + + Gets the names of the tuple elements. + + + + + Gets whether the specified type is a valid underlying type for a tuple. + Also returns true for tuple types themselves. + + + + + Construct a tuple type (without element names) from the given underlying type. + Returns null if the input is not a valid underlying type. + + + + + Gets the tuple element types from a tuple type or tuple underlying type. + + + + + Allows decoding signatures using decompiler types. + + + + + Enum that describes the accessibility of an entity. + + + + + The entity is completely inaccessible. This is used for C# explicit interface implementations. + + + + + The entity is only accessible within the same class. + + + + + The entity is accessible in derived classes within the same assembly. + This corresponds to C# private protected. + + + + + The entity is only accessible within the same class and in derived classes. + + + + + The entity is accessible within the same assembly. + + + + + The entity is accessible both everywhere in the assembly, and in all derived classes. + This corresponds to C# protected internal. + + + + + The entity is accessible everywhere. + + + + + Gets whether a <= b in the partial order of accessibilities: + return true if b is accessible everywhere where a is accessible. + + + + + Computes the intersection of the two accessibilities: + The result is accessible from any given point in the code + iff both a and b are accessible from that point. + + + + + Computes the union of the two accessibilities: + The result is accessible from any given point in the code + iff at least one of a or b is accessible from that point. + + + + + Gets the effective accessibility of the entity. + For example, a public method in an internal class returns "internal". + + + + + Represents an array type. + + + + + Helper methods for COM. + + + + + Gets whether the specified type is imported from COM. + + + + + Gets the CoClass of the specified COM interface. + + + + + Options that control how metadata is represented in the type system. + + + + + No options enabled; stay as close to the metadata as possible. + + + + + [DynamicAttribute] is used to replace 'object' types with the 'dynamic' type. + + If this option is not active, the 'dynamic' type is not used, and the attribute is preserved. + + + + + Tuple types are represented using the TupleType class. + [TupleElementNames] is used to name the tuple elements. + + If this option is not active, the tuples are represented using their underlying type, and the attribute is preserved. + + + + + If this option is active, [ExtensionAttribute] is removed and methods are marked as IsExtensionMethod. + Otherwise, the attribute is preserved but the methods are not marked. + + + + + Only load the public API into the type system. + + + + + Do not cache accessed entities. + In a normal type system (without this option), every type or member definition has exactly one ITypeDefinition/IMember + instance. This instance is kept alive until the whole type system can be garbage-collected. + When this option is specified, the type system avoids these caches. + This reduces the memory usage in many cases, but increases the number of allocations. + Also, some code in the decompiler expects to be able to compare type/member definitions by reference equality, + and thus will fail with uncached type systems. + + + + + If this option is active, [DecimalConstantAttribute] is removed and constant values are transformed into simple decimal literals. + + + + + If this option is active, modopt and modreq types are preserved in the type system. + + Note: the decompiler currently does not support handling modified types; + activating this option may lead to incorrect decompilation or internal errors. + + + + + If this option is active, [IsReadOnlyAttribute] on parameters+structs is removed + and parameters are marked as in, structs as readonly. + Otherwise, the attribute is preserved but the parameters and structs are not marked. + + + + + If this option is active, [IsByRefLikeAttribute] is removed and structs are marked as ref. + Otherwise, the attribute is preserved but the structs are not marked. + + + + + If this option is active, [IsUnmanagedAttribute] is removed from type parameters, + and HasUnmanagedConstraint is set instead. + + + + + If this option is active, [NullableAttribute] is removed and reference types with + nullability annotations are used instead. + + + + + If this option is active, [IsReadOnlyAttribute] on methods is removed + and the method marked as ThisIsRefReadOnly. + + + + + [NativeIntegerAttribute] is used to replace 'IntPtr' types with the 'nint' type. + + + + + Allow function pointer types. If this option is not enabled, function pointers are + replaced with the 'IntPtr' type. + + + + + Allow C# 11 scoped annotation. If this option is not enabled, ScopedRefAttribute + will be reported as custom attribute. + + + + + Replace 'IntPtr' types with the 'nint' type even in absence of [NativeIntegerAttribute]. + Note: DecompilerTypeSystem constructor removes this setting from the options if + not targeting .NET 7 or later. + + + + + If this option is active, [RequiresLocationAttribute] on parameters is removed + and parameters are marked as ref readonly. + Otherwise, the attribute is preserved but the parameters are not marked + as if it was a ref parameter without any attributes. + + + + + If this option is active, [ParamCollectionAttribute] on parameters is removed + and parameters are marked as params. + Otherwise, the attribute is preserved but the parameters are not marked + as if it was a normal parameter without any attributes. + + + + + If this option is active, span types (Span<T> and ReadOnlySpan<T>) are treated like + built-in types and language rules of C# 14 and later are applied. + + + + + If this option is active, extension member groups are detected, otherwise the compiler-generated nested classes are left as-is. + + + + + Default settings: typical options for the decompiler, with all C# language features enabled. + + + + + Manages the NRefactory type system for the decompiler. + + + This class is thread-safe. + + + + + Holds the full name of a type definition. + A full type name uniquely identifies a type definition within a single assembly. + + + A full type name can only represent type definitions, not arbitrary types. + It does not include any type arguments, and can not refer to array or pointer types. + + A full type name represented as reflection name has the syntax: + NamespaceName '.' TopLevelTypeName ['`'#] { '+' NestedTypeName ['`'#] } + + + + + Constructs a FullTypeName representing the given top-level type. + + + FullTypeName has an implicit conversion operator from TopLevelTypeName, + so you can simply write: + FullTypeName f = new TopLevelTypeName(...); + + + + + Constructs a FullTypeName by parsing the given reflection name. + Note that FullTypeName can only represent type definition names. If the reflection name + might refer to a parameterized type or array etc., use + instead. + + + Expected syntax: NamespaceName '.' TopLevelTypeName ['`'#] { '+' NestedTypeName ['`'#] } + where # are type parameter counts + + + + + Gets the top-level type name. + + + + + Gets whether this is a nested type. + + + + + Gets the nesting level. + + + + + Gets the name of the type. + For nested types, this is the name of the innermost type. + + + + + Gets the total type parameter count. + + + + + Gets the name of the nested type at the given level. + + + + + Gets the number of additional type parameters of the nested type at the given level. + + + + + Gets the declaring type name. + + This is a top-level type name. + new FullTypeName("NS.A+B+C").GetDeclaringType() will return new FullTypeName("NS.A+B") + + + + Creates a nested type name. + + new FullTypeName("NS.A+B").NestedType("C", 1) will return new FullTypeName("NS.A+B+C`1") + + + + Interface used to help with construction of the type system. + + + The type system is an immutable cyclic data structure: + the compilation (ICompilation) has references to all modules, + and each module has a reference back to the compilation. + + Module references are used to solve this cyclic dependency: + The compilation constructor accepts module references, + and only the IModuleReference.Resolve() function can observe a + partially-constructed compilation; but not any user code. + + + + + Resolves this metadata module. + + + + + Represents a metadata module. + + + + + Gets the underlying metadata file. May return null, if the module was not created from a file. + + + + + Gets whether this assembly is the main assembly of the compilation. + + + + + Gets the assembly name (short name). + + + + + Gets the assembly version. + + + + + Gets the full assembly name (including public key token etc.) + + + + + Gets all assembly attributes. + + + + + Gets all module attributes. + + + + + Gets whether the internals of this assembly are visible in the specified assembly. + + + + + Gets the root namespace for this module. + + + This always is the namespace without a name - it's unrelated to the 'root namespace' project setting. + It contains only subnamespaces and types defined in this module -- use ICompilation.RootNamespace + to get the combined view of all referenced assemblies. + + + + + Gets the type definition for a top-level type. + + This method uses ordinal name comparison, not the compilation's name comparer. + + + + Gets all non-nested types in the assembly. + + + + + Gets all types in the assembly, including nested types. + + + + + Represents an attribute. + + + + + Gets the type of the attribute. + + + + + Gets the constructor being used. + This property may return null if no matching constructor was found. + + + + + Gets whether there were errors decoding the attribute. + + + + + Gets the positional arguments. + + + + + Gets the named arguments passed to the attribute. + + + + + Gets all currently visible local variables and lambda parameters. + Does not include method parameters. + + + + + Gets whether the context is within a lambda expression or anonymous method. + + + + + Gets the primary module. + This is the module being (de)compiled; all other modules in the compilation are the other assemblies/modules + referenced by the main module. + + + + + Gets the list of all modules in the compilation. + + + This main module is the first entry in the list. + + + + + Gets the referenced modules. + This list does not include the main module. + + + + + Gets the root namespace of this compilation. + This is a merged version of the root namespaces of all assemblies. + + + This always is the namespace without a name - it's unrelated to the 'root namespace' project setting. + + + + + Gets the root namespace for a given extern alias. + + + If is null or an empty string, this method + returns the global root namespace. + If no alias with the specified name exists, this method returns null. + + + + + Gets the name comparer for the language being compiled. + This is the string comparer used for the INamespace.GetTypeDefinition method. + + + + + Gets the parent compilation. + This property never returns null. + + + + + Represents a resolved entity. + + + + + Gets the metadata token for this entity. + + + The token is only valid within the context of the assembly defining this entity. + Token may be 0 if this is a generated member. + Note: specialized members will return the token of the member definition. + + + + + Gets the short name of the entity. + + + + + Gets the declaring class. + For members, this is the class that contains the member. + For nested classes, this is the outer class. For top-level entities, this property returns null. + + + + + Gets/Sets the declaring type (incl. type arguments, if any). + This property will return null for top-level entities. + If this is not a specialized member, the value returned is equal to . + + + + + The module in which this entity is defined. + May return null, if the IEntity was not created from a module. + + + + + Gets the attributes on this entity. + Does not include inherited attributes. + + + + + Gets the accessibility of this entity. + + + + + Gets whether this entity is static. + Returns true if either the 'static' or the 'const' modifier is set. + + + + + Returns whether this entity is abstract. + + Static classes also count as abstract classes. + + + + Returns whether this entity is sealed. + + Static classes also count as sealed classes. + + + + Represents a field or constant. + + + + + Gets the name of the field. + + + + + Gets whether this field is readonly. + + + + + Gets whether the field type is 'ref readonly'. + + + + + Gets whether this field is volatile. + + + + + Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe. + + + + + Freezes this instance. + + + + + Provider used for interning. + + + A simple IInterningProvider implementation could use 3 dictionaries: + 1. using value equality comparer (for certain types known to implement value equality, e.g. string and IType) + 2. using comparer that calls into ISupportsInterning (for types implementing ISupportsInterning) + 3. list comparer (for InternList method) + + On the first Intern()-call, the provider tells the object to prepare for interning (ISupportsInterning.PrepareForInterning) + and stores it into a dictionary. On further Intern() calls, the original object is returned for all equal objects. + This allows reducing the memory usage by using a single object instance where possible. + + Interning provider implementations could also use the interning logic for different purposes: + for example, it could be used to determine which objects are used jointly between multiple type definitions + and which are used only within a single type definition. Then a persistent file format could be organized so + that shared objects are loaded only once, yet non-shared objects get loaded lazily together with the class. + + + + + Interns the specified object. + + If the object is freezable, it will be frozen. + + + + + Interns the specified object. + + If the object is freezable, it will be frozen. + + + + + Interns the specified string. + + + + + Inters a boxed value type. + + + + + Interns the given list. Uses reference equality to compare the list elements. + + + + + Gets the declaring type reference for the member. + + + + + Resolves the member. + + + Context to use for resolving this member reference. + Which kind of context is required depends on the which kind of member reference this is; + please consult the documentation of the method that was used to create this member reference, + or that of the class implementing this method. + + + Returns the resolved member, or null if the member could not be found. + + + + + Method/field/property/event. + + + + + Gets the original member definition for this member. + Returns this if this is not a specialized member. + Specialized members are the result of overload resolution with type substitution. + + + + + Gets the return type of this member. + This property never returns null. + + + + + Gets/Sets the declaring type (incl. type arguments, if any). + If this is not a specialized member, the value returned is equal to . + + + + + Gets the interface members explicitly implemented by this member. + + + For methods, equivalent to ( + from impl in DeclaringTypeDefinition.GetExplicitInterfaceImplementations() + where impl.Implementation == this + select impl.InterfaceMethod + ), + but may be more efficient than searching the whole list. + + Note that it is possible for a class to implement an interface using members in a + base class unrelated to that interface: + class BaseClass { public void Dispose() {} } + class C : BaseClass, IDisposable { } + In this case, the interface member will not show up in (BaseClass.Dispose).ImplementedInterfaceMembers, + so use (C).GetInterfaceImplementations() instead to handle this case. + + + + + Gets whether this member is explicitly implementing an interface. + + + + + Gets if the member is virtual. Is true only if the "virtual" modifier was used, but non-virtual + members can be overridden, too; if they are abstract or overriding a method. + + + + + Gets whether this member is overriding another member. + + + + + Gets if the member can be overridden. Returns true when the member is "abstract", "virtual" or "override" but not "sealed". + + + + + Gets the substitution belonging to this specialized member. + Returns TypeParameterSubstitution.Identity for not specialized members. + + + + + Specializes this member with the given substitution. + If this member is already specialized, the new substitution is composed with the existing substition. + + + + + Gets whether the members are considered equal when applying the specified type normalization. + + + + + Represents a method, constructor, destructor or operator. + + + + + Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)]) + + + Does not include inherited attributes. + + + + + Gets whether the return type is 'ref readonly'. + + + + + Gets whether this method may only be called on fresh instances. + Used with C# 9 `init;` property setters. + + + + + Gets whether the method accepts the 'this' reference as ref readonly. + This can be either because the method is C# 8.0 'readonly', or because it is within a C# 7.2 'readonly struct' + + + + + Gets the type parameters of this method; or an empty list if the method is not generic. + + + + + Gets the type arguments passed to this method. + If the method is generic but not parameterized yet, this property returns the type parameters, + as if the method was parameterized with its own type arguments (void M<T>() { M<T>(); }). + + + + + Returns true for classic extension methods, where extension method == implementation method, otherwise returns false. + + + + + Gets whether the method has a body. + This property returns false for abstract or extern methods, + or for partial methods without implementation. + + + + + Gets whether the method is a property/event accessor. + + + + + If this method is an accessor, returns the corresponding property/event. + Otherwise, returns null. + + + + + Gets the kind of accessor this is. + + + + + If this method is reduced from an extension method or a local function returns the original method, null otherwise. + A reduced method doesn't contain the extension method parameter. That means that it has one parameter less than its definition. + A local function doesn't contain compiler-generated method parameters at the end. + + + + + Specializes this method with the given substitution. + If this method is already specialized, the new substitution is composed with the existing substition. + + + + + Gets the fully qualified name of the class the return type is pointing to. + + + "System.Int32[]" for int[]
+ "System.Collections.Generic.List" for List<string> + "System.Environment.SpecialFolder" for Environment.SpecialFolder +
+
+ + + Gets the short name of the class the return type is pointing to. + + + "Int32[]" for int[]
+ "List" for List<string> + "SpecialFolder" for Environment.SpecialFolder +
+
+ + + Gets the full reflection name of the element. + + + For types, the reflection name can be parsed back into a IType by using + . + + + "System.Int32[]" for int[]
+ "System.Int32[][,]" for C# int[,][]
+ "System.Collections.Generic.List`1[[System.String]]" for List<string> + "System.Environment+SpecialFolder" for Environment.SpecialFolder +
+
+ + + Gets the full name of the namespace containing this entity. + + + + + Represents a resolved namespace. + + + + + Gets the extern alias for this namespace. + Returns an empty string for normal namespaces. + + + + + Gets the full name of this namespace. (e.g. "System.Collections") + + + + + Gets the short name of this namespace (e.g. "Collections"). + + + + + Gets the parent namespace. + Returns null if this is the root namespace. + + + + + Gets the child namespaces in this namespace. + + + + + Gets the types in this namespace. + + + + + Gets the modules that contribute types to this namespace (or to child namespaces). + + + + + Gets a direct child namespace by its short name. + Returns null when the namespace cannot be found. + + + This method uses the compilation's current string comparer. + + + + + Gets the type with the specified short name and type parameter count. + Returns null if the type cannot be found. + + + This method uses the compilation's current string comparer. + + + + + Provides helper methods for inheritance. + + + + + Gets the base member that has the same signature. + + + + + Gets all base members that have the same signature. + + + List of base members with the same signature. The member from the derived-most base class is returned first. + + + + + Finds the member declared in 'derivedType' that has the same signature (could override) 'baseMember'. + + + + + Represents the intersection of several types. + + + + + Should match order in . + + + + + C# 11 scoped annotation: "scoped ref" (ScopedRefAttribute) + + + + + Gets the attributes on this parameter. + + + + + Gets the reference kind of this parameter. + + + + + C# 11 scoped annotation. + + + + + Gets whether this parameter is a C# 'params' parameter. + + + + + Gets whether this parameter is optional. + The default value is given by the function. + + + + + Gets whether this parameter has a constant value when presented in method signature. + + + This can only be true if the parameter is optional, and it's true for most + optional parameters. However it is possible to compile a parameter without a default value, + and some parameters handle their default values in an special way. + + For example, does not use normal constants, + so when is false + we expose DecimalConstantAttribute directly instead of a constant value. + + On the call sites, though, we can still use the value inferred from the attribute. + + + + + Gets the owner of this parameter. + May return null; for example when parameters belong to lambdas or anonymous methods. + + + + + Represents a method or property. + + + + + Represents a property or indexer. + + + + + Gets whether the return type is 'ref readonly'. + + + + + Interface for TypeSystem objects that support interning. + See for more information. + + + + + Gets a hash code for interning. + + + + + Equality test for interning. + + + + + + + + + + + + + + The symbol is a property, but not an indexer. + + + + + + The symbol is an indexer, not a regular property. + + + + + + + + + The symbol is a method which is not an operator/constructor/destructor or accessor. + + + + + + The symbol is a user-defined operator. + + + + + + + + + + + + The accessor method for a property getter/setter or event add/remove. + + + + + + + + + The symbol is a variable, but not a parameter. + + + + + + + + + + + + Constraint on a type parameter. + + + + + Return type. Not actually an ISymbol implementation; but can appear as attribut target. + + + + + Interface for type system symbols. + + + + + This property returns an enum specifying which kind of symbol this is + (which derived interfaces of ISymbol are implemented) + + + + + Gets the short name of the symbol. + + + + + This interface represents a resolved type in the type system. + + + + A type is potentially + - a type definition (, i.e. a class, struct, interface, delegate, or built-in primitive type) + - a parameterized type (, e.g. List<int>) + - a type parameter (, e.g. T) + - an array () + - a pointer () + - a managed reference () + - one of the special types (, , + , ) + + The property can be used to switch on the kind of a type. + + + IType uses the null object pattern: serves as the null object. + Methods or properties returning IType never return null unless documented otherwise. + + + Types should be compared for equality using the method. + Identical types do not necessarily use the same object reference. + + + + + + Gets the type kind. + + + + + Gets whether the type is a reference type or value type. + + + true, if the type is a reference type. + false, if the type is a value type. + null, if the type is not known (e.g. unconstrained generic type parameter or type not found) + + + + + Gets whether this type is "ref-like": a ByReferenceType or "ref struct". + + + + + Gets the nullability annotation on this type. + + + + + Creates a new type that is a copy of this type, with the changed nullability annotation. + + + + + Gets the underlying type definition. + Can return null for types which do not have a type definition (for example arrays, pointers, type parameters). + + + + + Gets the underlying type definition or UnkownType, if unknown. + Can return null for types which do not have a type definition (for example arrays, pointers, type parameters). + + + + + Gets the parent type, if this is a nested type. + Returns null for top-level types. + + + + + Gets the number of type parameters. + + + + + Gets the type parameters. + Returns an empty list if this type is not generic. + + + + + Gets the type arguments passed to this type. + If this type is a generic type definition that is not parameterized, this property returns the type parameters, + as if the type was parameterized with its own type arguments (class C<T> { C<T> field; }). + + + + + Calls ITypeVisitor.Visit for this type. + + The return value of the ITypeVisitor.Visit call + + + + Calls ITypeVisitor.Visit for all children of this type, and reconstructs this type with the children based + on the return values of the visit calls. + + A copy of this type, with all children replaced by the return value of the corresponding visitor call. + If the visitor returned the original types for all children (or if there are no children), returns this. + + + + + Gets the direct base types. + + Returns the direct base types including interfaces + + + + Gets a type visitor that performs the substitution of class type parameters with the type arguments + of this parameterized type. + Returns TypeParameterSubstitution.Identity if the type is not parametrized. + + + + + Gets inner classes (including inherited inner classes). + + The filter used to select which types to return. + The filter is tested on the original type definitions (before parameterization). + Specified additional options for the GetMembers() operation. + + + If the nested type is generic, this method will return a parameterized type, + where the additional type parameters are set to . + + + Type parameters belonging to the outer class will have the value copied from the outer type + if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized, + and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members + from an and 'leaks' type parameters in member signatures. + + + + + class Base<T> { + class Nested<X> {} + } + class Derived<A, B> : Base<B> {} + + Derived[string,int].GetNestedTypes() = { Base`1+Nested`1[int, unbound] } + Derived.GetNestedTypes() = { Base`1+Nested`1[`1, unbound] } + Base[`1].GetNestedTypes() = { Base`1+Nested`1[`1, unbound] } + Base.GetNestedTypes() = { Base`1+Nested`1[`0, unbound] } + + + + + + Gets inner classes (including inherited inner classes) + that have typeArguments.Count additional type parameters. + + The type arguments passed to the inner class + The filter used to select which types to return. + The filter is tested on the original type definitions (before parameterization). + Specified additional options for the GetMembers() operation. + + Type parameters belonging to the outer class will have the value copied from the outer type + if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized, + and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members + from an and 'leaks' type parameters in member signatures. + + + + + Gets all instance constructors for this type. + + The filter used to select which constructors to return. + The filter is tested on the original method definitions (before specialization). + Specified additional options for the GetMembers() operation. + + The result does not include static constructors. + Constructors in base classes are not returned by default, as GetMemberOptions.IgnoreInheritedMembers is the default value. + + For methods on parameterized types, type substitution will be performed on the method signature, + and the appropriate will be returned. + + + + + + Gets all methods that can be called on this type. + + The filter used to select which methods to return. + The filter is tested on the original method definitions (before specialization). + Specified additional options for the GetMembers() operation. + + + The result does not include constructors or accessors. + + + For methods on parameterized types, type substitution will be performed on the method signature, + and the appropriate will be returned. + + + If the method being returned is generic, and this type is a parameterized type where the type + arguments involve another method's type parameters, the resulting specialized signature + will be ambiguous as to which method a type parameter belongs to. + For example, "List[[``0]].GetMethods()" will return "ConvertAll(Converter`2[[``0, ``0]])". + + If possible, use the other GetMethods() overload to supply type arguments to the method, + so that both class and method type parameter can be substituted at the same time, so that + the ambiguity can be avoided. + + + + + + Gets all generic methods that can be called on this type with the specified type arguments. + + The type arguments used for the method call. + The filter used to select which methods to return. + The filter is tested on the original method definitions (before specialization). + Specified additional options for the GetMembers() operation. + + The result does not include constructors or accessors. + + Type substitution will be performed on the method signature, creating a + with the specified type arguments. + + + When the list of type arguments is empty, this method acts like the GetMethods() overload without + the type arguments parameter - that is, it also returns generic methods, + and the other overload's remarks about ambiguous signatures apply here as well. + + + + + + Gets all properties that can be called on this type. + + The filter used to select which properties to return. + The filter is tested on the original property definitions (before specialization). + Specified additional options for the GetMembers() operation. + + For properties on parameterized types, type substitution will be performed on the property signature, + and the appropriate will be returned. + + + + + Gets all fields that can be accessed on this type. + + The filter used to select which constructors to return. + The filter is tested on the original field definitions (before specialization). + Specified additional options for the GetMembers() operation. + + For fields on parameterized types, type substitution will be performed on the field's return type, + and the appropriate will be returned. + + + + + Gets all events that can be accessed on this type. + + The filter used to select which events to return. + The filter is tested on the original event definitions (before specialization). + Specified additional options for the GetMembers() operation. + + For fields on parameterized types, type substitution will be performed on the event's return type, + and the appropriate will be returned. + + + + + Gets all members that can be called on this type. + + The filter used to select which members to return. + The filter is tested on the original member definitions (before specialization). + Specified additional options for the GetMembers() operation. + + + The resulting list is the union of GetFields(), GetProperties(), GetMethods() and GetEvents(). + It does not include constructors. + For parameterized types, type substitution will be performed. + + + For generic methods, the remarks about ambiguous signatures from the + method apply here as well. + + + + + + Gets all accessors belonging to properties or events on this type. + + The filter used to select which members to return. + The filter is tested on the original member definitions (before specialization). + Specified additional options for the GetMembers() operation. + + Accessors are not returned by GetMembers() or GetMethods(). + + + + + No options specified - this is the default. + Members will be specialized, and inherited members will be included. + + + + + Do not specialize the returned members - directly return the definitions. + + + + + Do not list inherited members - only list members defined directly on this type. + + + + + Represents a class, enum, interface, struct, delegate, record or VB module. + For partial classes, this represents the whole class. + + + + + Gets the known type code for this type definition. + + + + + For enums: returns the underlying primitive type. + For all other types: returns . + + + + + For structs: returns whether this is a readonly struct. + For all other types: returns false. + + + + + Gets the short type name as stored in metadata. + That is, the short type name including the generic arity (`N) appended. + + + "Int32" for int + "List`1" for List<T> + "List`1" for List<string> + + + + + Gets/Sets the declaring type (incl. type arguments, if any). + This property will return null for top-level types. + + + + + Gets whether this type contains extension methods or C# 14 extensions. + + This property is used to speed up the search for extension members. + + + + For types containing extension blocks, returns a non-null value. + For extension blocks, returns the extension info of the parent. + For all other types returns null. + + + + + The nullability specified in the [NullableContext] attribute on the type. + This serves as default nullability for members of the type that do not have a [Nullable] attribute. + + + + + Gets whether the type has the necessary members to be considered a C# 9 record or C# 10 record struct type. + + + + + Type parameter of a generic class/method. + + + + + Get the type of this type parameter's owner. + + SymbolKind.TypeDefinition or SymbolKind.Method + + + + Gets the owning method/class. + This property may return null (for example for the dummy type parameters used by ). + + + For "class Outer<T> { class Inner {} }", + inner.TypeParameters[0].Owner will be the outer class, because the same + ITypeParameter instance is used both on Outer`1 and Outer`1+Inner. + + + + + Gets the index of the type parameter in the type parameter list of the owning method/class. + + + + + Gets the name of the type parameter. + + + + + Gets the attributes declared on this type parameter. + + + + + Gets the variance of this type parameter. + + + + + Gets the effective base class of this type parameter. + + + + + Gets the effective interface set of this type parameter. + + + + + Gets if the type parameter has the 'new()' constraint. + + + + + Gets if the type parameter has the 'class' constraint. + + + + + Gets if the type parameter has the 'struct' or 'unmanaged' constraint. + + + + + Gets if the type parameter has the 'unmanaged' constraint. + + + + + if the allows ref struct constraint is specified for the type parameter. + + + + + Nullability of the reference type constraint. (e.g. "where T : class?"). + + Note that the nullability of a use of the type parameter may differ from this. + E.g. "T? GetNull<T>() where T : class => null;" + + + + + Represents the variance of a type parameter. + + + + + The type parameter is not variant. + + + + + The type parameter is covariant (used in output position). + + + + + The type parameter is contravariant (used in input position). + + + + + Represents a reference to a type. + Must be resolved before it can be used as type. + + + + + Resolves this type reference. + + + Context to use for resolving this type reference. + Which kind of context is required depends on the which kind of type reference this is; + please consult the documentation of the method that was used to create this type reference, + or that of the class implementing this method. + + + Returns the resolved type. + In case of an error, returns an unknown type (). + Never returns null. + + + + + Gets the current module. + This property may return null if this context does not specify any module. + + + + + Gets the current type definition. + + + + + Gets the current member. + + + + + Represents a variable (name/type pair). + + + + + Gets the name of the variable. + + + + + Gets the type of the variable. + + + + + Gets whether this variable is a constant (C#-like const). + + + + + If this field is a constant, retrieves the value. + For parameters, this is the default value. + + + + + Represents some well-known types. + + + + + Not one of the known types. + + + + object (System.Object) + + + System.DBNull + + + bool (System.Boolean) + + + char (System.Char) + + + sbyte (System.SByte) + + + byte (System.Byte) + + + short (System.Int16) + + + ushort (System.UInt16) + + + int (System.Int32) + + + uint (System.UInt32) + + + long (System.Int64) + + + ulong (System.UInt64) + + + float (System.Single) + + + double (System.Double) + + + decimal (System.Decimal) + + + System.DateTime + + + string (System.String) + + + void (System.Void) + + + System.Type + + + System.Array + + + System.Attribute + + + System.ValueType + + + System.Enum + + + System.Delegate + + + System.MulticastDelegate + + + System.Exception + + + System.IntPtr + + + System.UIntPtr + + + System.Collections.IEnumerable + + + System.Collections.IEnumerator + + + System.Collections.Generic.IEnumerable{T} + + + System.Collections.Generic.IEnumerator{T} + + + System.Collections.Generic.ICollection + + + System.Collections.Generic.ICollection{T} + + + System.Collections.Generic.IList + + + System.Collections.Generic.IList{T} + + + System.Collections.Generic.IReadOnlyCollection{T} + + + System.Collections.Generic.IReadOnlyList{T} + + + System.Threading.Tasks.Task + + + System.Threading.Tasks.Task{T} + + + System.Threading.Tasks.ValueTask + + + System.Threading.Tasks.ValueTask{T} + + + System.Nullable{T} + + + System.IDisposable + + + System.IAsyncDisposable + + + System.Runtime.CompilerServices.INotifyCompletion + + + System.Runtime.CompilerServices.ICriticalNotifyCompletion + + + System.TypedReference + + + System.IFormattable + + + System.FormattableString + + + System.Runtime.CompilerServices.DefaultInterpolatedStringHandler + + + System.Span{T} + + + System.ReadOnlySpan{T} + + + System.Memory{T} + + + System.Runtime.CompilerServices.Unsafe + + + System.Collections.Generic.IAsyncEnumerable{T} + + + System.Collections.Generic.IAsyncEnumerator{T} + + + System.Index + + + System.Range + + + + Contains well-known type references. + + + + + Gets the known type reference for the specified type code. + Returns null for KnownTypeCode.None. + + + + + Gets the C# primitive type name from the known type code. + Returns null if there is no primitive name for the specified type. + + + + + Static helper methods for working with nullable types. + + + + + Gets whether the specified type is a nullable type. + + + + + Returns the element type, if is a nullable type. + Otherwise, returns the type itself. + + + + + Creates a nullable type. + + + + + Creates a nullable type reference. + + + + + ParameterizedType represents an instance of a generic type. + Example: List<string> + + + When getting the members, this type modifies the lists so that + type parameters in the signatures of the members are replaced with + the type arguments. + + + + + Fast internal version of the constructor. (no safety checks) + Keeps the array that was passed and assumes it won't be modified. + + + + + Same as 'parameterizedType.TypeArguments[index]'. + + + + + Gets the definition of the generic type. + For ParameterizedType, this method never returns null. + + + + + Gets a type visitor that performs the substitution of class type parameters with the type arguments + of this parameterized type. + + + + + Gets a type visitor that performs the substitution of class type parameters with the type arguments + of this parameterized type, + and also substitutes method type parameters with the specified method type arguments. + + + + + ParameterizedTypeReference is a reference to generic class that specifies the type parameters. + Example: List<string> + + + + + Compares parameter lists by comparing the types of all parameters. + + + 'ref int' and 'out int' are considered to be equal - unless is set to true. + 'object' and 'dynamic' are also equal. + For generic methods, "Method{T}(T a)" and "Method{S}(S b)" are considered equal. + However, "Method(T a)" and "Method(S b)" are not considered equal when the type parameters T and S belong to classes. + + + + + Compares member signatures. + + + This comparer checks for equal short name, equal type parameter count, and equal parameter types (using ParameterListComparer). + + + + + Gets a signature comparer that uses an ordinal comparison for the member name. + + + + + Static helper methods for reflection names. + + + + + Retrieves the specified type in this compilation. + Returns if the type cannot be found in this compilation. + + + This method cannot be used with open types; all type parameters will be substituted + with . + + + + + Removes the ` with type parameter count from the reflection name. + + Do not use this method with the full name of inner classes. + + + + Removes the ` with type parameter count from the reflection name. + + Do not use this method with the full name of inner classes. + + + + Retrieves a built-in type using the specified type code. + + + + + Gets the type code for the specified type, or TypeCode.Empty if none of the other type codes match. + + + + + Parses a reflection name into a type reference. + + The reflection name of the type. + A type reference that represents the reflection name. + The syntax of the reflection type name is invalid + + If the type is open (contains type parameters '`0' or '``0'), + an with the appropriate CurrentTypeDefinition/CurrentMember is required + to resolve the reference to the ITypeParameter. + For looking up closed, assembly qualified type names, the root type resolve context for the compilation + is sufficient. + When looking up a type name that isn't assembly qualified, the type reference will look in + first, and if the type is not found there, + it will look in all other assemblies of the compilation. + + + + + + Represents an error while parsing a reflection name. + + + + + Default ITypeResolveContext implementation. + + + + + Contains static implementations of special types. + + + + + Gets the type representing resolve errors. + + + + + The null type is used as type of the null literal. It is a reference type without any members; and it is a subtype of all reference types. + + + + + Used for expressions without type, e.g. method groups or lambdas. + + + + + Type representing the C# 'dynamic' type. + + + + + Type representing the C# 9 'nint' type. + + + + + Type representing the C# 9 'nuint' type. + + + + + Type representing the result of the C# '__arglist()' expression. + + + + + A type used for unbound type arguments in partially parameterized types. + + + + + + Helper class for dealing with System.Threading.Tasks.Task. + + + + + Gets the T in Task<T>. + Returns void for non-generic Task. + Any other type is returned unmodified. + + + + + Gets whether the specified type is Task or Task<T>. + + + + + Gets whether the specified type is a Task-like type. + + + + + Gets whether the specified type is a non-generic Task-like type. + + Returns the full type-name of the builder type, if successful. + + + + Gets whether the specified type is a generic Task-like type. + + Returns the full type-name of the builder type, if successful. + + + + Creates a task type. + + + + + Holds the name of a top-level type. + This struct cannot refer to nested classes. + + + + + . + + + + Language-specific type that is not part of NRefactory.TypeSystem itself. + + + A or that is a class. + + + A or that is an interface. + + + A or that is a struct. + + + A or that is a delegate. + System.Delegate itself is TypeKind.Class + + + A that is an enum. + System.Enum itself is TypeKind.Class + + + The System.Void type. + + + + Type used for invalid expressions and for types whose definition could not be found. + + + + The type of the null literal. + + + + The type of expressions without type (except for null literals, which have TypeKind.Null). + + + + Type representing the C# 'dynamic' type. + + + + Represents missing type arguments in partially parameterized types. + + IType.GetNestedTypes(Predicate{ITypeDefinition}, GetMemberOptions) + + + The type is a type parameter. + + + + An array type + + + + A pointer type + + + + A managed reference type + + + + Intersection of several types + + + + + + + A C# 7 tuple type. + E.g. (string, int) + Note: System.ValueTuple<string, int> is not considered a tuple type. + + + + + + Modified type, with optional modifier. + + + + + Modified type, with required modifier. + + + + + C# 9 nint + + + + + C# 9 nuint + + + + + C# 9 delegate* + + + + + Substitutes class and method type parameters. + + + + + The identity function. + + + + + Creates a new type parameter substitution. + + + The type arguments to substitute for class type parameters. + Pass null to keep class type parameters unmodified. + + + The type arguments to substitute for method type parameters. + Pass null to keep method type parameters unmodified. + + + + + Gets the list of class type arguments. + Returns null if this substitution keeps class type parameters unmodified. + + + + + Gets the list of method type arguments. + Returns null if this substitution keeps method type parameters unmodified. + + + + + Computes a single TypeParameterSubstitution so that for all types t: + t.AcceptVisitor(Compose(g, f)) equals t.AcceptVisitor(f).AcceptVisitor(g) + + If you consider type parameter substitution to be a function, this is function composition. + + + + Contains extension methods for the type system. + + + + + Gets all base types. + + This is the reflexive and transitive closure of . + Note that this method does not return all supertypes - doing so is impossible due to contravariance + (and undesirable for covariance as the list could become very large). + + The output is ordered so that base types occur before derived types. + + + + + Gets all non-interface base types. + + + When is an interface, this method will also return base interfaces (return same output as GetAllBaseTypes()). + + The output is ordered so that base types occur before derived types. + + + + + Gets all base type definitions. + The output is ordered so that base types occur before derived types. + + + This is equivalent to type.GetAllBaseTypes().Select(t => t.GetDefinition()).Where(d => d != null).Distinct(). + + + + + Gets whether this type definition is derived from the base type definition. + + + + + Gets whether this type definition is derived from a given known type. + + + + + Returns all declaring type definitions of this type definition. + The output is ordered so that inner types occur before outer types. + + + + + Gets whether the type is an open type (contains type parameters). + + + + class X<T> { + List<T> open; + X<X<T[]>> open; + X<string> closed; + int closed; + } + + + + + + Gets the entity that owns the type parameters occurring in the specified type. + If both class and method type parameters are present, the method is returned. + Returns null if the specified type is closed. + + + + + + Gets whether the type is unbound (is a generic type, but no type arguments were provided). + + + In "typeof(List<Dictionary<,>>)", only the Dictionary is unbound, the List is considered + bound despite containing an unbound type. + This method returns false for partially parameterized types (Dictionary<string, >). + + + + + Gets whether the type is considered unmanaged. + + + The C# 6.0 spec lists the following criteria: An unmanaged type is one of the following + * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool + * any enum type + * any pointer type + * any user-defined struct type that is not a constructed (= generic) type and contains fields of unmanaged types only. + + C# 8.0 removes the restriction that constructed (= generic) types are not considered unmanaged types. + + + + + Gets whether the type is the specified known type. + For generic known types, this returns true for any parameterization of the type (and also for the definition itself). + + + + + Gets whether the type is the specified known type. + For generic known types, this returns true for any parameterization of the type (and also for the definition itself). + + + + + Gets the invoke method for a delegate type. + + + Returns null if the type is not a delegate type; or if the invoke method could not be found. + + + + + Gets all type definitions in the compilation. + This may include types from referenced assemblies that are not accessible in the main assembly. + + + + + Gets all top level type definitions in the compilation. + This may include types from referenced assemblies that are not accessible in the main assembly. + + + + + Retrieves the specified type in this compilation. + Returns an if the type cannot be found in this compilation. + + + There can be multiple types with the same full name in a compilation, as a + full type name is only unique per assembly. + If there are multiple possible matches, this method will return just one of them. + When possible, use instead to + retrieve a type from a specific assembly. + + + + + Gets the type definition for the specified unresolved type. + Returns null if the unresolved type does not belong to this assembly. + + + + + Gets whether the entity has an attribute of the specified attribute type. + + The entity on which the attributes are declared. + The attribute type to look for. + + Specifies whether attributes inherited from base classes and base members + (if the given in an override) + should be returned. + + + + + Gets the attribute of the specified attribute type. + + The entity on which the attributes are declared. + The attribute type to look for. + + Specifies whether attributes inherited from base classes and base members + (if the given in an override) + should be returned. + + + Returns the attribute that was found; or null if none was found. + If inherit is true, an from the entity itself will be returned if possible; + and the base entity will only be searched if none exists. + + + + + Gets the attributes on the entity. + + The entity on which the attributes are declared. + + Specifies whether attributes inherited from base classes and base members + (if the given in an override) + should be returned. + + + Returns the list of attributes that were found. + If inherit is true, attributes from the entity itself are returned first; + followed by attributes inherited from the base entity. + + + + + Gets whether the parameter has an attribute of the specified attribute type. + + The parameter on which the attributes are declared. + The attribute type to look for. + + + + Gets the attribute of the specified attribute type. + + The parameter on which the attributes are declared. + The attribute type to look for. + + Returns the attribute that was found; or null if none was found. + + + + + Checks if the parameter is allowed to be assigned a default value. + + + This checks , , , + and on this parameter and all subsequent parameters. + If the parameter has no , it does not check subsequent parameters. + + The parameter + True if the has a default value and is allowed to be assigned a default value. + + + + Gets the type definition for a top-level type. + + This method uses ordinal name comparison, not the compilation's name comparer. + + + + When given a generic type definition, returns the self-parameterized type + (i.e. the type of "this" within the type definition). + When given a non-generic type definition, returns that definition unchanged. + + + + + Gets the size (in bytes) of the input type. + Returns NativeIntSize for pointer-sized types. + Returns 0 for structs and other types of unknown size. + + + + + Gets the size of the input stack type. + + + * 4 for I4, + * 8 for I8, + * NativeIntSize for I and Ref, + * 0 otherwise (O, F, Void, Unknown). + + + + + Gets whether the type is a small integer type. + Small integer types are: + * bool, sbyte, byte, char, short, ushort + * any enums that have a small integer type as underlying type + + + + + Gets whether the type is a C# small integer type: byte, sbyte, short or ushort. + + Unlike the ILAst, C# does not consider bool, char or enums to be small integers. + + + + + Gets whether the type is a C# 9 native integer type: nint or nuint. + + Returns false for (U)IntPtr. + + + + + Gets whether the type is a C# primitive integer type: byte, sbyte, short, ushort, int, uint, long and ulong. + + Unlike the ILAst, C# does not consider bool, enums, pointers or IntPtr to be integers. + + + + + Gets whether the type is an IL integer type. + Returns true for I4, I, or I8. + + + + + Gets whether the type is an IL floating point type. + Returns true for F4 or F8. + + + + + Gets whether reading/writing an element of accessType from the pointer + is equivalent to reading/writing an element of the pointer's element type. + + + The access semantics may sligthly differ on read accesses of small integer types, + due to zero extension vs. sign extension when the signs differ. + + + + + Gets whether reading/writing an element of accessType from the pointer + is equivalent to reading/writing an element of the memoryType. + + + The access semantics may sligthly differ on read accesses of small integer types, + due to zero extension vs. sign extension when the signs differ. + + + + + Gets the stack type corresponding to this type. + + + + + If type is an enumeration type, returns the underlying type. + Otherwise, returns type unmodified. + + + + + Gets the sign of the input type. + + + Integer types (including IntPtr/UIntPtr) return the sign as expected. + Floating point types and decimal are considered to be signed. + char, bool and pointer types (e.g. void*) are unsigned. + Enums have a sign based on their underlying type. + All other types return Sign.None. + + + + + Maps the KnownTypeCode values to the corresponding PrimitiveTypes. + + + + + Maps the KnownTypeCode values to the corresponding PrimitiveTypes. + + + + + Maps the PrimitiveType values to the corresponding KnownTypeCodes. + + + + + Main interface for the decompiler type system. + + The MetadataModule class allows decoding/resolving metadata tokens into type system entities. + + + + + Represents an error while resolving a reference to a type or a member. + + + + + Initializes a new instance of the class + + + + + Initializes a new instance of the class + + A that describes the error. The content of message is intended to be understood by humans. The caller of this constructor is required to ensure that this string has been localized for the current system culture. + + + + Initializes a new instance of the class + + A that describes the error. The content of message is intended to be understood by humans. The caller of this constructor is required to ensure that this string has been localized for the current system culture. + The exception that is the cause of the current exception. If the innerException parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + + + + Initializes a new instance of the class + + The object that holds the serialized object data. + The contextual information about the source or destination. + + + + Base class for the visitor pattern on . + + + + + Used when calling a vararg method. Stores the actual parameter types being passed. + + + + + Gets the normalized version of fileName. + Slashes are replaced with backslashes, backreferences "." and ".." are 'evaluated'. + + + + + Converts a given absolute path and a given base path to a path that leads + from the base path to the absoulte path. (as a relative path) + + + + + An immutable mapping from keys of type long to values of type T. + + + + + Creates a new LongDict from the given entries. + If there are multiple entries for the same long key, + the resulting LongDict will store the value from the first entry. + + + + + .resources file. + + + + Holds the number used to identify resource files. + + + + Creates a new ResourcesFile. + + Input stream. + Whether the stream should be held open when the ResourcesFile is disposed. + + The stream is must be held open while the ResourcesFile is in use. + The stream must be seekable; any operation using the ResourcesFile will end up seeking the stream. + + + + + Gets a stream that starts with the serialized object data. + + + + + Gets the serialized object data. + + + + + Line Feed, U+000A + + + + + Carriage Return, U+000D + + + + + Next Line, U+0085 + + + + + Vertical Tab, U+000B + + + + + Form Feed, U+000C + + + + + Line Separator, U+2028 + + + + + Paragraph Separator, U+2029 + + + + + Defines unicode new lines according to Unicode Technical Report #13 + http://www.unicode.org/standard/reports/tr13/tr13-5.html + + + + + Carriage Return, U+000D + + + + + Line Feed, U+000A + + + + + Next Line, U+0085 + + + + + Vertical Tab, U+000B + + + + + Form Feed, U+000C + + + + + Line Separator, U+2028 + + + + + Paragraph Separator, U+2029 + + + + + Determines if a char is a new line delimiter. + + 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. + The current character. + A callback getting the next character (may be null). + + + + Determines if a char is a new line delimiter. + + 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. + The current character. + The next character (if != LF then length will always be 0 or 1). + + + + Determines if a char is a new line delimiter. + + 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. + The current character. + The length of the delimiter + The type of the delimiter + A callback getting the next character (may be null). + + + + Determines if a char is a new line delimiter. + + 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. + The current character. + The length of the delimiter + The type of the delimiter + The next character (if != LF then length will always be 0 or 1). + + + + Gets the new line type of a given char/next char. + + 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. + The current character. + A callback getting the next character (may be null). + + + + Gets the new line type of a given char/next char. + + 0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter. + The current character. + The next character (if != LF then length will always be 0 or 1). + + + + Determines if a char is a new line delimiter. + + Note that the only 2 char wide new line is CR LF and both chars are new line + chars on their own. For most cases GetDelimiterLength is the better choice. + + + + + Gets the new line as a string. + + + + + This class is used to prevent stack overflows by representing a 'busy' flag + that prevents reentrance when another call is running. + However, using a simple 'bool busy' is not thread-safe, so we use a + thread-static BusyManager. + + + + + Allows caching values for a specific compilation. + A CacheManager consists of a for shared instances (shared among all threads working with that resolve context). + + This class is thread-safe + + + + Invokes an action when it is disposed. + + + This class ensures the callback is invoked at most once, + even when Dispose is called on multiple threads. + + + + + Equivalent to collection.Select(func).ToArray(), but more efficient as it makes + use of the input collection's known size. + + + + + Equivalent to collection.Select(func).ToImmutableArray(), but more efficient as it makes + use of the input collection's known size. + + + + + Equivalent to collection.Select(func).ToArray(), but more efficient as it makes + use of the input collection's known size. + + + + + Equivalent to collection.Select(func).ToArray(), but more efficient as it makes + use of the input collection's known size. + + + + + Equivalent to collection.Select(func).ToArray(), but more efficient as it makes + use of the input collection's known size. + + + + + Equivalent to collection.Select(func).ToList(), but more efficient as it makes + use of the input collection's known size. + + + + + The merge step of merge sort. + + + + + Returns the minimum element. + + The input sequence is empty + + + + Returns the minimum element. + + The input sequence is empty + + + + Returns the maximum element. + + The input sequence is empty + + + + Returns the maximum element. + + The input sequence is empty + + + + Improved version of BitArray + + + + + Creates a new bitset, where initially all bits are zero. + + + + + Gets whether at least one bit is set. + + + + + Gets whether all bits in the specified range are set. + + + + + Gets whether both bitsets have the same content. + + + + + Gets whether this set is a subset of other, or equal. + + + + + Gets whether this set is a superset of other, or equal. + + + + + Gets whether at least one bit is set in both bitsets. + + + + + Sets all bits i; where startIndex <= i < endIndex. + + + + + Clear all bits i; where startIndex <= i < endIndex. + + + + + Static helper method for converting between primitive types. + + + + + Performs a conversion between primitive types. + Unfortunately we cannot use Convert.ChangeType because it has different semantics + (e.g. rounding behavior for floats, overflow, etc.), so we write down every possible primitive C# cast + and let the compiler figure out the exact semantics. + And we have to do everything twice, once in a checked-block, once in an unchecked-block. + + Overflow checking is enabled and an overflow occurred. + The cast is invalid, e.g. casting a boolean to an integer. + + + + Contains extension methods for internal use within the decompiler. + + + + + Depth-first-search of an graph data structure. + The two callbacks (successorFunc + postorderAction) will be called exactly once for each node reachable from startNodes. + + The start nodes. + Called multiple times per node. The first call should return true, subsequent calls must return false. + The first calls to this function occur in pre-order. + If null, normal Equals/GetHashCode will be used to compare nodes. + The function that gets the successors of an element. Called in pre-order. + Called in post-order. + + With reverse_successors=True, the start_nodes and each list of successors will be handled in reverse order. + This is useful if the post-order will be reversed later (e.g. for a topological sort) + so that blocks which could be output in either order (e.g. then-block and else-block of an if) + will maintain the order of the edges (then-block before else-block). + + + + + Represents a half-closed interval. + The start position is inclusive; but the end position is exclusive. + + + Start <= unchecked(End - 1): normal interval + Start == End: empty interval + Special case: Start == End == int.MinValue: interval containing all integers, not an empty interval! + + + + + Gets the inclusive start of the interval. + + + + + Gets the exclusive end of the interval. + + + Note that an End of int.MinValue is a special case, and stands + for an actual End of int.MaxValue+1. + If possible, prefer using InclusiveEnd for comparisons, as that does not have an overflow problem. + + + + + Creates a new interval. + + Start position (inclusive) + End position (exclusive). + Note that it is possible to create an interval that includes int.MaxValue + by using end==int.MaxValue+1==int.MinValue. + + + + Gets the inclusive end of the interval. (End - 1) + For empty intervals, this returns Start - 1. + + + Because there is no empty interval at int.MinValue, + (Start==End==int.MinValue is a special case referring to [int.MinValue..int.MaxValue]), + integer overflow is not a problem here. + + + + + Calculates the intersection between this interval and the other interval. + + + + + Represents a half-closed interval. + The start position is inclusive; but the end position is exclusive. + + + Start <= unchecked(End - 1): normal interval + Start == End: empty interval + Special case: Start == End == long.MinValue: interval containing all integers, not an empty interval! + + + + + Gets the inclusive start of the interval. + + + + + Gets the exclusive end of the interval. + + + Note that an End of long.MinValue is a special case, and stands + for an actual End of long.MaxValue+1. + If possible, prefer using InclusiveEnd for comparisons, as that does not have an overflow problem. + + + + + Creates a new interval. + + Start position (inclusive) + End position (exclusive). + Note that it is possible to create an interval that includes long.MaxValue + by using end==long.MaxValue+1==long.MinValue. + + This method can be used to create an empty interval by specifying start==end, + however this is error-prone due to the special case of + start==end==long.MinValue being interpreted as the full interval [long.MinValue,long.MaxValue]. + + + + + Creates a new interval from start to end. + Unlike the constructor where the end position is exclusive, + this method interprets the end position as inclusive. + + This method cannot be used to construct an empty interval. + + + + + Gets the inclusive end of the interval. (End - 1) + For empty intervals, this returns Start - 1. + + + Because there is no empty interval at int.MinValue, + (Start==End==int.MinValue is a special case referring to [int.MinValue..int.MaxValue]), + integer overflow is not a problem here. + + + + + Calculates the intersection between this interval and the other interval. + + + + + Returns an enumerator over all values in this interval. + + + + + Atomically performs the following operation: + - If target is null: stores newValue in target and returns newValue. + - If target is not null: returns target. + + + + + An immutable set of longs, that is implemented as a list of intervals. + + + + + The intervals in this set of longs. + + + Invariant: the intervals in this array are non-empty, non-overlapping, non-touching, and sorted. + + This invariant ensures every LongSet is always in a normalized representation. + + + + + Create a new LongSet that contains a single value. + + + + + Create a new LongSet that contains the values from the interval. + + + + + Creates a new LongSet the contains the values from the specified intervals. + + + + + The empty LongSet. + + + + + The LongSet that contains all possible long values. + + + + + Gets the number of values in this LongSet. + Note: for LongSet.Universe, the number of values does not fit into ulong. + Instead, this property returns the off-by-one value ulong.MaxValue to avoid overflow. + + + + + Given an enumerable of non-empty intervals sorted by the starting position, + merges overlapping or touching intervals to create a valid interval array for LongSet. + + + + + Creates a new LongSet where val is added to each element of this LongSet. + + + + + Creates a new set that contains all values that are in this, but not in other. + + + + + Creates a new LongSet that contains all elements not contained in this LongSet. + + + + + Gets whether this set is a subset of other, or equal. + + + + + Gets whether this set is a superset of other, or equal. + + + + + A dictionary that allows multiple pairs with the same key. + + + + + Removes all entries with the specified key. + + Returns true if at least one entry was removed. + + + + Returns the number of different keys. + + + + + Platform-specific code. + + + + + Static helper methods for traversing trees. + + + + + Converts a tree data structure into a flat list by traversing it in pre-order. + + The root element of the tree. + The function that gets the children of an element. + Iterator that enumerates the tree structure in pre-order. + + + + Converts a tree data structure into a flat list by traversing it in pre-order. + + The root elements of the forest. + The function that gets the children of an element. + Iterator that enumerates the tree structure in pre-order. + + + + Converts a tree data structure into a flat list by traversing it in post-order. + + The root element of the tree. + The function that gets the children of an element. + Iterator that enumerates the tree structure in post-order. + + + + Converts a tree data structure into a flat list by traversing it in post-order. + + The root elements of the forest. + The function that gets the children of an element. + Iterator that enumerates the tree structure in post-order. + + + + Union-Find data structure. + + + + + Represents win32 resources + + + + + Reads win32 resource root directory + + + + + + + Represents the implicitly-typed "out var". + Special-cased in overload resolution to be compatible with any out-parameter. + + + + + Type of the variable originally used in IL. It will be used, if "out var" cannot be used. + + + + + Resolve result for a C# 7 tuple literal. + + + + + Represents an ambiguous type resolve result. + + + + + Represents an ambiguous field/property/event access. + + + + + Resolve result representing an array access. + + + + + Resolve result representing an array creation. + + + + + Gets the size arguments. + + + + + Gets the initializer elements. + This field may be null if no initializer was specified. + + + + + Represents the resolve result of an 'ref x', 'in x' or 'out x' expression. + + + + + Should only be used for temporary ResolveResults in TypeInference and CSharpConversions, etc. + + + + + ResolveResult representing a compile-time constant. + Note: this class is mainly used for literals; there may be other ResolveResult classes + which are compile-time constants as well. + For example, a reference to a const field results in a . + + Check to determine is a resolve result is a constant. + + + + + Holds information about a conversion between two types. + + + + + Not a valid conversion. + + + + + Identity conversion. + + + + + The numeric conversion of a constant expression. + + + + + C# 'as' cast. + + + + + C# 6 string interpolation expression implicitly being converted to or . + + + + + C# 7 throw expression being converted to an arbitrary type. + + + + + C# 12 inline array implicitly being converted to or . + + + + + C# 14 implicit span conversion from an array type to or . + + + + + Gets whether the conversion is valid. + + + + + Gets whether the conversion is an 'as' cast. + + + + + Gets whether this conversion is a lifted version of another conversion. + + + + + Gets whether the conversion is dynamic. + + + + + Gets whether the conversion is a reference conversion. + + + + + Gets whether the conversion is an enumeration conversion. + + + + + Gets whether the conversion is a nullable conversion + (conversion between a nullable type and the regular type). + + + + + Gets whether this conversion is user-defined (op_Implicit or op_Explicit). + + + + + The conversion that is applied to the input before the user-defined conversion operator is invoked. + + + + + The conversion that is applied to the result of the user-defined conversion operator. + + + + + Gets whether this conversion is a boxing conversion. + + + + + Gets whether this conversion is an unboxing conversion. + + + + + Gets whether this conversion is a pointer conversion. + + + + + Gets whether this conversion is a method group conversion. + + + + + For method-group conversions, gets whether to perform a virtual method lookup at runtime. + + + + + For method-group conversions, gets whether the conversion captures the first argument. + + For instance methods, this property always returns true for C# method-group conversions. + For static methods, this property returns true for method-group conversions of an extension method performed on an instance (eg. Func<int> f = myEnumerable.Single). + + + + + Gets whether this conversion is an anonymous function conversion. + + + + + Gets the method associated with this conversion. + For user-defined conversions, this is the method being called. + For method-group conversions, this is the method that was chosen from the group. + + + + + Gets whether this conversion is a tuple conversion. + + + + + Gets whether this is an interpolated string conversion to or . + + + + + Gets whether this is an inline array conversion to or . + + + + + Gets whether this is an implicit span conversion from an array type to or . + + + + + For a tuple conversion, gets the individual tuple element conversions. + + + + + Represents an implicit or explicit type conversion. + conversionResolveResult.Input.Type is the source type; + conversionResolveResult.Type is the target type. + The property provides details about the kind of conversion. + + + + + For numeric conversions, specifies whether overflow checking is enabled. + + + + + Represents a resolve error. + + Note: some errors are represented by other classes; for example a may + be erroneous if the conversion is invalid. + + . + + + + Gets an ErrorResolveResult instance with Type = SpecialType.UnknownType. + + + + + Resolve result representing a 'foreach' loop. + + + + + Gets the semantic tree for the call to GetEnumerator. + + + + + Gets the collection type. + + + + + Gets the enumerator type. + + + + + Gets the element type. + This is the type that would be inferred for an implicitly-typed element variable. + For explicitly-typed element variables, this type may differ from ElementVariable.Type. + + + + + Gets the Current property on the IEnumerator. + Returns null if the property is not found. + + + + + Gets the MoveNext() method on the IEnumerator. + Returns null if the method is not found. + + + + + Refers to the object that is currently being initialized. + Used within . + + + + + Represents the result of a method, constructor or indexer invocation. + + + + + Gets the arguments that are being passed to the method, in the order the arguments are being evaluated. + + + + + Gets the list of initializer statements that are appplied to the result of this invocation. + This is used to represent object and collection initializers. + With the initializer statements, the is used + to refer to the result of this invocation. + + + + + Gets the arguments in the order they are being passed to the method. + For parameter arrays (params), this will return an ArrayCreateResolveResult. + + + + + Represents a local variable or parameter. + + + + + Represents the result of a member invocation. + Used for field/property/event access. + Also, derives from MemberResolveResult. + + + + + Gets the member. + This property never returns null. + + + + + Gets whether this MemberResolveResult is a virtual call. + + + + + Represents a named argument. + + + + + Gets the member to which the parameter belongs. + This field can be null. + + + + + Gets the parameter. + This field can be null. + + + + + Gets the parameter name. + + + + + Gets the argument passed to the parameter. + + + + + Represents that an expression resolved to a namespace. + + + + + Represents a unary/binary/ternary operator invocation. + + + + + Gets the operator type. + + + + + Gets the operands. + + + + + Gets the user defined operator method. + Returns null if this is a predefined operator. + + + + + Gets whether this is a lifted operator. + + + + + Represents the result of resolving an expression. + + + + + Represents the 'sizeof'. + + + + + The type referenced by the 'sizeof'. + + + + + Represents the 'this' reference. + Also used for the 'base' reference. + + + + + Gets whether this resolve result causes member invocations to be non-virtual. + + + + + Resolve result for a C# 'is' expression. + "Input is TargetType". + + + + + Type that is being compared with. + + + + + Represents the 'typeof'. + + + + + The type referenced by the 'typeof'. + + + + + The resolved expression refers to a type name. + + + + + Represents an unknown member. + + + + + The type on which the method is being called. + + + + + Represents an unknown method. + + + + + Represents an unknown identifier. + + + + + Class for dealing with .NET 5 single-file bundles. + + Based on code from Microsoft.NET.HostModel. + + + + + Check if the memory-mapped data is a single-file bundle + + + + + FileType: Identifies the type of file embedded into the bundle. + + The bundler differentiates a few kinds of files via the manifest, + with respect to the way in which they'll be used by the runtime. + + + + + Reads the manifest header from the memory mapping. + + + + + Reads the manifest header from the stream. + + + + + A container class that holds platform and GUID information about a Visual Studio project. + + + + + Initializes a new instance of the class. + + The project platform. + The project GUID. + + Thrown when is null or empty. + + + + Gets the GUID of this project. + This is usually a newly generated GUID for each decompiled project. + + + + + Gets the primary type GUID of this project. + This is one of the GUIDs from . + + + + + Gets the platform name of this project. Only single platform per project is supported. + + + + + A container class that holds information about a Visual Studio project. + + + + + Initializes a new instance of the class. + + The full path of the project file. + The project platform. + The project GUID. + + Thrown when + or is null or empty. + + + + Gets the name of the project. + + + + + Gets the full path to the project file. + + + + + A helper class that can write a Visual Studio Solution file for the provided projects. + + + + + Writes a solution file to the specified . + Also fixes intra-solution project references in the project files. + + The full path of the file to write. + The projects contained in this solution. + + Thrown when is null or empty. + Thrown when is null. + Thrown when contains no items. + + + + Description of DecompilerException. + + + + + Settings for the decompiler. + + + + + Equivalent to new DecompilerSettings(LanguageVersion.Latest) + + + + + Creates a new DecompilerSettings instance with initial settings + appropriate for the specified language version. + + + This does not imply that the resulting code strictly uses only language features from + that version. Language constructs like generics or ref locals cannot be removed from + the compiled code. + + + + + Deactivates all language features from versions newer than . + + + + + Use C# 9 nint/nuint types. + + + + + Treat IntPtr/UIntPtr as nint/nuint. + + + + + Decompile C# 9 covariant return types. + + + + + Use C# 9 init; property accessors. + + + + + Use C# 9 record classes. + + + + + Use C# 10 record structs. + + + + + Use field initializers in structs. + + + + + Use C# 9 with initializer expressions. + + + + + Use primary constructor syntax with records. + + + + + Use C# 9 delegate* unmanaged types. + If this option is disabled, function pointers will instead be decompiled with type `IntPtr`. + + + + + Use C# 11 scoped modifier. + + + + + Use C# 11 required modifier. + + + + + Use C# 8 switch expressions. + + + + + Use C# 10 file-scoped namespaces. + + + + + Decompile anonymous methods/lambdas. + + + + + Decompile anonymous types. + + + + + Use C# 3 lambda syntax if possible. + + + + + Decompile expression trees. + + + + + Decompile enumerators. + + + + + Decompile use of the 'dynamic' type. + + + + + Decompile async methods. + + + + + Decompile await in catch/finally blocks. + Only has an effect if is enabled. + + + + + Decompile IAsyncEnumerator/IAsyncEnumerable. + Only has an effect if is enabled. + + + + + Decompile [DecimalConstant(...)] as simple literal values. + + + + + Decompile C# 1.0 'public unsafe fixed int arr[10];' members. + + + + + Decompile 'string.Concat(a, b)' calls into 'a + b'. + + + + + Use lifted operators for nullables. + + + + + Decompile C# 6 ?. and ?[] operators. + + + + + Decompile automatic properties + + + + + Decompile getter-only automatic properties + + + + + Decompile automatic events + + + + + Decompile using statements. + + + + + Use enhanced using statements. + + + + + Gets/Sets whether to use braces for single-statement-blocks. + + + + + Decompile foreach statements. + + + + + Support GetEnumerator extension methods in foreach. + + + + + Support params collections. + + + + + Decompile lock statements. + + + + + Gets/Sets whether to use C# 2.0 method group conversions. + true: EventHandler h = this.OnClick; + false: EventHandler h = new EventHandler(this.OnClick); + + + + + Gets/Sets whether to use object creation expressions for generic types with new() constraint. + true: T t = new T(); + false: T t = Activator.CreateInstance<T>() + + + + + Gets/Sets whether to always cast targets to explicitly implemented methods. + true: ((ISupportInitialize)pictureBox1).BeginInit(); + false: pictureBox1.BeginInit(); + default: false + + + + + Gets/Sets whether to always qualify member references. + true: this.DoSomething(); + false: DoSomething(); + default: false + + + + + Gets/Sets whether to always show enum member values. + true: enum Kind { A = 0, B = 1, C = 5 } + false: enum Kind { A, B, C = 5 } + default: false + + + + + Gets/Sets whether to use variable names from debug symbols, if available. + + + + + Gets/Sets whether to use array initializers. + If set to false, might produce non-compilable code. + + + + + Gets/Sets whether to use C# 3.0 object/collection initializers. + + + + + Gets/Sets whether to use C# 6.0 dictionary initializers. + Only has an effect if ObjectOrCollectionInitializers is enabled. + + + + + Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers. + Only has an effect if ObjectOrCollectionInitializers is enabled. + + + + + Gets/Sets whether to use local ref variables in cases where this is necessary + for re-compilation with a modern C# compiler to reproduce the same behavior + as the original assembly produced with an old C# compiler that used an incorrect + order of evaluation. + See https://github.com/icsharpcode/ILSpy/issues/2050 + + + + + Gets/Sets whether to use C# 7.2 'ref' extension methods. + + + + + Gets/Sets whether to use C# 6.0 string interpolation + + + + + Gets/Sets whether to use C# 11.0 UTF-8 string literals + + + + + Gets/Sets whether to use C# 11.0 switch on (ReadOnly)Span<char> + + + + + Gets/Sets whether to use C# 11.0 unsigned right shift operator. + + + + + Gets/Sets whether to use C# 11.0 user-defined checked operators. + + + + + Gets/Sets whether to include XML documentation comments in the decompiled code. + + + + + Gets/Sets whether member bodies should be decompiled. + + + + + Gets/Sets whether simple calculated getter-only property declarations + should use expression body syntax. + + + + + Gets/Sets whether out variable declarations should be used when possible. + + + + + Gets/Sets whether discards should be used when possible. + Only has an effect if is enabled. + + + + + Gets/Sets whether IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs. + + + + + Gets/Sets whether IsReadOnlyAttribute should be replaced with 'readonly' modifiers on structs + and with the 'in' modifier on parameters. + + + + + Gets/Sets whether "private protected" should be used. + + + + + If this option is active, [IsUnmanagedAttribute] on type parameters + is replaced with "T : unmanaged" constraints. + + + + + Gets/Sets whether C# 7.3 stackalloc initializers should be used. + + + + + Gets/Sets whether C# 7.3 pattern based fixed statement should be used. + + + + + Gets/Sets whether tuple type syntax (int, string) + should be used for System.ValueTuple. + + + + + Gets/Sets whether throw expressions should be used. + + + + + Gets/Sets whether implicit conversions between tuples + should be used in the decompiled output. + + + + + Gets/Sets whether tuple comparisons should be detected. + + + + + Gets/Sets whether named arguments should be used. + + + + + Gets/Sets whether C# 7.2 non-trailing named arguments should be used. + + + + + Gets/Sets whether optional arguments should be removed, if possible. + + + + + Gets/Sets whether to expand params arguments by replacing explicit array creation + with individual values in method calls. + + + + + Gets/Sets whether C# 7.0 local functions should be transformed. + + + + + Gets/Sets whether C# 7.0 deconstruction should be detected. + + + + + Gets/Sets whether C# 7.0 pattern matching should be detected. + + + + + Gets/Sets whether C# 8.0 recursive patterns should be detected. + + + + + Gets/Sets whether C# 9.0 and, or, not patterns should be detected. + + + + + Gets/Sets whether C# 9.0 relational patterns should be detected. + + + + + Gets/Sets whether C# 8.0 static local functions should be transformed. + + + + + Gets/Sets whether C# 8.0 index and range syntax should be used. + + + + + Gets/Sets whether C# 8.0 nullable reference types are enabled. + + + + + Gets/Sets whether the decompiler can assume that 'ldlen; conv.i4.ovf' + does not throw an overflow exception. + + + + + Gets/Sets whether to use increment and decrement operators + + + + + Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ; + + + + + Gets/sets whether the decompiler should produce for loops. + + + + + Gets/sets whether the decompiler should produce do-while loops. + + + + + Gets/sets whether RequiresLocationAttribute on parameters should be replaced with 'ref readonly' modifiers. + + + + + Use primary constructor syntax with classes and structs. + + + + + Gets/Sets whether C# 12.0 inline array uses should be transformed. + + + + + Gets/Sets whether C# 14.0 extension members should be transformed. + + + + + Gets/Sets whether (ReadOnly)Span<T> should be treated like built-in types. + + + + + Gets/sets whether the decompiler should separate local variable declarations + from their initialization. + + + + + Gets or sets a value indicating whether the new SDK style format + shall be used for the generated project files. + + + + + Gets/sets whether namespaces and namespace-like identifiers should be split at '.' + and each part should produce a new level of nesting in the output directory structure. + + + + + If set to false (the default), the decompiler will inline local variables only when they occur + in a context where the C# compiler is known to emit compiler-generated locals. + If set to true, the decompiler will inline local variables whenever possible. + + + + + Always fully qualify namespaces using the "global::" prefix. + + + + + If set to false (the default), the decompiler will move field initializers at the start of constructors + to their respective field declarations (TransformFieldAndConstructorInitializers) only when the declaring + type has BeforeFieldInit or the member IsConst. + If set true, the decompiler will always move them regardless of the flags. + + + + + Sort custom attributes. + + + + + Check for overflow and underflow in operators. + + + + + Gets the type of the attribute. + + + + + Represents a block in the control flow graph. + + + + + User index, can be used to look up additional information in an array. + + + + + User data. + + + + + Visited flag, used in various algorithms. + + + + + Gets the node index in a post-order traversal of the control flow graph, starting at the + entry point. This field gets computed by dominance analysis. + + + + + Gets whether this node is reachable. Requires that dominance is computed! + + + + + Gets the immediate dominator (the parent in the dominator tree). + Null if dominance has not been calculated; or if the node is unreachable. + + + + + List of children in the dominator tree. + Null if dominance has not been calculated; or if the node is unreachable. + + + + + List of incoming control flow edges. + + + + + List of outgoing control flow edges. + + + + + Gets whether this dominates . + + + + + Interface for use with DataFlowVisitor. + + A mutable container for the state tracked by the data flow analysis. + + + States must form a join-semilattice: https://en.wikipedia.org/wiki/Semilattice + + To handle try{} finally{} properly, states should implement MeetWith() as well, + and thus should form a lattice. + + DataFlowVisitor expects the state to behave like a mutable reference type. + It might still be a good idea to use a struct to implement it so that .NET uses static dispatch for + method calls on the type parameter, but that struct must consist only of a readonly field + referencing some mutable object, to ensure the type parameter behaves as it if was a mutable reference type. + + + + + Gets whether this state is "less than" (or equal to) another state. + This is the partial order of the semi-lattice. + + + The exact meaning of this relation is up to the concrete implementation, + but usually "less than" means "has less information than". + A given position in the code starts at the "bottom state" (=no information) + and then adds more information as the analysis progresses. + After each change to the state, the old state must be less than the new state, + so that the analysis does not run into an infinite loop. + The partially ordered set must also have finite height (no infinite ascending chains s1 < s2 < ...), + to ensure the analysis terminates. + + + The simplest possible non-trivial state, bool isReachable, would implement LessThanOrEqual as: + return (this.isReachable ? 1 : 0) <= (otherState.isReachable ? 1 : 0); + Which can be simpified to: + return !this.isReachable || otherState.isReachable; + + + + + Creates a new object with a copy of the state. + + + Mutating methods such as ReplaceWith or JoinWith modify the contents of a state object. + Cloning the object allows the analysis to track multiple independent states, + such as the + + + The simple state "bool isReachable", would implement Clone as: + return new MyState(this.isReachable); + + + + + Replace the contents of this state object with a copy of those in . + + + x = x.Clone(); x.ReplaceWith(newContent); + is equivalent to + x = newContent.Clone(); + + ReplaceWith() is used to avoid allocating new state objects where possible. + + + The simple state "bool isReachable", would implement ReplaceWith as: + this.isReachable = newContent.isReachable; + + + + + Join the incomingState into this state. + + + Postcondition: old(this).LessThanOrEqual(this) && incomingState.LessThanOrEqual(this) + This method should set this to the smallest state that is greater than (or equal to) + both input states. + + JoinWith() is used when multiple control flow paths are joined together. + For example, it is used to combine the thenState with the elseState + at the end of a if-else construct. + + + The simple state "bool isReachable", would implement JoinWith as: + this.isReachable |= incomingState.isReachable; + + + + + A special operation to merge the end-state of the finally-block with the end state of + a branch leaving the try-block. + + If either input state is unreachable, this call must result in an unreachable state. + + + The simple state "bool isReachable", would implement TriggerFinally as: + this.isReachable &= finallyState.isReachable; + + + + + Gets whether this is the bottom state. + + The bottom state represents that the data flow analysis has not yet + found a code path from the entry point to this state's position. + It thus contains no information, and is "less than" all other states. + + + The bottom state is the bottom element in the semi-lattice. + + Initially, all code blocks not yet visited by the analysis will be in the bottom state. + Unreachable code will always remain in the bottom state. + Some analyses may also use the bottom state for reachable code after it was processed by the analysis. + For example, in DefiniteAssignmentVisitor the bottom states means + "either this code is unreachable, or all variables are definitely initialized". + + + The simple state "bool isReachable", would implement IsBottom as: + return !this.isReachable; + + + + + Equivalent to this.ReplaceWith(bottomState), but may be implemented more efficiently. + + + Since the DataFlowVisitor can only create states by cloning from the initial state, + this method is necessary for the DataFlowVisitor to gain access to the bottom element in + the first place. + + + The simple state "bool isReachable", would implement ReplaceWithBottom as: + this.isReachable = false; + + + + + Generic base class for forward data flow analyses. + + + The state type used for the data flow analysis. See for details. + + + + + The bottom state. + Must not be mutated. + + + + + Current state. + + Caution: any state object assigned to this member gets mutated as the visitor traverses the ILAst! + + + + + Combined state of all possible exceptional control flow paths in the current try block. + Serves as input state for catch blocks. + + Caution: any state object assigned to this member gets mutated as the visitor encounters instructions that may throw exceptions! + + Within a try block, currentStateOnException == stateOnException[tryBlock.Parent]. + + + + + + Initializes the DataFlowVisitor. + This method must be called once before any Visit()-methods can be called. + It must not be called more than once. + + The initial state at the entry point of the analysis. + + This is a method instead of a constructor because derived classes might need complex initialization + before they can construct the initial state. + + + + + Derived classes may add to this set of flags to ensure they don't forget to override an interesting method. + + + + + Handle control flow when the current instruction throws an exception: + joins the current state into the "exception state" of the current try block. + + + This should not only be called for instructions that may throw an exception, + but for all instructions (due to async exceptions like ThreadAbortException)! + + To avoid redundant calls, every Visit() call may assume that the current state + is already propagated, and has to guarantee the same at the end. + This means this method should be called after every state change. + Alternatively, derived classes may directly modify both state + and currentStateOnException, so that a full JoinWith() call + is not necessary. + + + + + Replace the current state with the bottom state. + + + + + Holds the state for incoming branches. + + + Only used for blocks in block containers; not for inline blocks. + + + + + Holds the state at the block container end-point. (=state for incoming 'leave' instructions) + + + + + Gets the state object that holds the state for incoming branches to the block. + + + Returns the a clone of the bottom state on the first call for a given block, + then returns the same object instance on further calls. + The caller is expected to mutate the returned state by calling JoinWith(). + + + + + For each block container, stores the set of blocks (via Block.ChildIndex) + that had their incoming state changed and were not processed yet. + + + + + Stores the stateOnException per try instruction. + + + + + Visits the TryBlock. + + Returns a new State object representing the exceptional control flow transfer out of the try block. + + + + + TryCatchHandler is handled directly in VisitTryCatch + + + + + Process branches leaving the try-finally, + * Calls TriggerFinally() on each branchesTriggeringFinally + * Removes entries from branchesTriggeringFinally if they won't trigger additional finally blocks. + * After all finallies are applied, the branch state is merged into the target block. + + + + + Evaluates the condition of an if. + + + A pair of: + * The state after the condition evaluates to true + * The state after the condition evaluates to false + + + this.state is invalid after this function was called, and must be overwritten + with one of the return values. + + + + + Evaluates a match instruction. + + + A pair of: + * The state after the pattern matches + * The state after the pattern fails to match + + + this.state is invalid after this function was called, and must be overwritten + with one of the return values. + + + + + DataFlowVisitor that performs definite assignment analysis. + + + + + State for definite assignment analysis. + + + + + bits[i]: There is a code path from the entry point to this state's position + that does not write to function.Variables[i]. + (i.e. the variable is not definitely assigned at the state's position) + + Initial state: all bits set = nothing is definitely assigned + Bottom state: all bits clear + + + + + Creates the initial state. + + + + + For a use of a local function, remember the current state to use as stateOnEntry when + later processing the local function body. + + + + + Description of Dominance. + + + + + Computes the dominator tree. + + + Precondition: the dominance tree is not already computed for some nodes reachable from entryPoint + (i.e. ImmediateDominator and DominatorTreeChildren are both null), + and the visited flag is false for any nodes reachable from entryPoint. + + Postcondition: a dominator tree is constructed for all nodes reachable from entryPoint, + and the visited flag remains false. + + + + + Returns the common ancestor of a and b in the dominator tree. + + Precondition: a and b are part of the same dominator tree. + + + + + Computes a BitSet where + result[i] == true iff cfg[i] is reachable and there is some node that is + reachable from cfg[i] but not dominated by cfg[i]. + + This is similar to "does cfg[i] have a non-empty dominance frontier?", + except that it uses non-strict dominance where the definition of dominance frontiers + uses "strictly dominates". + + Precondition: + Dominance was computed for cfg and cfg[i].UserIndex == i for all i. + + + + + Implements the "reaching definitions" analysis. + + https://en.wikipedia.org/wiki/Reaching_definition + + By "definitions", we mean stores to local variables. + + + Possible "definitions" that store to a variable are: + * StLoc + * TryCatchHandler (for the exception variable) + * ReachingDefinitionsVisitor.UninitializedVariable for uninitialized variables. + Note that we do not keep track of LdLoca/references/pointers. + The analysis will likely be wrong/incomplete for variables with AddressCount != 0. + + Note: this class does not store the computed information, because doing so + would significantly increase the number of states we need to store. + The only way to get the computed information out of this class is to + derive from the class and override the Visit methods at the points of interest + (usually the load instructions). + + + + + The state during the reaching definitions analysis. + + + A state can either be reachable, or unreachable: + 1) unreachable + Note that during the analysis, "unreachable" just means we have not yet found a path + from the entry point to the node. States transition from unreachable to reachable as + the analysis processes more control flow paths. + 2) reachable + In this case, the state contains, for each variable, the set of stores that might have + written to the variable before the control flow reached the state's source code position. + This set does not include stores that were definitely overwritten by other stores to the + same variable. + During the analysis, the set of stores gets extended as the analysis processes more code paths. + + The reachable state could be represented as a `Dictionary{ILVariable, ISet{ILInstruction}}`. + To consume less memory, we instead assign an integer index to all stores in the analyzed function ("store index"), + and store the state as a `BitSet` instead. + Each bit in the set corresponds to one store instruction, and is `true` iff the store is a reaching definition + for the variable it is storing to. + The `allStores` array has the same length as the bit sets and holds the corresponding `ILInstruction` objects (store instructions). + All stores for a single variable occupy a contiguous segment of the `allStores` array (and thus also of the `state`), + which allows us to efficient clear out all stores that get overwritten by a new store. + + + + + This bitset contains three different kinds of bits: + Reachable bit: (bit 0) + This state's position is reachable from the entry point. + + Reaching uninitialized variable bit: (bit si, where si > 0 and allStores[si] == null) + There is a code path from the scope's entry point to this state's position + that does not pass through any store to the variable. + + firstStoreIndexForVariable[v.IndexInScope] gives the index of that variable's uninitialized bit. + + Reaching store bit (bit si, where allStores[si] != null): + There is a code path from the entry point to this state's position + that passes through through allStores[si] and does not pass through another + store to allStores[si].Variable. + + The indices for a variable's reaching store bits are between firstStoreIndexForVariable[v.IndexInScope] + to firstStoreIndexForVariable[v.IndexInScope + 1] (both endpoints exclusive!). + + + The initial state has the "reachable bit" and the "reaching uninitialized variable bits" set, + and the "reaching store bits" unset. + + The bottom state has all bits unset. + + + + + Clears all store bits between startStoreIndex (incl.) and endStoreIndex (excl.) + + + + + To distinguish unreachable from reachable states, we use the first bit in the bitset to store the 'reachable bit'. + If this bit is set, the state is reachable, and the remaining bits + + + + + Because bit number 0 is the ReachableBit, we start counting store indices at 1. + + + + + The function being analyzed. + + + + + All stores for all variables in the scope. + + state[storeIndex] is true iff allStores[storeIndex] is a reaching definition. + Invariant: state.bits.Length == allStores.Length. + + + + + Maps instructions appearing in allStores to their index. + + Invariant: allStores[storeIndexMap[inst]] == inst + + Does not contain UninitializedVariable (as that special instruction has multiple store indices, one per variable) + + + + + For all variables v: allStores[firstStoreIndexForVariable[v.IndexInScope]] is the UninitializedVariable entry for v. + The next few stores (up to firstStoreIndexForVariable[v.IndexInScope + 1], exclusive) are the full list of stores for v. + + + Invariant: firstStoreIndexForVariable[scope.Variables.Count] == allStores.Length + + + + + analyzedVariables[v.IndexInScope] is true iff RD analysis is enabled for the variable. + + + + + Prepare reaching definitions analysis for the specified variable scope. + + The analysis will track all variables in the scope for which the predicate returns true + ("analyzed variables"). + + + + + Prepare reaching definitions analysis for the specified variable scope. + + The analysis will track all variables in the scope for which analyzedVariables[v.IndexInScope] is true. + + + + + Fill allStores and storeIndexMap. + + + + + Create the initial state (reachable bit + uninit variable bits set, store bits unset). + + + + + Gets all stores to v that reach the specified state. + + Precondition: v is an analyzed variable. + + + + + Gets whether v is potentially uninitialized in the specified state. + + Precondition: v is an analyzed variable. + + + + + Convert only the name. + + + + + Show the parameter list + + + + + Show names for parameters + + + + + Show the accessibility (private, public, etc.) + + + + + Show the definition key word (class, struct, Sub, Function, etc.) + + + + + Show the declaring type for the type or member + + + + + Show modifiers (virtual, override, etc.) + + + + + Show the return type + + + + + Use fully qualified names for types. + + + + + Show the list of type parameters on method and class declarations. + Type arguments for parameter/return types are always shown. + + + + + For fields, events and methods: adds a semicolon at the end. + For properties: shows "{ get; }" or similar. + + + + + Use fully qualified names for members. + + + + + Instead of placing the return type before the entity name, + append it after the parameter list, preceeded by a colon. + + + + + Show the variance modifier of the type parameter. + If active, shows 'Func<in T, out TResult>' instead of 'Func<T, TResult>'. + + + + + Show modifiers of parameters, e.g. 'this', 'params', 'ref', 'out' and 'in'. + + + + + Show default values of parameters. + + + + + Use T? instead of Nullable<T>. + + + + + Support init accessors. + + + + + Support record classes. + + + + + Support record structs. + + + + + Support >>> as unsigned right shift operator. + + + + + Support C# 11 operator checked. + + + + + Support C# 7.2 private protected. + + + + + Support C# 14 extension declarations. + + + + + Ambiences are used to convert type system symbols to text (usually for displaying the symbol to the user; e.g. in editor tooltips). + + + + + Contains extension methods for humanizing string values. + + + + + Container for registered Vocabularies. At present, only a single vocabulary is supported: Default. + + + + + The default vocabulary used for singular/plural irregularities. + Rules can be added to this vocabulary and will be picked up by called to Singularize() and Pluralize(). + At this time, multiple vocabularies and removing existing rules are not supported. + + + + + A container for exceptions to simple pluralization/singularization rules. + Vocabularies.Default contains an extensive list of rules for US English. + At this time, multiple vocabularies and removing existing rules are not supported. + + + + + Adds a word to the vocabulary which cannot easily be pluralized/singularized by RegEx, e.g. "person" and "people". + + The singular form of the irregular word, e.g. "person". + The plural form of the irregular word, e.g. "people". + True to match these words on their own as well as at the end of longer words. False, otherwise. + + + + Adds an uncountable word to the vocabulary, e.g. "fish". Will be ignored when plurality is changed. + + Word to be added to the list of uncountables. + + + + Adds a rule to the vocabulary that does not follow trivial rules for pluralization, e.g. "bus" -> "buses" + + RegEx to be matched, case insensitive, e.g. "(bus)es$" + RegEx replacement e.g. "$1" + + + + Adds a rule to the vocabulary that does not follow trivial rules for singularization, e.g. "vertices/indices -> "vertex/index" + + RegEx to be matched, case insensitive, e.g. ""(vert|ind)ices$"" + RegEx replacement e.g. "$1ex" + + + + Pluralizes the provided input considering irregular words + + Word to be pluralized + Normally you call Pluralize on singular words; but if you're unsure call it with false + + + + Singularizes the provided input considering irregular words + + Word to be singularized + Normally you call Singularize on plural words; but if you're unsure call it with false + Skip singularizing single words that have an 's' on the end + + + + If the word is the letter s, singular or plural, return the letter s singular + + + + Specifies that null is allowed as an input even if the corresponding type disallows it. + + + Specifies that null is disallowed as an input even if the corresponding type allows it. + + + Specifies that an output may be null even if the corresponding type disallows it. + + + Specifies that an output will not be null even if the corresponding type allows it. + + + Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. + + + Initializes the attribute with the specified return value condition. + + The return value condition. If the method returns this value, the associated parameter may be null. + + + + Gets the return value condition. + + + Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + + + Initializes the attribute with the specified return value condition. + + The return value condition. If the method returns this value, the associated parameter will not be null. + + + + Gets the return value condition. + + + Specifies that the output will be non-null if the named parameter is non-null. + + + Initializes the attribute with the associated parameter name. + + The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + + + + Gets the associated parameter name. + + + Applied to a method that will never return under any circumstance. + + + Specifies that the method will not return if the associated Boolean parameter is passed the specified value. + + + Initializes the attribute with the specified parameter value. + + The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + the associated parameter matches this value. + + + + Gets the condition parameter value. + + + Represent a type can be used to index a collection either from the start or the end. + + Index is used by the C# compiler to support the new index syntax + + int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ; + int lastElement = someArray[^1]; // lastElement = 5 + + + + + Construct an Index using a value and indicating if the index is from the start or from the end. + The index value. it has to be zero or positive number. + Indicating if the index is from the start or from the end. + + If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element. + + + + Create an Index pointing at first element. + + + Create an Index pointing at beyond last element. + + + Create an Index from the start at the position indicated by the value. + The index value from the start. + + + Create an Index from the end at the position indicated by the value. + The index value from the end. + + + Returns the index value. + + + Indicates whether the index is from the start or the end. + + + Calculate the offset from the start using the giving collection length. + The length of the collection that the Index will be used with. length has to be a positive value + + For performance reason, we don't validate the input length parameter and the returned offset value against negative values. + we don't validate either the returned offset is greater than the input length. + It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and + then used to index a collection will get out of range exception which will be same affect as the validation. + + + + Indicates whether the current Index object is equal to another object of the same type. + An object to compare with this object + + + Indicates whether the current Index object is equal to another Index object. + An object to compare with this object + + + Returns the hash code for this instance. + + + Converts integer number to an Index. + + + Converts the value of the current Index object to its equivalent string representation. + + + + Represents an ordered collection of JsonValues. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class, adding the given values to the collection. + + The values to be added to this collection. + + + + Gets the number of values in this collection. + + The number of values in this collection. + + + + Gets or sets the value at the given index. + + The zero-based index of the value to get or set. + + The getter will return JsonValue.Null if the given index is out of range. + + + + + Adds the given value to this collection. + + The value to be added. + Returns this collection. + + + + Inserts the given value at the given index in this collection. + + The index where the given value will be inserted. + The value to be inserted into this collection. + Returns this collection. + + + + Removes the value at the given index. + + The index of the value to be removed. + Return this collection. + + + + Clears the contents of this collection. + + Returns this collection. + + + + Determines whether the given item is in the JsonArray. + + The item to locate in the JsonArray. + Returns true if the item is found; otherwise, false. + + + + Determines the index of the given item in this JsonArray. + + The item to locate in this JsonArray. + The index of the item, if found. Otherwise, returns -1. + + + + Returns an enumerator that iterates through the collection. + + The enumerator that iterates through the collection. + + + + Returns an enumerator that iterates through the collection. + + The enumerator that iterates through the collection. + + + + Represents a key-value pair collection of JsonValue objects. + + + + + Initializes a new instance of the class. + + + + + Gets the number of properties in this JsonObject. + + The number of properties in this JsonObject. + + + + Gets or sets the property with the given key. + + The key of the property to get or set. + + The getter will return JsonValue.Null if the given key is not associated with any value. + + + + + Adds a key with a null value to this collection. + + The key of the property to be added. + Returns this JsonObject. + The that was added. + + + + Adds a value associated with a key to this collection. + + The key of the property to be added. + The value of the property to be added. + Returns this JsonObject. + + + + Removes a property with the given key. + + The key of the property to be removed. + + Returns true if the given key is found and removed; otherwise, false. + + + + + Clears the contents of this collection. + + Returns this JsonObject. + + + + Changes the key of one of the items in the collection. + + + This method has no effects if the oldKey does not exists. + If the newKey already exists, the value will be overwritten. + + The name of the key to be changed. + The new name of the key. + Returns this JsonObject. + + + + Determines whether this collection contains an item assosiated with the given key. + + The key to locate in this collection. + Returns true if the key is found; otherwise, false. + + + + Determines whether this collection contains the given JsonValue. + + The value to locate in this collection. + Returns true if the value is found; otherwise, false. + + + + Returns an enumerator that iterates through this collection. + + The enumerator that iterates through this collection. + + + + Returns an enumerator that iterates through this collection. + + The enumerator that iterates through this collection. + + + + Returns an enumerator that iterates through this collection. + + The enumerator that iterates through this collection. + + + + A wrapper object that contains a valid JSON value. + + + + + Represents a null JsonValue. + + + + + Initializes a new instance of the struct, representing a Boolean value. + + The value to be wrapped. + + + + Initializes a new instance of the struct, representing a Number value. + + The value to be wrapped. + + + + Initializes a new instance of the struct, representing a String value. + + The value to be wrapped. + + + + Initializes a new instance of the struct, representing a JsonObject. + + The value to be wrapped. + + + + Initializes a new instance of the struct, representing a Array reference value. + + The value to be wrapped. + + + + Initializes a new instance of the struct. + + The Json type of the JsonValue. + + The internal value of the JsonValue. + This is used when the Json type is Number or Boolean. + + + The internal value reference of the JsonValue. + This value is used when the Json type is String, JsonObject, or JsonArray. + + + + + Gets the type of this JsonValue. + + The type of this JsonValue. + + + + Gets a value indicating whether this JsonValue is Null. + + A value indicating whether this JsonValue is Null. + + + + Gets a value indicating whether this JsonValue is a Boolean. + + A value indicating whether this JsonValue is a Boolean. + + + + Gets a value indicating whether this JsonValue is an Integer. + + A value indicating whether this JsonValue is an Integer. + + + + Gets a value indicating whether this JsonValue is a Number. + + A value indicating whether this JsonValue is a Number. + + + + Gets a value indicating whether this JsonValue is a String. + + A value indicating whether this JsonValue is a String. + + + + Gets a value indicating whether this JsonValue is a JsonObject. + + A value indicating whether this JsonValue is a JsonObject. + + + + Gets a value indicating whether this JsonValue is a JsonArray. + + A value indicating whether this JsonValue is a JsonArray. + + + + Gets a value indicating whether this JsonValue represents a DateTime. + + A value indicating whether this JsonValue represents a DateTime. + + + + Gets a value indicating whether this value is true or false. + + This value as a Boolean type. + + + + Gets this value as an Integer type. + + This value as an Integer type. + + + + Gets this value as a Number type. + + This value as a Number type. + + + + Gets this value as a String type. + + This value as a String type. + + + + Gets this value as an JsonObject. + + This value as an JsonObject. + + + + Gets this value as an JsonArray. + + This value as an JsonArray. + + + + Gets this value as a system.DateTime. + + This value as a system.DateTime. + + + + Gets this (inner) value as a System.object. + + This (inner) value as a System.object. + + + + Gets or sets the value associated with the specified key. + + The key of the value to get or set. + + Thrown when this JsonValue is not a JsonObject. + + + + + Gets or sets the value at the specified index. + + The zero-based index of the value to get or set. + + Thrown when this JsonValue is not a JsonArray + + + + + Converts the given nullable boolean into a JsonValue. + + The value to be converted. + + + + Converts the given nullable double into a JsonValue. + + The value to be converted. + + + + Converts the given string into a JsonValue. + + The value to be converted. + + + + Converts the given JsonObject into a JsonValue. + + The value to be converted. + + + + Converts the given JsonArray into a JsonValue. + + The value to be converted. + + + + Converts the given DateTime? into a JsonValue. + + + The DateTime value will be stored as a string using ISO 8601 format, + since JSON does not define a DateTime type. + + The value to be converted. + + + + Converts the given JsonValue into an Int. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a nullable Int. + + The JsonValue to be converted. + + Throws System.InvalidCastException when the inner value type of the + JsonValue is not the desired type of the conversion. + + + + + Converts the given JsonValue into a Bool. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a nullable Bool. + + The JsonValue to be converted. + + Throws System.InvalidCastException when the inner value type of the + JsonValue is not the desired type of the conversion. + + + + + Converts the given JsonValue into a Double. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a nullable Double. + + The JsonValue to be converted. + + Throws System.InvalidCastException when the inner value type of the + JsonValue is not the desired type of the conversion. + + + + + Converts the given JsonValue into a String. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a JsonObject. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a JsonArray. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a DateTime. + + The JsonValue to be converted. + + + + Converts the given JsonValue into a nullable DateTime. + + The JsonValue to be converted. + + + + Returns a value indicating whether the two given JsonValues are equal. + + First JsonValue to compare. + Second JsonValue to compare. + + + + Returns a value indicating whether the two given JsonValues are unequal. + + First JsonValue to compare. + Second JsonValue to compare. + + + + Returns a JsonValue by parsing the given string. + + The JSON-formatted string to be parsed. + The representing the parsed text. + + + + + + + + + + Enumerates the types of Json values. + + + + + A null value. + + + + + A boolean value. + + + + + A number value. + + + + + A string value. + + + + + An object value. + + + + + An array value. + + + + + The exception that is thrown when a JSON message cannot be parsed. + + + This exception is only intended to be thrown by LightJson. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the given error type and position. + + The error type that describes the cause of the error. + The position in the text where the error occurred. + + + + Initializes a new instance of the class with the given message, error type, and position. + + The message that describes the error. + The error type that describes the cause of the error. + The position in the text where the error occurred. + + + + Enumerates the types of errors that can occur when parsing a JSON message. + + + + + Indicates that the cause of the error is unknown. + + + + + Indicates that the text ended before the message could be parsed. + + + + + Indicates that a JsonObject contains more than one key with the same name. + + + + + Indicates that the parser encountered and invalid or unexpected character. + + + + + Gets the text position where the error occurred. + + The text position where the error occurred. + + + + Gets the type of error that caused the exception to be thrown. + + The type of error that caused the exception to be thrown. + + + + Represents a reader that can read JsonValues. + + + + + Creates a JsonValue by using the given TextReader. + + The TextReader used to read a JSON message. + The parsed . + + + + Creates a JsonValue by reader the JSON message in the given string. + + The string containing the JSON message. + The parsed . + + + + Represents a position within a plain text resource. + + + + + The column position, 0-based. + + + + + The line position, 0-based. + + + + + Represents a text scanner that reads one character at a time. + + + + + Initializes a new instance of the class. + + The TextReader to read the text. + + + + Gets the position of the scanner within the text. + + The position of the scanner within the text. + + + + Reads the next character in the stream without changing the current position. + + The next character in the stream. + + + + Reads the next character in the stream without changing the current position. + + to throw an exception if the end of the file is + reached; otherwise, . + The next character in the stream, or -1 if the end of the file is reached with + set to . + + + + Reads the next character in the stream, advancing the text position. + + The next character in the stream. + + + + Advances the scanner to next non-whitespace character. + + + + + Verifies that the given character matches the next character in the stream. + If the characters do not match, an exception will be thrown. + + The expected character. + + + + Verifies that the given string matches the next characters in the stream. + If the strings do not match, an exception will be thrown. + + The expected string. + +
+
diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.ILSpyX.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.ILSpyX.dll new file mode 100644 index 0000000..856dc9a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ICSharpCode.ILSpyX.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/K4os.Compression.LZ4.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/K4os.Compression.LZ4.dll new file mode 100644 index 0000000..0711563 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/K4os.Compression.LZ4.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/McMaster.Extensions.CommandLineUtils.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/McMaster.Extensions.CommandLineUtils.dll new file mode 100644 index 0000000..08a9234 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/McMaster.Extensions.CommandLineUtils.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/McMaster.Extensions.Hosting.CommandLine.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/McMaster.Extensions.Hosting.CommandLine.dll new file mode 100644 index 0000000..856d61a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/McMaster.Extensions.Hosting.CommandLine.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Abstractions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100644 index 0000000..3b80ff8 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Binder.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Binder.dll new file mode 100644 index 0000000..a9dcffb Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Binder.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.CommandLine.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.CommandLine.dll new file mode 100644 index 0000000..2936d8f Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.CommandLine.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.EnvironmentVariables.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.EnvironmentVariables.dll new file mode 100644 index 0000000..11fa8e9 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.EnvironmentVariables.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.FileExtensions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.FileExtensions.dll new file mode 100644 index 0000000..2c93d62 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.FileExtensions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Json.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Json.dll new file mode 100644 index 0000000..2273fb2 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.Json.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.UserSecrets.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.UserSecrets.dll new file mode 100644 index 0000000..613ab64 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.UserSecrets.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.dll new file mode 100644 index 0000000..f930a29 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Configuration.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100644 index 0000000..c314b33 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.DependencyInjection.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.DependencyInjection.dll new file mode 100644 index 0000000..7bd9d34 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Diagnostics.Abstractions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Diagnostics.Abstractions.dll new file mode 100644 index 0000000..23e524c Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Diagnostics.Abstractions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Diagnostics.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Diagnostics.dll new file mode 100644 index 0000000..c24a2e1 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Diagnostics.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileProviders.Abstractions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileProviders.Abstractions.dll new file mode 100644 index 0000000..761dddc Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileProviders.Abstractions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileProviders.Physical.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileProviders.Physical.dll new file mode 100644 index 0000000..1b1a28a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileProviders.Physical.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileSystemGlobbing.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileSystemGlobbing.dll new file mode 100644 index 0000000..e42ed6a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.FileSystemGlobbing.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Hosting.Abstractions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Hosting.Abstractions.dll new file mode 100644 index 0000000..676458a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Hosting.Abstractions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Hosting.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Hosting.dll new file mode 100644 index 0000000..52ce14c Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Hosting.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Abstractions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Abstractions.dll new file mode 100644 index 0000000..4582072 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Abstractions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Configuration.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Configuration.dll new file mode 100644 index 0000000..8470ce8 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Configuration.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Console.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Console.dll new file mode 100644 index 0000000..a723647 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Console.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Debug.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Debug.dll new file mode 100644 index 0000000..baf50e5 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.Debug.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.EventLog.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.EventLog.dll new file mode 100644 index 0000000..7a11f22 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.EventLog.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.EventSource.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.EventSource.dll new file mode 100644 index 0000000..7d8d742 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.EventSource.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.dll new file mode 100644 index 0000000..4fed9f8 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Logging.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Options.ConfigurationExtensions.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Options.ConfigurationExtensions.dll new file mode 100644 index 0000000..98cff94 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Options.ConfigurationExtensions.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Options.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Options.dll new file mode 100644 index 0000000..260d814 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Options.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Primitives.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Primitives.dll new file mode 100644 index 0000000..faed5d2 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Microsoft.Extensions.Primitives.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Mdb.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Mdb.dll new file mode 100644 index 0000000..55f9ee2 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Mdb.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Pdb.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Pdb.dll new file mode 100644 index 0000000..0462a8f Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Pdb.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Rocks.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Rocks.dll new file mode 100644 index 0000000..561b0d7 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.Rocks.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.dll new file mode 100644 index 0000000..488bd5c Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Mono.Cecil.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Newtonsoft.Json.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Newtonsoft.Json.dll new file mode 100644 index 0000000..d035c38 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/Newtonsoft.Json.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Common.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Common.dll new file mode 100644 index 0000000..86fa402 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Common.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Configuration.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Configuration.dll new file mode 100644 index 0000000..9666b12 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Configuration.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Frameworks.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Frameworks.dll new file mode 100644 index 0000000..f9c1de8 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Frameworks.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Packaging.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Packaging.dll new file mode 100644 index 0000000..9e3f31d Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Packaging.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Protocol.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Protocol.dll new file mode 100644 index 0000000..0d9f87f Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Protocol.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Versioning.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Versioning.dll new file mode 100644 index 0000000..0f2e724 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/NuGet.Versioning.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Composition.AttributedModel.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Composition.AttributedModel.dll new file mode 100644 index 0000000..984850b Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Composition.AttributedModel.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Diagnostics.EventLog.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Diagnostics.EventLog.dll new file mode 100644 index 0000000..55e6b1e Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Diagnostics.EventLog.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Reflection.Metadata.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Reflection.Metadata.dll new file mode 100644 index 0000000..4cc2ae9 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Reflection.Metadata.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Security.Cryptography.Pkcs.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Security.Cryptography.Pkcs.dll new file mode 100644 index 0000000..bb334d3 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Security.Cryptography.Pkcs.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Security.Cryptography.ProtectedData.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Security.Cryptography.ProtectedData.dll new file mode 100644 index 0000000..40f1b5a Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/System.Security.Cryptography.ProtectedData.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.deps.json b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.deps.json new file mode 100644 index 0000000..cfb81af --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.deps.json @@ -0,0 +1,960 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "ilspycmd/1.0.0": { + "dependencies": { + "ICSharpCode.Decompiler": "8.0.0-noversion", + "ICSharpCode.ILSpyX": "8.0.0-noversion", + "McMaster.Extensions.Hosting.CommandLine": "5.1.0", + "Microsoft.Extensions.Hosting": "10.0.6", + "NuGet.Protocol": "7.3.0", + "System.Security.Cryptography.Pkcs": "10.0.6" + }, + "runtime": { + "ilspycmd.dll": {} + } + }, + "K4os.Compression.LZ4/1.3.8": { + "runtime": { + "lib/net6.0/K4os.Compression.LZ4.dll": { + "assemblyVersion": "1.3.8.0", + "fileVersion": "1.3.8.0", + "localPath": "K4os.Compression.LZ4.dll" + } + } + }, + "McMaster.Extensions.CommandLineUtils/5.1.0": { + "runtime": { + "lib/net8.0/McMaster.Extensions.CommandLineUtils.dll": { + "assemblyVersion": "5.1.0.0", + "fileVersion": "5.1.0.0", + "localPath": "McMaster.Extensions.CommandLineUtils.dll" + } + } + }, + "McMaster.Extensions.Hosting.CommandLine/5.1.0": { + "dependencies": { + "McMaster.Extensions.CommandLineUtils": "5.1.0", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net8.0/McMaster.Extensions.Hosting.CommandLine.dll": { + "assemblyVersion": "5.1.0.0", + "fileVersion": "5.1.0.0", + "localPath": "McMaster.Extensions.Hosting.CommandLine.dll" + } + } + }, + "Microsoft.Extensions.Configuration/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.dll" + } + } + }, + "Microsoft.Extensions.Configuration.Abstractions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.Abstractions.dll" + } + } + }, + "Microsoft.Extensions.Configuration.Binder/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.Binder.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.Binder.dll" + } + } + }, + "Microsoft.Extensions.Configuration.CommandLine/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.CommandLine.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.CommandLine.dll" + } + } + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.EnvironmentVariables.dll" + } + } + }, + "Microsoft.Extensions.Configuration.FileExtensions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.6", + "Microsoft.Extensions.FileProviders.Physical": "10.0.6", + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.FileExtensions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.FileExtensions.dll" + } + } + }, + "Microsoft.Extensions.Configuration.Json/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.6", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.Json.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.Json.dll" + } + } + }, + "Microsoft.Extensions.Configuration.UserSecrets/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.Configuration.Json": "10.0.6", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.6", + "Microsoft.Extensions.FileProviders.Physical": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Configuration.UserSecrets.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Configuration.UserSecrets.dll" + } + } + }, + "Microsoft.Extensions.DependencyInjection/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.DependencyInjection.dll" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/10.0.6": { + "runtime": { + "lib/net10.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.DependencyInjection.Abstractions.dll" + } + } + }, + "Microsoft.Extensions.Diagnostics/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.6", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Diagnostics.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Diagnostics.dll" + } + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Diagnostics.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Diagnostics.Abstractions.dll" + } + } + }, + "Microsoft.Extensions.FileProviders.Abstractions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.FileProviders.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.FileProviders.Abstractions.dll" + } + } + }, + "Microsoft.Extensions.FileProviders.Physical/10.0.6": { + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.6", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.6", + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.FileProviders.Physical.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.FileProviders.Physical.dll" + } + } + }, + "Microsoft.Extensions.FileSystemGlobbing/10.0.6": { + "runtime": { + "lib/net10.0/Microsoft.Extensions.FileSystemGlobbing.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.FileSystemGlobbing.dll" + } + } + }, + "Microsoft.Extensions.Hosting/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.Configuration.Binder": "10.0.6", + "Microsoft.Extensions.Configuration.CommandLine": "10.0.6", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.6", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.6", + "Microsoft.Extensions.Configuration.Json": "10.0.6", + "Microsoft.Extensions.Configuration.UserSecrets": "10.0.6", + "Microsoft.Extensions.DependencyInjection": "10.0.6", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Diagnostics": "10.0.6", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.6", + "Microsoft.Extensions.FileProviders.Physical": "10.0.6", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging.Configuration": "10.0.6", + "Microsoft.Extensions.Logging.Console": "10.0.6", + "Microsoft.Extensions.Logging.Debug": "10.0.6", + "Microsoft.Extensions.Logging.EventLog": "10.0.6", + "Microsoft.Extensions.Logging.EventSource": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Hosting.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Hosting.dll" + } + } + }, + "Microsoft.Extensions.Hosting.Abstractions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.6", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Hosting.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Hosting.Abstractions.dll" + } + } + }, + "Microsoft.Extensions.Logging/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.dll" + } + } + }, + "Microsoft.Extensions.Logging.Abstractions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.Abstractions.dll" + } + } + }, + "Microsoft.Extensions.Logging.Configuration/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.6", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.Configuration.Binder": "10.0.6", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.Configuration.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.Configuration.dll" + } + } + }, + "Microsoft.Extensions.Logging.Console/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging.Configuration": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.Console.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.Console.dll" + } + } + }, + "Microsoft.Extensions.Logging.Debug/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.Debug.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.Debug.dll" + } + } + }, + "Microsoft.Extensions.Logging.EventLog/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6", + "System.Diagnostics.EventLog": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.EventLog.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.EventLog.dll" + } + } + }, + "Microsoft.Extensions.Logging.EventSource/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Logging": "10.0.6", + "Microsoft.Extensions.Logging.Abstractions": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6", + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Logging.EventSource.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Logging.EventSource.dll" + } + } + }, + "Microsoft.Extensions.Options/10.0.6": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Options.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Options.dll" + } + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions/10.0.6": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.6", + "Microsoft.Extensions.Configuration.Binder": "10.0.6", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.6", + "Microsoft.Extensions.Options": "10.0.6", + "Microsoft.Extensions.Primitives": "10.0.6" + }, + "runtime": { + "lib/net10.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Options.ConfigurationExtensions.dll" + } + } + }, + "Microsoft.Extensions.Primitives/10.0.6": { + "runtime": { + "lib/net10.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "Microsoft.Extensions.Primitives.dll" + } + } + }, + "Mono.Cecil/0.11.6": { + "runtime": { + "lib/netstandard2.0/Mono.Cecil.Mdb.dll": { + "assemblyVersion": "0.11.6.0", + "fileVersion": "0.11.6.0", + "localPath": "Mono.Cecil.Mdb.dll" + }, + "lib/netstandard2.0/Mono.Cecil.Pdb.dll": { + "assemblyVersion": "0.11.6.0", + "fileVersion": "0.11.6.0", + "localPath": "Mono.Cecil.Pdb.dll" + }, + "lib/netstandard2.0/Mono.Cecil.Rocks.dll": { + "assemblyVersion": "0.11.6.0", + "fileVersion": "0.11.6.0", + "localPath": "Mono.Cecil.Rocks.dll" + }, + "lib/netstandard2.0/Mono.Cecil.dll": { + "assemblyVersion": "0.11.6.0", + "fileVersion": "0.11.6.0", + "localPath": "Mono.Cecil.dll" + } + } + }, + "Newtonsoft.Json/13.0.3": { + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.3.27908", + "localPath": "Newtonsoft.Json.dll" + } + } + }, + "NuGet.Common/7.3.0": { + "dependencies": { + "NuGet.Frameworks": "7.3.0" + }, + "runtime": { + "lib/net8.0/NuGet.Common.dll": { + "assemblyVersion": "7.3.0.0", + "fileVersion": "7.3.0.70", + "localPath": "NuGet.Common.dll" + } + } + }, + "NuGet.Configuration/7.3.0": { + "dependencies": { + "NuGet.Common": "7.3.0", + "System.Security.Cryptography.ProtectedData": "8.0.0" + }, + "runtime": { + "lib/net8.0/NuGet.Configuration.dll": { + "assemblyVersion": "7.3.0.0", + "fileVersion": "7.3.0.70", + "localPath": "NuGet.Configuration.dll" + } + } + }, + "NuGet.Frameworks/7.3.0": { + "runtime": { + "lib/net8.0/NuGet.Frameworks.dll": { + "assemblyVersion": "7.3.0.0", + "fileVersion": "7.3.0.70", + "localPath": "NuGet.Frameworks.dll" + } + } + }, + "NuGet.Packaging/7.3.0": { + "dependencies": { + "Newtonsoft.Json": "13.0.3", + "NuGet.Configuration": "7.3.0", + "NuGet.Versioning": "7.3.0", + "System.Security.Cryptography.Pkcs": "10.0.6" + }, + "runtime": { + "lib/net8.0/NuGet.Packaging.dll": { + "assemblyVersion": "7.3.0.0", + "fileVersion": "7.3.0.70", + "localPath": "NuGet.Packaging.dll" + } + } + }, + "NuGet.Protocol/7.3.0": { + "dependencies": { + "NuGet.Packaging": "7.3.0" + }, + "runtime": { + "lib/net8.0/NuGet.Protocol.dll": { + "assemblyVersion": "7.3.0.0", + "fileVersion": "7.3.0.70", + "localPath": "NuGet.Protocol.dll" + } + } + }, + "NuGet.Versioning/7.3.0": { + "runtime": { + "lib/net8.0/NuGet.Versioning.dll": { + "assemblyVersion": "7.3.0.0", + "fileVersion": "7.3.0.70", + "localPath": "NuGet.Versioning.dll" + } + } + }, + "System.Composition.AttributedModel/10.0.6": { + "runtime": { + "lib/net10.0/System.Composition.AttributedModel.dll": { + "assemblyVersion": "10.0.0.6", + "fileVersion": "10.0.626.17701", + "localPath": "System.Composition.AttributedModel.dll" + } + } + }, + "System.Diagnostics.EventLog/10.0.6": { + "runtime": { + "lib/net10.0/System.Diagnostics.EventLog.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "System.Diagnostics.EventLog.dll" + } + }, + "runtimeTargets": { + "runtimes/win/lib/net10.0/System.Diagnostics.EventLog.Messages.dll": { + "rid": "win", + "assetType": "runtime", + "assemblyVersion": "10.0.0.0", + "fileVersion": "0.0.0.0", + "localPath": "runtimes/win/lib/net10.0/System.Diagnostics.EventLog.Messages.dll" + }, + "runtimes/win/lib/net10.0/System.Diagnostics.EventLog.dll": { + "rid": "win", + "assetType": "runtime", + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "runtimes/win/lib/net10.0/System.Diagnostics.EventLog.dll" + } + } + }, + "System.Reflection.Metadata/10.0.6": { + "runtime": { + "lib/net10.0/System.Reflection.Metadata.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "System.Reflection.Metadata.dll" + } + } + }, + "System.Security.Cryptography.Pkcs/10.0.6": { + "runtime": { + "lib/net10.0/System.Security.Cryptography.Pkcs.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "System.Security.Cryptography.Pkcs.dll" + } + }, + "runtimeTargets": { + "runtimes/win/lib/net10.0/System.Security.Cryptography.Pkcs.dll": { + "rid": "win", + "assetType": "runtime", + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.626.17701", + "localPath": "runtimes/win/lib/net10.0/System.Security.Cryptography.Pkcs.dll" + } + } + }, + "System.Security.Cryptography.ProtectedData/8.0.0": { + "runtime": { + "lib/net8.0/System.Security.Cryptography.ProtectedData.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103", + "localPath": "System.Security.Cryptography.ProtectedData.dll" + } + } + }, + "ICSharpCode.Decompiler/8.0.0-noversion": { + "dependencies": { + "System.Reflection.Metadata": "10.0.6" + }, + "runtime": { + "ICSharpCode.Decompiler.dll": { + "assemblyVersion": "10.0.1.8346", + "fileVersion": "10.0.1.8346" + } + } + }, + "ICSharpCode.ILSpyX/8.0.0-noversion": { + "dependencies": { + "ICSharpCode.Decompiler": "8.0.0-noversion", + "K4os.Compression.LZ4": "1.3.8", + "Mono.Cecil": "0.11.6", + "System.Composition.AttributedModel": "10.0.6", + "System.Reflection.Metadata": "10.0.6" + }, + "runtime": { + "ICSharpCode.ILSpyX.dll": { + "assemblyVersion": "10.0.1.8346", + "fileVersion": "10.0.1.8346" + } + } + } + } + }, + "libraries": { + "ilspycmd/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "K4os.Compression.LZ4/1.3.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LhwlPa7c1zs1OV2XadMtAWdImjLIsqFJPoRcIWAadSRn0Ri1DepK65UbWLPmt4riLqx2d40xjXRk0ogpqNtK7g==", + "path": "k4os.compression.lz4/1.3.8", + "hashPath": "k4os.compression.lz4.1.3.8.nupkg.sha512" + }, + "McMaster.Extensions.CommandLineUtils/5.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YceiKmxdsBrlkAJpmJ2N8XkLyAH01xLsm4VLfjNp5MvtAom2wflZtEBz3CLMQret6Z7jSh3oBO1ULF1Is0tNxA==", + "path": "mcmaster.extensions.commandlineutils/5.1.0", + "hashPath": "mcmaster.extensions.commandlineutils.5.1.0.nupkg.sha512" + }, + "McMaster.Extensions.Hosting.CommandLine/5.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XN6s/86/bP0PSsP5p2eX49ZKmWrURSNg7nvrG5vws3abm7Py1A4bv3x3Pdvg7FqR8mLgEE0gNTI1qDtlYQIQnw==", + "path": "mcmaster.extensions.hosting.commandline/5.1.0", + "hashPath": "mcmaster.extensions.hosting.commandline.5.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lYQ9S1FGXIWIU7243RimdAXQYsFDeLhSSZvbSDwbeI/kCzZ4MIYXpp3kMQ+bDJXwl9pzMRIYkd4f9zGqcYxfAQ==", + "path": "microsoft.extensions.configuration/10.0.6", + "hashPath": "microsoft.extensions.configuration.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Abstractions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-a7bA7IT3ngIgcOMb/2MVH5CcfSxUCeQ6QXWS1Vt6oFpzLTH3U1+J2Xtc64Uw3whX9akYG8eR/UQeEzxo64zZLg==", + "path": "microsoft.extensions.configuration.abstractions/10.0.6", + "hashPath": "microsoft.extensions.configuration.abstractions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Binder/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-h22Fm4VxRmr4ty9rxJaW0i51xD56Bl5QhQ2hsGY2vl+6FioWmBhkpg3B78XQaK25N+hE41gZLZuYKGQS+OGbdw==", + "path": "microsoft.extensions.configuration.binder/10.0.6", + "hashPath": "microsoft.extensions.configuration.binder.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.CommandLine/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QIhi6cJMfeGBGs36DGc+3k5yYFAc9TAk3TN3WaommALXVv+syLSIkFwDgXDtrXvAgvFwOrRjxWpzJ88TLD1uhA==", + "path": "microsoft.extensions.configuration.commandline/10.0.6", + "hashPath": "microsoft.extensions.configuration.commandline.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZqkqIq6AXCBrLHqLGpjv0otGo0Dx1rF1UdDuVWDiog8jXuRwb3IH59fDONIxUschwDcYaD5xftrPCWdH1YD6lQ==", + "path": "microsoft.extensions.configuration.environmentvariables/10.0.6", + "hashPath": "microsoft.extensions.configuration.environmentvariables.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.FileExtensions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-hils30RkqBbtQVupvgUr7sgxJUYPc6YMEDge1QAXGTOhbRlqk2I0OH+BWMSsQjYnbGX2Ytl6EkrLgu9im6vE0w==", + "path": "microsoft.extensions.configuration.fileextensions/10.0.6", + "hashPath": "microsoft.extensions.configuration.fileextensions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Json/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-o/IG5ywTfT5U1ANCAC4w1vKtXapdL/OlunywrWboySYJB79eX0+mw7qxqNRkq1WMZOJoSyjPjbyZ17l3LS7A6Q==", + "path": "microsoft.extensions.configuration.json/10.0.6", + "hashPath": "microsoft.extensions.configuration.json.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.UserSecrets/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-DBuOHuzQitvowdS06xaHaOQl1Tcy8D+vU/FNAClkMPB23skPDbmN14t0ijJlQUGC9o10u+x+xVEsQk30ywYFtQ==", + "path": "microsoft.extensions.configuration.usersecrets/10.0.6", + "hashPath": "microsoft.extensions.configuration.usersecrets.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-poUvwtf92bEs8uBH3aRRs/ZgiAw+Z485EU7TtVPBt//MmD0uMPERe7+v3Ur7lpD8XgIEDL9sDoTBcW1LMG97CQ==", + "path": "microsoft.extensions.dependencyinjection/10.0.6", + "hashPath": "microsoft.extensions.dependencyinjection.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-w+dX4SIr1X9yegX2yX2dU1XtP4JAUVNdvOG/Evn+H+ndn96YzfIPX52FALXChrRNWFR9l77FQyg1mB7WQo6iOA==", + "path": "microsoft.extensions.dependencyinjection.abstractions/10.0.6", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Diagnostics/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vbigpAOKX+Bbm2uJQ/AqXqONEPPB3ZYkynRT24vo5ZWF1rzKPtVjpkQkJx5qTGp2dqNV5In9QqboayqmKdvGUA==", + "path": "microsoft.extensions.diagnostics/10.0.6", + "hashPath": "microsoft.extensions.diagnostics.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Diagnostics.Abstractions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-L98Xe5C+xyKytLNLiEyQ0rcY8GNXAeAn1xKsE0YDxPx/mXBYYtRoj8pC2cnbSFQUlOzBkyO90ivMSV22SRETFg==", + "path": "microsoft.extensions.diagnostics.abstractions/10.0.6", + "hashPath": "microsoft.extensions.diagnostics.abstractions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.FileProviders.Abstractions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iU/lPyrjHVA4jJ7Bl/VpXvgsAD4qJWc4oPSVJjMBeZjmv7IIo8wBKxnOUoXdZcSCUJ6MeBMs3WpXNfncO7OzRg==", + "path": "microsoft.extensions.fileproviders.abstractions/10.0.6", + "hashPath": "microsoft.extensions.fileproviders.abstractions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.FileProviders.Physical/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-t6T7umdzTKkSBOUMe5RYk826cTCsDU0hne9lPN5RGOSb3Kq0Xw8OEErM4zJ4dgZWV3G0ObK1Hf1IVU88uIKe6A==", + "path": "microsoft.extensions.fileproviders.physical/10.0.6", + "hashPath": "microsoft.extensions.fileproviders.physical.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.FileSystemGlobbing/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EG9GuYJlj1o1G8maSpKceZdj88OehKFRWaWp8BWUQWlvIJDWD8N0sIYDoRMGL/yX85H8KbVYPR9+dH/UjPEiKw==", + "path": "microsoft.extensions.filesystemglobbing/10.0.6", + "hashPath": "microsoft.extensions.filesystemglobbing.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Hosting/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ygrWasQx4OgbUfJpA2PQHon+c5yQWSoIpG2+f2uyEGs8ciTRoyn+Ne12e9zp6VZ2GNNb8CnUoxq1ika66tjVCA==", + "path": "microsoft.extensions.hosting/10.0.6", + "hashPath": "microsoft.extensions.hosting.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Hosting.Abstractions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-x3C8tgsX+xWvV5u76LFm24/U7sSnCRjuudBkbFsMV/DIqCA85te7YGg6dpa7lBToDhi4Lry9E7Arpy0laUw5AQ==", + "path": "microsoft.extensions.hosting.abstractions/10.0.6", + "hashPath": "microsoft.extensions.hosting.abstractions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZjpnbMD88IcZQE2pE9lcGv3mkH2mlApPWNh88ya1wJpcxZLp7p4aN7twI2FpawGPAsXNpmMgtKaz3o796YWKWQ==", + "path": "microsoft.extensions.logging/10.0.6", + "hashPath": "microsoft.extensions.logging.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1YgBO3wAy0dlpQyVTKWBSPND/t0yZHsvd3shGpbeEwH8JSb2hnFI2pNFrOOUi/stsp+T/dqwqmRIGh47ibo9bw==", + "path": "microsoft.extensions.logging.abstractions/10.0.6", + "hashPath": "microsoft.extensions.logging.abstractions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Configuration/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YXyeFL/MFNuy7k4zCIxldXdyyK7hpW3wPnqyS5HxOJ+BkMkaT7cYVmpWYNnRaiEM6a98vjVjvIRHiUUsTJfc6g==", + "path": "microsoft.extensions.logging.configuration/10.0.6", + "hashPath": "microsoft.extensions.logging.configuration.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Console/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-i6yclZFcPCX3MWphzPEbnBXpgT9vjZQppS4mFFvzSVols9JvvZPVeMe1ufv1bWC0/NwrBY5C+xKX4Joq+8HCkg==", + "path": "microsoft.extensions.logging.console/10.0.6", + "hashPath": "microsoft.extensions.logging.console.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Debug/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-CS6sPOCtu4NZo7fy4+475DPyqP0Yty2lj14yGZBC6JRdLQKuy+698gcZpKlCEzfr/0mqnbuBlrLRr/LgI7u/4g==", + "path": "microsoft.extensions.logging.debug/10.0.6", + "hashPath": "microsoft.extensions.logging.debug.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.EventLog/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-E/EI8sRdfbdLfHsmtdVwvX2ygoyCvP0l8Bk95QS00nw7ZHuEIibalafSTNMGrIz34+Wriyivl6unQ56g634QPQ==", + "path": "microsoft.extensions.logging.eventlog/10.0.6", + "hashPath": "microsoft.extensions.logging.eventlog.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.EventSource/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-On5ERRSmspe7/rCoiy+gaWmNI2hriIBTQS/2jtakeKE9MR7iDhOOjVjzjWapzZW3BlzAi4xCkocNqFl2AYQN3g==", + "path": "microsoft.extensions.logging.eventsource/10.0.6", + "hashPath": "microsoft.extensions.logging.eventsource.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Options/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-v5RTWm+3Gdub21ADJeRG5bunOOxutFNBZk6qGH6Az4L5nyRZoLe3Kse7jfAyUcdEoiKp72XpNw/wGR+9wP+MtQ==", + "path": "microsoft.extensions.options/10.0.6", + "hashPath": "microsoft.extensions.options.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Options.ConfigurationExtensions/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-O7xt1vYMxku2+/WpFkh6X8RzUtYbKR+XCt0KOO0W9TbRbFeQdfb9Nry/CdVq57kOyOKS3Z4qD1xqV/8LpJQ0Xw==", + "path": "microsoft.extensions.options.configurationextensions/10.0.6", + "hashPath": "microsoft.extensions.options.configurationextensions.10.0.6.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-L8P21mqaG+CXvPheLndean/cHCOcItJqH8nx+0YQnK7wAiOR0G1IOC418ZSzTMD2D6Gmo0f2M5WR70XtpX2B8g==", + "path": "microsoft.extensions.primitives/10.0.6", + "hashPath": "microsoft.extensions.primitives.10.0.6.nupkg.sha512" + }, + "Mono.Cecil/0.11.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA==", + "path": "mono.cecil/0.11.6", + "hashPath": "mono.cecil.0.11.6.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "path": "newtonsoft.json/13.0.3", + "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" + }, + "NuGet.Common/7.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-y+7cQuzc6zePfo3GdueKgFAfE06pyNv1EGeordAMXotm6WEJw/m7UHv7GSLnib2HEPpzUk4Wvxgn9VgWkIe6Yw==", + "path": "nuget.common/7.3.0", + "hashPath": "nuget.common.7.3.0.nupkg.sha512" + }, + "NuGet.Configuration/7.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-9qNpnZP73pfGm1MYET78OCW/HNnKNZpTfWPB2z/EyxQnfWtJBANeFyogX8s7S+oWMbR+EG2w6jbDVKdvVJfCXA==", + "path": "nuget.configuration/7.3.0", + "hashPath": "nuget.configuration.7.3.0.nupkg.sha512" + }, + "NuGet.Frameworks/7.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AnhSFUOrCrWp7pGtqhfOxa5HKm4rfpQxuatGDKzpGtTczasj6OcGVtB74PyqW7osdu9/BtkjnkAYvNk5iT82Gg==", + "path": "nuget.frameworks/7.3.0", + "hashPath": "nuget.frameworks.7.3.0.nupkg.sha512" + }, + "NuGet.Packaging/7.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yvmJ8LUPUVMm2DAKSK3+QfJKoCxQR1NuyPYLHqFHb1zmUcGwq+IvSl/4JjUivJDztXnI9GSVlE/SjQLsRJPoYw==", + "path": "nuget.packaging/7.3.0", + "hashPath": "nuget.packaging.7.3.0.nupkg.sha512" + }, + "NuGet.Protocol/7.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QWx4Fko06Act+gVhB9UUc8Hzt0fnA8qQhD5SFn/xEis2ZZVzmatHmMdsc0SV7tyvCUlfG8DzQzYLF7fF4LvTyA==", + "path": "nuget.protocol/7.3.0", + "hashPath": "nuget.protocol.7.3.0.nupkg.sha512" + }, + "NuGet.Versioning/7.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iOQPAdnVgj2U+K3AcdGGGcdS1tWyh3nvr64eqTDFCsDuHySBXSHRhl7eR8hdc0BZHxDjacRstbuaJKCurt2oPw==", + "path": "nuget.versioning/7.3.0", + "hashPath": "nuget.versioning.7.3.0.nupkg.sha512" + }, + "System.Composition.AttributedModel/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sdv1Uk4auk8lc/0hsuAwE8Hpgg3tgbZDk4yRANIpfgk13f6Ssh+sKQviJchygk0ZR/fnFV4LtMyqzwZS8g7UaQ==", + "path": "system.composition.attributedmodel/10.0.6", + "hashPath": "system.composition.attributedmodel.10.0.6.nupkg.sha512" + }, + "System.Diagnostics.EventLog/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-RMe4gRBwSVd1O6HVRjNwLgcH2jjrT8sHyNRJegZLX68voA+HzMf1xZPvFxMMDpyW86B9U2pYslgl4DFCE61WyA==", + "path": "system.diagnostics.eventlog/10.0.6", + "hashPath": "system.diagnostics.eventlog.10.0.6.nupkg.sha512" + }, + "System.Reflection.Metadata/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JQ3LKu6fdgnSqrgD5Uwfjvngi40lKjxWpUsaUnjQCgF4LWAjs+55ytZx11U+09FRByMS07LrFv89KXViUhlWTQ==", + "path": "system.reflection.metadata/10.0.6", + "hashPath": "system.reflection.metadata.10.0.6.nupkg.sha512" + }, + "System.Security.Cryptography.Pkcs/10.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-88tquaGJ1htm4DHWS6x9jwER7sFET2SVRN7HqO1FYZwE0diDcUmz0ajhVa8ZD2HGhDJBueSPjP/gqyP3gXtT2A==", + "path": "system.security.cryptography.pkcs/10.0.6", + "hashPath": "system.security.cryptography.pkcs.10.0.6.nupkg.sha512" + }, + "System.Security.Cryptography.ProtectedData/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==", + "path": "system.security.cryptography.protecteddata/8.0.0", + "hashPath": "system.security.cryptography.protecteddata.8.0.0.nupkg.sha512" + }, + "ICSharpCode.Decompiler/8.0.0-noversion": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "ICSharpCode.ILSpyX/8.0.0-noversion": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.dll new file mode 100644 index 0000000..603bf9b Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.runtimeconfig.json b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.runtimeconfig.json new file mode 100644 index 0000000..9ce916a --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/ilspycmd.runtimeconfig.json @@ -0,0 +1,16 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "System.GC.Server": true, + "System.Globalization.Invariant": true, + "System.Globalization.PredefinedCulturesOnly": true, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false + } + } +} \ No newline at end of file diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.Messages.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.Messages.dll new file mode 100644 index 0000000..5d94297 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.Messages.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.dll new file mode 100644 index 0000000..c9886bf Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Security.Cryptography.Pkcs.dll b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Security.Cryptography.Pkcs.dll new file mode 100644 index 0000000..28788c9 Binary files /dev/null and b/.tools/.store/ilspycmd/10.0.1.8346/ilspycmd/10.0.1.8346/tools/net10.0/any/runtimes/win/lib/net10.0/System.Security.Cryptography.Pkcs.dll differ diff --git a/.tools/.store/ilspycmd/10.0.1.8346/project.assets.json b/.tools/.store/ilspycmd/10.0.1.8346/project.assets.json new file mode 100644 index 0000000..bb582e8 --- /dev/null +++ b/.tools/.store/ilspycmd/10.0.1.8346/project.assets.json @@ -0,0 +1,71 @@ +{ + "version": 3, + "targets": { + "net10.0/win-x64": { + "ilspycmd/10.0.1.8346": { + "type": "package", + "tools": { + "tools/net10.0/any/DotnetToolSettings.xml": {}, + "tools/net10.0/any/ICSharpCode.Decompiler.dll": {}, + "tools/net10.0/any/ICSharpCode.Decompiler.xml": {}, + "tools/net10.0/any/ICSharpCode.ILSpyX.dll": {}, + "tools/net10.0/any/K4os.Compression.LZ4.dll": {}, + "tools/net10.0/any/McMaster.Extensions.CommandLineUtils.dll": {}, + "tools/net10.0/any/McMaster.Extensions.Hosting.CommandLine.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.Abstractions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.Binder.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.CommandLine.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.EnvironmentVariables.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.FileExtensions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.Json.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.UserSecrets.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Configuration.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.DependencyInjection.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Diagnostics.Abstractions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Diagnostics.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.FileProviders.Abstractions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.FileProviders.Physical.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.FileSystemGlobbing.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Hosting.Abstractions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Hosting.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.Abstractions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.Configuration.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.Console.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.Debug.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.EventLog.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.EventSource.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Logging.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Options.ConfigurationExtensions.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Options.dll": {}, + "tools/net10.0/any/Microsoft.Extensions.Primitives.dll": {}, + "tools/net10.0/any/Mono.Cecil.Mdb.dll": {}, + "tools/net10.0/any/Mono.Cecil.Pdb.dll": {}, + "tools/net10.0/any/Mono.Cecil.Rocks.dll": {}, + "tools/net10.0/any/Mono.Cecil.dll": {}, + "tools/net10.0/any/Newtonsoft.Json.dll": {}, + "tools/net10.0/any/NuGet.Common.dll": {}, + "tools/net10.0/any/NuGet.Configuration.dll": {}, + "tools/net10.0/any/NuGet.Frameworks.dll": {}, + "tools/net10.0/any/NuGet.Packaging.dll": {}, + "tools/net10.0/any/NuGet.Protocol.dll": {}, + "tools/net10.0/any/NuGet.Versioning.dll": {}, + "tools/net10.0/any/System.Composition.AttributedModel.dll": {}, + "tools/net10.0/any/System.Diagnostics.EventLog.dll": {}, + "tools/net10.0/any/System.Reflection.Metadata.dll": {}, + "tools/net10.0/any/System.Security.Cryptography.Pkcs.dll": {}, + "tools/net10.0/any/System.Security.Cryptography.ProtectedData.dll": {}, + "tools/net10.0/any/ilspycmd.deps.json": {}, + "tools/net10.0/any/ilspycmd.dll": {}, + "tools/net10.0/any/ilspycmd.pdb": {}, + "tools/net10.0/any/ilspycmd.runtimeconfig.json": {}, + "tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.Messages.dll": {}, + "tools/net10.0/any/runtimes/win/lib/net10.0/System.Diagnostics.EventLog.dll": {}, + "tools/net10.0/any/runtimes/win/lib/net10.0/System.Security.Cryptography.Pkcs.dll": {} + } + } + } + }, + "libraries": {}, + "projectFileDependencyGroups": {} +} \ No newline at end of file diff --git a/pluginmaster.json b/pluginmaster.json index af03b35..65779b8 100644 --- a/pluginmaster.json +++ b/pluginmaster.json @@ -3,20 +3,20 @@ "Author": "aRkker", "Name": "Anti-Dickhead ChatModule", "InternalName": "AntiDickheadChatmodule", - "AssemblyVersion": "0.0.6.0", + "AssemblyVersion": "0.0.6.3", "Description": "Makes your chat more sufferable. :)", "ApplicableVersion": "any", "Tags": [ "other", "social" ], - "DalamudApiLevel": 14, + "DalamudApiLevel": 15, "LoadRequiredState": 0, "LoadSync": false, "CanUnloadAsync": false, "LoadPriority": 0, - "Punchline": "Removes periods, and capitals", - "Changelog": "0.0.1.1\nReuploadto fix?\n0.0.1.0\nProbably broken 6.3", + "Punchline": "Lowercase sentence starts, strip the final period", + "Changelog": "0.0.6.3\nProbe ChatMessage and CheckMessageHandled for say-chat debugging\n\n0.0.6.2\nAdd chat-event logging for rewrite debugging\n\n0.0.6.1\nAPI 15 update and plugin rewrite\n\n0.0.1.1\nReuploadto fix?\n0.0.1.0\nProbably broken 6.3", "AcceptsFeedback": true, "LastUpdate": "1766266278", "IsHide": "False", @@ -104,7 +104,7 @@ "Author": "aRkker", "Name": "World Map Enhancer", "InternalName": "WorldMapEnhancer", - "AssemblyVersion": "1.0.6.2", + "AssemblyVersion": "1.0.6.3", "Description": "Simply zoom out by right clicking the world map, like God intended it", "ApplicableVersion": "any", "Tags": [ @@ -114,13 +114,13 @@ "rightclick", "zoom" ], - "DalamudApiLevel": 14, + "DalamudApiLevel": 15, "LoadRequiredState": 0, "LoadSync": false, "CanUnloadAsync": false, "LoadPriority": 0, "Punchline": "Right click to zoom out the big map", - "Changelog": "1.0.3.0\nDawntrail support 2.0\n\n1.0.1.0\nAPI 8, NET7", + "Changelog": "1.0.6.3\nAPI 15 update and plugin rewrite\n\n1.0.3.0\nDawntrail support 2.0\n\n1.0.1.0\nAPI 8, NET7", "AcceptsFeedback": true, "LastUpdate": "1766266278", "IsHide": "False", diff --git a/plugins/AntiDickheadChatmodule/AntiDickheadChatmodule.json b/plugins/AntiDickheadChatmodule/AntiDickheadChatmodule.json index 95acfd5..f5eebd7 100644 --- a/plugins/AntiDickheadChatmodule/AntiDickheadChatmodule.json +++ b/plugins/AntiDickheadChatmodule/AntiDickheadChatmodule.json @@ -2,19 +2,19 @@ "Author": "aRkker", "Name": "Anti-Dickhead ChatModule", "InternalName": "AntiDickheadChatmodule", - "AssemblyVersion": "0.0.6.0", + "AssemblyVersion": "0.0.6.3", "Description": "Makes your chat more sufferable. :)", "ApplicableVersion": "any", "Tags": [ "other", "social" ], - "DalamudApiLevel": 14, + "DalamudApiLevel": 15, "LoadRequiredState": 0, "LoadSync": false, "CanUnloadAsync": false, "LoadPriority": 0, - "Punchline": "Removes periods, and capitals", - "Changelog": "0.0.1.1\nReuploadto fix?\n0.0.1.0\nProbably broken 6.3", + "Punchline": "Lowercase sentence starts, strip the final period", + "Changelog": "0.0.6.3\nProbe ChatMessage and CheckMessageHandled for say-chat debugging\n\n0.0.6.2\nAdd chat-event logging for rewrite debugging\n\n0.0.6.1\nAPI 15 update and plugin rewrite\n\n0.0.1.1\nReuploadto fix?\n0.0.1.0\nProbably broken 6.3", "AcceptsFeedback": true } \ No newline at end of file diff --git a/plugins/AntiDickheadChatmodule/latest.zip b/plugins/AntiDickheadChatmodule/latest.zip index d023885..05124cf 100644 Binary files a/plugins/AntiDickheadChatmodule/latest.zip and b/plugins/AntiDickheadChatmodule/latest.zip differ diff --git a/plugins/WorldMapEnhancer/WorldMapEnhancer.json b/plugins/WorldMapEnhancer/WorldMapEnhancer.json index f7d3535..df93856 100644 --- a/plugins/WorldMapEnhancer/WorldMapEnhancer.json +++ b/plugins/WorldMapEnhancer/WorldMapEnhancer.json @@ -2,7 +2,7 @@ "Author": "aRkker", "Name": "World Map Enhancer", "InternalName": "WorldMapEnhancer", - "AssemblyVersion": "1.0.6.2", + "AssemblyVersion": "1.0.6.3", "Description": "Simply zoom out by right clicking the world map, like God intended it", "ApplicableVersion": "any", "Tags": [ @@ -12,12 +12,12 @@ "rightclick", "zoom" ], - "DalamudApiLevel": 14, + "DalamudApiLevel": 15, "LoadRequiredState": 0, "LoadSync": false, "CanUnloadAsync": false, "LoadPriority": 0, "Punchline": "Right click to zoom out the big map", - "Changelog": "1.0.3.0\nDawntrail support 2.0\n\n1.0.1.0\nAPI 8, NET7", + "Changelog": "1.0.6.3\nAPI 15 update and plugin rewrite\n\n1.0.3.0\nDawntrail support 2.0\n\n1.0.1.0\nAPI 8, NET7", "AcceptsFeedback": true } \ No newline at end of file diff --git a/plugins/WorldMapEnhancer/latest.zip b/plugins/WorldMapEnhancer/latest.zip index 0bc0ce7..abf5a03 100644 Binary files a/plugins/WorldMapEnhancer/latest.zip and b/plugins/WorldMapEnhancer/latest.zip differ diff --git a/recovery/README.md b/recovery/README.md new file mode 100644 index 0000000..f3dc337 --- /dev/null +++ b/recovery/README.md @@ -0,0 +1,58 @@ +# Binary Recovery + +This repo is a plugin feed, not a source repo. The recoverable assets live in `plugins/*/latest.zip`. + +## What already worked + +The current packages decompile cleanly with ILSpy into usable C# projects under `.recovery/decompiled`. + +Recovered assemblies: + +- `AntiDickheadChatmodule` +- `CrystallineConflictWinsTracker` +- `MultiboxMutexer` +- `OmicronMountMusicFixer` +- `WorldMapEnhancer` + +Observed runtime targets from shipped `.deps.json` files: + +- `AntiDickheadChatmodule`: `.NETCoreApp,Version=v10.0` +- `CrystallineConflictWinsTracker`: `.NETCoreApp,Version=v7.0` +- `MultiboxMutexer`: `.NETCoreApp,Version=v7.0` +- `OmicronMountMusicFixer`: `.NETCoreApp,Version=v10.0` +- `WorldMapEnhancer`: `.NETCoreApp,Version=v10.0` + +## Repeat The Recovery + +Run: + +```powershell +powershell -ExecutionPolicy Bypass -File .\recovery\recover-plugins.ps1 +``` + +That script will: + +1. Install `ilspycmd` into repo-local `.tools` if it is missing. +2. Extract every `plugins/*/latest.zip` into `.recovery/extract`. +3. Decompile every top-level DLL into `.recovery/decompiled/`. +4. Write `.recovery/inventory.csv` with the assembly names, runtime targets, PDB presence, and output paths. + +## What To Expect + +The output is usable, but not production-ready without cleanup: + +- The generated `.csproj` files only contain bare assembly references. You will need to rebuild package references and the Dalamud build setup. +- Some unsafe or native interop blocks decompile with `//IL_...` comments and occasional `Unknown result type` notes. Those are normal decompiler artifacts around hooks, pointers, and game structs. +- PDB-backed projects retain better type and file names. `CrystallineConflictWinsTracker` and `MultiboxMutexer` shipped PDBs. +- `MultiboxMutexer` and `OmicronMountMusicFixer` show Fody/Resourcer-generated artifacts in the decompile output. Those may be easier to replace with simpler source equivalents than to preserve exactly. + +## Recommended Next Pass + +For each recovered project: + +1. Create a fresh plugin project targeting the framework required by your current Dalamud toolchain. +2. Copy the decompiled source into that fresh project instead of trying to compile the raw ILSpy `.csproj` unchanged. +3. Re-add package references and Dalamud services incrementally until it builds. +4. Replace any fragile hook signatures, pointer code, or generated-resource code only where the compiler forces you to. + +If you want, the next step can be to take one recovered plugin and turn it back into a clean, buildable source project in this repo. diff --git a/recovery/recover-plugins.ps1 b/recovery/recover-plugins.ps1 new file mode 100644 index 0000000..d47c763 --- /dev/null +++ b/recovery/recover-plugins.ps1 @@ -0,0 +1,95 @@ +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +$repoRoot = Split-Path -Parent $PSScriptRoot +$pluginsRoot = Join-Path $repoRoot "plugins" +$toolRoot = Join-Path $repoRoot ".tools" +$recoveryRoot = Join-Path $repoRoot ".recovery" +$extractRoot = Join-Path $recoveryRoot "extract" +$decompileRoot = Join-Path $recoveryRoot "decompiled" +$inventoryPath = Join-Path $recoveryRoot "inventory.csv" +$toolExe = Join-Path $toolRoot "ilspycmd.exe" + +function Ensure-Directory([string]$Path) { + if (-not (Test-Path -LiteralPath $Path)) { + New-Item -ItemType Directory -Path $Path | Out-Null + } +} + +function Reset-Directory([string]$Path) { + if (Test-Path -LiteralPath $Path) { + Remove-Item -LiteralPath $Path -Recurse -Force + } + + New-Item -ItemType Directory -Path $Path | Out-Null +} + +function Get-RuntimeTarget([string]$DepsPath) { + if (-not (Test-Path -LiteralPath $DepsPath)) { + return $null + } + + try { + $deps = Get-Content -LiteralPath $DepsPath -Raw | ConvertFrom-Json + return $deps.runtimeTarget.name + } + catch { + return $null + } +} + +Ensure-Directory $toolRoot +Ensure-Directory $recoveryRoot +Ensure-Directory $extractRoot +Ensure-Directory $decompileRoot + +if (-not (Test-Path -LiteralPath $toolExe)) { + dotnet tool install --tool-path $toolRoot ilspycmd | Out-Host +} + +$inventory = New-Object System.Collections.Generic.List[object] + +Get-ChildItem -LiteralPath $pluginsRoot -Directory | Sort-Object Name | ForEach-Object { + $pluginDir = $_ + $zipPath = Join-Path $pluginDir.FullName "latest.zip" + + if (-not (Test-Path -LiteralPath $zipPath)) { + return + } + + $extractPath = Join-Path $extractRoot $pluginDir.Name + Reset-Directory $extractPath + Expand-Archive -LiteralPath $zipPath -DestinationPath $extractPath -Force + + $dlls = Get-ChildItem -LiteralPath $extractPath -Filter "*.dll" -File + + foreach ($dll in $dlls) { + $assemblyName = [System.IO.Path]::GetFileNameWithoutExtension($dll.Name) + $projectPath = Join-Path $decompileRoot $assemblyName + Reset-Directory $projectPath + + & $toolExe -p -o $projectPath $dll.FullName | Out-Host + + $depsPath = Join-Path $extractPath ($assemblyName + ".deps.json") + $pdbPath = Join-Path $extractPath ($assemblyName + ".pdb") + + $inventory.Add([pscustomobject]@{ + PluginFolder = $pluginDir.Name + AssemblyName = $assemblyName + RuntimeTarget = Get-RuntimeTarget $depsPath + ZipPath = $zipPath + DllPath = $dll.FullName + HasPdb = Test-Path -LiteralPath $pdbPath + ExtractPath = $extractPath + ProjectPath = $projectPath + }) + } +} + +$inventory | + Sort-Object PluginFolder, AssemblyName | + Export-Csv -LiteralPath $inventoryPath -NoTypeInformation + +$inventory | + Sort-Object PluginFolder, AssemblyName | + Format-Table PluginFolder, AssemblyName, RuntimeTarget, HasPdb, ProjectPath