public static function LoadTemplate($template_name, $overall = false)
 {
     if ($overall) {
         $template = __ARMORYDIRECTORY__ . '/admin/template/overall/overall_' . $template_name . '.php';
     } else {
         $template = __ARMORYDIRECTORY__ . '/admin/template/' . $template_name . '.php';
     }
     if (file_exists($template)) {
         include $template;
     } else {
         Armory::Log()->writeError('%s : unable to find template "%s" (template theme: %s, overall: %d, path: %s)!', __METHOD__, $template_name, self::GetTemplateTheme(), (int) $overall, $template);
     }
 }
Beispiel #2
0
 /**
  * Returns server type ID
  * @category Utils class
  * @access   public
  * @param    string $server
  * @return   int
  **/
 public function GetServerTypeByString($server)
 {
     $server = strtolower($server);
     if ($server == 'mangos') {
         return SERVER_MANGOS;
     } elseif ($server == 'trinity') {
         return SERVER_TRINITY;
     }
     Armory::Log()->writeError('%s : unsupported server type ("%s")!', __METHOD__, $server);
     return UNK_SERVER;
 }
Beispiel #3
0
 /**
  * Returns extended cost info for $costId cost.
  * @category Mangos class
  * @access   public
  * @param    int $costId
  * @return   array
  **/
 public function GetExtendedCost($costId)
 {
     if ($costId == 0) {
         return false;
     }
     if ($costId < 0) {
         $costId = abs($costId);
     }
     $costInfo = Armory::$aDB->selectRow("SELECT * FROM `ARMORYDBPREFIX_extended_cost` WHERE `id`=%d LIMIT 1", $costId);
     if (!$costInfo) {
         Armory::Log()->writeError('%s : wrong cost id: #%d', __METHOD__, $costId);
         return false;
     }
     $extended_cost = array();
     for ($i = 1; $i < 6; $i++) {
         if ($costInfo['item' . $i] > 0) {
             $extended_cost[$i]['count'] = $costInfo['item' . $i . 'count'];
             $extended_cost[$i]['icon'] = Items::GetItemIcon($costInfo['item' . $i]);
             $extended_cost[$i]['id'] = $costInfo['item' . $i];
         }
     }
     return $extended_cost;
 }
Beispiel #4
0
        die($errorDBVersion);
    }
}
/* Check config version */
if (!defined('CONFIG_VERSION') || !isset(Armory::$armoryconfig['configVersion'])) {
    if (isset(Armory::$armoryconfig['checkVersionType']) && Armory::$armoryconfig['checkVersionType'] == 'log') {
        Armory::Log()->writeError('ArmoryChecker : unable to detect Configuration version!');
    } else {
        die('<b>ConfigVersion error:</b> unable to detect Configuration version!');
    }
} else {
    if (CONFIG_VERSION != Armory::$armoryconfig['configVersion']) {
        $CfgError = sprintf('<b>ConfigVersion error:</b> your config version is outdated (current: %s, expected: %s).<br />
    Please, update your config file from configuration.php.default', Armory::$armoryconfig['configVersion'], CONFIG_VERSION);
        if (isset(Armory::$armoryconfig['checkVersionType']) && Armory::$armoryconfig['checkVersionType'] == 'log') {
            Armory::Log()->writeError('ArmoryChecker : %s', $CfgError);
        } else {
            die($CfgError);
        }
    }
}
/* Check maintenance */
if (Armory::$armoryconfig['maintenance'] == true && !defined('MAINTENANCE_PAGE')) {
    header('Location: maintenance.xml');
    exit;
}
if (!defined('skip_utils_class')) {
    if (!(include __ARMORYDIRECTORY__ . '/includes/classes/class.utils.php')) {
        die('<b>Error:</b> unable to load utils class!');
    }
    $utils = new Utils();
 public function LoadItem($item_entry, $itemGuid = 0, $ownerGuid = 0)
 {
     $item_row = Armory::$wDB->selectRow("SELECT * FROM `item_template` WHERE `entry` = '%d' LIMIT 1", $item_entry);
     if (!$item_row) {
         Armory::Log()->writeError('%s : item #%d (GUID: %d) was not found in `item_template` table.', __METHOD__, $item_entry, $itemGuid);
         return false;
     }
     // FlagsExtra check
     if (isset($item_row['FlagsExtra'])) {
         $item_row['Flags2'] = $item_row['FlagsExtra'];
         unset($item_row['FlagsExtra']);
         // For compatibility
     }
     // Assign variables
     foreach ($item_row as $field => $value) {
         $this->{$field} = $value;
     }
     // Create arrays
     // Item mods
     for ($i = 0; $i < MAX_ITEM_PROTO_STATS + 1; $i++) {
         $key = $i + 1;
         if (isset($this->{'stat_type' . $key})) {
             $this->ItemStat[$i] = array('type' => $this->{'stat_type' . $key}, 'value' => $this->{'stat_value' . $key});
         }
     }
     // Item damages
     for ($i = 0; $i < MAX_ITEM_PROTO_DAMAGES + 1; $i++) {
         $key = $i + 1;
         if (isset($this->{'dmg_type' . $key})) {
             $this->Damage[$i] = array('type' => $this->{'dmg_type' . $key}, 'min' => $this->{'dmg_min' . $key}, 'max' => $this->{'dmg_max' . $key});
         }
     }
     // Item spells
     for ($i = 0; $i < MAX_ITEM_PROTO_SPELLS + 1; $i++) {
         $key = $i + 1;
         if (isset($this->{'spellid_' . $key})) {
             $this->Spells[$i] = array('spellid' => $this->{'spellid_' . $key}, 'trigger' => $this->{'spelltrigger_' . $key}, 'charges' => $this->{'spellcharges_' . $key}, 'ppmRate' => $this->{'spellppmRate_' . $key}, 'cooldown' => $this->{'spellcooldown_' . $key}, 'category' => $this->{'spellcategory_' . $key}, 'categorycooldown' => $this->{'spellcategorycooldown_' . $key});
         }
     }
     // Item sockets
     for ($i = 0; $i < MAX_ITEM_PROTO_SOCKETS + 1; $i++) {
         $key = $i + 1;
         if (isset($this->{'socketColor_' . $key})) {
             $this->Socket[$i] = array('color' => $this->{'socketColor_' . $key}, 'content' => $this->{'socketContent_' . $key});
         }
     }
     $this->m_guid = $itemGuid;
     // Can have NULL value.
     $this->m_owner = $ownerGuid;
     // Can have NULL value.
     $this->loaded = true;
     return true;
 }
Beispiel #6
0
 /**
  * Build opponents list for current arena team
  * @category Arenateams class
  * @access   public
  * @return   array
  **/
 public function BuildOpposingTeamList()
 {
     if (!$this->arenateamid) {
         Armory::Log()->writeError('%s : arenateamid not provided', __METHOD__);
         return false;
     }
     $game_ids = Armory::$cDB->select("SELECT DISTINCT `gameid` FROM `armory_game_chart` WHERE `teamid`=%d", $this->arenateamid);
     if (!$game_ids) {
         Armory::Log()->writeLog('%s : unable to find any game for teamId %d', __METHOD__, $this->arenateamid);
         return false;
     }
     $all_games = array();
     $counter = count($game_ids);
     foreach ($game_ids as $game) {
         $all_games[] = $game['gameid'];
     }
     $game_chart = Armory::$cDB->select("\n        SELECT\n        `armory_game_chart`.`gameid`,\n        `armory_game_chart`.`teamid`,\n        `armory_game_chart`.`guid`,\n        COUNT(`armory_game_chart`.`teamid`) AS `countTeam`,\n        `arena_team`.`name`,\n        `arena_team`.`type`\n        FROM `armory_game_chart` AS `armory_game_chart`\n        LEFT JOIN `arena_team` AS `arena_team` ON `arena_team`.`arenateamid`=`armory_game_chart`.`teamid`\n        WHERE `armory_game_chart`.`gameid` IN (%s) AND `armory_game_chart`.`teamid` <> %d\n        GROUP BY `armory_game_chart`.`gameid`", $all_games, $this->arenateamid);
     if (!$game_chart) {
         Armory::Log()->writeError('%s : game_ids were fetched from DB, but script was unable to get data for these matches from characters DB (arenateamid:%d)', __METHOD__, $this->arenateamid);
         return false;
     }
     $chart_data = array();
     foreach ($game_chart as $team) {
         if (!isset($chart_data[$team['teamid']])) {
             // Do not add same teams more than 1 time
             $rating_change = Armory::$cDB->select("SELECT `gameid`, `changeType`, `ratingChange` FROM `armory_game_chart` WHERE `teamid`=%d AND `gameid` IN (%s)", $team['teamid'], $all_games);
             $rd = 0;
             if ($rating_change) {
                 $exists = array();
                 foreach ($rating_change as $rCh) {
                     if (!isset($exists[$rCh['gameid']])) {
                         if ($rCh['changeType'] == 1) {
                             $rd += $rCh['ratingChange'];
                         } else {
                             $rd -= $rCh['ratingChange'];
                         }
                         $exists[$rCh['gameid']] = true;
                     }
                 }
             }
             $losses = Armory::$cDB->selectCell("SELECT COUNT(distinct(`gameid`)) FROM `armory_game_chart` WHERE `changeType`=1 AND `teamid`='%d' AND `gameid` IN (%s)", $team['teamid'], $all_games);
             $wins = Armory::$cDB->selectCell("SELECT COUNT(distinct(`gameid`)) FROM `armory_game_chart` WHERE `changeType`=2 AND `teamid`='%d' AND `gameid` IN (%s)", $team['teamid'], $all_games);
             $chart_data[$team['teamid']] = array('deleted' => $this->TeamExists($team['teamid']) ? 'false' : 'true', 'games' => $losses + $wins, 'losses' => $losses, 'rd' => $rd, 'realm' => Armory::$currentRealmInfo['name'], 'teamName' => $team['name'], 'teamUrl' => sprintf("r=%s&ts=%d&t=%s", urlencode(Armory::$currentRealmInfo['name']), $team['type'], urlencode($team['name'])), 'wins' => $wins);
             $chart_data[$team['teamid']]['winPer'] = Utils::GetPercent($chart_data[$team['teamid']]['games'], $chart_data[$team['teamid']]['wins']);
         }
     }
     return $chart_data;
 }
Beispiel #7
0
 /**
  * @return array
  **/
 public function GetRandomSuffixData()
 {
     if ($this->m_server != SERVER_MANGOS) {
         Armory::Log()->writeError('%s : this method is usable with MaNGOS servers only.', __METHOD__);
         return false;
     }
     return array($this->GetUInt32Value(ITEM_FIELD_ENCHANTMENT_8_1), $this->GetUInt32Value(ITEM_FIELD_ENCHANTMENT_9_1), $this->GetUInt32Value(ITEM_FIELD_ENCHANTMENT_10_1));
 }
                Armory::Log()->writeLog('character-select-submit : realm %s not found in database!', $realmName);
                continue;
            } elseif (!isset(Armory::$realmData[$realm_id])) {
                Armory::Log()->writeLog('character-select-submit : connection data to realm %s (ID: %d) not found!', $realmName, $realm_id);
                continue;
            }
            $realm_info = Armory::$realmData[$realm_id];
            $db = new Armory::$dbClass($realm_info['host_characters'], $realm_info['user_characters'], $realm_info['pass_characters'], $realm_info['port_characters'], $realm_info['name_characters'], $realm_info['charset_characters']);
            if (!$db) {
                // Error message will appear in ArmoryDatabaseHandler::ArmoryDatabaseHandler();
                continue;
            }
            $char_data = $db->selectRow("SELECT `guid`, `name`, `class`, `race`, `gender`, `level`, `account` FROM `characters` WHERE `name`='%s' AND `account`=%d LIMIT 1", $utils->escape($_GET['cn' . $i]), $_SESSION['accountId']);
            if (!$char_data) {
                Armory::Log()->writeLog('character-select-submit : unable to get character data from DB (name: %s, accountId: %d)', $_GET['cn' . $i], $_SESSION['accountId']);
                continue;
            }
            $char_data['realm_id'] = $realm_id;
            if (isset($_GET['cn1']) && $i == 1) {
                $char_data['selected'] = 1;
            } else {
                $char_data['selected'] = $i;
            }
            $char_data['num'] = $i;
            $utils->AddCharacterAsSelected($char_data, $realm_id, $i);
        }
    }
} else {
    Armory::Log()->writeLog('character-select-submit : $_GET variable not found!');
}
exit;
Beispiel #9
0
 /**
  * Returns array with guild rank IDs.
  * @category Guilds class
  * @access   public
  * @return   array
  **/
 public function GetGuildRanks()
 {
     if (!$this->guildId) {
         Armory::Log()->writeError('%s : guildId not defined', __METHOD__);
         return false;
     }
     return Armory::$cDB->select("SELECT `rid` AS `id`, `rname` AS `name` FROM `guild_rank` WHERE `guildid`=%d", $this->guildId);
 }
Beispiel #10
0
 /**
  * Returns array with item sources (for search results)
  * @category Search class
  * @access   private
  * @param    array $items
  * @return   array
  **/
 private function GetItemSourceArray($items)
 {
     // Get item IDs first
     $result_ids = array();
     foreach ($items as $item) {
         $curr_item_id = 0;
         if (!isset($item['id']) && !isset($item['entry'])) {
             continue;
         } elseif (isset($item['id'])) {
             $curr_item_id = $item['id'];
         } elseif (isset($item['entry'])) {
             $curr_item_id = $item['entry'];
         }
         if ($curr_item_id == 0) {
             continue;
         }
         $result_ids[] = $curr_item_id;
     }
     // Get item sources
     $data = Armory::$aDB->select("\n        SELECT\n        `ARMORYDBPREFIX_source`.`item`,\n        `ARMORYDBPREFIX_source`.`source`,\n        `ARMORYDBPREFIX_source`.`areaKey`,\n        `ARMORYDBPREFIX_source`.`areaUrl`,\n        `ARMORYDBPREFIX_source`.`isHeroic`,\n        `ARMORYDBPREFIX_instance_template`.`name_%s` AS `areaName`,\n        `ARMORYDBPREFIX_instance_template`.`id` AS `areaId`\n        FROM `ARMORYDBPREFIX_source` AS `ARMORYDBPREFIX_source`\n        LEFT JOIN `ARMORYDBPREFIX_instance_template` AS `ARMORYDBPREFIX_instance_template` ON `ARMORYDBPREFIX_instance_template`.`key`=`ARMORYDBPREFIX_source`.`areaKey`\n        WHERE `ARMORYDBPREFIX_source`.`item` IN (%s)", Armory::GetLocale(), $result_ids);
     if (!$data) {
         Armory::Log()->writeError('%s : unable to get item sources from DB!', __METHOD__);
         return false;
     }
     $sources_result = array();
     foreach ($data as $entry) {
         if (!isset($sources_result[$entry['item']])) {
             $sources_result[$entry['item']] = $entry;
         }
     }
     return $sources_result;
 }
 private function GenerateAchievements()
 {
     if (!is_array($this->achievements_storage)) {
         Armory::Log()->writeError('%s : unable to generate achievements ID: achievements storage is empty!', __METHOD__);
         return false;
     }
     $this->achievements_id = array();
     $ach_storage = array();
     $criterias_storage = array();
     $latest_count = 0;
     foreach ($this->achievements_storage as $achievement) {
         if ($latest_count < 6) {
             $this->latest_achievements[] = $achievement;
             $latest_count++;
         }
         $ach_storage[$achievement['achievement']] = $achievement;
         $this->achievements_id[] = $achievement['achievement'];
     }
     foreach ($this->achievements_progress_storage as $criteria) {
         $criterias_storage[$criteria['criteria']] = $criteria;
     }
     $this->achievements_storage = $ach_storage;
     $this->achievements_progress_storage = $criterias_storage;
     unset($ach_storage, $criterias_storage);
     return true;
 }
 protected function _query($safe_sql, $queryType)
 {
     // Execute query and calculate execution time
     $make_array = array();
     $query_start = microtime(true);
     $this->queryCount++;
     $performed_query = mysql_query($safe_sql, $this->connectionLink);
     if (!$performed_query) {
         if (!$this->disableNextError) {
             Armory::Log()->writeLog('%s : unable to execute SQL query (%s). MySQL error: %s', __METHOD__, $safe_sql, mysql_error($this->connectionLink) ? sprintf('"%s" (Error #%d)', mysql_error($this->connectionLink), mysql_errno($this->connectionLink)) : 'none');
         }
         if ($this->disableNextError) {
             $this->disableNextError = false;
         }
         return false;
     }
     $result = false;
     switch ($queryType) {
         case QueryType::SINGLE_CELL:
             $row = mysql_fetch_row($performed_query);
             $result = $row[0];
             break;
         case QueryType::SINGLE_ROW:
             $result = mysql_fetch_assoc($performed_query);
             if (is_array($result)) {
                 foreach ($result as $rKey => $rValue) {
                     if (is_string($rKey)) {
                         $make_array[$rKey] = $rValue;
                     }
                 }
                 $result = $make_array;
             }
             break;
         case QueryType::MULTIPLY_ROW:
             $result = array();
             while ($_result = mysql_fetch_assoc($performed_query)) {
                 if (is_array($_result)) {
                     foreach ($_result as $rKey => $rValue) {
                         if (is_string($rKey)) {
                             $make_array[$rKey] = $rValue;
                         }
                     }
                     $result[] = $make_array;
                 } else {
                     $result[] = $_result;
                 }
             }
             break;
         case QueryType::OBJECT_QUERY:
             $result = array();
             while ($_result = mysql_fetch_object($performed_query)) {
                 $result[] = $_result;
             }
             break;
         case QueryType::SQL_QUERY:
             $result = true;
             break;
         default:
             $result = false;
             break;
     }
     $query_end = microtime(true);
     $queryTime = round($query_end - $query_start, 4);
     Armory::Log()->writeSql('[%s ms]: %s', $queryTime, $safe_sql);
     $this->queryTimeGeneration += $queryTime;
     return $result;
 }
 protected function ConvertArray($source)
 {
     if (!is_array($source)) {
         Armory::Log()->writeError('%s : source must have array type!', __METHOD__);
         return null;
     }
     $returnString = null;
     $count = count($source);
     for ($i = 0; $i < $count; $i++) {
         if (!isset($source[$i])) {
             continue;
         }
         if ($i) {
             $returnString .= ", '" . $this->SanitizeString($source[$i]) . "'";
         } else {
             $returnString .= "'" . $this->SanitizeString($source[$i]) . "'";
         }
     }
     return $returnString;
 }
Beispiel #14
0
 public static function LoadTableFromDB($table)
 {
     if (!self::$db) {
         Armory::Log()->writeError('%s : DB is not initialized!', __METHOD__);
         return false;
     }
     self::$db_table = $table;
     $table_data = self::$db->select("DESCRIBE %s", self::$db_table);
     if (!$table_data) {
         return false;
     }
     $td = array();
     $i = 0;
     foreach ($table_data as $tbl) {
         $td[] = array('name' => $tbl['Field'], 'key' => $tbl['Key'] == 'PRI' ? true : false);
     }
     return $td;
 }
Beispiel #15
0
 /**
  * Return item handler by item entry (from item storage)
  * Note: m_items must be initialized in Characters::BuildCharacter()!
  * @category Characters class
  * @access   public
  * @param    int $entry
  * @return   object
  **/
 public function GetItemByEntry($entry)
 {
     if (!is_array($this->m_items)) {
         Armory::Log()->writeError('%s : m_items must be an array!', __METHOD__);
         return false;
     }
     foreach ($this->m_items as $mItem) {
         if ($mItem->GetEntry() == $entry) {
             return $mItem;
         }
     }
     return false;
 }
Beispiel #16
0
}
session_start();
if (!@(include 'classes/class.armory.php')) {
    die('<b>Error:</b> unable to load Armory class!');
}
if (!@(include 'revision_nr.php')) {
    die('<b>Error:</b> unable to load revision_nr.php!');
}
$_SESSION['last_url'] = str_replace('.php', '.xml', $_SERVER['PHP_SELF']) . '?' . str_replace('locale=', 'l=', $_SERVER['QUERY_STRING']);
$armory = new Armory();
/* Check DbVersion */
$dbVersion = $armory->aDB->selectCell("SELECT `version` FROM `ARMORYDBPREFIX_db_version`");
if ($dbVersion != DB_VERSION) {
    if (!$dbVersion) {
        if (isset($armory->armoryconfig['checkVersionType']) && $armory->armoryconfig['checkVersionType'] == 'log') {
            $armory->Log()->writeError('ArmoryChecker: wrong Armory DB name!');
        } else {
            echo '<b>Fatal error</b>: wrong Armory DB name<br/>';
        }
    }
    $errorDBVersion = sprintf('Current version is %s but expected %s.<br />
    Apply all neccessary updates from \'sql/updates\' folder and refresh this page.', $dbVersion ? "'" . $dbVersion . "'" : 'not defined', "'" . DB_VERSION . "'");
    if (isset($armory->armoryconfig['checkVersionType']) && $armory->armoryconfig['checkVersionType'] == 'log') {
        $armory->Log()->writeError('ArmoryChecker : DB_VERSION error: %s', defined('DB_VERSION') ? $errorDBVersion : 'DB_VERSION constant not defined!');
    } else {
        echo '<b>DB_VERSION error</b>:<br />';
        if (!defined('DB_VERSION')) {
            die('DB_VERSION constant not defined!');
        }
        die($errorDBVersion);
    }
Beispiel #17
0
 /**
  * Create item tooltip with provided options
  *  - $parent: used for items that created by spells (displays under patterns/recipes, etc.)
  *  - $comparison: used for dual tooltips (if user logged in and primary character is selected)
  * This method must be called from self::ItemTooltip() only!
  * @category Items class
  * @access   private
  * @param    int $itemID
  * @param    XMLHandler $xml
  * @param    Characters $characters
  * @param    bool $parent = false
  * @param    bool $comparison = false
  **/
 private function CreateAdditionalItemTooltip($itemID, XMLHandler $xml, Characters $characters, $parent = false, $comparsion = false)
 {
     if (!$xml) {
         Armory::Log()->writeError('%s : xml should be instance of XMLHandler class. %s given.', __METHOD__, gettype($xml));
         return false;
     } elseif ($parent == true && is_array($comparsion)) {
         Armory::Log()->writeError('%s : $parent and $comparison have \'true\' value (not allowed), ignore.', __METHOD__);
         return false;
         // both variables can't have 'true' value.
     }
     // Item comparsion mode
     $realm = false;
     if (is_array($comparsion) && isset(Armory::$realmData[$comparsion['realm_id']])) {
         $realm = Armory::$realmData[$comparsion['realm_id']];
     }
     $proto = null;
     $isCharacter = $characters->CheckPlayer();
     if ($isCharacter && in_array(self::GetItemInfo($itemID, 'class'), array(ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON))) {
         $item = $characters->GetItemByEntry($itemID);
         if ($item) {
             $proto = $item->GetProto();
         } else {
             // Wrong item, nothing to do here.
             Armory::Log()->writeError('%s : wrong item handler for itemID #%d, character GUID: %d', __METHOD__, $itemID, $characters->GetGUID());
             return false;
         }
     } else {
         $isCharacter = false;
     }
     if (!$proto) {
         // Maybe we haven't any character? Let's find itemproto by entry.
         $proto = new ItemPrototype();
         $proto->LoadItem($itemID);
         if (!$proto) {
             Armory::Log()->writeError('%s : unable to find item with entry #%d', __METHOD__, $itemID);
             return false;
         }
     }
     // Check for ScalingStatDistribution (Heirloom items)
     $ssd = Armory::$aDB->selectRow("SELECT * FROM `ARMORYDBPREFIX_ssd` WHERE `entry`=%d LIMIT 1", $proto->ScalingStatDistribution);
     $ssd_level = MAX_PLAYER_LEVEL;
     if ($isCharacter) {
         $ssd_level = $characters->GetLevel();
         if ($ssd && $ssd_level > $ssd['MaxLevel']) {
             $ssd_level = $ssd['MaxLevel'];
         }
     }
     $ssv = Armory::$aDB->selectRow("SELECT * FROM `ARMORYDBPREFIX_ssv` WHERE `level`=%d LIMIT 1", $ssd_level);
     $xml->XMLWriter()->startElement('id');
     $xml->XMLWriter()->text($itemID);
     $xml->XMLWriter()->endElement();
     //id
     if (Utils::IsWriteRaw()) {
         $xml->XMLWriter()->writeRaw('<name>');
         $xml->XMLWriter()->writeRaw(self::GetItemName($itemID));
         $xml->XMLWriter()->writeRaw('</name>');
     } else {
         $xml->XMLWriter()->startElement('name');
         if (Armory::GetLocale() == 'en_gb' || Armory::GetLocale() == 'en_us') {
             $xml->XMLWriter()->text($proto->name);
         } else {
             $xml->XMLWriter()->text(self::GetItemName($itemID));
         }
         $xml->XMLWriter()->endElement();
         //name
     }
     $xml->XMLWriter()->startElement('icon');
     $xml->XMLWriter()->text(self::GetItemIcon($itemID, $proto->displayid));
     $xml->XMLWriter()->endElement();
     //icon
     // 3.2.x heroic item flag
     if ($proto->Flags & ITEM_FLAGS_HEROIC) {
         $xml->XMLWriter()->startElement('heroic');
         $xml->XMLWriter()->text('1');
         $xml->XMLWriter()->endElement();
         //heroic
     }
     $xml->XMLWriter()->startElement('overallQualityId');
     $xml->XMLWriter()->text($proto->Quality);
     $xml->XMLWriter()->endElement();
     //overallQualityId
     // Map
     if ($proto->Map > 0 && ($mapName = Armory::$aDB->selectCell("SELECT `name_%s` FROM `ARMORYDBPREFIX_maps` WHERE `id` = %d", Armory::GetLocale(), $proto->Map))) {
         if (Utils::IsWriteRaw()) {
             $xml->XMLWriter()->writeRaw('<instanceBound>' . $mapName . '</instanceBound>');
         } else {
             $xml->XMLWriter()->startElement('instanceBound');
             $xml->XMLWriter()->text($mapName);
             $xml->XMLWriter()->endElement();
             //instanceBound
         }
     }
     if ($proto->Flags & ITEM_FLAGS_CONJURED) {
         $xml->XMLWriter()->startElement('conjured');
         $xml->XMLWriter()->endElement();
         //conjured
     }
     $xml->XMLWriter()->startElement('bonding');
     $xml->XMLWriter()->text($proto->bonding);
     $xml->XMLWriter()->endElement();
     //bonding
     $xml->XMLWriter()->startElement('maxCount');
     $xml->XMLWriter()->text($proto->maxcount);
     $xml->XMLWriter()->endElement();
     //maxCount
     if ($proto->startquest > 0) {
         $xml->XMLWriter()->startElement('startQuestId');
         $xml->XMLWriter()->text($proto->startquest);
         $xml->XMLWriter()->endElement();
         //startQuestId
     }
     $xml->XMLWriter()->startElement('classId');
     $xml->XMLWriter()->text($proto->class);
     $xml->XMLWriter()->endElement();
     //classId
     $xml->XMLWriter()->startElement('equipData');
     $xml->XMLWriter()->startElement('inventoryType');
     $xml->XMLWriter()->text($proto->InventoryType);
     $xml->XMLWriter()->endElement();
     //inventoryType
     $xml->XMLWriter()->startElement('subclassName');
     $xml->XMLWriter()->text(self::GetItemSubTypeInfo($itemID, true, array('class' => $proto->class, 'subclass' => $proto->subclass)));
     $xml->XMLWriter()->endElement();
     //subclassName
     if ($proto->class == ITEM_CLASS_CONTAINER) {
         $xml->XMLWriter()->startElement('containerSlots');
         $xml->XMLWriter()->text($proto->ContainerSlots);
         $xml->XMLWriter()->endElement();
         //containerSlots
     }
     $xml->XMLWriter()->endElement();
     //equipData
     if ($proto->class == ITEM_CLASS_WEAPON) {
         $xml->XMLWriter()->startElement('damageData');
         $xml->XMLWriter()->startElement('damage');
         $xml->XMLWriter()->startElement('type');
         $xml->XMLWriter()->text('0');
         $xml->XMLWriter()->endElement();
         //type
         // Damage
         $minDmg = $proto->Damage[0]['min'];
         $maxDmg = $proto->Damage[0]['max'];
         $dps = null;
         // SSD Check
         if ($ssv) {
             if ($extraDPS = self::GetDPSMod($ssv, $proto->ScalingStatValue)) {
                 $average = $extraDPS * $proto->delay / 1000;
                 $minDmg = 0.7 * $average;
                 $maxDmg = 1.3 * $average;
                 $dps = round(($maxDmg + $minDmg) / (2 * ($proto->delay / 1000)));
             }
         }
         $xml->XMLWriter()->startElement('min');
         $xml->XMLWriter()->text(round($minDmg));
         $xml->XMLWriter()->endElement();
         //min
         $xml->XMLWriter()->startElement('max');
         $xml->XMLWriter()->text(round($maxDmg));
         $xml->XMLWriter()->endElement();
         //max
         $xml->XMLWriter()->endElement();
         //damage
         $xml->XMLWriter()->startElement('speed');
         $xml->XMLWriter()->text(round($proto->delay / 1000, 2));
         $xml->XMLWriter()->endElement();
         //speed
         for ($jj = 0; $jj <= 1; $jj++) {
             $d_type = $proto->Damage[$jj]['type'];
             // $data['dmg_type' . $jj];
             $d_min = $proto->Damage[$jj]['min'];
             // $data['dmg_min' . $jj];
             $d_max = $proto->Damage[$jj]['max'];
             // $data['dmg_max' . $jj];
             if ($d_max > 0 && $proto->class != ITEM_CLASS_PROJECTILE) {
                 $delay = $proto->delay / 1000;
                 if ($delay > 0) {
                     $dps = $dps + round(($d_max + $d_min) / (2 * $delay), 1);
                 }
                 if ($jj > 1) {
                     $delay = 0;
                 }
             }
         }
         if ($dps != null) {
             $xml->XMLWriter()->startElement('dps');
             $xml->XMLWriter()->text($dps);
             $xml->XMLWriter()->endElement();
             //dps
         }
         $xml->XMLWriter()->endElement();
         //damageData
     }
     // Projectile DPS
     if ($proto->class == ITEM_CLASS_PROJECTILE) {
         if ($proto->Damage[0]['min'] > 0 && $proto->Damage[0]['max'] > 0) {
             $xml->XMLWriter()->startElement('damageData');
             $xml->XMLWriter()->startElement('damage');
             $xml->XMLWriter()->startElement('type');
             $xml->XMLWriter()->text($proto->Damage[0]['type']);
             $xml->XMLWriter()->endElement();
             //type
             $xml->XMLWriter()->startElement('max');
             $xml->XMLWriter()->text($proto->Damage[0]['max']);
             $xml->XMLWriter()->endElement();
             //max
             $xml->XMLWriter()->startElement('min');
             $xml->XMLWriter()->text($proto->Damage[0]['min']);
             $xml->XMLWriter()->endElement();
             //min
             $xml->XMLWriter()->endElement();
             //damage
             $xml->XMLWriter()->endElement();
             //damageData
         }
     }
     // Gem properties
     if ($proto->class == ITEM_CLASS_GEM && $proto->GemProperties > 0) {
         $GemSpellItemEcnhID = Armory::$aDB->selectCell("SELECT `spellitemenchantement` FROM `ARMORYDBPREFIX_gemproperties` WHERE `id`=%d", $proto->GemProperties);
         $GemText = Armory::$aDB->selectCell("SELECT `text_%s` FROM `ARMORYDBPREFIX_enchantment` WHERE `id`=%d", Armory::GetLocale(), $GemSpellItemEcnhID);
         if ($GemText) {
             if (Utils::IsWriteRaw()) {
                 $xml->XMLWriter()->writeRaw('<gemProperties>');
                 $xml->XMLWriter()->writeRaw($GemText);
                 $xml->XMLWriter()->writeRaw('</gemProperties>');
             } else {
                 $xml->XMLWriter()->startElement('gemProperties');
                 $xml->XMLWriter()->text($GemText);
                 $xml->XMLWriter()->endElement();
                 //gemProperties
             }
         }
     }
     if ($proto->block > 0) {
         $xml->XMLWriter()->startElement('blockValue');
         $xml->XMLWriter()->text($proto->block);
         $xml->XMLWriter()->endElement();
         //blockValue
     }
     if ($proto->fire_res > 0) {
         $xml->XMLWriter()->startElement('fireResist');
         $xml->XMLWriter()->text($proto->fire_res);
         $xml->XMLWriter()->endElement();
         //fireResist
     }
     if ($proto->nature_res > 0) {
         $xml->XMLWriter()->startElement('natureResist');
         $xml->XMLWriter()->text($proto->nature_res);
         $xml->XMLWriter()->endElement();
         //natureResist
     }
     if ($proto->frost_res > 0) {
         $xml->XMLWriter()->startElement('frostResist');
         $xml->XMLWriter()->text($proto->frost_res);
         $xml->XMLWriter()->endElement();
         //frostResist
     }
     if ($proto->shadow_res > 0) {
         $xml->XMLWriter()->startElement('shadowResist');
         $xml->XMLWriter()->text($proto->shadow_res);
         $xml->XMLWriter()->endElement();
         //shadowResist
     }
     if ($proto->arcane_res > 0) {
         $xml->XMLWriter()->startElement('arcaneResist');
         $xml->XMLWriter()->text($proto->arcane_res);
         $xml->XMLWriter()->endElement();
         //arcaneResist
     }
     for ($i = 0; $i < MAX_ITEM_PROTO_STATS; $i++) {
         if ($ssd && $ssv) {
             if ($ssd['StatMod_' . $i] < 0) {
                 continue;
             }
             $val = self::GetSSDMultiplier($ssv, $proto->ScalingStatValue) * $ssd['Modifier_' . $i] / 10000;
             $bonus_template = self::GetItemBonusTemplate($ssd['StatMod_' . $i]);
             $xml->XMLWriter()->startElement($bonus_template);
             $xml->XMLWriter()->text(round($val));
             $xml->XMLWriter()->endElement();
         } else {
             $key = $i + 1;
             if ($proto->ItemStat[$i]['type'] > 0 && $proto->ItemStat[$i]['value'] > 0) {
                 $bonus_template = self::GetItemBonusTemplate($proto->ItemStat[$i]['type']);
                 $xml->XMLWriter()->startElement($bonus_template);
                 $xml->XMLWriter()->text($proto->ItemStat[$i]['value']);
                 $xml->XMLWriter()->endElement();
             }
         }
     }
     $armor = $proto->armor;
     if ($ssv && $proto->ScalingStatValue > 0) {
         if ($ssvarmor = $this->GetArmorMod($ssv, $proto->ScalingStatValue)) {
             $armor = $ssvarmor;
         }
     }
     $xml->XMLWriter()->startElement('armor');
     if ($proto->ArmorDamageModifier > 0) {
         $xml->XMLWriter()->writeAttribute('armorBonus', 1);
     }
     $xml->XMLWriter()->text($armor);
     $xml->XMLWriter()->endElement();
     //armor
     $itemSlotName = Utils::GetItemSlotTextByInvType($proto->InventoryType);
     if (!$parent && $isCharacter && $itemSlotName != null) {
         $enchantment = $characters->GetCharacterEnchant($itemSlotName);
         if ($enchantment > 0) {
             if (Utils::IsWriteRaw()) {
                 $xml->XMLWriter()->writeRaw('<enchant>');
                 $xml->XMLWriter()->writeRaw(Armory::$aDB->selectCell("SELECT `text_%s` FROM `ARMORYDBPREFIX_enchantment` WHERE `id`=%d LIMIT 1", Armory::GetLocale(), $enchantment));
                 $xml->XMLWriter()->writeRaw('</enchant>');
                 //enchant
             } else {
                 $xml->XMLWriter()->startElement('enchant');
                 $xml->XMLWriter()->text(Armory::$aDB->selectCell("SELECT `text_%s` FROM `ARMORYDBPREFIX_enchantment` WHERE `id`=%d LIMIT 1", Armory::GetLocale(), $enchantment));
                 $xml->XMLWriter()->endElement();
                 //enchant
             }
         }
     }
     // Random property
     if ($proto->RandomProperty > 0 || $proto->RandomSuffix > 0) {
         if (!$isCharacter) {
             $xml->XMLWriter()->startElement('randomEnchantData');
             $xml->XMLWriter()->endElement();
             //randomEnchantData
         } else {
             if ($itemSlotName) {
                 $rPropInfo = self::GetRandomPropertiesData($itemID, $characters->GetGUID(), $characters->GetEquippedItemGuidBySlot($itemSlotName), false, $characters->GetServerType(), $item, array('RandomProperty' => $proto->RandomProperty, 'RandomSuffix' => $proto->RandomSuffix));
             } else {
                 $rPropInfo = self::GetRandomPropertiesData($itemID, $characters->GetGUID(), 0, false, $characters->GetServerType(), $item);
             }
             if ($isCharacter && !$parent && is_array($rPropInfo)) {
                 $xml->XMLWriter()->startElement('randomEnchantData');
                 if (Utils::IsWriteRaw()) {
                     $xml->XMLWriter()->writeRaw('<suffix>');
                     $xml->XMLWriter()->writeRaw($rPropInfo['suffix']);
                     $xml->XMLWriter()->writeRaw('</suffix>');
                     //suffix
                 } else {
                     $xml->XMLWriter()->startElement('suffix');
                     $xml->XMLWriter()->text($rPropInfo['suffix']);
                     $xml->XMLWriter()->endElement();
                     //suffix
                 }
                 if (is_array($rPropInfo['data'])) {
                     if (Utils::IsWriteRaw()) {
                         foreach ($rPropInfo['data'] as $randProp) {
                             $xml->XMLWriter()->writeRaw('<enchant>');
                             $xml->XMLWriter()->writeRaw($randProp);
                             $xml->XMLWriter()->writeRaw('</enchant>');
                             //enchant
                         }
                     } else {
                         foreach ($rPropInfo['data'] as $randProp) {
                             $xml->XMLWriter()->startElement('enchant');
                             $xml->XMLWriter()->text($randProp);
                             $xml->XMLWriter()->endElement();
                             //enchant
                         }
                     }
                 }
                 $xml->XMLWriter()->endElement();
                 //randomEnchantData
             }
         }
     }
     // Socket data
     $xml->XMLWriter()->startElement('socketData');
     $socket_data = false;
     // If there's no character, check $proto->Socket[X]
     if (!$isCharacter) {
         for ($i = 0; $i < 3; $i++) {
             if (isset($proto->Socket[$i]['color']) && $proto->Socket[$i]['color'] > 0) {
                 switch ($proto->Socket[$i]['color']) {
                     case 1:
                         $socket_data = array('color' => 'Meta');
                         break;
                     case 2:
                         $socket_data = array('color' => 'Red');
                         break;
                     case 4:
                         $socket_data = array('color' => 'Yellow');
                         break;
                     case 8:
                         $socket_data = array('color' => 'Blue');
                         break;
                 }
                 if (is_array($socket_data)) {
                     if (Utils::IsWriteRaw()) {
                         $xml->XMLWriter()->writeRaw('<socket');
                         foreach ($socket_data as $socket_key => $socket_value) {
                             $xml->XMLWriter()->writeRaw(' ' . $socket_key . '="' . $socket_value . '"');
                         }
                         $xml->XMLWriter()->writeRaw('/>');
                     } else {
                         $xml->XMLWriter()->startElement('socket');
                         foreach ($socket_data as $socket_key => $socket_value) {
                             $xml->XMLWriter()->writeAttribute($socket_key, $socket_value);
                         }
                         $xml->XMLWriter()->endElement();
                         //socket
                     }
                 }
             }
         }
     } elseif ($isCharacter && isset($item) && is_object($item)) {
         $gems = array('g0' => $item->GetSocketInfo(1), 'g1' => $item->GetSocketInfo(2), 'g2' => $item->GetSocketInfo(3));
         for ($i = 0; $i < 3; $i++) {
             $index = $i + 1;
             if (isset($gems['g' . $i]['item']) && $gems['g' . $i]['item'] > 0 && ($parent == false || $comparsion == true)) {
                 $socket_data = array('color' => self::GetSocketColorString($proto->Socket[$i]['color'] ? $proto->Socket[$i]['color'] : 0), 'enchant' => $gems['g' . $i]['enchant'], 'icon' => $gems['g' . $i]['icon']);
                 if (self::IsGemMatchesSocketColor($gems['g' . $i]['color'], $proto->Socket[$i]['color'] ? $proto->Socket[$i]['color'] : -1)) {
                     $socket_data['match'] = '1';
                 }
             } else {
                 if (isset($proto->Socket[$i]['color']) && $proto->Socket[$i]['color'] > 0) {
                     $socket_data = array('color' => self::GetSocketColorString($proto->Socket[$i]['color']));
                 }
             }
             if (isset($socket_data) && is_array($socket_data)) {
                 if (Utils::IsWriteRaw()) {
                     $xml->XMLWriter()->writeRaw('<socket');
                     foreach ($socket_data as $socket_key => $socket_value) {
                         $xml->XMLWriter()->writeRaw(' ' . $socket_key . '="' . $socket_value . '"');
                     }
                     $xml->XMLWriter()->writeRaw('/>');
                 } else {
                     $xml->XMLWriter()->startElement('socket');
                     foreach ($socket_data as $socket_key => $socket_value) {
                         $xml->XMLWriter()->writeAttribute($socket_key, $socket_value);
                     }
                     $xml->XMLWriter()->endElement();
                     //socket
                 }
             }
             $socket_data = false;
         }
     }
     if ($proto->socketBonus > 0) {
         $bonus_text = Armory::$aDB->selectCell("SELECT `text_%s` FROM `ARMORYDBPREFIX_enchantment` WHERE `id`=%d", Armory::GetLocale(), $proto->socketBonus);
         if (Utils::IsWriteRaw()) {
             $xml->XMLWriter()->writeRaw('<socketMatchEnchant>');
             $xml->XMLWriter()->writeRaw($bonus_text);
             $xml->XMLWriter()->writeRaw('</socketMatchEnchant>');
             //socketMatchEnchant
         } else {
             $xml->XMLWriter()->startElement('socketMatchEnchant');
             $xml->XMLWriter()->text($bonus_text);
             $xml->XMLWriter()->endElement();
             //socketMatchEnchant
         }
     }
     $xml->XMLWriter()->endElement();
     //socketData
     // Durability
     if ($isCharacter) {
         $item_durability = $item->GetItemDurability();
     } else {
         $item_durability = array('current' => $proto->MaxDurability, 'max' => $proto->MaxDurability);
     }
     if (is_array($item_durability) && $item_durability['current'] > 0) {
         $xml->XMLWriter()->startElement('durability');
         $xml->XMLWriter()->writeAttribute('current', (int) $item_durability['current']);
         $xml->XMLWriter()->writeAttribute('max', (int) $item_durability['max']);
         $xml->XMLWriter()->endElement();
         //durability
     }
     $allowable_classes = self::AllowableClasses($proto->AllowableClass);
     if ($allowable_classes) {
         $xml->XMLWriter()->startElement('allowableClasses');
         foreach ($allowable_classes as $al_class) {
             if (Utils::IsWriteRaw()) {
                 $xml->XMLWriter()->writeRaw('<class>');
                 $xml->XMLWriter()->writeRaw($al_class);
                 $xml->XMLWriter()->writeRaw('</class>');
                 //class
             } else {
                 $xml->XMLWriter()->startElement('class');
                 $xml->XMLWriter()->text($al_class);
                 $xml->XMLWriter()->endElement();
                 //class
             }
         }
         $xml->XMLWriter()->endElement();
         //allowableClasses
     }
     $allowable_races = self::AllowableRaces($proto->AllowableRace);
     if ($allowable_races) {
         $xml->XMLWriter()->startElement('allowableRaces');
         foreach ($allowable_races as $al_race) {
             if (Utils::IsWriteRaw()) {
                 $xml->XMLWriter()->writeRaw('<race>');
                 $xml->XMLWriter()->writeRaw($al_race);
                 $xml->XMLWriter()->writeRaw('</race>');
                 //race
             } else {
                 $xml->XMLWriter()->startElement('race');
                 $xml->XMLWriter()->text($al_race);
                 $xml->XMLWriter()->endElement();
                 //race
             }
         }
         $xml->XMLWriter()->endElement();
         //allowableRaces
     }
     if ($proto->RequiredSkill > 0) {
         if (Utils::IsWriteRaw()) {
             $xml->XMLWriter()->writeRaw('<requiredSkill');
             $xml->XMLWriter()->writeRaw(' name="' . Armory::$aDB->selectCell("SELECT `name_%s` FROM `ARMORYDBPREFIX_skills` WHERE `id`=%d", Armory::GetLocale(), $proto->RequiredSkill) . '"');
             $xml->XMLWriter()->writeRaw(' rank="', $proto->RequiredSkillRank . '"');
             $xml->XMLWriter()->writeRaw('/>');
             //requiredSkill
         } else {
             $xml->XMLWriter()->startElement('requiredSkill');
             $xml->XMLWriter()->writeAttribute('name', Armory::$aDB->selectCell("SELECT `name_%s` FROM `ARMORYDBPREFIX_skills` WHERE `id`=%d", Armory::GetLocale(), $proto->RequiredSkill));
             $xml->XMLWriter()->writeAttribute('rank', $proto->RequiredSkillRank);
             $xml->XMLWriter()->endElement();
             //requiredSkill
         }
     }
     if ($proto->requiredspell > 0 && ($spellName = Armory::$aDB->selectCell("SELECT `SpellName_%s` FROM `ARMORYDBPREFIX_spell` WHERE `id`=%d", Armory::GetLocale(), $proto->requiredspell))) {
         $xml->XMLWriter()->startElement('requiredAbility');
         $xml->XMLWriter()->text($spellName);
         $xml->XMLWriter()->endElement();
         //requiredAbility
     }
     if ($proto->RequiredReputationFaction > 0 && ($factionName = Armory::$aDB->selectCell("SELECT `name_%s` FROM `ARMORYDBPREFIX_faction` WHERE `id`=%d", Armory::GetLocale(), $proto->RequiredReputationFaction))) {
         if (Utils::IsWriteRaw()) {
             $xml->XMLWriter()->writeRaw('<requiredFaction');
             $xml->XMLWriter()->writeRaw(' name="' . $factionName . '"');
             $xml->XMLWriter()->writeRaw(' rep="' . $proto->RequiredReputationRank . '"');
             $xml->XMLWriter()->writeRaw('/>');
             //requiredFaction
         } else {
             $xml->XMLWriter()->startElement('requiredFaction');
             $xml->XMLWriter()->writeAttribute('name', $factionName);
             $xml->XMLWriter()->writeAttribute('rep', $proto->RequiredReputationRank);
             $xml->XMLWriter()->endElement();
             //requiredFaction
         }
     }
     $xml->XMLWriter()->startElement('requiredLevel');
     $xml->XMLWriter()->text($proto->RequiredLevel);
     $xml->XMLWriter()->endElement();
     //requiredLevel
     if ($proto->ItemLevel > 0) {
         $xml->XMLWriter()->startElement('itemLevel');
         $xml->XMLWriter()->text($proto->ItemLevel);
         $xml->XMLWriter()->endElement();
         //itemLevel
     }
     // Item set
     if ($proto->itemset > 0) {
         $xml->XMLWriter()->startElement('setData');
         $itemsetName = Armory::$aDB->selectCell("SELECT `name_%s` FROM `ARMORYDBPREFIX_itemsetinfo` WHERE `id`=%d", Armory::GetLocale(), $proto->itemset);
         if (Utils::IsWriteRaw()) {
             $xml->XMLWriter()->writeRaw('<name>');
             $xml->XMLWriter()->writeRaw($itemsetName);
             $xml->XMLWriter()->writeRaw('</name>');
         } else {
             $xml->XMLWriter()->startElement('name');
             $xml->XMLWriter()->text($itemsetName);
             $xml->XMLWriter()->endElement();
             //name
         }
         $setdata = Armory::$aDB->selectRow("SELECT * FROM `ARMORYDBPREFIX_itemsetinfo` WHERE `id`=%d", $proto->itemset);
         if (self::IsMultiplyItemSet($proto->itemset)) {
             // Get itemset info from other table (armory_itemsetdata)
             $currentSetData = Armory::$aDB->select("SELECT * FROM `ARMORYDBPREFIX_itemsetdata` WHERE `original`=%d", $proto->itemset);
             if (is_array($currentSetData)) {
                 $activeSetInfo = array();
                 $basicSetData = $currentSetData[0];
                 foreach ($currentSetData as $iSet) {
                     for ($i = 1; $i < 6; $i++) {
                         if ($characters->IsItemEquipped($iSet['item' . $i])) {
                             $activeSetInfo['item' . $i] = $iSet['item' . $i];
                         }
                     }
                 }
                 for ($i = 1; $i < 6; $i++) {
                     if (Utils::IsWriteRaw()) {
                         $xml->XMLWriter()->writeRaw('<item');
                         if (isset($activeSetInfo['item' . $i])) {
                             $xml->XMLWriter()->writeRaw(' name="' . self::GetItemName($activeSetInfo['item' . $i]) . '"');
                             if ($characters->IsItemEquipped($activeSetInfo['item' . $i])) {
                                 $xml->XMLWriter()->writeRaw(' equipped="1"');
                             }
                         } else {
                             $xml->XMLWriter()->writeRaw(' name="' . self::GetItemName($basicSetData['item' . $i]) . '"');
                         }
                         $xml->XMLWriter()->writeRaw('/>');
                         //item
                     } else {
                         $xml->XMLWriter()->startElement('item');
                         if (isset($activeSetInfo['item' . $i])) {
                             $xml->XMLWriter()->writeAttribute('name', self::GetItemName($activeSetInfo['item' . $i]));
                             if ($characters->IsItemEquipped($activeSetInfo['item' . $i])) {
                                 $xml->XMLWriter()->writeAttribute('equipped', '1');
                             }
                         } else {
                             $xml->XMLWriter()->writeAttribute('name', self::GetItemName($basicSetData['item' . $i]));
                         }
                         $xml->XMLWriter()->endElement();
                         //item
                     }
                 }
             }
         } else {
             for ($i = 1; $i < 10; $i++) {
                 if (isset($setdata['item' . $i]) && self::IsItemExists($setdata['item' . $i])) {
                     if (Utils::IsWriteRaw()) {
                         $xml->XMLWriter()->writeRaw('<item');
                         $xml->XMLWriter()->writeRaw(' name="' . self::GetItemName($setdata['item' . $i]) . '"');
                         if ($characters->IsItemEquipped($setdata['item' . $i])) {
                             $xml->XMLWriter()->writeRaw(' equipped="1"');
                         }
                         $xml->XMLWriter()->writeRaw('/>');
                         //item
                     } else {
                         $xml->XMLWriter()->startElement('item');
                         $xml->XMLWriter()->writeAttribute('name', self::GetItemName($setdata['item' . $i]));
                         if ($characters->IsItemEquipped($setdata['item' . $i])) {
                             $xml->XMLWriter()->writeAttribute('equipped', 1);
                         }
                         $xml->XMLWriter()->endElement();
                         //item
                     }
                 }
             }
         }
         $itemsetbonus = self::GetItemSetBonusInfo($setdata);
         if (is_array($itemsetbonus)) {
             foreach ($itemsetbonus as $item_bonus) {
                 if (Utils::IsWriteRaw()) {
                     $xml->XMLWriter()->writeRaw('<setBonus');
                     $xml->XMLWriter()->writeRaw(' desc="' . $item_bonus['desc'] . '"');
                     $xml->XMLWriter()->writeRaw(' threshold="' . $item_bonus['threshold'] . '"');
                     $xml->XMLWriter()->writeRaw('/>');
                     //setBonus
                 } else {
                     $xml->XMLWriter()->startElement('setBonus');
                     $xml->XMLWriter()->writeAttribute('desc', $item_bonus['desc']);
                     $xml->XMLWriter()->writeAttribute('threshold', $item_bonus['threshold']);
                     $xml->XMLWriter()->endElement();
                     //setBonus
                 }
             }
         }
         $xml->XMLWriter()->endElement();
         //setData
     }
     $xml->XMLWriter()->startElement('spellData');
     $spellData = 0;
     $spellInfo = false;
     for ($i = 0; $i < 5; $i++) {
         if ($proto->Spells[$i]['spellid'] > 0) {
             $spellData = 1;
             $spell_tmp = Armory::$aDB->selectRow("SELECT * FROM `ARMORYDBPREFIX_spell` WHERE `id`=%d", $proto->Spells[$i]['spellid']);
             if (Armory::GetLocale() == 'en_gb' || Armory::GetLocale() == 'ru_ru') {
                 $tmp_locale = Armory::GetLocale();
             } else {
                 $tmp_locale = 'en_gb';
             }
             if (!isset($spell_tmp['Description_' . $tmp_locale]) || empty($spell_tmp['Description_' . $tmp_locale])) {
                 // Try to find at least en_gb locale
                 if (!isset($spell_tmp['Description_en_gb']) || empty($spell_tmp['Description_en_gb'])) {
                     continue;
                 } else {
                     $tmp_locale = 'en_gb';
                 }
             }
             $spellInfo = $this->SpellReplace($spell_tmp, Utils::ValidateSpellText($spell_tmp['Description_' . $tmp_locale]));
             if ($spellInfo) {
                 $spellData = 2;
                 $spellInfo = str_replace('&quot;', '"', $spellInfo);
                 $xml->XMLWriter()->startElement('spell');
                 $xml->XMLWriter()->startElement('trigger');
                 $xml->XMLWriter()->text($proto->Spells[$i]['trigger']);
                 $xml->XMLWriter()->endElement();
                 //trigger
                 $xml->XMLWriter()->startElement('desc');
                 $xml->XMLWriter()->text($spellInfo);
                 $xml->XMLWriter()->endElement();
                 //desc
                 $xml->XMLWriter()->endElement();
                 //spell
             }
         }
     }
     if ($spellData == 1 && $proto->description != null) {
         $xml->XMLWriter()->startElement('spell');
         $xml->XMLWriter()->startElement('trigger');
         $xml->XMLWriter()->text('6');
         $xml->XMLWriter()->endElement();
         //trigger
         $xml->XMLWriter()->startElement('desc');
         if (Armory::GetLocale() == 'en_gb' || Armory::GetLocale() == 'en_us') {
             $xml->XMLWriter()->text($proto->description);
         } else {
             $xml->XMLWriter()->text(self::GetItemDescription($itemID));
         }
         $xml->XMLWriter()->endElement();
         //desc
         if (!$parent) {
             for ($k = 1; $k < 4; $k++) {
                 if ($spell_tmp['EffectItemType_' . $k] > 0 && self::IsItemExists($spell_tmp['EffectItemType_' . $k])) {
                     $xml->XMLWriter()->startElement('itemTooltip');
                     self::ItemTooltip($spell_tmp['EffectItemType_' . $k], $xml, $characters, true);
                     $xml->XMLWriter()->endElement();
                     //itemTooltip
                     $spellreagents = $this->GetSpellItemCreateReagentsInfo($spell_tmp['EffectItemType_' . $k]);
                     if (is_array($spellreagents)) {
                         foreach ($spellreagents as $reagent) {
                             if (Utils::IsWriteRaw()) {
                                 $xml->XMLWriter()->writeRaw('<reagent');
                                 $xml->XMLWriter()->writeRaw(' count="' . $reagent['count'] . '"');
                                 $xml->XMLWriter()->writeRaw(' name="' . $reagent['name'] . '"');
                                 $xml->XMLWriter()->writeRaw('/>');
                                 //reagent
                             } else {
                                 $xml->XMLWriter()->startElement('reagent');
                                 $xml->XMLWriter()->writeAttribute('count', $reagent['count']);
                                 $xml->XMLWriter()->writeAttribute('name', $reagent['name']);
                                 $xml->XMLWriter()->endElement();
                                 //reagent
                             }
                         }
                     } else {
                         $xml->XMLWriter()->startElement('reagent');
                         $xml->XMLWriter()->endElement();
                         //reagent
                     }
                 }
             }
         }
         $xml->XMLWriter()->endElement();
         //spell
     }
     $xml->XMLWriter()->endElement();
     //spellData
     if ($proto->description != null && $proto->description != $spellInfo && $spellData != 1) {
         if (Utils::IsWriteRaw()) {
             $xml->XMLWriter()->writeRaw('<desc>');
             $xml->XMLWriter()->writeRaw(self::GetItemDescription($itemID));
             $xml->XMLWriter()->writeRaw('</desc>');
             //desc
         } else {
             $xml->XMLWriter()->startElement('desc');
             if (Armory::GetLocale() == 'en_gb' || Armory::GetLocale() == 'en_us') {
                 $xml->XMLWriter()->text($proto->description);
             } else {
                 $xml->XMLWriter()->text(self::GetItemDescription($itemID));
             }
             $xml->XMLWriter()->endElement();
             //desc
         }
     }
     if (!$parent) {
         $itemSource = self::GetItemSource($itemID);
         if (is_array($itemSource)) {
             if (Utils::IsWriteRaw()) {
                 $xml->XMLWriter()->writeRaw('<itemSource');
                 foreach ($itemSource as $source_key => $source_value) {
                     $xml->XMLWriter()->writeRaw(' ' . $source_key . '="' . $source_value . '"');
                 }
                 $xml->XMLWriter()->writeRaw('/>');
                 //itemSource
             } else {
                 $xml->XMLWriter()->startElement('itemSource');
                 foreach ($itemSource as $source_key => $source_value) {
                     $xml->XMLWriter()->writeAttribute($source_key, $source_value);
                 }
                 $xml->XMLWriter()->endElement();
                 //itemSource
             }
         }
         if ($itemSource['value'] == 'sourceType.vendor' && ($reqArenaRating = self::IsRequiredArenaRating($itemID))) {
             $xml->XMLWriter()->startElement('requiredPersonalArenaRating');
             $xml->XMLWriter()->writeAttribute('personalArenaRating', $reqArenaRating);
             $xml->XMLWriter()->endElement();
             //requiredPersonalArenaRating
         }
     }
 }