You are not logged in.

#1 09 Jun 2007 11:31 pm

winsr
Extreme Member
Registered: Mar 2007
Posts: 90

How to query for active servers, and player info on them

Hi guys,

How do you check on which servers are on with BF2142 (currently playing, map info, how many players, etc..), and how to retrive the list of players on them (names, ranks, points)?

Thanks

-Winsrp

Offline

 

#2 10 Jun 2007 10:14 am

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: How to query for active servers, and player info on them

the master server is at master.gamespy.com:28900.  it should be pretty easy to try to open a socket to that server (if you can connect, its online, if you cant, then its offline)

the master server and game servers use the gamespy version 4 server protocol (I think its version 4) and there are a few places out there that document how to query that.  there are a few apps and scripts out there that you could look at (downloads here(in PHP), here (in C) and lsgl (in PHP)

if you're wanting to include it in your app, it should be pretty easy to add in its stand alone form and you can just parse the results by adding the exe to your app, set it as an embedded resource, when you go to run the list, check the file system for the gslist.exe and if it doesnt exist you can extract it from your program, start the process, wrap standard out / error and parse the output. 

or you can just port it from C and include it without wrapping any process.

Offline

 

#3 11 Jun 2007 12:06 pm

winsr
Extreme Member
Registered: Mar 2007
Posts: 90

Re: How to query for active servers, and player info on them

dude, how do you find out all this things???? damn....big_smile

Offline

 

#4 11 Jun 2007 3:04 pm

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: How to query for active servers, and player info on them

been around the block a couple times wink

I wrote an app a while back that was a server browser for half-life, and have kind of followed programming libraries and applications that have done game server querying since then.

Offline

 

#5 13 Jun 2007 2:54 pm

winsr
Extreme Member
Registered: Mar 2007
Posts: 90

Re: How to query for active servers, and player info on them

ok i have checked the code (note i dont know PHP, thus i managed to translate the other PHP code of yours, the one that generated the auth key to retrive the stats), and i have also researched a bit about the gamespy query protocol... which is not too complex to translate BUT.. i was wondering how to actually ask for it.

I know the query must have a 10 hex value string, and that returns me another hex string with all the info i want or need, depending on how i asked for it, on the 10 hex string.

Now, i also noticed i need to open a UDP port to 28900 (but it says BF2, is it the same for BF2142?)

but.. then what, how do i make the query? how do i tell the master.gamespy.com at port 28900.. to accept my query packet?

I have also this reference

http://dev.kquery.com/index.php?article=42

Offline

 

#6 14 Jun 2007 12:22 am

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: How to query for active servers, and player info on them

there are 2 steps: 1) get the list of servers from the master server list. and 2) query each server for server info.

each one of those steps require that you connect to the server (master server list goes over TCP and the server query over UDP), and talk to it however it requires. 

basically you connect and get a challenge token from the server.  that token is then used to create a response / request to send back (both master server list and game query scramble up the token into something else to send back).  the server will then send you the details you're looking for.  Both master server / game query use a challenge / response protocol, but are sort of different after that.

I think the master server list comes encrypted and you have to decode it before you can parse out the server lists.  I had worked on it a while back (in .NET), but didn't have time to finish it (such is the story of my life).  I don't remember how far I got with it (or where I put it) though.  I do remember their encryption decoding processes being a pain to port to pure managed .NET (and think I cheated and just ported it directly using pointers and all that).

I believe the server query is comes in plain text after the challenge / response, but I wouldn't quote me on it. 

I believe both bf2 and bf2142's server query's are the same (with the exception of the challenge token logic being added to 2142's protocol).

kquery used to have a lot of info on their site, as far as documentation on how the different game protocols worked.  last time I checked there, it was a ghost town, so, who knows, maybe you can find something there about this (maybe even a .net implementation).

Offline

 

#7 14 Jun 2007 9:22 am

winsr
Extreme Member
Registered: Mar 2007
Posts: 90

Re: How to query for active servers, and player info on them

ok i think im getting really close now to have something done,

I found this code

http://www.codeproject.com/csharp/gameserverinfo.asp

But still it doesnt tells me how to query the game master server, to get the IPs/Ports

Offline

 

#8 14 Jun 2007 11:47 am

winsr
Extreme Member
Registered: Mar 2007
Posts: 90

Re: How to query for active servers, and player info on them

i have also find this information ...

External GameSpy Product Master Server Info:
GameSpy 3D: master0.gamespy.com:28900 (207.38.8.34)
GameSpy Arcade: master.gamespy.com:28900 (207.38.8.34)
[Used by America's Army, Quake, UT2K3, UT2K4. etc.]

GameSpy 3D Additional Ports:
TCP: 28900

GameSpy Arcade Additianl Ports:
TCP: 28900
TCP: 29900
TCP: 29920

Offline

 

#9 14 Jun 2007 12:32 pm

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: How to query for active servers, and player info on them

yea the master server query is a different thing.

gamespy has a bunch of game supporting services that they sell to game developers, so there are a ton of games that use their various protocols and services.  battlefield 2 and 2142 use gamespy (encoding type 2) for the server listing services that run on port 28900 of master.gamespy.com.  the protocol itself tells what game you need (battlefield 2142 is named stella, I forget what battlefield 2 is named in the protocol... battlefield2 I think).

I'll have to see if I cant dig up what I had done on it.

Offline

 

#10 14 Jun 2007 2:37 pm

winsr
Extreme Member
Registered: Mar 2007
Posts: 90

Re: How to query for active servers, and player info on them

So at the end, its just like getting stats, i should be taking info from something like this

http://stella.prod.gamespy.com

???

The bad thing on all this, is that every since piece of code that i found, its not even good enough to make a conection to the server to get the challenge token.... for which i have to say, have found several guys that state how to get it, and none of the codes work.

Ill be great to have a simple code that can conect to the master server to get a list of servers even if it is in plain text (or hex data), and then another to retrive the server info, even in plain text (or hex) that could actually work.

I have tried like 7 diferent forms now, and i send the first package, but never get the server responce. How sad. sad

Offline

 

#11 14 Jun 2007 4:21 pm

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: How to query for active servers, and player info on them

no, there are 3 sets of queries here.

  • player stats - the type that come from http:// stella.gamespy.com
  • server list - unlike player stats, this comes over raw TCP (not http) from master.gamespy.com:28900.  this is a simple text list of ip:ports of all the servers (ranked and unranked).
  • game server stats - unlike player stats and server list, this does not use TCP at all, it uses a UDP connection to query a single game server, to receive info on that server (server config info, player info: kills/deaths/ping...).


  • so if you think of it as a multi staged process:
    1. you get the list of servers.
    2. you get a list of players for each of the above servers
    3. you get the player stats of each player on each server as listed above.


    I dont know if you know C#, but this is how the thing I was working on should have worked (if I'd ever finished it):

    Code:

    Bf2142Service bf2142Service = new Bf2142Service();
    foreach(IPEndPoint serverAddress in bf2142Service.GetServerlist()) {
        foreach(Bf2142ServerInfo serverInfo in bf2142Service.GetServerInfo(serverAddress)) {
            foreach(PlayerInfo playerInfo in server.Players) {
                // get player stats based on PlayerInfo.Pid
            }
        }
    }

    so first I'd get the master list of IP addresses / port numbers.
    then I'd get the server details for the server,
    then I'd get the player stats (if the server was ranked) for each player based on the pid returned from the server query.


    each of these queries are different, use a application and transport protocol.

    here's a list of what does what:

    glist.exe (and the php equiv): - gets the list of bf2142 server:port
    LGSL: gets a game server's details (configuration, players...)
    your app: gets player stats.

    most apps that get server details (ase, hlsw and so on) use the server query protocol.  ASE will actually pull the master list of servers, as will xfire (whcih also gets the server details), LGSL and that code project article only show how to pull server stats if you know the server's IP/Port.  they dont show how to get that server's IP/Port.

    Offline

     

    #12 14 Jun 2007 8:52 pm

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    MadHatter :

    I dont know if you know C#

    If you have piece of code that could help, bring it on PHP, JAVA, DELPHI, VB, C++, you name it, ill understand it. wink

    MadHatter :

    1. you get the list of servers.
    2. you get a list of players for each of the above servers
    3. you get the player stats of each player on each server as listed above.

    Ok, i get that one, the stats parts, done with honors i'll say cool, now, i have seen the kind of info you can pull off for server details (once you have the IP and the port), it also comes in 3 parts, one is overall server info, then server rules, and at the end server players (with the kills and stuff).

    Now what i havent seen its the Master server list you are talking about, i have the code you gave me (php glist), but i didnt when too much into it, since it was on php, and i dont have a php debuger, but ill get the exe version, and try it out, to see whats going on in there, cus i want all code on the same application, to make it a complete tool.

    Code:

    Bf2142Service bf2142Service = new Bf2142Service();
    foreach(IPEndPoint serverAddress in bf2142Service.GetServerlist()) {
        foreach(Bf2142ServerInfo serverInfo in bf2142Service.GetServerInfo(serverAddress)) {
            foreach(PlayerInfo playerInfo in server.Players) {
                // get player stats based on PlayerInfo.Pid
            }
        }
    }

    What i see that you are trying to pull off here is like a masive player stats retrival, since you go thru all the servers, and all the player on them.

    Im trying to go with something like this

    Code:

    Dim DNSServer As New System.Net.Sockets.UdpClient
    Dim Conection_Address As System.Net.IPEndPoint
    Dim Initial_call() As Byte = {&HFE, &HFD, &H09, &H83, &H58, &H34, &H00}
    Dim Result As Integer
    
    ' "xxx.xxx.xxx.xxx" is replaced with what ever ip address i find, i take them from the ww.2142-stats.com server list
    
    Conection_Address = New System.Net.IPEndPoint("xxx.xxx.xxx.xxx", 29900)
    
    Result = DNSServer.Send(Initial_call, Initial_call.Length, Conection_Address)
    
    If DNSServer.Available = 0 Then
        MessageBox.Show("Crap, didnt get in")
    Else
        MessageBox.Show("hey, im in!!!")
    End If

    Now i have also added a timer to give it about 10 seconds to see if the DNSServer becomes available... but im falling there... it never get available, so if i try to retrive a responce from the same conection_address like this

    Code:

    Dim Initial_responce() As Byte
    Initial_responce = DNSServer.Receive(Conection_IP)

    it gives me an error. sad

    i have also tried a couple more things with sockets like this..

    Code:

    'sBuff =  sending buffer
    'rBuff = Receive buffer
    
    Protected Shared Function UDPDataTransmit( _ 
                ByVal sBuff() As Byte, ByRef rBuff() As Byte, _ 
                ByVal IP As String, ByVal Port As Integer) As Integer 'Returns # bytes received 
            Dim retstat As Integer 
            Dim Sck As Sockets.Socket 
            Dim Due As DateTime 
            Dim Encrp As IPEndPoint 
            Try 
                Sck = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) 
                Sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10000) 
                Sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 10000) 
    
                Encrp = New IPEndPoint(IPAddress.Parse(IP), Port) 
                retstat = Sck.SendTo(sBuff, 0, sBuff.Length, SocketFlags.None, Encrp) 
                If retstat > 0 Then 
                    Due = Now.AddMilliseconds(10000) '10 second time-out 
                    Do While Sck.Available = 0 AndAlso Now < Due 
                    Loop 
                    If Sck.Available = 0 Then 
                        'timed-out 
                        retstat = -3 
                        Return retstat 
    
    ... on so on

    but every time i fail to conect, so im stuck... out of ideas here, i guess i better start with the server list, since this server info retrival its not working very well.

    Last edited by winsr (14 Jun 2007 8:53 pm)

    Offline

     

    #13 15 Jun 2007 12:24 am

    MadHatter
    Administrator
    From: Dallas TX
    Registered: Jun 2006
    Posts: 529
    Website

    Re: How to query for active servers, and player info on them

    getting bf2142's master server list is a bit more complicated than that.  its not as easy as the server query.  they send a key, you encrypt that key and place it in a response back to them, then they send you an encrypted payload that you then have to decrypt.  the decrypted value is a new line separated list of ip:port numbers.

    Offline

     

    #14 15 Jun 2007 10:17 am

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    Sounds like a pain in the ass but, not imposible wink

    Offline

     

    #15 15 Jun 2007 11:10 am

    MadHatter
    Administrator
    From: Dallas TX
    Registered: Jun 2006
    Posts: 529
    Website

    Re: How to query for active servers, and player info on them

    the easiest thing to do would probably be to create a C++/CLI wrapper of the gslist.exe source code, and just use that to pull the server list.

    Offline

     

    #16 15 Jun 2007 3:35 pm

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    the only problem is that i cant make the glist to work  sad... ill im at work, ill have to try that at home.

    Offline

     

    #17 15 Jun 2007 7:57 pm

    MadHatter
    Administrator
    From: Dallas TX
    Registered: Jun 2006
    Posts: 529
    Website

    Re: How to query for active servers, and player info on them

    try:

    gslist.exe -n stella > 2142-servers.txt

    Offline

     

    #18 16 Jun 2007 12:01 am

    MadHatter
    Administrator
    From: Dallas TX
    Registered: Jun 2006
    Posts: 529
    Website

    Re: How to query for active servers, and player info on them

    here's a dll you can reference and use.

    http://sanity-free.org/misc/NullFX.Games.Protocols.zip

    use it to get the master list:

    Code:

    Imports NullFX.Games.Protocols
    Imports System.Net
    
    Module Module1
    
        Sub Main()
            Dim svc As Battlefield2142Service = New Battlefield2142Service()
            For Each endpoint As IPEndPoint In svc.GetMasterServerList()
                ' endpoint will be where you connect to to pull game server info
                Console.WriteLine(endpoint.ToString())
            Next
            Console.ReadLine()
        End Sub
    
    End Module

    that will just get you the ipendpoint of each game server listed in the master server list.  you'll still need to connect to the game server and pull the game info.  Keep in mind that they do have dead servers listed in there (ones that are not on line at the moment) I'll see if I cant port some of the lgsl php into something to get the server details and add it to that dll.

    Offline

     

    #19 18 Jun 2007 7:52 am

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    Again.... DAMN DUDE..... are you from another planet or im just too dumb??? tongue, ill try that, thanks dude.

    Offline

     

    #20 19 Jun 2007 8:04 am

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    Ok, i have tested it, and it works like a charm, if i trow the info into console it takes about 9.2 secs to deliver the hole list of servers, and if trow them to txtbox on screen it takes about 2.5 minutes sad, so i put it into a datagrid and takes 9.45 secs, (i had a timer on screen on the program for time measures, i like to do that with my coding) which i think its preatty good time, just 2.5 milis more than console. cool

    Now, i have to ask, just cus i have to ask.... its like something i just have to do.

    what did you put on that dll of yours????????? roll

    I know you probably wont give me the source... but as i just said... i had to ask.

    I'll see if I cant port some of the lgsl php into something to get the server details and add it to that dll.

    Are you really going to add the server query... omg.... so cool... thanks buddy.... and by the way, have you downloaded my app yet??, you are on the credits, did you know that?... i dont take the glory all for myself wink

    Offline

     

    #21 19 Jun 2007 10:07 am

    MadHatter
    Administrator
    From: Dallas TX
    Registered: Jun 2006
    Posts: 529
    Website

    Re: How to query for active servers, and player info on them

    yea I noticed it takes a while too and that could probably be improved somewhat.  I have no problem giving you the source code to it (though its coded in C# not vb)  I just thought it would be easier for you to include it / reference than to explain how to do it.  I just wrapped the gslist.exe, parsed the output and returned a list of native .net objects that could be used.

    here's the source code to that

    I've been really busy the past 3 or 4 days so I haven't had a chance to look at including the server stat stuff yet.

    thanks for the credit on the app, yea I do have it here at work, and it looks great.

    Offline

     

    #22 20 Jun 2007 6:54 am

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    cool, il try to change that code a bit, so i can use the command line parameters that the gslist allow, that way ill have less servers to query, ill just use the servers that have 1 or more people on it, since im just going to use them to find buddies on them, that way i also solve the problem of having to query unavailable or offline servers. cool

    Thanks a lot dude.

    Last edited by winsr (20 Jun 2007 6:55 am)

    Offline

     

    #23 20 Jun 2007 8:21 am

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    i just has a quick look at your code, and i think i can inprove some speed on it by returning the plain list insted of the ipendpoint array, that way i can make the conversion on my program, and at the same time i make the conversion ill start with the server querying. ill save the step of filling first a ipendpoint array, and then having to read from it, so ill read from the list and fill the array at the same time. But all and all... its a preatty clever setup you had there... ill see if i can make it on vb directly wink

    Offline

     

    #24 20 Jun 2007 8:35 am

    MadHatter
    Administrator
    From: Dallas TX
    Registered: Jun 2006
    Posts: 529
    Website

    Re: How to query for active servers, and player info on them

    the thing that is taking the longest time is the line:

    Code:

    string whatever = p.StandardOutput.ReadToEnd();

    or something like that.

    one way to speed it up (or would appear to speed things up) would be to create an event on the Battlefield2142Service called HostReceived or something like that and where you do ReadToEnd do ReadLine, then split, parse and create a new ip endpoint there.  Then you fire the event arg and place the newly received IP endpoint there.  to do that you need to create an event args class called HostReceivedEventArgs (or whatever you want to name it) that has a property called Host which would be the IPEndPoint object you pulled.  then instead of calling GetServerList, you add an event handler for the HostReceived event and get the server ip endpoint there.

    its not going to matter where you parse the result string at (so if you just return the big list of servers its going to take you the same amount of time to parse it in your app as it would in the class itself.

    if the event model is a bit confusing I can modify the code and re-upload it for you to look at.

    Offline

     

    #25 20 Jun 2007 8:51 am

    winsr
    Extreme Member
    Registered: Mar 2007
    Posts: 90

    Re: How to query for active servers, and player info on them

    Well i do get what your saying over there, you want to read the line as it comes down from the gslist, but if you run the gslist directly (now that i have tried that), youll see that the main delay is sending the token to the main server, receive responce, and then query back (so lets say thats a dead time that cannot be improved), the hole list pops up in about 2  seconds, but i guess the .readtoend method is in deed quite slow, since while running the gslist by itself it didnt took that much. Its just a matter of trial and error from here.

    On another though your idea will fit in another idea i have, im going to put several background processes to query for servers info (this is the part were you check for server detail after the lists start to come up), insted of a secuencial query, that way ill speed up that part, and show results as they come, so the app doesnt seems to be hanging in there doing nothing (or give my little status bar like its 100th use on the app big_smile, just love the bar).

    Combining this 2 ideas ill have the server query, right after the server list starts to pop up, and with 10 or 20 background threads running around, i should have all the info (with buddy search included) in about the time bf2142 gets his list of servers, which is around 30 secs, just a wild guess here, but i even spect to be faster than that. smile

    Offline

     



    © 2003 - 2018 NullFX
    Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License