/// <summary> /// Return all servers which match the specified query criteria /// </summary> /// <param name="queries">Array of query criteria</param> /// <returns></returns> public List <Server> Query(QueryData[] queries) { List <Server> filteredServers; lock (serverListLock) { filteredServers = new List <Server>(servers); } foreach (QueryData query in queries) { if (MasterServer.Settings.GlobalIgnoreGameTypeFilter && query.Key.ToLower() == "gametype") { connectionLogWriter.Write("<ServerList> Global option \"ignore gametype filter\" is enabled. All gametypes will be returned by the query", this); } else { foreach (Server server in servers) { if (!server.Active || !server.Matches(query.Key, query.Value, query.QueryType)) { filteredServers.Remove(server); } } } } connectionLogWriter.Write(String.Format("<ServerList> Query returned {0} server(s).", filteredServers.Count), this); return(filteredServers); }
/// <summary> /// Write a line to the connection log /// </summary> /// <param name="format">Format string</param> /// <param name="args">Parameters</param> protected virtual void ConnectionLog(string format, params object[] args) { if (logWriter != null) { logWriter.Write(String.Format("<{0}> {1}", SocketID, String.Format(format, args)), this); } }
/// <summary> /// Process this packet assuming it is a gamestate packet, returns true if parsed with no errors /// </summary> /// <returns>True if no errors were encountered whilst reading the values from the packet</returns> public bool ProcessGameState(Server server, IConnectionLogWriter log) { try { ClientIPs = PopArray(); // Array of player IP/port, for some reason at the start of the packet not the end with the other player data ServerID = PopInt(); // ??? Seems to always be zero ServerIP = PopString(); // ??? Seems to always be empty Port = PopInt(); // Server's listen port QueryPort = PopInt(); // **NOTE** Always zero! Name = PopString(); // Server name Map = PopString(); // Current map GameType = PopString(); // Current game type NumPlayers = PopInt(); // Current players MaxPlayers = PopInt(); // Maximum players Ping = PopInt(); // **NOTE** Always zero! Info = PopKeyValueArray(); // Additional server information as key/value pairs } catch { return(false); } PacketType = ServerInfoPacketType.GameState; try { // This could probably be done using PopStructArray but this works as well int playercount = PopByte(); // Read player info from the packet for (int player = 0; player < playercount; player++) { // Client IP array may be shorter than the player list if this is a listen server string clientIP = (player < ClientIPs.Length) ? ClientIPs[player] : "local"; Players.Add(new Player(server, this, clientIP)); } } catch { if (log != null) { log.Write(String.Format("<{0}> ERROR PARSING GAMESTATE PLAYER DATA", server.Connection.SocketID), this); log.Write(String.Format("<{0}> PACKET={1}", server.Connection.SocketID, Print()), this); } } return(true); }