Exemple #1
0
        /// <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();
                }
            }
        }
Exemple #2
0
        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();
                }
            }
        }
        private static async Task QueryJavaServerAsync(ServerConnectionDetails connectionDetails, PingServerDelegate pingCallback, ServerStatusDelegate statusCallBack)
        {
            CancellationTokenSource cts = new CancellationTokenSource(10000);

            using TcpClient client = new TcpClient();

            IPEndPoint endPoint     = null;
            var        sw           = Stopwatch.StartNew();
            string     jsonResponse = null;

            try
            {
                bool waitingOnPing = true;
                await client.ConnectAsync(connectionDetails.EndPoint.Address, connectionDetails.EndPoint.Port);

                endPoint = client.Client.RemoteEndPoint as IPEndPoint;

                if (client.Connected)
                {
                    //conn = new NetConnection(Direction.ClientBound, client.Client);
                    //conn.LogExceptions = false;
                    using (var conn = new NetConnection(PacketDirection.ClientBound, client.Client)
                    {
                        LogExceptions = true
                    })
                    {
                        long pingId     = Rnd.NextUInt();
                        long pingResult = 0;

                        EventWaitHandle ar = new EventWaitHandle(false, EventResetMode.AutoReset);

                        conn.OnPacketReceived += (sender, args) =>
                        {
                            if (args.Packet is ResponsePacket responsePacket)
                            {
                                jsonResponse = responsePacket.ResponseMsg;

                                if (pingCallback != null)
                                {
                                    conn.SendPacket(new PingPacket()
                                    {
                                        Payload = pingId,
                                    });

                                    sw.Restart();
                                }

                                ar.Set();
                            }
                            else if (args.Packet is PingPacket pong)
                            {
                                pingResult = sw.ElapsedMilliseconds;
                                if (pong.Payload == pingId)
                                {
                                    waitingOnPing = false;
                                    pingCallback?.Invoke(new ServerPingResponse(true, sw.ElapsedMilliseconds));
                                }
                                else
                                {
                                    waitingOnPing = false;
                                    pingCallback?.Invoke(new ServerPingResponse(true, sw.ElapsedMilliseconds));
                                }

                                ar.Set();
                            }
                        };

                        bool connectionClosed = false;
                        conn.OnConnectionClosed += (sender, args) =>
                        {
                            if (!cts.IsCancellationRequested)
                            {
                                cts.Cancel();
                            }

                            connectionClosed = true;
                            ar.Set();
                        };

                        conn.Initialize();

                        conn.SendPacket(new HandshakePacket()
                        {
                            NextState       = ConnectionState.Status,
                            ServerAddress   = connectionDetails.Hostname,
                            ServerPort      = (ushort)connectionDetails.EndPoint.Port,
                            ProtocolVersion = JavaProtocol.ProtocolVersion
                        });

                        conn.ConnectionState = ConnectionState.Status;

                        conn.SendPacket(new RequestPacket());

                        if (await WaitHandleHelpers.FromWaitHandle(ar, TimeSpan.FromMilliseconds(10000), cts.Token) &&
                            !connectionClosed && jsonResponse != null)
                        {
                            long timeElapsed = sw.ElapsedMilliseconds;
                            //  Log.Debug($"Server json: " + jsonResponse);
                            var query = ServerQuery.FromJson(jsonResponse);

                            if (query.Version.Protocol == JavaProtocol.ProtocolVersion)
                            {
                                query.Version.Compatibility = CompatibilityResult.Compatible;
                            }
                            else if (query.Version.Protocol < JavaProtocol.ProtocolVersion)
                            {
                                query.Version.Compatibility = CompatibilityResult.OutdatedServer;
                            }
                            else if (query.Version.Protocol > JavaProtocol.ProtocolVersion)
                            {
                                query.Version.Compatibility = CompatibilityResult.OutdatedClient;
                            }

                            var r = new ServerQueryStatus()
                            {
                                Delay         = timeElapsed,
                                Success       = true,
                                WaitingOnPing = pingCallback != null && waitingOnPing,

                                EndPoint = endPoint,
                                Address  = connectionDetails.Hostname,
                                Port     = (ushort)connectionDetails.EndPoint.Port,

                                Query = query
                            };

                            statusCallBack?.Invoke(new ServerQueryResponse(true, r));

                            if (waitingOnPing && pingCallback != null)
                            {
                                await WaitHandleHelpers.FromWaitHandle(ar, TimeSpan.FromSeconds(1000));
                            }
                        }
                        else
                        {
                            statusCallBack?.Invoke(new ServerQueryResponse(false, "multiplayer.status.cannot_connect",
                                                                           new ServerQueryStatus()
                            {
                                EndPoint = endPoint,
                                Delay    = sw.ElapsedMilliseconds,
                                Success  = false,

                                /* Motd = motd.MOTD,
                                 * ProtocolVersion = motd.ProtocolVersion,
                                 * MaxNumberOfPlayers = motd.MaxPlayers,
                                 * Version = motd.ClientVersion,
                                 * NumberOfPlayers = motd.Players,*/

                                Address       = connectionDetails.Hostname,
                                Port          = (ushort)connectionDetails.EndPoint.Port,
                                WaitingOnPing = false
                            }));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                cts.Cancel();

                if (sw.IsRunning)
                {
                    sw.Stop();
                }

                // client?.Dispose();

                string msg = ex.Message;
                if (ex is SocketException)
                {
                    msg = $"multiplayer.status.cannot_connect";
                }
                else
                {
                    Log.Error(ex, $"Could not get server query result!");
                }

                statusCallBack?.Invoke(new ServerQueryResponse(false, msg, new ServerQueryStatus()
                {
                    Delay   = sw.ElapsedMilliseconds,
                    Success = false,

                    EndPoint = endPoint,
                    Address  = connectionDetails.Hostname,
                    Port     = (ushort)connectionDetails.EndPoint.Port
                }));
            }
            finally
            {
                //conn?.Stop();
                //conn?.Dispose();
                //conn?.Dispose();
                //	client?.Close();
            }
        }
Exemple #4
0
        private static async Task QueryJavaServerAsync(string hostname, ushort port, PingServerDelegate pingCallback, ServerStatusDelegate statusCallBack)
        {
            IPEndPoint endPoint     = null;
            var        sw           = Stopwatch.StartNew();
            string     jsonResponse = null;

            try
            {
                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;
                }

                bool waitingOnPing = true;
                using (TcpClient client = new TcpClient())
                {
                    await client.ConnectAsync(result.Result, port);

                    endPoint = client.Client.RemoteEndPoint as IPEndPoint;

                    if (client.Connected)
                    {
                        //conn = new NetConnection(Direction.ClientBound, client.Client);
                        //conn.LogExceptions = false;
                        using (var conn = new NetConnection(Direction.ClientBound, client.Client)
                        {
                            LogExceptions = true
                        })
                        {
                            long pingId = Rnd.NextUInt();

                            EventWaitHandle ar = new EventWaitHandle(false, EventResetMode.AutoReset);

                            conn.OnPacketReceived += (sender, args) =>
                            {
                                if (args.Packet is ResponsePacket responsePacket)
                                {
                                    jsonResponse = responsePacket.ResponseMsg;
                                    ar.Set();
                                }
                                else if (args.Packet is PingPacket pong)
                                {
                                    if (pong.Payload == pingId)
                                    {
                                        waitingOnPing = false;
                                        pingCallback?.Invoke(new ServerPingResponse(true, sw.ElapsedMilliseconds));
                                    }
                                    else
                                    {
                                        waitingOnPing = false;
                                        pingCallback?.Invoke(new ServerPingResponse(true, sw.ElapsedMilliseconds));
                                    }
                                }
                            };

                            bool connectionClosed = false;
                            conn.OnConnectionClosed += (sender, args) =>
                            {
                                connectionClosed = true;
                                ar.Set();
                            };

                            conn.Initialize();

                            conn.SendPacket(new HandshakePacket()
                            {
                                NextState       = ConnectionState.Status,
                                ServerAddress   = hostname,
                                ServerPort      = port,
                                ProtocolVersion = JavaProtocol.ProtocolVersion
                            });

                            conn.ConnectionState = ConnectionState.Status;

                            conn.SendPacket(new RequestPacket());

                            if (await WaitHandleHelpers.FromWaitHandle(ar, TimeSpan.FromMilliseconds(10000)) &&
                                !connectionClosed && jsonResponse != null)
                            {
                                long timeElapsed = sw.ElapsedMilliseconds;
                                //  Log.Debug($"Server json: " + jsonResponse);
                                var query = ServerQuery.FromJson(jsonResponse);

                                if (pingCallback != null)
                                {
                                    conn.SendPacket(new PingPacket()
                                    {
                                        Payload = pingId,
                                    });

                                    sw.Restart();
                                }

                                var r = new ServerQueryStatus()
                                {
                                    Delay         = timeElapsed,
                                    Success       = true,
                                    WaitingOnPing = pingCallback != null && !waitingOnPing,

                                    EndPoint = endPoint,
                                    Address  = hostname,
                                    Port     = port,

                                    Query = query
                                };

                                statusCallBack?.Invoke(new ServerQueryResponse(true, r));
                            }
                            else
                            {
                                statusCallBack?.Invoke(new ServerQueryResponse(false, "multiplayer.status.cannot_connect",
                                                                               new ServerQueryStatus()
                                {
                                    EndPoint = endPoint,
                                    Delay    = sw.ElapsedMilliseconds,
                                    Success  = false,

                                    /* Motd = motd.MOTD,
                                     * ProtocolVersion = motd.ProtocolVersion,
                                     * MaxNumberOfPlayers = motd.MaxPlayers,
                                     * Version = motd.ClientVersion,
                                     * NumberOfPlayers = motd.Players,*/

                                    Address       = hostname,
                                    Port          = port,
                                    WaitingOnPing = false
                                }));
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (sw.IsRunning)
                {
                    sw.Stop();
                }

                Log.Error($"Could not get server query result! Exception: {ex.ToString()}");

                string msg = ex.Message;
                if (ex is SocketException)
                {
                    msg = $"multiplayer.status.cannot_connect";
                }

                statusCallBack?.Invoke(new ServerQueryResponse(false, msg, new ServerQueryStatus()
                {
                    Delay   = sw.ElapsedMilliseconds,
                    Success = false,

                    EndPoint = endPoint,
                    Address  = hostname,
                    Port     = port
                }));
            }
            finally
            {
                //conn?.Stop();
                //conn?.Dispose();
                //conn?.Dispose();
                //	client?.Close();
            }
        }
        /// <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();
            }
        }