From 907c6b65aac43cc913b5b44e25e576a5b285679e Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 16 Sep 2026 17:12:25 +0200 Subject: [PATCH] docs: add missing XML doc comments for CS1591 Signed-off-by: hazre --- BepInEx.Core/Bootstrap/BaseChainloader.cs | 29 ++++- BepInEx.Core/Bootstrap/TypeLoader.cs | 50 +++++---- .../Configuration/AcceptableValueBase.cs | 10 +- .../Configuration/AcceptableValueList.cs | 8 +- .../Configuration/AcceptableValueRange.cs | 6 +- .../Configuration/ConfigDefinition.cs | 20 ++-- .../Configuration/ConfigDescription.cs | 17 ++- BepInEx.Core/Configuration/ConfigEntryBase.cs | 36 +++--- BepInEx.Core/Configuration/ConfigFile.cs | 106 +++++++++--------- BepInEx.Core/Configuration/ConfigWrapper.cs | 12 +- .../Configuration/SettingChangedEventArgs.cs | 4 +- .../Configuration/TomlTypeConverter.cs | 18 +-- BepInEx.Core/Configuration/TypeConverter.cs | 10 +- BepInEx.Core/Console/ConsoleManager.cs | 27 ++++- BepInEx.Core/Console/SafeConsole.cs | 2 +- BepInEx.Core/Contract/Attributes.cs | 76 ++++++------- BepInEx.Core/Contract/IPlugin.cs | 4 +- BepInEx.Core/Contract/PluginInfo.cs | 18 +-- .../BepInExLogInterpolatedStringHandler.cs | 20 ++-- BepInEx.Core/Logging/ConsoleLogListener.cs | 3 +- BepInEx.Core/Logging/DiskLogListener.cs | 15 +-- BepInEx.Core/Logging/HarmonyLogSource.cs | 5 + BepInEx.Core/Logging/ILogListener.cs | 13 +-- BepInEx.Core/Logging/ILogSource.cs | 6 +- BepInEx.Core/Logging/LogEventArgs.cs | 12 +- BepInEx.Core/Logging/LogLevel.cs | 24 ++-- BepInEx.Core/Logging/Logger.cs | 14 +-- BepInEx.Core/Logging/ManualLogSource.cs | 32 +++--- BepInEx.Core/Logging/TraceLogSource.cs | 14 +-- BepInEx.Core/Paths.cs | 40 ++++--- BepInEx.Core/PlatformUtils.cs | 2 +- BepInEx.Core/Utility.cs | 52 ++++----- BepInEx.Preloader.Core/AssemblyBuildInfo.cs | 13 +++ BepInEx.Preloader.Core/EnvVars.cs | 15 ++- .../InternalPreloaderLogger.cs | 2 + .../Logging/ChainloaderLogHelper.cs | 4 + .../Logging/PreloaderConsoleListener.cs | 4 +- .../Patching/AssemblyPatcher.cs | 26 ++--- BepInEx.Preloader.Core/Patching/Attributes.cs | 23 ++-- .../Patching/BasePatcher.cs | 16 +-- .../Patching/PatcherContext.cs | 54 ++++----- .../Patching/PatcherPluginMetadata.cs | 4 +- .../RuntimeFixes/ConsoleSetOutFix.cs | 2 + .../RuntimeFixes/HarmonyBackendFix.cs | 2 + Runtimes/NET/BepInEx.NET.Common/BasePlugin.cs | 8 ++ .../NET/BepInEx.NET.Common/NetChainloader.cs | 5 + .../NET/BepInEx.NET.CoreCLR/HookEntrypoint.cs | 8 ++ .../BepInEx.NET.Shared/SharedEntrypoint.cs | 7 +- Runtimes/NET/BepisLoader/BepisLoader.cs | 7 +- build/Program.cs | 49 +++++++- 50 files changed, 544 insertions(+), 410 deletions(-) diff --git a/BepInEx.Core/Bootstrap/BaseChainloader.cs b/BepInEx.Core/Bootstrap/BaseChainloader.cs index 3aa6d92d5..8a84abc31 100644 --- a/BepInEx.Core/Bootstrap/BaseChainloader.cs +++ b/BepInEx.Core/Bootstrap/BaseChainloader.cs @@ -12,15 +12,18 @@ namespace BepInEx.Bootstrap; +/// Base chainloader used to load and manage plugins. public abstract class BaseChainloader { + /// Name of the currently executing BepInEx assembly. protected static readonly string CurrentAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + /// Version of the currently executing BepInEx assembly. protected static readonly Version CurrentAssemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; private static readonly Dictionary RefCache = new(); private static Regex allowedGuidRegex { get; } = new(@"^[a-zA-Z0-9\._\-]+$"); /// - /// Analyzes the given type definition and attempts to convert it to a valid + /// Analyzes the given type definition and attempts to convert it to a valid /// /// Type definition to analyze. /// The filepath of the assembly, to keep as metadata. @@ -117,6 +120,9 @@ static bool ReferencesThisAssembly(AssemblyDefinition ass, HashSet seen } return RefCache[key] = false; } + /// Checks whether the assembly contains loadable plugins. + /// Assembly definition to check. + /// True if the assembly references BepInEx and contains plugin types, otherwise false. protected static bool HasBepinPlugins(AssemblyDefinition ass) { if (!ReferencesThisAssembly(ass)) @@ -129,6 +135,9 @@ protected static bool HasBepinPlugins(AssemblyDefinition ass) return true; } + /// Checks whether the plugin targets an incompatible BepInEx version. + /// Plugin metadata to check. + /// True if the plugin targets a different BepInEx version, otherwise false. protected static bool PluginTargetsWrongBepin(PluginInfo pluginInfo) { var pluginTarget = pluginInfo.TargettedBepInExVersion; @@ -141,31 +150,34 @@ protected static bool PluginTargetsWrongBepin(PluginInfo pluginInfo) #region Contract + /// Title displayed on the BepInEx console window. protected virtual string ConsoleTitle => $"BepInEx {Utility.BepInExVersion} - {Paths.ProcessName}"; private bool _initialized; /// - /// List of all instances loaded via the chainloader. + /// List of all instances loaded via the chainloader. /// public Dictionary Plugins { get; } = new(); /// - /// Collection of error chainloader messages that occured during plugin loading. - /// Contains information about what certain plugins were not loaded. + /// Collection of error chainloader messages that occured during plugin loading. + /// Contains information about what certain plugins were not loaded. /// public List DependencyErrors { get; } = new(); /// - /// Occurs after a plugin is loaded. + /// Occurs after a plugin is loaded. /// public event Action PluginLoaded; /// - /// Occurs after all plugins are loaded. + /// Occurs after all plugins are loaded. /// public event Action Finished; + /// Initializes the chainloader and loads all plugins. + /// Path to the game executable. If null, paths must already be initialized. public virtual void Initialize(string gameExePath = null) { if (_initialized) @@ -190,6 +202,7 @@ public virtual void Initialize(string gameExePath = null) Logger.Log(LogLevel.Message, "Chainloader initialized"); } + /// Initializes the console and disk loggers. protected virtual void InitializeLoggers() { if (ConsoleManager.ConsoleEnabled && !ConsoleManager.ConsoleActive) @@ -550,6 +563,10 @@ private static void TryRunModuleCtor(PluginInfo plugin, Assembly assembly) } } + /// Loads a plugin from the given assembly. + /// Metadata of the plugin to load. + /// Assembly containing the plugin. + /// The loaded plugin instance. public abstract TPlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly); #endregion diff --git a/BepInEx.Core/Bootstrap/TypeLoader.cs b/BepInEx.Core/Bootstrap/TypeLoader.cs index 175ebaba1..7dba2d932 100644 --- a/BepInEx.Core/Bootstrap/TypeLoader.cs +++ b/BepInEx.Core/Bootstrap/TypeLoader.cs @@ -11,64 +11,64 @@ namespace BepInEx.Bootstrap; /// -/// A cacheable metadata item. Can be used with and -/// to cache plugin metadata. +/// A cacheable metadata item. Can be used with and +/// to cache plugin metadata. /// public interface ICacheable { /// - /// Serialize the object into a binary format. + /// Serialize the object into a binary format. /// /// void Save(BinaryWriter bw); /// - /// Loads the object from binary format. + /// Loads the object from binary format. /// /// void Load(BinaryReader br); } /// -/// A cached assembly. +/// A cached assembly. /// /// public class CachedAssembly where T : ICacheable { /// - /// List of cached items inside the assembly. + /// List of cached items inside the assembly. /// public List CacheItems { get; set; } /// - /// Hash of the assembly. Used to verify that the assembly hasn't been changed. + /// Hash of the assembly. Used to verify that the assembly hasn't been changed. /// public string Hash { get; set; } } /// -/// Provides methods for loading specified types from an assembly. +/// Provides methods for loading specified types from an assembly. /// public static class TypeLoader { /// - /// Default assembly resolved used by the + /// Default assembly resolved used by the /// public static readonly DefaultAssemblyResolver CecilResolver; /// - /// Default reader parameters used by + /// Default reader parameters used by /// public static readonly ReaderParameters ReaderParameters; + /// Additional directories searched when resolving assemblies. public static HashSet SearchDirectories = new(); private static readonly Dictionary AssemblyPathByName = new(StringComparer.InvariantCultureIgnoreCase); /// - /// Maps every managed assembly file in a directory to its assembly name, so files whose - /// filename does not match the assembly name (e.g. renamed by the user) still resolve. - /// First file wins when two files share an assembly name. + /// Maps every managed assembly file in a directory to its assembly name, so files whose filename does not match the assembly name (e.g. renamed by the user) still resolve. + /// First file wins when two files share an assembly name. /// public static void RegisterAssemblyPaths(string directory) { @@ -92,6 +92,10 @@ public static void RegisterAssemblyPaths(string directory) } } + /// Tries to get the registered file path of an assembly. + /// Name of the assembly to look up. + /// File path of the assembly, if registered. + /// True if the assembly path was found and exists, otherwise false. public static bool TryGetRegisteredAssemblyPath(string name, out string path) => AssemblyPathByName.TryGetValue(name, out path) && File.Exists(path); @@ -112,6 +116,10 @@ static TypeLoader() CecilResolver.ResolveFailure += CecilResolveOnFailure; } + /// Resolves Cecil assembly references that failed the default resolution. + /// Source of the event. + /// Reference of the assembly that failed to resolve. + /// The resolved assembly definition, or null if it could not be resolved. public static AssemblyDefinition CecilResolveOnFailure(object sender, AssemblyNameReference reference) { if (!Utility.TryParseAssemblyName(reference.FullName, out var name)) @@ -149,12 +157,12 @@ public static AssemblyDefinition CecilResolveOnFailure(object sender, AssemblyNa } /// - /// Event fired when fails to resolve a type during type loading. + /// Event fired when fails to resolve a type during type loading. /// public static event AssemblyResolveEventHandler AssemblyResolve; /// - /// Looks up assemblies in the given directory and locates all types that can be loaded and collects their metadata. + /// Looks up assemblies in the given directory and locates all types that can be loaded and collects their metadata. /// /// The specific base type to search for. /// The directory to search for assemblies. @@ -162,8 +170,7 @@ public static AssemblyDefinition CecilResolveOnFailure(object sender, AssemblyNa /// A filter function to quickly determine if the assembly can be loaded. /// The name of the cache to get cached types from. /// - /// A dictionary of all assemblies in the directory and the list of type metadatas of types that match the - /// selector. + /// A dictionary of all assemblies in the directory and the list of type metadatas of types that match the selector. /// public static Dictionary> FindPluginTypes(string directory, Func typeSelector, @@ -224,13 +231,12 @@ public static Dictionary> FindPluginTypes(string directory, } /// - /// Loads an index of type metadatas from a cache. + /// Loads an index of type metadatas from a cache. /// /// Name of the cache /// Cacheable item /// - /// Cached type metadatas indexed by the path of the assembly that defines the type. If no cache is defined, - /// return null. + /// Cached type metadatas indexed by the path of the assembly that defines the type. If no cache is defined, return null. /// public static Dictionary> LoadAssemblyCache(string cacheName) where T : ICacheable, new() @@ -277,7 +283,7 @@ public static Dictionary> LoadAssemblyCache(string } /// - /// Saves indexed type metadata into a cache. + /// Saves indexed type metadata into a cache. /// /// Name of the cache /// List of plugin metadatas indexed by the path to the assembly that contains the types @@ -319,7 +325,7 @@ public static void SaveAssemblyCache(string cacheName, } /// - /// Converts TypeLoadException to a readable string. + /// Converts TypeLoadException to a readable string. /// /// TypeLoadException /// Readable representation of the exception diff --git a/BepInEx.Core/Configuration/AcceptableValueBase.cs b/BepInEx.Core/Configuration/AcceptableValueBase.cs index e48354a3f..b67a9e679 100644 --- a/BepInEx.Core/Configuration/AcceptableValueBase.cs +++ b/BepInEx.Core/Configuration/AcceptableValueBase.cs @@ -3,7 +3,7 @@ namespace BepInEx.Configuration; /// -/// Base type of all classes representing and enforcing acceptable values of config settings. +/// Base type of all classes representing and enforcing acceptable values of config settings. /// public abstract class AcceptableValueBase { @@ -14,22 +14,22 @@ protected AcceptableValueBase(Type valueType) } /// - /// Type of the supported values. + /// Type of the supported values. /// public Type ValueType { get; } /// - /// Change the value to be acceptable, if it's not already. + /// Change the value to be acceptable, if it's not already. /// public abstract object Clamp(object value); /// - /// Check if the value is an acceptable value. + /// Check if the value is an acceptable value. /// public abstract bool IsValid(object value); /// - /// Get the string for use in config files. + /// Get the string for use in config files. /// public abstract string ToDescriptionString(); } diff --git a/BepInEx.Core/Configuration/AcceptableValueList.cs b/BepInEx.Core/Configuration/AcceptableValueList.cs index 5770a983d..cb737f81a 100644 --- a/BepInEx.Core/Configuration/AcceptableValueList.cs +++ b/BepInEx.Core/Configuration/AcceptableValueList.cs @@ -4,13 +4,13 @@ namespace BepInEx.Configuration; /// -/// Specify the list of acceptable values for a setting. +/// Specify the list of acceptable values for a setting. /// public class AcceptableValueList : AcceptableValueBase where T : IEquatable { /// - /// Specify the list of acceptable values for a setting. - /// If the setting does not equal any of the values, it will be set to the first one. + /// Specify the list of acceptable values for a setting. + /// If the setting does not equal any of the values, it will be set to the first one. /// public AcceptableValueList(params T[] acceptableValues) : base(typeof(T)) { @@ -22,7 +22,7 @@ public AcceptableValueList(params T[] acceptableValues) : base(typeof(T)) } /// - /// List of values that a setting can take. + /// List of values that a setting can take. /// public virtual T[] AcceptableValues { get; } diff --git a/BepInEx.Core/Configuration/AcceptableValueRange.cs b/BepInEx.Core/Configuration/AcceptableValueRange.cs index 2a3ddf46c..e9ba4471e 100644 --- a/BepInEx.Core/Configuration/AcceptableValueRange.cs +++ b/BepInEx.Core/Configuration/AcceptableValueRange.cs @@ -3,7 +3,7 @@ namespace BepInEx.Configuration; /// -/// Specify the range of acceptable values for a setting. +/// Specify the range of acceptable values for a setting. /// public class AcceptableValueRange : AcceptableValueBase where T : IComparable { @@ -23,12 +23,12 @@ public AcceptableValueRange(T minValue, T maxValue) : base(typeof(T)) } /// - /// Lowest acceptable value + /// Lowest acceptable value /// public virtual T MinValue { get; } /// - /// Highest acceptable value + /// Highest acceptable value /// public virtual T MaxValue { get; } diff --git a/BepInEx.Core/Configuration/ConfigDefinition.cs b/BepInEx.Core/Configuration/ConfigDefinition.cs index d963c196c..3166c1bf1 100644 --- a/BepInEx.Core/Configuration/ConfigDefinition.cs +++ b/BepInEx.Core/Configuration/ConfigDefinition.cs @@ -4,9 +4,9 @@ namespace BepInEx.Configuration; /// -/// Section and key of a setting. Used as a unique key for identification within a -/// . -/// The same definition can be used in multiple config files, it will point to different settings then. +/// Section and key of a setting. Used as a unique key for identification within a +/// . +/// The same definition can be used in multiple config files, it will point to different settings then. /// /// public class ConfigDefinition : IEquatable @@ -14,7 +14,7 @@ public class ConfigDefinition : IEquatable private static readonly char[] _invalidConfigChars = { '=', '\n', '\t', '\\', '"', '\'', '[', ']' }; /// - /// Create a new definition. Definitions with same section and key are equal. + /// Create a new definition. Definitions with same section and key are equal. /// /// Group of the setting, case sensitive. /// Name of the setting, case sensitive. @@ -35,17 +35,17 @@ public ConfigDefinition(string section, string key, string description) } /// - /// Group of the setting. All settings within a config file are grouped by this. + /// Group of the setting. All settings within a config file are grouped by this. /// public string Section { get; } /// - /// Name of the setting. + /// Name of the setting. /// public string Key { get; } /// - /// Check if the definitions are the same. + /// Check if the definitions are the same. /// /// public bool Equals(ConfigDefinition other) @@ -68,7 +68,7 @@ private static void CheckInvalidConfigChars(string val, string name) } /// - /// Check if the definitions are the same. + /// Check if the definitions are the same. /// public override bool Equals(object obj) { @@ -92,12 +92,12 @@ public override int GetHashCode() } /// - /// Check if the definitions are the same. + /// Check if the definitions are the same. /// public static bool operator ==(ConfigDefinition left, ConfigDefinition right) => Equals(left, right); /// - /// Check if the definitions are the same. + /// Check if the definitions are the same. /// public static bool operator !=(ConfigDefinition left, ConfigDefinition right) => !Equals(left, right); diff --git a/BepInEx.Core/Configuration/ConfigDescription.cs b/BepInEx.Core/Configuration/ConfigDescription.cs index ce4d9f942..d2945ce85 100644 --- a/BepInEx.Core/Configuration/ConfigDescription.cs +++ b/BepInEx.Core/Configuration/ConfigDescription.cs @@ -3,18 +3,15 @@ namespace BepInEx.Configuration; /// -/// Metadata of a . +/// Metadata of a . /// public class ConfigDescription { /// - /// Create a new description. + /// Create a new description. /// /// Text describing the function of the setting and any notes or warnings. - /// - /// Range of values that this setting can take. The setting's value will be automatically - /// clamped. - /// + /// Range of values that this setting can take. The setting's value will be automatically clamped. /// Objects that can be used by user-made classes to add functionality. public ConfigDescription(string description, AcceptableValueBase acceptableValues = null, params object[] tags) { @@ -24,22 +21,22 @@ public ConfigDescription(string description, AcceptableValueBase acceptableValue } /// - /// Text describing the function of the setting and any notes or warnings. + /// Text describing the function of the setting and any notes or warnings. /// public string Description { get; } /// - /// Range of acceptable values for a setting. + /// Range of acceptable values for a setting. /// public AcceptableValueBase AcceptableValues { get; } /// - /// Objects that can be used by user-made classes to add functionality. + /// Objects that can be used by user-made classes to add functionality. /// public object[] Tags { get; } /// - /// An empty description. + /// An empty description. /// public static ConfigDescription Empty { get; } = new(""); } diff --git a/BepInEx.Core/Configuration/ConfigEntryBase.cs b/BepInEx.Core/Configuration/ConfigEntryBase.cs index a4b44fbd0..d4d043059 100644 --- a/BepInEx.Core/Configuration/ConfigEntryBase.cs +++ b/BepInEx.Core/Configuration/ConfigEntryBase.cs @@ -6,7 +6,7 @@ namespace BepInEx.Configuration; /// -/// Provides access to a single setting inside of a . +/// Provides access to a single setting inside of a . /// /// Type of the setting. public sealed class ConfigEntry : ConfigEntryBase @@ -26,7 +26,7 @@ internal ConfigEntry(ConfigFile configFile, } /// - /// Value of this setting. + /// Value of this setting. /// public T Value { @@ -50,19 +50,19 @@ public override object BoxedValue } /// - /// Fired when the setting is changed. Does not detect changes made outside from this object. + /// Fired when the setting is changed. Does not detect changes made outside from this object. /// public event EventHandler SettingChanged; } /// -/// Container for a single setting of a . -/// Each config entry is linked to one config file. +/// Container for a single setting of a . +/// Each config entry is linked to one config file. /// public abstract class ConfigEntryBase { /// - /// Types of defaultValue and definition.AcceptableValues have to be the same as settingType. + /// Types of defaultValue and definition.AcceptableValues have to be the same as settingType. /// internal protected ConfigEntryBase(ConfigFile configFile, ConfigDefinition definition, @@ -87,43 +87,43 @@ internal protected ConfigEntryBase(ConfigFile configFile, } /// - /// Config file this entry is a part of. + /// Config file this entry is a part of. /// public ConfigFile ConfigFile { get; } /// - /// Category and name of this setting. Used as a unique key for identification within a - /// . + /// Category and name of this setting. Used as a unique key for identification within a + /// . /// public ConfigDefinition Definition { get; } /// - /// Description / metadata of this setting. + /// Description / metadata of this setting. /// public ConfigDescription Description { get; } /// - /// Type of the that this setting holds. + /// Type of the that this setting holds. /// public Type SettingType { get; } /// - /// Default value of this setting (set only if the setting was not changed before). + /// Default value of this setting (set only if the setting was not changed before). /// public object DefaultValue { get; } /// - /// Get or set the value of the setting. + /// Get or set the value of the setting. /// public abstract object BoxedValue { get; set; } /// - /// Get the serialized representation of the value. + /// Get the serialized representation of the value. /// public string GetSerializedValue() => TomlTypeConverter.ConvertToString(BoxedValue, SettingType); /// - /// Set the value by using its serialized form. + /// Set the value by using its serialized form. /// public void SetSerializedValue(string value) { @@ -140,7 +140,7 @@ public void SetSerializedValue(string value) } /// - /// If necessary, clamp the value to acceptable value range. T has to be equal to settingType. + /// If necessary, clamp the value to acceptable value range. T has to be equal to settingType. /// protected T ClampValue(T value) { @@ -150,12 +150,12 @@ protected T ClampValue(T value) } /// - /// Trigger setting changed event. + /// Trigger setting changed event. /// protected void OnSettingChanged(object sender) => ConfigFile.OnSettingChanged(sender, this); /// - /// Write a description of this setting using all available metadata. + /// Write a description of this setting using all available metadata. /// public void WriteDescription(StreamWriter writer) { diff --git a/BepInEx.Core/Configuration/ConfigFile.cs b/BepInEx.Core/Configuration/ConfigFile.cs index dfa756be9..980d37231 100644 --- a/BepInEx.Core/Configuration/ConfigFile.cs +++ b/BepInEx.Core/Configuration/ConfigFile.cs @@ -9,7 +9,7 @@ namespace BepInEx.Configuration; /// -/// A helper class to handle persistent data. All public methods are thread-safe. +/// A helper class to handle persistent data. All public methods are thread-safe. /// public class ConfigFile : IDictionary { @@ -19,7 +19,7 @@ public class ConfigFile : IDictionary public ConfigFile(string configPath, bool saveOnInit) : this(configPath, saveOnInit, null) { } /// - /// Create a new config file at the specified config path. + /// Create a new config file at the specified config path. /// /// Full path to a file that contains settings. The file will be created as needed. /// If the config file/directory doesn't exist, create it immediately. @@ -37,17 +37,18 @@ public ConfigFile(string configPath, bool saveOnInit, BepInPlugin ownerMetadata) else if (saveOnInit) TrySave(); } + /// Config file holding the core BepInEx settings. public static ConfigFile CoreConfig { get; } = new(Paths.BepInExConfigPath, true); /// - /// All config entries inside + /// All config entries inside /// protected Dictionary Entries { get; } = new(); private Dictionary OrphanedEntries { get; } = new(); /// - /// Create a list with all config entries inside of this config file. + /// Create a list with all config entries inside of this config file. /// [Obsolete("Use Keys instead")] public ReadOnlyCollection ConfigDefinitions @@ -62,14 +63,13 @@ public ReadOnlyCollection ConfigDefinitions } /// - /// Full path to the config file. The file might not exist until a setting is added and changed, or - /// is called. + /// Full path to the config file. The file might not exist until a setting is added and changed, or is called. /// public string ConfigFilePath { get; } /// - /// If enabled, writes the config to disk every time a value is set. - /// If disabled, you have to manually use or the changes will be lost! + /// If enabled, writes the config to disk every time a value is set. + /// If disabled, you have to manually use or the changes will be lost! /// public bool SaveOnConfigSet { get; set; } = true; @@ -206,8 +206,8 @@ ConfigEntryBase IDictionary.this[ConfigDefini } /// - /// Returns the ConfigDefinitions that the ConfigFile contains. - /// Creates a new array when the property is accessed. Thread-safe. + /// Returns the ConfigDefinitions that the ConfigFile contains. + /// Creates a new array when the property is accessed. Thread-safe. /// public ICollection Keys { @@ -221,8 +221,8 @@ public ICollection Keys } /// - /// Returns the ConfigEntryBase values that the ConfigFile contains. - /// Creates a new array when the property is accessed. Thread-safe. + /// Returns the ConfigEntryBase values that the ConfigFile contains. + /// Creates a new array when the property is accessed. Thread-safe. /// public ICollection Values { @@ -236,10 +236,10 @@ public ICollection Values } /// - /// Create an array with all config entries inside of this config file. Should be only used for metadata purposes. - /// If you want to access and modify an existing setting then use - /// - /// instead with no description. + /// Create an array with all config entries inside of this config file. Should be only used for metadata purposes. + /// If you want to access and modify an existing setting then use + /// + /// instead with no description. /// [Obsolete("Use Values instead")] public ConfigEntryBase[] GetConfigEntries() @@ -255,12 +255,12 @@ public ConfigEntryBase[] GetConfigEntries() private readonly object _ioLock = new(); /// - /// Generate user-readable comments for each of the settings in the saved .cfg file. + /// Generate user-readable comments for each of the settings in the saved .cfg file. /// public bool GenerateSettingDescriptions { get; set; } = true; /// - /// Reloads the config from disk. Unsaved changes are lost. + /// Reloads the config from disk. Unsaved changes are lost. /// public void Reload() { @@ -305,7 +305,7 @@ public void Reload() } /// - /// Writes the config to disk. + /// Writes the config to disk. /// public void Save() { @@ -356,9 +356,7 @@ public void Save() } /// - /// Writes the config to disk like , but logs and swallows I/O failures (e.g. a read-only - /// or locked config file) instead of throwing. Used only for the creation-time saves (initial file write and - /// new-entry binds), which can run before logging is up; explicit saves and setting changes still throw. + /// Writes the config to disk like , but logs and swallows I/O failures (e.g. a read-only or locked config file) instead of throwing. Used only for the creation-time saves (initial file write and new-entry binds), which can run before logging is up; explicit saves and setting changes still throw. /// private void TrySave() { @@ -378,9 +376,9 @@ private void TrySave() #region Wraps /// - /// Access one of the existing settings. If the setting has not been added yet, null is returned. - /// If the setting exists but has a different type than T, an exception is thrown. - /// New settings should be added with . + /// Access one of the existing settings. If the setting has not been added yet, null is returned. + /// If the setting exists but has a different type than T, an exception is thrown. + /// New settings should be added with . /// /// Type of the value contained in this setting. /// Section and Key of the setting. @@ -391,9 +389,9 @@ public ConfigEntry GetSetting(ConfigDefinition configDefinition) => : null; /// - /// Access one of the existing settings. If the setting has not been added yet, null is returned. - /// If the setting exists but has a different type than T, an exception is thrown. - /// New settings should be added with . + /// Access one of the existing settings. If the setting has not been added yet, null is returned. + /// If the setting exists but has a different type than T, an exception is thrown. + /// New settings should be added with . /// /// Type of the value contained in this setting. /// Section/category/group of the setting. Settings are grouped by this. @@ -405,10 +403,10 @@ public ConfigEntry GetSetting(string section, string key) => : null; /// - /// Access one of the existing settings. If the setting has not been added yet, false is returned. Otherwise, true. - /// If the setting exists but has a different type than T, an exception is thrown. - /// New settings should be added with - /// . + /// Access one of the existing settings. If the setting has not been added yet, false is returned. Otherwise, true. + /// If the setting exists but has a different type than T, an exception is thrown. + /// New settings should be added with + /// . /// /// Type of the value contained in this setting. /// Section and Key of the setting. @@ -429,10 +427,10 @@ public bool TryGetEntry(ConfigDefinition configDefinition, out ConfigEntry } /// - /// Access one of the existing settings. If the setting has not been added yet, null is returned. - /// If the setting exists but has a different type than T, an exception is thrown. - /// New settings should be added with - /// . + /// Access one of the existing settings. If the setting has not been added yet, null is returned. + /// If the setting exists but has a different type than T, an exception is thrown. + /// New settings should be added with + /// . /// /// Type of the value contained in this setting. /// Section/category/group of the setting. Settings are grouped by this. @@ -442,8 +440,8 @@ public bool TryGetEntry(string section, string key, out ConfigEntry entry) TryGetEntry(new ConfigDefinition(section, key), out entry); /// - /// Create a new setting. The setting is saved to drive and loaded automatically. - /// Each definition can be used to add only one setting, trying to add a second setting will throw an exception. + /// Create a new setting. The setting is saved to drive and loaded automatically. + /// Each definition can be used to add only one setting, trying to add a second setting will throw an exception. /// /// Type of the value contained in this setting. /// Section and Key of the setting. @@ -480,9 +478,8 @@ public ConfigEntry Bind(ConfigDefinition configDefinition, } /// - /// Create a new setting. The setting is saved to drive and loaded automatically. - /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an - /// exception. + /// Create a new setting. The setting is saved to drive and loaded automatically. + /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an exception. /// /// Type of the value contained in this setting. /// Section/category/group of the setting. Settings are grouped by this. @@ -496,9 +493,8 @@ public ConfigEntry Bind(string section, Bind(new ConfigDefinition(section, key), defaultValue, configDescription); /// - /// Create a new setting. The setting is saved to drive and loaded automatically. - /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an - /// exception. + /// Create a new setting. The setting is saved to drive and loaded automatically. + /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an exception. /// /// Type of the value contained in this setting. /// Section/category/group of the setting. Settings are grouped by this. @@ -509,8 +505,8 @@ public ConfigEntry Bind(string section, string key, T defaultValue, string Bind(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description)); /// - /// Create a new setting. The setting is saved to drive and loaded automatically. - /// Each definition can be used to add only one setting, trying to add a second setting will throw an exception. + /// Create a new setting. The setting is saved to drive and loaded automatically. + /// Each definition can be used to add only one setting, trying to add a second setting will throw an exception. /// /// Type of the value contained in this setting. /// Section and Key of the setting. @@ -523,9 +519,8 @@ public ConfigEntry AddSetting(ConfigDefinition configDefinition, Bind(configDefinition, defaultValue, configDescription); /// - /// Create a new setting. The setting is saved to drive and loaded automatically. - /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an - /// exception. + /// Create a new setting. The setting is saved to drive and loaded automatically. + /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an exception. /// /// Type of the value contained in this setting. /// Section/category/group of the setting. Settings are grouped by this. @@ -540,9 +535,8 @@ public ConfigEntry AddSetting(string section, Bind(new ConfigDefinition(section, key), defaultValue, configDescription); /// - /// Create a new setting. The setting is saved to drive and loaded automatically. - /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an - /// exception. + /// Create a new setting. The setting is saved to drive and loaded automatically. + /// Each section and key pair can be used to add only one setting, trying to add a second setting will throw an exception. /// /// Type of the value contained in this setting. /// Section/category/group of the setting. Settings are grouped by this. @@ -554,7 +548,7 @@ public ConfigEntry AddSetting(string section, string key, T defaultValue, Bind(new ConfigDefinition(section, key), defaultValue, new ConfigDescription(description)); /// - /// Access a setting. Use Bind instead. + /// Access a setting. Use Bind instead. /// [Obsolete("Use Bind instead")] public ConfigWrapper Wrap(string section, string key, string description = null, T defaultValue = default) @@ -569,7 +563,7 @@ public ConfigWrapper Wrap(string section, string key, string description = } /// - /// Access a setting. Use Bind instead. + /// Access a setting. Use Bind instead. /// [Obsolete("Use Bind instead")] public ConfigWrapper Wrap(ConfigDefinition configDefinition, T defaultValue = default) => @@ -580,12 +574,12 @@ public ConfigWrapper Wrap(ConfigDefinition configDefinition, T defaultValu #region Events /// - /// An event that is fired every time the config is reloaded. + /// An event that is fired every time the config is reloaded. /// public event EventHandler ConfigReloaded; /// - /// Fired when one of the settings is changed. + /// Fired when one of the settings is changed. /// public event EventHandler SettingChanged; diff --git a/BepInEx.Core/Configuration/ConfigWrapper.cs b/BepInEx.Core/Configuration/ConfigWrapper.cs index 6ba016693..f7751fd3a 100644 --- a/BepInEx.Core/Configuration/ConfigWrapper.cs +++ b/BepInEx.Core/Configuration/ConfigWrapper.cs @@ -3,7 +3,7 @@ namespace BepInEx.Configuration; /// -/// Provides access to a single setting inside of a . +/// Provides access to a single setting inside of a . /// /// Type of the setting. [Obsolete("Use ConfigFile from new Bind overloads instead")] @@ -20,22 +20,22 @@ internal ConfigWrapper(ConfigEntry configEntry) } /// - /// Entry of this setting in the . + /// Entry of this setting in the . /// public ConfigEntry ConfigEntry { get; } /// - /// Unique definition of this setting. + /// Unique definition of this setting. /// public ConfigDefinition Definition => ConfigEntry.Definition; /// - /// Config file this setting is inside of. + /// Config file this setting is inside of. /// public ConfigFile ConfigFile => ConfigEntry.ConfigFile; /// - /// Value of this setting. + /// Value of this setting. /// public T Value { @@ -44,7 +44,7 @@ public T Value } /// - /// Fired when the setting is changed. Does not detect changes made outside from this object. + /// Fired when the setting is changed. Does not detect changes made outside from this object. /// public event EventHandler SettingChanged; } diff --git a/BepInEx.Core/Configuration/SettingChangedEventArgs.cs b/BepInEx.Core/Configuration/SettingChangedEventArgs.cs index 7e167eca8..ccb29e746 100644 --- a/BepInEx.Core/Configuration/SettingChangedEventArgs.cs +++ b/BepInEx.Core/Configuration/SettingChangedEventArgs.cs @@ -3,7 +3,7 @@ namespace BepInEx.Configuration; /// -/// Arguments for events concerning a change of a setting. +/// Arguments for events concerning a change of a setting. /// /// public sealed class SettingChangedEventArgs : EventArgs @@ -15,7 +15,7 @@ public SettingChangedEventArgs(ConfigEntryBase changedSetting) } /// - /// Setting that was changed + /// Setting that was changed /// public ConfigEntryBase ChangedSetting { get; } } diff --git a/BepInEx.Core/Configuration/TomlTypeConverter.cs b/BepInEx.Core/Configuration/TomlTypeConverter.cs index a1b2348d8..43af873f1 100644 --- a/BepInEx.Core/Configuration/TomlTypeConverter.cs +++ b/BepInEx.Core/Configuration/TomlTypeConverter.cs @@ -8,7 +8,7 @@ namespace BepInEx.Configuration; /// -/// Serializer/deserializer used by the config system. +/// Serializer/deserializer used by the config system. /// public static class TomlTypeConverter { @@ -103,7 +103,7 @@ public static class TomlTypeConverter }; /// - /// Convert object of a given type to a string using available converters. + /// Convert object of a given type to a string using available converters. /// public static string ConvertToString(object value, Type valueType) { @@ -115,12 +115,12 @@ public static string ConvertToString(object value, Type valueType) } /// - /// Convert string to an object of a given type using available converters. + /// Convert string to an object of a given type using available converters. /// public static T ConvertToValue(string value) => (T) ConvertToValue(value, typeof(T)); /// - /// Convert string to an object of a given type using available converters. + /// Convert string to an object of a given type using available converters. /// public static object ConvertToValue(string value, Type valueType) { @@ -132,7 +132,7 @@ public static object ConvertToValue(string value, Type valueType) } /// - /// Get a converter for a given type if there is any. + /// Get a converter for a given type if there is any. /// public static TypeConverter GetConverter(Type valueType) { @@ -148,8 +148,8 @@ public static TypeConverter GetConverter(Type valueType) } /// - /// Add a new type converter for a given type. - /// If a different converter is already added, this call is ignored and false is returned. + /// Add a new type converter for a given type. + /// If a different converter is already added, this call is ignored and false is returned. /// public static bool AddConverter(Type type, TypeConverter converter) { @@ -167,12 +167,12 @@ public static bool AddConverter(Type type, TypeConverter converter) } /// - /// Check if a given type can be converted to and from string. + /// Check if a given type can be converted to and from string. /// public static bool CanConvert(Type type) => GetConverter(type) != null; /// - /// Give a list of types with registered converters. + /// Give a list of types with registered converters. /// public static IEnumerable GetSupportedTypes() => TypeConverters.Keys; diff --git a/BepInEx.Core/Configuration/TypeConverter.cs b/BepInEx.Core/Configuration/TypeConverter.cs index 71a92c84a..e6b12475e 100644 --- a/BepInEx.Core/Configuration/TypeConverter.cs +++ b/BepInEx.Core/Configuration/TypeConverter.cs @@ -3,19 +3,19 @@ namespace BepInEx.Configuration; /// -/// A serializer/deserializer combo for some type(s). Used by the config system. +/// A serializer/deserializer combo for some type(s). Used by the config system. /// public class TypeConverter { /// - /// Used to serialize the type into a (hopefully) human-readable string. - /// Object is the instance to serialize, Type is the object's type. + /// Used to serialize the type into a (hopefully) human-readable string. + /// Object is the instance to serialize, Type is the object's type. /// public Func ConvertToString { get; set; } /// - /// Used to deserialize the type from a string. - /// String is the data to deserialize, Type is the object's type, should return instance to an object of Type. + /// Used to deserialize the type from a string. + /// String is the data to deserialize, Type is the object's type, should return instance to an object of Type. /// public Func ConvertToObject { get; set; } } diff --git a/BepInEx.Core/Console/ConsoleManager.cs b/BepInEx.Core/Console/ConsoleManager.cs index be95cd026..7cad47980 100644 --- a/BepInEx.Core/Console/ConsoleManager.cs +++ b/BepInEx.Core/Console/ConsoleManager.cs @@ -8,16 +8,21 @@ namespace BepInEx; +/// Manages the external console used for log output. public static class ConsoleManager { + /// Hints how console output should be redirected. public enum ConsoleOutRedirectType { + /// Lets BepInEx decide how to redirect console output. [Description("Auto")] Auto = 0, + /// Prefers redirecting to console output; if possible, closes original standard output. [Description("Console Out")] ConsoleOut, + /// Prefers redirecting to standard output; if possible, closes console out. [Description("Standard Out")] StandardOut } @@ -26,21 +31,25 @@ public enum ConsoleOutRedirectType private const string ENABLE_CONSOLE_ARG = "--enable-console"; + /// Whether to show a console for log output. public static readonly ConfigEntry ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind( "Logging.Console", "Enabled", false, "Enables showing a console for log output."); + /// Whether closing the console is prevented in a platform-specific way. public static readonly ConfigEntry ConfigPreventClose = ConfigFile.CoreConfig.Bind( "Logging.Console", "PreventClose", false, "If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way)."); + /// Whether the console uses the Shift-JIS encoding instead of UTF-8. public static readonly ConfigEntry ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind( "Logging.Console", "ShiftJisEncoding", false, "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding."); + /// Hints what handle to assign as standard output. public static readonly ConfigEntry ConfigConsoleOutRedirectType = ConfigFile.CoreConfig.Bind( "Logging.Console", "StandardOutType", @@ -74,26 +83,30 @@ static ConsoleManager() } } + /// True if the console is enabled via config or the --enable-console argument. public static bool ConsoleEnabled => EnableConsoleArgOverride ?? ConfigConsoleEnabled.Value; internal static IConsoleDriver Driver { get; set; } /// - /// True if an external console has been started, false otherwise. + /// True if an external console has been started, false otherwise. /// public static bool ConsoleActive => Driver?.ConsoleActive ?? false; /// - /// The stream that writes to the standard out stream of the process. Should never be null. + /// The stream that writes to the standard out stream of the process. Should never be null. /// public static TextWriter StandardOutStream => Driver?.StandardOut; /// - /// The stream that writes to an external console. Null if no such console exists + /// The stream that writes to an external console. Null if no such console exists /// public static TextWriter ConsoleStream => Driver?.ConsoleOut; + /// Initializes the console driver for the current platform. + /// Whether a console is already active. + /// Whether to use the managed console encoder. public static void Initialize(bool alreadyActive, bool useManagedEncoder) { if (PlatformUtils.Is(Platform.Unix)) @@ -113,6 +126,7 @@ private static void DriverCheck() throw new InvalidOperationException("Driver has not been initialized"); } + /// Creates and attaches an external console. public static void CreateConsole() { if (ConsoleActive) @@ -131,6 +145,7 @@ public static void CreateConsole() Driver.PreventClose(); } + /// Detaches the external console. public static void DetachConsole() { if (!ConsoleActive) @@ -141,12 +156,16 @@ public static void DetachConsole() Driver.DetachConsole(); } + /// Sets the title of the external console. + /// Title to display. public static void SetConsoleTitle(string title) { DriverCheck(); Driver.SetConsoleTitle(title); } + /// Sets the icon of the external console. + /// Stream containing the icon. public static void SetConsoleIcon(Stream iconStream) { DriverCheck(); @@ -154,6 +173,8 @@ public static void SetConsoleIcon(Stream iconStream) Driver.SetConsoleIcon(iconStream); } + /// Sets the foreground color of the external console. + /// Color to set. public static void SetConsoleColor(ConsoleColor color) { DriverCheck(); diff --git a/BepInEx.Core/Console/SafeConsole.cs b/BepInEx.Core/Console/SafeConsole.cs index 9f50b5b0a..06a538430 100644 --- a/BepInEx.Core/Console/SafeConsole.cs +++ b/BepInEx.Core/Console/SafeConsole.cs @@ -9,7 +9,7 @@ namespace UnityInjector.ConsoleUtil; /// -/// Console class with safe handlers for Unity 4.x, which does not have a proper Console implementation +/// Console class with safe handlers for Unity 4.x, which does not have a proper Console implementation /// internal static class SafeConsole { diff --git a/BepInEx.Core/Contract/Attributes.cs b/BepInEx.Core/Contract/Attributes.cs index 647e87e42..f6fb75e6d 100644 --- a/BepInEx.Core/Contract/Attributes.cs +++ b/BepInEx.Core/Contract/Attributes.cs @@ -13,7 +13,7 @@ namespace BepInEx; #region BaseUnityPlugin /// -/// This attribute denotes that a class is a plugin, and specifies the required metadata. +/// This attribute denotes that a class is a plugin, and specifies the required metadata. /// [AttributeUsage(AttributeTargets.Class)] public class BepInPlugin : Attribute @@ -29,19 +29,19 @@ public BepInPlugin(string GUID, string Name, string Version) } /// - /// The unique identifier of the plugin. Should not change between plugin versions. + /// The unique identifier of the plugin. Should not change between plugin versions. /// public string GUID { get; protected set; } /// - /// The user friendly name of the plugin. Is able to be changed between versions. + /// The user friendly name of the plugin. Is able to be changed between versions. /// public string Name { get; protected set; } /// - /// The specific version of the plugin. + /// The specific version of the plugin. /// public Version Version { get; protected set; } @@ -77,32 +77,31 @@ internal static BepInPlugin FromCecilType(TypeDefinition td) } /// -/// This attribute specifies any dependencies that this plugin has on other plugins. +/// This attribute specifies any dependencies that this plugin has on other plugins. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class BepInDependency : Attribute, ICacheable { /// - /// Flags that are applied to a dependency + /// Flags that are applied to a dependency /// [Flags] public enum DependencyFlags { /// - /// The plugin has a hard dependency on the referenced plugin, and will not run without it. + /// The plugin has a hard dependency on the referenced plugin, and will not run without it. /// HardDependency = 1, /// - /// This plugin has a soft dependency on the referenced plugin, and is able to run without it. + /// This plugin has a soft dependency on the referenced plugin, and is able to run without it. /// SoftDependency = 2 } /// - /// Marks this as dependent on another plugin. The other plugin will be loaded before - /// this one. - /// If the other plugin doesn't exist, what happens depends on the parameter. + /// Marks this plugin as dependent on another plugin. The other plugin will be loaded before this one. + /// If the other plugin doesn't exist, what happens depends on the parameter. /// /// The GUID of the referenced plugin. /// The flags associated with this dependency definition. @@ -114,23 +113,19 @@ public BepInDependency(string DependencyGUID, DependencyFlags Flags = Dependency } /// - /// Marks this as dependent on another plugin. The other plugin will be loaded before - /// this one. - /// If the other plugin doesn't exist or is of a version not satisfying , this plugin will - /// not load and an error will be logged instead. + /// Marks this plugin as dependent on another plugin. The other plugin will be loaded before this one. + /// If the other plugin doesn't exist or is of a version not satisfying , this plugin will not load and an error will be logged instead. /// /// The GUID of the referenced plugin. /// - /// The version requirement of the referenced plugin, parsed as a SemVer range - /// (see ). A plain version such as - /// 1.2.0 requires that exact version; use a range such as >=1.2.0, 1.2.*, - /// ~1.2.0 or ^1.2.0 to accept more than one version. + /// The version requirement of the referenced plugin, parsed as a SemVer range (see ). A plain version such as + /// 1.2.0 requires that exact version; use a range such as >=1.2.0, 1.2.*, + /// ~1.2.0 or ^1.2.0 to accept more than one version. /// /// - /// When a version is supplied the dependency is always treated as a hard dependency. - /// Plugins migrating from BepInEx 5 should note a behaviour change: a bare version was previously - /// treated as a minimum (>=), whereas in BepInEx 6 it is an exact match. Use - /// >=1.2.0 to keep the old behaviour. + /// When a version is supplied the dependency is always treated as a hard dependency. + /// Plugins migrating from BepInEx 5 should note a behaviour change: a bare version was previously treated as a minimum (>=), whereas in BepInEx 6 it is an exact match. Use + /// >=1.2.0 to keep the old behaviour. /// public BepInDependency(string guid, string version) : this(guid) { @@ -138,17 +133,17 @@ public BepInDependency(string guid, string version) : this(guid) } /// - /// The GUID of the referenced plugin. + /// The GUID of the referenced plugin. /// public string DependencyGUID { get; protected set; } /// - /// The flags associated with this dependency definition. + /// The flags associated with this dependency definition. /// public DependencyFlags Flags { get; protected set; } /// - /// The version range of the referenced plugin. + /// The version range of the referenced plugin. /// public Range VersionRange { get; protected set; } @@ -182,14 +177,14 @@ internal static IEnumerable FromCecilType(TypeDefinition td) } /// -/// This attribute specifies other plugins that are incompatible with this plugin. +/// This attribute specifies other plugins that are incompatible with this plugin. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class BepInIncompatibility : Attribute, ICacheable { /// - /// Marks this as incompatible with another plugin. - /// If the other plugin exists, this plugin will not be loaded and a warning will be shown. + /// Marks this plugin as incompatible with another plugin. + /// If the other plugin exists, this plugin will not be loaded and a warning will be shown. /// /// The GUID of the referenced plugin. public BepInIncompatibility(string IncompatibilityGUID) @@ -198,7 +193,7 @@ public BepInIncompatibility(string IncompatibilityGUID) } /// - /// The GUID of the referenced plugin. + /// The GUID of the referenced plugin. /// public string IncompatibilityGUID { get; protected set; } @@ -218,8 +213,7 @@ internal static IEnumerable FromCecilType(TypeDefinition t } /// -/// This attribute specifies which processes this plugin should be run for. Not specifying this attribute will load the -/// plugin under every process. +/// This attribute specifies which processes this plugin should be run for. Not specifying this attribute will load the plugin under every process. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class BepInProcess : Attribute @@ -231,7 +225,7 @@ public BepInProcess(string ProcessName) } /// - /// The name of the process that this plugin will run under. + /// The name of the process that this plugin will run under. /// public string ProcessName { get; protected set; } @@ -248,7 +242,7 @@ internal static List FromCecilType(TypeDefinition td) #region MetadataHelper /// -/// Helper class to use for retrieving metadata about a plugin, defined as attributes. +/// Helper class to use for retrieving metadata about a plugin, defined as attributes. /// public static class MetadataHelper { @@ -301,7 +295,7 @@ internal static IEnumerable GetCustomAttributes(TypeDefiniti } /// - /// Retrieves the BepInPlugin metadata from a plugin type. + /// Retrieves the BepInPlugin metadata from a plugin type. /// /// The plugin type. /// The BepInPlugin metadata of the plugin type. @@ -316,14 +310,14 @@ public static BepInPlugin GetMetadata(Type pluginType) } /// - /// Retrieves the BepInPlugin metadata from a plugin instance. + /// Retrieves the BepInPlugin metadata from a plugin instance. /// /// The plugin instance. /// The BepInPlugin metadata of the plugin instance. public static BepInPlugin GetMetadata(object plugin) => GetMetadata(plugin.GetType()); /// - /// Gets the specified attributes of a type, if they exist. + /// Gets the specified attributes of a type, if they exist. /// /// The attribute type to retrieve. /// The plugin type. @@ -332,7 +326,7 @@ public static T[] GetAttributes(Type pluginType) where T : Attribute => (T[]) pluginType.GetCustomAttributes(typeof(T), true); /// - /// Gets the specified attributes of an assembly, if they exist. + /// Gets the specified attributes of an assembly, if they exist. /// /// The assembly. /// The attribute type to retrieve. @@ -341,7 +335,7 @@ public static T[] GetAttributes(Assembly assembly) where T : Attribute => (T[]) assembly.GetCustomAttributes(typeof(T), true); /// - /// Gets the specified attributes of an instance, if they exist. + /// Gets the specified attributes of an instance, if they exist. /// /// The attribute type to retrieve. /// The plugin instance. @@ -350,7 +344,7 @@ public static IEnumerable GetAttributes(object plugin) where T : Attribute GetAttributes(plugin.GetType()); /// - /// Gets the specified attributes of a reflection metadata type, if they exist. + /// Gets the specified attributes of a reflection metadata type, if they exist. /// /// The attribute type to retrieve. /// The reflection metadata instance. @@ -359,7 +353,7 @@ public static T[] GetAttributes(MemberInfo member) where T : Attribute => (T[]) member.GetCustomAttributes(typeof(T), true); /// - /// Retrieves the dependencies of the specified plugin type. + /// Retrieves the dependencies of the specified plugin type. /// /// The plugin type. /// A list of all plugin types that the specified plugin type depends upon. diff --git a/BepInEx.Core/Contract/IPlugin.cs b/BepInEx.Core/Contract/IPlugin.cs index 6043fb024..b4097f473 100644 --- a/BepInEx.Core/Contract/IPlugin.cs +++ b/BepInEx.Core/Contract/IPlugin.cs @@ -7,6 +7,7 @@ namespace BepInEx.Contract { + /// Contract that every plugin must implement. public interface IPlugin { /// @@ -20,8 +21,7 @@ public interface IPlugin ManualLogSource Logger { get; } /// - /// Default config file tied to this plugin. The config file will not be created until - /// any settings are added and changed, or is called. + /// Default config file tied to this plugin. The config file will not be created until any settings are added and changed, or is called. /// ConfigFile Config { get; } } diff --git a/BepInEx.Core/Contract/PluginInfo.cs b/BepInEx.Core/Contract/PluginInfo.cs index 0aa7585cc..9fd4f63e9 100644 --- a/BepInEx.Core/Contract/PluginInfo.cs +++ b/BepInEx.Core/Contract/PluginInfo.cs @@ -7,42 +7,42 @@ namespace BepInEx; /// -/// Data class that represents information about a loadable BepInEx plugin. -/// Contains all metadata and additional info required for plugin loading by . + /// Data class that represents information about a loadable BepInEx plugin. + /// Contains all metadata and additional info required for plugin loading by the chainloader. /// public class PluginInfo : ICacheable { /// - /// General metadata about a plugin. + /// General metadata about a plugin. /// public BepInPlugin Metadata { get; internal set; } /// - /// Collection of attributes that describe what processes the plugin can run on. + /// Collection of attributes that describe what processes the plugin can run on. /// public IEnumerable Processes { get; internal set; } /// - /// Collection of attributes that describe what plugins this plugin depends on. + /// Collection of attributes that describe what plugins this plugin depends on. /// public IEnumerable Dependencies { get; internal set; } /// - /// Collection of attributes that describe what plugins this plugin - /// is incompatible with. + /// Collection of attributes that describe what plugins this plugin is incompatible with. /// public IEnumerable Incompatibilities { get; internal set; } /// - /// File path to the plugin DLL + /// File path to the plugin DLL /// public string Location { get; internal set; } /// - /// Instance of the plugin that represents this info. NULL if no plugin is instantiated from info (yet) + /// Instance of the plugin that represents this info. NULL if no plugin is instantiated from info (yet) /// public object Instance { get; internal set; } + /// Full name of the plugin type. public string TypeName { get; internal set; } internal Version TargettedBepInExVersion { get; set; } diff --git a/BepInEx.Core/Logging/BepInExLogInterpolatedStringHandler.cs b/BepInEx.Core/Logging/BepInExLogInterpolatedStringHandler.cs index 9486a3246..ebcce2f4e 100644 --- a/BepInEx.Core/Logging/BepInExLogInterpolatedStringHandler.cs +++ b/BepInEx.Core/Logging/BepInExLogInterpolatedStringHandler.cs @@ -6,13 +6,11 @@ namespace BepInEx.Core.Logging.Interpolation; /// -/// Interpolated string handler for BepInEx . This allows to conditionally skip logging certain -/// messages and speed up logging in certain places. +/// Interpolated string handler for BepInEx . This allows to conditionally skip logging certain messages and speed up logging in certain places. /// /// -/// The class isn't meant to be constructed manually. -/// Instead, use with -/// string interpolation. +/// The class isn't meant to be constructed manually. +/// Instead, use with string interpolation. /// [InterpolatedStringHandler] public class BepInExLogInterpolatedStringHandler @@ -24,7 +22,7 @@ public class BepInExLogInterpolatedStringHandler private readonly StringBuilder sb; /// - /// Constructs a log handler. + /// Constructs a log handler. /// /// Length of the literal string. /// Number for formatted items. @@ -41,12 +39,12 @@ public BepInExLogInterpolatedStringHandler(int literalLength, } /// - /// Whether the interpolation is enabled and string will be logged. + /// Whether the interpolation is enabled and string will be logged. /// public bool Enabled { get; } /// - /// Appends a literal string to the interpolation. + /// Appends a literal string to the interpolation. /// /// String to append. public void AppendLiteral(string s) @@ -57,7 +55,7 @@ public void AppendLiteral(string s) } /// - /// Appends a value to the interpolation. + /// Appends a value to the interpolation. /// /// Value to append. /// Type of the value to append. @@ -70,7 +68,7 @@ public void AppendFormatted(T t) } /// - /// Append a formattable item. + /// Append a formattable item. /// /// Item to append. /// Format to append with. @@ -84,7 +82,7 @@ public void AppendFormatted(T t, string format) where T : IFormattable } /// - /// Append an IntPtr. + /// Append an IntPtr. /// /// Item to append. /// Format to append with. diff --git a/BepInEx.Core/Logging/ConsoleLogListener.cs b/BepInEx.Core/Logging/ConsoleLogListener.cs index e084dd9fd..9b81a1c62 100644 --- a/BepInEx.Core/Logging/ConsoleLogListener.cs +++ b/BepInEx.Core/Logging/ConsoleLogListener.cs @@ -4,10 +4,11 @@ namespace BepInEx.Logging; /// -/// Logs entries using a console spawned by BepInEx. +/// Logs entries using a console spawned by BepInEx. /// public class ConsoleLogListener : ILogListener { + /// Log levels displayed in the console output. protected static readonly ConfigEntry ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind( "Logging.Console", "LogLevels", LogLevel.Fatal | LogLevel.Error | LogLevel.Warning | LogLevel.Message | LogLevel.Info, diff --git a/BepInEx.Core/Logging/DiskLogListener.cs b/BepInEx.Core/Logging/DiskLogListener.cs index 5e2bb4695..6c8332d3c 100644 --- a/BepInEx.Core/Logging/DiskLogListener.cs +++ b/BepInEx.Core/Logging/DiskLogListener.cs @@ -6,21 +6,21 @@ namespace BepInEx.Logging; /// -/// Logs entries using Unity specific outputs. +/// Logs entries using Unity specific outputs. /// public class DiskLogListener : ILogListener { + /// Names of log sources excluded from the disk log. public static HashSet BlacklistedSources = new(); /// - /// Creates a new disk log listener. + /// Creates a new disk log listener. /// /// Path to the log. /// Log levels to display. /// Whether to append logs to an already existing log file. /// - /// Whether to delay flushing to disk to improve performance. Useful to set this to false - /// when debugging crashes. + /// Whether to delay flushing to disk to improve performance. Useful to set this to false when debugging crashes. /// /// Maximum amount of concurrently opened log files. Can help with infinite game boot loops. public DiskLogListener(string localPath, @@ -59,17 +59,17 @@ public DiskLogListener(string localPath, } /// - /// Log levels to display. + /// Log levels to display. /// public LogLevel DisplayedLogLevel { get; } /// - /// Writer for the disk log. + /// Writer for the disk log. /// public TextWriter LogWriter { get; protected set; } /// - /// Timer for flushing the logs to a file. + /// Timer for flushing the logs to a file. /// private Timer FlushTimer { get; } @@ -106,6 +106,7 @@ public void Dispose() catch (ObjectDisposedException) { } } + /// Finalizer that releases the resources held by the listener. ~DiskLogListener() { Dispose(); diff --git a/BepInEx.Core/Logging/HarmonyLogSource.cs b/BepInEx.Core/Logging/HarmonyLogSource.cs index f3a428e68..32af0f887 100644 --- a/BepInEx.Core/Logging/HarmonyLogSource.cs +++ b/BepInEx.Core/Logging/HarmonyLogSource.cs @@ -5,6 +5,7 @@ namespace BepInEx.Logging; +/// Log source that forwards HarmonyX messages to the BepInEx log. public class HarmonyLogSource : ILogSource { private static readonly ConfigEntry LogChannels = ConfigFile.CoreConfig.Bind( @@ -21,15 +22,19 @@ public class HarmonyLogSource : ILogSource [HarmonyLogger.LogChannel.IL] = LogLevel.Debug }; + /// Creates a new Harmony log source and subscribes to HarmonyX log messages. public HarmonyLogSource() { HarmonyLogger.ChannelFilter = LogChannels.Value; HarmonyLogger.MessageReceived += HandleHarmonyMessage; } + /// public void Dispose() => HarmonyLogger.MessageReceived -= HandleHarmonyMessage; + /// Name of the log source. public string SourceName { get; } = "HarmonyX"; + /// Occurs when HarmonyX produces a log message. public event EventHandler LogEvent; private void HandleHarmonyMessage(object sender, HarmonyLogger.LogEventArgs e) diff --git a/BepInEx.Core/Logging/ILogListener.cs b/BepInEx.Core/Logging/ILogListener.cs index c6d8a450a..5dbca6c38 100644 --- a/BepInEx.Core/Logging/ILogListener.cs +++ b/BepInEx.Core/Logging/ILogListener.cs @@ -3,24 +3,23 @@ namespace BepInEx.Logging; /// -/// A generic log listener that receives log events and can route them to some output (e.g. file, console, socket). +/// A generic log listener that receives log events and can route them to some output (e.g. file, console, socket). /// public interface ILogListener : IDisposable { /// - /// What log levels the listener preliminarily wants. + /// What log levels the listener preliminarily wants. /// /// - /// The filter is used to more efficiently discard log messages that aren't being listened to. - /// As such, the filter should represent the log levels that the listener will always want to process. - /// It is up to the the implementation of whether the messages are going to be processed or - /// discarded. + /// The filter is used to more efficiently discard log messages that aren't being listened to. + /// As such, the filter should represent the log levels that the listener will always want to process. + /// It is up to the the implementation of whether the messages are going to be processed or discarded. /// /// TODO: Right now the filter cannot be updated after the log listener has been attached to the logger. LogLevel LogLevelFilter { get; } /// - /// Handle an incoming log event. + /// Handle an incoming log event. /// /// Log source that sent the event. Don't use; instead use /// Information about the log message. diff --git a/BepInEx.Core/Logging/ILogSource.cs b/BepInEx.Core/Logging/ILogSource.cs index b07cbee3e..ee9dc65b1 100644 --- a/BepInEx.Core/Logging/ILogSource.cs +++ b/BepInEx.Core/Logging/ILogSource.cs @@ -3,17 +3,17 @@ namespace BepInEx.Logging; /// -/// Log source that can output log messages. +/// Log source that can output log messages. /// public interface ILogSource : IDisposable { /// - /// Name of the log source. + /// Name of the log source. /// string SourceName { get; } /// - /// Event that sends the log message. Call to send a log message. + /// Event that sends the log message. Call to send a log message. /// event EventHandler LogEvent; } diff --git a/BepInEx.Core/Logging/LogEventArgs.cs b/BepInEx.Core/Logging/LogEventArgs.cs index 26760eb03..df8df5a5c 100644 --- a/BepInEx.Core/Logging/LogEventArgs.cs +++ b/BepInEx.Core/Logging/LogEventArgs.cs @@ -3,12 +3,12 @@ namespace BepInEx.Logging; /// -/// Log event arguments. Contains info about the log message. +/// Log event arguments. Contains info about the log message. /// public class LogEventArgs : EventArgs { /// - /// Creates the log event args- + /// Creates the log event args- /// /// Logged data. /// Log level of the data. @@ -21,17 +21,17 @@ public LogEventArgs(object data, LogLevel level, ILogSource source) } /// - /// Logged data. + /// Logged data. /// public object Data { get; } /// - /// Log levels for the data. + /// Log levels for the data. /// public LogLevel Level { get; } /// - /// Log source that emitted the log event. + /// Log source that emitted the log event. /// public ILogSource Source { get; } @@ -39,7 +39,7 @@ public LogEventArgs(object data, LogLevel level, ILogSource source) public override string ToString() => $"[{Level,-7}:{Source.SourceName,10}] {Data}"; /// - /// Like but appends newline at the end. + /// Like but appends newline at the end. /// /// Same output as but with new line. public string ToStringLine() => $"[{Level,-7}:{Source.SourceName,10}] {Data}{Environment.NewLine}"; diff --git a/BepInEx.Core/Logging/LogLevel.cs b/BepInEx.Core/Logging/LogLevel.cs index bfd3ee553..d77865218 100644 --- a/BepInEx.Core/Logging/LogLevel.cs +++ b/BepInEx.Core/Logging/LogLevel.cs @@ -3,59 +3,59 @@ namespace BepInEx.Logging; /// -/// The level, or severity of a log entry. +/// The level, or severity of a log entry. /// [Flags] public enum LogLevel { /// - /// No level selected. + /// No level selected. /// None = 0, /// - /// A fatal error has occurred, which cannot be recovered from. + /// A fatal error has occurred, which cannot be recovered from. /// Fatal = 1, /// - /// An error has occured, but can be recovered from. + /// An error has occured, but can be recovered from. /// Error = 2, /// - /// A warning has been produced, but does not necessarily mean that something wrong has happened. + /// A warning has been produced, but does not necessarily mean that something wrong has happened. /// Warning = 4, /// - /// An important message that should be displayed to the user. + /// An important message that should be displayed to the user. /// Message = 8, /// - /// A message of low importance. + /// A message of low importance. /// Info = 16, /// - /// A message that would likely only interest a developer. + /// A message that would likely only interest a developer. /// Debug = 32, /// - /// All log levels. + /// All log levels. /// All = Fatal | Error | Warning | Message | Info | Debug } /// -/// Helper methods for log level handling. +/// Helper methods for log level handling. /// public static class LogLevelExtensions { /// - /// Gets the highest log level when there could potentially be multiple levels provided. + /// Gets the highest log level when there could potentially be multiple levels provided. /// /// The log level(s). /// The highest log level supplied. @@ -72,7 +72,7 @@ public static LogLevel GetHighestLevel(this LogLevel levels) } /// - /// Returns a translation of a log level to it's associated console colour. + /// Returns a translation of a log level to it's associated console colour. /// /// The log level(s). /// A console color associated with the highest log level supplied. diff --git a/BepInEx.Core/Logging/Logger.cs b/BepInEx.Core/Logging/Logger.cs index 65900598d..dcbc829d5 100644 --- a/BepInEx.Core/Logging/Logger.cs +++ b/BepInEx.Core/Logging/Logger.cs @@ -7,7 +7,7 @@ namespace BepInEx.Logging; /// -/// Handles pub-sub event marshalling across all log listeners and sources. +/// Handles pub-sub event marshalling across all log listeners and sources. /// public static class Logger { @@ -24,17 +24,17 @@ static Logger() } /// - /// Log levels that are currently listened to by at least one listener. + /// Log levels that are currently listened to by at least one listener. /// public static LogLevel ListenedLogLevels => listeners.ActiveLogLevels; /// - /// Collection of all log listeners that receive log events. + /// Collection of all log listeners that receive log events. /// public static ICollection Listeners => listeners; /// - /// Collection of all log source that output log events. + /// Collection of all log source that output log events. /// public static ICollection Sources { get; } @@ -44,14 +44,14 @@ internal static void InternalLogEvent(object sender, LogEventArgs eventArgs) } /// - /// Logs an entry to the internal logger instance. + /// Logs an entry to the internal logger instance. /// /// The level of the entry. /// The data of the entry. internal static void Log(LogLevel level, object data) => InternalLogSource.Log(level, data); /// - /// Logs an entry to the internal logger instance if any log listener wants the message. + /// Logs an entry to the internal logger instance if any log listener wants the message. /// /// The level of the entry. /// Log handler to resolve log from. @@ -61,7 +61,7 @@ internal static void Log(LogLevel level, InternalLogSource.Log(level, logHandler); /// - /// Creates a new log source with a name and attaches it to . + /// Creates a new log source with a name and attaches it to . /// /// Name of the log source to create. /// An instance of that allows to write logs. diff --git a/BepInEx.Core/Logging/ManualLogSource.cs b/BepInEx.Core/Logging/ManualLogSource.cs index f59263b89..f97293fdd 100644 --- a/BepInEx.Core/Logging/ManualLogSource.cs +++ b/BepInEx.Core/Logging/ManualLogSource.cs @@ -5,12 +5,12 @@ namespace BepInEx.Logging; /// -/// A generic, multi-purpose log source. Exposes simple API to manually emit logs. +/// A generic, multi-purpose log source. Exposes simple API to manually emit logs. /// public class ManualLogSource : ILogSource { /// - /// Creates a manual log source. + /// Creates a manual log source. /// /// Name of the log source. public ManualLogSource(string sourceName) @@ -28,14 +28,14 @@ public ManualLogSource(string sourceName) public void Dispose() { } /// - /// Logs a message with the specified log level. + /// Logs a message with the specified log level. /// /// Log levels to attach to the message. Multiple can be used with bitwise ORing. /// Data to log. public void Log(LogLevel level, object data) => LogEvent?.Invoke(this, new LogEventArgs(data, level, this)); /// - /// Logs an interpolated string with the specified log level. + /// Logs an interpolated string with the specified log level. /// /// Log levels to attach to the message. Multiple can be used with bitwise ORing. /// Handler for the interpolated string. @@ -48,73 +48,73 @@ public void Log(LogLevel level, } /// - /// Logs a message with level. + /// Logs a message with level. /// /// Data to log. public void LogFatal(object data) => Log(LogLevel.Fatal, data); /// - /// Logs an interpolated string with level. + /// Logs an interpolated string with level. /// /// Handler for the interpolated string. public void LogFatal(BepInExFatalLogInterpolatedStringHandler logHandler) => Log(LogLevel.Fatal, logHandler); /// - /// Logs a message with level. + /// Logs a message with level. /// /// Data to log. public void LogError(object data) => Log(LogLevel.Error, data); /// - /// Logs an interpolated string with level. + /// Logs an interpolated string with level. /// /// Handler for the interpolated string. public void LogError(BepInExErrorLogInterpolatedStringHandler logHandler) => Log(LogLevel.Error, logHandler); /// - /// Logs a message with level. + /// Logs a message with level. /// /// Data to log. public void LogWarning(object data) => Log(LogLevel.Warning, data); /// - /// Logs an interpolated string with level. + /// Logs an interpolated string with level. /// /// Handler for the interpolated string. public void LogWarning(BepInExWarningLogInterpolatedStringHandler logHandler) => Log(LogLevel.Warning, logHandler); /// - /// Logs a message with level. + /// Logs a message with level. /// /// Data to log. public void LogMessage(object data) => Log(LogLevel.Message, data); /// - /// Logs an interpolated string with level. + /// Logs an interpolated string with level. /// /// Handler for the interpolated string. public void LogMessage(BepInExMessageLogInterpolatedStringHandler logHandler) => Log(LogLevel.Message, logHandler); /// - /// Logs a message with level. + /// Logs a message with level. /// /// Data to log. public void LogInfo(object data) => Log(LogLevel.Info, data); /// - /// Logs an interpolated string with level. + /// Logs an interpolated string with level. /// /// Handler for the interpolated string. public void LogInfo(BepInExInfoLogInterpolatedStringHandler logHandler) => Log(LogLevel.Info, logHandler); /// - /// Logs a message with level. + /// Logs a message with level. /// /// Data to log. public void LogDebug(object data) => Log(LogLevel.Debug, data); /// - /// Logs an interpolated string with level. + /// Logs an interpolated string with level. /// /// Handler for the interpolated string. public void LogDebug(BepInExDebugLogInterpolatedStringHandler logHandler) => Log(LogLevel.Debug, logHandler); diff --git a/BepInEx.Core/Logging/TraceLogSource.cs b/BepInEx.Core/Logging/TraceLogSource.cs index d73be2d13..96c7f0cd9 100644 --- a/BepInEx.Core/Logging/TraceLogSource.cs +++ b/BepInEx.Core/Logging/TraceLogSource.cs @@ -3,7 +3,7 @@ namespace BepInEx.Logging; /// -/// A source that routes all logs from the inbuilt .NET API to the BepInEx logging system. +/// A source that routes all logs from the inbuilt .NET API to the BepInEx logging system. /// /// public class TraceLogSource : TraceListener @@ -11,7 +11,7 @@ public class TraceLogSource : TraceListener private static TraceLogSource traceListener; /// - /// Creates a new trace log source. + /// Creates a new trace log source. /// protected TraceLogSource() { @@ -19,17 +19,17 @@ protected TraceLogSource() } /// - /// Whether Trace logs are currently being rerouted. + /// Whether Trace logs are currently being rerouted. /// public static bool IsListening { get; private set; } /// - /// Internal log source. + /// Internal log source. /// protected ManualLogSource LogSource { get; } /// - /// Creates a new trace log source. + /// Creates a new trace log source. /// /// New log source (or already existing one). public static ILogSource CreateSource() @@ -45,13 +45,13 @@ public static ILogSource CreateSource() } /// - /// Writes a message to the underlying instance. + /// Writes a message to the underlying instance. /// /// The message to write. public override void Write(string message) => LogSource.Log(LogLevel.Info, message); /// - /// Writes a message and a newline to the underlying instance. + /// Writes a message and a newline to the underlying instance. /// /// The message to write. public override void WriteLine(string message) => LogSource.Log(LogLevel.Info, message); diff --git a/BepInEx.Core/Paths.cs b/BepInEx.Core/Paths.cs index b286d905d..c9d877159 100644 --- a/BepInEx.Core/Paths.cs +++ b/BepInEx.Core/Paths.cs @@ -5,74 +5,80 @@ namespace BepInEx; /// -/// Paths used by BepInEx +/// Paths used by BepInEx /// public static class Paths { /// - /// The directory that the core BepInEx DLLs reside in. + /// The directory that the core BepInEx DLLs reside in. /// public static string BepInExAssemblyDirectory { get; private set; } /// - /// The path to the core BepInEx DLL. + /// The path to the core BepInEx DLL. /// public static string BepInExAssemblyPath { get; private set; } /// - /// The path to the main BepInEx folder. + /// The path to the main BepInEx folder. /// public static string BepInExRootPath { get; private set; } /// - /// The path of the currently executing program BepInEx is encapsulated in. + /// The path of the currently executing program BepInEx is encapsulated in. /// public static string ExecutablePath { get; private set; } /// - /// The directory that the currently executing process resides in. - /// On OSX however, this is the parent directory of the game.app folder. + /// The directory that the currently executing process resides in. + /// On OSX however, this is the parent directory of the game.app folder. /// public static string GameRootPath { get; private set; } /// - /// The path to the config directory. + /// The path to the config directory. /// public static string ConfigPath { get; private set; } /// - /// The path to the global BepInEx configuration file. + /// The path to the global BepInEx configuration file. /// public static string BepInExConfigPath { get; private set; } /// - /// The path to temporary cache files. + /// The path to temporary cache files. /// public static string CachePath { get; private set; } /// - /// The path to the patcher plugin folder which resides in the BepInEx folder. + /// The path to the patcher plugin folder which resides in the BepInEx folder. /// public static string PatcherPluginPath { get; private set; } /// - /// The path to the plugin folder which resides in the BepInEx folder. - /// - /// This is ONLY guaranteed to be set correctly when Chainloader has been initialized. - /// + /// The path to the plugin folder which resides in the BepInEx folder. + /// + /// This is ONLY guaranteed to be set correctly when Chainloader has been initialized. + /// /// public static string PluginPath { get; private set; } /// - /// The name of the currently executing process. + /// The name of the currently executing process. /// public static string ProcessName { get; private set; } /// - /// List of directories from where Mono will search assemblies before assembly resolving is invoked. + /// List of directories from where Mono will search assemblies before assembly resolving is invoked. /// public static string[] DllSearchPaths { get; private set; } + /// Derives all well-known paths from the game executable location. + /// Full path to the game executable. + /// Root path of the BepInEx installation. Derived from the executable path if null. + /// Path to the managed game assemblies. Derived from the executable path if null. + /// Whether the game data folder sits next to the managed folder. + /// Additional directories Mono searches for assemblies. public static void SetExecutablePath(string executablePath, string bepinRootPath = null, string managedPath = null, diff --git a/BepInEx.Core/PlatformUtils.cs b/BepInEx.Core/PlatformUtils.cs index b3c2a8e0d..9e0fa623f 100644 --- a/BepInEx.Core/PlatformUtils.cs +++ b/BepInEx.Core/PlatformUtils.cs @@ -106,7 +106,7 @@ public static T AsDelegate(this IntPtr procAddress) where T : Delegate } /// - /// Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes. + /// Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes. /// public static void SetPlatform() { diff --git a/BepInEx.Core/Utility.cs b/BepInEx.Core/Utility.cs index cfac10d15..1f812b9cc 100644 --- a/BepInEx.Core/Utility.cs +++ b/BepInEx.Core/Utility.cs @@ -13,7 +13,7 @@ namespace BepInEx; /// -/// Generic helper properties and methods. +/// Generic helper properties and methods. /// public static class Utility { @@ -23,7 +23,7 @@ public static class Utility public static AssemblyLoadContext LoadContext = null!; /// - /// BepInEx version. + /// BepInEx version. /// public static SemanticVersioning.Version BepInExVersion = SemanticVersioning.Version.Parse(MetadataHelper.GetAttributes(typeof(Utility).Assembly)[0] @@ -33,13 +33,13 @@ public static class Utility private static bool? sreEnabled; /// - /// Whether current Common Language Runtime supports dynamic method generation using - /// namespace. + /// Whether current Common Language Runtime supports dynamic method generation using + /// namespace. /// public static bool CLRSupportsDynamicAssemblies => CheckSRE(); /// - /// An encoding for UTF-8 which does not emit a byte order mark (BOM). + /// An encoding for UTF-8 which does not emit a byte order mark (BOM). /// public static Encoding UTF8NoBom { get; } = new UTF8Encoding(false); @@ -68,7 +68,7 @@ private static bool CheckSRE() } /// - /// Try to perform an action. + /// Try to perform an action. /// /// Action to perform. /// Possible exception that gets returned. @@ -89,14 +89,14 @@ public static bool TryDo(Action action, out Exception exception) } /// - /// Combines multiple paths together, as the specific method is not available in .NET 3.5. + /// Combines multiple paths together, as the specific method is not available in .NET 3.5. /// /// The multiple paths to combine together. /// A combined path. public static string CombinePaths(params string[] parts) => parts.Aggregate(Path.Combine); /// - /// Returns the parent directory of a path, optionally specifying the amount of levels. + /// Returns the parent directory of a path, optionally specifying the amount of levels. /// /// The path to get the parent directory of. /// The amount of levels to traverse. Defaults to 1 @@ -110,7 +110,7 @@ public static string ParentDirectory(string path, int levels = 1) } /// - /// Tries to parse a bool, with a default value if unable to parse. + /// Tries to parse a bool, with a default value if unable to parse. /// /// The string to parse /// The value to return if parsing is unsuccessful. @@ -119,21 +119,21 @@ public static bool SafeParseBool(string input, bool defaultValue = false) => bool.TryParse(input, out var result) ? result : defaultValue; /// - /// Converts a file path into a UnityEngine.WWW format. + /// Converts a file path into a UnityEngine.WWW format. /// /// The file path to convert. /// A converted file path. public static string ConvertToWWWFormat(string path) => $"file://{path.Replace('\\', '/')}"; /// - /// Indicates whether a specified string is null, empty, or consists only of white-space characters. + /// Indicates whether a specified string is null, empty, or consists only of white-space characters. /// /// The string to test. /// True if the value parameter is null or empty, or if value consists exclusively of white-space characters. public static bool IsNullOrWhiteSpace(this string self) => self == null || self.All(char.IsWhiteSpace); /// - /// Sorts a given dependency graph using a direct toposort, reporting possible cyclic dependencies. + /// Sorts a given dependency graph using a direct toposort, reporting possible cyclic dependencies. /// /// Nodes to sort /// Function that maps a node to a collection of its dependencies. @@ -184,10 +184,11 @@ bool Visit(TNode node, Stack stack) } /// - /// Try to resolve and load the given assembly DLL. + /// Try to resolve and load the given assembly DLL. /// /// Name of the assembly, of the type . /// Directory to search the assembly from. + /// Function that loads an assembly from a file path. /// The loaded assembly. /// True, if the assembly was found and loaded. Otherwise, false. public static bool TryResolveDllAssembly(AssemblyName assemblyName, @@ -236,7 +237,7 @@ public static bool TryResolveDllAssembly(AssemblyName assemblyName, } /// - /// Checks whether a given cecil type definition is a subtype of a provided type. + /// Checks whether a given cecil type definition is a subtype of a provided type. /// /// Cecil type definition /// Type to check against @@ -249,7 +250,7 @@ public static bool IsSubtypeOf(this TypeDefinition self, Type td) } /// - /// Try to resolve and load the given assembly DLL. + /// Try to resolve and load the given assembly DLL. /// /// Name of the assembly, of the type . /// Directory to search the assembly from. @@ -259,7 +260,7 @@ public static bool TryResolveDllAssembly(AssemblyName assemblyName, string direc TryResolveDllAssembly(assemblyName, directory, LoadContext.LoadFromAssemblyPath, out assembly); /// - /// Try to resolve and load the given assembly DLL. + /// Try to resolve and load the given assembly DLL. /// /// Name of the assembly, of the type . /// Directory to search the assembly from. @@ -274,7 +275,7 @@ public static bool TryResolveDllAssembly(AssemblyName assemblyName, s => AssemblyDefinition.ReadAssembly(s, readerParameters), out assembly); /// - /// Tries to create a file with the given name + /// Tries to create a file with the given name /// /// Path of the file to create /// File open mode @@ -302,6 +303,9 @@ public static bool TryOpenFileStream(string path, } } + /// Enumerates all methods of the type and its base types. + /// Type definition to enumerate. + /// All methods declared on the type and its base types. public static IEnumerable EnumerateAllMethods(this TypeDefinition type) { var currentType = type; @@ -316,7 +320,7 @@ public static IEnumerable EnumerateAllMethods(this TypeDefinit } /// - /// Compute a MD5 hash of the given stream. + /// Compute a MD5 hash of the given stream. /// /// Stream to hash /// MD5 hash as a hex string @@ -355,7 +359,7 @@ public static string HashStrings(params string[] strings) } /// - /// Convert the given array to a hex string. + /// Convert the given array to a hex string. /// /// Bytes to convert. /// Bytes reinterpreted as a hex number. @@ -384,15 +388,14 @@ public static string GetCommandLineArgValue(string arg) } /// - /// Try to parse given string as an assembly name + /// Try to parse given string as an assembly name /// /// Fully qualified assembly name /// Resulting instance /// true, if parsing was successful, otherwise false /// - /// On some versions of mono, using fails because it runs on unmanaged side - /// which has problems with encoding. - /// Using solves this by doing parsing on managed side instead. + /// On some versions of mono, using fails because it runs on unmanaged side which has problems with encoding. + /// Using solves this by doing parsing on managed side instead. /// public static bool TryParseAssemblyName(string fullName, out AssemblyName assemblyName) { @@ -422,8 +425,7 @@ internal static void AddCecilPlatformAssemblies(this AppDomain appDomain, string } /// - /// Gets unique files in all given directories. If the file with the same name exists in multiple directories, - /// only the first occurrence is returned. + /// Gets unique files in all given directories. If the file with the same name exists in multiple directories, only the first occurrence is returned. /// /// Directories to search from. /// File pattern to search. diff --git a/BepInEx.Preloader.Core/AssemblyBuildInfo.cs b/BepInEx.Preloader.Core/AssemblyBuildInfo.cs index a6477ca63..d3c413e5d 100644 --- a/BepInEx.Preloader.Core/AssemblyBuildInfo.cs +++ b/BepInEx.Preloader.Core/AssemblyBuildInfo.cs @@ -4,22 +4,32 @@ namespace BepInEx.Preloader.Core { + /// Describes the target framework and architecture of a managed assembly. public class AssemblyBuildInfo { + /// Kind of .NET framework an assembly targets. public enum FrameworkType { + /// Framework could not be determined. Unknown, + /// .NET Framework. NetFramework, + /// .NET Standard. NetStandard, + /// .NET (Core). NetCore } + /// Target framework version of the assembly. public Version NetFrameworkVersion { get; private set; } + /// Whether the assembly targets AnyCPU. public bool IsAnyCpu { get; set; } + /// Whether the assembly prefers 64-bit execution. public bool Is64Bit { get; set; } + /// Kind of .NET framework the assembly targets. public FrameworkType AssemblyFrameworkType { get; set; } private void SetNet4Version(AssemblyDefinition assemblyDefinition) @@ -68,6 +78,9 @@ private void SetNet4Version(AssemblyDefinition assemblyDefinition) } } + /// Determines the target framework and architecture of an assembly. + /// Assembly to inspect. + /// Build information of the assembly. public static AssemblyBuildInfo DetermineInfo(AssemblyDefinition assemblyDefinition) { var buildInfo = new AssemblyBuildInfo(); diff --git a/BepInEx.Preloader.Core/EnvVars.cs b/BepInEx.Preloader.Core/EnvVars.cs index e4162c94e..9a1c6160c 100644 --- a/BepInEx.Preloader.Core/EnvVars.cs +++ b/BepInEx.Preloader.Core/EnvVars.cs @@ -4,34 +4,33 @@ namespace BepInEx.Preloader.Core; /// -/// Doorstop environment variables, passed into the BepInEx preloader. -/// https://github.com/NeighTools/UnityDoorstop/wiki#environment-variables +/// Doorstop environment variables, passed into the BepInEx preloader. +/// https://github.com/NeighTools/UnityDoorstop/wiki#environment-variables /// public static class EnvVars { /// - /// Path to the assembly that was invoked via Doorstop. Contains the same value as in "targetAssembly" configuration - /// option in the config file. + /// Path to the assembly that was invoked via Doorstop. Contains the same value as in "targetAssembly" configuration option in the config file. /// public static string DOORSTOP_INVOKE_DLL_PATH { get; private set; } /// - /// Full path to the game's "Managed" folder that contains all the game's managed assemblies + /// Full path to the game's "Managed" folder that contains all the game's managed assemblies /// public static string DOORSTOP_MANAGED_FOLDER_DIR { get; private set; } /// - /// Full path to the game executable currently running. + /// Full path to the game executable currently running. /// public static string DOORSTOP_PROCESS_PATH { get; private set; } /// - /// Array of paths where Mono searches DLLs from before assembly resolvers are invoked. + /// Array of paths where Mono searches DLLs from before assembly resolvers are invoked. /// public static string[] DOORSTOP_DLL_SEARCH_DIRS { get; private set; } /// - /// Path of the DLL that contains mono imports. + /// Path of the DLL that contains mono imports. /// public static string DOORSTOP_MONO_LIB_PATH { get; private set; } diff --git a/BepInEx.Preloader.Core/InternalPreloaderLogger.cs b/BepInEx.Preloader.Core/InternalPreloaderLogger.cs index 2fa3cd072..af565adb2 100644 --- a/BepInEx.Preloader.Core/InternalPreloaderLogger.cs +++ b/BepInEx.Preloader.Core/InternalPreloaderLogger.cs @@ -2,7 +2,9 @@ namespace BepInEx.Preloader.Core; +/// Provides the shared log source used by the preloader. public static class PreloaderLogger { + /// The preloader log source. public static ManualLogSource Log { get; } = Logger.CreateLogSource("Preloader"); } diff --git a/BepInEx.Preloader.Core/Logging/ChainloaderLogHelper.cs b/BepInEx.Preloader.Core/Logging/ChainloaderLogHelper.cs index f82e35437..eeaac44ae 100644 --- a/BepInEx.Preloader.Core/Logging/ChainloaderLogHelper.cs +++ b/BepInEx.Preloader.Core/Logging/ChainloaderLogHelper.cs @@ -8,6 +8,7 @@ namespace BepInEx.Preloader.Core.Logging; +/// Helper methods for logging chainloader startup information. public static class ChainloaderLogHelper { private static Dictionary MacOSVersions { get; } = new() @@ -33,6 +34,8 @@ public static class ChainloaderLogHelper ["21.2.0"] = "12.1", }; + /// Logs version, platform and process information. + /// Log source to write to. public static void PrintLogInfo(ManualLogSource log) { var bepinVersion = Utility.BepInExVersion; @@ -142,6 +145,7 @@ private static string GetPlatformString() return builder.ToString(); } + /// Replays logs captured by the preloader through the chainloader loggers. public static void RewritePreloaderLogs() { if (PreloaderConsoleListener.LogEvents == null || PreloaderConsoleListener.LogEvents.Count == 0) diff --git a/BepInEx.Preloader.Core/Logging/PreloaderConsoleListener.cs b/BepInEx.Preloader.Core/Logging/PreloaderConsoleListener.cs index f94fbd05c..202e4b993 100644 --- a/BepInEx.Preloader.Core/Logging/PreloaderConsoleListener.cs +++ b/BepInEx.Preloader.Core/Logging/PreloaderConsoleListener.cs @@ -5,7 +5,7 @@ namespace BepInEx.Preloader.Core.Logging; /// -/// Log listener that listens to logs during preloading time and buffers messages for output in Unity logs later. +/// Log listener that listens to logs during preloading time and buffers messages for output in Unity logs later. /// public class PreloaderConsoleListener : ILogListener { @@ -15,7 +15,7 @@ public class PreloaderConsoleListener : ILogListener "Which log levels to show in the console output."); /// - /// A list of all objects that this listener has received. + /// A list of all objects that this listener has received. /// public static List LogEvents { get; } = new(); diff --git a/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs b/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs index a6fc099cf..451976384 100644 --- a/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs +++ b/BepInEx.Preloader.Core/Patching/AssemblyPatcher.cs @@ -15,20 +15,21 @@ namespace BepInEx.Preloader.Core.Patching; /// -/// Worker class which is used for loading and patching entire folders of assemblies, or alternatively patching and -/// loading assemblies one at a time. +/// Worker class which is used for loading and patching entire folders of assemblies, or alternatively patching and loading assemblies one at a time. /// public class AssemblyPatcher : IDisposable { private Func assemblyLoader; + /// Creates a new assembly patcher. + /// Loader used to load patched assemblies. public AssemblyPatcher(Func assemblyLoader) { this.assemblyLoader = assemblyLoader; } /// - /// The context of this assembly patcher instance that is passed to all patcher plugins. + /// The context of this assembly patcher instance that is passed to all patcher plugins. /// public PatcherContext PatcherContext { get; } = new() { @@ -36,8 +37,7 @@ public AssemblyPatcher(Func assemblyLoader) }; /// - /// A cloned version of to ensure that any foreach loops do not break when the collection - /// gets modified. + /// A cloned version of to ensure that any foreach loops do not break when the collection gets modified. /// private IEnumerable PatcherPluginsSafe => PatcherContext.PatcherPlugins.ToList(); @@ -46,7 +46,7 @@ public AssemblyPatcher(Func assemblyLoader) private static Regex allowedGuidRegex { get; } = new(@"^[a-zA-Z0-9\._\-]+$"); /// - /// Performs work to dispose collection objects. + /// Performs work to dispose collection objects. /// public void Dispose() { @@ -122,7 +122,7 @@ private bool HasPatcherPlugins(AssemblyDefinition ass) } /// - /// Adds all patchers from all managed assemblies specified in a directory. + /// Adds all patchers from all managed assemblies specified in a directory. /// /// Directory to search patcher DLLs from. public void AddPatchersFromDirectory(string directory) @@ -222,18 +222,14 @@ void AddDefinition(PatchDefinition definition) /// - /// Adds all .dll assemblies in given directories to be patched and loaded by this patcher instance. Non-managed - /// assemblies - /// are skipped. + /// Adds all .dll assemblies in given directories to be patched and loaded by this patcher instance. Non-managed assemblies are skipped. /// /// The directories to search. public void LoadAssemblyDirectories(params string[] directories) => LoadAssemblyDirectories(directories, new[] { "dll" }); /// - /// Adds all assemblies in given directories to be patched and loaded by this patcher instance. Non-managed assemblies - /// are - /// skipped. + /// Adds all assemblies in given directories to be patched and loaded by this patcher instance. Non-managed assemblies are skipped. /// /// The directory to search. /// The file extensions to attempt to load. @@ -277,7 +273,7 @@ public void LoadAssemblyDirectories(IEnumerable directories, IEnumerable } /// - /// Attempts to load a managed assembly as an . Returns true if successful. + /// Attempts to load a managed assembly as an . Returns true if successful. /// /// The path of the assembly. /// The loaded assembly. Null if not successful in loading. @@ -297,7 +293,7 @@ public static bool TryLoadAssembly(string path, out AssemblyDefinition assembly) } /// - /// Applies patchers to all assemblies loaded into this assembly patcher and then loads patched assemblies into memory. + /// Applies patchers to all assemblies loaded into this assembly patcher and then loads patched assemblies into memory. /// public void PatchAndLoad() { diff --git a/BepInEx.Preloader.Core/Patching/Attributes.cs b/BepInEx.Preloader.Core/Patching/Attributes.cs index d8e31108b..0faa83e68 100644 --- a/BepInEx.Preloader.Core/Patching/Attributes.cs +++ b/BepInEx.Preloader.Core/Patching/Attributes.cs @@ -6,7 +6,7 @@ namespace BepInEx.Preloader.Core.Patching; /// -/// This attribute denotes that a class is a patcher plugin, and specifies the required metadata. +/// This attribute denotes that a class is a patcher plugin, and specifies the required metadata. /// [AttributeUsage(AttributeTargets.Class)] public class PatcherPluginInfoAttribute : Attribute @@ -22,19 +22,19 @@ public PatcherPluginInfoAttribute(string GUID, string Name, string Version) } /// - /// The unique identifier of the plugin. Should not change between plugin versions. + /// The unique identifier of the plugin. Should not change between plugin versions. /// public string GUID { get; protected set; } /// - /// The user friendly name of the plugin. Is able to be changed between versions. + /// The user friendly name of the plugin. Is able to be changed between versions. /// public string Name { get; protected set; } /// - /// The specific version of the plugin. + /// The specific version of the plugin. /// public Version Version { get; protected set; } @@ -80,19 +80,18 @@ internal static PatcherPluginInfoAttribute FromType(Type type) } /// -/// Defines an assembly that a patch method will target. +/// Defines an assembly that a patch method will target. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class TargetAssemblyAttribute : Attribute { /// - /// Marker used to indicate all possible assemblies to be targeted by a patch method. + /// Marker used to indicate all possible assemblies to be targeted by a patch method. /// public const string AllAssemblies = "_all"; /// - /// The short filename of the assembly. Use to mark all possible - /// assemblies as targets. + /// The short filename of the assembly. Use to mark all possible assemblies as targets. /// public TargetAssemblyAttribute(string targetAssembly) { @@ -100,13 +99,13 @@ public TargetAssemblyAttribute(string targetAssembly) } /// - /// The short filename of the assembly to target. + /// The short filename of the assembly to target. /// public string TargetAssembly { get; } } /// -/// Defines a type that a patch method will target. +/// Defines a type that a patch method will target. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class TargetTypeAttribute : Attribute @@ -120,12 +119,12 @@ public TargetTypeAttribute(string targetAssembly, string targetType) } /// - /// The short filename of the assembly to target. + /// The short filename of the assembly to target. /// public string TargetAssembly { get; } /// - /// The full name of the type to target for patching. + /// The full name of the type to target for patching. /// public string TargetType { get; } } diff --git a/BepInEx.Preloader.Core/Patching/BasePatcher.cs b/BepInEx.Preloader.Core/Patching/BasePatcher.cs index 15437314b..4c5494a16 100644 --- a/BepInEx.Preloader.Core/Patching/BasePatcher.cs +++ b/BepInEx.Preloader.Core/Patching/BasePatcher.cs @@ -4,10 +4,11 @@ namespace BepInEx.Preloader.Core.Patching; /// -/// A patcher that can contain multiple methods for patching assemblies. +/// A patcher that can contain multiple methods for patching assemblies. /// public abstract class BasePatcher { + /// Initializes a new patcher plugin. protected BasePatcher() { Info = PatcherPluginInfoAttribute.FromType(GetType()); @@ -19,33 +20,32 @@ protected BasePatcher() } /// - /// A instance created for use by this patcher plugin. + /// A instance created for use by this patcher plugin. /// public ManualLogSource Log { get; } /// - /// A configuration file binding created with the of this plugin as the - /// filename. + /// A configuration file binding created with the of this plugin as the filename. /// public ConfigFile Config { get; } /// - /// Metadata associated with this patcher plugin. + /// Metadata associated with this patcher plugin. /// public PatcherPluginInfoAttribute Info { get; } /// - /// The context of the this BasePatcher is associated with. + /// The context of the this BasePatcher is associated with. /// public PatcherContext Context { get; set; } /// - /// Executed before any patches from any plugin are applied. + /// Executed before any patches from any plugin are applied. /// public virtual void Initialize() { } /// - /// Executed after all patches from all plugins have been applied. + /// Executed after all patches from all plugins have been applied. /// public virtual void Finalizer() { } } diff --git a/BepInEx.Preloader.Core/Patching/PatcherContext.cs b/BepInEx.Preloader.Core/Patching/PatcherContext.cs index 084aa842c..296b4ae93 100644 --- a/BepInEx.Preloader.Core/Patching/PatcherContext.cs +++ b/BepInEx.Preloader.Core/Patching/PatcherContext.cs @@ -5,10 +5,14 @@ namespace BepInEx.Preloader.Core.Patching; /// -/// A definition of an individual patch for use by . +/// A definition of an individual patch for use by . /// public class PatchDefinition { + /// Creates a new patch definition for the given target assemblies. + /// Attribute describing the targeted assemblies. + /// Patcher instance that owns the patch method. + /// Patch method to invoke. public PatchDefinition(TargetAssemblyAttribute targetAssembly, BasePatcher instance, MethodInfo methodInfo) { TargetAssembly = targetAssembly; @@ -18,6 +22,10 @@ public PatchDefinition(TargetAssemblyAttribute targetAssembly, BasePatcher insta FullName = $"{MethodInfo.DeclaringType.FullName}/{MethodInfo.Name} -> {TargetAssembly.TargetAssembly}"; } + /// Creates a new patch definition for the given target type. + /// Attribute describing the targeted type. + /// Patcher instance that owns the patch method. + /// Patch method to invoke. public PatchDefinition(TargetTypeAttribute targetType, BasePatcher instance, MethodInfo methodInfo) { TargetType = targetType; @@ -29,75 +37,71 @@ public PatchDefinition(TargetTypeAttribute targetType, BasePatcher instance, Met } /// - /// The assembly / assemblies this patch will target, if there any. + /// The assembly / assemblies this patch will target, if there any. /// public TargetAssemblyAttribute TargetAssembly { get; } /// - /// The type / types this patch will target, if there are any. + /// The type / types this patch will target, if there are any. /// public TargetTypeAttribute TargetType { get; } /// - /// The instance of the this originates from. + /// The instance of the this originates from. /// public BasePatcher Instance { get; } /// - /// The method that will perform the patching logic defined by this instance. + /// The method that will perform the patching logic defined by this instance. /// public MethodInfo MethodInfo { get; } /// - /// A friendly name for this patch definition, for use in logging and error tracking. + /// A friendly name for this patch definition, for use in logging and error tracking. /// public string FullName { get; } } /// -/// Context provided to patcher plugins from the associated patcher engine. +/// Context provided to patcher plugins from the associated patcher engine. /// public class PatcherContext { /// - /// Contains a list of assemblies that will be patched and loaded into the runtime. - /// - /// The dictionary has the name of the file, without any directories. These are used by the dumping - /// functionality, and as such, these are also required to be unique. They do not have to be exactly the same as - /// the real filename, however they have to be mapped deterministically. - /// - /// Order is not respected, as it will be sorted by dependencies. + /// Contains a list of assemblies that will be patched and loaded into the runtime. + /// + /// The dictionary has the name of the file, without any directories. These are used by the dumping functionality, and as such, these are also required to be unique. They do not have to be exactly the same as the real filename, however they have to be mapped deterministically. + /// + /// Order is not respected, as it will be sorted by dependencies. /// public Dictionary AvailableAssemblies { get; } = new(); /// - /// Contains a mapping of available assembly name to their original filenames. + /// Contains a mapping of available assembly name to their original filenames. /// public Dictionary AvailableAssembliesPaths { get; } = new(); /// - /// Contains a dictionary of assemblies that have been loaded as part of executing this assembly patcher. - /// - /// The key is the same key as used in , while the value is the actual assembly - /// itself. - /// + /// Contains a dictionary of assemblies that have been loaded as part of executing this assembly patcher. + /// + /// The key is the same key as used in , while the value is the actual assembly itself. + /// /// public Dictionary LoadedAssemblies { get; } = new(); /// - /// A list of plugins that will be initialized and executed, in the order of the list. + /// A list of plugins that will be initialized and executed, in the order of the list. /// public List PatcherPlugins { get; } = new(); /// - /// A list of individual patches that will execute, generated by parsing - /// . + /// A list of individual patches that will execute, generated by parsing + /// . /// public List PatchDefinitions { get; } = new(); /// - /// The directory location as to where patched assemblies will be saved to and loaded from disk, for debugging - /// purposes. Defaults to BepInEx/DumpedAssemblies/ + /// The directory location as to where patched assemblies will be saved to and loaded from disk, for debugging purposes. Defaults to BepInEx/DumpedAssemblies/<ProcessName> /// public string DumpedAssembliesPath { get; internal set; } } diff --git a/BepInEx.Preloader.Core/Patching/PatcherPluginMetadata.cs b/BepInEx.Preloader.Core/Patching/PatcherPluginMetadata.cs index 6994dea9b..e1ff6c33c 100644 --- a/BepInEx.Preloader.Core/Patching/PatcherPluginMetadata.cs +++ b/BepInEx.Preloader.Core/Patching/PatcherPluginMetadata.cs @@ -4,12 +4,12 @@ namespace BepInEx.Preloader.Core.Patching; /// -/// A single cached assembly patcher. +/// A single cached assembly patcher. /// internal class PatcherPluginMetadata : ICacheable { /// - /// Type name of the patcher. + /// Type name of the patcher. /// public string TypeName { get; set; } = string.Empty; diff --git a/BepInEx.Preloader.Core/RuntimeFixes/ConsoleSetOutFix.cs b/BepInEx.Preloader.Core/RuntimeFixes/ConsoleSetOutFix.cs index 7b08ddaf9..c71453730 100644 --- a/BepInEx.Preloader.Core/RuntimeFixes/ConsoleSetOutFix.cs +++ b/BepInEx.Preloader.Core/RuntimeFixes/ConsoleSetOutFix.cs @@ -6,11 +6,13 @@ namespace BepInEx.Preloader.RuntimeFixes; +/// Redirects console output to the BepInEx log. public static class ConsoleSetOutFix { private static LoggedTextWriter loggedTextWriter; internal static ManualLogSource ConsoleLogSource = Logger.CreateLogSource("Console"); + /// Replaces the console output writer with a logging writer. public static void Apply() { loggedTextWriter = new LoggedTextWriter { Parent = Console.Out }; diff --git a/BepInEx.Preloader.Core/RuntimeFixes/HarmonyBackendFix.cs b/BepInEx.Preloader.Core/RuntimeFixes/HarmonyBackendFix.cs index 615bc4060..4361ded80 100644 --- a/BepInEx.Preloader.Core/RuntimeFixes/HarmonyBackendFix.cs +++ b/BepInEx.Preloader.Core/RuntimeFixes/HarmonyBackendFix.cs @@ -4,6 +4,7 @@ namespace BepInEx.Preloader.RuntimeFixes; +/// Applies the configured MonoMod backend for Harmony patches. public static class HarmonyBackendFix { private static readonly ConfigEntry ConfigHarmonyBackend = ConfigFile.CoreConfig.Bind( @@ -12,6 +13,7 @@ public static class HarmonyBackendFix MonoModBackend.auto, "Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.\nThis setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting."); + /// Reads the backend setting and configures MonoMod accordingly. public static void Initialize() { switch (ConfigHarmonyBackend.Value) diff --git a/Runtimes/NET/BepInEx.NET.Common/BasePlugin.cs b/Runtimes/NET/BepInEx.NET.Common/BasePlugin.cs index 5d40b10aa..629e3b294 100644 --- a/Runtimes/NET/BepInEx.NET.Common/BasePlugin.cs +++ b/Runtimes/NET/BepInEx.NET.Common/BasePlugin.cs @@ -4,8 +4,10 @@ namespace BepInEx.NET.Common { + /// Base class that every .NET plugin must inherit. public abstract class BasePlugin { + /// Initializes a new plugin instance. protected BasePlugin() { var metadata = MetadataHelper.GetMetadata(this); @@ -17,14 +19,20 @@ protected BasePlugin() Config = new ConfigFile(Utility.CombinePaths(Paths.ConfigPath, metadata.GUID + ".cfg"), false, metadata); } + /// Logger instance tied to this plugin. public ManualLogSource Log { get; } + /// Default config file tied to this plugin. public ConfigFile Config { get; } + /// Harmony instance tied to this plugin. public Harmony HarmonyInstance { get; set; } + /// Called when the plugin is loaded. public abstract void Load(); + /// Called when the plugin is unloaded. + /// True if the plugin was unloaded, otherwise false. public virtual bool Unload() => false; } } diff --git a/Runtimes/NET/BepInEx.NET.Common/NetChainloader.cs b/Runtimes/NET/BepInEx.NET.Common/NetChainloader.cs index 5e4af6689..e4239da72 100644 --- a/Runtimes/NET/BepInEx.NET.Common/NetChainloader.cs +++ b/Runtimes/NET/BepInEx.NET.Common/NetChainloader.cs @@ -5,17 +5,21 @@ namespace BepInEx.NET.Common { + /// Chainloader that loads .NET plugins. public class NetChainloader : BaseChainloader { // TODO: Remove once proper instance handling exists + /// The active chainloader instance. public static NetChainloader Instance { get; set; } + /// public override void Initialize(string gameExePath = null) { Instance = this; base.Initialize(gameExePath); } + /// public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly) { var type = pluginAssembly.GetType(pluginInfo.TypeName); @@ -27,6 +31,7 @@ public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAsse return pluginInstance; } + /// protected override void InitializeLoggers() { base.InitializeLoggers(); diff --git a/Runtimes/NET/BepInEx.NET.CoreCLR/HookEntrypoint.cs b/Runtimes/NET/BepInEx.NET.CoreCLR/HookEntrypoint.cs index 5912f5804..c98116bd2 100644 --- a/Runtimes/NET/BepInEx.NET.CoreCLR/HookEntrypoint.cs +++ b/Runtimes/NET/BepInEx.NET.CoreCLR/HookEntrypoint.cs @@ -9,12 +9,16 @@ using BepInEx.NET.Shared; using BepInEx.Preloader.Core; +/// Entry point used by the .NET CoreCLR startup hook. public class StartupHook { + /// Directories searched when resolving BepInEx assemblies. public static List ResolveDirectories = new(); + /// Fallback executable name used when the game assembly cannot be determined. public static string DoesNotExistPath = "_doesnotexist_.exe"; + /// Determines the game assembly and initializes BepInEx. public static void Initialize() { var executableFilename = Process.GetCurrentProcess().MainModule.FileName; @@ -26,6 +30,10 @@ public static void Initialize() Initialize(assemblyFilename); } + /// Initializes BepInEx for the given game assembly. + /// Full path to the game assembly. + /// Root path of the BepInEx installation. Derived from the assembly path if null. + /// Assembly load context to load BepInEx into. Uses the default context if null. public static void Initialize(string assemblyFilename, string bepinRootPath = null, AssemblyLoadContext alc = null) { var silentExceptionLog = $"bepinex_preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"; diff --git a/Runtimes/NET/BepInEx.NET.Shared/SharedEntrypoint.cs b/Runtimes/NET/BepInEx.NET.Shared/SharedEntrypoint.cs index 09a163515..87e8f205b 100644 --- a/Runtimes/NET/BepInEx.NET.Shared/SharedEntrypoint.cs +++ b/Runtimes/NET/BepInEx.NET.Shared/SharedEntrypoint.cs @@ -93,15 +93,16 @@ public static Assembly LocalResolve(object sender, ResolveEventArgs args) /// - /// Generic helper properties and methods. + /// Generic helper properties and methods. /// internal static class LocalUtility { /// - /// Try to resolve and load the given assembly DLL. + /// Try to resolve and load the given assembly DLL. /// /// Name of the assembly, of the type . /// Directory to search the assembly from. + /// Function that loads an assembly from a file path. /// The loaded assembly. /// True, if the assembly was found and loaded. Otherwise, false. private static bool TryResolveDllAssembly(AssemblyName assemblyName, @@ -141,7 +142,7 @@ private static bool TryResolveDllAssembly(AssemblyName assemblyName, } /// - /// Try to resolve and load the given assembly DLL. + /// Try to resolve and load the given assembly DLL. /// /// Name of the assembly, of the type . /// Directory to search the assembly from. diff --git a/Runtimes/NET/BepisLoader/BepisLoader.cs b/Runtimes/NET/BepisLoader/BepisLoader.cs index b79499aa4..5dd0903b9 100644 --- a/Runtimes/NET/BepisLoader/BepisLoader.cs +++ b/Runtimes/NET/BepisLoader/BepisLoader.cs @@ -4,6 +4,7 @@ namespace BepisLoader; +/// Bootstraps BepInEx and launches the game. public class BepisLoader { internal static string resoDir = string.Empty; @@ -46,8 +47,8 @@ static void Main(string[] args) var asm = alc.LoadFromAssemblyPath(Path.Combine(bepinPath, "core", "BepInEx.NET.CoreCLR.dll")); - var t = asm.GetType("StartupHook"); - var m = t.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static, [typeof(string), typeof(string), typeof(AssemblyLoadContext)]); + var t = asm.GetType("StartupHook") ?? throw new InvalidOperationException("StartupHook type not found."); + var m = t.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static, [typeof(string), typeof(string), typeof(AssemblyLoadContext)]) ?? throw new InvalidOperationException("StartupHook.Initialize method not found."); m.Invoke(null, [resoDllPath, bepinPath, alc]); // Find and load Resonite @@ -156,6 +157,8 @@ protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) private static string logPath = string.Empty; private static readonly object _lock = new object(); private static readonly HashSet _loggedMessages = new(StringComparer.OrdinalIgnoreCase); + /// Appends a message to the loader log file. + /// Message to log. Duplicate messages are only written once. public static void Log(string message) { try diff --git a/build/Program.cs b/build/Program.cs index 53b2dc676..8be945167 100644 --- a/build/Program.cs +++ b/build/Program.cs @@ -1,4 +1,3 @@ -#pragma warning disable CS1591 // ReSharper disable ClassNeverInstantiated.Global using System; using System.Collections.Generic; @@ -19,8 +18,12 @@ using Microsoft.Build.Definition; using Microsoft.Build.Evaluation; +/// Cake Frosting build entry point. public static class Program { + /// Runs the build with the given command-line arguments. + /// Command-line arguments passed to the build. + /// The process exit code. public static int Main(string[] args) { return new CakeHost() @@ -29,15 +32,21 @@ public static int Main(string[] args) } } +/// Shared state and settings for the build. public class BuildContext : FrostingContext { + /// Kind of build to produce. public enum ProjectBuildType { + /// Stable release build. Release, + /// Local development build. Development, + /// Bleeding-edge CI build. BleedingEdge } + /// Version of hookfxr downloaded for distributions. public const string HOOKFXR_VERSION = "1.1.0"; internal readonly DistributionTarget[] Distributions = @@ -51,6 +60,8 @@ public enum ProjectBuildType }; + /// Creates build state from the Cake context. + /// Cake context to derive paths and arguments from. public BuildContext(ICakeContext ctx) : base(ctx) { @@ -70,20 +81,32 @@ public BuildContext(ICakeContext ctx) NugetSource = ctx.Argument("nuget-source", "https://nuget.bepinex.dev/v3/index.json"); } + /// Kind of build to produce. public ProjectBuildType BuildType { get; } + /// CI build identifier. Negative when not built by CI. public int BuildId { get; } + /// Commit the last build ran on. Empty when building everything. public string LastBuildCommit { get; } + /// API key used to push NuGet packages. public string NugetApiKey { get; } + /// NuGet feed packages are pushed to. public string NugetSource { get; } + /// Repository root directory. public DirectoryPath RootDirectory { get; } + /// Directory holding all build output, including final distributions. public DirectoryPath OutputDirectory { get; } + /// Directory holding cached downloads. public DirectoryPath CacheDirectory { get; } + /// Directory holding assembled distributions. public DirectoryPath DistributionDirectory { get; } + /// Version prefix read from the repository properties. public string VersionPrefix { get; } + /// Commit the current build is produced from. public GitCommit CurrentCommit { get; } + /// Version suffix for the current build type. public string VersionSuffix => BuildType switch { ProjectBuildType.Release => "", @@ -92,6 +115,7 @@ public BuildContext(ICakeContext ctx) var _ => throw new ArgumentOutOfRangeException() }; + /// Full package version of the current build. public string BuildPackageVersion => VersionPrefix + BuildType switch { @@ -99,12 +123,15 @@ public BuildContext(ICakeContext ctx) var _ => $"-{VersionSuffix}+{this.GitShortenSha(RootDirectory, CurrentCommit)}", }; + /// Download URL of the hookfxr release zip. public static string HookfxrZipUrl = $"https://github.com/ResoniteModding/hookfxr/releases/download/v{HOOKFXR_VERSION}/hookfxr-Release.zip"; } +/// Cleans build output directories. [TaskName("Clean")] public sealed class CleanTask : FrostingTask { + /// public override void Run(BuildContext ctx) { ctx.CreateDirectory(ctx.OutputDirectory); @@ -117,10 +144,12 @@ public override void Run(BuildContext ctx) } } +/// Restores dotnet CLI tools. [TaskName("RestoreTools")] [IsDependentOn(typeof(CleanTask))] public sealed class RestoreToolsTask : FrostingTask { + /// public override void Run(BuildContext ctx) { ctx.Log.Information("Restoring dotnet tools..."); @@ -134,10 +163,12 @@ public override void Run(BuildContext ctx) } } +/// Builds the solution and publishes the loader. [TaskName("Compile")] [IsDependentOn(typeof(RestoreToolsTask))] public sealed class CompileTask : FrostingTask { + /// public override void Run(BuildContext ctx) { var hasBepisLoader = ctx.Distributions.Any(d => d.Runtime == "BepisLoader"); @@ -208,9 +239,11 @@ public override void Run(BuildContext ctx) } } +/// Downloads external distribution dependencies. [TaskName("DownloadDependencies")] public sealed class DownloadDependenciesTask : FrostingTask { + /// public override void Run(BuildContext ctx) { ctx.Log.Information("Downloading dependencies"); @@ -232,11 +265,13 @@ public override void Run(BuildContext ctx) } } +/// Assembles distributable archives from build output. [TaskName("MakeDist")] [IsDependentOn(typeof(CompileTask))] [IsDependentOn(typeof(DownloadDependenciesTask))] public sealed class MakeDistTask : FrostingTask { + /// public override void Run(BuildContext ctx) { ctx.CreateDirectory(ctx.DistributionDirectory); @@ -377,12 +412,15 @@ public override void Run(BuildContext ctx) } } +/// Pushes built packages to the NuGet feed. [TaskName("PushNuGet")] public sealed class PushNuGetTask : FrostingTask { + /// public override bool ShouldRun(BuildContext ctx) => !string.IsNullOrWhiteSpace(ctx.NugetApiKey) && ctx.BuildType != BuildContext.ProjectBuildType.Development; + /// public override void Run(BuildContext ctx) { var nugetPath = ctx.OutputDirectory.Combine("NuGet"); @@ -396,12 +434,15 @@ public override void Run(BuildContext ctx) } } +/// Builds the Thunderstore package for the loader. [TaskName("BuildThunderstorePackage")] [IsDependentOn(typeof(MakeDistTask))] public sealed class BuildThunderstorePackageTask : FrostingTask { + /// public override bool ShouldRun(BuildContext ctx) => ctx.Distributions.Any(d => d.Runtime == "BepisLoader"); + /// public override void Run(BuildContext ctx) { ctx.Log.Information("Building Thunderstore package for BepisLoader..."); @@ -434,15 +475,18 @@ public override void Run(BuildContext ctx) } } +/// Fixes Linux executable permissions inside the Thunderstore package. [TaskName("FixThunderstoreLinuxPermissions")] [IsDependentOn(typeof(BuildThunderstorePackageTask))] [SupportedOSPlatform("linux")] public sealed class FixThunderstoreLinuxPermissionsTask : FrostingTask { + /// public override bool ShouldRun(BuildContext ctx) => ctx.Distributions.Any(d => d.Runtime == "BepisLoader") && System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux); + /// [SupportedOSPlatform("linux")] public override void Run(BuildContext ctx) { @@ -498,12 +542,14 @@ public override void Run(BuildContext ctx) } } +/// Zips distributions and writes release metadata. [TaskName("Publish")] [IsDependentOn(typeof(MakeDistTask))] [IsDependentOn(typeof(PushNuGetTask))] [IsDependentOn(typeof(FixThunderstoreLinuxPermissionsTask))] public sealed class PublishTask : FrostingTask { + /// public override void Run(BuildContext ctx) { ctx.Log.Information("Packing BepInEx"); @@ -545,6 +591,7 @@ public override void Run(BuildContext ctx) } } +/// Default build task. [TaskName("Default")] [IsDependentOn(typeof(CompileTask))] public class DefaultTask : FrostingTask { }