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="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>
|
||||
|
@@ -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>
|
||||
|
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.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();
|
||||
|
@@ -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");
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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">
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user