234 lines
6.3 KiB
C#
234 lines
6.3 KiB
C#
using System.Diagnostics;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using HarmonyLib;
|
|
using PluginLoader.Compiler;
|
|
using PluginLoader.Data;
|
|
using PluginLoader.GUI;
|
|
using PluginLoader.Stats;
|
|
using Sandbox.Game.World;
|
|
using VRage.Plugins;
|
|
using SEPMPlugin = PluginLoader.SEPM.SEPMPlugin;
|
|
|
|
namespace PluginLoader;
|
|
|
|
public class Main : IHandleInputPlugin
|
|
{
|
|
public static Main Instance;
|
|
|
|
private readonly List<PluginInstance> plugins = new();
|
|
|
|
private bool init;
|
|
|
|
public Main()
|
|
{
|
|
var sw = Stopwatch.StartNew();
|
|
|
|
Splash = new();
|
|
|
|
Instance = this;
|
|
|
|
var temp = Cursor.Current;
|
|
Cursor.Current = Cursors.AppStarting;
|
|
|
|
var pluginsDir = LoaderTools.PluginsDir;
|
|
Directory.CreateDirectory(pluginsDir);
|
|
|
|
LogFile.Init(pluginsDir);
|
|
LogFile.WriteLine("Starting - v" + Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
|
|
|
// Fix tls 1.2 not supported on Windows 7 - github.com is tls 1.2 only
|
|
try
|
|
{
|
|
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
|
|
}
|
|
catch (NotSupportedException e)
|
|
{
|
|
LogFile.WriteLine("An error occurred while setting up networking, web requests will probably fail: " + e);
|
|
}
|
|
|
|
Splash.SetText("Finding references...");
|
|
RoslynReferences.GenerateAssemblyList();
|
|
|
|
AppDomain.CurrentDomain.AssemblyResolve += ResolveDependencies;
|
|
|
|
Config = PluginConfig.Load(pluginsDir);
|
|
List = new(pluginsDir, Config);
|
|
|
|
Config.Init(List);
|
|
|
|
StatsClient.OverrideBaseUrl(Config.StatsServerBaseUrl);
|
|
|
|
Splash.SetText("Patching...");
|
|
LogFile.WriteLine("Patching");
|
|
|
|
new Harmony("avaness.PluginLoader").PatchAll(Assembly.GetExecutingAssembly());
|
|
|
|
Splash.SetText("Instantiating plugins...");
|
|
LogFile.WriteLine("Instantiating plugins");
|
|
foreach (var id in Config)
|
|
{
|
|
var data = List[id];
|
|
if (data is GitHubPlugin github)
|
|
github.Init(pluginsDir);
|
|
if (PluginInstance.TryGet(data, out var p))
|
|
{
|
|
plugins.Add(p);
|
|
if (data.IsLocal)
|
|
HasLocal = true;
|
|
}
|
|
}
|
|
|
|
sw.Stop();
|
|
|
|
// FIXME: It can potentially run in the background speeding up the game's startup
|
|
//ReportEnabledPlugins();
|
|
|
|
LogFile.WriteLine($"Finished startup. Took {sw.ElapsedMilliseconds}ms");
|
|
|
|
Cursor.Current = temp;
|
|
|
|
Splash.Delete();
|
|
Splash = null;
|
|
}
|
|
|
|
public PluginList List { get; }
|
|
public PluginConfig Config { get; }
|
|
public SplashScreen Splash { get; }
|
|
|
|
/// <summary>
|
|
/// True if a local plugin was loaded
|
|
/// </summary>
|
|
public bool HasLocal { get; }
|
|
|
|
// Skip local plugins, keep only enabled ones
|
|
public string[] TrackablePluginIds => Config.EnabledPlugins.Where(id => !List[id].IsLocal).ToArray();
|
|
|
|
public void Init(object gameInstance)
|
|
{
|
|
LogFile.WriteLine($"Initializing {plugins.Count} plugins");
|
|
for (var i = plugins.Count - 1; i >= 0; i--)
|
|
{
|
|
var p = plugins[i];
|
|
if (!p.Init(gameInstance))
|
|
plugins.RemoveAtFast(i);
|
|
}
|
|
|
|
init = true;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (init)
|
|
for (var i = plugins.Count - 1; i >= 0; i--)
|
|
{
|
|
var p = plugins[i];
|
|
if (!p.Update())
|
|
plugins.RemoveAtFast(i);
|
|
}
|
|
}
|
|
|
|
public void HandleInput()
|
|
{
|
|
if (init)
|
|
for (var i = plugins.Count - 1; i >= 0; i--)
|
|
{
|
|
var p = plugins[i];
|
|
if (!p.HandleInput())
|
|
plugins.RemoveAtFast(i);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
foreach (var p in plugins)
|
|
p.Dispose();
|
|
plugins.Clear();
|
|
|
|
AppDomain.CurrentDomain.AssemblyResolve -= ResolveDependencies;
|
|
LogFile.Dispose();
|
|
Instance = null;
|
|
}
|
|
|
|
public bool TryGetPluginInstance(string id, out PluginInstance instance)
|
|
{
|
|
instance = null;
|
|
if (!init)
|
|
return false;
|
|
|
|
foreach (var p in plugins)
|
|
if (p.Id == id)
|
|
{
|
|
instance = p;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void ReportEnabledPlugins()
|
|
{
|
|
if (!PlayerConsent.ConsentGiven)
|
|
return;
|
|
|
|
Splash.SetText("Reporting plugin usage...");
|
|
LogFile.WriteLine("Reporting plugin usage");
|
|
|
|
// Config has already been validated at this point so all enabled plugins will have list items
|
|
// FIXME: Move into a background thread
|
|
if (StatsClient.Track(TrackablePluginIds))
|
|
LogFile.WriteLine("List of enabled plugins has been sent to the statistics server");
|
|
else
|
|
LogFile.WriteLine("Failed to send the list of enabled plugins to the statistics server");
|
|
}
|
|
|
|
public void RegisterComponents()
|
|
{
|
|
LogFile.WriteLine($"Registering {plugins.Count} components");
|
|
foreach (var plugin in plugins)
|
|
plugin.RegisterSession(MySession.Static);
|
|
}
|
|
|
|
public void DisablePlugins()
|
|
{
|
|
Config.Disable();
|
|
plugins.Clear();
|
|
LogFile.WriteLine("Disabled all plugins");
|
|
}
|
|
|
|
public void InstantiatePlugins()
|
|
{
|
|
LogFile.WriteLine($"Loading {plugins.Count} plugins");
|
|
for (var i = plugins.Count - 1; i >= 0; i--)
|
|
{
|
|
var p = plugins[i];
|
|
if (!p.Instantiate())
|
|
plugins.RemoveAtFast(i);
|
|
}
|
|
}
|
|
|
|
|
|
private Assembly ResolveDependencies(object sender, ResolveEventArgs args)
|
|
{
|
|
var assembly = args.RequestingAssembly?.GetName().ToString();
|
|
if (args.Name.Contains("0Harmony"))
|
|
{
|
|
if (assembly != null)
|
|
LogFile.WriteLine("Resolving 0Harmony for " + assembly);
|
|
else
|
|
LogFile.WriteLine("Resolving 0Harmony");
|
|
return typeof(Harmony).Assembly;
|
|
}
|
|
|
|
if (args.Name.Contains("SEPluginManager"))
|
|
{
|
|
if (assembly != null)
|
|
LogFile.WriteLine("Resolving SEPluginManager for " + assembly);
|
|
else
|
|
LogFile.WriteLine("Resolving SEPluginManager");
|
|
return typeof(SEPMPlugin).Assembly;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
} |