More async init, add proper NLog target for WPF and free console in UI mode

This commit is contained in:
John Gross
2018-01-21 21:23:11 -08:00
parent c5e1dd7c3a
commit 0328876d50
12 changed files with 133 additions and 19 deletions

View File

@@ -11,15 +11,16 @@
<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="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>
<rules>
<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" 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="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>-->
</rules>

View File

@@ -149,6 +149,11 @@ namespace Torch.API
/// Path of the dedicated instance folder.
/// </summary>
string InstancePath { get; }
/// <summary>
/// Raised when the server's Init() method has completed.
/// </summary>
event Action<ITorchServer> Initialized;
}
/// <summary>

View 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),
};
}
}

View File

@@ -12,6 +12,7 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using NLog;
using NLog.Targets;
using Torch.Utils;
namespace Torch.Server
@@ -85,23 +86,26 @@ quit";
public void Run()
{
_server = new TorchServer(_config);
try
{
_server.Init();
var init = Task.Run(() => _server.Init());
if (!_config.NoGui)
{
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();
}
else
{
init.Wait();
_server.Start();
}
}
finally
catch
{
if (_server.IsRunning)
_server.Stop();

View File

@@ -2,6 +2,7 @@
using System.IO;
using System.Reflection;
using System.ServiceProcess;
using NLog.Targets;
using Torch.Utils;
namespace Torch.Server
@@ -14,6 +15,7 @@ namespace Torch.Server
[STAThread]
public static void Main(string[] args)
{
Target.Register<FlowDocumentTarget>("FlowDocument");
//Ensures that all the files are downloaded in the Torch directory.
var workingDir = new FileInfo(typeof(Program).Assembly.Location).Directory.ToString();
var binDir = Path.Combine(workingDir, "DedicatedServer64");

View File

@@ -15,6 +15,21 @@
<TargetFrameworkProfile />
<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 Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
@@ -195,6 +210,7 @@
<Compile Include="..\Versioning\AssemblyVersion.cs">
<Link>Properties\AssemblyVersion.cs</Link>
</Compile>
<Compile Include="FlowDocumentTarget.cs" />
<Compile Include="ListBoxExtensions.cs" />
<Compile Include="Managers\EntityControlManager.cs" />
<Compile Include="Managers\MultiplayerManagerDedicated.cs" />
@@ -411,6 +427,18 @@
<LastGenOutput>SessionSettingsViewModel.cs</LastGenOutput>
</Content>
</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="$(SolutionDir)\TransformOnBuild.targets" />
<PropertyGroup>

View File

@@ -75,6 +75,8 @@ namespace Torch.Server
private bool _hasRun;
public event Action<ITorchServer> Initialized;
/// <inheritdoc />
public InstanceManager DedicatedInstance { get; }
@@ -112,13 +114,15 @@ namespace Torch.Server
/// <inheritdoc />
public override void Init()
{
Log.Info("Initializing server");
Sandbox.Engine.Platform.Game.IsDedicated = true;
base.Init();
Log.Info($"Init server '{Config.InstanceName}' at '{Config.InstancePath}'");
Managers.GetManager<ITorchSessionManager>().SessionStateChanged += OnSessionStateChanged;
GetManager<InstanceManager>().LoadInstance(Config.InstancePath);
CanRun = true;
Initialized?.Invoke(this);
Log.Info($"Initialized server '{Config.InstanceName}' at '{Config.InstancePath}'");
}
private void OnSessionStateChanged(ITorchSession session, TorchSessionState newState)
@@ -216,7 +220,8 @@ namespace Torch.Server
public override void 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));
ElapsedPlayTime = elapsed;

View File

@@ -34,7 +34,7 @@ namespace Torch.Server
/// </summary>
public partial class ChatControl : UserControl
{
private TorchBase _server;
private ITorchServer _server;
public ChatControl()
{
@@ -43,13 +43,19 @@ namespace Torch.Server
public void BindServer(ITorchServer server)
{
_server = (TorchBase)server;
_server = server;
server.Initialized += Server_Initialized ;
}
private void Server_Initialized(ITorchServer obj)
{
Dispatcher.InvokeAsync(() =>
{
ChatItems.Inlines.Clear();
});
var sessionManager = server.Managers.GetManager<ITorchSessionManager>();
var sessionManager = _server.Managers.GetManager<ITorchSessionManager>();
if (sessionManager != null)
sessionManager.SessionStateChanged += SessionStateChanged;
}

View File

@@ -47,8 +47,12 @@ namespace Torch.Server
public void BindServer(ITorchServer 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;
}

View File

@@ -38,9 +38,18 @@ namespace Torch.Server.Views
public void BindServer(ITorchServer server)
{
_server = server;
_server.Initialized += Server_Initialized;
}
private void Server_Initialized(ITorchServer obj)
{
Dispatcher.InvokeAsync(() =>
{
_plugins = _server.Managers.GetManager<PluginManager>();
var pluginManager = new PluginManagerViewModel(_plugins);
DataContext = pluginManager;
});
}
private void OpenFolder_OnClick(object sender, RoutedEventArgs e)

View File

@@ -57,7 +57,7 @@
</Label>
</StackPanel>
<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"/>
</TabItem>
<TabItem Header="Configuration">

View File

@@ -8,10 +8,12 @@ using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NLog;
using Sandbox;
using Torch.API;
using Torch.Server.Managers;
@@ -36,6 +38,8 @@ namespace Torch.Server
DataContext = server;
InitializeComponent();
AttachConsole();
Left = _config.WindowPosition.X;
Top = _config.WindowPosition.Y;
Width = _config.WindowSize.X;
@@ -45,13 +49,13 @@ namespace Torch.Server
PlayerList.BindServer(server);
Plugins.BindServer(server);
LoadConfig((TorchConfig)server.Config);
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)