/// <inheritdoc /> public async Task QueryServerAsync(ServerConnectionDetails connectionDetails, PingServerDelegate pingCallback, ServerStatusDelegate statusCallBack) { ManualResetEventSlim ar = new ManualResetEventSlim(false); Stopwatch sw = new Stopwatch(); long pingTime = 0; /*var result = await ResolveHostnameAsync(hostname); * if (!result.Success) * { * statusCallBack?.Invoke(new ServerQueryResponse(false, "multiplayer.status.cannot_resolve", new ServerQueryStatus() * { * Delay = sw.ElapsedMilliseconds, * Success = false, * * EndPoint = null, * Address = hostname, * Port = port * })); * * return; * }*/ using (MiNET.Utils.DedicatedThreadPool threadPool = new MiNET.Utils.DedicatedThreadPool(new MiNET.Utils.DedicatedThreadPoolSettings(1, MiNET.Utils.ThreadType.Background, "ServerPingThread"))) { BedrockClient client = null; try { IPEndPoint serverEndpoint = new IPEndPoint(connectionDetails.EndPoint.Address, (int)connectionDetails.EndPoint.Port); client = new BedrockClient(Game, null, serverEndpoint, new PlayerProfile(string.Empty, $"Pinger{serverEndpoint.ToString()}", $"Pinger{serverEndpoint.ToString()}", null, null, null, "xbox"), threadPool, null) { //IgnoreUnConnectedPong = true }; client.Connection.AutoConnect = false; BedrockMotd motd = new BedrockMotd(string.Empty); client.OnMotdReceivedHandler += (sender, m) => { motd = m; pingTime = m.Latency; ar.Set(); pingCallback.Invoke(new ServerPingResponse(true, pingTime)); }; client.Start(ar); //client.SendUnconnectedPing(); sw.Restart(); //ar.WaitAsync().Wait(TimeSpan.FromMilliseconds(10000)); if (await WaitHandleHelpers.FromWaitHandle(ar.WaitHandle, TimeSpan.FromMilliseconds(10000))) { client.Close(); // var m = new BedrockMotd(client.Connection.RemoteServerName); var compatability = CompatibilityResult.Unknown; if (motd.ProtocolVersion == McpeProtocolInfo.ProtocolVersion) { compatability = CompatibilityResult.Compatible; } /*else if (MathF.Abs(motd.ProtocolVersion - McpeProtocolInfo.ProtocolVersion) < 3) //Ehh? * { * compatability = CompatibilityResult.Unknown; * }*/ else if (motd.ProtocolVersion < McpeProtocolInfo.ProtocolVersion) { // compatability = CompatibilityResult.OutdatedServer; } else if (motd.ProtocolVersion > McpeProtocolInfo.ProtocolVersion) { // compatability = CompatibilityResult.OutdatedClient; } statusCallBack?.Invoke(new ServerQueryResponse(true, new ServerQueryStatus() { EndPoint = motd.ServerEndpoint, Delay = pingTime, Success = true, Address = connectionDetails.Hostname, Port = (ushort)connectionDetails.EndPoint.Port, WaitingOnPing = false, Query = new ServerQuery() { Players = new Players() { Max = motd.MaxPlayers, Online = motd.Players }, Version = new API.Services.Version() { Protocol = motd.ProtocolVersion, Name = motd.ClientVersion, Compatibility = compatability }, Description = new Description() { Text = motd.MOTD }, Modinfo = null, Favicon = null } })); } else { statusCallBack?.Invoke(new ServerQueryResponse(false, "multiplayer.status.cannot_connect", new ServerQueryStatus() { EndPoint = serverEndpoint, Delay = sw.ElapsedMilliseconds, Success = false, Address = connectionDetails.Hostname, Port = (ushort)connectionDetails.EndPoint.Port, WaitingOnPing = false })); } } catch (Exception e) { Log.Error($"Could not get bedrock query: {e.ToString()}"); statusCallBack?.Invoke(new ServerQueryResponse(false, "Failed to connect...", new ServerQueryStatus() { Success = false })); } finally { client?.Dispose(); } } }
/// <inheritdoc /> public async Task QueryServerAsync(ServerConnectionDetails connectionDetails, PingServerDelegate pingCallback, ServerStatusDelegate statusCallBack) { ManualResetEventSlim ar = new ManualResetEventSlim(false); Stopwatch sw = new Stopwatch(); long pingTime = 0; BedrockClient client = null; try { IPEndPoint serverEndpoint = new IPEndPoint( connectionDetails.EndPoint.Address, (int)connectionDetails.EndPoint.Port); client = new BedrockClient( Game, serverEndpoint, new PlayerProfile( string.Empty, $"Pinger{serverEndpoint.ToString()}", $"Pinger{serverEndpoint.ToString()}", null, null, null), null) { //IgnoreUnConnectedPong = true }; client.Connection.AutoConnect = false; BedrockMotd motd = new BedrockMotd(string.Empty); client.OnMotdReceivedHandler += (sender, m) => { motd = m; pingTime = m.Latency; ar.Set(); pingCallback.Invoke(new ServerPingResponse(true, pingTime)); }; client.Start(ar); sw.Restart(); if (await WaitHandleHelpers.FromWaitHandle(ar.WaitHandle, TimeSpan.FromMilliseconds(2500))) { client.Close(); var compatability = CompatibilityResult.Unknown; if (motd.ProtocolVersion == McpeProtocolInfo.ProtocolVersion) { compatability = CompatibilityResult.Compatible; } statusCallBack?.Invoke( new ServerQueryResponse( true, new ServerQueryStatus() { EndPoint = motd.ServerEndpoint, Delay = pingTime, Success = true, Address = connectionDetails.Hostname, Port = (ushort)connectionDetails.EndPoint.Port, WaitingOnPing = false, Query = new ServerQuery() { Players = new Players() { Max = motd.MaxPlayers, Online = motd.Players }, Version = new API.Services.Version() { Protocol = motd.ProtocolVersion, Name = motd.ClientVersion, Compatibility = compatability }, Description = new Description() { Text = motd.MOTD }, Modinfo = null, Favicon = null } })); } else { statusCallBack?.Invoke( new ServerQueryResponse( false, "multiplayer.status.cannot_connect", new ServerQueryStatus() { EndPoint = serverEndpoint, Delay = sw.ElapsedMilliseconds, Success = false, Address = connectionDetails.Hostname, Port = (ushort)connectionDetails.EndPoint.Port, WaitingOnPing = false })); } } catch (Exception e) { Log.Error($"Could not get bedrock query: {e.ToString()}"); statusCallBack?.Invoke( new ServerQueryResponse(false, "Failed to connect...", new ServerQueryStatus() { Success = false })); } finally { client?.Close(); client?.Dispose(); } }
private async Task QueryPeServerAsync(string hostname, ushort port, PingServerDelegate pingCallback, ServerStatusDelegate statusCallBack) { ManualResetEventSlim ar = new ManualResetEventSlim(false); Stopwatch sw = new Stopwatch(); long pingTime = 0; var result = await ResolveHostnameAsync(hostname); if (!result.Success) { statusCallBack?.Invoke(new ServerQueryResponse(false, "multiplayer.status.cannot_resolve", new ServerQueryStatus() { Delay = sw.ElapsedMilliseconds, Success = false, EndPoint = null, Address = hostname, Port = port })); return; } using (DedicatedThreadPool threadPool = new DedicatedThreadPool(new DedicatedThreadPoolSettings(1, ThreadType.Background, "ServerPingThread"))) { BedrockClient client = null; try { IPEndPoint serverEndpoint = new IPEndPoint(result.Result, (int)port); client = new BedrockClient(Alex, null, serverEndpoint, new PlayerProfile(string.Empty, $"Pinger{serverEndpoint.ToString()}", $"Pinger{serverEndpoint.ToString()}", null, null, null, true), threadPool, null) { //IgnoreUnConnectedPong = true }; client.Connection.AutoConnect = false; BedrockMotd motd = new BedrockMotd(string.Empty); client.OnMotdReceivedHandler += (sender, m) => { motd = m; pingTime = m.Latency; ar.Set(); pingCallback.Invoke(new ServerPingResponse(true, pingTime)); }; client.Start(ar); //client.SendUnconnectedPing(); sw.Restart(); //ar.WaitAsync().Wait(TimeSpan.FromMilliseconds(10000)); if (await WaitHandleHelpers.FromWaitHandle(ar.WaitHandle, TimeSpan.FromMilliseconds(10000))) { client.Close(); // var m = new BedrockMotd(client.Connection.RemoteServerName); statusCallBack?.Invoke(new ServerQueryResponse(true, new ServerQueryStatus() { EndPoint = motd.ServerEndpoint, Delay = pingTime, Success = true, Address = hostname, Port = port, WaitingOnPing = false, Query = new ServerQuery() { Players = new Players() { Max = motd.MaxPlayers, Online = motd.Players }, Version = new API.Services.Version() { Protocol = motd.ProtocolVersion, }, Description = new Description() { Text = motd.MOTD }, Modinfo = null, Favicon = null } })); } else { statusCallBack?.Invoke(new ServerQueryResponse(false, "multiplayer.status.cannot_connect", new ServerQueryStatus() { EndPoint = serverEndpoint, Delay = sw.ElapsedMilliseconds, Success = false, Address = hostname, Port = port, WaitingOnPing = false })); } } catch (Exception e) { Log.Error($"Could not get bedrock query: {e.ToString()}"); statusCallBack?.Invoke(new ServerQueryResponse(false, "Failed to connect...", new ServerQueryStatus() { Success = false })); } finally { client?.Dispose(); } } }
/// <inheritdoc /> public async Task StartLanDiscovery(CancellationToken cancellationToken, LandDiscoveryDelegate callback = null) { if (callback == null) { return; } Stopwatch sw = new Stopwatch(); sw.Start(); RaknetConnection connection = new RaknetConnection(); connection.RemoteEndpoint = null; connection.AutoConnect = false; connection.Start(); while (!connection.FoundServer) { if ((!sw.IsRunning || sw.ElapsedMilliseconds > 100)) { sw.Restart(); connection.SendUnconnectedPingInternal(null); } if (cancellationToken.IsCancellationRequested || connection.FoundServer) { break; } await Task.Delay(200); } sw.Stop(); var remoteEndPoint = connection.RemoteEndpoint; var remoteServerName = connection.RemoteServerName; var ping = sw.ElapsedMilliseconds; connection.Session?.Close(); connection.Stop(); var motd = new BedrockMotd(remoteServerName); await callback.Invoke( new LanDiscoveryResult( remoteEndPoint, new ServerPingResponse(connection.FoundServer, ping), new ServerQueryResponse( connection.FoundServer, new ServerQueryStatus() { Address = remoteEndPoint.Address.ToString(), Delay = sw.ElapsedMilliseconds, Port = (ushort)remoteEndPoint.Port, Query = new ServerQuery() { Players = new Players() { Max = motd.MaxPlayers, Online = motd.Players }, Version = new API.Services.Version() { Protocol = motd.ProtocolVersion, Name = motd.ClientVersion, Compatibility = CompatibilityResult.Compatible }, Description = new Description() { Text = motd.MOTD }, Modinfo = null, Favicon = null }, WaitingOnPing = false, Success = true, EndPoint = remoteEndPoint }))); }