105 lines
2.9 KiB
C#
105 lines
2.9 KiB
C#
using System.Diagnostics;
|
|
using System.Reflection;
|
|
using Sandbox.Graphics.GUI;
|
|
using VRage;
|
|
|
|
namespace PluginLoader.Data;
|
|
|
|
public class LocalPlugin : PluginData
|
|
{
|
|
private LocalPlugin()
|
|
{
|
|
}
|
|
|
|
public LocalPlugin(string dll)
|
|
{
|
|
Id = dll;
|
|
Status = PluginStatus.None;
|
|
}
|
|
|
|
public override string Source => MyTexts.GetString(MyCommonTexts.Local);
|
|
|
|
public override string Id
|
|
{
|
|
get => base.Id;
|
|
set
|
|
{
|
|
base.Id = value;
|
|
if (File.Exists(value))
|
|
FriendlyName = Path.GetFileName(value);
|
|
}
|
|
}
|
|
|
|
public override Assembly? GetAssembly()
|
|
{
|
|
if (!File.Exists(Id)) return null;
|
|
//prevent random unloading if being used by another process
|
|
int maxRetries = 10;
|
|
while (maxRetries > 0)
|
|
{
|
|
try
|
|
{
|
|
AppDomain.CurrentDomain.AssemblyResolve += LoadFromSameFolder;
|
|
var a = Assembly.LoadFile(Id);
|
|
Version = a?.GetName()?.Version ?? Version;
|
|
return a;
|
|
}
|
|
catch (IOException)
|
|
{
|
|
LogFile.WriteLine($"Waiting to load {Id} because it's being used by another process");
|
|
Thread.Sleep(250);
|
|
maxRetries--;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return Id;
|
|
}
|
|
|
|
public override void Show()
|
|
{
|
|
var file = Path.GetFullPath(Id);
|
|
if (File.Exists(file))
|
|
Process.Start("explorer.exe", $"/select, \"{file}\"");
|
|
}
|
|
|
|
private Assembly? LoadFromSameFolder(object sender, ResolveEventArgs args)
|
|
{
|
|
if (args.RequestingAssembly?.IsDynamic ?? false)
|
|
return null;
|
|
|
|
if (args.Name.Contains("0Harmony") || args.Name.Contains("SEPluginManager"))
|
|
return null;
|
|
|
|
var location = args.RequestingAssembly?.Location;
|
|
if (string.IsNullOrWhiteSpace(location) || !Path.GetFullPath(location)
|
|
.StartsWith(Path.GetDirectoryName(Id)!,
|
|
StringComparison.OrdinalIgnoreCase))
|
|
return null;
|
|
|
|
var folderPath = Path.GetDirectoryName(Id);
|
|
if (string.IsNullOrEmpty(folderPath)) return null;
|
|
var assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll");
|
|
if (!File.Exists(assemblyPath))
|
|
return null;
|
|
|
|
var assembly = Assembly.LoadFile(assemblyPath);
|
|
LogFile.WriteLine("Resolving " + assembly.GetName().Name + " for " + args.RequestingAssembly?.FullName);
|
|
|
|
var main = Main.Instance;
|
|
if (!main.Config.IsEnabled(assemblyPath))
|
|
main.List.Remove(assemblyPath);
|
|
|
|
return assembly;
|
|
}
|
|
|
|
public override void GetDescriptionText(MyGuiControlMultilineText textbox)
|
|
{
|
|
textbox.Visible = false;
|
|
textbox.Clear();
|
|
}
|
|
} |