Terry wrote:

I don't know if this will help, but I'm in the process of putting a site
together for game browser development. The site as a whole is incomplete
and just getting started, but I do have a writeup of the Half-Life master
and game server protocol with sample C# code snippets (I'll be posting the
full source tonight or tomorrow). It's here ->
http://www.game-tracker.com/gameproto/halflife.htm


Terry

I just tried this with an old C application I crufted together several years ago, here's the number of servers returned...


half-life.east.won.net port 27010 - 7328 servers
half-life.central.won.net port 27010 - 7213 servers
half-life.west.won.net port 27010 - 7196 servers

You might want to collect the results of all 3 WON masters, sort them by IP address and eliminate duplicates to get a more complete list.


Here's the C code...


#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <winsock.h>

#define BUF_SIZE 2048


void main(int argc, char *argv[]) { WSADATA WSAData; struct hostent *hp; unsigned int addr; SOCKET socket_desc; SOCKADDR_IN master_sin; int mode; TIMEVAL timeout; fd_set fd_read; int done; int value;

   union port_u
   {
      unsigned char port_b[2];
      unsigned short port;
   } port_u;

FILE *fp;

   unsigned char buffer[BUF_SIZE];
   int  length;
   int  offset, num_nodes, i;
   long unique, *pUnique;


if (argc < 3) { printf("usage: get_won master_IP_address master_port\n"); printf(" for example: get_won half-life.east.won.net 27010\n"); printf(" or : get_won half-life.west.won.net 27010\n"); return; }

   // start up the Windows Sockets Interface...
   if (WSAStartup(0x0101, &WSAData))
   {
      printf("Can't start Sockets Interface!\n");
      return;
   }

socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

   if (socket_desc == INVALID_SOCKET)
   {
      printf("Can't create Server socket!: error=%d\n",
              WSAGetLastError());
      return;
   }

   mode = 1; // set no blocking mode for socket...
   if (ioctlsocket(socket_desc, FIONBIO, &mode) == SOCKET_ERROR)
   {
      printf("Can't set socket to non-blocking mode!: error=%d\n",
              WSAGetLastError());
      return;
   }


// find the IP address of the master... if (isalpha(argv[1][0])) { hp = gethostbyname(argv[1]);

      if (hp == NULL)
      {
         printf("Can't resolve host IP address!: error=%d\n",
                 WSAGetLastError());
         return;
      }

      memcpy(&addr, hp->h_addr, 4);
   }
   else
   {
      addr = inet_addr(argv[1]);
   }

   // set up the master socket...
   memset(&master_sin, 0, sizeof(master_sin));

   master_sin.sin_family = AF_INET;
   memcpy(&(master_sin.sin_addr), &addr, 4);
   master_sin.sin_port = htons((u_short)atoi(argv[2]));


buffer[0] = 'e'; // A2M_GET_SERVERS_BATCH; buffer[1] = 0;

   sendto(socket_desc, buffer, 2, 0,
          (struct sockaddr *)&master_sin, sizeof(master_sin));

   timeout.tv_sec = 5;  // set timeout to 5 seconds
   timeout.tv_usec = 0;

   FD_ZERO(&fd_read);  // set the select file descriptor sets
   FD_SET(socket_desc, &fd_read);

   printf("opening output file: won.txt\n");
   fp = fopen("won.txt", "w");

done = 0;

   while (!done)
   {
      value = select(0, &fd_read, NULL, NULL, &timeout);

      if (value == SOCKET_ERROR)
      {
         printf("Error from select function: error=%d\n",
                 WSAGetLastError());

         done = 1;
      }
      else if (value > 0)
      {
         length = recvfrom(socket_desc, buffer, BUF_SIZE, 0, NULL, NULL);

         if ((length < 10) ||
             (buffer[0] != 0xFF) || (buffer[1] != 0xFF) ||
             (buffer[2] != 0xFF) || (buffer[3] != 0xFF) ||
             (buffer[4] != 'f'))
         {
            printf("Invalid packet received from WON master!\n");
            done = 1;
            continue;
         }

offset = 6;

         pUnique = (long *)&buffer[offset];
         unique = *pUnique;

         num_nodes = (length - 10) / 6;
         offset += 4;

         for (i=0; i < num_nodes; i++)
         {
            port_u.port_b[0] = buffer[offset+5];
            port_u.port_b[1] = buffer[offset+4];

            fprintf(fp, "%d.%d.%d.%d:%d\n",
                    buffer[offset], buffer[offset+1],
                    buffer[offset+2], buffer[offset+3], port_u.port);
            offset += 6;
         }

         if (unique == 0)  // if no more servers left then done...
            done = 1;
         else
         {
            buffer[0] = 'e';  // A2M_GET_SERVERS_BATCH;
            *(int *)&buffer[1] = unique;

            printf("reading data from WON master...\n");
            sendto(socket_desc, buffer, 5, 0,
                   (struct sockaddr *)&master_sin, sizeof(master_sin));
         }
      }
      else
      {
         printf("Timeout occurred waiting for WON master to respond!\n");

         done = 1;
      }
   }

fclose(fp);

closesocket(socket_desc);

}

--
Jeffrey "botman" Broome

_______________________________________________
hlds_apps mailing list
[EMAIL PROTECTED]
http://list.valvesoftware.com/mailman/listinfo/hlds_apps

Reply via email to