示例#1
0
        public void Query(string[] metaservers = null)
        {
            l.Info("[META] Querying metaservers.");

            if (metaservers == null)
            {
                metaservers = DefaultMetaservers;
            }

            foreach (var metaserver in DefaultMetaservers)
            {
                IPHostEntry host = Dns.GetHostEntry(metaserver);

                if (host == null)
                {
                    l.Error("Host DNS lookup failed for metaserver: " + metaserver);
                    continue;
                }

                Socket socket = null;

                try
                {
                    try
                    {
                        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP);
                        socket.Connect(host.AddressList, NetConstants.MetaserverPort);
                    }
                    catch (Exception ex)
                    {
                        l.Warn("Failed to connect to: " + host.HostName + ".  Exception: " + ex.ToString());
                        continue;
                    }

                    if (!socket.Connected)
                    {
                        socket.Dispose();
                        continue;
                    }

                    byte[] sendBytes = ASCIIEncoding.ASCII.GetBytes("?version=_");

                    try
                    {
                        socket.Send(sendBytes);
                    }
                    catch (Exception ex)
                    {
                        l.Warn("Error sending to metaserver '" + metaserver + "': " + ex.ToString());
                        continue;
                    }

                    int packetsReceived = 0;

                receive:
                    if (packetsReceived > 1) l.Trace("packetsReceived > 1");

                    byte[] recvBuffer = new byte[8192];
                    int bytesRead = 0;
                    try
                    {
                        if (packetsReceived == 0 || socket.Poll(250, SelectMode.SelectRead))
                        {
                            socket.ReceiveTimeout = 5000; // HARDTIME TIMEOUT
                            bytesRead = socket.Receive(recvBuffer);
                        }
                    }
                    catch (Exception ex)
                    {
                        l.Warn("Error receiving from metaserver: " + ex.ToString());
                        continue;
                    }

                    if (bytesRead == 0)
                    {
                        if (packetsReceived == 0)
                        {
                            l.Warn("Received nothing from metaserver'" + metaserver + "'");
                        }
                        continue;
                    }

                    packetsReceived++;

                    string result = ASCIIEncoding.ASCII.GetString(recvBuffer);

                    string[] lines = result.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

                    int lineCount = 0;
                    string protocolType = null;
                    string protocolUnknown2;
                    foreach (var line in lines)
                    {
                        if (line.StartsWith(((char)0).ToString())) break;

                        string[] cells = line.Split(',');

                        if (lineCount++ == 0)
                        {
                            protocolType = cells[0];
                            if (protocolType.Equals("r"))
                            {
                                protocolUnknown2 = cells[1];
                            }
                            continue;
                        }

                        ServerListing listing = null;
                        if (protocolType.Equals("r"))
                        {
                            listing = new ServerListing(cells[0]);
                            listing.Source = protocolType;
                            listing.Port = Convert.ToInt32(cells[1]);
                            listing.Status = cells[2];
                            listing.Age = Convert.ToInt32(cells[3]);
                            listing.Players = Convert.ToInt32(cells[4]);
                            listing.Queue = Convert.ToInt32(cells[5]);
                            listing.Type = cells[6];
                            listing.Comment = String.Empty;

                        }
                        else if (protocolType.Equals("s"))
                        {
                            listing = new ServerListing(cells[0]);
                            listing.Source = protocolType;
                            listing.Type = cells[1];
                            listing.Comment = cells[2];
                            listing.Port = Convert.ToInt32(cells[4]);
                            listing.Players = Convert.ToInt32(cells[5]);
                            listing.Queue = Convert.ToInt32(cells[6].Trim());
                            listing.Status = "2"; // TODO  REVIEW
                            if (listing.Type.Equals("unknown")) listing.Status = "3"; // TODO  REVIEW
                            listing.Age = 0;
                        }
                        else
                        {
                            l.Warn("Unknown metaserver protocol: " + protocolType);
                        }

                        if (listing != null && listing.IsSupported)
                        {
                            l.Debug("[meta] " + listing.ToString());
                            if (ServerListings.Contains(listing))
                            {
                                ServerListings.Remove(listing);
                            }
                            ServerListings.Add(listing);
                            servers.Set(listing.Key, listing);
                        }
                    }
                    goto receive;
                }
                finally
                {
                    try
                    {
                        if (socket != null)
                        {
                            socket.Dispose();
                            socket = null;
                        }
                    }
                    catch (Exception ex) { l.Trace(ex.ToString()); }
                }
            }
        }