mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Change the behaviors of the default providers so if multiple assemblies with the same name exists, but in different directories, ignore any that are located deeper.
70 lines
2.7 KiB
C#
70 lines
2.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using BepInEx.Logging;
|
|
|
|
namespace BepInEx.PluginProvider;
|
|
|
|
[BepInPluginProvider("BepInExPluginProvider", "BepInExPluginProvider", "1.0")]
|
|
internal class BepInExPluginProvider : BasePluginProvider
|
|
{
|
|
private static readonly Dictionary<string, string> AssemblyLocationsByFilename = new();
|
|
|
|
public override IList<IPluginLoadContext> GetPlugins()
|
|
{
|
|
var loadContexts = new List<IPluginLoadContext>();
|
|
foreach (var dll in Directory.GetFiles(Path.GetFullPath(Paths.PluginPath), "*.dll", SearchOption.AllDirectories))
|
|
{
|
|
try
|
|
{
|
|
var filename = Path.GetFileNameWithoutExtension(dll);
|
|
var foundDirectory = Path.GetDirectoryName(dll);
|
|
|
|
// Prioritize the shallowest path of each assembly name
|
|
if (AssemblyLocationsByFilename.TryGetValue(filename, out var existingDirectory))
|
|
{
|
|
int levelExistingDirectory = existingDirectory?.Count(x => x == Path.DirectorySeparatorChar) ?? 0;
|
|
int levelFoundDirectory = foundDirectory?.Count(x => x == Path.DirectorySeparatorChar) ?? 0;
|
|
|
|
bool shallowerPathFound = levelExistingDirectory > levelFoundDirectory;
|
|
Logger.LogWarning($"Found duplicate assemblies filenames: {filename} was found at {foundDirectory} " +
|
|
$"while it exists already at {AssemblyLocationsByFilename[filename]}. " +
|
|
$"Only the {(shallowerPathFound ? "first" : "second")} will be examined and resolved");
|
|
|
|
if (levelExistingDirectory > levelFoundDirectory)
|
|
AssemblyLocationsByFilename[filename] = foundDirectory;
|
|
}
|
|
else
|
|
{
|
|
AssemblyLocationsByFilename.Add(filename, foundDirectory);
|
|
}
|
|
|
|
loadContexts.Add(new BepInExPluginLoadContext
|
|
{
|
|
AssemblyHash = File.GetLastWriteTimeUtc(dll).ToString("O"),
|
|
AssemblyIdentifier = dll
|
|
});
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Log(LogLevel.Error, e);
|
|
}
|
|
}
|
|
|
|
return loadContexts;
|
|
}
|
|
|
|
public override Assembly ResolveAssembly(string name)
|
|
{
|
|
if (!AssemblyLocationsByFilename.TryGetValue(name, out var location))
|
|
return null;
|
|
|
|
if (!Utility.TryResolveDllAssemblyWithSymbols(new(name), location, out var ass))
|
|
return null;
|
|
|
|
return ass;
|
|
}
|
|
}
|