+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Ghost Players

  1. #1
    garrensilverwing's Avatar
    garrensilverwing is offline x10 Sophmore garrensilverwing is an unknown quantity at this point
    Join Date
    Nov 2008
    Posts
    148

    Ghost Players

    This guy and I are creating a ranking system for this game we play. The game automatically generates game reports and posts them on a webserver: server.war2.ru/reports. The guy wrote a short php function that parses the game reports and then separates important information out, including winner's name, loser's name, etc... Now in some cases the function will parse a game and give us either a blank winner, or a blank loser. We have no idea what is causing this and was hoping you could help us out a little. Here is a link to a game report that creates a ghost player: http://server.war2.ru/reports/gr_20091201223149_025853, in this case the player should be vanwilder but it is coming as blank. If anyone has an idea of how to fix this I will give them rep and whatever else I can! Here is the function:

    Code:
      <?php
         function insertLadderGame($GameID, $map, $Winner, $Loser)
         {
            $wresult = mysql_query("select * from standings where Player = '$Winner'");
            $lresult = mysql_query("select * from standings where Player = '$Loser'");
            if (mysql_num_rows($wresult) == 0 || mysql_num_rows($lresult) == 0)
            {
                 if (mysql_num_rows($wresult) == 0)
                 {
                    $result = mysql_query("SELECT * FROM standings order by Rank desc limit 1") or die(mysql_error());
                    while($row = mysql_fetch_array($result)){$highestRank = $row['Rank'];}
                    $WOldRank = $WNewRank = $highestRank + 1;
                    mysql_query("INSERT INTO standings (Player,Rank,Wins,Losses,HighRank,Streak)                VALUES('$Winner','$WNewRank','1','0','$WNewRank','1');") or die(mysql_error());
                 }
                 else
                 {
                    $result = mysql_query("SELECT * FROM standings where Player = '$Winner'") or die(mysql_error());
                    while($row = mysql_fetch_array($result))
                    {$WOldRank = $WNewRank = $row['Rank']; $Wins = $row['Wins']; $wStreak = $row['Streak'];}
                    if ($wStreak > 0) $wStreak++;
                    else $wStreak = 1;
                    mysql_query("UPDate standings SET Wins='$Wins+1', Streak='$wStreak' where Player = '$Winner'") or die(mysql_error());
                 }
                 if (mysql_num_rows($lresult) == 0)
                 {
                    $result = mysql_query("SELECT * FROM standings order by Rank desc limit 1") or die(mysql_error());
                    while($row = mysql_fetch_array($result))
                    {$highestRank = $row['Rank'];}
                    $LOldRank = $LNewRank = $highestRank + 1;
                    mysql_query("INSERT INTO standings (Player,Rank,Wins,Losses,HighRank,Streak)
                    VALUES('$Loser','$LNewRank','0','1','$LNewRank','-1');") or die(mysql_error());
                 }
                 else
                 {
                    $result = mysql_query("SELECT * FROM standings where Player = '$Winner'") or die(mysql_error());
                    while($row = mysql_fetch_array($result))
                    {$LOldRank = $LNewRank = $row['Rank'];$Losses = $row['Losses'];$lStreak = $row['Streak'];}
                    if ($lStreak < 0) $lStreak--;
                    else $lStreak = -1;
                    mysql_query("UPDate standings SET Losses='$Losses+1', Streak='$lStreak' where Player = '$Loser'") or die(mysql_error());
                 }
                 $DateT = substr($GameID, 4, 14);
                 mysql_query("INSERT INTO checkedgames (GameID,Winner,Loser,WOldRank,WNewRank,LOldRank,LNewRank,Map,DateT)
                 VALUES('$GameID', '$Winner','$Loser','$WOldRank','$WNewRank','$LOldRank','$LNewRank','$map','$DateT' );") or die(mysql_error());
                 return 0;
            }
    // If neither player is new
            $result = mysql_query("SELECT * FROM standings where Player='$Winner'") or die(mysql_error());
            while($row = mysql_fetch_array($result))
            {$highrank = $row['HighRank'];$WOldRank = $row['rank'];$Wins = $row['Wins'];$WStreak = $row['Streak'];$WSeries = $row['series'];}
            $Wins++;
            if ($wstreak > 0) $wstreak++;
            else $wstreak = 1;
            $result = mysql_query("SELECT * FROM standings where Player='$Loser'") or die(mysql_error());
            while($row = mysql_fetch_array($result))
            {$LOldrank = $row['Rank'];$Losses = $row['Losses'];$LStreak = $row['Streak'];}
            $Losses++;
            if ($LStreak < 0) $LStreak--;
            else $LStreak = -1;
            if ($LOldRank + $WOldRank == 3) $WSeries++;
            if ($WSeries > 0)
            {
                 mysql_query("UPDATE standings SET series='$WSeries' where Player = '$Winner'") or die(mysql_error());
                 if ($WSeries == 3)
                 {$counter = 3; while($counter > 2 && $counter < 11) {$newrank = $counter-1; mysql_query("UPDATE standings SET rank ='$newrank' where Rank = '$counter'"); $counter = $counter+1;}
                      mysql_query("UPDATE standings SET series='0', rank='1' where Player = '$Winner'") or die(mysql_error());
                      mysql_query("UPDATE standings SET series='0', rank='10' where Player = '$Loser'") or die(mysql_error());
    
                 }
            }
            if ($WOldRank > $LOldRank && $WSeries == 0)
            {
                 $WNewRank = ($WOldRank + $LOldRank)/2;
                 $WNewRank = intval($WNewRank);
                 $n = $WOldRank-1;
                 if ($WNewRank == 2)
                 {
                      mysql_query("UPDATE standings SET series='0', rank='2' where player = '$Loser'") or die(mysql_error());
                      $result = mysql_query("SELECT * FROM standings where rank = '1'") or die(mysql_error());
                      while($row = mysql_fetch_array($result)) $TopPlayer = $row['Player'];
                      mysql_query("UPDATE standings SET series='0' where Player = '$TopPlayer'") or die(mysql_error());
                 }
                 
                 while ($n >= $WNewRank)
                 {
                      $result = mysql_query("SELECT * FROM standings where rank = '$n'") or die(mysql_error());
                      while($row = mysql_fetch_array($result)) $passedPlayer = $row['player'];
                      $m = $n+1;
                      mysql_query("UPDATE standings SET rank='$m' where player = '$passedPlayer'") or die(mysql_error());
                      $n--;
                 }
            }
            else $wnewrank = $woldrank;
            if ($wnewrank < $highrank) $highrank = $wnewrank;
            if ($wnewrank == $loldrank) $lnewrank = $loldrank + 1;
            else $lnewrank = $loldrank;
            mysql_query("UPDATE standings SET rank='$wnewrank', wins='$wins', streak='$wstreak', highrank='$highrank' where player = '$winner'");
            mysql_query("UPDATE standings SET losses='$losses', streak='$lstreak' where player = '$loser'");
            mysql_query("INSERT INTO checkedgames (gameID,loser,winner,woldrank,wnewrank,loldrank,lnewrank,map,datet)
            VALUES('$gameID', '$loser','$winner','$woldrank','$wnewrank','$loldrank','$lnewrank','$map','now()' );")
            or die(mysql_error());
            return 0;
         }
    
         function insertGameID($GameID)
         {
            mysql_query("INSERT INTO checkedgames (GameID,Loser,Winner,WOldRank,WNewRank,LOldRank,LNewRank,Map)
            VALUES('$GameID', 'none','none','none','none','none','none','none');") or die(mysql_error());
         }
    
         function  parseGameInfo($GameID)
         {
            set_time_limit(8000);
            $war2gameinfo = file('http://server.war2.ru/reports/'.$GameID);
            $war2gameinfotxt = implode('',$war2gameinfo);
    
            if (preg_match('/mapauth=\"Self-Made\"/', $war2gameinfotxt) == 0 && preg_match('/DRAW/', $war2gameinfotxt) == 0
            && preg_match('/DISCONNECT/', $war2gameinfotxt) == 0)
            {
                 if (preg_match('/  LOSS/', $war2gameinfotxt) == 0)
                 {
                      return 0;
                 }
                 if (preg_match('/  WIN/', $war2gameinfotxt) == 0)
                 {
                      return 0;
                 }
                 $startHere = strstr($war2gameinfotxt,'joins=');
                 $line = explode("\n", $startHere);
                 $joinCount = substr($startHere, 6, 1);
                 $englishCount = preg_match_all('/ and played for/', $startHere, $matches);
                 if ($englishCount < $joinCount)
                 {          
                      return 0;
                 }
                 $watcherCount = preg_match_all('/ 1 for Units/', $startHere, $matches);
                 $PlayerCount = $joinCount - $watcherCount;
                 if ($PlayerCount == 2)
                 {
                       preg_match('/mapfile=\".+\.pud\"/', $war2gameinfotxt, $mapmatch);
                       $map = substr($mapmatch[0], 9, -5);
                       $throwAway = preg_match_all('/\d+ for Units/', $startHere, $matches);
                      /* While loop: creates a variable Player1 first time through, Player2 second time through.
                         Sets Player1[0] to the first Player's name, [1] to the result, [2] to his units.
                         Sets Player2[0] to the second Player's name, etc.
                         If Player's units are more than 1, and he lost or disconnected, his name is set to $Loser.
                         If Player's units are more than 1, and he won, his name is set to $Winner.
                      */
                       $n = 0;
                        while ($n < $PlayerCount)
                        {${'Player'.($n+1)} = preg_split("/\s+/", $line[3+$n]);${'Player'.($n+1)}[2] = $matches[0][$n]; if (${'Player'.($n+1)}[2] > 1 && ${'Player'.($n+1)}[1] == 'LOSS') $Loser = ${'Player'.($n+1)}[0]; if (${'Player'.($n+1)}[2] > 1 && ${'Player'.($n+1)}[1] == 'WIN')
                              $Winner = ${'Player'.($n+1)}[0];
                            $n++;
                        }
                    }
    
                 else
                 {
                      return 0;
                 }
    
            }
            else
            {
                return 0;
            }
            if($Winner == "" OR $Loser == ""){
                echo "<li style=\"color: red\">$GameID</li>";
            }
            else {
            insertLadderGame($GameID, $map, $Winner, $Loser);
            }
            return 0;
        }
    ?>

  2. #2
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Ghost Players

    Quote Originally Posted by garrensilverwing View Post
    Here is a link to a game report that creates a ghost player: http://server.war2.ru/reports/gr_20091201223149_025853, in this case the player should be vanwilder but it is coming as blank.
    On that page, there is no "vanwilder". There's an "Equinox" who is listed with a loss and "BiBiFox[iS]" and "VaRioLa-" with wins--are you referring to one of them? If so, which one?

    In some places in the code, names used mixed case. In others, the same names are lower case. You should always write code that will work whether the language is case sensitive or insensitive. Otherwise you'll find yourself doing the wrong thing at some point and introducing a bug. I see it happen.

    Much of the code, especially in insertLadderGame, could be clarified by refactoring it into other functions, such as insertWinner(...), updateLoser(...) &c.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
      <?php
    function insertLadderGame($GameID$map$Winner$Loser) {
       
    $wresult mysql_query("select * from standings where Player = '$Winner'");
       
    $lresult mysql_query("select * from standings where Player = '$Loser'");
    "SELECT *" is wasteful and causes more work should you change the table schema. Better to fetch only the columns you care about.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
       if (mysql_num_rows($wresult) == || mysql_num_rows($lresult) == 0)
       {
            if (
    mysql_num_rows($wresult) == 0) {
               
    $result mysql_query("SELECT * FROM standings order by Rank desc limit 1") or die(mysql_error());
               while(
    $row mysql_fetch_array($result)){$highestRank $row['Rank'];} 
    $result will have at most one row; no need for a while loop. This applies in a couple places.

    Don't use "or die", throw an exception. I'll keep saying it until people listen.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
            } else {
               
    $result mysql_query("SELECT * FROM standings where Player = '$Winner'") or die(mysql_error()); 
    You just ran this query. It's still in $wresult.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
               while($row mysql_fetch_array($result))
               {
    $WOldRank $WNewRank $row['Rank']; $Wins $row['Wins']; $wStreak $row['Streak'];} 
    Assuming there should be at most one row in `standings` for each player, there's no need for a while loop. Even if there were more than one, the loop would be the wrong thing to do.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
               if ($wStreak 0$wStreak++;
               else 
    $wStreak 1;
               
    mysql_query("UPDate standings SET Wins='$Wins+1', Streak='$wStreak' where Player = '$Winner'") or die(mysql_error()); 
    "'$Wins+1'" won't perform addition. Either remove the single quotes or perform addition in PHP. The same thing happens later in the loser update branch.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
            } else {
               
    $result mysql_query("SELECT * FROM standings where Player = '$Winner'") or die(mysql_error()); 
    Here, you're updating the loser, but fetching the standings for the winner. Also, the result of the same query is in $lresult.


    Instead of the code above, you could create a few functions and have:
    PHP Code:
    class DBException extends RuntimeException {}

    function 
    insertNewPlayer($player$win) {
        
    $result mysql_query("SELECT Rank FROM standings ORDER BY Rank DESC LIMIT 1"
            or die(
    mysql_error());
        
    $row mysql_fetch_array($result);
        ++
    $row['Rank'];
        
    $standing = array('oldRank' => $row['Rank'], 'newRank' => $row['Rank'], 'Player' => $player);
        if (
    $win) {
            
    $standing['Streak'] = $standing['Wins'] = 1;
            
    $standing['Losses'] = 0;
        } else {
            
    $standing['Streak'] = -1;
            
    $standing['Wins'] = 0;
            
    $standing['Losses'] = 1;
        }
        
        if (! 
    mysql_query("INSERT INTO standings (Player,Rank,Wins,Losses,HighRank,Streak)
                     VALUES('
    $player','$standing[newRank]',$standing[Wins],$standing[Losses],'$standing[newRank]','$standing[Streak]');")) 
        {
            throw new 
    DBException(mysql_error(), mysql_errno());
        }
        return 
    $standing;
    }

    function 
    insertWinner($player) {
        return 
    insertNewPlayer($playerTrue);
    }
    function 
    insertLoser($player) {
        return 
    insertNewPlayer($playerFalse);
    }

    function 
    updateWinner($player$result) {
        
    $standing mysql_fetch_array($result);
        ++
    $standing['Wins'];
        if (
    $standing['Streak'] > 0) ++$standing['Streak'];
        else 
    $standing['Streak'] = 1;
        if (! 
    mysql_query("UPDATE standings SET Wins='$standing[Wins]', Streak='$standing[Streak]' WHERE Player = '$player'")) {
            throw new 
    DBException(mysql_error(), mysql_errno());
        }
        
    $standing['oldRank'] = $standing['newRank'] = $standing['Rank'];
        return 
    $standing;
    }
    function 
    updateLoser($player$result) {
        
    $standing mysql_fetch_array($result);
        ++
    $standing['Losses'];
        if (
    $standing['Streak'] < 0) --$standing['Streak'];
        else 
    $standing['Streak'] = -1;
        if (!
    mysql_query("UPDate standings SET Losses='$standing[Losses]', Streak='$standing[Streak]' WHERE Player = '$player'")) {
            throw new 
    DBException(mysql_error(), mysql_errno());
        }
        
    $standing['oldRank'] = $standing['newRank'] = $standing['Rank'];
        return 
    $standing;
    }

    function 
    insertLadderGame($GameID$map$Winner$Loser) {
        
    $wresult mysql_query("select Wins, Streak, Rank, HighRank, Series from standings where Player = '$Winner'");
        
    $lresult mysql_query("select Losses, Streak, Rank from standings where Player = '$Loser'");
        if (
    mysql_num_rows($wresult) == || mysql_num_rows($lresult) == 0) {
            if (
    mysql_num_rows($wresult) == 0) {
                
    // winner is not in standings, unknown about loser
                
    $winnersStanding insertWinner($Winner);
            } else {
                
    $winnersStanding updateWinner($Winner$wresult);
            }
            if (
    mysql_num_rows($lresult) == 0) {
                
    $losersStanding insertLoser($Loser);
            } else {
                
    $losersStanding updateLoser($Loser$lresult);
            }
            
    $DateT substr($GameID414);
            
    mysql_query("INSERT INTO checkedgames (GameID,Winner,Loser,WOldRank,WNewRank,LOldRank,LNewRank,Map,DateT)
                 VALUES('
    $GameID', '$Winner','$Loser','$winnersStanding[oldRank]','$winnersStanding[newRank]','$losersStanding[oldRank]','$losersStanding[newRank]','$map','$DateT' );"
                or throw new 
    DBException(mysql_error(), mysql_errno());
            return 
    0;
        }
        .... 
    Back to the original code.
    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
    // If neither player is new
            
    $result mysql_query("SELECT * FROM standings where Player='$Winner'") or die(mysql_error());
            while(
    $row mysql_fetch_array($result))
            ...
            
    $result mysql_query("SELECT * FROM standings where Player='$Loser'") or die(mysql_error());
            while(
    $row mysql_fetch_array($result)) 
    Again, unnecessary queries, columns and loops.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
                 if ($WSeries == 3)
                 {
    $counter 3; while($counter && $counter 11) {$newrank $counter-1mysql_query("UPDATE standings SET rank ='$newrank' where Rank = '$counter'"); $counter $counter+1;} 
    This can be done in a single query:
    Code:
    UPDATE standings SET Rank=Rank-1 WHERE Rank BETWEEN 3 AND 10
    If it couldn't, a for loop would better match the intent. Also, are you sure that's the correct thing to do?

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
            if ($WOldRank $LOldRank && $WSeries == 0)
            {
                 
    $WNewRank = ($WOldRank $LOldRank)/2;
                 
    $WNewRank intval($WNewRank); 
    You can combine the last two lines into "$WNewRank = (int)(($WOldRank + $LOldRank)/2)".

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
                 $n $WOldRank-1;
                 if (
    $WNewRank == 2)
                 {
                      
    mysql_query("UPDATE standings SET series='0', rank='2' where player = '$Loser'") or die(mysql_error());
                      
    $result mysql_query("SELECT * FROM standings where rank = '1'") or die(mysql_error());
                      while(
    $row mysql_fetch_array($result)) $TopPlayer $row['Player'];
                      
    mysql_query("UPDATE standings SET series='0' where Player = '$TopPlayer'") or die(mysql_error());
                 } 
    You can combine the last two queries into:
    Code:
    UPDATE standings SET series='0' WHERE Rank=1
    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
                 while ($n >= $WNewRank) {
                      
    $result mysql_query("SELECT * FROM standings where rank = '$n'") or die(mysql_error());
                      while(
    $row mysql_fetch_array($result)) $passedPlayer $row['player'];
                      
    $m $n+1;
                      
    mysql_query("UPDATE standings SET rank='$m' where player = '$passedPlayer'") or die(mysql_error());
                      
    $n--;
                 } 
    Equivalent single query:
    Code:
    UPDATE standings SET Rank=Rank+1 WHERE Rank BETWEEN $WNewRank AND $WOldRank-1
    More to follow.
    Last edited by misson; 12-07-2009 at 02:48 AM. Reason: typo in insertNewPlayer
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  3. #3
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Ghost Players

    Whoops... forgot about this for a bit.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
    function  parseGameInfo($GameID) {
       
    set_time_limit(8000);
       
    $war2gameinfo file('http://server.war2.ru/reports/'.$GameID);
       
    $war2gameinfotxt implode('',$war2gameinfo); 
    Use file_get_contents rather than file+implode.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
       if (preg_match('/mapauth=\"Self-Made\"/'$war2gameinfotxt) == && preg_match('/DRAW/'$war2gameinfotxt) == 0
       
    && preg_match('/DISCONNECT/'$war2gameinfotxt) == 0)
       {
            if (
    preg_match('/  LOSS/'$war2gameinfotxt) == 0) {
                 return 
    0;
            }
            if (
    preg_match('/  WIN/'$war2gameinfotxt) == 0) {
                 return 
    0;
            } 
    "\s" is safer than a plain space character because "\s" will also match tabs.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
            $startHere strstr($war2gameinfotxt,'joins=');
            
    $line explode("\n"$startHere); 
    Since you never go through most of the lines, this is wasteful. Since you only seem to be using it to look for "LOSS" and "WIN", I'd use a regexp.

    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
                preg_match('/mapfile=\".+\.pud\"/'$war2gameinfotxt$mapmatch);
                
    $map substr($mapmatch[0], 9, -5); 
    No need for the call to substr, just use grouping:
    PHP Code:
                preg_match('/mapfile=\"(.+)\.pud\"/'$war2gameinfotxt$mapmatch);
                
    $map $mapmatch[1]; 
    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
                $throwAway preg_match_all('/\d+ for Units/'$startHere$matches);
                
    $n 0;
                while (
    $n $PlayerCount)
                {${
    'Player'.($n+1)} = preg_split("/\s+/"$line[3+$n]);${'Player'.($n+1)}[2] = $matches[0][$n]; if (${'Player'.($n+1)}[2] > && ${'Player'.($n+1)}[1] == 'LOSS'$Loser = ${'Player'.($n+1)}[0]; if (${'Player'.($n+1)}[2] > && ${'Player'.($n+1)}[1] == 'WIN')
                       
    $Winner = ${'Player'.($n+1)}[0];
                    
    $n++;
                }
            } 
    I was meaning to say this earlier, but all those statements on one line isn't very readable.

    $matches is an array of strings, so $matches holds a string like "330 for Units". Change the regexp to use grouping (/(\d+) for Units/) and reference $matches[1][$n].

    Multi-dimensional arrays are a little neater than variable variables:
    PHP Code:
                $Players=array();
                for (
    $n=0$n $PlayerCount; ++$n) {
                    
    $Players[$n] = preg_split("/\s+/"$line[3+$n]);
                    
    $Players[$n]['unitScore'] = $matches[0][$n]; 
                    if (
    $Players[$n]['unitScore'] > && $Players[$n][1] == 'LOSS'
                        
    $Loser $Players[$n][0];
                    if (
    $Players[$n]['unitScore'] > && $Players[$n][1] == 'WIN')
                        
    $Winner $Players[$n][0];
                } 
    or (using a regexp rather than $line):
    PHP Code:
                preg_match_all('/^\s*(\S*)\s+(LOSS|WIN)\s*$/m'$startHere$PlayersPREG_SET_ORDER);
                foreach (
    $Players as $n => &$Player) {
                    
    $Player['unitScore'] = $matches[0][$n]; 
                    if (
    $Player['unitScore'] > && $Player[2] == 'LOSS'
                        
    $Loser $Player[1];
                    if (
    $Player['unitScore'] > && $Player[2] == 'WIN')
                        
    $Winner $Player[1];
                } 
    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
            else {
                return 
    0;
            }
        } else {
            return 
    0;
        } 
    Can you tell what these cases cover at this point? Either add a comment explaining each case, or change the conditions and switch the if and else blocks so that the short case immediately follows the if.
    Last edited by misson; 12-07-2009 at 02:09 AM.
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  4. #4
    garrensilverwing's Avatar
    garrensilverwing is offline x10 Sophmore garrensilverwing is an unknown quantity at this point
    Join Date
    Nov 2008
    Posts
    148

    Re: Ghost Players

    sorry for the mixed cases, i was in the middle of changing them all when i decided to post on here, i thought the example game was vanwilder but i guess its bibifock[is] instead...i'll go through all your suggestions and clean it up, this was originally coded by my friend so its still confusing to me haha thanks a bunch misson!

    as far as the if/else statement blocks go, i had to reduce the number of characters in the post so i took the comments out, sorry for the confusion

    here are a list of games that actually produce ghost players:

    http://server.war2.ru/reports/gr_20091201193149_025685
    http://server.war2.ru/reports/gr_20091201203339_025726
    http://server.war2.ru/reports/gr_20091201223149_025853
    http://server.war2.ru/reports/gr_20091201224435_025884
    http://server.war2.ru/reports/gr_20091201233500_025964
    http://server.war2.ru/reports/gr_20091202003142_026062
    http://server.war2.ru/reports/gr_20091202004918_026086
    http://server.war2.ru/reports/gr_20091202050006_000016
    Edit:
    I worked all day on fixing all the problems the code has, including changing a lot of what you said misson, but i'm still having a problem with the ghost games here is the new code, and just above this is a list of game reports that produce ghost players:

    Code:
    function  parseGameInfo($GameID)
    		{
    			set_time_limit(8000);
    			$DateT = substr($GameID, 3, 14);
    			$war2gameinfotxt = file_get_contents('http://server.war2.ru/reports/'.$GameID);
    			if (preg_match('/mapauth=\"Self-Made\"/', $war2gameinfotxt) == 0 && preg_match('/DRAW/', $war2gameinfotxt) == 0
    			&& preg_match('/DISCONNECT/', $war2gameinfotxt) == 0)
    				{
    					if (preg_match('/\sLOSS/', $war2gameinfotxt) == 0)
    					{
    						return 0;
    					}
    					if (preg_match('/\sWIN/', $war2gameinfotxt) == 0)
    					{
    						return 0;
    					}
    					$startHere = strstr($war2gameinfotxt,'joins=');
    					$line = explode("\n", $startHere);
    					$joinCount = substr($startHere, 6, 1);
    					$englishCount = preg_match_all('/\sand played for/', $startHere, $matches);
    					if ($englishCount < $joinCount)
    						{		  
    							return 0;
    						}
    					$watcherCount = preg_match_all('/\s1 for Units/', $startHere, $matches);
    					$PlayerCount = $joinCount - $watcherCount;
    					if ($PlayerCount == 2)
    						{
    							preg_match('/mapfile=\"(.+)\.pud\"/', $war2gameinfotxt, $mapmatch);
    							$map = $mapmatch[1];  
    							$throwAway = preg_match_all('/\d+ for Units/', $startHere, $matches);
    							$n = 0;
    							/* While loop: creates a variable Player1 first time through, Player2 second time through.
    								Sets Player1[0] to the first Player's name, [1] to the result, [2] to his units.
    								Sets Player2[0] to the second Player's name, etc.
    								If Player's units are more than 1, and he lost or disconnected, his name is set to $Loser.
    								If Player's units are more than 1, and he won, his name is set to $Winner.
    							*/
    					preg_match_all('/^(.*)\s+(LOSS)$/', $startHere, $Players, PREG_SET_ORDER);
    					$Players=array();
    					for ($n=0; $n < $PlayerCount; ++$n) 
    						{
    						$Players[$n] = preg_split("/\s+/", $line[3+$n]);
    						$Players[$n]['unitScore'] = $matches[0][$n]; 
    						if ($Players[$n]['unitScore'] > 1 && $Players[$n][1] == 'LOSS') 
    							$Loser = $Players[$n][0];
    						if ($Players[$n]['unitScore'] > 1 && $Players[$n][1] == 'WIN')
    							$Winner = $Players[$n][0];
    						}  
    					}
    					 else		//If there are more than two players (non-watchers)
    					 {
    						  return 0;
    					 }
    				}
    				else		//If a player (non-watcher) was disconnected
    					{
    						return 0;
    					}
    			if($Winner == "" OR $Loser == "")
    				{
    					echo "\n<li><a href=\"http://server.war2.ru/reports/$GameID\">http://server.war2.ru/reports/$GameID</a></li>";
    					mysql_query("INSERT INTO ghostgames (GameID) VALUES('$GameID');");
    				}
    			else 
    				{
    					insertLadderGame($GameID, $map, $Winner, $Loser, $DateT);
    				}
    			return 0;
    		}
    Last edited by garrensilverwing; 12-07-2009 at 12:20 AM. Reason: Automerged Doublepost

  5. #5
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Ghost Players

    Try the [php] tags rather than [code] when posting PHP. It will colorize your code, making it easier to read and spot certain errors.

    One area to focus on when cleaning up is the ranking logic. See if you can write a more logical breakdown, reworking it into higher-level tasks that will be implemented as functions. That section is ripe for logic errors.

    As for the missing players, look to:
    Quote Originally Posted by garrensilverwing View Post
    PHP Code:
    function  parseGameInfo($GameID) {
        ...
                
    preg_match_all('/^(.*)\s+(LOSS)$/'$startHere$PlayersPREG_SET_ORDER);
                
    $Players=array();
                for (
    $n=0$n $PlayerCount; ++$n) {
                    
    $Players[$n] = preg_split("/\s+/"$line[3+$n]);
                    
    $Players[$n]['unitScore'] = $matches[0][$n]; 
                    
    var_dump($Players[$n]);
                    if (
    $Players[$n]['unitScore'] > && $Players[$n][1] == 'LOSS'
                        
    $Loser $Players[$n][0];
                    if (
    $Players[$n]['unitScore'] > && $Players[$n][1] == 'WIN')
                        
    $Winner $Players[$n][0];
                } 
    This loops over the number of players, rather than the number of joined people. With two players and four people (two watchers), only the first two people are considered. You could loop over $joinCount, but I recommend replacing the loop (and deleting the explode of $startHere into $lines) with preg_match_all as I showed in the last post. Here it is again:
    PHP Code:
                preg_match_all('/^\s*(\S+)\s+(LOSS|WIN)\s*$/m'$startHere$PlayersPREG_SET_ORDER);
                
    var_dump($Players);
                foreach (
    $Players as $n => &$Player) {
                    
    $Player['unitScore'] = $matches[0][$n]; 
                    if (
    $Player['unitScore'] > && $Player[2] == 'LOSS'
                        
    $Loser $Player[1];
                    if (
    $Player['unitScore'] > && $Player[2] == 'WIN')
                        
    $Winner $Player[1];
                } 
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  6. #6
    garrensilverwing's Avatar
    garrensilverwing is offline x10 Sophmore garrensilverwing is an unknown quantity at this point
    Join Date
    Nov 2008
    Posts
    148

    Re: Ghost Players

    i made the change to the code as you suggested and it certainly seems to have cut back on the number of ghost games, there used to be roughly 18% ghost games and now only 4%, a huge decrease. if you want to see how everything is working, go to http://war2ladder.x10hosting.com. if you have any ideas on what could still be causing the 4% ghost game problem, it would be hugely appreciated. there are some logic errors or something in the ranking system but i'll open a new topic for that

  7. #7
    misson is offline x10 Spammer misson is a jewel in the rough
    Join Date
    Mar 2008
    Location
    Libertatia
    Posts
    2,506

    Re: Ghost Players

    Post another set of URIs for problem games and the current code, and I'll take a look.
    Be sure to read all pages linked in this post; they have further information that should prove useful. When asking for help, make sure you follow Eric Raymond's and Jon Skeet's guidelines for prompt, accurate responses. Please answer any questions I ask; they're not rhetorical (probably). Any posted code is intended as illustrative example, rather than a solution to your problem to be copied without alteration. Study it to learn how to write your own solution.
    Misson, not Mission.

  8. #8
    garrensilverwing's Avatar
    garrensilverwing is offline x10 Sophmore garrensilverwing is an unknown quantity at this point
    Join Date
    Nov 2008
    Posts
    148

    Re: Ghost Players

    http://server.war2.ru/reports/gr_20091202224058_000869
    http://server.war2.ru/reports/gr_20091207063748_003914
    http://server.war2.ru/reports/gr_20091207062354_003887
    http://server.war2.ru/reports/gr_20091207061558_003901
    http://server.war2.ru/reports/gr_20091207061022_003881
    http://server.war2.ru/reports/gr_20091207055250_003852
    http://server.war2.ru/reports/gr_20091206072941_002253
    http://server.war2.ru/reports/gr_20091206071344_002226
    http://server.war2.ru/reports/gr_20091206061809_002136
    http://server.war2.ru/reports/gr_20091206055702_002117
    http://server.war2.ru/reports/gr_20091206053854_002082
    http://server.war2.ru/reports/gr_20091206053044_002090
    http://server.war2.ru/reports/gr_20091206014511_001723
    http://server.war2.ru/reports/gr_20091205121152_000859
    http://server.war2.ru/reports/gr_20091204235407_003890
    http://server.war2.ru/reports/gr_20091204233118_003856
    http://server.war2.ru/reports/gr_20091204072849_003055
    http://server.war2.ru/reports/gr_20091203072839_001582
    http://server.war2.ru/reports/gr_20091202231005_000886

    PHP Code:
         function  parseGameInfo($GameID)
            {
                
    set_time_limit(8000);
                
    $DateT substr($GameID314);
                
    $war2gameinfotxt file_get_contents('http://server.war2.ru/reports/'.$GameID);
                if (
    preg_match('/mapauth=\"Self-Made\"/'$war2gameinfotxt) == && preg_match('/DRAW/'$war2gameinfotxt) == 0
                
    && preg_match('/DISCONNECT/'$war2gameinfotxt) == 0)
                    {
                        if (
    preg_match('/\sLOSS/'$war2gameinfotxt) == 0)
                        {
                            return 
    0;
                        }
                        if (
    preg_match('/\sWIN/'$war2gameinfotxt) == 0)
                        {
                            return 
    0;
                        }
                        
    $startHere strstr($war2gameinfotxt,'joins=');
                        
    $line explode("\n"$startHere);
                        
    $joinCount substr($startHere61);
                        
    $englishCount preg_match_all('/\sand played for/'$startHere$matches);
                        if (
    $englishCount $joinCount)
                            {          
                                return 
    0;
                            }
                        
    $watcherCount preg_match_all('/\s1 for Units/'$startHere$matches);
                        
    $PlayerCount $joinCount $watcherCount;
                        if (
    $PlayerCount == 2)
                            {
                                
    preg_match('/mapfile=\"(.+)\.pud\"/'$war2gameinfotxt$mapmatch);
                                
    $map $mapmatch[1];  
                                
    $throwAway preg_match_all('/\d+ for Units/'$startHere$matches);
                                
    $n 0;
                                
    /* While loop: creates a variable Player1 first time through, Player2 second time through.
                                    Sets Player1[0] to the first Player's name, [1] to the result, [2] to his units.
                                    Sets Player2[0] to the second Player's name, etc.
                                    If Player's units are more than 1, and he lost or disconnected, his name is set to $Loser.
                                    If Player's units are more than 1, and he won, his name is set to $Winner.
                                */
                                
    preg_match_all('/^\s*(\S+)\s+(LOSS|WIN)\s*$/m'$startHere$PlayersPREG_SET_ORDER);
                                
    var_dump($Players);
                                foreach (
    $Players as $n => &$Player
                                    {
                                        
    $Player['unitScore'] = $matches[0][$n]; 
                                        if (
    $Player['unitScore'] > && $Player[2] == 'LOSS'
                                            
    $Loser $Player[1];
                                        if (
    $Player['unitScore'] > && $Player[2] == 'WIN')
                                            
    $Winner $Player[1];
                                    }  
                            }
                         else        
    //If there are more than two players (non-watchers)
                         
    {
                              return 
    0;
                         }
                    }
                    else        
    //If a player (non-watcher) was disconnected
                        
    {
                            return 
    0;
                        }
                if(
    $Winner == "" OR $Loser == "")
                    {
                        
    mysql_query("INSERT INTO ghostgames (GameID) VALUES('$GameID');");
                    }
                else 
                    {
                        
    insertLadderGame($GameID$map$Winner$Loser$DateT);
                        return 
    0;
                    }
                return 
    0;
            } 
    Last edited by garrensilverwing; 12-07-2009 at 02:56 PM.

  9. #9
    descalzo's Avatar
    descalzo is offline Grim Squeaker descalzo has a brilliant futuredescalzo has a brilliant futuredescalzo has a brilliant future
    Join Date
    Jul 2009
    Location
    Ankh-Morpork
    Posts
    7,636

    Re: Ghost Players

    Code:
    preg_match_all('/^\s*(\S+)\s+(LOSS|WIN)\s*$/m',
        $startHere, $Players, PREG_SET_ORDER);
    Will not match lines like ....

    Code:
     
    NINJA_STRYKE     LOSS     rating=895 [#00000]  prob=35.3%  K=50  adj=-17
    ArRoW            WIN      rating=1000 [#00000]  prob=64.7%  K=50  adj=+17
    The rating=895 [#00000] prob=35.3% K=50 adj=-17 part makes it a no-match.

    I think that covers a lot of the problem files.

  10. #10
    garrensilverwing's Avatar
    garrensilverwing is offline x10 Sophmore garrensilverwing is an unknown quantity at this point
    Join Date
    Nov 2008
    Posts
    148

    Re: Ghost Players

    yeah actually me and the other guy noticed that too, but there are a couple files that are still problematic that don't have those extra lines

+ Reply to Thread
Page 1 of 2 12 LastLast

Similar Threads

  1. Role Players wanted for discussion
    By Any_Key in forum Off Topic
    Replies: 1
    Last Post: 04-09-2009, 05:11 PM
  2. Empire Games
    By thesims3mods in forum Gamer's Lounge
    Replies: 1
    Last Post: 02-07-2009, 03:39 PM
  3. The new Rainbow Six and Ghost Rechon for XBOX 360
    By apple19 in forum Gamer's Lounge
    Replies: 5
    Last Post: 12-20-2006, 03:54 PM
  4. Ghost Orbs
    By cky2k1016 in forum Off Topic
    Replies: 5
    Last Post: 06-06-2006, 10:07 PM
  5. Looking for Ogame players
    By elforo in forum Gamer's Lounge
    Replies: 1
    Last Post: 03-07-2006, 05:44 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
x10hosting free hosting for the masses
dedicated servers