Skip to content

Commit

Permalink
Merge pull request #10 from zkhssb/new
Browse files Browse the repository at this point in the history
日志更新和一些问题的尝试性修复
  • Loading branch information
zkhssb authored Jan 25, 2024
2 parents cfd8e14 + 2bf3023 commit 5f33821
Show file tree
Hide file tree
Showing 15 changed files with 273 additions and 200 deletions.
2 changes: 1 addition & 1 deletion NectarRCON/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<ui:ControlsDictionary />
<ResourceDictionary Source="pack://application:,,,/NectarRCON;component/Resources/Languages/zh_cn.xaml" />
<ResourceDictionary>
<sys:String x:Key="app.version">1.0.0-beta4</sys:String>
<sys:String x:Key="app.version">1.0.0-beta5</sys:String>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Expand Down
52 changes: 42 additions & 10 deletions NectarRCON/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,42 @@
using NectarRCON.ViewModels;
using NectarRCON.Windows;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Extensions.Logging;
using NectarRCON.Dp;
using Serilog;
using Wpf.Ui.Mvvm.Contracts;
using Wpf.Ui.Mvvm.Services;

namespace NectarRCON;

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App
{
private static readonly IHost _host = Host
private static readonly ILoggerFactory LoggerFactory = new LoggerFactory();
private static string LogFileName = $"logs/program/log{DateTime.Now:yyyyMMddhhmm}.log";

private static readonly IHost Host = Microsoft.Extensions.Hosting.Host
.CreateDefaultBuilder()
.ConfigureLogging(builder =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.File(LogFileName,
rollingInterval: RollingInterval.Infinite, flushToDiskInterval: TimeSpan.FromSeconds(1))
.CreateLogger();

builder.AddSerilog();
})
.ConfigureServices((context, services) =>
{
services.AddSingleton(LoggerFactory);
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));

services.AddHostedService<ApplicationHostService>();

services.AddSingleton<ILanguageService, LanguageService>();
Expand Down Expand Up @@ -52,18 +71,18 @@ public partial class App

services.AddTransient<AddServerWindow>();
services.AddTransient<AddServerWindowViewModel>();

}).Build();

public static T GetService<T>()
where T : class
{
return (_host.Services.GetService(typeof(T)) as T)!;
return (Host.Services.GetService(typeof(T)) as T)!;
}

public static T GetService<T>(Type type)
where T : class
where T : class
{
return (_host.Services.GetServices<T>().Where(t => t.GetType() == type).FirstOrDefault())!;
return Host.Services.GetServices<T>().FirstOrDefault(t => t.GetType() == type)!;
}

private async void OnStartup(object sender, StartupEventArgs e)
Expand All @@ -74,13 +93,26 @@ private async void OnStartup(object sender, StartupEventArgs e)
{
rconEncoding.GetEncoding();
}

await _host.StartAsync();

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
await Host.StartAsync();
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
Log.Error("未经处理的异常: {0}", exception);

MessageBox.Show(
exception +
$"\n\n程序遇到异常,即将退出!\n建议前往Github提交Issue\n请前往日志查看详细信息!\nCheck log: {Path.Combine(Environment.CurrentDirectory, LogFileName).Replace("\\", "/")}",
"程序崩溃", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(1);
}

private async void OnExit(object sender, ExitEventArgs e)
{
await _host.StopAsync();
_host.Dispose();
await Host.StopAsync();
Host.Dispose();
}
}
}
5 changes: 4 additions & 1 deletion NectarRCON/NectarRCON.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<UseWPF>true</UseWPF>
<ApplicationIcon>Resources\Icon.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Version>1.0.0-beta3</Version>
<Version>1.0.0-beta5</Version>
<LangVersion>12</LangVersion>
</PropertyGroup>

Expand All @@ -24,6 +24,9 @@
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="Serilog" Version="3.1.2-dev-02097" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.1-dev-10370" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.1-dev-00972" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
<PackageReference Include="WPF-UI" Version="2.0.3" />
</ItemGroup>
Expand Down
41 changes: 18 additions & 23 deletions NectarRCON/Rcon/RconMultiConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,28 @@
using System.Security.Authentication;
using System.Windows.Controls;
using NectarRCON.Dp;
using Serilog;

namespace NectarRCON.Services
{
/// <summary>
/// Rcon多客户端连接服务
/// </summary>
internal class RconMultiConnection : IRconConnection, IDisposable
internal class RconMultiConnection(
IServerPasswordService serverPasswordService,
ILanguageService languageService,
IRconConnectionInfoService rconConnectionInfoService,
IMessageBoxService messageBoxService)
: IRconConnection, IDisposable
{
private readonly RconSettingsDp _settingsDp = DpFile.LoadSingleton<RconSettingsDp>();
public event MessageEvent? OnMessage;
public event RconEvent? OnClosed;
public event RconEvent? OnConnected;
public event RconEvent? OnConnecting;

private readonly IServerPasswordService _serverPasswordService;
private readonly ILanguageService _languageService;
private readonly IRconConnectionInfoService _rconConnectionInfoService;
private readonly IMessageBoxService _messageBoxService;

private readonly Dictionary<ServerInformation,IRconAdapter> _connections = new();
private bool _isConnecting = false;

public RconMultiConnection(IServerPasswordService serverPasswordService, ILanguageService languageService, IRconConnectionInfoService rconConnectionInfoService, IMessageBoxService messageBoxService)
{
_serverPasswordService = serverPasswordService;
_languageService = languageService;
_rconConnectionInfoService = rconConnectionInfoService;
_messageBoxService = messageBoxService;
}
private bool _isConnecting;

public void Close()
{
Expand All @@ -54,7 +47,7 @@ public void Connect()
{
Close();
_isConnecting = true;
var servers = _rconConnectionInfoService.GetInformation();
var servers = rconConnectionInfoService.GetInformation();
try
{
foreach (ServerInformation info in servers)
Expand All @@ -64,17 +57,19 @@ public void Connect()
string address = DNSHelpers.SRVQuery(info.Address);
if (string.IsNullOrEmpty(address)) // 如果没有SRV记录,就按照原来的样子设置服务器
address = $"{info.Address.Replace("localhost", "127.0.0.1")}:{info.Port}";
ServerPassword? serverPassword = _serverPasswordService.Get(info); // 从设置中读取Rcon密码
ServerPassword? serverPassword = serverPasswordService.Get(info); // 从设置中读取Rcon密码
string password = serverPassword?.Password ?? string.Empty;

// 创建对应的Rcon客户端实例
// 目前支支持了Minecraft,后期会支持更多(嘛..主要是懒)
IRconAdapter adapter = AdapterHelpers.CreateAdapterInstance(info.Adapter)
?? throw new InvalidOperationException($"adapter not found: {info.Adapter}");

string host = address.Split(":")[0];
int port = int.Parse(address.Split(":")[1]);
var host = address.Split(":")[0];
var port = int.Parse(address.Split(":")[1]);

Log.Information("[RconMultiConnection] Connecting to {host}:{port}", host, port);

try
{
adapter.Connect(host, port);
Expand All @@ -89,7 +84,7 @@ public void Connect()
catch (Exception ex)
{
OnClosed?.Invoke(info);
_messageBoxService.Show(ex, $"Server: \"{info.Name}\"");
messageBoxService.Show(ex, $"Server: \"{info.Name}\"");
}

//设置编码
Expand All @@ -105,7 +100,7 @@ public void Connect()
}

public bool IsConnected()
=> _connections.Where(e => e.Value.IsConnected).Any();
=> _connections.Any(e => e.Value.IsConnected);

public bool IsConnecting()
=> _isConnecting;
Expand All @@ -126,12 +121,12 @@ public void Send(string command)
{
connection.Dispose(); // 内部会调用Close
OnClosed?.Invoke(info);
OnMessage?.Invoke(info, _languageService.GetKey("service.rcon.offline"));
OnMessage?.Invoke(info, languageService.GetKey("service.rcon.offline"));
}
}
else
{
OnMessage?.Invoke(info, _languageService.GetKey("service.rcon.offline"));
OnMessage?.Invoke(info, languageService.GetKey("service.rcon.offline"));
}
}
}
Expand Down
48 changes: 24 additions & 24 deletions NectarRCON/Rcon/RconSingleConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,21 @@
using System.Security.Authentication;
using System.Windows;
using NectarRCON.Dp;
using Serilog;

namespace NectarRCON.Services;
public class RconSingleConnection : IRconConnection
public class RconSingleConnection(
IServerPasswordService serverPasswordService,
ILanguageService languageService,
IRconConnectionInfoService rconConnectionInfoService)
: IRconConnection
{
private readonly RconSettingsDp _settingsDp = DpFile.LoadSingleton<RconSettingsDp>();
private readonly IServerPasswordService _serverPasswordService;
private readonly ILanguageService _languageService;
private readonly IRconConnectionInfoService _rconConnectionInfoService;

public RconSingleConnection(IServerPasswordService serverPasswordService, ILanguageService languageService, IRconConnectionInfoService rconConnectionInfoService)
{
_serverPasswordService = serverPasswordService;
_languageService = languageService;
_rconConnectionInfoService = rconConnectionInfoService;
}

private IRconAdapter? _rconClient
= null;

private bool _connecting = false;
private bool _connecting;

public event MessageEvent? OnMessage;
public event RconEvent? OnClosed;
Expand All @@ -51,7 +46,7 @@ public void Close()
}
public void Connect()
{
ServerInformation info = _rconConnectionInfoService.GetLastInformation() ?? throw new ArgumentNullException("Internal error, please try again");
ServerInformation info = rconConnectionInfoService.GetLastInformation() ?? throw new ArgumentNullException("Internal error, please try again");
_connecting = true;
OnConnecting?.Invoke(info);
try
Expand All @@ -64,17 +59,19 @@ public void Connect()
address = $"{info.Address.Replace("localhost", "127.0.0.1")}:{info.Port}";


ServerPassword? serverPassword = _serverPasswordService.Get(info);
ServerPassword? serverPassword = serverPasswordService.Get(info);
string password = serverPassword?.Password ?? string.Empty;

// 创建对应的Rcon客户端实例
// 目前支支持了Minecraft,后期会支持更多(嘛..主要是懒)
_rconClient = AdapterHelpers.CreateAdapterInstance(info.Adapter)
?? throw new InvalidOperationException($"adapter not found: {info.Adapter}");
_rconClient.SetEncoding(_settingsDp.Encoding.GetEncoding());
string host = address.Split(":")[0];
int port = int.Parse(address.Split(":")[1]);
var host = address.Split(":")[0];
var port = int.Parse(address.Split(":")[1]);

Log.Information("[RconSingleConnection] Connecting to {host}:{port}", host, port);

_rconClient.Connect(host, port); // 连接

if (!_rconClient.Authenticate(password))
Expand All @@ -86,8 +83,8 @@ public void Connect()
}
catch (FormatException ex)
{
MessageBox.Show(_languageService.GetKey("ui.text.format_exception")
.Replace("%s", ex.Message), _languageService.GetKey("text.error"), MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show(languageService.GetKey("ui.text.format_exception")
.Replace("%s", ex.Message), languageService.GetKey("text.error"), MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
Expand All @@ -113,36 +110,39 @@ public void Send(string command)
Close();
if (ex is SocketException or IOException && _settingsDp.AutoReconnect)
{
Log.Information("Rcon连接已经断开,开始自动重连...");
try
{
Connect();
}
catch
catch (Exception e)
{
// ignored
Log.Error("自动重连失败 {err}", e);
}

if (IsConnected())
{
try
{
Log.Information("尝试重发命令...");
string result = _rconClient.Run(command);
OnMessage?.Invoke(_serverInformation, result);
Log.Information("重发命令成功 -> {command}", command);
return;
}
catch
catch(Exception e)
{
// ignored
Log.Error("尝试重发命令失败 {err}", e);
}
}
}
MessageBox.Show($"{_languageService.GetKey("text.error")}\n{ex.Message}", ex.GetType().FullName, MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show($"{languageService.GetKey("text.error")}\n{ex.Message}", ex.GetType().FullName, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
else
{
Close();
MessageBox.Show($"{_languageService.GetKey("text.server.not_connect.text")}", _languageService.GetKey("text.error"), MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show($"{languageService.GetKey("text.server.not_connect.text")}", languageService.GetKey("text.error"), MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
2 changes: 2 additions & 0 deletions NectarRCON/Resources/Languages/en_us.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<sys:String x:Key="ui.settings.rcon.auto_reconnect">Auto Reconnect</sys:String>
<sys:String x:Key="ui.settings.rcon.is_keep_connection_window_open">KeepConnectionWindowOpen</sys:String>
<sys:String x:Key="ui.settings.rcon.encoding">Encoding</sys:String>
<sys:String x:Key="ui.menu.log.clear_program">Clear Program Logs</sys:String>
<sys:String x:Key="ui.menu.log.clear_program.ask">Do you want to clear program logs?</sys:String>

<sys:String x:Key="ui.server_page.menu.open">Connect</sys:String>
<sys:String x:Key="ui.server_page.menu.edit">Edit</sys:String>
Expand Down
2 changes: 2 additions & 0 deletions NectarRCON/Resources/Languages/zh_cn.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<sys:String x:Key="ui.settings.rcon.auto_reconnect">掉线自动重连</sys:String>
<sys:String x:Key="ui.settings.rcon.is_keep_connection_window_open">掉线不回到主页</sys:String>
<sys:String x:Key="ui.settings.rcon.encoding">文本编码</sys:String>
<sys:String x:Key="ui.menu.log.clear_program">清理程序日志</sys:String>
<sys:String x:Key="ui.menu.log.clear_program.ask">是否清理程序日志?</sys:String>

<sys:String x:Key="ui.server_page.menu.open">连接</sys:String>
<sys:String x:Key="ui.server_page.menu.edit">编辑</sys:String>
Expand Down
2 changes: 2 additions & 0 deletions NectarRCON/Resources/Languages/zh_tw.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<sys:String x:Key="ui.settings.rcon.auto_reconnect">斷綫自動重連</sys:String>
<sys:String x:Key="ui.settings.rcon.is_keep_connection_window_open">斷線不回到主頁</sys:String>
<sys:String x:Key="ui.settings.rcon.encoding">文本編碼</sys:String>
<sys:String x:Key="ui.menu.log.clear_program">清除程式日誌</sys:String>
<sys:String x:Key="ui.menu.log.clear_program.ask">您是否要清除程式日誌?</sys:String>

<sys:String x:Key="ui.server_page.menu.open">連線</sys:String>
<sys:String x:Key="ui.server_page.menu.edit">編輯</sys:String>
Expand Down
Loading

0 comments on commit 5f33821

Please sign in to comment.