Don't crash when modifying constructor
Tweak log level of assembly resolver. Events relating to game initialization and shutdown. Plugin manager loads plugins right before the dependency manager is attached.
This commit is contained in:
@@ -103,6 +103,16 @@ namespace Torch.API
|
|||||||
/// Initialize the Torch instance.
|
/// Initialize the Torch instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current state of the game this instance of torch is controlling.
|
||||||
|
/// </summary>
|
||||||
|
TorchGameState GameState { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event raised when <see cref="GameState"/> changes.
|
||||||
|
/// </summary>
|
||||||
|
event TorchGameStateChangedDel GameStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -186,6 +186,7 @@
|
|||||||
<Compile Include="Session\ITorchSession.cs" />
|
<Compile Include="Session\ITorchSession.cs" />
|
||||||
<Compile Include="Session\ITorchSessionManager.cs" />
|
<Compile Include="Session\ITorchSessionManager.cs" />
|
||||||
<Compile Include="Session\TorchSessionState.cs" />
|
<Compile Include="Session\TorchSessionState.cs" />
|
||||||
|
<Compile Include="TorchGameState.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
47
Torch.API/TorchGameState.cs
Normal file
47
Torch.API/TorchGameState.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sandbox;
|
||||||
|
|
||||||
|
namespace Torch.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the state of a <see cref="MySandboxGame"/>
|
||||||
|
/// </summary>
|
||||||
|
public enum TorchGameState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The game is currently being created.
|
||||||
|
/// </summary>
|
||||||
|
Creating,
|
||||||
|
/// <summary>
|
||||||
|
/// The game has been created and is ready to begin loading.
|
||||||
|
/// </summary>
|
||||||
|
Created,
|
||||||
|
/// <summary>
|
||||||
|
/// The game is currently loading.
|
||||||
|
/// </summary>
|
||||||
|
Loading,
|
||||||
|
/// <summary>
|
||||||
|
/// The game is fully loaded and ready to start sessions
|
||||||
|
/// </summary>
|
||||||
|
Loaded,
|
||||||
|
/// <summary>
|
||||||
|
/// The game is beginning the unload sequence
|
||||||
|
/// </summary>
|
||||||
|
Unloading,
|
||||||
|
/// <summary>
|
||||||
|
/// The game has been shutdown and is no longer active
|
||||||
|
/// </summary>
|
||||||
|
Unloaded
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback raised when a game's state changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="game">The game who had a state change</param>
|
||||||
|
/// <param name="newState">The game's new state</param>
|
||||||
|
public delegate void TorchGameStateChangedDel(MySandboxGame game, TorchGameState newState);
|
||||||
|
}
|
@@ -95,7 +95,6 @@ namespace Torch.Server
|
|||||||
MyGlobalTypeMetadata.Static.Init();
|
MyGlobalTypeMetadata.Static.Init();
|
||||||
|
|
||||||
GetManager<InstanceManager>().LoadInstance(Config.InstancePath);
|
GetManager<InstanceManager>().LoadInstance(Config.InstancePath);
|
||||||
Plugins.LoadPlugins();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InvokeBeforeRun()
|
private void InvokeBeforeRun()
|
||||||
|
@@ -24,7 +24,7 @@ namespace Torch.Managers.PatchManager.MSIL
|
|||||||
{
|
{
|
||||||
_module = method.Module;
|
_module = method.Module;
|
||||||
_genericTypeArgs = method.DeclaringType?.GenericTypeArguments ?? new Type[0];
|
_genericTypeArgs = method.DeclaringType?.GenericTypeArguments ?? new Type[0];
|
||||||
_genericMethArgs = method.GetGenericArguments();
|
_genericMethArgs = (method is MethodInfo ? method.GetGenericArguments() : new Type[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemberInfo ResolveMember(int token)
|
public MemberInfo ResolveMember(int token)
|
||||||
|
@@ -148,7 +148,7 @@ namespace Torch.Managers
|
|||||||
var dlls = Directory.GetFiles(PluginDir, "*.dll", SearchOption.AllDirectories);
|
var dlls = Directory.GetFiles(PluginDir, "*.dll", SearchOption.AllDirectories);
|
||||||
foreach (var dllPath in dlls)
|
foreach (var dllPath in dlls)
|
||||||
{
|
{
|
||||||
_log.Debug($"Loading plugin {dllPath}");
|
_log.Info($"Loading plugin {dllPath}");
|
||||||
var asm = Assembly.UnsafeLoadFrom(dllPath);
|
var asm = Assembly.UnsafeLoadFrom(dllPath);
|
||||||
|
|
||||||
foreach (var type in asm.GetExportedTypes())
|
foreach (var type in asm.GetExportedTypes())
|
||||||
|
@@ -120,12 +120,13 @@ namespace Torch
|
|||||||
sessionManager.AddFactory((x) => new EntityManager(this));
|
sessionManager.AddFactory((x) => new EntityManager(this));
|
||||||
|
|
||||||
Managers.AddManager(sessionManager);
|
Managers.AddManager(sessionManager);
|
||||||
Managers.AddManager(new PatchManager(this));
|
var patcher = new PatchManager(this);
|
||||||
Managers.AddManager(new KeenLogManager(this));
|
GameStateInjector.Inject(patcher.AcquireContext());
|
||||||
|
Managers.AddManager(patcher);
|
||||||
|
// Managers.AddManager(new KeenLogManager(this));
|
||||||
Managers.AddManager(new FilesystemManager(this));
|
Managers.AddManager(new FilesystemManager(this));
|
||||||
Managers.AddManager(new UpdateManager(this));
|
Managers.AddManager(new UpdateManager(this));
|
||||||
Managers.AddManager(Plugins);
|
Managers.AddManager(Plugins);
|
||||||
|
|
||||||
TorchAPI.Instance = this;
|
TorchAPI.Instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +270,7 @@ namespace Torch
|
|||||||
MySession.OnUnloading += OnSessionUnloading;
|
MySession.OnUnloading += OnSessionUnloading;
|
||||||
MySession.OnUnloaded += OnSessionUnloaded;
|
MySession.OnUnloaded += OnSessionUnloaded;
|
||||||
RegisterVRagePlugin();
|
RegisterVRagePlugin();
|
||||||
|
Managers.GetManager<PluginManager>().LoadPlugins();
|
||||||
Managers.Attach();
|
Managers.Attach();
|
||||||
_init = true;
|
_init = true;
|
||||||
}
|
}
|
||||||
@@ -383,5 +385,90 @@ namespace Torch
|
|||||||
{
|
{
|
||||||
GetManager<IPluginManager>().UpdatePlugins();
|
GetManager<IPluginManager>().UpdatePlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TorchGameState _gameState = TorchGameState.Unloaded;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public TorchGameState GameState
|
||||||
|
{
|
||||||
|
get => _gameState;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_gameState = value;
|
||||||
|
GameStateChanged?.Invoke(MySandboxGame.Static, _gameState);
|
||||||
|
Log.Info($"Game state changed {_gameState}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event TorchGameStateChangedDel GameStateChanged;
|
||||||
|
|
||||||
|
#region GameStateInjecting
|
||||||
|
private static class GameStateInjector
|
||||||
|
{
|
||||||
|
#pragma warning disable 649
|
||||||
|
[ReflectedMethodInfo(typeof(MySandboxGame), nameof(MySandboxGame.Dispose))]
|
||||||
|
private static MethodInfo _sandboxGameDispose;
|
||||||
|
[ReflectedMethodInfo(typeof(MySandboxGame), "Initialize")]
|
||||||
|
private static MethodInfo _sandboxGameInit;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
internal static void Inject(PatchContext target)
|
||||||
|
{
|
||||||
|
ConstructorInfo ctor = typeof(MySandboxGame).GetConstructor(new[] {typeof(string[])});
|
||||||
|
if (ctor == null)
|
||||||
|
throw new ArgumentException("Can't find constructor MySandboxGame(string[])");
|
||||||
|
target.GetPattern(ctor).Prefixes.Add(MethodRef(nameof(PrefixConstructor)));
|
||||||
|
target.GetPattern(ctor).Suffixes.Add(MethodRef(nameof(SuffixConstructor)));
|
||||||
|
target.GetPattern(_sandboxGameInit).Prefixes.Add(MethodRef(nameof(PrefixInit)));
|
||||||
|
target.GetPattern(_sandboxGameInit).Suffixes.Add(MethodRef(nameof(SuffixInit)));
|
||||||
|
target.GetPattern(_sandboxGameDispose).Prefixes.Add(MethodRef(nameof(PrefixDispose)));
|
||||||
|
target.GetPattern(_sandboxGameDispose).Suffixes.Add(MethodRef(nameof(SuffixDispose)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MethodInfo MethodRef(string name)
|
||||||
|
{
|
||||||
|
return typeof(GameStateInjector).GetMethod(name,
|
||||||
|
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrefixConstructor()
|
||||||
|
{
|
||||||
|
if (Instance is TorchBase tb)
|
||||||
|
tb.GameState = TorchGameState.Creating;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SuffixConstructor()
|
||||||
|
{
|
||||||
|
if (Instance is TorchBase tb)
|
||||||
|
tb.GameState = TorchGameState.Created;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrefixInit()
|
||||||
|
{
|
||||||
|
if (Instance is TorchBase tb)
|
||||||
|
tb.GameState = TorchGameState.Loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SuffixInit()
|
||||||
|
{
|
||||||
|
if (Instance is TorchBase tb)
|
||||||
|
tb.GameState = TorchGameState.Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrefixDispose()
|
||||||
|
{
|
||||||
|
if (Instance is TorchBase tb)
|
||||||
|
tb.GameState = TorchGameState.Unloading;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SuffixDispose()
|
||||||
|
{
|
||||||
|
if (Instance is TorchBase tb)
|
||||||
|
tb.GameState = TorchGameState.Unloaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -67,7 +67,7 @@ namespace Torch.Utils
|
|||||||
string assemblyPath = Path.Combine(path, assemblyName + ".dll");
|
string assemblyPath = Path.Combine(path, assemblyName + ".dll");
|
||||||
if (!File.Exists(assemblyPath))
|
if (!File.Exists(assemblyPath))
|
||||||
continue;
|
continue;
|
||||||
_log.Debug("Loading {0} from {1}", assemblyName, SimplifyPath(assemblyPath));
|
_log.Trace("Loading {0} from {1}", assemblyName, SimplifyPath(assemblyPath));
|
||||||
LogManager.Flush();
|
LogManager.Flush();
|
||||||
Assembly asm = Assembly.LoadFrom(assemblyPath);
|
Assembly asm = Assembly.LoadFrom(assemblyPath);
|
||||||
_assemblies.Add(assemblyName, asm);
|
_assemblies.Add(assemblyName, asm);
|
||||||
|
Reference in New Issue
Block a user