Decompiled source of DevConsole v1.0.12
BepInEx/plugins/Hikaria.DevConsole/Hikaria.DevConsoleLite.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils; using GameData; using HarmonyLib; using Hikaria.DevConsoleLite.Plugin; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Mono.CSharp; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Hikaria.DevConsole")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Hikaria.DevConsole")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6445e8e3-afb9-4d0b-82cb-2c79e5995123")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace Hikaria.DevConsoleLite { public sealed class Command { public string Name { get; private set; } public string HelpText { get; private set; } public bool IsCustomCommand { get; private set; } internal string[] Aliases { get; private set; } internal Parameter[] Parameters { get; private set; } internal Action<object[]> Callback { get; private set; } internal Action DefaultCallback { get; private set; } public static Command Create(string name, string aliases, string helpText, Action callback) { Command command = new Command(); command.Name = name; command.Aliases = aliases.Split(new char[1] { ',' }); command.HelpText = helpText; command.Parameters = new Parameter[0]; command.Callback = delegate { callback(); }; return command; } public static Command Create<T1>(string name, string aliases, string helpText, Parameter p1, Action<T1> callback, Action defaultCallback = null) { Command command = new Command(); command.Name = name; command.Aliases = aliases.Split(new char[1] { ',' }); command.HelpText = helpText; command.Parameters = new Parameter[1] { p1.SetType<T1>() }; command.Callback = delegate(object[] o) { callback((T1)o[0]); }; command.DefaultCallback = defaultCallback; return command; } public static Command Create<T1, T2>(string name, string aliases, string helpText, Parameter p1, Parameter p2, Action<T1, T2> callback, Action defaultCallback = null) { Command command = new Command(); command.Name = name; command.Aliases = aliases.Split(new char[1] { ',' }); command.HelpText = helpText; command.Parameters = new Parameter[2] { p1.SetType<T1>(), p2.SetType<T2>() }; command.Callback = delegate(object[] o) { callback((T1)o[0], (T2)o[1]); }; command.DefaultCallback = defaultCallback; return command; } public static Command Create<T1, T2, T3>(string name, string aliases, string helpText, Parameter p1, Parameter p2, Parameter p3, Action<T1, T2, T3> callback, Action defaultCallback = null) { Command command = new Command(); command.Name = name; command.Aliases = aliases.Split(new char[1] { ',' }); command.HelpText = helpText; command.Parameters = new Parameter[3] { p1.SetType<T1>(), p2.SetType<T2>(), p3.SetType<T3>() }; command.Callback = delegate(object[] o) { callback((T1)o[0], (T2)o[1], (T3)o[2]); }; command.DefaultCallback = defaultCallback; return command; } public static Command Create<T1, T2, T3, T4>(string name, string aliases, string helpText, Parameter p1, Parameter p2, Parameter p3, Parameter p4, Action<T1, T2, T3, T4> callback, Action defaultCallback = null) { Command command = new Command(); command.Name = name; command.Aliases = aliases.Split(new char[1] { ',' }); command.HelpText = helpText; command.Parameters = new Parameter[4] { p1.SetType<T1>(), p2.SetType<T2>(), p3.SetType<T3>(), p4.SetType<T4>() }; command.Callback = delegate(object[] o) { callback((T1)o[0], (T2)o[1], (T3)o[2], (T4)o[3]); }; command.DefaultCallback = defaultCallback; return command; } public static Command Create<T1, T2, T3, T4, T5>(string name, string aliases, string helpText, Parameter p1, Parameter p2, Parameter p3, Parameter p4, Parameter p5, Action<T1, T2, T3, T4, T5> callback, Action defaultCallback = null) { Command command = new Command(); command.Name = name; command.Aliases = aliases.Split(new char[1] { ',' }); command.HelpText = helpText; command.Parameters = new Parameter[5] { p1.SetType<T1>(), p2.SetType<T2>(), p3.SetType<T3>(), p4.SetType<T4>(), p5.SetType<T5>() }; command.Callback = delegate(object[] o) { callback((T1)o[0], (T2)o[1], (T3)o[2], (T4)o[3], (T5)o[4]); }; command.DefaultCallback = defaultCallback; return command; } internal static Command Create(DevConsoleCommandAttribute commandAttribute, MethodInfo method) { ParameterInfo[] parameters = method.GetParameters(); Parameter[] array = new Parameter[parameters.Length]; for (int i = 0; i < array.Length; i++) { array[i] = Parameter.Create(parameters[i].Name, (i < commandAttribute.ParameterHelpText.Length) ? commandAttribute.ParameterHelpText[i] : ""); array[i].SetType(parameters[i].ParameterType); } return new Command { Name = commandAttribute.Name, Aliases = commandAttribute.Aliases, HelpText = commandAttribute.HelpText, Parameters = array, Callback = delegate(object[] o) { method.Invoke(null, o); } }; } private Command() { } public override string ToString() { return Name; } public string ToFormattedString() { string text = GetFormattedName(); for (int i = 0; i < Parameters.Length; i++) { if (i < Parameters.Length) { text += " "; } text += GetFormattedParameter(i); } return text; } public string GetFormattedName() { return "<b>" + Name + "</b>"; } public string GetFormattedParameter(int parameterIndex) { return Parameters[parameterIndex].ToFormattedString(); } public IReadOnlyList<string> GetAliases() { return Aliases; } public IReadOnlyList<Parameter> GetParameters() { return Parameters; } internal void FixName() { Name = string.Concat(Name.Where((char c) => !char.IsWhiteSpace(c))).ToLower(); } internal void FixAliases() { List<string> aliases = new List<string>(); Array.ForEach(Aliases, delegate(string a) { string text = string.Concat(a.Where((char c) => !char.IsWhiteSpace(c))).ToLower(); if (!string.IsNullOrEmpty(text)) { aliases.Add(text); } }); if (aliases.Count == 0) { aliases.Add(""); } Aliases = aliases.ToArray(); } internal bool HasAlias(params string[] aliases) { if (aliases.Length != 0) { return aliases.Any((string a) => !string.IsNullOrEmpty(a) && Aliases.Contains(a.ToLower())); } return false; } internal void SetAsCustomCommand() { IsCustomCommand = true; } } public static class DevConsole { private static DevConsoleMono _console; internal static Dictionary<string, Object> s_AssetLookup = new Dictionary<string, Object>(); public static bool isInit; internal static Dictionary<Command, bool> _commandsNeedToAdd = new Dictionary<Command, bool>(); internal static Dictionary<Type, Func<string, object>> _parametersNeedToAdd = new Dictionary<Type, Func<string, object>>(); public static bool IsEnabled { get { return _console.ConsoleIsEnabled; } set { if (value) { EnableConsole(); } else { DisableConsole(); } } } public static bool IsOpen { get { return _console.ConsoleIsShowing; } set { if (value) { _console.OpenConsole(); } else { _console.CloseConsole(); } } } public static bool IsOpenAndFocused => _console.ConsoleIsShowingAndFocused; public static bool IsKeyBindingsEnabled { get { return _console.BindingsIsEnabled; } set { _console.BindingsIsEnabled = value; } } public static KeyCode? ToggleKey { get { return _console.ConsoleToggleKey; } set { _console.ConsoleToggleKey = value; } } public static int AverageFps => _console.AverageFps; public static float AverageMs => _console.AverageMs; public static event Action OnConsoleEnabled; public static event Action OnConsoleDisabled; public static event Action OnConsoleOpened; public static event Action OnConsoleClosed; public static event Action OnConsoleFocused; public static event Action OnConsoleFocusLost; public static bool AddCommand(Command command, bool onlyInDevBuild = false) { if (command == null) { throw new ArgumentNullException("command"); } if (isInit) { return _console.AddCommand(command, onlyInDevBuild, isCustomCommand: true); } _commandsNeedToAdd.Add(command, onlyInDevBuild); return true; } public static bool RemoveCommand(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } return _console.RemoveCommand(name); } public static bool RunCommand(string input) { if (string.IsNullOrEmpty(input)) { throw new ArgumentNullException("input"); } return _console.RunCommand(input); } public static Command GetCommand(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } return _console.GetCommand(name); } public static bool GetCommand(string name, out Command command) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } return _console.GetCommand(name, out command); } public static bool AddParameterType<T>(Func<string, T> parseFunc) { if (parseFunc == null) { throw new ArgumentNullException("parseFunc"); } if (isInit) { return _console.AddParameterType(typeof(T), (string s) => parseFunc(s)); } _parametersNeedToAdd.Add(typeof(T), (string s) => parseFunc(s)); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Log(object message) { _console.Log(message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Log(object message, Color colour) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _console.Log(message, ColorUtility.ToHtmlStringRGBA(colour)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogVariable(string variableName, object value, string suffix = "") { _console.LogVariable(variableName, value, suffix); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogException(Exception exception) { _console.LogException(exception); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogError(object message) { _console.LogError(message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogWarning(object message) { _console.LogWarning(message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogSuccess(object message) { _console.LogSuccess(message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogSeperator(object message = null) { _console.LogSeperator(message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogCollection<T>(in IReadOnlyCollection<T> collection, Func<T, string> toString = null, string prefix = "", string suffix = "") { _console.LogCollection(in collection, toString, prefix, suffix); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogCommand() { _console.LogCommand(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void LogCommand(string name) { _console.LogCommand(name); } public static void SetToggleKey(KeyCode? toggleKey) { _console.ConsoleToggleKey = toggleKey; } public static void DisableToggleKey() { _console.ConsoleToggleKey = null; } public static void EnableConsole() { _console.EnableConsole(); } public static void DisableConsole() { _console.DisableConsole(); } public static void OpenConsole() { _console.OpenConsole(); } public static void CloseConsole() { _console.CloseConsole(); } public static void ClearConsole() { _console.ClearConsole(); } public static void SetTrackedStat(string name, Func<object> func, bool startEnabled = true) { _console.SetTrackedStat(name, func, startEnabled); } public static bool RemoveTrackedStat(string name) { return _console.RemoveTrackedStat(name); } public static Coroutine InvokeCoroutine(IEnumerator enumerator) { return MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)_console, enumerator); } public static Coroutine InvokeDelayed(Action action, float delay) { return MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)_console, Invoke()); IEnumerator Invoke() { yield return (object)new WaitForSeconds(delay); action?.Invoke(); } } internal static string GetFriendlyName(Type type) { if (type.IsGenericType) { Type underlyingType = Nullable.GetUnderlyingType(type); if (underlyingType != null) { return GetFriendlyName(underlyingType) + "?"; } return type.Name.Split(new char[1] { '`' })[0] + "<" + string.Join(", ", from x in type.GetGenericArguments() select GetFriendlyName(x)) + ">"; } return type.Name; } internal static void InvokeOnConsoleEnabled() { DevConsole.OnConsoleEnabled?.Invoke(); } internal static void InvokeOnConsoleDisabled() { DevConsole.OnConsoleDisabled?.Invoke(); } internal static void InvokeOnConsoleOpened() { DevConsole.OnConsoleOpened?.Invoke(); } internal static void InvokeOnConsoleClosed() { DevConsole.OnConsoleClosed?.Invoke(); } internal static void InvokeOnConsoleFocused() { DevConsole.OnConsoleFocused?.Invoke(); } internal static void InvokeOnConsoleFocusLost() { DevConsole.OnConsoleFocusLost?.Invoke(); } public static void Init() { if (isInit) { return; } isInit = true; AssetBundle val = AssetBundle.LoadFromFile(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\devconsole"); string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)val.AllAssetNames()); foreach (string text in array) { Object val2 = val.LoadAsset(text); if (val2 != (Object)null) { string key = text.ToUpper(); s_AssetLookup.Add(key, val2); } } _console = Object.Instantiate<GameObject>(((Il2CppObjectBase)s_AssetLookup["ASSETS/UNITY-DEVELOPERCONSOLE/RESOURCES/PREFABS/FAB_DEVCONSOLE.INSTANCE.PREFAB"]).Cast<GameObject>()).AddComponent<DevConsoleMono>(); foreach (KeyValuePair<Command, bool> item in _commandsNeedToAdd) { _console.AddCommand(item.Key, item.Value, isCustomCommand: true); } foreach (KeyValuePair<Type, Func<string, object>> item2 in _parametersNeedToAdd) { _console.AddParameterType(item2.GetType(), item2.Value); } } } [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] public sealed class DevConsoleCommandAttribute : Attribute { internal string Name { get; } internal string[] Aliases { get; } internal string HelpText { get; } internal string[] ParameterHelpText { get; } internal bool OnlyInDevBuild { get; } public DevConsoleCommandAttribute(string name, string aliases, string helpText, bool onlyInDevBuild, params string[] parameterHelpText) { Name = name; Aliases = aliases.Split(new char[1] { ',' }); HelpText = helpText; ParameterHelpText = parameterHelpText ?? new string[0]; OnlyInDevBuild = onlyInDevBuild; } public DevConsoleCommandAttribute(string name, string aliases, string helpText, params string[] parameterHelpText) : this(name, aliases, helpText, onlyInDevBuild: false, parameterHelpText) { } } internal static class DevConsoleData { private static Dictionary<string, object> _data; public static string FilePath { get; private set; } static DevConsoleData() { _data = new Dictionary<string, object>(); FilePath = Paths.ConfigPath + "\\Hikaria\\DevConsole\\DevConsole.dat"; } public static void SetObject(string key, object value) { _data[key] = value; } public static T GetObject<T>(string key, T defaultValue) { try { return (!_data.ContainsKey(key)) ? defaultValue : ((T)_data[key]); } catch (Exception) { return defaultValue; } } public static void Save() { FileStream fileStream = new FileStream(FilePath, FileMode.Create); BinaryFormatter binaryFormatter = new BinaryFormatter(); try { binaryFormatter.Serialize(fileStream, _data); } catch (Exception data) { Logs.LogError(data); Logs.LogError("Failed to save developer console preferences due to an exception."); } finally { fileStream.Close(); } } public static void Load() { if (!File.Exists(FilePath)) { return; } FileStream fileStream = new FileStream(FilePath, FileMode.Open); BinaryFormatter binaryFormatter = new BinaryFormatter(); bool flag = false; try { _data = (Dictionary<string, object>)binaryFormatter.Deserialize(fileStream); } catch (Exception data) { Logs.LogError(data); flag = true; } finally { fileStream.Close(); } if (flag) { File.Delete(FilePath); } } public static void Clear() { _data.Clear(); } } internal sealed class DevConsoleMono : MonoBehaviour { private abstract class StatBase { public abstract string Desc { get; } public abstract object GetResult(Evaluator evaluator); public abstract override string ToString(); } private sealed class EvaluatedStat : StatBase { public override string Desc => "Evaluated"; public string Expression { get; } public EvaluatedStat(string expression) { Expression = expression; } public override object GetResult(Evaluator evaluator) { if (evaluator == null) { return "C# expression evaluation is not supported on this platform."; } return ((evaluator != null) ? evaluator.Evaluate(Expression) : null) ?? null; } public override string ToString() { return Expression; } } private sealed class LambdaStat : StatBase { private readonly Func<object> _func; public override string Desc => "Lambda"; public LambdaStat(Func<object> func) { _func = func; } public override object GetResult(Evaluator _ = null) { return _func?.Invoke() ?? null; } public override string ToString() { return "Cannot be viewed"; } } private sealed class ReflectedStat : StatBase { private readonly FieldInfo _field; private readonly PropertyInfo _property; public override string Desc => "Reflected"; public ReflectedStat(FieldInfo field) { _field = field; } public ReflectedStat(PropertyInfo property) { _property = property; } public override object GetResult(Evaluator _ = null) { object obj = _field?.GetValue(null); if (obj == null) { PropertyInfo property = _property; if ((object)property == null) { return null; } obj = property.GetValue(null); } return obj; } public override string ToString() { return _field?.FieldType.Name ?? _property.PropertyType.Name; } } private const string ErrorColour = "#E99497"; private const string WarningColour = "#DEBF1F"; private const string SuccessColour = "#B3E283"; private const string ClearLogText = "Type <b>devconsole</b> for instructions on how to use the developer console."; private const int MaximumTextVertices = 64000; private const float MinConsoleWidth = 650f; private const float MaxConsoleWidth = 1600f; private const float MinConsoleHeight = 200f; private const float MaxConsoleHeight = 900f; private const int MinLogTextSize = 14; private const int MaxLogTextSize = 35; private const int CommandHistoryLength = 10; private const int MaxCachedEnumTypes = 6; private const float FpsUpdateRate = 4f; private const float StatUpdateRate = 0.1f; private const int StatDefaultFontSize = 18; private const string MonoNotSupportedText = "C# expression evaluation is not supported on this platform."; private const KeyCode DefaultToggleKey = 96; private const KeyCode UpArrowKey = 273; private const KeyCode DownArrowKey = 274; private const KeyCode BackspaceKey = 8; private const KeyCode LeftControlKey = 306; private const string InputSystemPrefabPath = "ASSETS/UNITY-DEVELOPERCONSOLE/RESOURCES/PREFABS/FAB_DEVCONSOLE.OLDEVENTSYSTEM.PREFAB"; private const string PrefConsoleToggleKey = "DevConsole.legacyConsoleToggleKey"; private const string PrefBindings = "DevConsole.legacyBindings"; private const string PrefDisplayUnityLogs = "DevConsole.displayUnityLogs"; private const string PrefDisplayUnityErrors = "DevConsole.displayUnityErrors"; private const string PrefDisplayUnityExceptions = "DevConsole.displayUnityExceptions"; private const string PrefDisplayUnityWarnings = "DevConsole.displayUnityWarnings"; private const string PrefShowFps = "DevConsole.displayFps"; private const string PrefLogTextSize = "DevConsole.logTextSize"; private const string PrefIncludedUsings = "DevConsole.includedUsings"; private const string PrefShowStats = "DevConsole.displayStats"; private const string PrefStats = "DevConsole.stats"; private const string PrefHiddenStats = "DevConsole.hiddenStats"; private const string PrefStatsFontSize = "DevConsole.statsFontSize"; private const string PrefPersistStats = "DevConsole.persistStats"; private static readonly Version _version = new Version(1, 0, 12); private static readonly string[] _permanentCommands = new string[9] { "devconsole", "commands", "help", "print", "clear", "reset", "bind", "unbind", "bindings" }; private CanvasGroup _canvasGroup; private Text _versionText; private InputField _inputField; private Text _suggestionText; private GameObject _logFieldPrefab; private RectTransform _logContentTransform; private ScrollRect _logScrollView; private RectTransform _dynamicTransform; private Image _resizeButtonImage; private Color _resizeButtonHoverColour; private Button _closeButton; private Button _decreaseTextSizeButton; private Button _increaseTextSizeButton; private EventTrigger _resizeButtonEventTrigger; private EventTrigger _repositioningButtonEventTrigger; private bool _init; private bool _focusInputField; private bool _oldFocusInputField; private Dictionary<KeyCode, string> _bindings = new Dictionary<KeyCode, string>(); private bool _ignoreCtrlBackspace; private readonly List<InputField> _logFields = new List<InputField>(); private string _logTextStore = ""; private readonly TextGenerator _textGenerator = new TextGenerator(); private int _vertexCount; private int _initLogTextSize; private bool _pretendScrollAtBottom; private bool _scrollToBottomNextFrame; private bool _repositioning; private Vector2 _initPosition; private Vector2 _repositionOffset; private bool _resizing; private Vector2 _initSize; private Color _resizeButtonColour; private float _initLogFieldWidth; private float _currentLogFieldWidth; private Vector2Int _screenSize; private readonly Dictionary<string, Command> _commands = new Dictionary<string, Command>(); private readonly Dictionary<Type, Func<string, object>> _parameterParseFuncs = new Dictionary<Type, Func<string, object>>(); private readonly List<string> _commandHistory = new List<string>(10); private string _currentCommand = string.Empty; private string _previousCommand = string.Empty; private int _commandHistoryIndex = -1; private bool _displayUnityLogs = true; private bool _displayUnityErrors = true; private bool _displayUnityExceptions = true; private bool _displayUnityWarnings = true; private string[] _commandStringSuggestions; private Command[] _commandSuggestions; private int _commandSuggestionIndex; private readonly List<Type> _cacheEnumTypes = new List<Type>(6); private Evaluator _monoEvaluator; private List<string> _includedUsings = new List<string>(); private bool _isDisplayingFps; private float _fpsDeltaTime; private int _fps; private float _fpsMs; private float _fpsElapsed; private GUIStyle _fpsStyle; private Vector2 _fpsLabelSize; private Color _fpsTextColour; private bool _isDisplayingStats; private GUIStyle _statStyle; private readonly Dictionary<string, StatBase> _stats = new Dictionary<string, StatBase>(); private HashSet<string> _hiddenStats = new HashSet<string>(); private readonly Dictionary<string, object> _cachedStats = new Dictionary<string, object>(); private List<string> _persistStats = new List<string>(); private float _statUpdateTime; private int _statFontSize = 18; internal static CursorLockMode lastLockMode; internal static bool lastVisible; public static DevConsoleMono Instance { get; private set; } internal KeyCode? ConsoleToggleKey { get; set; } = (KeyCode)96; internal bool ConsoleIsEnabled { get; private set; } internal bool ConsoleIsShowing { get; private set; } internal bool ConsoleIsShowingAndFocused { get { if (ConsoleIsShowing) { return _inputField.isFocused; } return false; } } internal bool BindingsIsEnabled { get; set; } = true; internal int AverageFps { get { if (!_isDisplayingFps) { return -1; } return _fps; } } internal float AverageMs { get { if (!_isDisplayingFps) { return -1f; } return _fpsMs; } } private string InputText { get { return _inputField.text; } set { _inputField.text = value; } } private int InputCaretPosition { get { return _inputField.caretPosition; } set { _inputField.caretPosition = value; } } private string StoredLogText { get { lock (_logTextStore) { return _logTextStore; } } set { lock (_logTextStore) { _logTextStore = value; } } } private int LogTextSize { get { return _logFieldPrefab.GetComponent<InputField>().textComponent.fontSize; } set { Text textComponent = _logFieldPrefab.GetComponent<InputField>().textComponent; if (textComponent.fontSize == value) { return; } textComponent.fontSize = value; List<InputField> logFields = _logFields; if (logFields != null && logFields.Count > 0) { _logFields.ForEach(delegate(InputField x) { x.textComponent.fontSize = value; }); RefreshLogFieldsSize(); } } } internal void EnableConsole() { //IL_0043: 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) if (_init || !ConsoleIsEnabled) { Application.logMessageReceivedThreaded += LogCallback.op_Implicit((Action<string, string, LogType>)OnLogMessageReceived); ClearConsole(); InputText = string.Empty; _screenSize = new Vector2Int(Screen.width, Screen.height); ConsoleIsEnabled = true; ((Behaviour)this).enabled = true; DevConsole.InvokeOnConsoleEnabled(); } } internal void DisableConsole() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (_init || ConsoleIsEnabled) { if (ConsoleIsShowing) { CloseConsole(); } _dynamicTransform.anchoredPosition = _initPosition; _dynamicTransform.sizeDelta = _initSize; _commandHistory.Clear(); _cacheEnumTypes.Clear(); ClearConsole(); Application.logMessageReceived -= LogCallback.op_Implicit((Action<string, string, LogType>)OnLogMessageReceived); ConsoleIsEnabled = false; ((Behaviour)this).enabled = false; DevConsole.InvokeOnConsoleDisabled(); } } internal void OpenConsole() { //IL_0019: 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) if (_init || (ConsoleIsEnabled && !ConsoleIsShowing)) { lastLockMode = Cursor.lockState; lastVisible = Cursor.visible; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; if ((Object)(object)EventSystem.current == (Object)null) { EventSystem.current = Object.Instantiate<GameObject>(((Il2CppObjectBase)DevConsole.s_AssetLookup["ASSETS/UNITY-DEVELOPERCONSOLE/RESOURCES/PREFABS/FAB_DEVCONSOLE.OLDEVENTSYSTEM.PREFAB"]).Cast<GameObject>()).GetComponent<EventSystem>(); ((Object)((Component)EventSystem.current).gameObject).name = "EventSystem"; } _canvasGroup.alpha = 1f; _canvasGroup.interactable = true; _canvasGroup.blocksRaycasts = true; ConsoleIsShowing = true; _focusInputField = true; DevConsole.InvokeOnConsoleOpened(); } } internal void CloseConsole() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (_init || (ConsoleIsEnabled && ConsoleIsShowing)) { Cursor.lockState = lastLockMode; Cursor.visible = lastVisible; _canvasGroup.alpha = 0f; _canvasGroup.interactable = false; _canvasGroup.blocksRaycasts = false; ConsoleIsShowing = false; _repositioning = false; _resizing = false; _focusInputField = false; if (_inputField.isFocused && (Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } DevConsole.InvokeOnConsoleClosed(); } } internal void ToggleConsole() { if (ConsoleIsShowing) { CloseConsole(); } else { OpenConsole(); } } internal void ClearConsole() { ClearLogFields(); _vertexCount = 0; StoredLogText = "Type <b>devconsole</b> for instructions on how to use the developer console."; _pretendScrollAtBottom = true; } internal void ResetConsole() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) _dynamicTransform.anchoredPosition = _initPosition; _dynamicTransform.sizeDelta = _initSize; _currentLogFieldWidth = _initLogFieldWidth; RefreshLogFieldsSize(); } internal void SubmitInput() { if (!string.IsNullOrWhiteSpace(InputText) && RunCommand(InputText)) { _scrollToBottomNextFrame = true; } InputText = string.Empty; } internal bool RunCommand(string rawInput) { string[] input = GetInput(rawInput); Command command = GetCommand(input[0]); AddToCommandHistory(input[0], rawInput); if (command == null) { string text = TryEvaluateInput(rawInput); if (!string.IsNullOrEmpty(text)) { Log(text); return false; } LogError("Could not find the specified command: \"" + input[0] + "\"."); return false; } input = ConvertInput(input, command.Parameters.Length); if (input.Length == 1 && command.DefaultCallback != null) { try { command.DefaultCallback(); } catch (Exception ex) { LogError("Command default callback threw an exception."); Logs.LogMessage(ex.Message); return false; } return true; } if (command.Parameters.Length != input.Length - 1) { LogError("Invalid number of parameters: " + command.ToFormattedString() + "."); return false; } object[] array = new object[command.Parameters.Length]; for (int i = 0; i < array.Length; i++) { string text2 = input[i + 1]; try { array[i] = ParseParameter(text2, command.Parameters[i].Type); } catch (Exception) { LogError("Invalid parameter type: \"" + text2 + "\". Expected " + command.GetFormattedParameter(i) + "."); return false; } } try { command.Callback((array.Length == 0) ? null : array); } catch (Exception ex3) { LogError("Command callback threw an exception."); Logs.LogMessage(ex3.Message); return false; } return true; } internal bool AddCommand(Command command, bool onlyInDevBuild = false, bool isCustomCommand = false) { if (onlyInDevBuild && !Debug.isDebugBuild) { return false; } command.FixName(); command.FixAliases(); if (!string.IsNullOrEmpty(command.Name) && !_commands.ContainsKey(command.Name) && !_commands.Values.Select((Command c) => c.Aliases).Any((string[] a) => command.HasAlias(a))) { if (DevConsole.isInit) { _commands.Add(command.Name, command); } else { DevConsole._commandsNeedToAdd.Add(command, onlyInDevBuild); } if (isCustomCommand) { command.SetAsCustomCommand(); } return true; } return false; } internal bool RemoveCommand(string name) { Command command = GetCommand(name); if (command == null) { return true; } if (_permanentCommands.Contains(command.Name)) { return false; } return _commands.Remove(command.Name); } internal Command GetCommand(string name) { if (!_commands.TryGetValue(name.ToLower(), out var value)) { return _commands.Values.FirstOrDefault((Command c) => c.HasAlias(name)); } return value; } internal bool GetCommand(string name, out Command command) { if (!_commands.TryGetValue(name.ToLower(), out command)) { return (command = _commands.Values.FirstOrDefault((Command c) => c.HasAlias(name))) != null; } return true; } internal bool AddParameterType(Type type, Func<string, object> parseFunc) { if (!_parameterParseFuncs.ContainsKey(type)) { _parameterParseFuncs.Add(type, parseFunc); return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Log(object message) { StoredLogText += $"\n{message}"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Log(object message, string htmlColour) { Log($"<color={htmlColour}>{message}</color>"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogVariable(string variableName, object value, string suffix = "") { Log($"{variableName}: {value}{suffix}."); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogException(Exception exception) { if (exception != null) { Log(string.Format("({0:HH:mm:ss}) <color={1}><b>Exception:</b> </color>{2}", DateTime.Now, "#E99497", exception.Message)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogError(object message) { Log(message, "#E99497"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogWarning(object message) { Log(message, "#DEBF1F"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogSuccess(object message) { Log(message, "#B3E283"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogSeperator(object message = null) { if (message == null) { Log("-"); } else { Log($"- <b>{message}</b> -"); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogCollection<T>(in IReadOnlyCollection<T> collection, Func<T, string> toString = null, string prefix = "", string suffix = "") { if (collection != null && collection.Count != 0) { Log(string.Join("\n", collection.Select((T x) => prefix + (toString?.Invoke(x) ?? x.ToString()) + suffix))); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogCommand() { LogCommand(_currentCommand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LogCommand(string name) { if (GetCommand(name, out var command)) { Log(">> " + command.ToFormattedString() + "."); } } internal void OnInputValueChanged(string _) { if (!_ignoreCtrlBackspace && GetKey((KeyCode)306) && GetKeyDown((KeyCode)8)) { string text = InputText.Substring(0, InputCaretPosition); string text2 = InputText.Substring(InputCaretPosition, InputText.Length - InputCaretPosition); string[] array = text.Split(new char[1] { ' ' }); int num = 0; for (int i = 0; i < array.Length - 1; i++) { num += array[i].Length + 1; } _ignoreCtrlBackspace = true; InputText = InputText.Substring(0, num) + text2; _ignoreCtrlBackspace = false; InputCaretPosition = num; } RefreshCommandSuggestions(); RefreshCommandParameterSuggestions(); if (_inputField.text.Length != 0 && !GetKeyDown((KeyCode)273)) { OnValidateInput(); } } internal void OnValidateInput() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (InputText.Length != 0 && ConsoleToggleKey.HasValue && GetKeyDown(ConsoleToggleKey.Value)) { InputText = InputText.Substring(0, InputText.Length - 1); } else if (InputText[Math.Max(0, InputCaretPosition - 1)] == '\t') { InputText = InputText.Substring(0, InputText.Length - 1); AutoComplete(); } else if (InputText[Math.Max(0, InputCaretPosition - 1)] == '\n') { StringBuilder stringBuilder = new StringBuilder(InputText); stringBuilder.Remove(InputCaretPosition - 1, 1); InputText = stringBuilder.ToString(); SubmitInput(); } } internal void OnRepositionButtonPointerDown(BaseEventData eventData) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) _repositioning = true; _repositionOffset = ((Il2CppObjectBase)eventData).Cast<PointerEventData>().position - Vector2.op_Implicit(((Transform)_dynamicTransform).position); } internal void OnRepositionButtonPointerUp(BaseEventData _) { _repositioning = false; } internal void OnResizeButtonPointerDown(BaseEventData _) { _resizing = true; } internal void OnResizeButtonPointerUp(BaseEventData _) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) _resizing = false; ((Graphic)_resizeButtonImage).color = _resizeButtonColour; RefreshLogFieldsSize(); } internal void OnResizeButtonPointerEnter(BaseEventData _) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) ((Graphic)_resizeButtonImage).color = _resizeButtonColour * _resizeButtonHoverColour; } internal void OnResizeButtonPointerExit(BaseEventData _) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!_resizing) { ((Graphic)_resizeButtonImage).color = _resizeButtonColour; } } internal void OnAuthorButtonPressed() { } internal void OnIncreaseTextSizeButtonPressed() { LogTextSize = Math.Min(35, LogTextSize + 4); } internal void OnDecreaseTextSizeButtonPressed() { LogTextSize = Math.Max(14, LogTextSize - 4); } private void OnLogMessageReceived(string logString, string _, LogType type) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected I4, but got Unknown string text = DateTime.Now.ToString("HH:mm:ss"); switch ((int)type) { case 3: if (_displayUnityLogs) { Log("(" + text + ") <b>Log:</b> " + logString); } break; case 0: if (_displayUnityErrors) { Log("(" + text + ") <color=#E99497><b>Error:</b> </color>" + logString); } break; case 4: if (_displayUnityExceptions) { Log("(" + text + ") <color=#E99497><b>Exception:</b> </color>" + logString); } break; case 2: if (_displayUnityWarnings) { Log("(" + text + ") <color=#DEBF1F><b>Warning:</b> </color>" + logString); } break; case 1: break; } } private void Awake() { //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Expected O, but got Unknown //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Expected O, but got Unknown //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Expected O, but got Unknown //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Expected O, but got Unknown //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Expected O, but got Unknown //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Expected O, but got Unknown //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) Instance = this; _init = true; ((Object)((Component)this).gameObject).name = "DevConsoleInstance"; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); _canvasGroup = ((Component)((Component)this).transform).GetComponentInChildren<CanvasGroup>(); foreach (Text item in ((IEnumerable<Text>)((Component)((Component)this).transform).GetComponentsInChildren<Text>()).ToList()) { switch (((Object)item).name) { case "SuggestionText": _suggestionText = item; break; case "VersionText": _versionText = item; break; case "AuthorText": item.text = "Hikaria"; break; } } foreach (RectTransform item2 in ((IEnumerable<RectTransform>)((Component)((Component)this).transform).GetComponentsInChildren<RectTransform>()).ToList()) { switch (((Object)item2).name) { case "Content": _logContentTransform = item2; break; case "BackPanel": _dynamicTransform = item2; break; case "ResizeButton": _resizeButtonEventTrigger = ((Component)item2).GetComponent<EventTrigger>(); break; case "RepositionButton": _repositioningButtonEventTrigger = ((Component)item2).GetComponent<EventTrigger>(); break; } } foreach (Image item3 in ((IEnumerable<Image>)((Component)((Component)this).transform).GetComponentsInChildren<Image>()).ToList()) { if (((Object)item3).name == "ResizeButton") { _resizeButtonImage = item3; } } foreach (InputField item4 in ((IEnumerable<InputField>)((Component)((Component)this).transform).GetComponentsInChildren<InputField>()).ToList()) { if (((Object)item4).name == "InputField") { _inputField = item4; } } foreach (ScrollRect item5 in ((IEnumerable<ScrollRect>)((Component)((Component)this).transform).GetComponentsInChildren<ScrollRect>()).ToList()) { if (((Object)item5).name == "Scroll View") { _logScrollView = item5; } } foreach (RectTransform item6 in ((IEnumerable<RectTransform>)((Component)((Component)this).transform).GetComponentsInChildren<RectTransform>()).ToList()) { if (((Object)((Component)((Transform)item6).parent).gameObject).name == "LogField.Instance") { _logFieldPrefab = ((Component)((Transform)item6).parent).gameObject; } } foreach (Button item7 in ((IEnumerable<Button>)((Component)((Component)this).transform).GetComponentsInChildren<Button>()).ToList()) { switch (((Object)item7).name) { case "DecreaseTextSizeButton": _decreaseTextSizeButton = item7; break; case "IncreaseTextSizeButton": _increaseTextSizeButton = item7; break; case "CloseButton": _closeButton = item7; break; } } Entry val = new Entry(); val.eventID = (EventTriggerType)3; ((UnityEvent<BaseEventData>)(object)val.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)OnResizeButtonPointerUp)); _resizeButtonEventTrigger.triggers.Add(val); Entry val2 = new Entry(); val2.eventID = (EventTriggerType)2; ((UnityEvent<BaseEventData>)(object)val2.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)OnResizeButtonPointerDown)); _resizeButtonEventTrigger.triggers.Add(val2); Entry val3 = new Entry(); val3.eventID = (EventTriggerType)1; ((UnityEvent<BaseEventData>)(object)val3.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)OnResizeButtonPointerExit)); _resizeButtonEventTrigger.triggers.Add(val3); Entry val4 = new Entry(); val4.eventID = (EventTriggerType)0; ((UnityEvent<BaseEventData>)(object)val4.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)OnResizeButtonPointerEnter)); _resizeButtonEventTrigger.triggers.Add(val4); Entry val5 = new Entry(); val5.eventID = (EventTriggerType)3; ((UnityEvent<BaseEventData>)(object)val5.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)OnRepositionButtonPointerUp)); _repositioningButtonEventTrigger.triggers.Add(val5); Entry val6 = new Entry(); val6.eventID = (EventTriggerType)2; ((UnityEvent<BaseEventData>)(object)val6.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)OnRepositionButtonPointerDown)); _repositioningButtonEventTrigger.triggers.Add(val6); ((UnityEvent)_closeButton.onClick).AddListener(UnityAction.op_Implicit((Action)CloseConsole)); ((UnityEvent)_increaseTextSizeButton.onClick).AddListener(UnityAction.op_Implicit((Action)OnIncreaseTextSizeButtonPressed)); ((UnityEvent)_decreaseTextSizeButton.onClick).AddListener(UnityAction.op_Implicit((Action)OnDecreaseTextSizeButtonPressed)); _resizeButtonHoverColour = Color.white; _versionText.text = $"v{_version}"; _initPosition = _dynamicTransform.anchoredPosition; _initSize = _dynamicTransform.sizeDelta; _initLogFieldWidth = _logFieldPrefab.GetComponent<RectTransform>().sizeDelta.x; _initLogTextSize = _logFieldPrefab.GetComponent<InputField>().textComponent.fontSize; _currentLogFieldWidth = _initLogFieldWidth; _resizeButtonColour = ((Graphic)_resizeButtonImage).color; _logFieldPrefab.SetActive(false); ((UnityEvent<string>)(object)_inputField.onValueChanged).AddListener(UnityAction<string>.op_Implicit((Action<string>)delegate(string s) { OnInputValueChanged(s); })); LoadPreferences(); InitBuiltInCommands(); InitBuiltInParsers(); InitAttributes(); InitMonoEvaluator(); _persistStats.Clear(); EnableConsole(); ClearConsole(); CloseConsole(); if (_monoEvaluator == null) { LogWarning("Some features may not be available: C# expression evaluation is not supported on this platform."); } _init = false; } private void Update() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) if (!ConsoleIsEnabled || !ConsoleIsShowing) { return; } if (_scrollToBottomNextFrame) { _logScrollView.verticalNormalizedPosition = 0f; LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)((Component)_logScrollView).transform).GetComponent<RectTransform>()); if (_pretendScrollAtBottom && (_logScrollView.verticalNormalizedPosition < 0f || Mathf.Approximately(_logScrollView.verticalNormalizedPosition, 0f))) { _pretendScrollAtBottom = false; } _scrollToBottomNextFrame = false; } if (((Vector2Int)(ref _screenSize)).x != Screen.width || ((Vector2Int)(ref _screenSize)).y != Screen.height) { _screenSize = new Vector2Int(Screen.width, Screen.height); ResetConsole(); } if (_focusInputField) { EventSystem.current.SetSelectedGameObject(((Component)_inputField).gameObject, (BaseEventData)null); _focusInputField = false; } if (_inputField.isFocused != _oldFocusInputField) { if (_inputField.isFocused) { DevConsole.InvokeOnConsoleFocused(); } else { DevConsole.InvokeOnConsoleFocusLost(); } _oldFocusInputField = _inputField.isFocused; } if (_repositioning) { Vector2 mousePosition = GetMousePosition(); ((Transform)_dynamicTransform).position = new Vector3(mousePosition.x - _repositionOffset.x, mousePosition.y - _repositionOffset.y, ((Transform)_dynamicTransform).position.z); } if (_resizing) { Vector2 val = default(Vector2); RectTransformUtility.ScreenPointToLocalPointInRectangle(_dynamicTransform, GetMousePosition(), (Camera)null, ref val); val.x = Mathf.Clamp(Mathf.Abs(val.x), 650f, 1600f); val.y = Mathf.Clamp(Mathf.Abs(val.y), 200f, 900f); _dynamicTransform.sizeDelta = val; _currentLogFieldWidth = _initLogFieldWidth * (_dynamicTransform.sizeDelta.x / _initSize.x); } } private void LateUpdate() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) if (!ConsoleIsEnabled) { return; } if (_isDisplayingFps) { _fpsDeltaTime += (Time.unscaledDeltaTime - _fpsDeltaTime) * 0.1f; _fpsElapsed += Time.deltaTime; if (_fpsElapsed > 0.25f) { _fpsMs = _fpsDeltaTime * 1000f; _fps = Mathf.RoundToInt(1f / _fpsDeltaTime); _fpsElapsed -= 0.25f; _fpsTextColour = Color.white; if ((Application.targetFrameRate == -1 && _fps >= 60) || (Application.targetFrameRate != -1 && _fps >= Application.targetFrameRate)) { _fpsTextColour = Color.green; } else if (_fps < 10) { _fpsTextColour = Color.red; } else if (_fps < 30 && (Application.targetFrameRate > 30 || Application.targetFrameRate == -1)) { _fpsTextColour = Color.yellow; } } } if (BindingsIsEnabled && !_inputField.isFocused && ((Object)(object)EventSystem.current == (Object)null || (Object)(object)EventSystem.current.currentSelectedGameObject == (Object)null)) { if ((int)FocusStateManager.CurrentState == 8 || PlayerChatManager.InChatMode) { return; } try { foreach (KeyCode key in _bindings.Keys) { if (GetKeyDown(key)) { RunCommand(_bindings[key]); } } } catch (Exception ex) { LogError("Checking bindings failed with an exception: " + ex.Message); } } if (StoredLogText != string.Empty) { if (_pretendScrollAtBottom || _logScrollView.verticalNormalizedPosition < 0.001f || Mathf.Approximately(_logScrollView.verticalNormalizedPosition, 0.001f)) { _scrollToBottomNextFrame = true; } string logText = string.Copy(StoredLogText); StoredLogText = string.Empty; ProcessLogText(in logText); RebuildLayout(); } if (ConsoleToggleKey.HasValue && (!ConsoleIsShowing || !_inputField.isFocused || InputText.Length <= 1) && GetKeyDown(ConsoleToggleKey.Value)) { ToggleConsole(); } else { if (!ConsoleIsShowing || !_inputField.isFocused) { return; } if (_commandStringSuggestions != null && _commandStringSuggestions.Length != 0) { if (GetKeyDown((KeyCode)273)) { CycleCommandSuggestions(1); } else if (GetKeyDown((KeyCode)274)) { CycleCommandSuggestions(-1); } return; } if (string.IsNullOrEmpty(InputText) && _commandHistoryIndex != -1) { _commandHistoryIndex = -1; } if (GetKeyDown((KeyCode)273)) { CycleCommandHistory(1); } else if (GetKeyDown((KeyCode)274)) { CycleCommandHistory(-1); } } } private void OnGUI() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0077: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) if (!ConsoleIsEnabled) { return; } if (_isDisplayingFps) { if (_fpsStyle == null || _statFontSize != _fpsStyle.fontSize) { GUIStyle val = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = _statFontSize }; val.normal.textColor = Color.white; val.normal.background = Texture2D.whiteTexture; _fpsStyle = val; _fpsLabelSize = _fpsStyle.CalcSize(new GUIContent("0.00 ms (000 fps)")); } Color backgroundColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; GUI.backgroundColor = new Color(0f, 0f, 0f, 0.75f); GUI.contentColor = _fpsTextColour; GUI.Box(new Rect(10f, 10f, _fpsLabelSize.x + 10f, _fpsLabelSize.y + 10f), $"{_fpsMs:0.00} ms ({_fps:0.} fps)", _fpsStyle); GUI.backgroundColor = backgroundColor; GUI.contentColor = contentColor; } if (!_isDisplayingStats || !_stats.Any()) { return; } if (_statStyle == null || _statFontSize != _statStyle.fontSize) { GUIStyle val2 = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = _statFontSize }; val2.normal.textColor = Color.white; val2.normal.background = Texture2D.whiteTexture; _statStyle = val2; } Color backgroundColor2 = GUI.backgroundColor; Color contentColor2 = GUI.contentColor; GUI.backgroundColor = new Color(0f, 0f, 0f, 0.75f); float num = 10f + (_isDisplayingFps ? (_fpsLabelSize.y + 10f) : 0f); int num2 = 0; bool flag = Time.time > _statUpdateTime; if (flag) { _statUpdateTime = Time.time + 0.1f; } foreach (KeyValuePair<string, StatBase> stat in _stats) { if (_hiddenStats.Contains(stat.Key)) { continue; } object obj; if (stat.Value is EvaluatedStat && !flag && _cachedStats.ContainsKey(stat.Key)) { obj = _cachedStats[stat.Key]; } else { try { obj = stat.Value.GetResult(_monoEvaluator); } catch (Exception) { obj = "ERROR"; } if (stat.Value is EvaluatedStat) { _cachedStats[stat.Key] = obj; } } string text = string.Format("{0}: {1}", stat.Key, obj ?? "NULL"); GUI.contentColor = ((obj == null) ? Color.yellow : ((obj.Equals("ERROR") || obj.Equals("C# expression evaluation is not supported on this platform.")) ? Color.red : Color.white)); Vector2 val3 = _statStyle.CalcSize(new GUIContent(text)); GUI.Box(new Rect(10f, num + ((float)num2 * (val3.y + 10f + 5f) + 5f), val3.x + 10f, val3.y + 10f), text, _statStyle); num2++; } GUI.backgroundColor = backgroundColor2; GUI.contentColor = contentColor2; } private void OnDestroy() { SavePreferences(); } private void InitBuiltInCommands() { AddCommand(Command.Create("devconsole", "", "Display instructions on how to use the developer console", delegate { LogSeperator($"Developer console (v{_version})"); Log("Use <b>commands</b> to display a list of available commands."); Log("Use " + GetCommand("help").ToFormattedString() + " to display information about a specific command."); Log("Use UP / DOWN to cycle through command history or suggested commands."); Log("Use TAB to autocomplete a suggested command.\n"); Log("Created by @Hikaria."); LogSeperator(); })); AddCommand(Command.Create("print", "echo", "Display a message in the developer console", Parameter.Create("message", "Message to display"), delegate(string s) { Log(s); })); AddCommand(Command.Create("clear", "", "Clear the developer console", delegate { ClearConsole(); })); AddCommand(Command.Create("reset", "", "Reset the position and size of the developer console", delegate { ResetConsole(); })); AddCommand(Command.Create("closeconsole", "hideconsole", "Close the developer console window", delegate { CloseConsole(); })); AddCommand(Command.Create("help", "info", "Display information about a specified command", Parameter.Create("commandName", "Name of the command to get information about"), delegate(string s) { Command command8 = GetCommand(s); if (command8 == null) { LogError("Unknown command name specified: \"" + s + "\". Use <b>list</b> for a list of all commands."); } else { LogSeperator(command8.Name); if (!string.IsNullOrEmpty(command8.HelpText)) { Log(command8.HelpText + "."); } string[] aliases = command8.Aliases; if (aliases != null && aliases.Length != 0 && command8.Aliases.Any((string a) => !string.IsNullOrEmpty(a))) { string[] value = command8.Aliases.Select((string alias) => "<i>" + alias + "</i>").ToArray(); Log("Aliases: " + string.Join(", ", value) + "."); } if (command8.Parameters.Length != 0) { Log("Syntax: " + command8.ToFormattedString() + "."); } Parameter[] parameters = command8.Parameters; foreach (Parameter parameter in parameters) { if (!string.IsNullOrEmpty(parameter.HelpText)) { Log(" <b>" + parameter.Name + "</b>: " + parameter.HelpText + "."); } } LogSeperator(); } }, delegate { if (string.IsNullOrWhiteSpace(_previousCommand) || _previousCommand.ToLower().Equals("help")) { RunCommand("help help"); } else { RunCommand("help " + _previousCommand); } })); AddCommand(Command.Create("enum", "", "Display information about a specified enum", Parameter.Create("enumName", "Name of the enum to get information about (case-sensitive)"), delegate(string s) { Type type = _cacheEnumTypes.FirstOrDefault((Type t) => t.Name.Equals(s)); if (type == null) { List<Type> list2 = new List<Type>(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetTypes().SelectMany((Type t) => t.GetMembers()).Union(assembly.GetTypes()) .FirstOrDefault((MemberInfo t) => t.ReflectedType != null && t.ReflectedType.IsEnum && (t.ReflectedType.Name.Equals(s) || s.Equals(t.ReflectedType.Namespace + "." + t.ReflectedType.Name)))?.ReflectedType; if (type != null) { if (s.Equals(type.Namespace + "." + type.Name)) { list2 = new List<Type> { type }; break; } list2.Add(type); } } if (list2.Count > 1) { LogError("Multiple results found: " + string.Join(", ", list2.Select((Type x) => x.Namespace + "." + x.Name)) + "."); return; } if (list2.Count != 1) { LogError("Could not find enum type with the specified name: \"" + s + "\""); return; } type = list2.FirstOrDefault(); _cacheEnumTypes.Add(type); if (_cacheEnumTypes.Count > 6) { _cacheEnumTypes.RemoveAt(0); } } LogSeperator(type.Namespace + "." + type.Name + " (" + type.GetEnumUnderlyingType().Name + ")" + ((type.GetCustomAttribute(typeof(FlagsAttribute)) == null) ? "" : " [Flags]")); FieldInfo[] fields = type.GetFields(); string text2 = string.Empty; bool flag = true; for (int num4 = 0; num4 < fields.Length; num4++) { if (!fields[num4].Name.Equals("value__")) { text2 += string.Format("{0}{1} = {2}", flag ? "" : "\n", fields[num4].Name, fields[num4].GetRawConstantValue()); flag = false; } } Log(text2); LogSeperator(); })); AddCommand(Command.Create("commands", "", "Display a sorted list of all available commands", delegate { LogSeperator("Commands"); Log(string.Join(", ", _commands.Keys.OrderBy((string s) => s))); LogSeperator(); })); AddCommand(Command.Create("customcommands", "", "Display a sorted list of all available custom commands", delegate { IList<string> list = _commands.Keys.Where((string s) => _commands[s].IsCustomCommand).ToList(); if (list != null && list.Count == 0) { Log("There are no custom commands defined."); } else { LogSeperator("Custom commands"); Log(string.Join(", ", list.OrderBy((string s) => s))); LogSeperator(); } })); AddCommand(Command.Create("consoleversion", "", "Display the developer console version", delegate { Log($"Developer console version: {_version}."); })); AddCommand(Command.Create("bind", "addbind", "Add a key binding for a command", Parameter.Create("Key", "Key to bind the command to"), Parameter.Create("Command", "Command to execute when the key bind is pressed"), delegate(KeyCode key, string command) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (_bindings.ContainsKey(key)) { LogError(string.Format("A key binding already exists for <i>{0}</i>. Use {1} to remove the key binding.", key, GetCommand("unbind").ToFormattedString())); } else { _bindings[key] = command; LogSuccess($"Successfully added a key binding for <i>{key}</i>."); } })); AddCommand(Command.Create("unbind", "removebind", "Remove a key binding", Parameter.Create("Key", "Key binding to remove"), delegate(KeyCode key) { //IL_0006: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!_bindings.ContainsKey(key)) { LogError($"A key binding doesn't exist for <i>{key}</i>."); } else { _bindings.Remove(key); LogSuccess($"Successfully removed a key binding for <i>{key}</i>."); } })); AddCommand(Command.Create("binds", "", "List all the key bindings", delegate { if (_bindings.Count == 0) { Log("There are no key bindings. Use " + GetCommand("bind").GetFormattedName() + " to add a key binding."); } else { LogSeperator($"Key bindings ({_bindings.Count})"); Log(string.Join("\n", _bindings.Keys.Select((KeyCode x) => $"<i>{x}</i>: \"{_bindings[x]}\""))); LogSeperator(); } })); AddCommand(Command.Create("log_size", "", "Query or set the font size used in the developer console log", Parameter.Create("fontSize", ""), delegate(int fontSize) { if (fontSize < 14 || fontSize > 35) { LogError($"Invalid font size specified: {fontSize}. Must be between {14} and {35}."); } else { int logTextSize = LogTextSize; LogTextSize = fontSize; LogSuccess($"Successfully changed the log font size to {fontSize} (was {logTextSize})."); } }, delegate { LogVariable("Log font size", _logFields.First().textComponent.fontSize, $" (Default: {_initLogTextSize})"); })); AddCommand(Command.Create("quit", "exit", "Exit the player application", delegate { if (Application.isEditor) { LogError("Cannot quit the player application when running in the Editor."); } else { Application.Quit(); } })); AddCommand(Command.Create("appversion", "", "Display the application version", delegate { LogVariable("App version", Application.version); })); AddCommand(Command.Create("unityversion", "", "Display the engine version", delegate { LogVariable("Engine version", Application.unityVersion); })); AddCommand(Command.Create("unityinput", "", "Display the input system being used by the developer console", delegate { Log("The legacy input system is currently being used."); })); AddCommand(Command.Create("path", "", "Display the path to the application executable", delegate { LogVariable("Application path", AppDomain.CurrentDomain.BaseDirectory); })); AddCommand(Command.Create("fullscreen", "", "Query or set whether the window is full screen", Parameter.Create("enabled", "Whether the window is full screen (use \"NULL\" to toggle)"), delegate(bool? b) { if (!b.HasValue) { b = !Screen.fullScreen; } Screen.fullScreen = b.Value; LogSuccess((b.Value ? "Enabled" : "Disabled") + " fullscreen mode."); }, delegate { LogVariable("Full screen", Screen.fullScreen); })); AddCommand(Command.Create("fullscreen_mode", "", "Query or set the full screen mode", Parameter.Create("mode", ""), delegate(FullScreenMode m) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Screen.fullScreenMode = m; LogSuccess($"Full screen mode set to {m}."); }, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) LogVariable("Full screen mode", Screen.fullScreenMode); })); AddCommand(Command.Create("vsync", "", "Query or set whether VSync is enabled", Parameter.Create("vSyncCount", "The number of VSyncs that should pass between each frame (0, 1, 2, 3, or 4)"), delegate(int i) { if (i < 0 || i > 4) { LogError($"Provided VSyncCount is not an accepted value: \"{i}\"."); } else { QualitySettings.vSyncCount = i; LogSuccess($"VSyncCount set to {i}."); } }, delegate { LogVariable("VSync count", QualitySettings.vSyncCount); })); AddCommand(Command.Create("monitor_size", "monitor_resolution", "Display the current monitor resolution", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) LogVariable("Monitor size", Screen.currentResolution); })); AddCommand(Command.Create("window_size", "window_resolution", "Display the current window resolution", delegate { LogVariable("Window size", $"{Screen.width} x {Screen.height}"); })); AddCommand(Command.Create("targetfps", "", "Query or set the target frame rate", Parameter.Create("targetFrameRate", "Frame rate the application will try to render at."), delegate(int i) { Application.targetFrameRate = i; LogSuccess($"Target frame rate set to {i}."); }, delegate { LogVariable("Target frame rate", Application.targetFrameRate); })); AddCommand(Command.Create("cam_ortho", "", "Query or set whether the main camera is orthographic", Parameter.Create("enabled", "Whether the main camera is orthographic (use \"NULL\" to toggle)"), delegate(bool? b) { if ((Object)(object)Camera.main == (Object)null) { LogError("Could not find the main camera."); } else { if (!b.HasValue) { b = !Camera.main.orthographic; } Camera.main.orthographic = b.Value; LogSuccess((b.Value ? "Enabled" : "Disabled") + " orthographic mode on the main camera."); } }, delegate { if ((Object)(object)Camera.main == (Object)null) { LogError("Could not find the main camera."); } else { LogVariable("Orthographic", Camera.main.orthographic); } })); AddCommand(Command.Create("cam_fov", "", "Query or set the main camera field of view", Parameter.Create("fieldOfView", "Field of view"), delegate(int f) { if ((Object)(object)Camera.main == (Object)null) { LogError("Could not find the main camera."); } else { Camera.main.fieldOfView = f; LogSuccess($"Main camera's field of view set to {f}."); } }, delegate { if ((Object)(object)Camera.main == (Object)null) { LogError("Could not find the main camera."); } else { LogVariable("Field of view", Camera.main.fieldOfView); } })); AddCommand(Command.Create("scene_load", "", "Load the scene at the specified build index", Parameter.Create("buildIndex", "Build index of the scene to load, specified in the Unity build settings"), delegate(int i) { if (i >= SceneManager.sceneCountInBuildSettings) { LogError($"Invalid build index specified: \"{i}\". Check the Unity build settings."); } else { SceneManager.LoadScene(i); LogSuccess($"Loaded scene at build index {i}."); } }), onlyInDevBuild: true); AddCommand(Command.Create("scene_info", "", "Display information about the current scene", Parameter.Create("sceneIndex", "Index of the scene in the currently loaded scenes"), delegate(int i) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (i >= SceneManager.sceneCount) { LogError($"Could not find active scene at index: {i}."); } else { Scene sceneAt2 = SceneManager.GetSceneAt(i); LogSeperator(((Scene)(ref sceneAt2)).name); Log($"Scene index: {i}."); Log($"Build index: {((Scene)(ref sceneAt2)).buildIndex}."); Log("Path: " + ((Scene)(ref sceneAt2)).path + "."); LogSeperator(); } }, delegate { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (SceneManager.sceneCount == 0) { Log("Could not find any active scenes."); } else { LogSeperator("Active scenes"); for (int num2 = 0; num2 < SceneManager.sceneCount; num2++) { Scene sceneAt = SceneManager.GetSceneAt(num2); Log($" {num2}) {((Scene)(ref sceneAt)).name}, build index: {((Scene)(ref sceneAt)).buildIndex}."); } LogCommand(); LogSeperator(); } })); AddCommand(Command.Create("obj_info", "", "Display information about a game object in the scene", Parameter.Create("name", "Name of the game object"), delegate(string s) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) GameObject val2 = GameObject.Find(s); if ((Object)(object)val2 == (Object)null) { LogError("Could not find game object: \"" + s + "\"."); } else { LogSeperator(((Object)val2).name + " (" + (val2.activeInHierarchy ? "enabled" : " disabled") + ")"); RectTransform val3 = default(RectTransform); if (val2.TryGetComponent<RectTransform>(ref val3)) { Log("RectTransform:"); LogVariable(" Anchored position", val3.anchoredPosition); LogVariable(" Size", val3.sizeDelta); LogVariable(" Pivot", val3.pivot); } else { Log("Transform:"); LogVariable(" Position", val2.transform.position); LogVariable(" Rotation", val2.transform.rotation); LogVariable(" Scale", val2.transform.localScale); } LogVariable("Tag", val2.tag); LogVariable("Physics layer", LayerMask.LayerToName(val2.layer)); Component[] array3 = Il2CppArrayBase<Component>.op_Implicit(val2.GetComponents<Component>()); if (array3.Length > 1) { Log("Components:"); for (int n = 1; n < array3.Length; n++) { Component obj3 = array3[n]; MonoBehaviour val4 = (MonoBehaviour)(object)((obj3 is MonoBehaviour) ? obj3 : null); if (val4 != null) { Log(string.Format(" {0}: {1} ({2}).", n, ((object)val4).GetType().Name, ((Behaviour)val4).enabled ? "enabled" : "disabled")); } else { Log($" {n}: {((object)array3[n]).GetType().Name}."); } } } if (val2.transform.childCount > 0) { Log("Children:"); for (int num = 0; num < val2.transform.childCount; num++) { Transform child = val2.transform.GetChild(num); Log(string.Format(" {0}: {1} ({2}).", num, ((Object)((Component)child).gameObject).name, ((Component)child).gameObject.activeInHierarchy ? "enabled" : "disabled")); } } LogSeperator(); } })); AddCommand(Command.Create("obj_list", "", "Display a hierarchical list of all game objects in the scene", delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref activeScene)).GetRootGameObjects()); string logResult = string.Empty; GameObject[] array2 = array; Transform t2; foreach (GameObject val in array2) { logResult = logResult + ((Object)val.gameObject).name + ".\n"; logChildren(val, 2); } activeScene = SceneManager.GetActiveScene(); LogSeperator("Hierarchy (" + ((Scene)(ref activeScene)).name + ")"); Log(logResult.TrimEnd(new char[1] { '\n' })); LogSeperator(); void logChildren(GameObject obj, int tabAmount) { string tabbed = getTabbed(tabAmount); for (int l = 0; l < obj.transform.childCount; l++) { t2 = obj.transform.GetChild(l); logResult = logResult + tabbed + ((Object)((Component)t2).gameObject).name + ".\n"; logChildren(((Component)t2).gameObject, tabAmount + 2); } } })); AddCommand(Command.Create("log_logs", "", "Query, enable or disable displaying Unity logs in the developer console", Parameter.Create("enabled", "Whether Unity logs should be displayed in the developer console (use \"NULL\" to toggle)"), delegate(bool? b) { if (!b.HasValue) { b = !_displayUnityLogs; } _displayUnityLogs = b.Value; LogSuccess((b.Value ? "Enabled" : "Disabled") + " displaying Unity logs in the developer console."); }, delegate { LogVariable("Log unity logs", _displayUnityLogs); })); AddCommand(Command.Create("log_errors", "", "Query, enable or disable displaying Unity errors in the developer console", Parameter.Create("enabled", "Whether Unity errors should be displayed in the developer console (use \"NULL\" to toggle)"), delegate(bool? b) { if (!b.HasValue) { b = !_displayUnityErrors; } _displayUnityErrors = b.Value; LogSuccess((b.Value ? "Enabled" : "Disabled") + " displaying Unity errors in the developer console."); }, delegate { LogVariable("Log unity errors", _displayUnityErrors); })); AddCommand(Command.Create("log_exceptions", "", "Query, enable or disable displaying Unity exceptions in the developer console", Parameter.Create("enabled", "Whether Unity exceptions should be displayed in the developer console (use \"NULL\" to toggle)"), delegate(bool? b) { if (!b.HasValue) { b = !_displayUnityExceptions; } _displayUnityExceptions = b.Value; LogSuccess((b.Value ? "Enabled" : "Disabled") + " displaying Unity exceptions in the developer console."); }, delegate { LogVariable("Log unity exceptions", _displayUnityExceptions); })); AddCommand(Command.Create("log_warnings", "", "Query, enable or disable displaying Unity warnings in the developer console", Parameter.Create("enabled", "Whether Unity warnings should be displayed in the developer console (use \"NULL\" to toggle)"), delegate(bool? b) { if (!b.HasValue) { b = !_displayUnityWarnings; } _displayUnityWarnings = b.Value; LogSuccess((b.Value ? "Enabled" : "Disabled") + " displaying Unity warnings in the developer console."); }, delegate { LogVariable("Log unity warnings", _displayUnityWarnings); })); AddCommand(Command.Create("cs_evaluate", "cs_eval,evaluate,eval", "Evaluate a C# expression or statement and display the result", Parameter.Create("expression", "The expression to evaluate"), delegate(string input) { if (_monoEvaluator == null) { DevConsole.LogError("C# expression evaluation is not supported on this platform."); return; } try { if (!input.EndsWith(";")) { input += ";"; } object obj2 = _monoEvaluator.Evaluate(input); if (obj2 == null) { Log("Null."); } else if (obj2.GetType() != typeof(string) && typeof(IEnumerable).IsAssignableFrom(obj2.GetType())) { Log("{ " + string.Join(", ", ((IEnumerable)obj2).Cast<object>()) + " }"); } else { Log($"{obj2}."); } } catch (Exception ex2) { LogError("An exception was thrown whilst evaluating the C# expression or statement: " + ex2.Message + "."); } })); AddCommand(Command.Create("cs_run", "run", "Execute a C# expression or statement", Parameter.Create("statement", "The statement to execute"), delegate(string input) { if (_monoEvaluator == null) { DevConsole.LogError("C# expression evaluation is not supported on this platform."); return; } try { if (!input.EndsWith(";")) { input += ";"; } if (_monoEvaluator.Run(input)) { LogSuccess("Successfully executed the C# expression or statement."); } else { LogError("Failed to parse the C# expression or statement."); } } catch (Exception ex) { LogError("An exception was thrown whilst executing the C# expression or statement: " + ex.Message + "."); } })); AddCommand(Command.Create("cs_usings", "", "Display a list of all active using statements", delegate { if (_monoEvaluator == null) { DevConsole.LogError("C# expression evaluation is not supported on this platform."); } else { string @using = _monoEvaluator.GetUsing(); if (string.IsNullOrEmpty(@using)) { Log("There are no active using statements."); } else { LogSeperator("Usings"); Log(@using.TrimEnd(new char[1] { '\n' })); LogSeperator(); } } })); AddCommand(Command.Create("cs_variables", "cs_vars", "Display a list of all local variables defined", delegate { if (_monoEvaluator == null) { DevConsole.LogError("C# expression evaluation is not supported on this platform."); } else { string vars = _monoEvaluator.GetVars(); if (string.IsNullOrEmpty(vars)) { Log("There are no local variables defined."); } else { LogSeperator("Local variables"); Log(vars.TrimEnd(new char[1] { '\n' })); LogSeperator(); } } })); AddCommand(Command.Create("cs_setusing", "", "Set whether a using statement is included automatically when starting the developer console", Parameter.Create("namespace", "Namespace to use as the using statement (e.g. \"System.Collections\""), Parameter.Create("enabled", "Whether the using statement is automatically included upon starting the developer console"), delegate(string usingName, bool enabled) { if (enabled) { if (_includedUsings.Contains(usingName)) { LogError("The specifed using statement is already enabled: \"" + usingName + "\"."); } else { _includedUsings.Add(usingName); LogSuccess("Enabled \"" + usingName + "\" as an automatically included using statement."); } } else if (!_includedUsings.Contains(usingName)) { LogError("The specified using statement is already disabled: \"" + usingName + "\"."); } else { _includedUsings.Remove(usingName); LogSuccess("Disabled \"" + usingName + "\" as an automatically included using statement."); } })); AddCommand(Command.Create("cs_autousings", "", "Display a list of all user-defined using statements that are included automatically when starting the developer console", delegate { if (_includedUsings.Count == 0) { Log("There are no user-defined using statements."); } else { LogSeperator("User-defined usings"); IReadOnlyCollection<string> collection2 = _includedUsings; LogCollection(in collection2); LogSeperator(); } })); AddCommand(Command.Create("cs_help", "", "Display information about the reflection commands", delegate { Command command2 = GetCommand("cs_evaluate"); Command command3 = GetCommand("cs_run"); Command command4 = GetCommand("cs_usings"); Command command5 = GetCommand("cs_vars"); Command command6 = GetCommand("cs_setusing"); Command command7 = GetCommand("cs_autousings"); LogSeperator("Reflection commands help"); LogVariable(command2.ToFormattedString(), command2.HelpText); LogVariable(command3.ToFormattedString(), command3.HelpText); LogVariable(command4.ToFormattedString(), command4.HelpText); LogVariable(command5.ToFormattedString(), command5.HelpText); LogVariable(command6.ToFormattedString(), command6.HelpText); LogVariable(command7.ToFormattedString(), command7.HelpText); LogSeperator(); })); AddCommand(Command.Create("stats_help", "", "Display information about the developer console stats feature", delegate { DevConsole.LogSeperator("Developer console tracked stats display"); DevConsole.Log("When enabled, stats such as variables can be displayed on-screen during gameplay."); DevConsole.Log("There are three ways to add tracked stats:"); DevConsole.Log("1. Using commands (" + GetCommand("stats_set").GetFormattedName() + ") to add a stat that is evaluated as a C# expression;"); DevConsole.Log("2. Declaring a <i>" + typeof(DevConsoleTrackedStatAttribute).Name + "</i> attribute on a declared static field or property; or"); DevConsole.Log("3. Calling <i>DevConsole.SetTrackedStat()</i> to add a stat this is retrieved via a provided lambda function."); DevConsole.LogSeperator(); })); AddCommand(Command.Create("stats_showfps", "stats_displayfps,showfps,displayfps", "Query or set whether the fps is being displayed on-screen", Parameter.Create("enabled", "Whether the fps is being displayed on-screen (use \"NULL\" to toggle)"), delegate(bool? b) { if (!b.HasValue) { b = !_isDisplayingFps; } if (b != _isDisplayingFps) { _isDisplayingFps = !_isDisplayingFps; if (_isDisplayingFps) { _fps = 0; _fpsMs = 0f; _fpsDeltaTime = 0f; _fpsElapsed = 0f; _fpsStyle = null; } } LogSuccess((b.Value ? "Enabled" : "Disabled") + " the on-screen fps."); }, delegate { LogVariable("Show fps", _isDisplayingFps); })); AddCommand(Command.Create("stats_list", "", "Display a list of the tracked developer console stats that can be displayed on-screen", delegate { if (!_stats.Any()) { DevConsole.Log("There are no tracked developer console stats. Use " + GetCommand("stats_set").GetFormattedName() + " to set one up."); } else { LogSeperator("Tracked developer console stats"); IReadOnlyCollection<KeyValuePair<string, StatBase>> collection = _stats; LogCollection(in collection, (KeyValuePair<string, StatBase> x) => string.Format("<b>{0}:</b> {1} ({2}){3}.", x.Key, x.Value, x.Value.Desc, _hiddenStats.Contains(x.Key) ? " <i>[Disabled]</i>" : "")); LogSeperator(); } })); AddCommand(Command.Create("stats_display", "", "Set or query whether the developer console stats are being displayed on-screen", Parameter.Create("display", ""), delegate(bool? b) { if (!b.HasValue) { b = !_isDisplayingStats; } _isDisplayingStats = b.Value; DevConsole.LogSuccess((_isDisplayingStats ? "Enabled" : "Disabled") + " the on-screen developer console stats display."); }, delegate { DevConsole.LogVariable("Display on-screen developer console stats", _isDisplayingStats); })); AddCommand(Command.Create("stats_set", "", "Set a stat on the developer console which can be displayed on-screen", Parameter.Create("name", "Name of the stat"), Parameter.Create("expression", "The C# expression to evaluate"), delegate(string name, string expression) { if (name == null || expression == null) { DevConsole.LogError("Parameters cannot be null."); } else { if (!expression.EndsWith(";")) { expression += ";"; } _stats[name] = new EvaluatedStat(expression); DevConsole.LogSuccess("Successfully set " + name + " as a developer console stat."); } })); AddCommand(Command.Create("stats_evaluate", "stats_eval", "Evaluate one of the developer console stats", Parameter.Create("name", "Name of the stat"), delegate(string name) { if (!_stats.ContainsKey(name)) { DevConsole.LogError("Could not find " + name + ". Use " + GetCommand("stats_display").GetFormattedName() + " to display a list of all developer console stats."); return; } try { DevConsole.LogVariable(name, _stats[name].GetResult(_monoEvaluator) ?? "NULL"); } catch (Exception exception) { DevConsole.LogException(exception); } })); AddCommand(Command.Create("stats_remove", "", "Remove a stat from the developer console", Parameter.Create("name", "Name of the stat"), delegate(string name) { if (!_stats.Remove(name)) { DevConsole.LogError("Could not remove " + name + ". Use " + GetCommand("stats_display").GetFormattedName() + " to display a list of all developer console stats."); } else { _hiddenStats.Remove(name); _cachedStats.Remove(name); DevConsole.LogSuccess("Successfully removed " + name + " from the developer console stats."); } })); AddCommand(Command.Create("stats_toggle", "", "Set whether a particular developer console stat should be displayed or not", Parameter.Create("name", "Name of the stat"), Parameter.Create("display", ""), delegate(string name, bool? b) { if (!_stats.ContainsKey(name)) { DevConsole.LogError("Could not find " + name + ". Use " + GetCommand("stats_display").GetFormattedName() + " to display a list of all developer console stats."); } else { if (!b.HasValue) { b = _hiddenStats.Contains(name); } if (b.Value) { _hiddenStats.Remove(name); } else { _hiddenStats.Add(name); } DevConsole.LogSuccess((b.Value ? "Enabled" : "Disabled") + " the on-screen developer console stats display for " + name + "."); } })); AddCommand(Command.Create("stats_fontsize", "", "Query or set the font size of the tracked developer console stats & fps display", Parameter.Create("fontSize", $"Size of the font (default: {18})"), delegate(int f) { if (f <= 0) { LogError("Font size must be non-zero and positive."); } else { int statFontSize = _statFontSize; _statFontSize = f; LogSuccess($"Set the stats font size to {_statFontSize} (was {statFontSize})."); } }, delegate { LogVariable("Stats font size", _statFontSize); })); AddCommand(Command.Create("time", "", "Display the current time", delegate { Log($"Current time: {DateTime.Now}."); })); AddCommand(Command.Create("sys_info", "", "Display system information", delegate { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) LogSeperator("System information"); LogVariable("Name", SystemInfo.deviceName); LogVariable("Model", SystemInfo.deviceModel); LogVariable("Type", SystemInfo.deviceType, ((int)SystemInfo.operatingSystemFamily == 0) ? "" : $" ({SystemInfo.operatingSystemFamily})"); LogVariable("OS", SystemInfo.operatingSystem); if (SystemInfo.batteryLevel != -1f) { Log($"Battery status: {SystemInfo.batteryStatus} ({SystemInfo.batteryLevel * 100f}%)."); } Log(""); LogVariable("CPU", SystemInfo.processorType); LogVariable(" Memory size", SystemInfo.systemMemorySize, " megabytes"); LogVariable(" Processors", SystemInfo.processorCount); LogVariable(" Frequency", SystemInfo.processorFrequency, " MHz"); Log(""); LogVariable("GPU", SystemInfo.graphicsDeviceName); LogVariable(" Type", SystemInfo.graphicsDeviceType); LogVariable(" Vendor", SystemInfo.graphicsDeviceVendor); LogVariable(" Version", SystemInfo.graphicsDeviceVersion); LogVariable(" Memory size", SystemInfo.graphicsMemorySize, " megabytes"); LogVariable(" Multi threaded", SystemInfo.graphicsMultiThreaded); LogSeperator(); })); AddCommand(Command.Create("datapath", "", "Display information about where data is stored by Unity and the developer console", delegate { LogSeperator("Data paths"); LogVariable("Data path", Application.dataPath); LogVariable("Persistent data path", Application.persistentDataPath); LogVariable("Developer console data path", DevConsoleData.FilePath); LogSeperator(); })); AddCommand(Command.Create("colour", "color", "Display a colour in the developer console", Parameter.Create("colour", "Colour to display. Formats: #RRGGBBAA (hex), #RRGGBB (hex), name (red,yellow,etc.), R.R,G.G,B.B (0.0-1.0), RRR,GGG,BBB (0-255)"), delegate(Color colour) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) LogVariable("<color=#" + ColorUtility.ToHtmlStringRGBA(colour) + ">Colour</color>", colour); }, delegate { Log("Supported formats: #RRGGBBAA (hex), #RRGGBB (hex), name (red,yellow,etc.), R.R,G.G,B.B (0.0-1.0), RRR,GGG,BBB (0-255)."); })); static string getTabbed(int tabAmount) { string text = string.Empty; for (int j = 0; j < tabAmount; j++) { text += ((j % 2 == 0) ? '|' : ' '); } return text; } } private void InitBuiltInParsers() { AddParameterType(typeof(bool), delegate(string s) { if (int.TryParse(s, out var result)) { switch (result) { case 0: return false; case 1: return true; } } return Convert.ChangeType(s, typeof(bool)); }); AddParameterType(typeof(bool?), (string s) => (s.ToLower() == "null" || s == "~") ? null : ParseParameter(s, typeof(bool))); AddParameterType(typeof(Color), delegate(string s) { //IL_005f: 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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) Color black = default(Color); if (ColorUtility.TryParseHtmlString(s, ref black)) { return black; } string[] array = s.Split(new char[1] { ',' }); int num = Math.Min(4, array.Length); try { black = Color.black; for (int i = 0; i < num; i++) { ((Color)(ref black))[i] = Mathf.RoundToInt((float)int.Parse(array[i]) / 255f); } } catch { black = Color.black; for (int j = 0; j < num; j++) { ((Color)(ref black))[j] = float.Parse(array[j]); } } return black; }); } private void InitAttributes() { string[] source = new string[12] { "Unity", "System", "Mono.", "mscorlib", "netstandard", "TextMeshPro", "Microsoft.GeneratedCode", "I18N", "Boo.", "UnityScript.", "ICSharpCode.", "ExCSS.Unity" }; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string assemblyName = assembly.GetName().Name; if (source.Any((string a) => assemblyName.ToLower().StartsWith(a.ToLower()))) { continue; } try { Type[] exportedTypes = assembly.GetExportedTypes(); foreach (Type type in exportedTypes) { MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(DevConsoleCommandAttribute), inherit: false); for (int l = 0; l < customAttributes.Length; l++) { DevConsoleCommandAttribute devConsoleCommandAttribute = (DevConsoleCommandAttribute)customAttributes[l]; if (devConsoleCommandAttribute != null) { AddCommand(Command.Create(devConsoleCommandAttribute, methodInfo), devConsoleCommandAttribute.OnlyInDevBuild, isCustomCommand: true); } } } FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { DevConsoleTrackedStatAttribute customAttribute = fieldInfo.GetCustomAttribute<DevConsoleTrackedStatAttribute>(); if (customAttribute != null) { string text = customAttribute.Name ?? fieldInfo.Name; _stats[text] = new ReflectedStat(fieldInfo); if (!customAttribute.StartEnabled && !_persistStats.Contains(text)) { _hiddenStats.Add(text); } } } PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { DevConsoleTrackedStatAttribute customAttribute2 = propertyInfo.GetCustomAttribute<DevConsoleTrackedStatAttribute>(); if (customAttribute2 != null) { string text2 = customAttribute2.Name ?? propertyInfo.Name; _stats[text2] = new ReflectedStat(propertyInfo); if (!customAttribute2.StartEnabled && !_persistStats.Contains(text2)) { _hiddenStats.Add(text2); } } } } } catch (NotSupportedException) { } catch (FileNotFoundException) { } catch (Exception ex3) { Debug.LogErr
BepInEx/plugins/Hikaria.DevConsole/Mono.CSharp.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading; using System.Xml; using Mono.CSharp.Linq; using Mono.CSharp.Nullable; using Mono.CSharp.yyParser; using Mono.CSharp.yydebug; using Mono.CompilerServices.SymbolWriter; using Mono.Security.Cryptography; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Mono.CSharp.dll")] [assembly: AssemblyDescription("Mono.CSharp.dll")] [assembly: AssemblyDefaultAlias("Mono.CSharp.dll")] [assembly: AssemblyCompany("Mono development team")] [assembly: AssemblyProduct("Mono Common Language Infrastructure")] [assembly: AssemblyCopyright("(c) Various Mono authors")] [assembly: SatelliteContractVersion("4.0.0.0")] [assembly: AssemblyInformationalVersion("4.6.57.0")] [assembly: AssemblyFileVersion("4.6.57.0")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyDelaySign(true)] [assembly: AssemblyKeyFile("../mono.pub")] [assembly: ComVisible(false)] [assembly: InternalsVisibleTo("Microsoft.CSharp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: AssemblyVersion("4.0.0.0")] internal static class Consts { public const string MonoVersion = "5.0.1.0"; public const string MonoCompany = "Mono development team"; public const string MonoProduct = "Mono Common Language Infrastructure"; public const string MonoCopyright = "(c) Various Mono authors"; public const int MonoCorlibVersion = 1050001000; public const string FxVersion = "4.0.0.0"; public const string FxFileVersion = "4.6.57.0"; public const string EnvironmentVersion = "4.0.30319.42000"; public const string VsVersion = "0.0.0.0"; public const string VsFileVersion = "11.0.0.0"; private const string PublicKeyToken = "b77a5c561934e089"; public const string AssemblyI18N = "I18N, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMono_Http = "Mono.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMono_Posix = "Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMono_Security = "Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyCorlib = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Data = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Design = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Drawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Messaging = "System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Security = "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Web = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Core = "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } namespace Mono.Security.Cryptography { public sealed class CryptoConvert { private CryptoConvert() { } private static int ToInt32LE(byte[] bytes, int offset) { return (bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset]; } private static uint ToUInt32LE(byte[] bytes, int offset) { return (uint)((bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset]); } private static byte[] GetBytesLE(int val) { return new byte[4] { (byte)((uint)val & 0xFFu), (byte)((uint)(val >> 8) & 0xFFu), (byte)((uint)(val >> 16) & 0xFFu), (byte)((uint)(val >> 24) & 0xFFu) }; } private static byte[] Trim(byte[] array) { for (int i = 0; i < array.Length; i++) { if (array[i] != 0) { byte[] array2 = new byte[array.Length - i]; Buffer.BlockCopy(array, i, array2, 0, array2.Length); return array2; } } return null; } public static RSA FromCapiPrivateKeyBlob(byte[] blob) { return FromCapiPrivateKeyBlob(blob, 0); } public static RSA FromCapiPrivateKeyBlob(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } RSAParameters parameters = default(RSAParameters); try { if (blob[offset] != 7 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 843141970) { throw new CryptographicException("Invalid blob header"); } int num = ToInt32LE(blob, offset + 12); byte[] array = new byte[4]; Buffer.BlockCopy(blob, offset + 16, array, 0, 4); Array.Reverse((Array)array); parameters.Exponent = Trim(array); int num2 = offset + 20; int num3 = num >> 3; parameters.Modulus = new byte[num3]; Buffer.BlockCopy(blob, num2, parameters.Modulus, 0, num3); Array.Reverse((Array)parameters.Modulus); num2 += num3; int num4 = num3 >> 1; parameters.P = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.P, 0, num4); Array.Reverse((Array)parameters.P); num2 += num4; parameters.Q = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.Q, 0, num4); Array.Reverse((Array)parameters.Q); num2 += num4; parameters.DP = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.DP, 0, num4); Array.Reverse((Array)parameters.DP); num2 += num4; parameters.DQ = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.DQ, 0, num4); Array.Reverse((Array)parameters.DQ); num2 += num4; parameters.InverseQ = new byte[num4]; Buffer.BlockCopy(blob, num2, parameters.InverseQ, 0, num4); Array.Reverse((Array)parameters.InverseQ); num2 += num4; parameters.D = new byte[num3]; if (num2 + num3 + offset <= blob.Length) { Buffer.BlockCopy(blob, num2, parameters.D, 0, num3); Array.Reverse((Array)parameters.D); } } catch (Exception inner) { throw new CryptographicException("Invalid blob.", inner); } RSA rSA = null; try { rSA = RSA.Create(); rSA.ImportParameters(parameters); } catch (CryptographicException ex) { try { rSA = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); rSA.ImportParameters(parameters); } catch { throw ex; } } return rSA; } public static DSA FromCapiPrivateKeyBlobDSA(byte[] blob) { return FromCapiPrivateKeyBlobDSA(blob, 0); } public static DSA FromCapiPrivateKeyBlobDSA(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } DSAParameters parameters = default(DSAParameters); try { if (blob[offset] != 7 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 844321604) { throw new CryptographicException("Invalid blob header"); } int num = ToInt32LE(blob, offset + 12) >> 3; int num2 = offset + 16; parameters.P = new byte[num]; Buffer.BlockCopy(blob, num2, parameters.P, 0, num); Array.Reverse((Array)parameters.P); num2 += num; parameters.Q = new byte[20]; Buffer.BlockCopy(blob, num2, parameters.Q, 0, 20); Array.Reverse((Array)parameters.Q); num2 += 20; parameters.G = new byte[num]; Buffer.BlockCopy(blob, num2, parameters.G, 0, num); Array.Reverse((Array)parameters.G); num2 += num; parameters.X = new byte[20]; Buffer.BlockCopy(blob, num2, parameters.X, 0, 20); Array.Reverse((Array)parameters.X); num2 += 20; parameters.Counter = ToInt32LE(blob, num2); num2 += 4; parameters.Seed = new byte[20]; Buffer.BlockCopy(blob, num2, parameters.Seed, 0, 20); Array.Reverse((Array)parameters.Seed); num2 += 20; } catch (Exception inner) { throw new CryptographicException("Invalid blob.", inner); } DSA dSA = null; try { dSA = DSA.Create(); dSA.ImportParameters(parameters); } catch (CryptographicException ex) { try { dSA = new DSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); dSA.ImportParameters(parameters); } catch { throw ex; } } return dSA; } public static byte[] ToCapiPrivateKeyBlob(RSA rsa) { RSAParameters rSAParameters = rsa.ExportParameters(includePrivateParameters: true); int num = rSAParameters.Modulus.Length; byte[] array = new byte[20 + (num << 2) + (num >> 1)]; array[0] = 7; array[1] = 2; array[5] = 36; array[8] = 82; array[9] = 83; array[10] = 65; array[11] = 50; byte[] bytesLE = GetBytesLE(num << 3); array[12] = bytesLE[0]; array[13] = bytesLE[1]; array[14] = bytesLE[2]; array[15] = bytesLE[3]; int num2 = 16; int num3 = rSAParameters.Exponent.Length; while (num3 > 0) { array[num2++] = rSAParameters.Exponent[--num3]; } num2 = 20; byte[]? modulus = rSAParameters.Modulus; int num4 = modulus.Length; Array.Reverse((Array)modulus, 0, num4); Buffer.BlockCopy(modulus, 0, array, num2, num4); num2 += num4; byte[]? p = rSAParameters.P; num4 = p.Length; Array.Reverse((Array)p, 0, num4); Buffer.BlockCopy(p, 0, array, num2, num4); num2 += num4; byte[]? q = rSAParameters.Q; num4 = q.Length; Array.Reverse((Array)q, 0, num4); Buffer.BlockCopy(q, 0, array, num2, num4); num2 += num4; byte[]? dP = rSAParameters.DP; num4 = dP.Length; Array.Reverse((Array)dP, 0, num4); Buffer.BlockCopy(dP, 0, array, num2, num4); num2 += num4; byte[]? dQ = rSAParameters.DQ; num4 = dQ.Length; Array.Reverse((Array)dQ, 0, num4); Buffer.BlockCopy(dQ, 0, array, num2, num4); num2 += num4; byte[]? inverseQ = rSAParameters.InverseQ; num4 = inverseQ.Length; Array.Reverse((Array)inverseQ, 0, num4); Buffer.BlockCopy(inverseQ, 0, array, num2, num4); num2 += num4; byte[]? d = rSAParameters.D; num4 = d.Length; Array.Reverse((Array)d, 0, num4); Buffer.BlockCopy(d, 0, array, num2, num4); return array; } public static byte[] ToCapiPrivateKeyBlob(DSA dsa) { DSAParameters dSAParameters = dsa.ExportParameters(includePrivateParameters: true); int num = dSAParameters.P.Length; byte[] array = new byte[16 + num + 20 + num + 20 + 4 + 20]; array[0] = 7; array[1] = 2; array[5] = 34; array[8] = 68; array[9] = 83; array[10] = 83; array[11] = 50; byte[] bytesLE = GetBytesLE(num << 3); array[12] = bytesLE[0]; array[13] = bytesLE[1]; array[14] = bytesLE[2]; array[15] = bytesLE[3]; int num2 = 16; byte[]? p = dSAParameters.P; Array.Reverse((Array)p); Buffer.BlockCopy(p, 0, array, num2, num); num2 += num; byte[]? q = dSAParameters.Q; Array.Reverse((Array)q); Buffer.BlockCopy(q, 0, array, num2, 20); num2 += 20; byte[]? g = dSAParameters.G; Array.Reverse((Array)g); Buffer.BlockCopy(g, 0, array, num2, num); num2 += num; byte[]? x = dSAParameters.X; Array.Reverse((Array)x); Buffer.BlockCopy(x, 0, array, num2, 20); num2 += 20; Buffer.BlockCopy(GetBytesLE(dSAParameters.Counter), 0, array, num2, 4); num2 += 4; byte[]? seed = dSAParameters.Seed; Array.Reverse((Array)seed); Buffer.BlockCopy(seed, 0, array, num2, 20); return array; } public static RSA FromCapiPublicKeyBlob(byte[] blob) { return FromCapiPublicKeyBlob(blob, 0); } public static RSA FromCapiPublicKeyBlob(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } try { if (blob[offset] != 6 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 826364754) { throw new CryptographicException("Invalid blob header"); } int num = ToInt32LE(blob, offset + 12); RSAParameters parameters = new RSAParameters { Exponent = new byte[3] }; parameters.Exponent[0] = blob[offset + 18]; parameters.Exponent[1] = blob[offset + 17]; parameters.Exponent[2] = blob[offset + 16]; int srcOffset = offset + 20; int num2 = num >> 3; parameters.Modulus = new byte[num2]; Buffer.BlockCopy(blob, srcOffset, parameters.Modulus, 0, num2); Array.Reverse((Array)parameters.Modulus); RSA rSA = null; try { rSA = RSA.Create(); rSA.ImportParameters(parameters); } catch (CryptographicException) { rSA = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); rSA.ImportParameters(parameters); } return rSA; } catch (Exception inner) { throw new CryptographicException("Invalid blob.", inner); } } public static DSA FromCapiPublicKeyBlobDSA(byte[] blob) { return FromCapiPublicKeyBlobDSA(blob, 0); } public static DSA FromCapiPublicKeyBlobDSA(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } try { if (blob[offset] != 6 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 827544388) { throw new CryptographicException("Invalid blob header"); } int num = ToInt32LE(blob, offset + 12); DSAParameters parameters = default(DSAParameters); int num2 = num >> 3; int num3 = offset + 16; parameters.P = new byte[num2]; Buffer.BlockCopy(blob, num3, parameters.P, 0, num2); Array.Reverse((Array)parameters.P); num3 += num2; parameters.Q = new byte[20]; Buffer.BlockCopy(blob, num3, parameters.Q, 0, 20); Array.Reverse((Array)parameters.Q); num3 += 20; parameters.G = new byte[num2]; Buffer.BlockCopy(blob, num3, parameters.G, 0, num2); Array.Reverse((Array)parameters.G); num3 += num2; parameters.Y = new byte[num2]; Buffer.BlockCopy(blob, num3, parameters.Y, 0, num2); Array.Reverse((Array)parameters.Y); num3 += num2; parameters.Counter = ToInt32LE(blob, num3); num3 += 4; parameters.Seed = new byte[20]; Buffer.BlockCopy(blob, num3, parameters.Seed, 0, 20); Array.Reverse((Array)parameters.Seed); num3 += 20; DSA dSA = DSA.Create(); dSA.ImportParameters(parameters); return dSA; } catch (Exception inner) { throw new CryptographicException("Invalid blob.", inner); } } public static byte[] ToCapiPublicKeyBlob(RSA rsa) { RSAParameters rSAParameters = rsa.ExportParameters(includePrivateParameters: false); int num = rSAParameters.Modulus.Length; byte[] array = new byte[20 + num]; array[0] = 6; array[1] = 2; array[5] = 36; array[8] = 82; array[9] = 83; array[10] = 65; array[11] = 49; byte[] bytesLE = GetBytesLE(num << 3); array[12] = bytesLE[0]; array[13] = bytesLE[1]; array[14] = bytesLE[2]; array[15] = bytesLE[3]; int num2 = 16; int num3 = rSAParameters.Exponent.Length; while (num3 > 0) { array[num2++] = rSAParameters.Exponent[--num3]; } num2 = 20; byte[]? modulus = rSAParameters.Modulus; int num4 = modulus.Length; Array.Reverse((Array)modulus, 0, num4); Buffer.BlockCopy(modulus, 0, array, num2, num4); num2 += num4; return array; } public static byte[] ToCapiPublicKeyBlob(DSA dsa) { DSAParameters dSAParameters = dsa.ExportParameters(includePrivateParameters: false); int num = dSAParameters.P.Length; byte[] array = new byte[16 + num + 20 + num + num + 4 + 20]; array[0] = 6; array[1] = 2; array[5] = 34; array[8] = 68; array[9] = 83; array[10] = 83; array[11] = 49; byte[] bytesLE = GetBytesLE(num << 3); array[12] = bytesLE[0]; array[13] = bytesLE[1]; array[14] = bytesLE[2]; array[15] = bytesLE[3]; int num2 = 16; byte[]? p = dSAParameters.P; Array.Reverse((Array)p); Buffer.BlockCopy(p, 0, array, num2, num); num2 += num; byte[]? q = dSAParameters.Q; Array.Reverse((Array)q); Buffer.BlockCopy(q, 0, array, num2, 20); num2 += 20; byte[]? g = dSAParameters.G; Array.Reverse((Array)g); Buffer.BlockCopy(g, 0, array, num2, num); num2 += num; byte[]? y = dSAParameters.Y; Array.Reverse((Array)y); Buffer.BlockCopy(y, 0, array, num2, num); num2 += num; Buffer.BlockCopy(GetBytesLE(dSAParameters.Counter), 0, array, num2, 4); num2 += 4; byte[]? seed = dSAParameters.Seed; Array.Reverse((Array)seed); Buffer.BlockCopy(seed, 0, array, num2, 20); return array; } public static RSA FromCapiKeyBlob(byte[] blob) { return FromCapiKeyBlob(blob, 0); } public static RSA FromCapiKeyBlob(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } switch (blob[offset]) { case 0: if (blob[offset + 12] == 6) { return FromCapiPublicKeyBlob(blob, offset + 12); } break; case 6: return FromCapiPublicKeyBlob(blob, offset); case 7: return FromCapiPrivateKeyBlob(blob, offset); } throw new CryptographicException("Unknown blob format."); } public static DSA FromCapiKeyBlobDSA(byte[] blob) { return FromCapiKeyBlobDSA(blob, 0); } public static DSA FromCapiKeyBlobDSA(byte[] blob, int offset) { if (blob == null) { throw new ArgumentNullException("blob"); } if (offset >= blob.Length) { throw new ArgumentException("blob is too small."); } return blob[offset] switch { 6 => FromCapiPublicKeyBlobDSA(blob, offset), 7 => FromCapiPrivateKeyBlobDSA(blob, offset), _ => throw new CryptographicException("Unknown blob format."), }; } public static byte[] ToCapiKeyBlob(AsymmetricAlgorithm keypair, bool includePrivateKey) { if (keypair == null) { throw new ArgumentNullException("keypair"); } if (keypair is RSA) { return ToCapiKeyBlob((RSA)keypair, includePrivateKey); } if (keypair is DSA) { return ToCapiKeyBlob((DSA)keypair, includePrivateKey); } return null; } public static byte[] ToCapiKeyBlob(RSA rsa, bool includePrivateKey) { if (rsa == null) { throw new ArgumentNullException("rsa"); } if (includePrivateKey) { return ToCapiPrivateKeyBlob(rsa); } return ToCapiPublicKeyBlob(rsa); } public static byte[] ToCapiKeyBlob(DSA dsa, bool includePrivateKey) { if (dsa == null) { throw new ArgumentNullException("dsa"); } if (includePrivateKey) { return ToCapiPrivateKeyBlob(dsa); } return ToCapiPublicKeyBlob(dsa); } public static string ToHex(byte[] input) { if (input == null) { return null; } StringBuilder stringBuilder = new StringBuilder(input.Length * 2); foreach (byte b in input) { stringBuilder.Append(b.ToString("X2", CultureInfo.InvariantCulture)); } return stringBuilder.ToString(); } private static byte FromHexChar(char c) { if (c >= 'a' && c <= 'f') { return (byte)(c - 97 + 10); } if (c >= 'A' && c <= 'F') { return (byte)(c - 65 + 10); } if (c >= '0' && c <= '9') { return (byte)(c - 48); } throw new ArgumentException("invalid hex char"); } public static byte[] FromHex(string hex) { if (hex == null) { return null; } if ((hex.Length & 1) == 1) { throw new ArgumentException("Length must be a multiple of 2"); } byte[] array = new byte[hex.Length >> 1]; int num = 0; int num2 = 0; while (num < array.Length) { array[num] = (byte)(FromHexChar(hex[num2++]) << 4); array[num++] += FromHexChar(hex[num2++]); } return array; } } } namespace Mono.CompilerServices.SymbolWriter { public class MonoSymbolFileException : Exception { public MonoSymbolFileException() { } public MonoSymbolFileException(string message, params object[] args) : base(string.Format(message, args)) { } public MonoSymbolFileException(string message, Exception innerException) : base(message, innerException) { } } internal sealed class MyBinaryWriter : BinaryWriter { public MyBinaryWriter(Stream stream) : base(stream) { } public void WriteLeb128(int value) { Write7BitEncodedInt(value); } } internal class MyBinaryReader : BinaryReader { public MyBinaryReader(Stream stream) : base(stream) { } public int ReadLeb128() { return Read7BitEncodedInt(); } public string ReadString(int offset) { long position = BaseStream.Position; BaseStream.Position = offset; string result = ReadString(); BaseStream.Position = position; return result; } } public interface ISourceFile { SourceFileEntry Entry { get; } } public interface ICompileUnit { CompileUnitEntry Entry { get; } } public interface IMethodDef { string Name { get; } int Token { get; } } public class MonoSymbolFile : IDisposable { private List<MethodEntry> methods = new List<MethodEntry>(); private List<SourceFileEntry> sources = new List<SourceFileEntry>(); private List<CompileUnitEntry> comp_units = new List<CompileUnitEntry>(); private Dictionary<int, AnonymousScopeEntry> anonymous_scopes; private OffsetTable ot; private int last_type_index; private int last_method_index; private int last_namespace_index; public readonly int MajorVersion = 50; public readonly int MinorVersion; public int NumLineNumbers; private MyBinaryReader reader; private Dictionary<int, SourceFileEntry> source_file_hash; private Dictionary<int, CompileUnitEntry> compile_unit_hash; private List<MethodEntry> method_list; private Dictionary<int, MethodEntry> method_token_hash; private Dictionary<string, int> source_name_hash; private Guid guid; internal int LineNumberCount; internal int LocalCount; internal int StringSize; internal int LineNumberSize; internal int ExtendedLineNumberSize; public int CompileUnitCount => ot.CompileUnitCount; public int SourceCount => ot.SourceCount; public int MethodCount => ot.MethodCount; public int TypeCount => ot.TypeCount; public int AnonymousScopeCount => ot.AnonymousScopeCount; public int NamespaceCount => last_namespace_index; public Guid Guid => guid; public OffsetTable OffsetTable => ot; public SourceFileEntry[] Sources { get { if (reader == null) { throw new InvalidOperationException(); } SourceFileEntry[] array = new SourceFileEntry[SourceCount]; for (int i = 0; i < SourceCount; i++) { array[i] = GetSourceFile(i + 1); } return array; } } public CompileUnitEntry[] CompileUnits { get { if (reader == null) { throw new InvalidOperationException(); } CompileUnitEntry[] array = new CompileUnitEntry[CompileUnitCount]; for (int i = 0; i < CompileUnitCount; i++) { array[i] = GetCompileUnit(i + 1); } return array; } } public MethodEntry[] Methods { get { if (reader == null) { throw new InvalidOperationException(); } lock (this) { read_methods(); MethodEntry[] array = new MethodEntry[MethodCount]; method_list.CopyTo(array, 0); return array; } } } internal MyBinaryReader BinaryReader { get { if (reader == null) { throw new InvalidOperationException(); } return reader; } } public MonoSymbolFile() { ot = new OffsetTable(); } public int AddSource(SourceFileEntry source) { sources.Add(source); return sources.Count; } public int AddCompileUnit(CompileUnitEntry entry) { comp_units.Add(entry); return comp_units.Count; } public void AddMethod(MethodEntry entry) { methods.Add(entry); } public MethodEntry DefineMethod(CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) { if (reader != null) { throw new InvalidOperationException(); } MethodEntry methodEntry = new MethodEntry(this, comp_unit, token, scope_vars, locals, lines, code_blocks, real_name, flags, namespace_id); AddMethod(methodEntry); return methodEntry; } internal void DefineAnonymousScope(int id) { if (reader != null) { throw new InvalidOperationException(); } if (anonymous_scopes == null) { anonymous_scopes = new Dictionary<int, AnonymousScopeEntry>(); } anonymous_scopes.Add(id, new AnonymousScopeEntry(id)); } internal void DefineCapturedVariable(int scope_id, string name, string captured_name, CapturedVariable.CapturedKind kind) { if (reader != null) { throw new InvalidOperationException(); } anonymous_scopes[scope_id].AddCapturedVariable(name, captured_name, kind); } internal void DefineCapturedScope(int scope_id, int id, string captured_name) { if (reader != null) { throw new InvalidOperationException(); } anonymous_scopes[scope_id].AddCapturedScope(id, captured_name); } internal int GetNextTypeIndex() { return ++last_type_index; } internal int GetNextMethodIndex() { return ++last_method_index; } internal int GetNextNamespaceIndex() { return ++last_namespace_index; } private void Write(MyBinaryWriter bw, Guid guid) { bw.Write(5037318119232611860L); bw.Write(MajorVersion); bw.Write(MinorVersion); bw.Write(guid.ToByteArray()); long position = bw.BaseStream.Position; ot.Write(bw, MajorVersion, MinorVersion); methods.Sort(); for (int i = 0; i < methods.Count; i++) { methods[i].Index = i + 1; } ot.DataSectionOffset = (int)bw.BaseStream.Position; foreach (SourceFileEntry source in sources) { source.WriteData(bw); } foreach (CompileUnitEntry comp_unit in comp_units) { comp_unit.WriteData(bw); } foreach (MethodEntry method in methods) { method.WriteData(this, bw); } ot.DataSectionSize = (int)bw.BaseStream.Position - ot.DataSectionOffset; ot.MethodTableOffset = (int)bw.BaseStream.Position; for (int j = 0; j < methods.Count; j++) { methods[j].Write(bw); } ot.MethodTableSize = (int)bw.BaseStream.Position - ot.MethodTableOffset; ot.SourceTableOffset = (int)bw.BaseStream.Position; for (int k = 0; k < sources.Count; k++) { sources[k].Write(bw); } ot.SourceTableSize = (int)bw.BaseStream.Position - ot.SourceTableOffset; ot.CompileUnitTableOffset = (int)bw.BaseStream.Position; for (int l = 0; l < comp_units.Count; l++) { comp_units[l].Write(bw); } ot.CompileUnitTableSize = (int)bw.BaseStream.Position - ot.CompileUnitTableOffset; ot.AnonymousScopeCount = ((anonymous_scopes != null) ? anonymous_scopes.Count : 0); ot.AnonymousScopeTableOffset = (int)bw.BaseStream.Position; if (anonymous_scopes != null) { foreach (AnonymousScopeEntry value in anonymous_scopes.Values) { value.Write(bw); } } ot.AnonymousScopeTableSize = (int)bw.BaseStream.Position - ot.AnonymousScopeTableOffset; ot.TypeCount = last_type_index; ot.MethodCount = methods.Count; ot.SourceCount = sources.Count; ot.CompileUnitCount = comp_units.Count; ot.TotalFileSize = (int)bw.BaseStream.Position; bw.Seek((int)position, SeekOrigin.Begin); ot.Write(bw, MajorVersion, MinorVersion); bw.Seek(0, SeekOrigin.End); } public void CreateSymbolFile(Guid guid, FileStream fs) { if (reader != null) { throw new InvalidOperationException(); } Write(new MyBinaryWriter(fs), guid); } private MonoSymbolFile(Stream stream) { reader = new MyBinaryReader(stream); try { long num = reader.ReadInt64(); int num2 = reader.ReadInt32(); int num3 = reader.ReadInt32(); if (num != 5037318119232611860L) { throw new MonoSymbolFileException("Symbol file is not a valid"); } if (num2 != 50) { throw new MonoSymbolFileException("Symbol file has version {0} but expected {1}", num2, 50); } if (num3 != 0) { throw new MonoSymbolFileException("Symbol file has version {0}.{1} but expected {2}.{3}", num2, num3, 50, 0); } MajorVersion = num2; MinorVersion = num3; guid = new Guid(reader.ReadBytes(16)); ot = new OffsetTable(reader, num2, num3); } catch (Exception innerException) { throw new MonoSymbolFileException("Cannot read symbol file", innerException); } source_file_hash = new Dictionary<int, SourceFileEntry>(); compile_unit_hash = new Dictionary<int, CompileUnitEntry>(); } public static MonoSymbolFile ReadSymbolFile(Assembly assembly) { string mdbFilename = assembly.Location + ".mdb"; Guid moduleVersionId = assembly.GetModules()[0].ModuleVersionId; return ReadSymbolFile(mdbFilename, moduleVersionId); } public static MonoSymbolFile ReadSymbolFile(string mdbFilename) { return ReadSymbolFile(new FileStream(mdbFilename, FileMode.Open, FileAccess.Read)); } public static MonoSymbolFile ReadSymbolFile(string mdbFilename, Guid assemblyGuid) { MonoSymbolFile monoSymbolFile = ReadSymbolFile(mdbFilename); if (assemblyGuid != monoSymbolFile.guid) { throw new MonoSymbolFileException("Symbol file `{0}' does not match assembly", mdbFilename); } return monoSymbolFile; } public static MonoSymbolFile ReadSymbolFile(Stream stream) { return new MonoSymbolFile(stream); } public SourceFileEntry GetSourceFile(int index) { if (index < 1 || index > ot.SourceCount) { throw new ArgumentException(); } if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (source_file_hash.TryGetValue(index, out var value)) { return value; } long position = reader.BaseStream.Position; reader.BaseStream.Position = ot.SourceTableOffset + SourceFileEntry.Size * (index - 1); value = new SourceFileEntry(this, reader); source_file_hash.Add(index, value); reader.BaseStream.Position = position; return value; } } public CompileUnitEntry GetCompileUnit(int index) { if (index < 1 || index > ot.CompileUnitCount) { throw new ArgumentException(); } if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (compile_unit_hash.TryGetValue(index, out var value)) { return value; } long position = reader.BaseStream.Position; reader.BaseStream.Position = ot.CompileUnitTableOffset + CompileUnitEntry.Size * (index - 1); value = new CompileUnitEntry(this, reader); compile_unit_hash.Add(index, value); reader.BaseStream.Position = position; return value; } } private void read_methods() { lock (this) { if (method_token_hash == null) { method_token_hash = new Dictionary<int, MethodEntry>(); method_list = new List<MethodEntry>(); long position = reader.BaseStream.Position; reader.BaseStream.Position = ot.MethodTableOffset; for (int i = 0; i < MethodCount; i++) { MethodEntry methodEntry = new MethodEntry(this, reader, i + 1); method_token_hash.Add(methodEntry.Token, methodEntry); method_list.Add(methodEntry); } reader.BaseStream.Position = position; } } } public MethodEntry GetMethodByToken(int token) { if (reader == null) { throw new InvalidOperationException(); } lock (this) { read_methods(); method_token_hash.TryGetValue(token, out var value); return value; } } public MethodEntry GetMethod(int index) { if (index < 1 || index > ot.MethodCount) { throw new ArgumentException(); } if (reader == null) { throw new InvalidOperationException(); } lock (this) { read_methods(); return method_list[index - 1]; } } public int FindSource(string file_name) { if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (source_name_hash == null) { source_name_hash = new Dictionary<string, int>(); for (int i = 0; i < ot.SourceCount; i++) { SourceFileEntry sourceFile = GetSourceFile(i + 1); source_name_hash.Add(sourceFile.FileName, i); } } if (!source_name_hash.TryGetValue(file_name, out var value)) { return -1; } return value; } } public AnonymousScopeEntry GetAnonymousScope(int id) { if (reader == null) { throw new InvalidOperationException(); } lock (this) { if (anonymous_scopes != null) { anonymous_scopes.TryGetValue(id, out var value); return value; } anonymous_scopes = new Dictionary<int, AnonymousScopeEntry>(); reader.BaseStream.Position = ot.AnonymousScopeTableOffset; for (int i = 0; i < ot.AnonymousScopeCount; i++) { AnonymousScopeEntry value = new AnonymousScopeEntry(reader); anonymous_scopes.Add(value.ID, value); } return anonymous_scopes[id]; } } public void Dispose() { Dispose(disposing: true); } protected virtual void Dispose(bool disposing) { if (disposing && reader != null) { reader.Close(); reader = null; } } } public class OffsetTable { [Flags] public enum Flags { IsAspxSource = 1, WindowsFileNames = 2 } public const int MajorVersion = 50; public const int MinorVersion = 0; public const long Magic = 5037318119232611860L; public int TotalFileSize; public int DataSectionOffset; public int DataSectionSize; public int CompileUnitCount; public int CompileUnitTableOffset; public int CompileUnitTableSize; public int SourceCount; public int SourceTableOffset; public int SourceTableSize; public int MethodCount; public int MethodTableOffset; public int MethodTableSize; public int TypeCount; public int AnonymousScopeCount; public int AnonymousScopeTableOffset; public int AnonymousScopeTableSize; public Flags FileFlags; public int LineNumberTable_LineBase = -1; public int LineNumberTable_LineRange = 8; public int LineNumberTable_OpcodeBase = 9; internal OffsetTable() { int platform = (int)Environment.OSVersion.Platform; if (platform != 4 && platform != 128) { FileFlags |= Flags.WindowsFileNames; } } internal OffsetTable(BinaryReader reader, int major_version, int minor_version) { TotalFileSize = reader.ReadInt32(); DataSectionOffset = reader.ReadInt32(); DataSectionSize = reader.ReadInt32(); CompileUnitCount = reader.ReadInt32(); CompileUnitTableOffset = reader.ReadInt32(); CompileUnitTableSize = reader.ReadInt32(); SourceCount = reader.ReadInt32(); SourceTableOffset = reader.ReadInt32(); SourceTableSize = reader.ReadInt32(); MethodCount = reader.ReadInt32(); MethodTableOffset = reader.ReadInt32(); MethodTableSize = reader.ReadInt32(); TypeCount = reader.ReadInt32(); AnonymousScopeCount = reader.ReadInt32(); AnonymousScopeTableOffset = reader.ReadInt32(); AnonymousScopeTableSize = reader.ReadInt32(); LineNumberTable_LineBase = reader.ReadInt32(); LineNumberTable_LineRange = reader.ReadInt32(); LineNumberTable_OpcodeBase = reader.ReadInt32(); FileFlags = (Flags)reader.ReadInt32(); } internal void Write(BinaryWriter bw, int major_version, int minor_version) { bw.Write(TotalFileSize); bw.Write(DataSectionOffset); bw.Write(DataSectionSize); bw.Write(CompileUnitCount); bw.Write(CompileUnitTableOffset); bw.Write(CompileUnitTableSize); bw.Write(SourceCount); bw.Write(SourceTableOffset); bw.Write(SourceTableSize); bw.Write(MethodCount); bw.Write(MethodTableOffset); bw.Write(MethodTableSize); bw.Write(TypeCount); bw.Write(AnonymousScopeCount); bw.Write(AnonymousScopeTableOffset); bw.Write(AnonymousScopeTableSize); bw.Write(LineNumberTable_LineBase); bw.Write(LineNumberTable_LineRange); bw.Write(LineNumberTable_OpcodeBase); bw.Write((int)FileFlags); } public override string ToString() { return $"OffsetTable [{TotalFileSize} - {DataSectionOffset}:{DataSectionSize} - {SourceCount}:{SourceTableOffset}:{SourceTableSize} - {MethodCount}:{MethodTableOffset}:{MethodTableSize} - {TypeCount}]"; } } public class LineNumberEntry { public sealed class LocationComparer : IComparer<LineNumberEntry> { public static readonly LocationComparer Default = new LocationComparer(); public int Compare(LineNumberEntry l1, LineNumberEntry l2) { if (l1.Row != l2.Row) { int row = l1.Row; return row.CompareTo(l2.Row); } return l1.Column.CompareTo(l2.Column); } } public readonly int Row; public int Column; public int EndRow; public int EndColumn; public readonly int File; public readonly int Offset; public readonly bool IsHidden; public static readonly LineNumberEntry Null = new LineNumberEntry(0, 0, 0, 0); public LineNumberEntry(int file, int row, int column, int offset) : this(file, row, column, offset, is_hidden: false) { } public LineNumberEntry(int file, int row, int offset) : this(file, row, -1, offset, is_hidden: false) { } public LineNumberEntry(int file, int row, int column, int offset, bool is_hidden) : this(file, row, column, -1, -1, offset, is_hidden) { } public LineNumberEntry(int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden) { File = file; Row = row; Column = column; EndRow = end_row; EndColumn = end_column; Offset = offset; IsHidden = is_hidden; } public override string ToString() { return string.Format("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); } } public class CodeBlockEntry { public enum Type { Lexical = 1, CompilerGenerated, IteratorBody, IteratorDispatcher } public int Index; public int Parent; public Type BlockType; public int StartOffset; public int EndOffset; public CodeBlockEntry(int index, int parent, Type type, int start_offset) { Index = index; Parent = parent; BlockType = type; StartOffset = start_offset; } internal CodeBlockEntry(int index, MyBinaryReader reader) { Index = index; int num = reader.ReadLeb128(); BlockType = (Type)(num & 0x3F); Parent = reader.ReadLeb128(); StartOffset = reader.ReadLeb128(); EndOffset = reader.ReadLeb128(); if (((uint)num & 0x40u) != 0) { int num2 = reader.ReadInt16(); reader.BaseStream.Position += num2; } } public void Close(int end_offset) { EndOffset = end_offset; } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128((int)BlockType); bw.WriteLeb128(Parent); bw.WriteLeb128(StartOffset); bw.WriteLeb128(EndOffset); } public override string ToString() { return $"[CodeBlock {Index}:{Parent}:{BlockType}:{StartOffset}:{EndOffset}]"; } } public struct LocalVariableEntry { public readonly int Index; public readonly string Name; public readonly int BlockIndex; public LocalVariableEntry(int index, string name, int block) { Index = index; Name = name; BlockIndex = block; } internal LocalVariableEntry(MonoSymbolFile file, MyBinaryReader reader) { Index = reader.ReadLeb128(); Name = reader.ReadString(); BlockIndex = reader.ReadLeb128(); } internal void Write(MonoSymbolFile file, MyBinaryWriter bw) { bw.WriteLeb128(Index); bw.Write(Name); bw.WriteLeb128(BlockIndex); } public override string ToString() { return $"[LocalVariable {Name}:{Index}:{BlockIndex - 1}]"; } } public struct CapturedVariable { public enum CapturedKind : byte { Local, Parameter, This } public readonly string Name; public readonly string CapturedName; public readonly CapturedKind Kind; public CapturedVariable(string name, string captured_name, CapturedKind kind) { Name = name; CapturedName = captured_name; Kind = kind; } internal CapturedVariable(MyBinaryReader reader) { Name = reader.ReadString(); CapturedName = reader.ReadString(); Kind = (CapturedKind)reader.ReadByte(); } internal void Write(MyBinaryWriter bw) { bw.Write(Name); bw.Write(CapturedName); bw.Write((byte)Kind); } public override string ToString() { return $"[CapturedVariable {Name}:{CapturedName}:{Kind}]"; } } public struct CapturedScope { public readonly int Scope; public readonly string CapturedName; public CapturedScope(int scope, string captured_name) { Scope = scope; CapturedName = captured_name; } internal CapturedScope(MyBinaryReader reader) { Scope = reader.ReadLeb128(); CapturedName = reader.ReadString(); } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128(Scope); bw.Write(CapturedName); } public override string ToString() { return $"[CapturedScope {Scope}:{CapturedName}]"; } } public struct ScopeVariable { public readonly int Scope; public readonly int Index; public ScopeVariable(int scope, int index) { Scope = scope; Index = index; } internal ScopeVariable(MyBinaryReader reader) { Scope = reader.ReadLeb128(); Index = reader.ReadLeb128(); } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128(Scope); bw.WriteLeb128(Index); } public override string ToString() { return $"[ScopeVariable {Scope}:{Index}]"; } } public class AnonymousScopeEntry { public readonly int ID; private List<CapturedVariable> captured_vars = new List<CapturedVariable>(); private List<CapturedScope> captured_scopes = new List<CapturedScope>(); public CapturedVariable[] CapturedVariables { get { CapturedVariable[] array = new CapturedVariable[captured_vars.Count]; captured_vars.CopyTo(array, 0); return array; } } public CapturedScope[] CapturedScopes { get { CapturedScope[] array = new CapturedScope[captured_scopes.Count]; captured_scopes.CopyTo(array, 0); return array; } } public AnonymousScopeEntry(int id) { ID = id; } internal AnonymousScopeEntry(MyBinaryReader reader) { ID = reader.ReadLeb128(); int num = reader.ReadLeb128(); for (int i = 0; i < num; i++) { captured_vars.Add(new CapturedVariable(reader)); } int num2 = reader.ReadLeb128(); for (int j = 0; j < num2; j++) { captured_scopes.Add(new CapturedScope(reader)); } } internal void AddCapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind) { captured_vars.Add(new CapturedVariable(name, captured_name, kind)); } internal void AddCapturedScope(int scope, string captured_name) { captured_scopes.Add(new CapturedScope(scope, captured_name)); } internal void Write(MyBinaryWriter bw) { bw.WriteLeb128(ID); bw.WriteLeb128(captured_vars.Count); foreach (CapturedVariable captured_var in captured_vars) { captured_var.Write(bw); } bw.WriteLeb128(captured_scopes.Count); foreach (CapturedScope captured_scope in captured_scopes) { captured_scope.Write(bw); } } public override string ToString() { return $"[AnonymousScope {ID}]"; } } public class CompileUnitEntry : ICompileUnit { public readonly int Index; private int DataOffset; private MonoSymbolFile file; private SourceFileEntry source; private List<SourceFileEntry> include_files; private List<NamespaceEntry> namespaces; private bool creating; public static int Size => 8; CompileUnitEntry ICompileUnit.Entry => this; public SourceFileEntry SourceFile { get { if (creating) { return source; } ReadData(); return source; } } public NamespaceEntry[] Namespaces { get { ReadData(); NamespaceEntry[] array = new NamespaceEntry[namespaces.Count]; namespaces.CopyTo(array, 0); return array; } } public SourceFileEntry[] IncludeFiles { get { ReadData(); if (include_files == null) { return new SourceFileEntry[0]; } SourceFileEntry[] array = new SourceFileEntry[include_files.Count]; include_files.CopyTo(array, 0); return array; } } public CompileUnitEntry(MonoSymbolFile file, SourceFileEntry source) { this.file = file; this.source = source; Index = file.AddCompileUnit(this); creating = true; namespaces = new List<NamespaceEntry>(); } public void AddFile(SourceFileEntry file) { if (!creating) { throw new InvalidOperationException(); } if (include_files == null) { include_files = new List<SourceFileEntry>(); } include_files.Add(file); } public int DefineNamespace(string name, string[] using_clauses, int parent) { if (!creating) { throw new InvalidOperationException(); } int nextNamespaceIndex = file.GetNextNamespaceIndex(); NamespaceEntry item = new NamespaceEntry(name, nextNamespaceIndex, using_clauses, parent); namespaces.Add(item); return nextNamespaceIndex; } internal void WriteData(MyBinaryWriter bw) { DataOffset = (int)bw.BaseStream.Position; bw.WriteLeb128(source.Index); int value = ((include_files != null) ? include_files.Count : 0); bw.WriteLeb128(value); if (include_files != null) { foreach (SourceFileEntry include_file in include_files) { bw.WriteLeb128(include_file.Index); } } bw.WriteLeb128(namespaces.Count); foreach (NamespaceEntry @namespace in namespaces) { @namespace.Write(file, bw); } } internal void Write(BinaryWriter bw) { bw.Write(Index); bw.Write(DataOffset); } internal CompileUnitEntry(MonoSymbolFile file, MyBinaryReader reader) { this.file = file; Index = reader.ReadInt32(); DataOffset = reader.ReadInt32(); } public void ReadAll() { ReadData(); } private void ReadData() { if (creating) { throw new InvalidOperationException(); } lock (file) { if (namespaces != null) { return; } MyBinaryReader binaryReader = file.BinaryReader; int num = (int)binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = DataOffset; int index = binaryReader.ReadLeb128(); source = file.GetSourceFile(index); int num2 = binaryReader.ReadLeb128(); if (num2 > 0) { include_files = new List<SourceFileEntry>(); for (int i = 0; i < num2; i++) { include_files.Add(file.GetSourceFile(binaryReader.ReadLeb128())); } } int num3 = binaryReader.ReadLeb128(); namespaces = new List<NamespaceEntry>(); for (int j = 0; j < num3; j++) { namespaces.Add(new NamespaceEntry(file, binaryReader)); } binaryReader.BaseStream.Position = num; } } } public class SourceFileEntry { public readonly int Index; private int DataOffset; private MonoSymbolFile file; private string file_name; private byte[] guid; private byte[] hash; private bool creating; private bool auto_generated; private readonly string sourceFile; public static int Size => 8; public byte[] Checksum => hash; public string FileName { get { return file_name; } set { file_name = value; } } public bool AutoGenerated => auto_generated; public SourceFileEntry(MonoSymbolFile file, string file_name) { this.file = file; this.file_name = file_name; Index = file.AddSource(this); creating = true; } public SourceFileEntry(MonoSymbolFile file, string sourceFile, byte[] guid, byte[] checksum) : this(file, sourceFile, sourceFile, guid, checksum) { } public SourceFileEntry(MonoSymbolFile file, string fileName, string sourceFile, byte[] guid, byte[] checksum) : this(file, fileName) { this.guid = guid; hash = checksum; this.sourceFile = sourceFile; } internal void WriteData(MyBinaryWriter bw) { DataOffset = (int)bw.BaseStream.Position; bw.Write(file_name); if (guid == null) { guid = new byte[16]; } if (hash == null) { try { using FileStream inputStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read); MD5 mD = MD5.Create(); hash = mD.ComputeHash(inputStream); } catch { hash = new byte[16]; } } bw.Write(guid); bw.Write(hash); bw.Write((byte)(auto_generated ? 1u : 0u)); } internal void Write(BinaryWriter bw) { bw.Write(Index); bw.Write(DataOffset); } internal SourceFileEntry(MonoSymbolFile file, MyBinaryReader reader) { this.file = file; Index = reader.ReadInt32(); DataOffset = reader.ReadInt32(); int num = (int)reader.BaseStream.Position; reader.BaseStream.Position = DataOffset; sourceFile = (file_name = reader.ReadString()); guid = reader.ReadBytes(16); hash = reader.ReadBytes(16); auto_generated = reader.ReadByte() == 1; reader.BaseStream.Position = num; } public void SetAutoGenerated() { if (!creating) { throw new InvalidOperationException(); } auto_generated = true; file.OffsetTable.FileFlags |= OffsetTable.Flags.IsAspxSource; } public bool CheckChecksum() { try { using FileStream inputStream = new FileStream(sourceFile, FileMode.Open); byte[] array = MD5.Create().ComputeHash(inputStream); for (int i = 0; i < 16; i++) { if (array[i] != hash[i]) { return false; } } return true; } catch { return false; } } public override string ToString() { return $"SourceFileEntry ({Index}:{DataOffset})"; } } public class LineNumberTable { protected LineNumberEntry[] _line_numbers; public readonly int LineBase; public readonly int LineRange; public readonly byte OpcodeBase; public readonly int MaxAddressIncrement; public const int Default_LineBase = -1; public const int Default_LineRange = 8; public const byte Default_OpcodeBase = 9; public const byte DW_LNS_copy = 1; public const byte DW_LNS_advance_pc = 2; public const byte DW_LNS_advance_line = 3; public const byte DW_LNS_set_file = 4; public const byte DW_LNS_const_add_pc = 8; public const byte DW_LNE_end_sequence = 1; public const byte DW_LNE_MONO_negate_is_hidden = 64; internal const byte DW_LNE_MONO__extensions_start = 64; internal const byte DW_LNE_MONO__extensions_end = 127; public LineNumberEntry[] LineNumbers => _line_numbers; protected LineNumberTable(MonoSymbolFile file) { LineBase = file.OffsetTable.LineNumberTable_LineBase; LineRange = file.OffsetTable.LineNumberTable_LineRange; OpcodeBase = (byte)file.OffsetTable.LineNumberTable_OpcodeBase; MaxAddressIncrement = (255 - OpcodeBase) / LineRange; } internal LineNumberTable(MonoSymbolFile file, LineNumberEntry[] lines) : this(file) { _line_numbers = lines; } internal void Write(MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo) { int num = (int)bw.BaseStream.Position; bool flag = false; int num2 = 1; int num3 = 0; int num4 = 1; for (int i = 0; i < LineNumbers.Length; i++) { int num5 = LineNumbers[i].Row - num2; int num6 = LineNumbers[i].Offset - num3; if (LineNumbers[i].File != num4) { bw.Write((byte)4); bw.WriteLeb128(LineNumbers[i].File); num4 = LineNumbers[i].File; } if (LineNumbers[i].IsHidden != flag) { bw.Write((byte)0); bw.Write((byte)1); bw.Write((byte)64); flag = LineNumbers[i].IsHidden; } if (num6 >= MaxAddressIncrement) { if (num6 < 2 * MaxAddressIncrement) { bw.Write((byte)8); num6 -= MaxAddressIncrement; } else { bw.Write((byte)2); bw.WriteLeb128(num6); num6 = 0; } } if (num5 < LineBase || num5 >= LineBase + LineRange) { bw.Write((byte)3); bw.WriteLeb128(num5); if (num6 != 0) { bw.Write((byte)2); bw.WriteLeb128(num6); } bw.Write((byte)1); } else { byte value = (byte)(num5 - LineBase + LineRange * num6 + OpcodeBase); bw.Write(value); } num2 = LineNumbers[i].Row; num3 = LineNumbers[i].Offset; } bw.Write((byte)0); bw.Write((byte)1); bw.Write((byte)1); if (hasColumnsInfo) { for (int j = 0; j < LineNumbers.Length; j++) { LineNumberEntry lineNumberEntry = LineNumbers[j]; if (lineNumberEntry.Row >= 0) { bw.WriteLeb128(lineNumberEntry.Column); } } } if (hasEndInfo) { for (int k = 0; k < LineNumbers.Length; k++) { LineNumberEntry lineNumberEntry2 = LineNumbers[k]; if (lineNumberEntry2.EndRow == -1 || lineNumberEntry2.EndColumn == -1 || lineNumberEntry2.Row > lineNumberEntry2.EndRow) { bw.WriteLeb128(16777215); continue; } bw.WriteLeb128(lineNumberEntry2.EndRow - lineNumberEntry2.Row); bw.WriteLeb128(lineNumberEntry2.EndColumn); } } file.ExtendedLineNumberSize += (int)bw.BaseStream.Position - num; } internal static LineNumberTable Read(MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo) { LineNumberTable lineNumberTable = new LineNumberTable(file); lineNumberTable.DoRead(file, br, readColumnsInfo, readEndInfo); return lineNumberTable; } private void DoRead(MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds) { List<LineNumberEntry> list = new List<LineNumberEntry>(); bool flag = false; bool flag2 = false; int num = 1; int num2 = 0; int file2 = 1; while (true) { byte b = br.ReadByte(); if (b == 0) { byte b2 = br.ReadByte(); long position = br.BaseStream.Position + b2; b = br.ReadByte(); switch (b) { case 1: { if (flag2) { list.Add(new LineNumberEntry(file2, num, -1, num2, flag)); } _line_numbers = list.ToArray(); if (includesColumns) { for (int i = 0; i < _line_numbers.Length; i++) { LineNumberEntry lineNumberEntry = _line_numbers[i]; if (lineNumberEntry.Row >= 0) { lineNumberEntry.Column = br.ReadLeb128(); } } } if (!includesEnds) { return; } for (int j = 0; j < _line_numbers.Length; j++) { LineNumberEntry lineNumberEntry2 = _line_numbers[j]; int num3 = br.ReadLeb128(); if (num3 == 16777215) { lineNumberEntry2.EndRow = -1; lineNumberEntry2.EndColumn = -1; } else { lineNumberEntry2.EndRow = lineNumberEntry2.Row + num3; lineNumberEntry2.EndColumn = br.ReadLeb128(); } } return; } case 64: flag = !flag; flag2 = true; break; default: throw new MonoSymbolFileException("Unknown extended opcode {0:x}", b); case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: break; } br.BaseStream.Position = position; } else if (b < OpcodeBase) { switch (b) { case 1: list.Add(new LineNumberEntry(file2, num, -1, num2, flag)); flag2 = false; break; case 2: num2 += br.ReadLeb128(); flag2 = true; break; case 3: num += br.ReadLeb128(); flag2 = true; break; case 4: file2 = br.ReadLeb128(); flag2 = true; break; case 8: num2 += MaxAddressIncrement; flag2 = true; break; default: throw new MonoSymbolFileException("Unknown standard opcode {0:x} in LNT", b); } } else { b -= OpcodeBase; num2 += b / LineRange; num += LineBase + b % LineRange; list.Add(new LineNumberEntry(file2, num, -1, num2, flag)); flag2 = false; } } } public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) { if (_line_numbers.Length > 1) { start = _line_numbers[0]; end = _line_numbers[_line_numbers.Length - 1]; return true; } start = LineNumberEntry.Null; end = LineNumberEntry.Null; return false; } } public class MethodEntry : IComparable { [Flags] public enum Flags { LocalNamesAmbiguous = 1, ColumnsInfoIncluded = 2, EndInfoIncluded = 4 } public readonly int CompileUnitIndex; public readonly int Token; public readonly int NamespaceID; private int DataOffset; private int LocalVariableTableOffset; private int LineNumberTableOffset; private int CodeBlockTableOffset; private int ScopeVariableTableOffset; private int RealNameOffset; private Flags flags; private int index; public readonly CompileUnitEntry CompileUnit; private LocalVariableEntry[] locals; private CodeBlockEntry[] code_blocks; private ScopeVariable[] scope_vars; private LineNumberTable lnt; private string real_name; public readonly MonoSymbolFile SymbolFile; public const int Size = 12; public Flags MethodFlags => flags; public int Index { get { return index; } set { index = value; } } internal MethodEntry(MonoSymbolFile file, MyBinaryReader reader, int index) { SymbolFile = file; this.index = index; Token = reader.ReadInt32(); DataOffset = reader.ReadInt32(); LineNumberTableOffset = reader.ReadInt32(); long position = reader.BaseStream.Position; reader.BaseStream.Position = DataOffset; CompileUnitIndex = reader.ReadLeb128(); LocalVariableTableOffset = reader.ReadLeb128(); NamespaceID = reader.ReadLeb128(); CodeBlockTableOffset = reader.ReadLeb128(); ScopeVariableTableOffset = reader.ReadLeb128(); RealNameOffset = reader.ReadLeb128(); flags = (Flags)reader.ReadLeb128(); reader.BaseStream.Position = position; CompileUnit = file.GetCompileUnit(CompileUnitIndex); } internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, Flags flags, int namespace_id) { SymbolFile = file; this.real_name = real_name; this.locals = locals; this.code_blocks = code_blocks; this.scope_vars = scope_vars; this.flags = flags; index = -1; Token = token; CompileUnitIndex = comp_unit.Index; CompileUnit = comp_unit; NamespaceID = namespace_id; CheckLineNumberTable(lines); lnt = new LineNumberTable(file, lines); file.NumLineNumbers += lines.Length; int num = ((locals != null) ? locals.Length : 0); if (num <= 32) { for (int i = 0; i < num; i++) { string name = locals[i].Name; for (int j = i + 1; j < num; j++) { if (locals[j].Name == name) { flags |= Flags.LocalNamesAmbiguous; return; } } } return; } Dictionary<string, LocalVariableEntry> dictionary = new Dictionary<string, LocalVariableEntry>(); for (int k = 0; k < locals.Length; k++) { LocalVariableEntry value = locals[k]; if (dictionary.ContainsKey(value.Name)) { flags |= Flags.LocalNamesAmbiguous; break; } dictionary.Add(value.Name, value); } } private static void CheckLineNumberTable(LineNumberEntry[] line_numbers) { int num = -1; int num2 = -1; if (line_numbers == null) { return; } foreach (LineNumberEntry lineNumberEntry in line_numbers) { if (lineNumberEntry.Equals(LineNumberEntry.Null)) { throw new MonoSymbolFileException(); } if (lineNumberEntry.Offset < num) { throw new MonoSymbolFileException(); } if (lineNumberEntry.Offset > num) { num2 = lineNumberEntry.Row; num = lineNumberEntry.Offset; } else if (lineNumberEntry.Row > num2) { num2 = lineNumberEntry.Row; } } } internal void Write(MyBinaryWriter bw) { if (index <= 0 || DataOffset == 0) { throw new InvalidOperationException(); } bw.Write(Token); bw.Write(DataOffset); bw.Write(LineNumberTableOffset); } internal void WriteData(MonoSymbolFile file, MyBinaryWriter bw) { if (index <= 0) { throw new InvalidOperationException(); } LocalVariableTableOffset = (int)bw.BaseStream.Position; int num = ((locals != null) ? locals.Length : 0); bw.WriteLeb128(num); for (int i = 0; i < num; i++) { locals[i].Write(file, bw); } file.LocalCount += num; CodeBlockTableOffset = (int)bw.BaseStream.Position; int num2 = ((code_blocks != null) ? code_blocks.Length : 0); bw.WriteLeb128(num2); for (int j = 0; j < num2; j++) { code_blocks[j].Write(bw); } ScopeVariableTableOffset = (int)bw.BaseStream.Position; int num3 = ((scope_vars != null) ? scope_vars.Length : 0); bw.WriteLeb128(num3); for (int k = 0; k < num3; k++) { scope_vars[k].Write(bw); } if (real_name != null) { RealNameOffset = (int)bw.BaseStream.Position; bw.Write(real_name); } LineNumberEntry[] lineNumbers = lnt.LineNumbers; foreach (LineNumberEntry lineNumberEntry in lineNumbers) { if (lineNumberEntry.EndRow != -1 || lineNumberEntry.EndColumn != -1) { flags |= Flags.EndInfoIncluded; } } LineNumberTableOffset = (int)bw.BaseStream.Position; lnt.Write(file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); DataOffset = (int)bw.BaseStream.Position; bw.WriteLeb128(CompileUnitIndex); bw.WriteLeb128(LocalVariableTableOffset); bw.WriteLeb128(NamespaceID); bw.WriteLeb128(CodeBlockTableOffset); bw.WriteLeb128(ScopeVariableTableOffset); bw.WriteLeb128(RealNameOffset); bw.WriteLeb128((int)flags); } public void ReadAll() { GetLineNumberTable(); GetLocals(); GetCodeBlocks(); GetScopeVariables(); GetRealName(); } public LineNumberTable GetLineNumberTable() { lock (SymbolFile) { if (lnt != null) { return lnt; } if (LineNumberTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = LineNumberTableOffset; lnt = LineNumberTable.Read(SymbolFile, binaryReader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); binaryReader.BaseStream.Position = position; return lnt; } } public LocalVariableEntry[] GetLocals() { lock (SymbolFile) { if (locals != null) { return locals; } if (LocalVariableTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = LocalVariableTableOffset; int num = binaryReader.ReadLeb128(); locals = new LocalVariableEntry[num]; for (int i = 0; i < num; i++) { locals[i] = new LocalVariableEntry(SymbolFile, binaryReader); } binaryReader.BaseStream.Position = position; return locals; } } public CodeBlockEntry[] GetCodeBlocks() { lock (SymbolFile) { if (code_blocks != null) { return code_blocks; } if (CodeBlockTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = CodeBlockTableOffset; int num = binaryReader.ReadLeb128(); code_blocks = new CodeBlockEntry[num]; for (int i = 0; i < num; i++) { code_blocks[i] = new CodeBlockEntry(i, binaryReader); } binaryReader.BaseStream.Position = position; return code_blocks; } } public ScopeVariable[] GetScopeVariables() { lock (SymbolFile) { if (scope_vars != null) { return scope_vars; } if (ScopeVariableTableOffset == 0) { return null; } MyBinaryReader binaryReader = SymbolFile.BinaryReader; long position = binaryReader.BaseStream.Position; binaryReader.BaseStream.Position = ScopeVariableTableOffset; int num = binaryReader.ReadLeb128(); scope_vars = new ScopeVariable[num]; for (int i = 0; i < num; i++) { scope_vars[i] = new ScopeVariable(binaryReader); } binaryReader.BaseStream.Position = position; return scope_vars; } } public string GetRealName() { lock (SymbolFile) { if (real_name != null) { return real_name; } if (RealNameOffset == 0) { return null; } real_name = SymbolFile.BinaryReader.ReadString(RealNameOffset); return real_name; } } public int CompareTo(object obj) { MethodEntry methodEntry = (MethodEntry)obj; if (methodEntry.Token < Token) { return 1; } if (methodEntry.Token > Token) { return -1; } return 0; } public override string ToString() { return $"[Method {index}:{Token:x}:{CompileUnitIndex}:{CompileUnit}]"; } } public struct NamespaceEntry { public readonly string Name; public readonly int Index; public readonly int Parent; public readonly string[] UsingClauses; public NamespaceEntry(string name, int index, string[] using_clauses, int parent) { Name = name; Index = index; Parent = parent; UsingClauses = ((using_clauses != null) ? using_clauses : new string[0]); } internal NamespaceEntry(MonoSymbolFile file, MyBinaryReader reader) { Name = reader.ReadString(); Index = reader.ReadLeb128(); Parent = reader.ReadLeb128(); int num = reader.ReadLeb128(); UsingClauses = new string[num]; for (int i = 0; i < num; i++) { UsingClauses[i] = reader.ReadString(); } } internal void Write(MonoSymbolFile file, MyBinaryWriter bw) { bw.Write(Name); bw.WriteLeb128(Index); bw.WriteLeb128(Parent); bw.WriteLeb128(UsingClauses.Length); string[] usingClauses = UsingClauses; foreach (string value in usingClauses) { bw.Write(value); } } public override string ToString() { return $"[Namespace {Name}:{Index}:{Parent}]"; } } public class SourceMethodBuilder { private List<LocalVariableEntry> _locals; private List<CodeBlockEntry> _blocks; private List<ScopeVariable> _scope_vars; private Stack<CodeBlockEntry> _block_stack; private readonly List<LineNumberEntry> method_lines; private readonly ICompileUnit _comp_unit; private readonly int ns_id; private readonly IMethodDef method; public CodeBlockEntry[] Blocks { get { if (_blocks == null) { return new CodeBlockEntry[0]; } CodeBlockEntry[] array = new CodeBlockEntry[_blocks.Count]; _blocks.CopyTo(array, 0); return array; } } public CodeBlockEntry CurrentBlock { get { if (_block_stack != null && _block_stack.Count > 0) { return _block_stack.Peek(); } return null; } } public LocalVariableEntry[] Locals { get { if (_locals == null) { return new LocalVariableEntry[0]; } return _locals.ToArray(); } } public ICompileUnit SourceFile => _comp_unit; public ScopeVariable[] ScopeVariables { get { if (_scope_vars == null) { return new ScopeVariable[0]; } return _scope_vars.ToArray(); } } public SourceMethodBuilder(ICompileUnit comp_unit) { _comp_unit = comp_unit; method_lines = new List<LineNumberEntry>(); } public SourceMethodBuilder(ICompileUnit comp_unit, int ns_id, IMethodDef method) : this(comp_unit) { this.ns_id = ns_id; this.method = method; } public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) { MarkSequencePoint(offset, file, line, column, -1, -1, is_hidden); } public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden) { LineNumberEntry lineNumberEntry = new LineNumberEntry(file?.Index ?? 0, line, column, end_line, end_column, offset, is_hidden); if (method_lines.Count > 0) { LineNumberEntry lineNumberEntry2 = method_lines[method_lines.Count - 1]; if (lineNumberEntry2.Offset == offset) { if (LineNumberEntry.LocationComparer.Default.Compare(lineNumberEntry, lineNumberEntry2) > 0) { method_lines[method_lines.Count - 1] = lineNumberEntry; } return; } } method_lines.Add(lineNumberEntry); } public void StartBlock(CodeBlockEntry.Type type, int start_offset) { StartBlock(type, start_offset, (_blocks == null) ? 1 : (_blocks.Count + 1)); } public void StartBlock(CodeBlockEntry.Type type, int start_offset, int scopeIndex) { if (_block_stack == null) { _block_stack = new Stack<CodeBlockEntry>(); } if (_blocks == null) { _blocks = new List<CodeBlockEntry>(); } int parent = ((CurrentBlock != null) ? CurrentBlock.Index : (-1)); CodeBlockEntry item = new CodeBlockEntry(scopeIndex, parent, type, start_offset); _block_stack.Push(item); _blocks.Add(item); } public void EndBlock(int end_offset) { _block_stack.Pop().Close(end_offset); } public void AddLocal(int index, string name) { if (_locals == null) { _locals = new List<LocalVariableEntry>(); } int block = ((CurrentBlock != null) ? CurrentBlock.Index : 0); _locals.Add(new LocalVariableEntry(index, name, block)); } public void AddScopeVariable(int scope, int index) { if (_scope_vars == null) { _scope_vars = new List<ScopeVariable>(); } _scope_vars.Add(new ScopeVariable(scope, index)); } public void DefineMethod(MonoSymbolFile file) { DefineMethod(file, method.Token); } public void DefineMethod(MonoSymbolFile file, int token) { CodeBlockEntry[] array = Blocks; if (array.Length != 0) { List<CodeBlockEntry> list = new List<CodeBlockEntry>(array.Length); int num = 0; for (int i = 0; i < array.Length; i++) { num = Math.Max(num, array[i].Index); } for (int j = 0; j < num; j++) { int num2 = j + 1; if (j < array.Length && array[j].Index == num2) { list.Add(array[j]); continue; } bool flag = false; for (int k = 0; k < array.Length; k++) { if (array[k].Index == num2) { list.Add(array[k]); flag = true; break; } } if (!flag) { list.Add(new CodeBlockEntry(num2, -1, CodeBlockEntry.Type.CompilerGenerated, 0)); } } array = list.ToArray(); } MethodEntry entry = new MethodEntry(file, _comp_unit.Entry, token, ScopeVariables, Locals, method_lines.ToArray(), array, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id); file.AddMethod(entry); } } } namespace Mono.CSharp { public abstract class CompilerGeneratedContainer : ClassOrStruct { protected CompilerGeneratedContainer(TypeContainer parent, MemberName name, Modifiers mod) : this(parent, name, mod, MemberKind.Class) { } protected CompilerGeneratedContainer(TypeContainer parent, MemberName name, Modifiers mod, MemberKind kind) : base(parent, name, null, kind) { base.ModFlags = mod | Modifiers.COMPILER_GENERATED | Modifiers.SEALED; spec = new TypeSpec(Kind, null, this, null, base.ModFlags); } protected void CheckMembersDefined() { if (base.HasMembersDefined) { throw new InternalErrorException("Helper class already defined!"); } } protected override bool DoDefineMembers() { if (Kind == MemberKind.Class && !base.IsStatic && !base.PartialContainer.HasInstanceConstructor) { DefineDefaultConstructor(is_static: false); } return base.DoDefineMembers(); } protected static MemberName MakeMemberName(MemberBase host, string name, int unique_id, TypeParameters tparams, Location loc) { string name2 = MakeName((host == null) ? null : ((host is InterfaceMemberBase) ? ((InterfaceMemberBase)host).GetFullName(host.MemberName) : host.MemberName.Name), "c", name, unique_id); TypeParameters typeParameters = null; if (tparams != null) { typeParameters = new TypeParameters(tparams.Count); for (int i = 0; i < tparams.Count; i++) { typeParameters.Add((TypeParameter)null); } } return new MemberName(name2, typeParameters, loc); } public static string MakeName(string host, string typePrefix, string name, int id) { return "<" + host + ">" + typePrefix + "__" + name + id.ToString("X"); } protected override TypeSpec[] ResolveBaseTypes(out FullNamedExpression base_class) { base_type = Compiler.BuiltinTypes.Object; base_class = null; return null; } } public class HoistedStoreyClass : CompilerGeneratedContainer { public sealed class HoistedField : Field { public HoistedField(HoistedStoreyClass parent, FullNamedExpression type, Modifiers mod, string name, Attributes attrs, Location loc) : base(parent, type, mod, new MemberName(name, loc), attrs) { } protected override bool ResolveMemberType() { if (!base.ResolveMemberType()) { return false; } HoistedStoreyClass genericStorey = ((HoistedStoreyClass)Parent).GetGenericStorey(); if (genericStorey != null && genericStorey.Mutator != null) { member_type = genericStorey.Mutator.Mutate(base.MemberType); } return true; } } protected TypeParameterMutator mutator; public TypeParameterMutator Mutator { get { return mutator; } set { mutator = value; } } public HoistedStoreyClass(TypeDefinition parent, MemberName name, TypeParameters tparams, Modifiers mods, MemberKind kind) : base(parent, name, mods | Modifiers.PRIVATE, kind) { if (tparams != null) { TypeParameters typeParameters = name.TypeParameters; TypeParameterSpec[] array = new TypeParameterSpec[tparams.Count]; TypeParameterSpec[] array2 = new TypeParameterSpec[tparams.Count]; for (int i = 0; i < tparams.Count; i++) { typeParameters[i] = tparams[i].CreateHoistedCopy(spec); array[i] = tparams[i].Type; array2[i] = typeParameters[i].Type; } TypeParameterInflator inflator = new TypeParameterInflator(this, null, array, array2); for (int j = 0; j < tparams.Count; j++) { array[j].InflateConstraints(inflator, array2[j]); } mutator = new TypeParameterMutator(tparams, typeParameters); } } public HoistedStoreyClass GetGenericStorey() { TypeContainer typeContainer = this; while (typeContainer != null && typeContainer.CurrentTypeParameters == null) { typeContainer = typeContainer.Parent; } return typeContainer as HoistedStoreyClass; } } public class AnonymousMethodStorey : HoistedStoreyClass { private struct StoreyFieldPair { public readonly AnonymousMethodStorey Storey; public readonly Field Field; public StoreyFieldPair(AnonymousMethodStorey storey, Field field) { Storey = storey; Field = field; } } private sealed class ThisInitializer : Statement { private readonly HoistedThis hoisted_this; private readonly AnonymousMethodStorey parent; public ThisInitializer(HoistedThis hoisted_this, AnonymousMethodStorey parent) { this.hoisted_this = hoisted_this; this.parent = parent; } protected override void DoEmit(EmitContext ec) { Expression source = ((parent != null) ? ((Expression)new FieldExpr(parent.HoistedThis.Field, Location.Null) { InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, Location.Null) }) : ((Expression)new CompilerGeneratedThis(ec.CurrentType, loc))); hoisted_this.EmitAssign(ec, source, leave_copy: false, isCompound: false); } protected override bool DoFlowAnalysis(FlowAnalysisContext fc) { return false; } protected override void CloneTo(CloneContext clonectx, Statement target) { } } public readonly int ID; public readonly ExplicitBlock OriginalSourceBlock; private List<StoreyFieldPair> used_parent_storeys; private List<ExplicitBlock> children_references; protected List<HoistedParameter> hoisted_params; private List<HoistedParameter> hoisted_local_params; protected List<HoistedVariable> hoisted_locals; protected HoistedThis hoisted_this; public Expression Instance; private bool initialize_hoisted_this; private AnonymousMethodStorey hoisted_this_parent; public HoistedThis HoistedThis { get { return hoisted_this; } set { hoisted_this = value; } } public IList<ExplicitBlock> ReferencesFromChildrenBlock => children_references; public AnonymousMethodStorey(ExplicitBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind) : base(parent, CompilerGeneratedContainer.MakeMemberName(host, name, parent.PartialContainer.CounterAnonymousContainers, tparams, block.StartLocation), tparams, (Modifiers)0, kind) { OriginalSourceBlock = block; ID = parent.PartialContainer.CounterAnonymousContainers++; } public void AddCapturedThisField(EmitContext ec, AnonymousMethodStorey parent) { TypeExpr type = new TypeExpression(ec.CurrentType, base.Location); Field field = AddCompilerGeneratedField("$this", type); hoisted_this = new HoistedThis(this, field); initialize_hoisted_this = true; hoisted_this_parent = parent; } public Field AddCapturedVariable(string name, TypeSpec type) { CheckMembersDefined(); FullNamedExpression type2 = new TypeExpression(type, base.Location); if (!spec.IsGenericOrParentIsGeneric) { return AddCompilerGeneratedField(name, type2); } Field field = new HoistedField(this, type2, Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED, name, null, base.Location); AddField(field); return field; } protected Field AddCompilerGeneratedField(string name, FullNamedExpression type) { return AddCompilerGeneratedField(name, type, privateAccess: false); } protected Field AddCompilerGeneratedField(string name, FullNamedExpression type, bool privateAccess) { Modifiers mod = Modifiers.COMPILER_GENERATED | (privateAccess ? Modifiers.PRIVATE : Modifiers.INTERNAL); Field field = new Field(this, type, mod, new MemberName(name, base.Location), null); AddField(field); return field; } public void AddReferenceFromChildrenBlock(ExplicitBlock block) { if (children_references == null) { children_references = new List<ExplicitBlock>(); } if (!children_references.Contains(block)) { children_references.Add(block); } } public void AddParentStoreyReference(EmitContext ec, AnonymousMethodStorey storey) { CheckMembersDefined(); if (used_parent_storeys == null) { used_parent_storeys = new List<StoreyFieldPair>(); } else if (used_parent_storeys.Exists((StoreyFieldPair i) => i.Storey == storey)) { return; } TypeExpr type = storey.CreateStoreyTypeExpression(ec); Field field = AddCompilerGeneratedField("<>f__ref$" + storey.ID, type); used_parent_storeys.Add(new StoreyFieldPair(storey, field)); } public void CaptureLocalVariable(ResolveContext ec, LocalVariable localVariable) { if (this is StateMachine) { if (ec.CurrentBlock.ParametersBlock != localVariable.Block.ParametersBlock) { ec.CurrentBlock.Explicit.HasCapturedVariable = true; } } else { ec.CurrentBlock.Explicit.HasCapturedVariable = true; } HoistedVariable hoistedVariable = localVariable.HoistedVariant; if (hoistedVariable != null && hoistedVariable.Storey != this && hoistedVariable.Storey is StateMachine) { hoistedVariable.Storey.hoisted_locals.Remove(hoistedVariable); hoistedVariable.Storey.Members.Remove(hoistedVariable.Field); hoistedVariable = null; } if (hoistedVariable == null) { hoistedVariable = (localVariable.HoistedVariant = new HoistedLocalVariable(this, localVariable, GetVariableMangledName(ec, localVariable))); if (hoisted_locals == null) { hoisted_locals = new List<HoistedVariable>(); } hoisted_locals.Add(hoistedVariable); } if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit && !(hoistedVariable.Storey is StateMachine) && hoistedVariable.Storey != null) { hoistedVariable.Storey.AddReferenceFromChildrenBlock(ec.CurrentBlock.Explicit); } } public void CaptureParameter(ResolveContext ec, ParametersBlock.ParameterInfo parameterInfo, ParameterReference parameterReference) { if (!(this is StateMachine)) { ec.CurrentBlock.Explicit.HasCapturedVariable = true; } HoistedParameter hoistedParameter = parameterInfo.Parameter.HoistedVariant; if (parameterInfo.Block.StateMachine != null) { if (hoistedParameter == null && parameterInfo.Block.StateMachine != this) { StateMachine stateMachine = parameterInfo.Block.StateMachine; hoistedParameter = new HoistedParameter(stateMachine, parameterReference); parameterInfo.Parameter.HoistedVariant = hoistedParameter; if (stateMachine.hoisted_params == null) { stateMachine.hoisted_params = new List<HoistedParameter>(); } stateMachine.hoisted_params.Add(hoistedParameter); } if (hoistedParameter != null && hoistedParameter.Storey != this && hoistedParameter.Storey is StateMachine) { if (hoisted_local_params == null) { hoisted_local_params = new List<HoistedParameter>(); } hoisted_local_params.Add(hoistedParameter); hoistedParameter = null; } } if (hoistedParameter == null) { hoistedParameter = new HoistedParameter(this, parameterReference); parameterInfo.Parameter.HoistedVariant = hoistedParameter; if (hoisted_params == null) { hoisted_params = new List<HoistedParameter>(); } hoisted_params.Add(hoistedParameter); } if (ec.CurrentBlock.Explicit != parameterInfo.Block) { hoistedParameter.Storey.AddReferenceFromChildrenBlock(ec.CurrentBlock.Explicit); } } private TypeExpr CreateStoreyTypeExpression(EmitContext ec) { if (CurrentTypeParameters != null) { TypeParameters typeParameters = ((ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.Storey != null) ? ec.CurrentAnonymousMethod.Storey.CurrentTypeParameters : ec.CurrentTypeParameters); TypeArguments typeArguments = new TypeArguments(); for (int i = 0; i < typeParameters.Count; i++) { typeArguments.Add(new SimpleName(typeParameters[i].Name, base.Location)); } return new GenericTypeExpr(base.Definition, typeArguments, base.Location); } return new TypeExpression(CurrentType, base.Location); } public void SetNestedStoryParent(AnonymousMethodStorey parentStorey) { Parent = parentStorey; spec.IsGeneric = false; spec.DeclaringType = parentStorey.CurrentType; base.MemberName.TypeParameters = null; } protected override bool DoResolveTypeParameters() { if (CurrentTypeParameters != null) { for (int i = 0; i < CurrentTypeParameters.Count; i++) { TypeParameterSpec type = CurrentTypeParameters[i].Type; type.BaseType = mutator.Mutate(type.BaseType); if (type.InterfacesDefined != null) { TypeSpec[] array = new TypeSpec[type.InterfacesDefined.Length]; for (int j = 0; j < array.Length; j++) { array[j] = mutator.Mutate(type.InterfacesDefined[j]); } type.InterfacesDefined = array; } if (type.TypeArguments != null) { type.TypeArguments = mutator.Mutate(type.TypeArguments); } } } Parent.CurrentType.MemberCache.AddMember(spec); return true; } public void EmitStoreyInstantiation(EmitContext ec, ExplicitBlock block) { if (Instance != null) { throw new InternalErrorException(); } ResolveContext resolveContext = new ResolveContext(ec.MemberContext); resolveContext.CurrentBlock = block; TypeExpr typeExpr = CreateStoreyTypeExpression(ec); Expression expression = new New(typeExpr, null, base.Location).Resolve(resolveContext); if (ec.CurrentAnonymousMethod is StateMachineInitializer && (block.HasYield || block.HasAwait)) { Field field = ec.CurrentAnonymousMethod.Storey.AddCompilerGeneratedField(LocalVariable.GetCompilerGeneratedName(block), typeExpr, privateAccess: true); field.Define(); field.Emit(); FieldExpr fieldExpr = new FieldExpr(field, base.Location); fieldExpr.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, base.Location); fieldExpr.EmitAssign(ec, expression, leave_copy: false, isCompound: false); Instance = fieldExpr; } else { TemporaryVariableReference temporaryVariableReference = TemporaryVariableReference.Create(expression.Type, block, base.Location, writeToSymbolFile: true); if (expression.Type.IsStruct) { temporaryVariableReference.LocalInfo.CreateBuilder(ec); } else { temporaryVariableReference.EmitAssign(ec, expression); } Instance = temporaryVariableReference; } EmitHoistedFieldsInitialization(resolveContext, ec); } private void EmitHoistedFieldsInitialization(ResolveContext rc, EmitContext ec) { if (used_parent_storeys != null) { foreach (StoreyFieldPair used_parent_storey in used_parent_storeys) { Expression storeyInstanceExpression = GetStoreyInstanceExpression(ec); FieldSpec member = used_parent_storey.Field.Spec; if (TypeManager.IsGenericType(storeyInstanceExpression.Type)) { member = MemberCache.GetMember(storeyInstanceExpression.Type, member); } SimpleAssign simpleAssign = new SimpleAssign(new FieldExpr(member, base.Location) { InstanceExpression = storeyInstanceExpression }, used_parent_storey.Storey.GetStoreyInstanceExpression(ec)); if (simpleAssign.Resolve(rc) != null) { simpleAssign.EmitStatement(ec); } } } if (initialize_hoisted_this) { rc.CurrentBlock.AddScopeStatement(new ThisInitializer(hoisted_this, hoisted_this_parent)); } AnonymousExpression currentAnonymousMethod = ec.CurrentAnonymousMethod; ec.CurrentAnonymousMethod = null; if (hoisted_params != null) { EmitHoistedParameters(ec, hoisted_params); } ec.CurrentAnonymousMethod = currentAnonymousMethod; } protected virtual void EmitHoistedParameters(EmitContext ec, List<HoistedParameter> hoisted) { foreach (HoistedParameter hp in hoisted) { if (hp == null) { continue; } if (hoisted_local_params != null) { FieldExpr fieldExpr = new FieldExpr(hoisted_local_params.Find((HoistedParameter l) => l.Parameter.Parameter == hp.Parameter.Parameter).Field, base.Location); fieldExpr.InstanceExpression = new CompilerGeneratedThis(CurrentType, base.Location); hp.EmitAssign(ec, fieldExpr, leave_copy: false, isCompound: false); } else { hp.EmitHoistingAssignment(ec); } } } private Field GetReferencedStoreyField(AnonymousMethodStorey storey) { if (used_parent_storeys == null) { return null; } foreach (StoreyFieldPair used_parent_storey in used_parent_storeys) { if (used_parent_storey.Storey == storey) { return used_parent_storey.Field; } } return null; } public Expression GetStoreyInstanceExpression(EmitContext ec) { AnonymousExpression currentAnonymousMethod = ec.CurrentAnonymousMethod; if (currentAnonymousMethod == null) { return Instance; } if (currentAnonymousMethod.Storey == null) { return Instance; } Field referencedStoreyField = currentAnonymousMethod.Storey.GetReferencedStoreyField(this); if (referencedStoreyField == null) { if (currentAnonymousMethod.Storey == this) { return new CompilerGeneratedThis(CurrentType, base.Location); } return Instance; } return new FieldExpr(referencedStoreyField, base.Location) { InstanceExpression = new CompilerGeneratedThis(CurrentType, base.Location) }; } protected virtual string GetVariableMangledName(ResolveContext rc, LocalVariable local_info) { return local_info.Name; } } public abstract class HoistedVariable { private class ExpressionTreeVariableReference : Expression { private readonly HoistedVariable hv; public ExpressionTreeVariableReference(HoistedVariable hv) { this.hv = hv; } public override bool ContainsEmitWithAwait() { return false; } public override Expression CreateExpressionTree(ResolveContext ec) { return hv.CreateExpressionTree(); } protected override Expression DoResolve(ResolveContext ec) { eclass = ExprClass.Value; type = ec.Module.PredefinedTypes.Expression.Resolve(); return this; } public override void Emit(EmitContext ec) { ResolveContext resolveContext = new ResolveContext(ec.MemberContext); Expression expression = hv.GetFieldExpression(ec).CreateExpressionTree(resolveContext, convertInstance: false); expression.Resolve(resolveContext)?.Emit(ec); } } protected readonly AnonymousMethodStorey storey; protected Field field; private Dictionary<AnonymousExpression, FieldExpr> cached_inner_access; private FieldExpr cached_outer_access; public Field Field => field; public AnonymousMethodStorey Storey => storey; protected HoistedVariable(AnonymousMethodStorey storey, string name, TypeSpec type) : this(storey, storey.AddCapturedVariable(name, type)) { } protected HoistedVariable(AnonymousMethodStorey storey, Field field) { this.storey = storey; this.field = field; } public void AddressOf(EmitContext ec, AddressOp mode) { GetFieldExpression(ec).AddressOf(ec, mode); } public Expression CreateExpressionTree() { return new ExpressionTreeVariableReference(this); } public void Emit(EmitContext ec) { GetFieldExpression(ec).Emit(ec); } public Expression EmitToField(EmitContext ec) { return GetFieldExpression(ec); } protected virtual FieldExpr GetFieldExpression(EmitContext ec) { if (ec.CurrentAnonymousMethod == null || ec.CurrentAnonymousMethod.Storey == null) { if (cached_outer_access != null) { return cached_outer_access; } if (storey.Instance.Type.IsGenericOrParentIsGeneric) { FieldSpec member = MemberCache.GetMember(storey.Instance.Type, field.Spec); cached_outer_access = new FieldExpr(member, field.Location); } else { cached_outer_access = new FieldExpr(field, field.Location); } cached_outer_access.InstanceExpression = storey.GetStoreyInstanceExpression(ec); return cached_outer_access; } FieldExpr value; if (cached_inner_access != null) { if (!cached_inner_access.TryGetValue(ec.CurrentAnonymousMethod, out value)) { value = null; } } else { value = null; cached_inner_access = new Dictionary<AnonymousExpression, FieldExpr>(4); } if (value == null) { value = ((!field.Parent.IsGenericOrParentIsGeneric) ? new FieldExpr(field, field.Location) : new FieldExpr(MemberCache.GetMember(field.Parent.CurrentType, field.Spec), field.Location)); value.InstanceExpression = storey.GetStoreyInstanceExpression(ec); cached_inner_access.Add(ec.CurrentAnonymousMethod, value); } return value; } public void Emit(EmitContext ec, bool leave_copy) { GetFieldExpression(ec).Emit(ec, leave_copy); } public void EmitAssign(EmitContext ec, Expression source, bool leave_copy, bool isCompound) { GetFieldExpression(ec).EmitAssign(ec, source, leave_copy, isCompound: false); } } public class HoistedParameter : HoistedVariable { private sealed class HoistedFieldAssign : CompilerAssign { public HoistedFieldAssign(Expression target, Expression source) : base(target, source, target.Location) { } protected override Expression ResolveConversions(ResolveContext ec) { return this; } } private readonly ParameterReference parameter; public bool IsAssigned { get; set; } public ParameterReference Parameter => parameter; public HoistedParameter(AnonymousMethodStorey scope, ParameterReference par) : base(scope, par.Name, par.Type) { parameter = par; } public HoistedParameter(HoistedParameter hp, string name) : base(hp.storey, name, hp.parameter.Type) { parameter = hp.parameter; } public void EmitHoistingAssignment(EmitContext ec) { HoistedParameter hoistedVariant = parameter.Parameter.HoistedVariant; parameter.Parameter.HoistedVariant = null; new HoistedFieldAssign(GetFieldExpression(ec), parameter).EmitStatement(ec); parameter.Parameter.HoistedVariant = hoistedVariant; } } internal class HoistedLocalVariable : HoistedVariable { public HoistedLocalVariable(AnonymousMethodStorey storey, LocalVariable local, string name) : base(storey, name, local.Type) { } } public class HoistedThis : HoistedVariable { public HoistedThis(AnonymousMethodStorey storey, Field field) : base(storey, field) { } } public class AnonymousMethodExpression : Expression { private class Quote : ShimExpression { public Quote(Expression expr) : base(expr) { } public override Expression CreateExpressionTree(ResolveContext ec) { Arguments arguments = new Arguments(1); arguments.Add(new Argument(expr.CreateExpressionTree(ec))); return CreateExpressionFactoryCall(ec, "Quote", arguments); } protected override Expression DoResolve(ResolveContext rc) { expr = expr.Resolve(rc); if (expr == null) { return null; } eclass = expr.eclass; type = expr.Type; return this; } } private readonly Dictionary<TypeSpec, Expression> compatibles; public ParametersBlock Block; public override string ExprClassName => "anonymous method"; public virtual bool HasExplicitParameters => Parameters != ParametersCompiled.Undefined; public override bool IsSideEffectFree => true; public ParametersCompiled Parameters => Block.Parameters; public ReportPrinter TypeInferenceReportPrinter { get; set; } public AnonymousMethodExpression(Location loc) { base.loc = loc; compatibles = new Dictionary<TypeSpec, Expression>(); } public bool ImplicitStandardConversionExists(ResolveContext ec, TypeSpec delegate_type) { using (ec.With(ResolveContext.Options.InferReturnType, enable: false)) { using (ec.Set(ResolveContext.Options.ProbingMode)) { ReportPrinter printer = ec.Report.SetPrinter(TypeInferenceReportPrinter ?? new NullReportPrinter()); bool result = Compatible(ec, delegate_type) != null; ec.Report.SetPrinter(printer); return result; } } } private TypeSpec CompatibleChecks(ResolveContext ec, TypeSpec delegate_type) { if (delegate_type.IsDelegate) { return delegate_type; } if (delegate_type.IsExpressionTreeType) { delegate_type = delegate_type.TypeArguments[0]; if (delegate_type.IsDelegate) { return delegate_type; } ec.Report.Error(835, loc, "Cannot convert `{0}' to an expression tree of non-delegate type `{1}'", GetSignatureForError(), delegate_type.GetSignatureForError()); return null; } ec.Report.Error(1660, loc, "Cannot convert `{0}' to non-delegate type `{1}'", GetSignatureForError(), delegate_type.GetSignatureForError()); return null; } protected bool VerifyExplicitParameters(ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection parameters) { if (VerifyParameterCompatibility(ec, tic, delegate_type, parameters, ec.IsInProbingMode)) { return true; } if (!ec.IsInProbingMode) { ec.Report.Error(1661, loc, "Cannot convert `{0}' to delegate type `{1}' since there is a parameter mismatch", GetSignatureForError(), delegate_type.GetSignatureForError()); } return false; } protected bool VerifyParameterCompatibility(ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors) { if (Parameters.Count != invoke_pd.Count) { if (ignore_errors) { return false; } ec.Report.Error(1593, loc, "Delegate `{0}' does not take `{1}' arguments", delegate_type.GetSignatureForError(), Parameters.Count.ToString()); return false; } bool flag = !HasExplicitParameters; bool flag2 = false; for (int i = 0; i < Parameters.Count; i++) { Parameter.Modifier modFlags = invoke_pd.FixedParameters[i].ModFlags; if (Parameters.FixedParameters[i].ModFlags != modFlags && modFlags != Parameter.Modifier.PARAMS) { if (ignore_errors) { return false; } if (modFlags == Parameter.Modifier.NONE) { ec.Report.Error(1677, Parameters[i].Location, "Parameter `{0}' should not be declared with the `{1}' keyword", (i + 1).ToString(), Parameter.GetModifierSignature(Parameters[i].ModFlags)); } else { ec.Report.Error(1676, Parameters[i].Location, "Parameter `{0}' must be declared with the `{1}' keyword", (i + 1).ToString(), Parameter.GetModifierSignature(modFlags)); } flag2 = true; } if (flag) { continue; }