More async init, add proper NLog target for WPF and free console in UI mode
This commit is contained in:
@@ -11,15 +11,16 @@
|
|||||||
<target xsi:type="File" name="chat" layout="${longdate} ${message}" fileName="Logs\Chat.log" />
|
<target xsi:type="File" name="chat" layout="${longdate} ${message}" fileName="Logs\Chat.log" />
|
||||||
<target xsi:type="ColoredConsole" name="console" layout="${var:logStamp} ${logger:shortName=true}: ${var:logContent}" />
|
<target xsi:type="ColoredConsole" name="console" layout="${var:logStamp} ${logger:shortName=true}: ${var:logContent}" />
|
||||||
<target xsi:type="File" name="patch" layout="${var:logContent}" fileName="Logs\patch.log"/>
|
<target xsi:type="File" name="patch" layout="${var:logContent}" fileName="Logs\patch.log"/>
|
||||||
|
<target xsi:type="FlowDocument" name="wpf" layout="${var:logStamp} ${logger:shortName=true}: ${var:logContent}" />
|
||||||
</targets>
|
</targets>
|
||||||
|
|
||||||
<rules>
|
<rules>
|
||||||
<logger name="Keen" minlevel="Warn" writeTo="main"/>
|
<logger name="Keen" minlevel="Warn" writeTo="main"/>
|
||||||
<logger name="Keen" minlevel="Info" writeTo="console"/>
|
<logger name="Keen" minlevel="Info" writeTo="console, wpf"/>
|
||||||
<logger name="Keen" minlevel="Debug" writeTo="keen" final="true" />
|
<logger name="Keen" minlevel="Debug" writeTo="keen" final="true" />
|
||||||
<logger name="Keen" writeTo="null" final="true" />
|
<logger name="Keen" writeTo="null" final="true" />
|
||||||
|
|
||||||
<logger name="*" minlevel="Info" writeTo="main, console" />
|
<logger name="*" minlevel="Info" writeTo="main, console, wpf" />
|
||||||
<logger name="Chat" minlevel="Info" writeTo="chat" />
|
<logger name="Chat" minlevel="Info" writeTo="chat" />
|
||||||
<!--<logger name="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>-->
|
<!--<logger name="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>-->
|
||||||
</rules>
|
</rules>
|
||||||
|
@@ -149,6 +149,11 @@ namespace Torch.API
|
|||||||
/// Path of the dedicated instance folder.
|
/// Path of the dedicated instance folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string InstancePath { get; }
|
string InstancePath { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the server's Init() method has completed.
|
||||||
|
/// </summary>
|
||||||
|
event Action<ITorchServer> Initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
46
Torch.Server/FlowDocumentTarget.cs
Normal file
46
Torch.Server/FlowDocumentTarget.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using NLog;
|
||||||
|
using NLog.Targets;
|
||||||
|
|
||||||
|
namespace Torch.Server
|
||||||
|
{
|
||||||
|
[Target("flowDocument")]
|
||||||
|
public sealed class FlowDocumentTarget : TargetWithLayout
|
||||||
|
{
|
||||||
|
private FlowDocument _document = new FlowDocument { Background = new SolidColorBrush(Colors.Black) };
|
||||||
|
private readonly Paragraph _paragraph = new Paragraph();
|
||||||
|
|
||||||
|
public FlowDocument Document => _document;
|
||||||
|
|
||||||
|
public FlowDocumentTarget()
|
||||||
|
{
|
||||||
|
_document.Blocks.Add(_paragraph);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Write(LogEventInfo logEvent)
|
||||||
|
{
|
||||||
|
_document.Dispatcher.BeginInvoke(() =>
|
||||||
|
{
|
||||||
|
var message = $"{Layout.Render(logEvent)}\n";
|
||||||
|
_paragraph.Inlines.Add(new Run(message) {Foreground = LogLevelColors[logEvent.Level]});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<LogLevel, SolidColorBrush> LogLevelColors = new Dictionary<LogLevel, SolidColorBrush>
|
||||||
|
{
|
||||||
|
[LogLevel.Trace] = new SolidColorBrush(Colors.DimGray),
|
||||||
|
[LogLevel.Debug] = new SolidColorBrush(Colors.DarkGray),
|
||||||
|
[LogLevel.Info] = new SolidColorBrush(Colors.White),
|
||||||
|
[LogLevel.Warn] = new SolidColorBrush(Colors.Magenta),
|
||||||
|
[LogLevel.Error] = new SolidColorBrush(Colors.Yellow),
|
||||||
|
[LogLevel.Fatal] = new SolidColorBrush(Colors.Red),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NLog.Targets;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
|
|
||||||
namespace Torch.Server
|
namespace Torch.Server
|
||||||
@@ -85,23 +86,26 @@ quit";
|
|||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
_server = new TorchServer(_config);
|
_server = new TorchServer(_config);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_server.Init();
|
var init = Task.Run(() => _server.Init());
|
||||||
if (!_config.NoGui)
|
if (!_config.NoGui)
|
||||||
{
|
{
|
||||||
if (_config.Autostart)
|
if (_config.Autostart)
|
||||||
Task.Run(() => _server.Start());
|
init.ContinueWith(x => _server.Start());
|
||||||
|
|
||||||
|
Log.Info("Showing UI");
|
||||||
|
Console.SetOut(TextWriter.Null);
|
||||||
|
NativeMethods.FreeConsole();
|
||||||
new TorchUI(_server).ShowDialog();
|
new TorchUI(_server).ShowDialog();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
init.Wait();
|
||||||
_server.Start();
|
_server.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
catch
|
||||||
{
|
{
|
||||||
if (_server.IsRunning)
|
if (_server.IsRunning)
|
||||||
_server.Stop();
|
_server.Stop();
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
|
using NLog.Targets;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
|
|
||||||
namespace Torch.Server
|
namespace Torch.Server
|
||||||
@@ -14,6 +15,7 @@ namespace Torch.Server
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
Target.Register<FlowDocumentTarget>("FlowDocument");
|
||||||
//Ensures that all the files are downloaded in the Torch directory.
|
//Ensures that all the files are downloaded in the Torch directory.
|
||||||
var workingDir = new FileInfo(typeof(Program).Assembly.Location).Directory.ToString();
|
var workingDir = new FileInfo(typeof(Program).Assembly.Location).Directory.ToString();
|
||||||
var binDir = Path.Combine(workingDir, "DedicatedServer64");
|
var binDir = Path.Combine(workingDir, "DedicatedServer64");
|
||||||
|
@@ -15,6 +15,21 @@
|
|||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
<NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>
|
||||||
</NuGetPackageImportStamp>
|
</NuGetPackageImportStamp>
|
||||||
|
<PublishUrl>publish\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@@ -195,6 +210,7 @@
|
|||||||
<Compile Include="..\Versioning\AssemblyVersion.cs">
|
<Compile Include="..\Versioning\AssemblyVersion.cs">
|
||||||
<Link>Properties\AssemblyVersion.cs</Link>
|
<Link>Properties\AssemblyVersion.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="FlowDocumentTarget.cs" />
|
||||||
<Compile Include="ListBoxExtensions.cs" />
|
<Compile Include="ListBoxExtensions.cs" />
|
||||||
<Compile Include="Managers\EntityControlManager.cs" />
|
<Compile Include="Managers\EntityControlManager.cs" />
|
||||||
<Compile Include="Managers\MultiplayerManagerDedicated.cs" />
|
<Compile Include="Managers\MultiplayerManagerDedicated.cs" />
|
||||||
@@ -411,6 +427,18 @@
|
|||||||
<LastGenOutput>SessionSettingsViewModel.cs</LastGenOutput>
|
<LastGenOutput>SessionSettingsViewModel.cs</LastGenOutput>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(SolutionDir)\TransformOnBuild.targets" />
|
<Import Project="$(SolutionDir)\TransformOnBuild.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
@@ -75,6 +75,8 @@ namespace Torch.Server
|
|||||||
|
|
||||||
private bool _hasRun;
|
private bool _hasRun;
|
||||||
|
|
||||||
|
public event Action<ITorchServer> Initialized;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public InstanceManager DedicatedInstance { get; }
|
public InstanceManager DedicatedInstance { get; }
|
||||||
|
|
||||||
@@ -112,13 +114,15 @@ namespace Torch.Server
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
|
Log.Info("Initializing server");
|
||||||
Sandbox.Engine.Platform.Game.IsDedicated = true;
|
Sandbox.Engine.Platform.Game.IsDedicated = true;
|
||||||
base.Init();
|
base.Init();
|
||||||
Log.Info($"Init server '{Config.InstanceName}' at '{Config.InstancePath}'");
|
|
||||||
|
|
||||||
Managers.GetManager<ITorchSessionManager>().SessionStateChanged += OnSessionStateChanged;
|
Managers.GetManager<ITorchSessionManager>().SessionStateChanged += OnSessionStateChanged;
|
||||||
GetManager<InstanceManager>().LoadInstance(Config.InstancePath);
|
GetManager<InstanceManager>().LoadInstance(Config.InstancePath);
|
||||||
CanRun = true;
|
CanRun = true;
|
||||||
|
Initialized?.Invoke(this);
|
||||||
|
Log.Info($"Initialized server '{Config.InstanceName}' at '{Config.InstancePath}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSessionStateChanged(ITorchSession session, TorchSessionState newState)
|
private void OnSessionStateChanged(ITorchSession session, TorchSessionState newState)
|
||||||
@@ -216,7 +220,8 @@ namespace Torch.Server
|
|||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
SimulationRatio = Sync.ServerSimulationRatio;
|
// Stops 1.00-1.02 flicker.
|
||||||
|
SimulationRatio = Math.Min(Sync.ServerSimulationRatio, 1);
|
||||||
var elapsed = TimeSpan.FromSeconds(Math.Floor(_uptime.Elapsed.TotalSeconds));
|
var elapsed = TimeSpan.FromSeconds(Math.Floor(_uptime.Elapsed.TotalSeconds));
|
||||||
ElapsedPlayTime = elapsed;
|
ElapsedPlayTime = elapsed;
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ namespace Torch.Server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ChatControl : UserControl
|
public partial class ChatControl : UserControl
|
||||||
{
|
{
|
||||||
private TorchBase _server;
|
private ITorchServer _server;
|
||||||
|
|
||||||
public ChatControl()
|
public ChatControl()
|
||||||
{
|
{
|
||||||
@@ -43,13 +43,19 @@ namespace Torch.Server
|
|||||||
|
|
||||||
public void BindServer(ITorchServer server)
|
public void BindServer(ITorchServer server)
|
||||||
{
|
{
|
||||||
_server = (TorchBase)server;
|
_server = server;
|
||||||
|
|
||||||
|
server.Initialized += Server_Initialized ;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Server_Initialized(ITorchServer obj)
|
||||||
|
{
|
||||||
Dispatcher.InvokeAsync(() =>
|
Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
ChatItems.Inlines.Clear();
|
ChatItems.Inlines.Clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
var sessionManager = server.Managers.GetManager<ITorchSessionManager>();
|
var sessionManager = _server.Managers.GetManager<ITorchSessionManager>();
|
||||||
if (sessionManager != null)
|
if (sessionManager != null)
|
||||||
sessionManager.SessionStateChanged += SessionStateChanged;
|
sessionManager.SessionStateChanged += SessionStateChanged;
|
||||||
}
|
}
|
||||||
|
@@ -47,8 +47,12 @@ namespace Torch.Server
|
|||||||
public void BindServer(ITorchServer server)
|
public void BindServer(ITorchServer server)
|
||||||
{
|
{
|
||||||
_server = server;
|
_server = server;
|
||||||
|
_server.Initialized += Server_Initialized ;
|
||||||
|
}
|
||||||
|
|
||||||
var sessionManager = server.Managers.GetManager<ITorchSessionManager>();
|
private void Server_Initialized(ITorchServer obj)
|
||||||
|
{
|
||||||
|
var sessionManager = _server.Managers.GetManager<ITorchSessionManager>();
|
||||||
sessionManager.SessionStateChanged += SessionStateChanged;
|
sessionManager.SessionStateChanged += SessionStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,9 +38,18 @@ namespace Torch.Server.Views
|
|||||||
public void BindServer(ITorchServer server)
|
public void BindServer(ITorchServer server)
|
||||||
{
|
{
|
||||||
_server = server;
|
_server = server;
|
||||||
|
_server.Initialized += Server_Initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Server_Initialized(ITorchServer obj)
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() =>
|
||||||
|
{
|
||||||
_plugins = _server.Managers.GetManager<PluginManager>();
|
_plugins = _server.Managers.GetManager<PluginManager>();
|
||||||
var pluginManager = new PluginManagerViewModel(_plugins);
|
var pluginManager = new PluginManagerViewModel(_plugins);
|
||||||
DataContext = pluginManager;
|
DataContext = pluginManager;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenFolder_OnClick(object sender, RoutedEventArgs e)
|
private void OpenFolder_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
@@ -57,7 +57,7 @@
|
|||||||
</Label>
|
</Label>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TabControl Grid.Row="2" Height="Auto" x:Name="TabControl" Margin="5,10,5,5">
|
<TabControl Grid.Row="2" Height="Auto" x:Name="TabControl" Margin="5,10,5,5">
|
||||||
<TabItem Header="Console">
|
<TabItem Header="Log">
|
||||||
<RichTextBox x:Name="ConsoleText" VerticalScrollBarVisibility="Visible" FontFamily="Consolas"/>
|
<RichTextBox x:Name="ConsoleText" VerticalScrollBarVisibility="Visible" FontFamily="Consolas"/>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem Header="Configuration">
|
<TabItem Header="Configuration">
|
||||||
|
@@ -8,10 +8,12 @@ using System.Timers;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
using NLog;
|
||||||
using Sandbox;
|
using Sandbox;
|
||||||
using Torch.API;
|
using Torch.API;
|
||||||
using Torch.Server.Managers;
|
using Torch.Server.Managers;
|
||||||
@@ -36,6 +38,8 @@ namespace Torch.Server
|
|||||||
DataContext = server;
|
DataContext = server;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
AttachConsole();
|
||||||
|
|
||||||
Left = _config.WindowPosition.X;
|
Left = _config.WindowPosition.X;
|
||||||
Top = _config.WindowPosition.Y;
|
Top = _config.WindowPosition.Y;
|
||||||
Width = _config.WindowSize.X;
|
Width = _config.WindowSize.X;
|
||||||
@@ -45,13 +49,13 @@ namespace Torch.Server
|
|||||||
PlayerList.BindServer(server);
|
PlayerList.BindServer(server);
|
||||||
Plugins.BindServer(server);
|
Plugins.BindServer(server);
|
||||||
LoadConfig((TorchConfig)server.Config);
|
LoadConfig((TorchConfig)server.Config);
|
||||||
|
|
||||||
AttachConsole();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AttachConsole()
|
private void AttachConsole()
|
||||||
{
|
{
|
||||||
Console.SetOut(new MultiTextWriter(new RichTextBoxWriter(ConsoleText), Console.Out));
|
var doc = LogManager.Configuration.FindTargetByName<FlowDocumentTarget>("wpf")?.Document;
|
||||||
|
ConsoleText.Document = doc ?? new FlowDocument(new Paragraph(new Run("No target!")));
|
||||||
|
ConsoleText.TextChanged += (sender, args) => ConsoleText.ScrollToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadConfig(TorchConfig config)
|
public void LoadConfig(TorchConfig config)
|
||||||
|
Reference in New Issue
Block a user