初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
using PCL.Core.App.Localization;
|
||||
using PCL.Core.Link.McPing;
|
||||
using PCL.Core.Link.McPing.Model;
|
||||
using PCL.Core.Minecraft;
|
||||
using PCL.Core.UI;
|
||||
|
||||
namespace PCL;
|
||||
|
||||
public partial class MinecraftServer : Grid
|
||||
{
|
||||
private const string fallbackImageUri =
|
||||
"pack://application:,,,/Plain Craft Launcher 2;component/Images/Icons/DefaultServer.png";
|
||||
|
||||
private static readonly DependencyProperty AddressProperty = DependencyProperty.Register(nameof(Address),
|
||||
typeof(string), typeof(MinecraftServer), new PropertyMetadata(string.Empty, OnAddressChanged));
|
||||
|
||||
public MinecraftServer()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public string Address
|
||||
{
|
||||
get => (string)(GetValue(AddressProperty));
|
||||
set => SetValue(AddressProperty, value);
|
||||
}
|
||||
|
||||
private static void OnAddressChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var server = (MinecraftServer)d;
|
||||
d.Dispatcher.BeginInvoke(new Func<Task>(() => server.UpdateServerInfoAsync(e.NewValue?.ToString())));
|
||||
}
|
||||
|
||||
public async Task UpdateServerInfoAsync(string address)
|
||||
{
|
||||
if (address is null)
|
||||
return;
|
||||
address = address.Replace(":", ":");
|
||||
// 预先重置UI状态
|
||||
LabServerDesc.Foreground = Brushes.White;
|
||||
LabServerDesc.Text = Lang.Text("Tools.ServerQuery.State.Querying");
|
||||
LabServerPlayer.Text = "-/-";
|
||||
LabServerPlayer.ToolTip = null;
|
||||
LabServerLatency.Text = string.Empty;
|
||||
ImageLoaderHelper.SetFallbackImage(ImgServerLogo, fallbackImageUri);
|
||||
|
||||
try
|
||||
{
|
||||
// 获取可达地址(DNS解析)
|
||||
var addr = await ServerAddressResolver.GetResolvedServerAddressAsync(address);
|
||||
|
||||
// Ping服务器
|
||||
using (var query = McPingServiceFactory.CreateService(addr.Host, addr.Ip, addr.Port))
|
||||
{
|
||||
var ret = await query.PingAsync();
|
||||
|
||||
if (ret is null) throw new Exception(Lang.Text("Tools.ServerQuery.State.NoInfo"));
|
||||
|
||||
// 处理服务器图标
|
||||
await ImageLoaderHelper.SetServerLogoAsync(ret.Favicon, ImgServerLogo);
|
||||
|
||||
// 更新UI
|
||||
UpdateServerStatus(ret);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(ex, "[MinecraftServer] 信息查询失败");
|
||||
LabServerDesc.Text = Lang.Text("Tools.ServerQuery.Error.UnableToConnect", ex.Message);
|
||||
LabServerDesc.Foreground = Brushes.Red;
|
||||
ImageLoaderHelper.SetFallbackImage(ImgServerLogo, fallbackImageUri);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateServerStatus(McPingResult ret)
|
||||
{
|
||||
// 延迟颜色判断
|
||||
var latencyColor = ret.Latency < 150 ? "a" : ret.Latency < 400 ? "6" : "c";
|
||||
|
||||
// 更新描述
|
||||
LabServerDesc.Text = Lang.Text("Tools.ServerQuery.Title.MinecraftServer");
|
||||
MotdRenderer.RenderMotd(ret.Description, false, 2, 14);
|
||||
MotdRenderer.RenderCanvas();
|
||||
|
||||
// 更新玩家信息
|
||||
LabServerPlayer.Text = $"{ret.Players.Online}/{ret.Players.Max}";
|
||||
ModStyle.MinecraftFormatter.SetColorfulTextLab($"§{latencyColor}{ret.Latency}ms", LabServerLatency, false);
|
||||
|
||||
// 玩家列表提示
|
||||
if (ret.Players.Samples.Any())
|
||||
{
|
||||
LabServerPlayer.ToolTip = string.Join("\r\n", ret.Players.Samples.Select(x => x.Name));
|
||||
ToolTipService.SetPlacement(LabServerPlayer, PlacementMode.Mouse);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user