During some testing with a Battlefield 2 server, I noticed that the server will send partial keys at the end of a packet in rare cases. The following packet will start with the same (now complete) key and the value. In GameDig, these partial keys completely throw off parsing of the packet (see gamedig/node-gamedig#708).
I noticed that GameQ seems to handle this case, cleaning up the partial key.
|
// Compare last var of current packet with first var of next packet |
|
// On a partial match, remove last var from current packet, |
|
// variable header from next packet |
|
for ($i = 0, $x = $packetCount; $i < $x - 1; $i++) { |
|
// First packet |
|
$fst = substr($packets[$i], 0, -1); |
|
// Second packet |
|
$snd = $packets[$i + 1]; |
|
// Get last variable from first packet |
|
$fstvar = substr($fst, strrpos($fst, "\x00") + 1); |
|
// Get first variable from last packet |
|
$snd = substr($snd, strpos($snd, "\x00") + 2); |
|
$sndvar = substr($snd, 0, strpos($snd, "\x00")); |
|
// Check if fstvar is a substring of sndvar |
|
// If so, remove it from the first string |
|
if (!empty($fstvar) && strpos($sndvar, $fstvar) !== false) { |
|
$packets[$i] = preg_replace("#(\\x00[^\\x00]+\\x00)$#", "\x00", $packets[$i]); |
|
} |
|
} |
However, running GameQ against my test server (202.61.196.80:29902) still returns broken data. After some debugging I found that GameQ actually skips the first key from the second package. Instead of comparing the last key of packet n with the first key of packet n+1, the cleanup loop compares it to the second key of packet n+1.
It seems the issue is caused by line 201, which skips the first key (and two more characters). Line 202 then extracts what used to be the second key.
|
// Get first variable from last packet |
|
$snd = substr($snd, strpos($snd, "\x00") + 2); |
|
$sndvar = substr($snd, 0, strpos($snd, "\x00")); |
In my example, I end up with $fstvar = "bf2_sponsorlo" being compared to $sndvar = "bf2_communitylogo_url". Since the keys don't match, the partial key at the end of the first packet is not cleaned up and parsing breaks (complete key from 2nd packet is parsed as value for partial key from first packet).
If I remove line 201, the cleanup extracts $fstvar = "bf2_sponsorlo" and $sndvar = "bf2_sponsorlogo_url" - which do match and thus trigger the cleanup. The second packet is then parsed correctly.
It's entirely possible that the cleanup was built to clean up a different kind of packet split issue. But just going by the comment in line 200, it seems that line 201 was simply added in error.
During some testing with a Battlefield 2 server, I noticed that the server will send partial keys at the end of a packet in rare cases. The following packet will start with the same (now complete) key and the value. In GameDig, these partial keys completely throw off parsing of the packet (see gamedig/node-gamedig#708).
I noticed that GameQ seems to handle this case, cleaning up the partial key.
GameQ/src/GameQ/Protocols/Gamespy3.php
Lines 190 to 208 in 347cf58
However, running GameQ against my test server (
202.61.196.80:29902) still returns broken data. After some debugging I found that GameQ actually skips the first key from the second package. Instead of comparing the last key of packet n with the first key of packet n+1, the cleanup loop compares it to the second key of packet n+1.It seems the issue is caused by line 201, which skips the first key (and two more characters). Line 202 then extracts what used to be the second key.
GameQ/src/GameQ/Protocols/Gamespy3.php
Lines 200 to 202 in 347cf58
In my example, I end up with
$fstvar = "bf2_sponsorlo"being compared to$sndvar = "bf2_communitylogo_url". Since the keys don't match, the partial key at the end of the first packet is not cleaned up and parsing breaks (complete key from 2nd packet is parsed as value for partial key from first packet).If I remove line 201, the cleanup extracts
$fstvar = "bf2_sponsorlo"and$sndvar = "bf2_sponsorlogo_url"- which do match and thus trigger the cleanup. The second packet is then parsed correctly.It's entirely possible that the cleanup was built to clean up a different kind of packet split issue. But just going by the comment in line 200, it seems that line 201 was simply added in error.