コード例 #1
0
        /// <summary>
        /// Creates a new instance of the <see cref="GameStat.Collections.ServerCollection"/> class and queries a master server.
        /// </summary>
        /// <param name="type">One of the <see cref="GameStat.MasterType"/> values.</param>
        /// <param name="filter">One or more of the <see cref="GameStat.MasterFilter"/> values.</param>
        /// <param name="host">The hostname/ip to query.</param>
        /// <param name="port">The master server's query port.</param>
        /// <returns>A new <see cref="GameStat.Collections.ServerCollection"/> class initialized with server information, or <c>null</c> if the master server didn't return any.</returns>
        /// <exception cref="System.Net.Sockets.SocketException">An error occurred when attempting to access the master server.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">The given <paramref name="type"/> is not recognized by GameStat.</exception>
        /// <exception cref="System.ArgumentException">An invalid argument was given.</exception>
        /// <exception cref="System.NotImplementedException">Support for the given <paramref name="type"/> is not implemented yet.</exception>
        /// <exception cref="GameStat.CorruptPacketException">A currupt or unknown packet was recieved from the master server.</exception>
        /// <remarks>
        ///    If <paramref name="host"/> is set to null, GameStat will try to guess it.  If <paramref name="host"/> can not be guessed, an <see cref="System.ArgumentException"/> will be thrown.
        ///    If <paramref name="port"/> is set to 0, GameStat will try to guess it.  If <paramref name="port"/> can not be guessed, an <see cref="System.ArgumentException"/> will be thrown.
        /// </remarks>
        /// <example>
        /// This example queries the Counter-Strike master server and writes the resulting information to the console.
        /// <code lang="C#">
        ///
        /// try {
        ///    ServerCollection servers=ServerInfo.QueryMaster(MasterType.Counter-Strike,
        ///       MasterFilter.NotFull|MasterFilter.NotEmpty|MasterFilter.NoPassword, null, 0);
        ///
        ///    if(servers!=null) {
        ///       foreach(Server s in servers)
        ///          Console.WriteLine(s.Host+":"+s.Port.ToString());
        ///    }
        ///    else Console.WriteLine("Master server didn't return any servers.");
        /// }
        /// catch(Exception ex) {
        ///    Console.Error.WriteLine("An Exception Occured!");
        ///    Console.Error.WriteLine(ex.ToString());
        /// }
        /// </code>
        /// </example>
        public static Collections.ServerCollection QueryMaster(MasterType type, MasterFilter filter, string host, ushort port)
        {
            IntPtr serversptr = GSQueryMaster((ushort)type, host, port, (ushort)filter);

            if (serversptr == IntPtr.Zero)
            {
                GSErrorCode err = GSLastError();
                switch (err)
                {
                case GSErrorCode.Ok:
                    return(null);

                case GSErrorCode.Winsock:
                case GSErrorCode.UnknownHost:
                case GSErrorCode.Connect:
                case GSErrorCode.Timeout:
                    throw new System.Net.Sockets.SocketException();

                case GSErrorCode.UnknownType:
                    throw new ArgumentOutOfRangeException("type");

                case GSErrorCode.Corrupt:
                    throw new CorruptPacketException();

                case GSErrorCode.UnknownPort:
                    throw new ArgumentException(GSErrorString(err), "port");

                case GSErrorCode.NotImplemented:
                    throw new NotImplementedException(GSErrorString(err));

                case GSErrorCode.InvalidParameter:
                    throw new ArgumentException(GSErrorString(err));
                }
            }

            Collections.ServerCollection sc = new Collections.ServerCollection();

            for (IntPtr cur = serversptr; cur != IntPtr.Zero;)
            {
                GS_SERVER server = (GS_SERVER)Marshal.PtrToStructure(cur, typeof(GS_SERVER));

                if (server.host != IntPtr.Zero)
                {
                    Server s = new Server();
                    s.Host = Marshal.PtrToStringAnsi(server.host);
                    s.Port = server.port;

                    sc.Add(s);
                }

                cur = server.next;
            }

            GSFreeServers(serversptr);

            return(sc);
        }
コード例 #2
0
 private static extern string GSErrorString(GSErrorCode err);
コード例 #3
0
        /// <summary>
        /// Creates a new instance of the <see cref="GameStat.ServerInfo"/> class and queries a server.
        /// </summary>
        /// <param name="type">One of the <see cref="GameStat.GameType"/> values.</param>
        /// <param name="host">The hostname/ip to query.</param>
        /// <param name="port">The game server's query port.  This will likely be different from the game port.</param>
        /// <returns>A new <see cref="GameStat.ServerInfo"/> class initialized with server information, or <c>null</c> if the server didn't return any information.</returns>
        /// <exception cref="System.Net.Sockets.SocketException">An error occurred when attempting to access the server.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">The given <paramref name="type"/> is not recognized by GameStat.</exception>
        /// <exception cref="System.ArgumentException">An invalid argument was given.</exception>
        /// <exception cref="System.NotImplementedException">Support for the given <paramref name="type"/> is not implemented yet.</exception>
        /// <exception cref="GameStat.CorruptPacketException">A currupt or unknown packet was recieved from the server.</exception>
        /// <remarks>If <paramref name="port"/> is set to 0, GameStat will try to guess it.  If <paramref name="type"/> is a generic protocol and <paramref name="port"/> can not be guessed, an <see cref="System.ArgumentException"/> will be thrown.</remarks>
        /// <example>
        /// This example queries a QuakeWorld server and writes the resulting information to the console.
        /// <code lang="C#">
        ///
        /// try {
        ///    ServerInfo info=ServerInfo.Query(GameType.QuakeWorld, "quake.sol.net", 27511);
        ///    if(info!=null) {
        ///       Console.WriteLine("Host: "+info.Host);
        ///       Console.WriteLine("Mod: "+info.Mod);
        ///       Console.WriteLine("Map: "+info.Map);
        ///       Console.WriteLine("Players: {0}/{1}", info.NumPlayers, info.MaxPlayers);
        ///    }
        ///    else Console.WriteLine("Server didn't return any info.");
        /// }
        /// catch(Exception ex) {
        ///    Console.Error.WriteLine("An Exception Occured!");
        ///    Console.Error.WriteLine(ex.ToString());
        /// }
        /// </code>
        /// </example>
        public static ServerInfo Query(GameType type, string host, ushort port)
        {
            if (host == null)
            {
                throw new ArgumentNullException("host");
            }

            IntPtr infoptr = GSQueryServer((ushort)type, host, port);

            if (infoptr == IntPtr.Zero)
            {
                GSErrorCode err = GSLastError();
                switch (err)
                {
                case GSErrorCode.Ok:
                    return(null);

                case GSErrorCode.Winsock:
                case GSErrorCode.UnknownHost:
                case GSErrorCode.Connect:
                case GSErrorCode.Timeout:
                    throw new System.Net.Sockets.SocketException();

                case GSErrorCode.UnknownType:
                    throw new ArgumentOutOfRangeException("type");

                case GSErrorCode.Corrupt:
                    throw new CorruptPacketException();

                case GSErrorCode.UnknownPort:
                    throw new ArgumentException(GSErrorString(err), "port");

                case GSErrorCode.NotImplemented:
                    throw new NotImplementedException(GSErrorString(err));

                case GSErrorCode.InvalidParameter:
                    throw new ArgumentException(GSErrorString(err));
                }
            }

            GS_SERVERINFO info = (GS_SERVERINFO)Marshal.PtrToStructure(infoptr, typeof(GS_SERVERINFO));

            ServerInfo si = new ServerInfo();

            if (info.host != IntPtr.Zero)
            {
                si.Host = Marshal.PtrToStringAnsi(info.host);
            }
            if (info.mod != IntPtr.Zero)
            {
                si.Mod = Marshal.PtrToStringAnsi(info.mod);
            }
            if (info.map != IntPtr.Zero)
            {
                si.Map = Marshal.PtrToStringAnsi(info.map);
            }

            si.NumPlayers = info.numplayers;
            si.MaxPlayers = info.maxplayers;
            si.TimeLimit  = TimeSpan.FromMinutes((double)info.timelimit);
            si.ScoreLimit = info.scorelimit;
            si.Passworded = (info.passworded == 1);
            si.Ping       = TimeSpan.FromMilliseconds((double)info.ping);

            for (IntPtr cur = info.properties; cur != IntPtr.Zero;)
            {
                GS_PROPERTY p = (GS_PROPERTY)Marshal.PtrToStructure(cur, typeof(GS_PROPERTY));

                if (p.key != IntPtr.Zero && p.value != IntPtr.Zero)
                {
                    si.Properties[Marshal.PtrToStringAnsi(p.key)] = Marshal.PtrToStringAnsi(p.value);
                }

                cur = p.next;
            }

            for (IntPtr cur = info.players; cur != IntPtr.Zero;)
            {
                GS_PLAYERINFO p = (GS_PLAYERINFO)Marshal.PtrToStructure(cur, typeof(GS_PLAYERINFO));

                if (p.name != IntPtr.Zero)
                {
                    Player player = new Player();
                    player.Name  = Marshal.PtrToStringAnsi(p.name);
                    player.Score = p.score;
                    player.Ping  = TimeSpan.FromMilliseconds((double)p.ping);
                    player.Time  = TimeSpan.FromSeconds((double)p.time);

                    si.Players.Add(player);
                }

                cur = p.next;
            }

            GSFreeServerInfo(infoptr);

            return(si);
        }