User:Pizzahut/msqp.php: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(Created page with 'This is a code example for querying a Half-Life master server using the PHP language. For querying more than 231 servers it needs to be extended. The purpose of this program is t…')
 
(Version 2 - the original intention was to add more master servers, instead it's currently retrying the same server.)
Line 3: Line 3:
<?php
<?php


// There are two HL1 master list servers:
// Method 1: Try a different server if one is timing out.
// Method 2: Retry the same server if a timeout occurs.
$method = 2;
 
// There are two HL1 master servers:
// 1. 69.28.151.162 hl1master.steampowered.com
// 1. 69.28.151.162 hl1master.steampowered.com
// 2. 72.165.61.190
// 2. 72.165.61.190
// Using the domain name is preferred, but this server often times out.
// Using the domain name is preferred, but this server often times out.
$server1 = "hl1master.steampowered.com";
$server1 = "hl1master.steampowered.com";
$server2 = "72.165.61.190";
if ($method == 1)
$port = 27010;
{
$timeout = 10;
  $server2 = "72.165.61.190";
echo "Timeout = ",$timeout,"s\n";
  // The current Steam\config\masterservers.vdf contains 5 servers,
 
  // the more up-to-date but occasionally empty MasterServer2.vdf
$fp = fsockopen("udp://$server1", $port, $errno, $errstr, $timeout);
  // contains 4 servers. Game servers contact 2 master servers.
if (!$fp) exit("Error $errno : $errstr");
}
stream_set_timeout($fp, $timeout);


// region=world, filter: game=Team Fortress Classic
function select_master_server($ip,&$fp)
if (!fwrite($fp, "1\xFF0.0.0.0:0\0\\gamedir\\tfc\0")) {
{
   fclose($fp);
   $port = 27010;
   exit("fwrite error\n");
   $timeout = 1;
}


$s = bin2hex(fread($fp, 6));
   echo "Connecting to master server \"$ip\".\n";
$info = stream_get_meta_data($fp);
if ($info['timed_out']) {
  fclose($fp);
   echo "Server 1 timed out, trying server 2.\n";


   $fp = fsockopen("udp://$server2", $port, $errno, $errstr, $timeout);
   $fp = fsockopen("udp://$ip", $port, $errno, $errstr, $timeout);
   if (!$fp) exit("Error $errno : $errstr");
   if (!$fp) exit("Error $errno : $errstr");
   stream_set_timeout($fp, $timeout);
   stream_set_timeout($fp, $timeout);


   // region=world, filter: game=Team Fortress Classic
   // region=world, filter: game=Team Fortress Classic
   if (!fwrite($fp, "1\xFF0.0.0.0:0\0\\gamedir\\tfc\0")) {
   if (!fwrite($fp, "1\xFF0.0.0.0:0\0\\gamedir\\tfc\0"))
  {
       fclose($fp);
       fclose($fp);
       exit("fwrite error\n");
       exit("fwrite error\n");
Line 41: Line 40:
   $s = bin2hex(fread($fp, 6));
   $s = bin2hex(fread($fp, 6));
   $info = stream_get_meta_data($fp);
   $info = stream_get_meta_data($fp);
   if ($info['timed_out']) {
   if ($info['timed_out'])
  {
      echo "Master server \"$ip\" timed out.\n";
       fclose($fp);
       fclose($fp);
       exit("Server 2 timed out, aborting.\n");
  } else {
       if ($s !== "ffffffff660a") {
        fclose($fp);
        exit("Expected ff ff ff ff 66 0a (hex) but got $s.");
      }
   }
   }
  return $info['timed_out'];
}
if ($method == 1)
{
  if (select_master_server($server1,$fp))
      if (select_master_server($server2,$fp))
        exit("All servers timed out, aborting.\n");
}
}
if ($s !== "ffffffff660a") {
 
   fclose($fp);
if ($method == 2)
  exit("Expected ff ff ff ff 66 0a (hex) but got $s.");
{
   for ($i = 1; $i <= 10; $i++)
  {
      if (!select_master_server($server1,$fp))
        break;
      if ($i == 10)
        exit("Giving up after 10 tries.\n");
      else
        echo "Retrying ($i).\n";
  }
}
}



Revision as of 17:17, 8 December 2010

This is a code example for querying a Half-Life master server using the PHP language. For querying more than 231 servers it needs to be extended. The purpose of this program is to get a list of TFC servers, there are only about 150 left at the time of writing so it doesn't check for more. Btw currently the master servers only return 50 to 70 TFC servers, but as stated there are about 150, which you can verify with HLSW's Gamers Search (when it's not having one of its off days).

<?php

// Method 1: Try a different server if one is timing out.
// Method 2: Retry the same server if a timeout occurs.
$method = 2;

// There are two HL1 master servers:
// 1. 69.28.151.162 hl1master.steampowered.com
// 2. 72.165.61.190
// Using the domain name is preferred, but this server often times out.
$server1 = "hl1master.steampowered.com";
if ($method == 1)
{
   $server2 = "72.165.61.190";
   // The current Steam\config\masterservers.vdf contains 5 servers,
   // the more up-to-date but occasionally empty MasterServer2.vdf
   // contains 4 servers. Game servers contact 2 master servers.
}

function select_master_server($ip,&$fp)
{
   $port = 27010;
   $timeout = 1;

   echo "Connecting to master server \"$ip\".\n";

   $fp = fsockopen("udp://$ip", $port, $errno, $errstr, $timeout);
   if (!$fp) exit("Error $errno : $errstr");
   stream_set_timeout($fp, $timeout);

   // region=world, filter: game=Team Fortress Classic
   if (!fwrite($fp, "1\xFF0.0.0.0:0\0\\gamedir\\tfc\0"))
   {
      fclose($fp);
      exit("fwrite error\n");
   }

   $s = bin2hex(fread($fp, 6));
   $info = stream_get_meta_data($fp);
   if ($info['timed_out'])
   {
      echo "Master server \"$ip\" timed out.\n";
      fclose($fp);
   } else {
      if ($s !== "ffffffff660a") {
         fclose($fp);
         exit("Expected ff ff ff ff 66 0a (hex) but got $s.");
      }
   }
   return $info['timed_out'];
}

if ($method == 1)
{
   if (select_master_server($server1,$fp))
      if (select_master_server($server2,$fp))
         exit("All servers timed out, aborting.\n");
}

if ($method == 2)
{
   for ($i = 1; $i <= 10; $i++)
   {
      if (!select_master_server($server1,$fp))
         break;
      if ($i == 10)
         exit("Giving up after 10 tries.\n");
      else
         echo "Retrying ($i).\n";
   }
}

$count = 0;
do {
   $a1 = ord(fread($fp,1));
   $info = stream_get_meta_data($fp);
   if ($info['timed_out']) {
      echo "Time out occured.\n";
      break;
   }

   // Let's always read the rest of the address, even if it starts with 0.
   // This may avoid subsequent problems, but I'm paranoid here.
   $a2 = ord(fread($fp,1));
   $a3 = ord(fread($fp,1));
   $a4 = ord(fread($fp,1));
   $a5 = ord(fread($fp,1))*256 + ord(fread($fp,1));

   if ($a1 != 0) {
      $count++;
      echo "$count $a1.$a2.$a3.$a4:$a5\n";
   }
} while ($a1 != 0);
echo "Retrieved $count servers.\n";

fclose($fp);
?>