Document all undocumented code; change access level of certain types to clean up API

This commit is contained in:
ghorsington committed 2020-08-06 22:29:06 +03:00
1 parent ba5d1c4796
commit 78484b7070
20 files changed
+219 -24

No files matched your search

+13
View File
@@ -25,6 +25,10 @@ namespace BepInEx.Bootstrap
public static Dictionary<string, PluginInfo> PluginInfos { get; } = new Dictionary<string, PluginInfo>();
private static readonly List<BaseUnityPlugin> _plugins = new List<BaseUnityPlugin>();
/// <summary>
/// List of all <see cref="BepInPlugin"/> loaded via the chainloader.
/// </summary>
[Obsolete("Use PluginInfos instead")]
public static List<BaseUnityPlugin> Plugins
{
@@ -38,6 +42,10 @@ namespace BepInEx.Bootstrap
}
}
/// <summary>
/// Collection of error chainloader messages that occured during plugin loading.
/// Contains information about what certain plugins were not loaded.
/// </summary>
public static List<string> DependencyErrors { get; } = new List<string>();
/// <summary>
@@ -128,6 +136,11 @@ namespace BepInEx.Bootstrap
private static Regex allowedGuidRegex { get; } = new Regex(@"^[a-zA-Z0-9\._\-]+$");
/// <summary>
/// Analyzes the given type definition and attempts to convert it to a valid <see cref="PluginInfo"/>
/// </summary>
/// <param name="type">Type definition to analyze.</param>
/// <returns>If the type represent a valid plugin, returns a <see cref="PluginInfo"/> instance. Otherwise, return null.</returns>
public static PluginInfo ToPluginInfo(TypeDefinition type)
{
if (type.IsInterface || type.IsAbstract)
+3
View File
@@ -79,6 +79,9 @@ namespace BepInEx.Bootstrap
};
}
/// <summary>
/// Event fired when <see cref="TypeLoader"/> fails to resolve a type during type loading.
/// </summary>
public static event AssemblyResolveEventHandler AssemblyResolve;
/// <summary>
+2 -2
View File
@@ -219,7 +219,7 @@ namespace BepInEx.Configuration
/// <summary>
/// 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 <see cref="Bind{T}"/>.
/// New settings should be added with <see cref="Bind{T}(BepInEx.Configuration.ConfigDefinition,T,BepInEx.Configuration.ConfigDescription)"/>.
/// </summary>
/// <typeparam name="T">Type of the value contained in this setting.</typeparam>
/// <param name="configDefinition">Section and Key of the setting.</param>
@@ -242,7 +242,7 @@ namespace BepInEx.Configuration
/// <summary>
/// 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 <see cref="Bind{T}"/>.
/// New settings should be added with <see cref="Bind{T}(BepInEx.Configuration.ConfigDefinition,T,BepInEx.Configuration.ConfigDescription)"/>.
/// </summary>
/// <typeparam name="T">Type of the value contained in this setting.</typeparam>
/// <param name="section">Section/category/group of the setting. Settings are grouped by this.</param>
+1 -1
View File
@@ -7,7 +7,7 @@ using MonoMod.Utils;
namespace BepInEx
{
public static class ConsoleManager
internal static class ConsoleManager
{
private const uint SHIFT_JIS_CP = 932;
+1 -1
View File
@@ -5,7 +5,7 @@ using HarmonyLib;
namespace BepInEx.Unix
{
public static class ConsoleWriter
internal static class ConsoleWriter
{
private static ConstructorInfo cStreamWriterConstructor = AccessTools.Constructor(AccessTools.TypeByName("System.IO.CStreamWriter"), new []{ typeof(Stream), typeof(Encoding), typeof(bool) });
public static TextWriter CreateConsoleStreamWriter(Stream stream, Encoding encoding, bool leaveOpen)
+1 -1
View File
@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace BepInEx.Unix
{
public class UnixStream : Stream
internal class UnixStream : Stream
{
public override bool CanRead => Access == FileAccess.Read || Access == FileAccess.ReadWrite;
public override bool CanSeek => false;
+2 -2
View File
@@ -114,7 +114,7 @@ namespace BepInEx
/// <summary>
/// Marks this <see cref="BaseUnityPlugin"/> as depenant on another plugin. The other plugin will be loaded before this one.
/// If the other plugin doesn't exist or is of a version below <see cref="MinimumDependencyVersion"/>, this plugin will not load and an error will be logged instead.
/// If the other plugin doesn't exist or is of a version below <see cref="MinimumVersion"/>, this plugin will not load and an error will be logged instead.
/// </summary>
/// <param name="DependencyGUID">The GUID of the referenced plugin.</param>
/// <param name="MinimumDependencyVersion">The minimum version of the referenced plugin.</param>
@@ -288,7 +288,7 @@ namespace BepInEx
/// <summary>
/// Retrieves the dependencies of the specified plugin type.
/// </summary>
/// <param name="Plugin">The plugin type.</param>
/// <param name="plugin">The plugin type.</param>
/// <returns>A list of all plugin types that the specified plugin type depends upon.</returns>
public static IEnumerable<BepInDependency> GetDependencies(Type plugin)
{
+23
View File
@@ -6,18 +6,41 @@ using BepInEx.Bootstrap;
namespace BepInEx
{
/// <summary>
/// Data class that represents information about a loadable BepInEx plugin.
/// Contains all metadata and additional info required for plugin loading by <see cref="Chainloader"/>.
/// </summary>
public class PluginInfo : ICacheable
{
/// <summary>
/// General metadata about a plugin.
/// </summary>
public BepInPlugin Metadata { get; internal set; }
/// <summary>
/// Collection of <see cref="BepInProcess"/> attributes that describe what processes the plugin can run on.
/// </summary>
public IEnumerable<BepInProcess> Processes { get; internal set; }
/// <summary>
/// Collection of <see cref="BepInDependency"/> attributes that describe what plugins this plugin depends on.
/// </summary>
public IEnumerable<BepInDependency> Dependencies { get; internal set; }
/// <summary>
/// Collection of <see cref="BepInIncompatibility"/> attributes that describe what plugins this plugin
/// is incompatible with.
/// </summary>
public IEnumerable<BepInIncompatibility> Incompatibilities { get; internal set; }
/// <summary>
/// File path to the plugin DLL
/// </summary>
public string Location { get; internal set; }
/// <summary>
/// Instance of the plugin that represents this info. NULL if no plugin is instantiated from info (yet)
/// </summary>
public BaseUnityPlugin Instance { get; internal set; }
internal string TypeName { get; set; }
+2
View File
@@ -8,6 +8,7 @@ namespace BepInEx.Logging
/// </summary>
public class ConsoleLogListener : ILogListener
{
/// <inheritdoc />
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if ((eventArgs.Level & ConfigConsoleDisplayedLevel.Value) == 0)
@@ -18,6 +19,7 @@ namespace BepInEx.Logging
ConsoleManager.SetConsoleColor(ConsoleColor.Gray);
}
/// <inheritdoc />
public void Dispose() { }
private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind(
+24
View File
@@ -9,14 +9,33 @@ namespace BepInEx.Logging
/// </summary>
public class DiskLogListener : ILogListener
{
/// <summary>
/// Log levels to display.
/// </summary>
public LogLevel DisplayedLogLevel { get; set; }
/// <summary>
/// Writer for the disk log.
/// </summary>
public TextWriter LogWriter { get; protected set; }
/// <summary>
/// Timer for flushing the logs to a file.
/// </summary>
public Timer FlushTimer { get; protected set; }
/// <summary>
/// Whether to write Unity log messages to disk log.
/// </summary>
public bool WriteFromUnityLog { get; set; }
/// <summary>
/// Creates a new disk log listener.
/// </summary>
/// <param name="localPath">Path to the log.</param>
/// <param name="displayedLogLevel">Log levels to display.</param>
/// <param name="appendLog">Whether to append logs to an already existing log file.</param>
/// <param name="includeUnityLog">Whether to include Unity log into the disk log.</param>
public DiskLogListener(string localPath, LogLevel displayedLogLevel = LogLevel.Info, bool appendLog = false, bool includeUnityLog = false)
{
WriteFromUnityLog = includeUnityLog;
@@ -46,6 +65,7 @@ namespace BepInEx.Logging
FlushTimer = new Timer(o => { LogWriter?.Flush(); }, null, 2000, 2000);
}
/// <inheritdoc />
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if (!WriteFromUnityLog && eventArgs.Source is UnityLogSource)
@@ -57,6 +77,7 @@ namespace BepInEx.Logging
LogWriter.WriteLine(eventArgs.ToString());
}
/// <inheritdoc />
public void Dispose()
{
FlushTimer?.Dispose();
@@ -64,6 +85,9 @@ namespace BepInEx.Logging
LogWriter?.Dispose();
}
/// <summary>
/// Disposes of Disk logger
/// </summary>
~DiskLogListener()
{
Dispose();
+8
View File
@@ -2,8 +2,16 @@
namespace BepInEx.Logging
{
/// <summary>
/// A generic log listener that receives log events and can route them to some output (e.g. file, console, socket).
/// </summary>
public interface ILogListener : IDisposable
{
/// <summary>
/// Handle an incoming log event.
/// </summary>
/// <param name="sender">Log source that sent the event. Don't use; instead use <see cref="LogEventArgs.Source"/></param>
/// <param name="eventArgs">Information about the log message.</param>
void LogEvent(object sender, LogEventArgs eventArgs);
}
}
+9
View File
@@ -2,10 +2,19 @@
namespace BepInEx.Logging
{
/// <summary>
/// Log source that can output log messages.
/// </summary>
public interface ILogSource : IDisposable
{
/// <summary>
/// Name of the log source.
/// </summary>
string SourceName { get; }
/// <summary>
/// Event that sends the log message. Call <see cref="EventHandler.Invoke"/> to send a log message.
/// </summary>
event EventHandler<LogEventArgs> LogEvent;
}
}
+24 -1
View File
@@ -2,14 +2,32 @@
namespace BepInEx.Logging
{
/// <summary>
/// Log event arguments. Contains info about the log message.
/// </summary>
public class LogEventArgs : EventArgs
{
/// <summary>
/// Logged data.
/// </summary>
public object Data { get; protected set; }
/// <summary>
/// Log levels for the data.
/// </summary>
public LogLevel Level { get; protected set; }
/// <summary>
/// Log source that emitted the log event.
/// </summary>
public ILogSource Source { get; protected set; }
/// <summary>
/// Creates the log event args-
/// </summary>
/// <param name="data">Logged data.</param>
/// <param name="level">Log level of the data.</param>
/// <param name="source">Log source that emits these args.</param>
public LogEventArgs(object data, LogLevel level, ILogSource source)
{
Data = data;
@@ -17,14 +35,19 @@ namespace BepInEx.Logging
Source = source;
}
/// <inheritdoc />
public override string ToString()
{
return $"[{Level,-7}:{Source.SourceName,10}] {Data}";
}
/// <summary>
/// Like <see cref="ToString"/> but appends newline at the end.
/// </summary>
/// <returns>Same output as <see cref="ToString"/> but with new line.</returns>
public string ToStringLine()
{
return $"[{Level,-7}:{Source.SourceName,10}] {Data}{Environment.NewLine}";
return $"{ToString()}{Environment.NewLine}";
}
}
}
+3
View File
@@ -49,6 +49,9 @@ namespace BepInEx.Logging
All = Fatal | Error | Warning | Message | Info | Debug
}
/// <summary>
/// Helper methods for log level handling.
/// </summary>
public static class LogLevelExtensions
{
/// <summary>
+13 -2
View File
@@ -4,12 +4,18 @@ using System.Collections.Generic;
namespace BepInEx.Logging
{
/// <summary>
/// A static <see cref="BaseLogger"/> instance.
/// A static Logger instance.
/// </summary>
public static class Logger
{
/// <summary>
/// Collection of all log listeners that receive log events.
/// </summary>
public static ICollection<ILogListener> Listeners { get; } = new List<ILogListener>();
/// <summary>
/// Collection of all log source that output log events.
/// </summary>
public static ICollection<ILogSource> Sources { get; } = new LogSourceCollection();
private static readonly ManualLogSource InternalLogSource = CreateLogSource("BepInEx");
@@ -38,7 +44,7 @@ namespace BepInEx.Logging
/// Logs an entry to the current logger instance.
/// </summary>
/// <param name="level">The level of the entry.</param>
/// <param name="entry">The textual value of the entry.</param>
/// <param name="data">The textual value of the entry.</param>
internal static void Log(LogLevel level, object data)
{
InternalLogSource.Log(level, data);
@@ -51,6 +57,11 @@ namespace BepInEx.Logging
internal static void LogInfo(object data) => Log(LogLevel.Info, data);
internal static void LogDebug(object data) => Log(LogLevel.Debug, data);
/// <summary>
/// Creates a new log source with a name and attaches it to log sources.
/// </summary>
/// <param name="sourceName">Name of the log source to create.</param>
/// <returns>An instance of <see cref="ManualLogSource"/> that allows to write logs.</returns>
public static ManualLogSource CreateLogSource(string sourceName)
{
var source = new ManualLogSource(sourceName);
+45
View File
@@ -2,28 +2,73 @@
namespace BepInEx.Logging
{
/// <summary>
/// A generic, multi-purpose log source. Exposes simple API to manually emit logs.
/// </summary>
public class ManualLogSource : ILogSource
{
/// <inheritdoc />
public string SourceName { get; }
/// <inheritdoc />
public event EventHandler<LogEventArgs> LogEvent;
/// <summary>
/// Creates a manual log source.
/// </summary>
/// <param name="sourceName">Name of the log source.</param>
public ManualLogSource(string sourceName)
{
SourceName = sourceName;
}
/// <summary>
/// Logs a message with the specified log level.
/// </summary>
/// <param name="level">Log levels to attach to the message. Multiple can be used with bitwise ORing.</param>
/// <param name="data">Data to log.</param>
public void Log(LogLevel level, object data)
{
LogEvent?.Invoke(this, new LogEventArgs(data, level, this));
}
/// <summary>
/// Logs a message with <see cref="LogLevel.Fatal"/> level.
/// </summary>
/// <param name="data">Data to log.</param>
public void LogFatal(object data) => Log(LogLevel.Fatal, data);
/// <summary>
/// Logs a message with <see cref="LogLevel.Error"/> level.
/// </summary>
/// <param name="data">Data to log.</param>
public void LogError(object data) => Log(LogLevel.Error, data);
/// <summary>
/// Logs a message with <see cref="LogLevel.Warning"/> level.
/// </summary>
/// <param name="data">Data to log.</param>
public void LogWarning(object data) => Log(LogLevel.Warning, data);
/// <summary>
/// Logs a message with <see cref="LogLevel.Message"/> level.
/// </summary>
/// <param name="data">Data to log.</param>
public void LogMessage(object data) => Log(LogLevel.Message, data);
/// <summary>
/// Logs a message with <see cref="LogLevel.Info"/> level.
/// </summary>
/// <param name="data">Data to log.</param>
public void LogInfo(object data) => Log(LogLevel.Info, data);
/// <summary>
/// Logs a message with <see cref="LogLevel.Debug"/> level.
/// </summary>
/// <param name="data">Data to log.</param>
public void LogDebug(object data) => Log(LogLevel.Debug, data);
/// <inheritdoc />
public void Dispose() { }
}
}
+18 -4
View File
@@ -3,15 +3,22 @@
namespace BepInEx.Logging
{
/// <summary>
/// A trace listener that writes to an underlying <see cref="BaseLogger"/> instance.
/// A source that routes all logs from <see cref="Trace"/> API to BepInEx logger.
/// </summary>
/// <inheritdoc cref="TraceListener"/>
public class TraceLogSource : TraceListener
{
/// <summary>
/// Whether Trace logs are rerouted.
/// </summary>
public static bool IsListening { get; protected set; } = false;
private static TraceLogSource traceListener;
/// <summary>
/// Creates a new trace log source.
/// </summary>
/// <returns>New log source (or already existing one).</returns>
public static ILogSource CreateSource()
{
if (traceListener == null)
@@ -24,16 +31,21 @@ namespace BepInEx.Logging
return traceListener.LogSource;
}
/// <summary>
/// Internal log source.
/// </summary>
protected ManualLogSource LogSource { get; }
/// <param name="logger">The logger instance to write to.</param>
/// <summary>
/// Creates a new trace log source.
/// </summary>
protected TraceLogSource()
{
LogSource = new ManualLogSource("Trace");
}
/// <summary>
/// Writes a message to the underlying <see cref="BaseLogger"/> instance.
/// Writes a message to the underlying <see cref="ManualLogSource"/> instance.
/// </summary>
/// <param name="message">The message to write.</param>
public override void Write(string message)
@@ -42,7 +54,7 @@ namespace BepInEx.Logging
}
/// <summary>
/// Writes a message and a newline to the underlying <see cref="BaseLogger"/> instance.
/// Writes a message and a newline to the underlying <see cref="ManualLogSource"/> instance.
/// </summary>
/// <param name="message">The message to write.</param>
public override void WriteLine(string message)
@@ -50,9 +62,11 @@ namespace BepInEx.Logging
LogSource.LogInfo(message);
}
/// <inheritdoc />
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
=> TraceEvent(eventCache, source, eventType, id, string.Format(format, args));
/// <inheritdoc />
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
{
LogLevel level;
+2
View File
@@ -34,6 +34,7 @@ namespace BepInEx.Logging
Logger.LogError("Unable to start Unity log writer");
}
/// <inheritdoc />
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if (eventArgs.Source is UnityLogSource)
@@ -44,6 +45,7 @@ namespace BepInEx.Logging
WriteStringToUnityLog?.Invoke(eventArgs.ToStringLine());
}
/// <inheritdoc />
public void Dispose() { }
private ConfigEntry<bool> LogConsoleToUnity = ConfigFile.CoreConfig.Bind("Logging",
+10 -3
View File
@@ -10,15 +10,21 @@ namespace BepInEx.Logging
/// </summary>
public class UnityLogSource : ILogSource
{
/// <inheritdoc />
public string SourceName { get; } = "Unity Log";
/// <inheritdoc />
public event EventHandler<LogEventArgs> LogEvent;
/// <summary>
/// Creates a new Unity log source.
/// </summary>
public UnityLogSource()
{
InternalUnityLogMessage += unityLogMessageHandler;
InternalUnityLogMessage += UnityLogMessageHandler;
}
private void unityLogMessageHandler(object sender, LogEventArgs eventArgs)
private void UnityLogMessageHandler(object sender, LogEventArgs eventArgs)
{
var newEventArgs = new LogEventArgs(eventArgs.Data, eventArgs.Level, this);
LogEvent?.Invoke(this, newEventArgs);
@@ -26,11 +32,12 @@ namespace BepInEx.Logging
private bool disposed = false;
/// <inheritdoc />
public void Dispose()
{
if (!disposed)
{
InternalUnityLogMessage -= unityLogMessageHandler;
InternalUnityLogMessage -= UnityLogMessageHandler;
disposed = true;
}
}
+15 -7
View File
@@ -123,6 +123,14 @@ namespace BepInEx
return self == null || self.All(Char.IsWhiteSpace);
}
/// <summary>
/// Sorts a given dependency graph using a direct toposort, reporting possible cyclic dependencies.
/// </summary>
/// <param name="nodes">Nodes to sort</param>
/// <param name="dependencySelector">Function that maps a node to a collection of its dependencies.</param>
/// <typeparam name="TNode">Type of the node in a dependency graph.</typeparam>
/// <returns>Collection of nodes sorted in the order of least dependencies to the most.</returns>
/// <exception cref="Exception">Thrown when a cyclic dependency occurs.</exception>
public static IEnumerable<TNode> TopologicalSort<TNode>(IEnumerable<TNode> nodes, Func<TNode, IEnumerable<TNode>> dependencySelector)
{
List<TNode> sorted_list = new List<TNode>();
@@ -173,13 +181,6 @@ namespace BepInEx
}
}
/// <summary>
/// Try to resolve and load the given assembly DLL.
/// </summary>
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
/// <param name="directory">Directory to search the assembly from.</param>
/// <param name="assembly">The loaded assembly.</param>
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName, string directory, Func<string, T> loader, out T assembly) where T : class
{
assembly = null;
@@ -210,6 +211,12 @@ namespace BepInEx
return false;
}
/// <summary>
/// Checks whether a given cecil type definition is a subtype of a provided type.
/// </summary>
/// <param name="self">Cecil type definition</param>
/// <param name="td">Type to check against</param>
/// <returns>Whether the given cecil type is a subtype of the type.</returns>
public static bool IsSubtypeOf(this TypeDefinition self, Type td)
{
if (self.FullName == td.FullName)
@@ -234,6 +241,7 @@ namespace BepInEx
/// </summary>
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
/// <param name="directory">Directory to search the assembly from.</param>
/// <param name="readerParameters">Reader parameters that contain possible custom assembly resolver.</param>
/// <param name="assembly">The loaded assembly.</param>
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, ReaderParameters readerParameters, out AssemblyDefinition assembly)