Difference between revisions of "Talk:WebAPI/GetPlayerItems"

From Team Fortress Wiki
Jump to: navigation, search
(PHP on Windows)
(PHP on Windows)
Line 10: Line 10:
 
:If it is equipped by the Pyro, ''$equippedPyro'' will be 64, otherwise it will be 0. Obviously, you're going to want to come up with a function that does this for you instead of having a whole bunch of "equipped" variables, but the point stands. -- [[Image:User Alex2539 Sig.png|47px|link=User:Alex2539|Alex2539]] - {{mod}} <sub>([[User_talk:Alex2539|talk]] | [[Special:Contributions/Alex2539|contribs]])</sub> -- 18:49, 24 November 2010 (UTC)
 
:If it is equipped by the Pyro, ''$equippedPyro'' will be 64, otherwise it will be 0. Obviously, you're going to want to come up with a function that does this for you instead of having a whole bunch of "equipped" variables, but the point stands. -- [[Image:User Alex2539 Sig.png|47px|link=User:Alex2539|Alex2539]] - {{mod}} <sub>([[User_talk:Alex2539|talk]] | [[Special:Contributions/Alex2539|contribs]])</sub> -- 18:49, 24 November 2010 (UTC)
 
::Sure, the binary value is the same. But when parsing it from a string using json_decode() (or even loading it from MySQL), it ends up as a string because it's too big to be an int. [[User:Netshroud|Netshroud]] 23:22, 24 November 2010 (UTC)
 
::Sure, the binary value is the same. But when parsing it from a string using json_decode() (or even loading it from MySQL), it ends up as a string because it's too big to be an int. [[User:Netshroud|Netshroud]] 23:22, 24 November 2010 (UTC)
 +
:::PHP automatically converts between data types if possible when necessary. It doesn't matter that the value is coming from a string. I promise you, this works. Here, I've cut out bits from my own code to prove to you that this works. This script will output the info for every item in a given backpack. You just need to supply your own API key and a profile number:
 +
<pre><?php
 +
$APIkey = ''; // Use your own API key here
 +
$profile = ''; // Find some profile number and place it here
 +
 +
// Put together the URL for the backpack
 +
$backpackURL = "http://api.steampowered.com/ITFItems_440/GetPlayerItems/v0001/?key=" . $APIkey . "&SteamID=" . $profile . "&format=json";
 +
 +
// Download and decode the json file
 +
$userBackpack = json_decode(file_get_contents($backpackURL), true);
 +
 +
$result = $userBackpack['result'];
 +
$items = $result['items'];
 +
 +
// Iterate through each item
 +
foreach($items['item'] as $ind=>$item) {
 +
// Store all of the item's information in separate variables
 +
$id =  $item['id'];
 +
$defindex = $item['defindex'];
 +
$level = $item['level'];
 +
$quantity = $item['quantity'];
 +
$flag_cannot_trade = (array_key_exists('flag_cannot_trade', $item) ? $item['flag_cannot_trade'] : false);
 +
$inventory = $item['inventory']; // The inventory value is stored just like all of the others
 +
$position = $inventory & 65535; // You can directly perform bitwise operations on the value. PHP understands that you mean this to be a number
 +
$equipped = ($inventory >> 16) & 1023; // More bitwise operations to get the equipped number
 +
$equippedString = getEquipped($equipped); // Convert the equipped number into a string
 +
$quality = $item['quality'];
 +
 +
// Print out everything. It's ugly, but it does the job.
 +
echo "
 +
ID: $id <br/>
 +
Defindex: $defindex <br/>
 +
Level: $level <br/>
 +
Quantity: $quantity <br/>
 +
Cannot trade: $flag_cannot_trade <br/>
 +
Inventory: $inventory <br/>
 +
&nbsp;&nbsp;&nbsp;&nbsp;Position: $position <br/>
 +
&nbsp;&nbsp;&nbsp;&nbsp;Equipped: $equipped - $equippedString <br/>
 +
Quality: $quality <br/>
 +
<br/>";
 +
}
 +
 +
function getEquipped($equipNumber) {
 +
// Create an array with all of the classes in the proper order
 +
$classList = array(0=>'Scout', 'Sniper', 'Soldier', 'Demoman', 'Medic', 'Heavy', 'Pyro', 'Spy', 'Engineer');
 +
// Start with an empty string
 +
$equippedString = '';
 +
for ($i = 0; $i < 10; $i++) {
 +
if ((1<<$i) & $equipNumber) { // Check that the class's bit appears in the number
 +
if ($equippedString)
 +
$equippedString .= ', '; // If the string is not empty, add a comma
 +
 +
$equippedString .= $classList[$i]; // Add the name of the class to the string if it is equipped by that class
 +
}
 +
}
 +
if (!$equippedString)
 +
$equippedString = 'None'; // The string is "None" if no one has it equipped
 +
return $equippedString;
 +
}
 +
?></pre>
 +
As you can see, I'm getting all of the information from json_decode and the inventory number is easily split into its two components. Also, the''$equipped'' variable is passed to the ''getEquipped()'' function which handily returns a string listing the classes that have the item equipped (or "None" when no one has it equipped). Just to make sure this works, I tested it on my own profile and set an item in both extremes: one in position 1 with no one equipping it and one in position 200 with everyone equipping it. Both returned perfect values, as did every item in between. -- [[Image:User Alex2539 Sig.png|47px|link=User:Alex2539|Alex2539]] - {{mod}} <sub>([[User_talk:Alex2539|talk]] | [[Special:Contributions/Alex2539|contribs]])</sub> -- 22:24, 25 November 2010 (UTC)

Revision as of 22:24, 25 November 2010

PHP on Windows

It's not easy to extract the backpack position or perform any other operations on the inventory bitmask, as PHP_INT_MAX on Windows (even 64-bit) is 2147483647 (2^31 - 1) and PHP does not support unsigned integers. Netshroud 06:48, 24 November 2010 (UTC)

Sure it is. No matter what the integer value is, the binary value is the same. 4294967295 as an unsigned 32-bit integer has exactly the same binary representation as -1 as a signed 32-bit integer (32 ones). It doesn't matter that PHP only supports signed integers since you typically will never want to deal with the entire integer value directly anyway. Once you split the inventory value into its two 16-bit components, it is very simple to deal with.
Assuming the entire inventory value (ie: both backpack position and equipped values) is stored in $inventory, then you can split it into $position and $equipped like this:
$position = $inventory & 65535;
$equipped = ($inventory >> 16) & 511; //I only took the first 9 bits since there are only 9 classes. 
Using this will make $position equal to the numerical value of the position in the backpack (ie: between 1 and 200 inclusive) and $equipped will represent the classes that have the item equipped, as demonstrated in the schema. That is, each class is assigned a power of 2 and that number is the sum of all of the classes that are equipping it. For example, if both the Scout and the Demoman have the Ghastly Gibus equipped, then the Gibus would get an $equipped value of 9: the Scout's number is 1 and the Demoman's is 8. To find out if a class has an item equipped, you just need to do something like this:
$equippedPyro = $equipped & 64;
If it is equipped by the Pyro, $equippedPyro will be 64, otherwise it will be 0. Obviously, you're going to want to come up with a function that does this for you instead of having a whole bunch of "equipped" variables, but the point stands. -- Alex2539 - (talk | contribs) -- 18:49, 24 November 2010 (UTC)
Sure, the binary value is the same. But when parsing it from a string using json_decode() (or even loading it from MySQL), it ends up as a string because it's too big to be an int. Netshroud 23:22, 24 November 2010 (UTC)
PHP automatically converts between data types if possible when necessary. It doesn't matter that the value is coming from a string. I promise you, this works. Here, I've cut out bits from my own code to prove to you that this works. This script will output the info for every item in a given backpack. You just need to supply your own API key and a profile number:
<?php
	$APIkey = ''; // Use your own API key here
	$profile = ''; // Find some profile number and place it here
	
	// Put together the URL for the backpack
	$backpackURL = "http://api.steampowered.com/ITFItems_440/GetPlayerItems/v0001/?key=" . $APIkey . "&SteamID=" . $profile . "&format=json";
	
	// Download and decode the json file
	$userBackpack = json_decode(file_get_contents($backpackURL), true);
	
	$result = $userBackpack['result'];
	$items = $result['items'];
	
	// Iterate through each item
	foreach($items['item'] as $ind=>$item) {
		// Store all of the item's information in separate variables
		$id =  $item['id'];
		$defindex = $item['defindex'];
		$level = $item['level'];
		$quantity = $item['quantity'];
		$flag_cannot_trade = (array_key_exists('flag_cannot_trade', $item) ? $item['flag_cannot_trade'] : false); 
		$inventory = $item['inventory']; // The inventory value is stored just like all of the others
		$position = $inventory & 65535; // You can directly perform bitwise operations on the value. PHP understands that you mean this to be a number
		$equipped = ($inventory >> 16) & 1023; // More bitwise operations to get the equipped number
		$equippedString = getEquipped($equipped); // Convert the equipped number into a string
		$quality = $item['quality'];
		
		// Print out everything. It's ugly, but it does the job.
		echo "
			ID: $id <br/>
			Defindex: $defindex <br/>
			Level: $level <br/>
			Quantity: $quantity <br/>
			Cannot trade: $flag_cannot_trade <br/>
			Inventory: $inventory <br/>
			    Position: $position <br/>
			    Equipped: $equipped - $equippedString <br/>
			Quality: $quality <br/>
			<br/>";
	}
	
	function getEquipped($equipNumber) {
		// Create an array with all of the classes in the proper order
		$classList = array(0=>'Scout', 'Sniper', 'Soldier', 'Demoman', 'Medic', 'Heavy', 'Pyro', 'Spy', 'Engineer');
		// Start with an empty string
		$equippedString = '';
		for ($i = 0; $i < 10; $i++) {
			if ((1<<$i) & $equipNumber) { // Check that the class's bit appears in the number
				if ($equippedString)
					$equippedString .= ', '; // If the string is not empty, add a comma
					
				$equippedString .= $classList[$i]; // Add the name of the class to the string if it is equipped by that class
			}
		}
		if (!$equippedString)
			$equippedString = 'None'; // The string is "None" if no one has it equipped
		return $equippedString; 
	}	
?>

As you can see, I'm getting all of the information from json_decode and the inventory number is easily split into its two components. Also, the$equipped variable is passed to the getEquipped() function which handily returns a string listing the classes that have the item equipped (or "None" when no one has it equipped). Just to make sure this works, I tested it on my own profile and set an item in both extremes: one in position 1 with no one equipping it and one in position 200 with everyone equipping it. Both returned perfect values, as did every item in between. -- Alex2539 - (talk | contribs) -- 22:24, 25 November 2010 (UTC)