Gamespy BF2 Login Validator
This code is a re-write of the code in C from Luigi Auriemma. This was being used on The Sandbox Network
to create logins from the sandbox mod.
<\?php
//Functions "prototypes"
function str_split2($s){
        return explode("\r\n",trim(chunk_split($s,1)));
}
//regular modulus isnt working for some reason? (returns negative numbers from 2 positive operands sometimes)
function Mod($A, $B)
{
     
      /*14454429 / 53 = 272828.8491
        14454429 % 53 = 53 * .8491
        14454429 % 53 = 45
       
        So we want to first devide with all floats there, then subtract that from itself rounded down
        so we end up with just the digits (ex 8.81 - 8 = .81)
       
        Then multiply that by B      
      */      
     
      $tempFloat = $A / $B;
      //floor() rounds down
      $tempInt = floor($tempFloat);      
      $tempFloat -=$tempInt;      
     
      //round this either up or down depending
      return   round($B * $tempFloat,1);
}
/*
On Success this function will return 1
If the password is incorrect it will return 2
If the login name is incorrect it will return 3
Otherwise it will return 0
*/
function CheckGamespy($AccountName, $AccountPass)
{
//socket_connect($fp,"gpcm.gamespy.com", 29900);
$fp = fsockopen("gpcm.gamespy.com", 29900, $errno, $errstr, 30);
if (!$fp)
{
    echo "$errstr ($errno)
\n";
}
//for($i = 0; strpos($buf,"final\")<1 ; $i++)
{
$buf=fgets($fp,39);
$Server_Challenge = $buf;
//each '\'needs '\'
$Server_Challenge = str_replace('\lc\1\challenge\',"",$Server_Challenge);
$Server_Challenge = str_replace('\id\1\final\',"",$Server_Challenge);
//$Server_Challenge = "RGHMSXVPWF";
//Now to get the first part
$blah = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for($i = 0; $i<=63;$i++)
{      
      $table[$i] = substr($blah,0,1);
      $blah = str_replace($table[$i],"",$blah );
}
//For the thing tim from epoch 1/1/70
$seed = time();
//$seed = 1214493696;
//4 294 967 295 is the higest int in C
for($i = 0; $i!=32; $i++)
{
      $seed = ( ( $seed * 214013 ) + 2531011);
      if($seed > 4294967295)
      {
              $seed = $seed - ( floor($seed / 4294967295) * 4294967295);
              //This method is slow
              //while($seed > 4294967295)
              //{
              //       $seed = $seed - 4294967296;              
     
              //}
      }
      $sdata[$i] = $table[mod($seed,62)];      
     
      //echo Mod($seed,62) .'
';
      //$seed = $seed % 62;
      //echo $seed .'
';
}
$Client_Challenge = implode("",$sdata);
//HERE
//$passwordmd5 = do_md5($AccountPass);
$passwordmd5 = md5($AccountPass);
$PreReply = $passwordmd5 ."                                                 " .$AccountName   .$Client_Challenge .$Server_Challenge .$passwordmd5;
//$Finalmd5 = do_md5($PreReply);
$Finalmd5 = md5($PreReply);
//echo $implode("",$Finalmd5);
//First part of the client challenge to send back //HERE
$Reply = '\login\\challenge\' .implode("",$sdata) ."\uniquenick\" .$AccountName ."\response\" .$Finalmd5 ."\port\".($seed & 32767) ."\productid\10492\gamename\battlefield6\namespaceid\12\sdkrevision\3\id\1\final\";
fputs($fp,$Reply);
$Result = fgets($fp,154);
//echo md5($AccountPass);
//This is after the md5'd password
//echo $seed & 32767;
$LogonID = str_replace("\lc\2\sesskey\", "", $Result);
//$LogonID = substr_replace($LogonID,"\proof")
$temp = str_split($LogonID);
for($i = 0; $temp[$i] != '\';$i++)
{
      $sesskey = $sesskey .$temp[$i];
}
$Logout = sprintf("\logout\\sesskey\%d\final\", $sesskey);
fputs($fp,$Logout);
}
fclose($fp);
if(strstr($Result,"sesskey"))
{      
      return 1;      
}
else if(strstr($Result,"The password provided is incorrect"))
{      
      return 2;
}
else if(strstr($Result,"The uniquenick provided is incorrect"))
{
      return 3;
}
else
{
      return 0;
}
}
?>