Location: PHPKode > scripts > Gear Score Calculator > GearScore.php
<?php

/**
 * Elad Nava
 * GearScore Calculator
 *
 * @author 		$Author: Elad Nava $
 * @copyright	(c) 2010 Elad Nava
 * @link				http://invisionize.com
 * @version		1.0.0
 * @desc			This is my personal GearScore Calculator class,
 *						I created it specifically for one of my IPB3 applications,
 *						but I believe it could be used in other ways as well.
 *
 *						This class calculates an identical GearScore to that of the in-game addon,
 *						"GearScore". An example of this class in use is Wtfismygearscore.com. 
 *
 *						I am not affiliated in any way with the author of the in-game addon "GearScore".
 */

/*
========= Example Usage ========= 

<?php

	//--------------------------------
	// Initiate GearScore Class
	//--------------------------------

	if ( ! class_exists( 'GearScore' ) )
	{
		require_once( 'GearScore.php' );
	}
	
	$GearScore = new GearScore();
	
	//--------------------------------------
	// Fill in the variables
	//--------------------------------------
	
	$region		= ""; 						// Game region. E.g. "US", "EU", "KR", "CN", "TW"
	$realm		= "";						// Character's realm name. E.g. "Lightning's Blade", "Aerie Peak"
	$character = "";						// Character's in-game name. E.g. "Chromie"
	
	$score = $GearScore->getCharacterScore( $character, $realm, $region );
	
	// $score now contains the character's current GearScore
	// The actual items calculated are the ones from last log off,
	// This is when the armory updates the character's items.

?>

*/

class GearScore
{
	protected $slotMod 	= array();
	protected $gsFormula 	= array();

	public function __construct()
	{
		$this->gsFormula = array(
		
											// 0 is used for iLevel < 120
											
											0 		=> array(
																	2 => array( 73.0000, 1.0000 ),
																	3 => array( 81.3750, 0.8125 ),
																	4 => array( 91.4500, 0.6500 ),
																),
											
											// 1 is used for iLevel >= 120
											
											1	=> array( 
																	1 => array( 0.0000, 2.2500 ),
																	2 => array( 8.0000, 2.0000 ),
																	3 => array( 0.7500, 1.8000 ),
																	4 => array( 26.000, 1.2000 ),
																)
										 );	
										 
		//----------------------------------------
		// slotMod nerfs itemScore by slot
		//
		// 100 is used for Two-Handers
		//----------------------------------------
										
		$this->slotMod = array(
											1 		=> 1.0000,
											2 		=> 0.5625,
											3 		=> 0.7500,
											5 		=> 1.0000,
											6 		=> 0.7500,
											7 		=> 1.0000,
											8 		=> 0.7500,
											9 		=> 0.5625,
											10		=> 0.7500,
											11		=> 0.5625,
											12		=> 0.5625,
											13		=> 0.5625,
											14		=> 0.5625,
											15		=> 0.5625,
											16 	=> 1.0000,
											17		=> 1.0000,
											18		=> 0.3164,
											100	=> 2.0000,
										);
	}
	
	public function getCharacterScore( $character, $realm, $region = "US" )
	{
		//--------------------------------
		// Get character from Armory
		//--------------------------------
		
		$armoryXML = $this->getCharacterSheet( $character, $realm, $region );
		
		//--------------------------------
		// "Server Busy?"
		//--------------------------------
		
		if ( ! isset( $armoryXML->characterInfo ) )
		{
			$this->fatalError( "There was a problem fetching the character data from the Armory. It is possible that your server has been temporarily suspended if you have made numerous requests in a short amount of time." );
		}
		
		//--------------------------------
		// Set-up $character array
		//--------------------------------
		
		$character = array(
									'items'	=> array(),
									'class'	=> (string)$armoryXML->characterInfo->character['classId']
								  );
		
		//--------------------------------
		// Loop over character items
		//--------------------------------
		
		foreach ( $armoryXML->characterInfo->characterTab->items->item as $item )
		{
			//------------------------------------
			// Increment slot for compliance
			// with InventorySlotId (ingame)
			//------------------------------------
			
			$slot = ( (string)$item['slot'] + 1 );
			
			$character['items'][ $slot ] = array(
																'slot'			=> $slot,
																'level'		=> (string)$item['level'],
																'rarity'		=> (string)$item['rarity'],
															);
		}
		
		//--------------------------------
		// Calculate and return score
		//--------------------------------
		
		return $this->calculateGearScore( $character );
	}
	
	public function calculateGearScore( $character )
	{
		//--------------------------------
		// INIT
		//--------------------------------
		
		$GearScore = 0;
		
		foreach ( $character['items'] as $slot => $item )
		{
			//--------------------------------
			// Filter items (Shirt, Tabard)
			//--------------------------------
			
			if ( array_key_exists( $slot, $this->slotMod ) )
			{
				//--------------------------------
				// Bearing a 2-hander?
				//--------------------------------
				
				if ( $slot == 16 && ! isset( $character['items'][17] ) )
				{
					//--------------------------------
					// Double GS for 2-hander
					//--------------------------------
					
					$item['slot'] = 100;
				}
				
				//--------------------------------
				// Get the specific item's GS
				//--------------------------------
				
				$itemScore = $this->getItemScore( $item );
				
				//--------------------------------
				// Hunter weapon GS nerf
				//--------------------------------
				
				if ( $character['class'] == 3 )
				{
					if ( $slot == 16 || $slot == 17 )
					{
						$itemScore *= 0.3164;
					}
					
					if ( $slot == 18 )
					{		
						$itemScore *= 5.3224;
					}
				}
				
				//--------------------------------
				// Add to total GS and iLevel
				//--------------------------------
				
				$GearScore += $itemScore;
			}
		}
		
		//--------------------------------
		// Negative GS is illegal
		//--------------------------------
		
		if ( $GearScore <= 0 )
		{
			$GearScore = 0;
		}
		
		//--------------------------------
		// Floor the final score
		//--------------------------------
		
		$GearScore = floor( $GearScore );
		
		//--------------------------------
		// Return character GearScore
		//--------------------------------

		return $GearScore;
	}
	
	public function getItemScore( $item )
	{
		//--------------------------------
		// INIT
		//--------------------------------
	
		$scale 			= 1.8618;
		$itemScore 	= 0;
		$qualityScale 	= 1;
		
		//--------------------------------
		// Change some variables
		//--------------------------------
		
		if ( $item['rarity'] == 5 )
		{
		 	$qualityScale 		= 1.3;			 	
		 	$item['rarity'] 	= 4;
		}	
		else if ( $item['rarity'] == 1 || $item['rarity'] == 0 )
		{
			$qualityScale 		= 0.005;
			$item['rarity'] 	= 2;
		}
		else if ( $item['rarity'] == 7 )
		{
			$item['level'] 		= 187.05;
			$item['rarity'] 	= 3;
		}
		
		//----------------------------------
		// Use special formula if > 120
		//----------------------------------

		if ( $item['level'] > 120 )
		{
			$formula = $this->gsFormula[0];
		}
		else
		{
			$formula = $this->gsFormula[1];
		}
		
		//----------------------------------
		// The actual calculation!
		//----------------------------------
		         
         $itemScore = floor( ( ( $item['level'] - $formula[ $item['rarity'] ][0] ) / $formula[ $item['rarity'] ][1] ) * $this->slotMod[ $item['slot'] ] * $scale * $qualityScale );
		
		if ( $itemScore < 0 )
		{
			$itemScore = 0;
		}
		
		return $itemScore;
	}
	
	public function fatalError( $error )
	{
		print "<h1>GearScore Fatal Error</h1>{$error} Please contact the Webmaster.";
		exit();
	}
	
	public function getCharacterSheet( $character, $realm, $region )
	{
		//--------------------------------
		// INIT
		//--------------------------------
		
		$realm 		= trim( urlencode( $realm ) );
		$character = trim( urlencode( $character ) );
		
		if ( ! $character || ! $realm || ! $region )
		{
			$this->fatalError( "Invalid call to getCharacterSheet(): Missing an important parameter!" );
		}
		
		//--------------------------------
		// Build URL
		//--------------------------------
		
		switch( strtolower( $region ) )
		{
			case 'us':
				$url = "http://www.wowarmory.com/";
			break;
			case 'eu':
				$url = "http://eu.wowarmory.com/";
			break;
			case 'kr':
				$url = "http://kr.wowarmory.com/";
			break;
			case 'cn':
				$url = "http://cn.wowarmory.com/";
			break;
			case 'tw':
				$url = "http://tw.wowarmory.com/";
			break;
			default:
				$url = "http://www.wowarmory.com/";
			break;
		}
		
		$url .= "character-sheet.xml?r={$realm}&cn={$character}";
	
		$armory 	= parse_url($url);
		$headers 	= array();
		
		//--------------------------------
		// Open connection to armory
		//--------------------------------
		
		$transfer = fsockopen( $armory['host'], 80, $errno, $errstr, 5 ); 
				
		//--------------------------------
		// Set-up headers
		//--------------------------------
		
		$headers[] = "GET {$armory['path']}?{$armory['query']} HTTP/1.0";
		$headers[] = "Host: {$armory['host']}";
		$headers[] = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
		$headers[] = "Accept-Language: en-us, en;q=0.50";
		$headers[] = "Connection: Close";
		
		//--------------------------------
		// Converge into string
		//--------------------------------
		
		$send = implode( "\r\n", $headers ) . "\r\n\r\n";
		
		//--------------------------------
		// Send headers
		//--------------------------------
		
		fwrite( $transfer, $send );
		
		//--------------------------------
		// Get response XML
		//--------------------------------
		
		while ( $transfer && ! feof( $transfer ) )
		{
			$headerbuffer = fgets($transfer, 1024);
			
			if ( urlencode( $headerbuffer ) == "%0D%0A" )
			{
				break;
			}
		}
		
		$xml = '';
		
		while ( ! feof( $transfer ) )
		{
			$xml .= fgets( $transfer, 1024 );
		}
		
		//--------------------------------
		// Close connection
		//--------------------------------
		
		fclose( $transfer );
		
		//--------------------------------
		// Return XML
		//--------------------------------
		
		return simplexml_load_string( $xml );
	}
}

?>
Return current item: Gear Score Calculator