mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
161 lines
5.0 KiB
C#
161 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Robust.Shared.ContentPack;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Log;
|
|
using Robust.Shared.Asynchronous;
|
|
using Robust.Shared.Reflection;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Robust.Server
|
|
{
|
|
|
|
internal static class Program
|
|
{
|
|
|
|
private static bool _hasStarted;
|
|
|
|
internal static void Main(string[] args)
|
|
{
|
|
Start(args, new ServerOptions());
|
|
}
|
|
|
|
internal static void Start(string[] args, ServerOptions options, bool contentStart = false)
|
|
{
|
|
if (_hasStarted)
|
|
{
|
|
throw new InvalidOperationException("Cannot start twice!");
|
|
}
|
|
|
|
_hasStarted = true;
|
|
|
|
if (!CommandLineArgs.TryParse(args, out var parsed))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ParsedMain(parsed, contentStart, options);
|
|
}
|
|
|
|
private static void ParsedMain(CommandLineArgs args, bool contentStart, ServerOptions options)
|
|
{
|
|
ServerWarmup.RunWarmup();
|
|
|
|
Thread.CurrentThread.Name = "Main Thread";
|
|
var deps = IoCManager.InitThread();
|
|
ServerIoC.RegisterIoC(deps);
|
|
deps.BuildGraph();
|
|
SetupLogging(deps);
|
|
InitReflectionManager(deps);
|
|
|
|
var server = deps.Resolve<IBaseServerInternal>();
|
|
var logger = deps.Resolve<ILogManager>().RootSawmill;
|
|
|
|
server.ContentStart = contentStart;
|
|
server.SetCommandLineArgs(args);
|
|
|
|
logger.Info("Server -> Starting");
|
|
|
|
if (server.Start(options))
|
|
{
|
|
logger.Fatal("Server -> Can not start server");
|
|
//Not like you'd see this, haha. Perhaps later for logging.
|
|
return;
|
|
}
|
|
|
|
string strVersion = Assembly.GetExecutingAssembly().GetName().Version!.ToString();
|
|
logger.Info("Server Version " + strVersion + " -> Ready");
|
|
|
|
server.MainLoop();
|
|
|
|
logger.Info("Goodbye.");
|
|
|
|
// Used to dispose of systems that want to be disposed.
|
|
// Such as the log manager.
|
|
deps.Clear();
|
|
}
|
|
|
|
internal static void InitReflectionManager(IDependencyCollection deps)
|
|
{
|
|
// gets a handle to the shared and the current (server) dll.
|
|
deps.Resolve<IReflectionManager>().LoadAssemblies(new List<Assembly>(2)
|
|
{
|
|
AppDomain.CurrentDomain.GetAssemblyByName("Robust.Shared"),
|
|
Assembly.GetExecutingAssembly()
|
|
});
|
|
}
|
|
|
|
internal static void SetupLogging(IDependencyCollection deps)
|
|
{
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
#if WINDOWS_USE_UTF8_CONSOLE
|
|
System.Console.OutputEncoding = Encoding.UTF8;
|
|
#else
|
|
System.Console.OutputEncoding = Encoding.Unicode;
|
|
#endif
|
|
}
|
|
|
|
var mgr = deps.Resolve<ILogManager>();
|
|
var handler = new ConsoleLogHandler();
|
|
mgr.RootSawmill.AddHandler(handler);
|
|
mgr.GetSawmill("res.typecheck").Level = LogLevel.Info;
|
|
mgr.GetSawmill("go.sys").Level = LogLevel.Info;
|
|
mgr.GetSawmill("loc").Level = LogLevel.Error;
|
|
// mgr.GetSawmill("szr").Level = LogLevel.Info;
|
|
|
|
#if DEBUG_ONLY_FCE_INFO
|
|
#if DEBUG_ONLY_FCE_LOG
|
|
var fce = mgr.GetSawmill("fce");
|
|
#endif
|
|
AppDomain.CurrentDomain.FirstChanceException += (sender, args) =>
|
|
{
|
|
// TODO: record FCE stats
|
|
#if DEBUG_ONLY_FCE_LOG
|
|
fce.Fatal(message);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
var uh = mgr.GetSawmill("unhandled");
|
|
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
|
|
{
|
|
var message = ((Exception) args.ExceptionObject).ToString();
|
|
try
|
|
{
|
|
uh.Log(args.IsTerminating ? LogLevel.Fatal : LogLevel.Error, message);
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
// Avoid eating the exception if it's during shutdown and the sawmill is already gone.
|
|
System.Console.WriteLine($"UnhandledException but sawmill is disposed! {message}");
|
|
}
|
|
};
|
|
|
|
var uo = mgr.GetSawmill("unobserved");
|
|
TaskScheduler.UnobservedTaskException += (sender, args) =>
|
|
{
|
|
try
|
|
{
|
|
uo.Error(args.Exception!.ToString());
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
// Avoid eating the exception if it's during shutdown and the sawmill is already gone.
|
|
System.Console.WriteLine($"UnobservedTaskException but sawmill is disposed! {args.Exception}");
|
|
}
|
|
#if EXCEPTION_TOLERANCE
|
|
args.SetObserved(); // don't crash
|
|
#endif
|
|
};
|
|
}
|
|
|
|
}
|
|
|
|
}
|