move some parts of main class to other

fix poorly implemented features
This commit is contained in:
zznty
2022-06-05 15:50:03 +07:00
parent a1e9434444
commit 0a40b1fe0f
6 changed files with 70 additions and 156 deletions

View File

@@ -16,30 +16,6 @@ namespace Torch.API
/// </summary> /// </summary>
public interface ITorchBase public interface ITorchBase
{ {
/// <summary>
/// Fired when the session begins loading.
/// </summary>
[Obsolete("Prefer using the TorchSessionManager.SessionStateChanged event")]
event Action SessionLoading;
/// <summary>
/// Fired when the session finishes loading.
/// </summary>
[Obsolete("Prefer using the TorchSessionManager.SessionStateChanged event")]
event Action SessionLoaded;
/// <summary>
/// Fires when the session begins unloading.
/// </summary>
[Obsolete("Prefer using the TorchSessionManager.SessionStateChanged event")]
event Action SessionUnloading;
/// <summary>
/// Fired when the session finishes unloading.
/// </summary>
[Obsolete("Prefer using the TorchSessionManager.SessionStateChanged event")]
event Action SessionUnloaded;
/// <summary> /// <summary>
/// Gets the currently running session instance, or null if none exists. /// Gets the currently running session instance, or null if none exists.
/// </summary> /// </summary>
@@ -67,6 +43,16 @@ namespace Torch.API
/// The binary version of the current instance. /// The binary version of the current instance.
/// </summary> /// </summary>
Version TorchVersion { get; } Version TorchVersion { get; }
/// <summary>
/// Path of the dedicated instance folder.
/// </summary>
string InstancePath { get; }
/// <summary>
/// Name of the dedicated instance.
/// </summary>
string InstanceName { get; }
/// <summary> /// <summary>
/// Invoke an action on the game thread. /// Invoke an action on the game thread.
@@ -146,16 +132,6 @@ namespace Torch.API
/// </summary> /// </summary>
ServerState State { get; } ServerState State { get; }
/// <summary>
/// Path of the dedicated instance folder.
/// </summary>
string InstancePath { get; }
/// <summary>
/// Name of the dedicated instance.
/// </summary>
string InstanceName { get; }
/// <summary> /// <summary>
/// Raised when the server's Init() method has completed. /// Raised when the server's Init() method has completed.
/// </summary> /// </summary>

View File

@@ -37,15 +37,9 @@ namespace Torch.Server
{ {
public class TorchServer : TorchBase, ITorchServer public class TorchServer : TorchBase, ITorchServer
{ {
private bool _hasRun;
private bool _canRun;
private TimeSpan _elapsedPlayTime;
private bool _isRunning;
private float _simRatio; private float _simRatio;
private ServerState _state;
private Stopwatch _uptime; private Stopwatch _uptime;
private Timer _watchdog; private Timer _watchdog;
private int _players;
private MultiplayerManagerDedicated _multiplayerManagerDedicated; private MultiplayerManagerDedicated _multiplayerManagerDedicated;
internal bool FatalException { get; set; } internal bool FatalException { get; set; }
@@ -67,11 +61,13 @@ namespace Torch.Server
var sessionManager = Managers.GetManager<ITorchSessionManager>(); var sessionManager = Managers.GetManager<ITorchSessionManager>();
sessionManager.AddFactory(x => new MultiplayerManagerDedicated(this)); sessionManager.AddFactory(x => new MultiplayerManagerDedicated(this));
sessionManager.SessionStateChanged += OnSessionStateChanged;
// Needs to be done at some point after MyVRageWindows.Init // Needs to be done at some point after MyVRageWindows.Init
// where the debug listeners are registered // where the debug listeners are registered
if (!((TorchConfig)Config).EnableAsserts) if (!((TorchConfig)Config).EnableAsserts)
MyDebug.Listeners.Clear(); MyDebug.Listeners.Clear();
_simUpdateTimer.Elapsed += SimUpdateElapsed; _simUpdateTimer.Elapsed += SimUpdateElapsed;
_simUpdateTimer.Start(); _simUpdateTimer.Start();
} }
@@ -85,7 +81,7 @@ namespace Torch.Server
} }
} }
public bool HasRun { get => _hasRun; set => SetValue(ref _hasRun, value); } public bool HasRun { get; set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -104,22 +100,19 @@ namespace Torch.Server
} }
/// <inheritdoc /> /// <inheritdoc />
public TimeSpan ElapsedPlayTime { get => _elapsedPlayTime; set => SetValue(ref _elapsedPlayTime, value); } public TimeSpan ElapsedPlayTime { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public Thread GameThread => MySandboxGame.Static?.UpdateThread; public Thread GameThread => MySandboxGame.Static?.UpdateThread;
/// <inheritdoc /> /// <inheritdoc />
public bool IsRunning { get => _isRunning; set => SetValue(ref _isRunning, value); } public bool IsRunning { get; set; }
public bool CanRun { get => _canRun; set => SetValue(ref _canRun, value); } public bool CanRun { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public InstanceManager DedicatedInstance { get; } public InstanceManager DedicatedInstance { get; }
/// <inheritdoc />
public string InstanceName { get; }
/// <inheritdoc /> /// <inheritdoc />
protected override uint SteamAppId => 244850; protected override uint SteamAppId => 244850;
@@ -127,22 +120,17 @@ namespace Torch.Server
protected override string SteamAppName => "SpaceEngineersDedicated"; protected override string SteamAppName => "SpaceEngineersDedicated";
/// <inheritdoc /> /// <inheritdoc />
public ServerState State { get => _state; private set => SetValue(ref _state, value); } public ServerState State { get; private set; }
public event Action<ITorchServer> Initialized; public event Action<ITorchServer> Initialized;
/// <inheritdoc /> public int OnlinePlayers { get; private set; }
public string InstancePath { get; }
public int OnlinePlayers { get => _players; private set => SetValue(ref _players, value); }
/// <inheritdoc /> /// <inheritdoc />
public override void Init() public override void Init()
{ {
Log.Info("Initializing server"); Log.Info("Initializing server");
MySandboxGame.IsDedicated = true;
base.Init(); base.Init();
Managers.GetManager<ITorchSessionManager>().SessionStateChanged += OnSessionStateChanged;
GetManager<InstanceManager>().LoadInstance(InstancePath); GetManager<InstanceManager>().LoadInstance(InstancePath);
CanRun = true; CanRun = true;
Initialized?.Invoke(this); Initialized?.Invoke(this);
@@ -237,21 +225,27 @@ namespace Torch.Server
[SuppressPropertyChangedWarnings] [SuppressPropertyChangedWarnings]
private void OnSessionStateChanged(ITorchSession session, TorchSessionState newState) private void OnSessionStateChanged(ITorchSession session, TorchSessionState newState)
{ {
if (newState == TorchSessionState.Unloading || newState == TorchSessionState.Unloaded) switch (newState)
{ {
_watchdog?.Dispose(); case TorchSessionState.Unloading:
_watchdog = null; _watchdog?.Dispose();
ModCommunication.Unregister(); _watchdog = null;
ModCommunication.Unregister();
break;
case TorchSessionState.Loaded:
_multiplayerManagerDedicated = CurrentSession.Managers.GetManager<MultiplayerManagerDedicated>();
_multiplayerManagerDedicated.PlayerJoined += MultiplayerManagerDedicatedOnPlayerJoined;
_multiplayerManagerDedicated.PlayerLeft += MultiplayerManagerDedicatedOnPlayerLeft;
CurrentSession.Managers.GetManager<CommandManager>().RegisterCommandModule(typeof(WhitelistCommands));
ModCommunication.Register();
break;
case TorchSessionState.Loading:
case TorchSessionState.Unloaded:
break;
default:
throw new ArgumentOutOfRangeException(nameof(newState), newState, null);
} }
if (newState == TorchSessionState.Loaded)
{
_multiplayerManagerDedicated = CurrentSession.Managers.GetManager<MultiplayerManagerDedicated>();
_multiplayerManagerDedicated.PlayerJoined += MultiplayerManagerDedicatedOnPlayerJoined;
_multiplayerManagerDedicated.PlayerLeft += MultiplayerManagerDedicatedOnPlayerLeft;
CurrentSession.Managers.GetManager<CommandManager>().RegisterCommandModule(typeof(WhitelistCommands));
ModCommunication.Register();
}
} }
private void MultiplayerManagerDedicatedOnPlayerLeft(IPlayer player) private void MultiplayerManagerDedicatedOnPlayerLeft(IPlayer player)

View File

@@ -419,12 +419,15 @@ namespace Torch.Managers
AppDomain.CurrentDomain.AssemblyResolve += ResolveDependentAssembly; AppDomain.CurrentDomain.AssemblyResolve += ResolveDependentAssembly;
foreach (Assembly asm in assemblies) foreach (Assembly asm in assemblies)
{ {
TorchBase.RegisterAuxAssembly(asm); TorchLauncher.RegisterAssembly(asm);
} }
} }
private static bool IsAssemblyCompatible(AssemblyName a, AssemblyName b) private static bool IsAssemblyCompatible(AssemblyName a, AssemblyName b)
{ {
if (a.Version is null || b.Version is null)
return a.Name == b.Name;
return a.Name == b.Name && a.Version.Major == b.Version.Major && a.Version.Minor == b.Version.Minor; return a.Name == b.Name && a.Version.Major == b.Version.Major && a.Version.Minor == b.Version.Minor;
} }

View File

@@ -37,17 +37,16 @@ namespace Torch
{ {
static TorchBase() static TorchBase()
{ {
MyVRageWindows.Init("SpaceEngineersDedicated", MySandboxGame.Log, null, false); TorchLauncher.RegisterAssembly(typeof(ITorchBase).Assembly);
ReflectedManager.Process(typeof(TorchBase).Assembly); TorchLauncher.RegisterAssembly(typeof(TorchBase).Assembly);
ReflectedManager.Process(typeof(ITorchBase).Assembly); TorchLauncher.RegisterAssembly(Assembly.GetEntryAssembly());
PatchManager.AddPatchShim(typeof(GameStatePatchShim)); PatchManager.AddPatchShim(typeof(GameStatePatchShim));
PatchManager.AddPatchShim(typeof(GameAnalyticsPatch)); PatchManager.AddPatchShim(typeof(GameAnalyticsPatch));
PatchManager.AddPatchShim(typeof(KeenLogPatch)); PatchManager.AddPatchShim(typeof(KeenLogPatch));
PatchManager.AddPatchShim(typeof(XmlRootWriterPatch)); PatchManager.AddPatchShim(typeof(XmlRootWriterPatch));
PatchManager.CommitInternal(); PatchManager.CommitInternal();
RegisterCoreAssembly(typeof(ITorchBase).Assembly);
RegisterCoreAssembly(typeof(TorchBase).Assembly);
RegisterCoreAssembly(Assembly.GetEntryAssembly());
//exceptions in English, please //exceptions in English, please
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
} }
@@ -64,6 +63,8 @@ namespace Torch
/// <inheritdoc /> /// <inheritdoc />
public SemanticVersioning.Version TorchVersion { get; } public SemanticVersioning.Version TorchVersion { get; }
public string InstancePath { get; protected init;}
public string InstanceName { get; protected init; }
/// <inheritdoc /> /// <inheritdoc />
public Version GameVersion { get; private set; } public Version GameVersion { get; private set; }
@@ -78,18 +79,6 @@ namespace Torch
/// <inheritdoc /> /// <inheritdoc />
public ITorchSession CurrentSession => Managers?.GetManager<ITorchSessionManager>()?.CurrentSession; public ITorchSession CurrentSession => Managers?.GetManager<ITorchSessionManager>()?.CurrentSession;
/// <inheritdoc />
public event Action SessionLoading;
/// <inheritdoc />
public event Action SessionLoaded;
/// <inheritdoc />
public event Action SessionUnloading;
/// <inheritdoc />
public event Action SessionUnloaded;
/// <summary> /// <summary>
/// Common log for the Torch instance. /// Common log for the Torch instance.
/// </summary> /// </summary>
@@ -106,7 +95,6 @@ namespace Torch
/// <exception cref="InvalidOperationException">Thrown if a TorchBase instance already exists.</exception> /// <exception cref="InvalidOperationException">Thrown if a TorchBase instance already exists.</exception>
protected TorchBase(ITorchConfig config) protected TorchBase(ITorchConfig config)
{ {
RegisterCoreAssembly(GetType().Assembly);
#pragma warning disable CS0618 #pragma warning disable CS0618
if (Instance != null) if (Instance != null)
throw new InvalidOperationException("A TorchBase instance already exists."); throw new InvalidOperationException("A TorchBase instance already exists.");
@@ -158,27 +146,6 @@ namespace Torch
PatchManager.CommitInternal(); PatchManager.CommitInternal();
} }
}; };
sessionManager.SessionStateChanged += (session, state) =>
{
switch (state)
{
case TorchSessionState.Loading:
SessionLoading?.Invoke();
break;
case TorchSessionState.Loaded:
SessionLoaded?.Invoke();
break;
case TorchSessionState.Unloading:
SessionUnloading?.Invoke();
break;
case TorchSessionState.Unloaded:
SessionUnloaded?.Invoke();
break;
default:
throw new ArgumentOutOfRangeException(nameof(state), state, null);
}
};
} }
[Obsolete("Prefer using Managers.GetManager for global managers")] [Obsolete("Prefer using Managers.GetManager for global managers")]
@@ -193,11 +160,6 @@ namespace Torch
return Managers.AddManager(manager); return Managers.AddManager(manager);
} }
public bool IsOnGameThread()
{
return Thread.CurrentThread.ManagedThreadId == MySandboxGame.Static.UpdateThread.ManagedThreadId;
}
#region Game Actions #region Game Actions
/// <summary> /// <summary>
@@ -288,8 +250,6 @@ namespace Torch
public virtual void Init() public virtual void Init()
{ {
Debug.Assert(!_init, "Torch instance is already initialized."); Debug.Assert(!_init, "Torch instance is already initialized.");
SpaceEngineersGame.SetupBasicGameInfo();
SpaceEngineersGame.SetupPerGameSettings();
ObjectFactoryInitPatch.ForceRegisterAssemblies(); ObjectFactoryInitPatch.ForceRegisterAssemblies();
Debug.Assert(MyPerGameSettings.BasicGameInfo.GameVersion != null, "MyPerGameSettings.BasicGameInfo.GameVersion != null"); Debug.Assert(MyPerGameSettings.BasicGameInfo.GameVersion != null, "MyPerGameSettings.BasicGameInfo.GameVersion != null");
@@ -297,7 +257,7 @@ namespace Torch
try try
{ {
Console.Title = $"{Config.InstanceName} - Torch {TorchVersion}, SE {GameVersion}"; Console.Title = $"{InstanceName} - Torch {TorchVersion}, SE {GameVersion}";
} }
catch catch
{ {
@@ -311,17 +271,17 @@ namespace Torch
#endif #endif
Log.Info($"Torch Version: {TorchVersion}"); Log.Info($"Torch Version: {TorchVersion}");
Log.Info($"Game Version: {GameVersion}"); Log.Info($"Game Version: {GameVersion}");
Log.Info($"Executing assembly: {Assembly.GetEntryAssembly().FullName}"); Log.Info($"Executing assembly: {Assembly.GetEntryAssembly()?.FullName}");
Log.Info($"Executing directory: {AppDomain.CurrentDomain.BaseDirectory}"); Log.Info($"Executing directory: {AppDomain.CurrentDomain.BaseDirectory}");
Managers.GetManager<PluginManager>().LoadPlugins(); Managers.GetManager<PluginManager>().LoadPlugins();
Game = new VRageGame(this, TweakGameSettings, SteamAppName, SteamAppId, Config.InstancePath, RunArgs); Game = new VRageGame(this, TweakGameSettings, SteamAppName, SteamAppId, InstancePath, RunArgs);
if (!Game.WaitFor(VRageGame.GameState.Stopped)) if (!Game.WaitFor(VRageGame.GameState.Stopped))
Log.Warn("Failed to wait for game to be initialized"); Log.Warn("Failed to wait for game to be initialized");
Managers.Attach(); Managers.Attach();
_init = true; _init = true;
if (GameState >= TorchGameState.Created && GameState < TorchGameState.Unloading) if (GameState is >= TorchGameState.Created and < TorchGameState.Unloading)
// safe to commit here; all important static ctors have run // safe to commit here; all important static ctors have run
PatchManager.CommitInternal(); PatchManager.CommitInternal();
} }
@@ -435,41 +395,5 @@ namespace Torch
/// <inheritdoc/> /// <inheritdoc/>
public event TorchGameStateChangedDel GameStateChanged; public event TorchGameStateChangedDel GameStateChanged;
private static readonly HashSet<Assembly> _registeredCoreAssemblies = new HashSet<Assembly>();
/// <summary>
/// Registers a core (Torch) assembly with the system, including its
/// <see cref="EventManager"/> shims, <see cref="PatchManager"/> shims, and <see cref="ReflectedManager"/> components.
/// </summary>
/// <param name="asm">Assembly to register</param>
internal static void RegisterCoreAssembly(Assembly asm)
{
lock (_registeredCoreAssemblies)
if (_registeredCoreAssemblies.Add(asm))
{
ReflectedManager.Process(asm);
EventManager.AddDispatchShims(asm);
PatchManager.AddPatchShims(asm);
}
}
private static readonly HashSet<Assembly> _registeredAuxAssemblies = new HashSet<Assembly>();
private static readonly TimeSpan _gameStateChangeTimeout = TimeSpan.FromMinutes(1);
/// <summary>
/// Registers an auxillary (plugin) assembly with the system, including its
/// <see cref="ReflectedManager"/> related components.
/// </summary>
/// <param name="asm">Assembly to register</param>
internal static void RegisterAuxAssembly(Assembly asm)
{
lock (_registeredAuxAssemblies)
if (_registeredAuxAssemblies.Add(asm))
{
ReflectedManager.Process(asm);
PatchManager.AddPatchShims(asm);
}
}
} }
} }

View File

@@ -3,12 +3,16 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Torch.Event;
using Torch.Managers.PatchManager;
using VRage.Collections;
namespace Torch.Utils namespace Torch.Utils
{ {
public class TorchLauncher public static class TorchLauncher
{ {
private static readonly Dictionary<string, string> Assemblies = new Dictionary<string, string>(); private static readonly MyConcurrentHashSet<Assembly> RegisteredAssemblies = new();
private static readonly Dictionary<string, string> Assemblies = new();
public static void Launch(params string[] binaryPaths) public static void Launch(params string[] binaryPaths)
{ {
@@ -29,6 +33,15 @@ namespace Torch.Utils
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
} }
public static void RegisterAssembly(Assembly assembly)
{
if (!RegisteredAssemblies.Add(assembly))
return;
ReflectedManager.Process(assembly);
EventManager.AddDispatchShims(assembly);
PatchManager.AddPatchShims(assembly);
}
private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args) private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
{ {
var name = args.Name; var name = args.Name;

View File

@@ -35,11 +35,13 @@ using VRage.Game.ObjectBuilder;
using VRage.Game.SessionComponents; using VRage.Game.SessionComponents;
using VRage.GameServices; using VRage.GameServices;
using VRage.Mod.Io; using VRage.Mod.Io;
using VRage.Platform.Windows;
using VRage.Plugins; using VRage.Plugins;
using VRage.Scripting; using VRage.Scripting;
using VRage.Steam; using VRage.Steam;
using VRage.Utils; using VRage.Utils;
using VRageRender; using VRageRender;
using Game = Sandbox.Engine.Platform.Game;
using MyRenderProfiler = VRage.Profiler.MyRenderProfiler; using MyRenderProfiler = VRage.Profiler.MyRenderProfiler;
namespace Torch namespace Torch
@@ -141,7 +143,9 @@ namespace Torch
private void Create() private void Create()
{ {
bool dedicated = true; bool dedicated = true;
Game.IsDedicated = true;
Environment.SetEnvironmentVariable("SteamAppId", _appSteamId.ToString()); Environment.SetEnvironmentVariable("SteamAppId", _appSteamId.ToString());
MyVRageWindows.Init("SpaceEngineersDedicated", MySandboxGame.Log, null, false);
SpaceEngineersGame.SetupBasicGameInfo(); SpaceEngineersGame.SetupBasicGameInfo();
SpaceEngineersGame.SetupPerGameSettings(); SpaceEngineersGame.SetupPerGameSettings();
MyFinalBuildConstants.APP_VERSION = MyPerGameSettings.BasicGameInfo.GameVersion; MyFinalBuildConstants.APP_VERSION = MyPerGameSettings.BasicGameInfo.GameVersion;