- work agains items + some random fixes .. use own item-table

- do not display serverside events in calendar
- include gems in item comparison .. also parse their stats in setup
- filters use conditions and are more restrictive
- changed DBSimple version so it uses mysqli (mysql is deprecated as of php 5.5)
- moved each filter class to matching type; file for baseType and BaseFilter
- baseType querys are somewhat modular, trying to avoid ridiculous joins that WILL occur sometimes (especially with items) as far as possible
This commit is contained in:
Sarjuuk
2013-09-08 21:41:49 +02:00
parent f422411cb6
commit 360f2e6878
86 changed files with 5976 additions and 3793 deletions

View File

@@ -28,3 +28,5 @@ RewriteEngine on
RewriteRule ^([a-z0-9\-]+)$ ?$1 [NC] # /items => ?items
RewriteRule ^([a-z0-9\-]+)=([^?&]*)$ ?$1=$2 [NC] # /items=4.1 => ?items=4.1
RewriteRule ^([a-z0-9\-]+)=([^?&]*)[&?](.*)$ ?$1=$2&$3 [NC] # /items=4.1?filter=sl=7 => ?items=4.1&filter=sl=7

View File

@@ -60,5 +60,6 @@ $AoWoWconf['limit'] = 300; // Limit of
$AoWoWconf['debug'] = true; // Disable cache, show smarty console panel, enable sql-errors
$AoWoWconf['map_grouping'] = 0; // Map object grouping factor. Meters = 10^param. 0:disabled; 1|2|3:enabled (1:recommended)
$AoWoWconf['battlegroup'] = 'Pure Pwnage'; // pretend, we belong to a battlegroup to satisfy profiler-related Jscripts; region can be determined from realmlist.timezone
$AoWoWconf['maintainance'] = false; // brb gnomes say hi
?>

View File

@@ -15,9 +15,9 @@ var wt_presets = {
},
3: {
pve: {
beast: {__icon:'ability_hunter_bestialdiscipline',rgddps:213,hitrtng:100,agi:58,critstrkrtng:40,int:37,atkpwr:30,armorpenrtng:28,hastertng:21},
beast: {__icon:'ability_hunter_beasttaming',rgddps:213,hitrtng:100,agi:58,critstrkrtng:40,int:37,atkpwr:30,armorpenrtng:28,hastertng:21},
marks: {__icon:'ability_hunter_focusedaim',rgddps:379,hitrtng:100,agi:74,critstrkrtng:57,armorpenrtng:40,int:39,atkpwr:32,hastertng:24},
surv: {__icon:'ability_hunter_camouflage',rgddps:181,hitrtng:100,agi:76,critstrkrtng:42,int:35,hastertng:31,atkpwr:29,armorpenrtng:26}
surv: {__icon:'inv_spear_02',rgddps:181,hitrtng:100,agi:76,critstrkrtng:42,int:35,hastertng:31,atkpwr:29,armorpenrtng:26}
}
},
4: {

View File

@@ -0,0 +1,273 @@
<?php
/**
* Используйте константу DBSIMPLE_SKIP в качестве подстановочного значения чтобы пропустить опцональный SQL блок.
*/
define('DBSIMPLE_SKIP', log(0));
/**
* Имена специализированных колонок в резальтате,
* которые используются как ключи в результирующем массиве
*/
define('DBSIMPLE_ARRAY_KEY', 'ARRAY_KEY'); // hash-based resultset support
define('DBSIMPLE_PARENT_KEY', 'PARENT_KEY'); // forrest-based resultset support
/**
* Класс обертка для DbSimple
*
* <br>нужен для ленивой инициализации коннекта к базе
*
* @package DbSimple
* @method mixed transaction(string $mode=null)
* @method mixed commit()
* @method mixed rollback()
* @method mixed select(string $query [, $arg1] [,$arg2] ...)
* @method mixed selectRow(string $query [, $arg1] [,$arg2] ...)
* @method array selectCol(string $query [, $arg1] [,$arg2] ...)
* @method string selectCell(string $query [, $arg1] [,$arg2] ...)
* @method mixed query(string $query [, $arg1] [,$arg2] ...)
* @method string escape(mixed $s, bool $isIdent=false)
* @method DbSimple_SubQuery subquery(string $query [, $arg1] [,$arg2] ...)
* @method callback setLogger(callback $logger)
* @method callback setCacher(callback $cacher)
* @method string setIdentPrefix($prx)
* @method string setCachePrefix($prx)
*/
class DbSimple_Connect
{
/** @var DbSimple_Generic_Database База данных */
protected $DbSimple;
/** @var string DSN подключения */
protected $DSN;
/** @var string Тип базы данных */
protected $shema;
/** @var array Что выставить при коннекте */
protected $init;
/** @var integer код ошибки */
public $error = null;
/** @var string сообщение об ошибке */
public $errmsg = null;
/**
* Конструктор только запоминает переданный DSN
* создание класса и коннект происходит позже
*
* @param string $dsn DSN строка БД
*/
public function __construct($dsn)
{
$this->DbSimple = null;
$this->DSN = $dsn;
$this->init = array();
$this->shema = ucfirst(substr($dsn, 0, strpos($dsn, ':')));
}
/**
* Взять базу из пула коннектов
*
* @param string $dsn DSN строка БД
* @return DbSimple_Connect
*/
public static function get($dsn)
{
static $pool = array();
return isset($pool[$dsn]) ? $pool[$dsn] : $pool[$dsn] = new self($dsn);
}
/**
* Возвращает тип базы данных
*
* @return string имя типа БД
*/
public function getShema()
{
return $this->shema;
}
/**
* Коннект при первом запросе к базе данных
*/
public function __call($method, $params)
{
if ($this->DbSimple === null)
$this->connect($this->DSN);
return call_user_func_array(array(&$this->DbSimple, $method), $params);
}
/**
* mixed selectPage(int &$total, string $query [, $arg1] [,$arg2] ...)
* Функцию нужно вызвать отдельно из-за передачи по ссылке
*/
public function selectPage(&$total, $query)
{
if ($this->DbSimple === null)
$this->connect($this->DSN);
$args = func_get_args();
$args[0] = &$total;
return call_user_func_array(array(&$this->DbSimple, 'selectPage'), $args);
}
/**
* Подключение к базе данных
* @param string $dsn DSN строка БД
*/
protected function connect($dsn)
{
$parsed = $this->parseDSN($dsn);
if (!$parsed)
$this->errorHandler('Ошибка разбора строки DSN', $dsn);
if (!isset($parsed['scheme']))
$this->errorHandler('Невозможно загрузить драйвер базы данных', $parsed);
$this->shema = ucfirst($parsed['scheme']);
require_once dirname(__FILE__).'/'.$this->shema.'.php';
$class = 'DbSimple_'.$this->shema;
$this->DbSimple = new $class($parsed);
$this->errmsg = &$this->DbSimple->errmsg;
$this->error = &$this->DbSimple->error;
$prefix = isset($parsed['prefix']) ? $parsed['prefix'] : ($this->_identPrefix ? $this->_identPrefix : false);
if ($prefix)
$this->DbSimple->setIdentPrefix($prefix);
if ($this->_cachePrefix) $this->DbSimple->setCachePrefix($this->_cachePrefix);
if ($this->_cacher) $this->DbSimple->setCacher($this->_cacher);
if ($this->_logger) $this->DbSimple->setLogger($this->_logger);
$this->DbSimple->setErrorHandler($this->errorHandler!==null ? $this->errorHandler : array(&$this, 'errorHandler'));
//выставление переменных
foreach($this->init as $query)
call_user_func_array(array(&$this->DbSimple, 'query'), $query);
$this->init = array();
}
/**
* Функция обработки ошибок - стандартный обработчик
* Все вызовы без @ прекращают выполнение скрипта
*
* @param string $msg Сообщение об ошибке
* @param array $info Подробная информация о контексте ошибки
*/
public function errorHandler($msg, $info)
{
// Если использовалась @, ничего не делать.
if (!error_reporting()) return;
// Выводим подробную информацию об ошибке.
echo "SQL Error: $msg<br><pre>";
print_r($info);
echo "</pre>";
exit();
}
/**
* Выставляет запрос для инициализации
*
* @param string $query запрос
*/
public function addInit($query)
{
$args = func_get_args();
if ($this->DbSimple !== null)
return call_user_func_array(array(&$this->DbSimple, 'query'), $args);
$this->init[] = $args;
}
/**
* Устанавливает новый обработчик ошибок
* Обработчик получает 2 аргумента:
* - сообщение об ошибке
* - массив (код, сообщение, запрос, контекст)
*
* @param callback|null|false $handler обработчик ошибок
* <br> null - по умолчанию
* <br> false - отключен
* @return callback|null|false предыдущий обработчик
*/
public function setErrorHandler($handler)
{
$prev = $this->errorHandler;
$this->errorHandler = $handler;
if ($this->DbSimple)
$this->DbSimple->setErrorHandler($handler);
return $prev;
}
/** @var callback обработчик ошибок */
private $errorHandler = null;
private $_cachePrefix = '';
private $_identPrefix = null;
private $_logger = null;
private $_cacher = null;
/**
* callback setLogger(callback $logger)
* Set query logger called before each query is executed.
* Returns previous logger.
*/
public function setLogger($logger)
{
$prev = $this->_logger;
$this->_logger = $logger;
if ($this->DbSimple)
$this->DbSimple->setLogger($logger);
return $prev;
}
/**
* callback setCacher(callback $cacher)
* Set cache mechanism called during each query if specified.
* Returns previous handler.
*/
public function setCacher(Zend_Cache_Backend_Interface $cacher=null)
{
$prev = $this->_cacher;
$this->_cacher = $cacher;
if ($this->DbSimple)
$this->DbSimple->setCacher($cacher);
return $prev;
}
/**
* string setIdentPrefix($prx)
* Set identifier prefix used for $_ placeholder.
*/
public function setIdentPrefix($prx)
{
$old = $this->_identPrefix;
if ($prx !== null) $this->_identPrefix = $prx;
if ($this->DbSimple)
$this->DbSimple->setIdentPrefix($prx);
return $old;
}
/**
* string setCachePrefix($prx)
* Set cache prefix used in key caclulation.
*/
public function setCachePrefix($prx)
{
$old = $this->_cachePrefix;
if ($prx !== null) $this->_cachePrefix = $prx;
if ($this->DbSimple)
$this->DbSimple->setCachePrefix($prx);
return $old;
}
/**
* Разбирает строку DSN в массив параметров подключения к базе
*
* @param string $dsn строка DSN для разбора
* @return array Параметры коннекта
*/
protected function parseDSN($dsn)
{
$parsed = parse_url($dsn);
if (!$parsed)
return null;
$params = null;
if (!empty($parsed['query']))
{
parse_str($parsed['query'], $params);
$parsed += $params;
}
$parsed['dsn'] = $dsn;
return $parsed;
}
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,9 +14,9 @@
* @author Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/
* @author Konstantin Zhinko, http://forum.dklab.ru/users/KonstantinGinkoTit/
*
* @version 2.x $Id: Ibase.php 221 2007-07-27 23:24:35Z dk $
* @version 2.x $Id$
*/
require_once dirname(__FILE__) . '/Generic.php';
require_once dirname(__FILE__) . '/Database.php';
/**
* Best transaction parameters for script queries.
@@ -30,7 +30,7 @@ define('IBASE_BEST_FETCH', IBASE_UNIXTIME);
* Database class for Interbase/Firebird.
*/
class DbSimple_Ibase extends DbSimple_Generic_Database
class DbSimple_Ibase extends DbSimple_Database
{
var $DbSimple_Ibase_BEST_TRANSACTION = IBASE_BEST_TRANSACTION;
var $DbSimple_Ibase_USE_NATIVE_PHOLDERS = true;
@@ -45,7 +45,7 @@ class DbSimple_Ibase extends DbSimple_Generic_Database
*/
function DbSimple_Ibase($dsn)
{
$p = DbSimple_Generic::parseDSN($dsn);
$p = DbSimple_Database::parseDSN($dsn);
if (!is_callable('ibase_connect')) {
return $this->_setLastError("-1", "Interbase/Firebird extension is not loaded", "ibase_connect");
}
@@ -77,10 +77,9 @@ class DbSimple_Ibase extends DbSimple_Generic_Database
$this->trans = @ibase_trans($parameters, $this->link);
}
function& _performNewBlob($blobid=null)
function _performNewBlob($blobid=null)
{
$obj =& new DbSimple_Ibase_Blob($this, $blobid);
return $obj;
return new DbSimple_Ibase_Blob($this, $blobid);
}
function _performGetBlobFieldNames($result)
@@ -199,7 +198,6 @@ class DbSimple_Ibase extends DbSimple_Generic_Database
$row = @ibase_fetch_assoc($result, $flags);
if (ibase_errmsg()) return $this->_setDbError($this->_lastQuery);
if ($row === false) return null;
return $row;
}
@@ -211,7 +209,7 @@ class DbSimple_Ibase extends DbSimple_Generic_Database
}
class DbSimple_Ibase_Blob extends DbSimple_Generic_Blob
class DbSimple_Ibase_Blob implements DbSimple_Blob
{
var $blob; // resourse link
var $id;

View File

@@ -14,15 +14,15 @@
* @author Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/
* @author Konstantin Zhinko, http://forum.dklab.ru/users/KonstantinGinkoTit/
*
* @version 2.x $Id: Mysql.php 163 2007-01-10 09:47:49Z dk $
* @version 2.x $Id: Mysql.php 247 2008-08-18 21:17:08Z dk $
*/
require_once dirname(__FILE__) . '/Generic.php';
require_once dirname(__FILE__).'/Database.php';
/**
* Database class for MySQL.
*/
class DbSimple_Mysql extends DbSimple_Generic_Database
class DbSimple_Mysql extends DbSimple_Database
{
var $link;
@@ -32,58 +32,54 @@ class DbSimple_Mysql extends DbSimple_Generic_Database
*/
function DbSimple_Mysql($dsn)
{
$p = DbSimple_Generic::parseDSN($dsn);
if (!is_callable('mysql_connect')) {
return $this->_setLastError("-1", "MySQL extension is not loaded", "mysql_connect");
}
$ok = $this->link = @mysql_connect(
$p['host'] . (empty($p['port'])? "" : ":".$p['port']),
$p['user'],
$p['pass'],
$connect = 'mysql_'.((isset($dsn['persist']) && $dsn['persist'])?'p':'').'connect';
if (!is_callable($connect))
return $this->_setLastError("-1", "MySQL extension is not loaded", $connect);
$ok = $this->link = @call_user_func($connect,
$dsn['host'] . (empty($dsn['port'])? "" : ":".$dsn['port']),
empty($dsn['user'])?'':$dsn['user'],
empty($dsn['pass'])?'':$dsn['pass'],
true
);
$this->_resetLastError();
if (!$ok) return $this->_setDbError('mysql_connect()');
$ok = @mysql_select_db(preg_replace('{^/}s', '', $p['path']), $this->link);
if (!$ok) return $this->_setDbError('mysql_select_db()');
if (!$ok)
if (!$ok) return $this->_setDbError('mysql_connect("' . $str . '", "' . $p['user'] . '")');
$ok = @mysql_select_db(preg_replace('{^/}s', '', $dsn['path']), $this->link);
if (!$ok)
return $this->_setDbError('mysql_select_db()');
mysql_query('SET NAMES '.(isset($dsn['enc'])?$dsn['enc']:'UTF8'));
}
function _performEscape($s, $isIdent=false)
protected function _performEscape($s, $isIdent=false)
{
if (!$isIdent) {
if (!$isIdent)
return "'" . mysql_real_escape_string($s, $this->link) . "'";
} else {
else
return "`" . str_replace('`', '``', $s) . "`";
}
}
function _performTransaction($parameters=null)
protected function _performNewBlob($blobid=null)
{
return $this->query('BEGIN');
return new DbSimple_Mysql_Blob($this, $blobid);
}
function& _performNewBlob($blobid=null)
{
$obj =& new DbSimple_Mysql_Blob($this, $blobid);
return $obj;
}
function _performGetBlobFieldNames($result)
protected function _performGetBlobFieldNames($result)
{
$blobFields = array();
for ($i=mysql_num_fields($result)-1; $i>=0; $i--) {
for ($i=mysql_num_fields($result)-1; $i>=0; $i--)
{
$type = mysql_field_type($result, $i);
if (strpos($type, "BLOB") !== false) $blobFields[] = mysql_field_name($result, $i);
if (stripos($type, "BLOB") !== false)
$blobFields[] = mysql_field_name($result, $i);
}
return $blobFields;
}
function _performGetPlaceholderIgnoreRe()
protected function _performGetPlaceholderIgnoreRe()
{
return '
" (?> [^"\\\\]+|\\\\"|\\\\)* " |
@@ -94,54 +90,40 @@ class DbSimple_Mysql extends DbSimple_Generic_Database
}
function _performCommit()
protected function _performTransaction($parameters=null)
{
return $this->query('BEGIN');
}
protected function _performCommit()
{
return $this->query('COMMIT');
}
function _performRollback()
protected function _performRollback()
{
return $this->query('ROLLBACK');
}
function _performTransformQuery(&$queryMain, $how)
protected function _performTransformQuery(&$queryMain, $how)
{
// If we also need to calculate total number of found rows...
switch ($how) {
switch ($how)
{
// Prepare total calculation (if possible)
case 'CALC_TOTAL':
$m = null;
if (preg_match('/^(\s* SELECT)(.*)/six', $queryMain[0], $m)) {
if ($this->_calcFoundRowsAvailable()) {
if (preg_match('/^(\s* SELECT)(.*)/six', $queryMain[0], $m))
$queryMain[0] = $m[1] . ' SQL_CALC_FOUND_ROWS' . $m[2];
}
}
return true;
// Perform total calculation.
case 'GET_TOTAL':
// Built-in calculation available?
if ($this->_calcFoundRowsAvailable()) {
$queryMain = array('SELECT FOUND_ROWS()');
}
// Else use manual calculation.
// TODO: GROUP BY ... -> COUNT(DISTINCT ...)
$re = '/^
(?> -- [^\r\n]* | \s+)*
(\s* SELECT \s+) #1
(.*?) #2
(\s+ FROM \s+ .*?) #3
((?:\s+ ORDER \s+ BY \s+ .*?)?) #4
((?:\s+ LIMIT \s+ \S+ \s* (?:, \s* \S+ \s*)? )?) #5
$/six';
$m = null;
if (preg_match($re, $queryMain[0], $m)) {
$query[0] = $m[1] . $this->_fieldList2Count($m[2]) . " AS C" . $m[3];
$skipTail = substr_count($m[4] . $m[5], '?');
if ($skipTail) array_splice($query, -$skipTail);
}
return true;
}
@@ -149,77 +131,76 @@ class DbSimple_Mysql extends DbSimple_Generic_Database
}
function _performQuery($queryMain)
protected function _performQuery($queryMain)
{
$this->_lastQuery = $queryMain;
$this->_expandPlaceholders($queryMain, false);
$result = @mysql_query($queryMain[0], $this->link);
if ($result === false) return $this->_setDbError($queryMain[0]);
$result = mysql_query($queryMain[0], $this->link);
if ($result === false)
return $this->_setDbError($queryMain[0]);
if (!is_resource($result)) {
if (preg_match('/^\s* INSERT \s+/six', $queryMain[0])) {
if (preg_match('/^\s* INSERT \s+/six', $queryMain[0]))
{
// INSERT queries return generated ID.
return @mysql_insert_id($this->link);
return mysql_insert_id($this->link);
}
// Non-SELECT queries return number of affected rows, SELECT - resource.
return @mysql_affected_rows($this->link);
return mysql_affected_rows($this->link);
}
return $result;
}
function _performFetch($result)
protected function _performFetch($result)
{
$row = @mysql_fetch_assoc($result);
$row = mysql_fetch_assoc($result);
if (mysql_error()) return $this->_setDbError($this->_lastQuery);
if ($row === false) return null;
return $row;
}
function _setDbError($query)
protected function _setDbError($query)
{
if ($this->link) {
return $this->_setLastError(mysql_errno($this->link), mysql_error($this->link), $query);
} else {
return $this->_setLastError(mysql_errno(), mysql_error(), $query);
}
function _calcFoundRowsAvailable()
{
$ok = version_compare(mysql_get_server_info($this->link), '4.0') >= 0;
return $ok;
}
}
class DbSimple_Mysql_Blob extends DbSimple_Generic_Blob
class DbSimple_Mysql_Blob implements DbSimple_Blob
{
// MySQL does not support separate BLOB fetching.
var $blobdata = null;
var $curSeek = 0;
private $blobdata = null;
private $curSeek = 0;
function DbSimple_Mysql_Blob(&$database, $blobdata=null)
public function __construct(&$database, $blobdata=null)
{
$this->blobdata = $blobdata;
$this->curSeek = 0;
}
function read($len)
public function read($len)
{
$p = $this->curSeek;
$this->curSeek = min($this->curSeek + $len, strlen($this->blobdata));
return substr($this->blobdata, $this->curSeek, $len);
return substr($this->blobdata, $p, $len);
}
function write($data)
public function write($data)
{
$this->blobdata .= $data;
}
function close()
public function close()
{
return $this->blobdata;
}
function length()
public function length()
{
return strlen($this->blobdata);
}

View File

@@ -0,0 +1,183 @@
<?php
/**
* DbSimple_Mysqli: MySQLi database.
* (C) Dk Lab, http://en.dklab.ru
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* See http://www.gnu.org/copyleft/lesser.html
*
* Placeholders are emulated because of logging purposes.
*
* @author Andrey Stavitsky
*
* @version 2.x $Id$
*/
require_once dirname(__FILE__).'/Database.php';
/**
* Database class for MySQL.
*/
class DbSimple_Mysqli extends DbSimple_Database
{
private $link;
private $isMySQLnd;
public function DbSimple_Mysqli($dsn)
{
$base = preg_replace('{^/}s', '', $dsn['path']);
if (!class_exists('mysqli'))
return $this->_setLastError('-1', 'mysqli extension is not loaded', 'mysqli');
try
{
$this->link = mysqli_init();
$this->link->options(MYSQLI_OPT_CONNECT_TIMEOUT,
isset($dsn['timeout']) && $dsn['timeout'] ? $dsn['timeout'] : 0);
$this->link->real_connect((isset($dsn['persist']) && $dsn['persist'])?'p:'.$dsn['host']:$dsn['host'],
$dsn['user'], isset($dsn['pass'])?$dsn['pass']:'', $base,
empty($dsn['port'])?NULL:$dsn['port'], NULL,
(isset($dsn['compression']) && $dsn['compression'])
? MYSQLI_CLIENT_COMPRESS : NULL);
$this->link->set_charset((isset($dsn['enc']) ? $dsn['enc'] : 'UTF8'));
$this->isMySQLnd = method_exists('mysqli_result', 'fetch_all');
}
catch (mysqli_sql_exception $e)
{
$this->_setLastError($e->getCode() , $e->getMessage(), 'new mysqli');
}
}
protected function _performGetPlaceholderIgnoreRe()
{
return '
" (?> [^"\\\\]+|\\\\"|\\\\)* " |
\' (?> [^\'\\\\]+|\\\\\'|\\\\)* \' |
` (?> [^`]+ | ``)* ` | # backticks
/\* .*? \*/ # comments
';
}
protected function _performEscape($s, $isIdent=false)
{
if (!$isIdent)
{
return "'" .$this->link->escape_string($s). "'";
}
else
{
return "`" . str_replace('`', '``', $s) . "`";
}
}
protected function _performTransaction($parameters=null)
{
return $this->link->query('BEGIN');
}
protected function _performCommit()
{
return $this->link->query('COMMIT');
}
protected function _performRollback()
{
return $this->link->query('ROLLBACK');
}
protected function _performQuery($queryMain)
{
$this->_lastQuery = $queryMain;
$this->_expandPlaceholders($queryMain, false);
$result = $this->link->query($queryMain[0]);
if (!$result)
return $this->_setDbError($this->link, $queryMain[0]);
if ($this->link->errno!=0)
return $this->_setDbError($this->link, $queryMain[0]);
if (preg_match('/^\s* INSERT \s+/six', $queryMain[0]))
return $this->link->insert_id;
if ($this->link->field_count == 0)
return $this->link->affected_rows;
if ($this->isMySQLnd)
{
$res = $result->fetch_all(MYSQLI_ASSOC);
$result->close();
}
else
{
$res = $result;
}
return $res;
}
protected function _performTransformQuery(&$queryMain, $how)
{
// If we also need to calculate total number of found rows...
switch ($how)
{
// Prepare total calculation (if possible)
case 'CALC_TOTAL':
$m = null;
if (preg_match('/^(\s* SELECT)(.*)/six', $queryMain[0], $m))
$queryMain[0] = $m[1] . ' SQL_CALC_FOUND_ROWS' . $m[2];
return true;
// Perform total calculation.
case 'GET_TOTAL':
// Built-in calculation available?
$queryMain = array('SELECT FOUND_ROWS()');
return true;
}
return false;
}
protected function _setDbError($obj,$q)
{
$info=$obj?$obj:$this->link;
return $this->_setLastError($info->errno, $info->error, $q);
}
protected function _performNewBlob($id=null)
{
}
protected function _performGetBlobFieldNames($result)
{
return array();
}
protected function _performFetch($result)
{
if ($this->isMySQLnd)
return $result;
$row = $result->fetch_assoc();
if ($this->link->error)
return $this->_setDbError($this->_lastQuery);
if ($row === false)
{
$result->close();
return null;
}
return $row;
}
}
?>

View File

@@ -12,7 +12,8 @@ class AchievementList extends BaseType
public $criteria = [];
public $tooltip = [];
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_achievement WHERE [filter] [cond] GROUP BY Id ORDER BY `orderInGroup` ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_achievement a';
protected $queryOpts = ['a' => ['o' => 'orderInGroup ASC']];
public function __construct($conditions = [], $applyFilter = false)
{
@@ -95,27 +96,6 @@ class AchievementList extends BaseType
return $data;
}
// hmm, really needed? .. probably .. needs rename? .. also probably
public function getDetailedData()
{
$data = [];
foreach ($this->iterate() as $__)
{
$data[$this->id] = array(
'id' => $this->id,
'name' => $this->getField('name', true),
'description' => $this->getField('description', true),
'points' => $this->curTpl['points'],
'iconname' => $this->curTpl['iconString'],
'count' => $this->curTpl['reqCriteriaCount'],
'reward' => $this->getField('reward', true)
);
}
return $data;
}
// only for current template
public function getCriteria($idx = -1)
{
@@ -242,4 +222,109 @@ class AchievementList extends BaseType
}
}
class AchievementListFilter extends Filter
{
// cr => [type, field, misc, extraCol]
protected $genericFilter = array( // misc (bool): _NUMERIC => useFloat; _STRING => localized; _FLAG => match Value; _BOOLEAN => stringSet
2 => [FILTER_CR_BOOLEAN, 'reward_loc0', true ], // givesreward
3 => [FILTER_CR_STRING, 'reward', true ], // rewardtext
7 => [FILTER_CR_BOOLEAN, 'series', ], // givesreward
9 => [FILTER_CR_NUMERIC, 'id', null, true], // prcntbasemanarequired
10 => [FILTER_CR_STRING, 'iconString', ], // icon
18 => [FILTER_CR_STAFFFLAG, 'flags', ], // lastrank
);
protected function createSQLForCriterium(&$cr)
{
if (in_array($cr[0], array_keys($this->genericFilter)))
{
if ($genCR = $this->genericCriterion($cr))
return $genCR;
unset($cr);
$this->error = true;
return [1];
}
switch ($cr[0])
{
case 4: // location [enum]
/* todo */ return [1]; // no plausible locations parsed yet
case 5: // first in series [yn]
return $this->int2Bool($cr[1]) ? ['AND', ['series', 0, '!'], [['series', 0xFFFF0000, '&'], 0]] : [['series', 0xFFFF0000, '&'], 0, '!'];
case 6: // last in series [yn]
return $this->int2Bool($cr[1]) ? ['AND', ['series', 0, '!'], [['series', 0xFFFF, '&'], 0]] : [['series', 0xFFFF, '&'], 0, '!'];
case 11: // Related Event [enum]
/* todo */ return [1]; // >0:holidayId; -2323:any; -2324:none .. not quite like the subcategories
case 14: // hascomments [yn]
/* todo */ return [1];
case 15: // hasscreenshots [yn]
/* todo */ return [1];
case 16: // hasvideos [yn]
/* todo */ return [1];
}
unset($cr);
$this->error = 1;
return [1];
}
protected function createSQLForValues()
{
$parts = [];
$_v = &$this->fiData['v'];
// name ex: +description, +rewards
if (isset($_v['na']))
{
if (isset($_v['ex']) && $_v['ex'] == 'on')
$parts[] = ['OR', ['name_loc'.User::$localeId, $_v['na']], ['description_loc'.User::$localeId, $_v['na']], ['reward_loc'.User::$localeId, $_v['na']]];
else
$parts[] = ['name_loc'.User::$localeId, $_v['na']];
}
// points min
if (isset($_v['minpt']))
{
if ($this->isSaneNumeric($_v['minpt']))
$parts[] = ['points', $_v['minpt'], '>='];
else
unset($_v['minpt']);
}
// points max
if (isset($_v['maxpt']))
{
if ($this->isSaneNumeric($_v['maxpt']))
$parts[] = ['points', $_v['maxpt'], '<='];
else
unset($_v['maxpt']);
}
// faction (side)
if (isset($_v['si']))
{
switch ($_v['si'])
{
case 3: // both
$parts[] = ['faction', 0];
break;
case -1: // faction, exclusive both
case -2:
$parts[] = ['faction', -$_v['si']];
break;
case 1: // faction, inclusive both
case 2:
$parts[] = ['OR', ['faction', 0], ['faction', $_v['si']]];
break;
default:
unset($_v['si']);
}
}
return $parts;
}
}
?>

865
includes/class.basetype.php Normal file
View File

@@ -0,0 +1,865 @@
<?php
if(!defined('AOWOW_REVISION'))
die("illegal access");
abstract class BaseType
{
public $id = 0;
public $error = true;
protected $templates = [];
protected $curTpl = []; // lets iterate!
protected $filter = null;
protected $matches = null; // total matches unaffected by sqlLimit in config
protected $queryBase = '';
protected $queryOpts = [];
/*
* condition as array [expression, value, operator]
* expression: str - must match fieldname;
* int - impl. 1: select everything
* array - another condition array
* value: str - operator defaults to: LIKE %<val>%
* int - operator defaults to: = <val>
* array - operator defaults to: IN (<val>)
* operator: modifies/overrides default
* ! - negated default value (NOT LIKE; <>; NOT IN)
* condition as str
* defines linking (AND || OR)
* condition as int
* defines LIMIT
*
* example:
* array(
* ['id', 45],
* ['name', 'test', '!'],
* [
* 'AND',
* ['flags', 0xFF, '&'],
* ['flags2', 0xF, '&'],
* ]
* [['mask', 0x3, '&'], 0]
* 'OR',
* 5
* )
* results in
* WHERE ((`id` = 45) OR (`name` NOT LIKE "%test%") OR ((`flags` & 255) AND (`flags2` & 15)) OR ((`mask` & 3) = 0)) LIMIT 5
*/
public function __construct($conditions = [], $applyFilter = false)
{
global $AoWoWconf; // yes i hate myself..
$where = [];
$linking = ' AND ';
$limit = $AoWoWconf['sqlLimit'];
$className = get_class($this);
if (!$this->queryBase || $conditions === null)
return;
// may be called without filtering
if ($applyFilter && class_exists($className.'Filter'))
{
$fiName = $className.'Filter';
$this->filter = new $fiName($this);
}
$prefixes = [];
if (preg_match('/FROM \??[\w\_]+( AS)?\s?`?(\w+)`?$/i', $this->queryBase, $match))
$prefixes['base'] = $match[2];
else
$prefixes['base'] = '';
// add conditions from filter
// to consider - conditions from filters are already escaped and contain sql-wildcards reescaping those sucks
$conditions[] = $this->filter ? $this->filter->getConditions() : null;
$resolveCondition = function ($c, $supLink) use (&$resolveCondition, &$prefixes)
{
$subLink = '';
if (!$c)
return null;
foreach ($c as $foo)
{
if ($foo === 'AND')
$subLink = ' AND ';
else if ($foo === 'OR') // nessi-bug: if (0 == 'OR') was true once... w/e
$subLink = ' OR ';
}
// need to manually set link for subgroups to be recognized as condition set
if ($subLink)
{
$sql = [];
foreach ($c as $foo)
if (is_array($foo))
if ($x = $resolveCondition($foo, $supLink))
$sql[] = $x;
return '('.implode($subLink, $sql).')';
}
else
{
if ($c[0] == '1')
return '1';
else if ($c[0] == '0')
return '(0)'; // trick if ($x = 0) into true...
else if (is_array($c[0]) && isset($c[1]))
$field = $resolveCondition($c[0], $supLink);
else if ($c[0])
{
$setPrefix = function($f) use(&$prefixes)
{
if (is_array($f))
$f = $f[0];
if (is_numeric($f))
return $f;
$f = explode('.', Util::sqlEscape($f));
switch (count($f))
{
case 2:
if (!in_array($f[0], $prefixes))
{
// choose table to join or return null if prefix not existant
if (!in_array($f[0], array_keys($this->queryOpts)))
return null;
$prefixes[] = $f[0];
}
return '`'.$f[0].'`.`'.$f[1].'`';
case 1:
return '`'.$prefixes['base'].'`.`'.$f[0].'`';
default:
return null;
}
};
// basic formulas
if (preg_match('/^\([\s\+\-\*\/\w\(\)\.]+\)$/i', strtr($c[0], ['`' => '', '´' => '', '--' => ''])))
$field = preg_replace_callback('/[\w\]*\.?[\w]+/i', $setPrefix, $c[0]);
else
$field = $setPrefix($c[0]);
if (!$field)
return null;
}
else
return null;
if (is_array($c[1]))
{
$val = implode(',', Util::sqlEscape($c[1], true));
if ($val === '')
return null;
$op = (isset($c[2]) && $c[2] == '!') ? 'NOT IN' : 'IN';
$val = '('.$val.')';
}
else if (Util::checkNumeric($c[1]))
{
$op = (isset($c[2]) && $c[2] == '!') ? '<>' : '=';
$val = $c[1];
}
else if (is_string($c[1]))
{
$val = Util::sqlEscape($c[1], true);
$op = (isset($c[2]) && $c[2] == '!') ? 'NOT LIKE' : 'LIKE';
$val = $val === '' ? '""' : '"%'.$val.'%"';
}
else // null for example
return null;
if (isset($c[2]) && $c[2] != '!')
$op = $c[2];
return '('.$field.' '.$op.' '.$val.')';
}
};
foreach ($conditions as $i => $c)
{
switch(getType($c))
{
case 'array':
break;
case 'string':
case 'integer':
if (is_string($c))
$linking = $c == 'AND' ? ' AND ' : ' OR ';
else
$limit = $c > 0 ? $c : 0;
default:
unset($conditions[$i]);
}
}
foreach ($conditions as $c)
if ($x = $resolveCondition($c, $linking))
$where[] = $x;
// optional query parts may require other optional parts to work
foreach ($prefixes as $pre)
if (isset($this->queryOpts[$pre][0]))
foreach ($this->queryOpts[$pre][0] as $req)
if (!in_array($req, $prefixes))
$prefixes[] = $req;
// remove optional query parts, that are not required
foreach ($this->queryOpts as $k => $arr)
if (!in_array($k, $prefixes))
unset($this->queryOpts[$k]);
// insert additional selected fields
if ($s = array_column($this->queryOpts, 's'))
$this->queryBase = str_replace(' FROM', implode('', $s).' FROM', $this->queryBase);
// append joins
if ($j = array_column($this->queryOpts, 'j'))
foreach ($j as $_)
$this->queryBase .= is_array($_) ? (empty($_[1]) ? ' JOIN ' : ' LEFT JOIN ') . $_[0] : ' JOIN ' . $_;
// append conditions
if ($where)
$this->queryBase .= ' WHERE (' . implode($linking, $where).')';
// append grouping
if ($g = array_column($this->queryOpts, 'g'))
$this->queryBase .= ' GROUP BY ' . implode(', ', $g);
// append post filtering
if ($h = array_column($this->queryOpts, 'h'))
$this->queryBase .= ' HAVING ' . implode(' AND ', $h);
// append ordering
if ($o = array_column($this->queryOpts, 'o'))
$this->queryBase .= ' ORDER BY ' . implode(', ', $o);
// apply limit
if ($limit)
$this->queryBase .= ' LIMIT '.$limit;
// Util::execTime(true);
// var_dump($this->queryBase);
// echo "<br><br>\n\n";
// execure query (finally)
$rows = DB::Aowow()->SelectPage($this->matches, $this->queryBase);
if (!$rows)
return;
// var_dump(Util::execTime());
// echo "<br><br><br>\n\n";
// assign query results to template
foreach ($rows as $k => $tpl)
$this->templates[$k] = $tpl;
// push first element for instant use
$this->reset();
// all clear
$this->error = false;
}
public function &iterate()
{
// reset on __construct
$this->reset();
while (list($id, $_) = each($this->templates))
{
$this->id = $id;
$this->curTpl = &$this->templates[$id]; // do not use $tpl from each(), as we want to be referenceable
yield $id => $this->curTpl;
unset($this->curTpl); // kill reference or it will 'bleed' into the next iteration
}
// reset on __destruct .. Generator, Y U NO HAVE __destruct ?!
$this->reset();
}
protected function reset()
{
unset($this->curTpl); // kill reference or strange stuff will happen
$this->curTpl = reset($this->templates);
$this->id = key($this->templates);
}
// read-access to templates
public function getField($field, $localized = false)
{
if (!$this->curTpl || (!$localized && !isset($this->curTpl[$field])))
return '';
if ($localized)
return Util::localizedString($this->curTpl, $field);
$value = $this->curTpl[$field];
return Util::checkNumeric($value) ? floatVal($value) : $value;
}
public function getRandomId()
{
$pattern = '/SELECT .* (-?[\w_]*\.?(id|entry)) AS ARRAY_KEY,?.* FROM (.*) WHERE .*/i';
$replace = 'SELECT $1 FROM $3 ORDER BY RAND() ASC LIMIT 1';
$query = preg_replace($pattern, $replace, $this->queryBase);
return DB::Aowow()->selectCell($query);
}
public function getFoundIDs()
{
return array_keys($this->templates);
}
public function getMatches()
{
return $this->matches;
}
public function filterGetForm($key = null, $raw = false)
{
$form = [];
if (!$this->filter)
return $form;
foreach ($this->filter->getForm() as $name => $data)
{
if (!$data || ($key && $name != $key))
continue;
switch ($name)
{
case 'setCriteria':
$form[$name] = $raw ? $data : 'fi_setCriteria('.$data['cr'].', '.$data['crs'].', '.$data['crv'].');';
break;
case 'extraCols':
$form[$name] = $raw ? $data : 'fi_extraCols = '.json_encode(array_unique($data), JSON_NUMERIC_CHECK).';';
break;
case 'setWeights':
$form[$name] = $raw ? $data : 'fi_setWeights('.json_encode($data, JSON_NUMERIC_CHECK).', 0, 1, 1);';
break;
case 'form':
if ($key == $name) // only if explicitely specifies
$form[$name] = $data;
break;
default:
break;
}
}
return $key ? (empty($form[$key]) ? [] : $form[$key]) : $form;
}
public function filterGetError()
{
if ($this->filter)
return $this->filter->error;
else
return false;
}
// should return data required to display a listview of any kind
// this is a rudimentary example, that will not suffice for most Types
abstract public function getListviewData();
// should return data to extend global js variables for a certain type (e.g. g_items)
abstract public function addGlobalsToJScript(&$smarty, $addMask = GLOBALINFO_ANY);
// NPC, GO, Item, Quest, Spell, Achievement, Profile would require this
abstract public function renderTooltip();
}
trait listviewHelper
{
public function hasSetFields($fields)
{
if (!is_array($fields))
return 0x0;
$result = 0x0;
foreach ($this->iterate() as $__)
{
foreach ($fields as $k => $str)
{
if ($this->getField($str))
{
$result |= 1 << $k;
unset($fields[$k]);
}
}
if (empty($fields)) // all set .. return early
{
$this->reset(); // Generators have no __destruct, reset manually, when not doing a full iteration
return $result;
}
}
return $result;
}
public function hasDiffFields($fields)
{
if (!is_array($fields))
return 0x0;
$base = [];
$result = 0x0;
foreach ($fields as $k => $str)
$base[$str] = $this->getField($str);
foreach ($this->iterate() as $__)
{
foreach ($fields as $k => $str)
{
if ($base[$str] != $this->getField($str))
{
$result |= 1 << $k;
unset($fields[$k]);
}
}
if (empty($fields)) // all fields diff .. return early
{
$this->reset(); // Generators have no __destruct, reset manually, when not doing a full iteration
return $result;
}
}
return $result;
}
public function hasAnySource()
{
if (!isset($this->sources))
return false;
foreach ($this->sources as $src)
{
if (!is_array($src))
continue;
if (!empty($src))
return true;
}
return false;
}
}
trait spawnHelper
{
private static $spawnQuery = " SELECT a.guid AS ARRAY_KEY, map, position_x, position_y, spawnMask, phaseMask, spawntimesecs, eventEntry, pool_entry AS pool FROM ?# a LEFT JOIN ?# b ON a.guid = b.guid LEFT JOIN ?# c ON a.guid = c.guid WHERE id = ?d";
private function fetch()
{
if (!$this->id)
return false;
switch (get_class($this))
{
case 'CreatureList':
return DB::Aowow()->select(self::$spawnQuery, 'creature', 'game_event_creature', 'pool_creature', $this->id);
case 'GameObjectList':
return DB::Aowow()->select(self::$spawnQuery, 'gameobject', 'game_event_gameobject', 'pool_gameobject', $this->id);
default:
return false;
}
}
/*
todo (med): implement this alpha-map-check-virtual-map-transform-wahey!
note: map in tooltips is activated by either '#map' as anchor (will automatic open mapviewer, when clicking link) in the href or as parameterless rel-parameter e.g. rel="map" in the anchor
*/
public function getSpawns($spawnInfo)
{
// SPAWNINFO_SHORT: true => only the most populated area and only coordinates
$data = [];
// $raw = $this->fetch();
// if (!$raw)
// return [];
/*
SPAWNINFO_FULL:
$data = array(
areaId => array(
floorNo => array (
posX =>
posY =>
respawn =>
phaseMask =>
spawnMask =>
eventId =>
poolId =>
)
)
)
SPAWNINFO_SHORT: [zoneId, [[x1, y1], [x2, y2], ..]] // only the most populated zone
SPAWNINFO_ZONES: [zoneId1, zoneId2, ..] // only zones
*/
return $data;
}
}
/*
roight!
just noticed, that the filters on pages originally pointed to ?filter=<pageName>
wich probably checked for correctness of inputs and redirected the correct values as a get-request
..
well, as it is now, its working .. and you never change a running system ..
*/
abstract class Filter
{
private static $pattern = "/[^\p{L}0-9\s_\-\'\.\?\*]/ui";// delete any char not in unicode, number, space, underscore, hyphen, single quote, dot or common wildcard
private static $wCards = ['*' => '%', '?' => '_'];
private static $criteria = ['cr', 'crs', 'crv']; // [cr]iterium, [cr].[s]ign, [cr].[v]alue
public $error = false; // erronous search fields
private $cndSet = [];
protected $parent = null; // itemFilter requires this
protected $fiData = ['c' => [], 'v' =>[]];
protected $formData = array( // data to fill form fields
'form' => [], // base form - unsanitized
'setCriteria' => [], // dynamic criteria list - index checked
'setWeights' => [], // dynamic weights list - index checked
'extraCols' => [] // extra columns for LV - added as required
);
// parse the provided request into a usable format; recall self with GET-params if nessecary
public function __construct($parent)
{
$this->parent = $parent;
// prefer POST over GET, translate to url
if (!empty($_POST))
{
foreach ($_POST as $k => $v)
{
if (is_array($v)) // array -> max depths:1
{
if (in_array($k, ['cr', 'wt']) && empty($v[0]))
continue;
$sub = [];
foreach ($v as $sk => $sv)
$sub[$sk] = Util::checkNumeric($sv) ? $sv : urlencode($sv);
if (!empty($sub) && in_array($k, self::$criteria))
$this->fiData['c'][$k] = $sub;
else if (!empty($sub))
$this->fiData['v'][$k] = $sub;
}
else // stings and integer
{
if (in_array($k, self::$criteria))
$this->fiData['c'][$k] = Util::checkNumeric($v) ? $v : urlencode($v);
else
$this->fiData['v'][$k] = Util::checkNumeric($v) ? $v : urlencode($v);
}
}
// create get-data
$tmp = [];
foreach (array_merge($this->fiData['c'], $this->fiData['v']) as $k => $v)
{
if ($v == '')
continue;
else if (is_array($v))
$tmp[$k] = $k."=".implode(':', $v);
else
$tmp[$k] = $k."=".$v;
}
// do get request
header('Location: '.STATIC_URL.'?'.$_SERVER['QUERY_STRING'].'='.implode(';', $tmp));
}
// sanitize input and build sql
else if (!empty($_GET['filter']))
{
$tmp = explode(';', $_GET['filter']);
$cr = $crs = $crv = [];
foreach (self::$criteria as $c)
{
foreach ($tmp as $i => $term)
{
if (strpos($term, $c.'=') === 0)
{
$$c = explode(':', explode('=', $term)[1]);
$this->formData['setCriteria'][$c] = json_encode($$c, JSON_NUMERIC_CHECK); // todo (high): move to checks
unset($tmp[$i]);
}
}
}
for ($i = 0; $i < max(count($cr), count($crv), count($crs)); $i++)
{
if (!isset($cr[$i]) || !isset($crs[$i]) || !isset($crv[$i]) ||
!intVal($cr[$i]) || $crs[$i] === '' || $crv[$i] === '')
{
$this->error = true;
continue;
}
$this->sanitize($crv[$i]);
if ($crv[$i] !== '')
{
$this->fiData['c']['cr'][] = intVal($cr[$i]);
$this->fiData['c']['crs'][] = intVal($crs[$i]);
$this->fiData['c']['crv'][] = $crv[$i];
}
else
$this->error = true;
}
foreach ($tmp as $v)
{
if (!strstr($v, '='))
continue;
$w = explode('=', $v);
if (strstr($w[1], ':'))
{
$tmp2 = explode(':', $w[1]);
$this->formData['form'][$w[0]] = $tmp2;
array_walk($tmp2, function(&$v) { $v = intVal($v); });
$this->fiData['v'][$w[0]] = $tmp2;
}
else
{
$this->formData['form'][$w[0]] = $w[1];
$this->sanitize($w[1]);
if ($w[1] !== '')
{
Util::checkNumeric($w[1]);
$this->fiData['v'][$w[0]] = $w[1];
}
else
$this->error = true;
}
}
$this->evaluateFilter();
}
}
// todo: kill data, that is unexpected or points to wrong indizes
private function evaluateFilter()
{
// values
$this->cndSet = $this->createSQLForValues();
// criteria
foreach ($this->criteriaIterator() as &$_cr)
$this->cndSet[] = $this->createSQLForCriterium($_cr);
if ($this->cndSet)
array_unshift($this->cndSet, empty($this->fiData['v']['ma']) ? 'AND' : 'OR');
}
public function getForm()
{
return $this->formData;
}
public function getConditions()
{
return $this->cndSet;
}
// santas little helper..
private function &criteriaIterator()
{
if (!$this->fiData['c'])
return;
for ($i = 0; $i < count($this->fiData['c']['cr']); $i++)
{
// throws a notice if yielded directly "Only variable references should be yielded by reference"
$v = [&$this->fiData['c']['cr'][$i], &$this->fiData['c']['crs'][$i], &$this->fiData['c']['crv'][$i]];
yield $i => $v;
}
}
protected function int2Op(&$op)
{
switch ($op)
{
case 1: $op = '>'; return true;
case 2: $op = '>='; return true;
case 3: $op = '='; return true;
case 4: $op = '<='; return true;
case 5: $op = '<'; return true;
default: return false;
}
}
protected function int2Bool(&$op)
{
switch ($op)
{
case 1: $op = true; return true;
case 2: $op = false; return true;
default: return false;
}
}
protected function list2Mask($list, $noOffset = false)
{
$mask = 0x0;
$o = $noOffset ? 0 : 1; // schoolMask requires this..?
if (!is_array($list))
$mask = (1 << (intVal($list) - $o));
else
foreach ($list as $itm)
$mask += (1 << (intVal($itm) - $o));
return $mask;
}
protected function isSaneNumeric(&$val, $castInt = true)
{
if ($castInt && is_float($val))
$val = intVal($val);
if (is_int($val) || (is_float($val) && $val >= 0.0))
return true;
return false;
}
private function sanitize(&$str)
{
$str = preg_replace(Filter::$pattern, '', trim($str));
$str = Util::checkNumeric($str) ? $str : strtr($str, Filter::$wCards);
}
private function genericBoolean($field, $op, $isString)
{
if ($this->int2Bool($op))
{
if ($isString)
return [$field, '', $op ? '!' : null];
else
return [$field, 0, $op ? '>' : '<='];
}
return null;
}
private function genericBooleanFlags($field, $value, $op)
{
if ($this->int2Bool($op))
return [[$field, $value, '&'], $op ? $value : 0];
return null;
}
private function genericString($field, $value, $localized)
{
$field .= $localized ? '_loc' . User::$localeId : null;
return [$field, (string)$value];
}
private function genericNumeric($field, &$value, $op, $castInt)
{
if (!$this->isSaneNumeric($value, $castInt))
return null;
if ($this->int2Op($op))
return [$field, $value, $op];
return null;
}
private function genericEnum($field, $value)
{
if (is_bool($value))
return [$field, 0, ($value ? '>' : '<=')];
else if ($value == -2323) // any
return [$field, 0, '>'];
else if ($value == -2324) // none
return [$field, 0, '<='];
else if ($value !== null)
return [$field, $value];
return null;
}
protected function genericCriterion(&$cr)
{
$gen = $this->genericFilter[$cr[0]];
$result = null;
switch ($gen[0])
{
case FILTER_CR_NUMERIC:
$result = $this->genericNumeric($gen[1], $cr[2], $cr[1], empty($gen[2]));
break;
case FILTER_CR_FLAG:
$result = $this->genericBooleanFlags($gen[1], $gen[2], $cr[1]);
break;
case FILTER_CR_STAFFFLAG:
if (User::isInGroup(U_GROUP_STAFF) && $cr[1] >= 0)
$result = $this->genericBooleanFlags($gen[1], (1 << $cr[1]), true);
break;
case FILTER_CR_BOOLEAN:
$result = $this->genericBoolean($gen[1], $cr[1], !empty($gen[2]));
break;
case FILTER_CR_STRING:
$result = $this->genericString($gen[1], $cr[2], !empty($gen[2]));
break;
case FILTER_CR_ENUM:
if (isset($this->enums[$cr[0]][$cr[1]]))
$result = $this->genericEnum($gen[1], $this->enums[$cr[0]][$cr[1]]);
else if (intVal($cr[1]) != 0)
$result = $this->genericEnum($gen[1], intVal($cr[1]));
break;
}
if ($result && !empty($gen[3]))
$this->formData['extraCols'][] = $cr[0];
return $result;
}
// apply Util::sqlEscape() and intVal() in the implementation of these
abstract protected function createSQLForCriterium(&$cr);
abstract protected function createSQLForValues();
}
?>

View File

@@ -7,7 +7,7 @@ class CharClassList extends BaseType
{
public static $type = TYPE_CLASS;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_classes WHERE [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_classes c';
public function __construct($conditions = [])
{

View File

@@ -7,7 +7,7 @@ class CharRaceList extends BaseType
{
public static $type = TYPE_RACE;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_races WHERE [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_races r';
public function getListviewData()
{

View File

@@ -12,7 +12,11 @@ class CreatureList extends BaseType
public $tooltips = [];
protected $setupQuery = 'SELECT ct.*, ct.id AS ARRAY_KEY, ft.A, ft.H, ft.factionId FROM ?_creature ct LEFT JOIN ?_factiontemplate ft ON ft.id = ct.faction_A WHERE [filter] [cond]';
protected $queryBase = 'SELECT ct.*, ct.id AS ARRAY_KEY FROM ?_creature ct';
protected $queryOpts = array(
'ct' => [['ft']],
'ft' => ['j' => '?_factiontemplate ft ON ft.id = ct.faction_A', 's' => ', ft.A, ft.H, ft.factionId']
);
public static function getName($id)
{

View File

@@ -7,7 +7,7 @@ class CurrencyList extends BaseType
{
public static $type = TYPE_CURRENCY;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_currencies WHERE [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_currencies c';
public function getListviewData()
{

View File

@@ -17,7 +17,7 @@ class DB
private static function createConnectSyntax(&$options)
{
return 'mysql://'.$options['user'].':'.$options['pass'].'@'.$options['host'].'/'.$options['db'];
return 'mysqli://'.$options['user'].':'.$options['pass'].'@'.$options['host'].'/'.$options['db'];
}
public static function connect($idx)

View File

@@ -1,530 +0,0 @@
<?php
if(!defined('AOWOW_REVISION'))
die("illegal access");
abstract class Filter
{
private static $pattern = "/[^\p{L}0-9\s_\-\'\?\*]/ui";// delete any char not in unicode, number, space, underscore, hyphen, single quote or common wildcard
private static $wildcards = ['*' => '%', '?' => '_'];
private static $criteria = ['cr', 'crs', 'crv']; // [cr]iterium, [cr].[s]ign, [cr].[v]alue
private $fiData = ['c' => [], 'v' =>[]];
private $query = '';
private $form = []; // unsanitized: needed to preselect form-fields
private $setCr = []; // unsanitized: needed to preselect criteria
public $error = false; // erronous search fields
// parse the provided request into a usable format; recall self with GET-params if nessecary
public function init()
{
// prefer POST over GET, translate to url
if (!empty($_POST))
{
foreach ($_POST as $k => $v)
{
if (is_array($v)) // array -> max depths:1
{
if ($k == 'cr' && empty($v[0]))
continue;
$sub = [];
foreach ($v as $sk => $sv)
$sub[$sk] = is_numeric($sv) ? (int)$sv : urlencode($sv);
if (!empty($sub) && in_array($k, Filter::$criteria))
$this->fiData['c'][$k] = $sub;
else if (!empty($sub))
$this->fiData['v'][$k] = $sub;
}
else // stings and integer
{
if (in_array($k, Filter::$criteria))
$this->fiData['c'][$k] = is_numeric($v) ? (int)$v : urlencode($v);
else
$this->fiData['v'][$k] = is_numeric($v) ? (int)$v : urlencode($v);
}
}
// create get-data
$tmp = [];
foreach (array_merge($this->fiData['c'], $this->fiData['v']) as $k => $v)
{
if ($v == '')
continue;
else if (is_array($v))
$tmp[$k] = $k."=".implode(':', $v);
else
$tmp[$k] = $k."=".$v;
}
// do get request
$this->redirect(implode(';', $tmp));
}
// sanitize input and build sql
else if (!empty($_GET['filter']))
{
$tmp = explode(';', $_GET['filter']);
$cr = $crs = $crv = [];
foreach (Filter::$criteria as $c)
{
foreach ($tmp as $i => $term)
{
if (strpos($term, $c.'=') === 0)
{
$$c = explode(':', explode('=', $term)[1]);
$this->setCr[$c] = json_encode($$c, JSON_NUMERIC_CHECK);
unset($tmp[$i]);
}
}
}
for ($i = 0; $i < max(count($cr), count($crv), count($crs)); $i++)
{
if (!isset($cr[$i]) || !isset($crs[$i]) || !isset($crv[$i]) ||
!intVal($cr[$i]) || $crs[$i] == '' || $crv[$i] == '')
{
$this->error = true;
continue;
}
$this->sanitize($crv[$i]);
if ($crv[$i] != '')
{
$this->fiData['c']['cr'][] = intVal($cr[$i]);
$this->fiData['c']['crs'][] = $crs[$i];
$this->fiData['c']['crv'][] = $crv[$i];
}
else
$this->error = true;
}
foreach ($tmp as $v)
{
$w = explode('=', $v);
if (strstr($w[1], ':'))
{
$tmp2 = explode(':', $w[1]);
$this->form[$w[0]] = $tmp2;
array_walk($tmp2, function(&$v) { $v = intVal($v); });
$this->fiData['v'][$w[0]] = $tmp2;
}
else
{
$this->form[$w[0]] = $w[1];
$this->sanitize($w[1]);
if ($w[1] != '')
$this->fiData['v'][$w[0]] = is_numeric($w[1]) ? (int)$w[1] : $w[1];
else
$this->error = true;
}
}
return $this->fiData;
}
}
public function buildQuery()
{
if (!empty($this->query))
return $this->query;
$parts = [];
// values
$parts = $this->createSQLForValues($this->fiData['v']);
// criteria
$c = &$this->fiData['c'];
if (!empty($c))
{
if (is_array($c['cr']))
{
for ($i = 0; $i < count($c['cr']); $i++)
$parts[] = $this->createSQLForCriterium(array($c['cr'][$i], $c['crs'][$i], $c['crv'][$i]));
}
else
$parts[] = $this->createSQLForCriterium(array($c['cr'], $c['crs'], $c['crv']));
}
$this->query = empty($parts) ? '' : '('.implode(empty($this->fiData['v']['ma']) ? ' AND ' : ' OR ', $parts).')';
return $this->query;
}
public function getQuery()
{
return $this->query;
}
public function getForm()
{
return $this->form;
}
public function getSetCriteria()
{
if (!empty($this->setCr['cr']))
return sprintf(Util::$setCriteriaString, $this->setCr['cr'], $this->setCr['crs'], $this->setCr['crv']);
else
return null;
}
// santas little helper..
protected function int2Op($int)
{
switch ($int)
{
case 1: return '>';
case 2: return '>=';
case 3: return '=';
case 4: return '<=';
case 5: return '<';
default: die('invalid op');
}
}
protected function int2Bool($int)
{
switch ($int)
{
case 1: return true;
case 2: return false;
default: die('invalid op');
}
}
protected function list2Mask($list, $noOffset = false)
{
$mask = 0x0;
$o = $noOffset ? 0 : 1; // schoolMask requires this..?
if (is_array($list))
{
foreach ($list as $itm)
$mask += (1 << (intVal($itm) - $o));
}
else
$mask = (1 << (intVal($list) - $o));
return $mask;
}
private function sanitize(&$str)
{
$str = preg_replace(Filter::$pattern, '', trim($str));
$str = strtr($str, Filter::$wildcards);
}
// if called with POST-data, convert to GET request and call self
private function redirect($get)
{
header('Location: '.STATIC_URL.'?'.$_SERVER['QUERY_STRING'].'='.$get);
}
// TODO: wrong wrong wrong!!
// 1) filter-Ids are different for each type; 2) (NOT) IN - subqueries will eat the mysql-server alive!
protected function createSQLForCommunity($cr)
{
switch ($cr[0])
{
case 14: // has Comments [y|n]
return ''; // IN / NOT IN (select Ids FROM aowow_comments ON type = X AND id Y and flags = valid)
case 15: // has Screenshots [y|n]
return ''; // IN / NOT IN (select Ids FROM aowow_screenshots ON type = X AND id Y and flags = valid)
case 16: // has Videos [y|n]
return ''; // IN / NOT IN (select Ids FROM aowow_videos ON type = X AND id Y and flags = valid)
}
}
// apply Util::sqlEscape() and intVal() in the implementation of these
abstract protected function createSQLForCriterium($cr);
abstract protected function createSQLForValues($vl);
}
class AchievementListFilter extends Filter
{
protected function createSQLForCriterium($cr)
{
if ($r = $this->createSQLForCommunity($cr))
return $r;
switch ($cr[0])
{
case 2: // gives a reward [y|n]
return 'reward_loc0 '.($this->int2Bool($cr[1]) ? '<>' : '=').' \'\'';
case 3: // reward text [str]
return 'reward_loc'.User::$localeId.' LIKE \'%'.Util::sqlEscape($cr[2]).'%\'';
// case 4: // location [int]
// return ''; // no plausible locations parsed yet
case 5: // first in series [y|n]
return $this->int2Bool($cr[1]) ? '(series <> 0 AND (series & 0xFFFF0000) = 0)' : '(series & 0xFFFF0000) <> 0';
case 6: // last in series [y|n]
return $this->int2Bool($cr[1]) ? '(series <> 0 AND (series & 0xFFFF) = 0)' : '(series & 0xFFFF) <> 0';
case 7: // part of series [y|n]
return 'series '.($this->int2Bool($cr[1]) ? '<>' : '=').' 0';
case 9: // Id [op] [int]
return 'id '.$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 10: // Icon [str]
return 'iconString LIKE \'%'.Util::sqlEscape($cr[2]).'%\'';
// case 11: // Related Event [int]
// return ''; // >0:holidayId; -2323:any; -2324:none
case 18: // flags (staff only)
if (User::isInGroup(U_GROUP_STAFF))
return 'flags &'.(1 << max($cr[1] - 1, 0)) ;
default:
return '1';
}
}
protected function createSQLForValues($vl)
{
$parts = [];
// name ex: +description, +rewards
if (isset($vl['na']))
{
if (isset($vl['ex']) && $vl['ex'] == 'on')
$parts[] = '(name_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%" OR description_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%" OR reward_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%")';
else
$parts[] = 'name_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%"';
}
// points min
if (isset($vl['minpt']))
$parts[] = 'points >= '.intVal($vl['minpt']);
// points max
if (isset($vl['maxpt']))
$parts[] = 'points <= '.intVal($vl['maxpt']);
// faction (side)
if (isset($vl['si']))
{
if ($vl['si'] == 3) // both
$parts[] = 'faction = '.intVal($vl['si']);
else if ($vl['si'] > 0) // faction, inclusive both
$parts[] = '(faction = 3 OR faction = '.intVal($vl['si']).')';
else if ($vl['si'] < 0) // faction, exclusive both
$parts[] = 'faction = '.intVal(-$vl['si']);
}
return $parts;
}
}
class SpellListFilter extends Filter
{
// sources in filter and general use different indizes
private static $fiSource = array(
1 => -2, // Any
2 => -1, // None
3 => 1, // Crafted
4 => 2, // Drop
6 => 4, // Quest
7 => 5, // Vendor
8 => 6, // Trainer
9 => 7, // Discovery
10 => 9 // Talent
);
protected function createSQLForCriterium($cr)
{
if ($r = $this->createSQLForCommunity($cr))
return $r;
switch ($cr[0])
{
case 1: // costAbs [op] [int]
return 's.powerCost '.$this->int2Op($cr[1]).' IF(s.powerType IN (1, 6), 10 * '.intVal($cr[2]).', '.intVal($cr[2]).')';
case 2: // costPct [op] [int]
return 's.powerCostPercent '.$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 3: // requires FocusGO [y|n]
return $this->int2Bool($cr[1]) ? 's.spellFocusObject > 0' : 's.spellFocusObject = 0';
case 4: // trainingcost [op] [int]
return 's.trainingcost '.$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 5: // Profession Specialitation [y|n]
return 's.reqSpellId '.($this->int2Bool($cr[1]) ? ' > ' : ' = ').' 0';
case 9: // Source [int]
if ($foo = self::$fiSource[$cr[1]])
{
if ($foo > 0) // specific
return 's.source LIKE "%'.$foo.':%"';
else if ($foo == -2) // any
return 's.source <> ""';
else if ($foo == -1) // none
return 's.source = ""';
}
return '1';
case 10: // First Rank [y|n]
return $this->int2Bool($cr[1]) ? 's.cuFlags & '.SPELL_CU_FIRST_RANK : '(s.cuFlags & '.SPELL_CU_FIRST_RANK.') = 0' ;
case 12: // Last Rank [y|n]
return $this->int2Bool($cr[1]) ? 's.cuFlags & '.SPELL_CU_LAST_RANK : '(s.cuFlags & '.SPELL_CU_LAST_RANK.') = 0' ;
case 13: // Rank# [op] [int]
return 's.rankId '.$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 14: // spellId [op] [int]
return 's.id '.$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 15: // iconString [string]
return 's.iconString LIKE "%'.Util::sqlEscape($cr[2]).'%"';
case 19: // scales /W level [y|n] 0x80000 = SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION
return $this->int2Bool($cr[1]) ? 's.attributes0 & 0x80000' : '(s.attributes0 & 0x80000) = 0';
case 20: // has Reagents [y|n]
return $this->int2Bool($cr[1]) ? 's.reagent1 > 0 OR s.reagent2 > 0 OR s.reagent3 > 0 OR s.reagent4 > 0 OR s.reagent5 > 0 OR s.reagent6 > 0 OR s.reagent7 > 0 OR s.reagent8 > 0' : 's.reagents1 = 0 AND s.reagents2 = 0 AND s.reagents3 = 0 AND s.reagents4 = 0 AND s.reagents5 = 0 AND s.reagents6 = 0 AND s.reagents7 = 0 AND s.reagents8 = 0';
case 25: // rewards skill points [y|n]
return $this->int2Bool($cr[1]) ? 's.skillLevelYellow > 1' : 's.skillLevelYellow <= 1';
default:
return '1';
}
}
protected function createSQLForValues($vl)
{
$parts = [];
//string (extended)
if (isset($vl['na']))
{
if (isset($vl['ex']) && $vl['ex'] == 'on')
$parts[] = '(s.name_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%" OR buff_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%" OR description_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%")';
else
$parts[] = 's.name_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%"';
}
// spellLevel min
if (isset($vl['minle']))
$parts[] = 's.spellLevel >= '.intVal($vl['minle']);
// spellLevel max
if (isset($vl['maxle']))
$parts[] = 's.spellLevel <= '.intVal($vl['maxle']);
// skillLevel min
if (isset($vl['minrs']))
$parts[] = 's.learnedAt >= '.intVal($vl['minrs']);
// skillLevel max
if (isset($vl['maxrs']))
$parts[] = 's.learnedAt <= '.intVal($vl['maxrs']);
// race
if (isset($vl['ra']))
$parts[] = 's.reqRaceMask & '.$this->list2Mask($vl['ra']);
// class [list]
if (isset($vl['cl']))
$parts[] = 's.reqClassMask & '.$this->list2Mask($vl['cl']);
// school [list]
if (isset($vl['sc']))
$parts[] = 's.schoolMask & '.$this->list2Mask($vl['sc'], true);
// glyph type [list] wonky, admittedly, but consult SPELL_CU_* in defines and it makes sense
if (isset($vl['gl']))
$parts[] = 's.cuFlags & '.($this->list2Mask($vl['gl']) << 6);
// dispel type
if (isset($vl['dt']))
$parts[] = 's.dispelType = '.intVal($vl['dt']);
// mechanic
if (isset($vl['me']))
$parts[] = 's.mechanic = '.intVal($vl['me']).' OR s.effect1Mechanic = '.intVal($vl['me']).' OR s.effect2Mechanic = '.intVal($vl['me']).' OR s.effect3Mechanic = '.intVal($vl['me']);
return $parts;
}
}
// missing filter: "Available to Players"
class ItemsetListFilter extends Filter
{
protected function createSQLForCriterium($cr)
{
if ($r = $this->createSQLForCommunity($cr))
return $r;
switch ($cr[0])
{
case 2: // Id
return 'id '.$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 3: // pieces [int]
return '(IF(item1 > 0, 1, 0) + IF(item2 > 0, 1, 0) + IF(item3 > 0, 1, 0) + IF(item4 > 0, 1, 0) + IF(item5 > 0, 1, 0) +
IF(item6 > 0, 1, 0) + IF(item7 > 0, 1, 0) + IF(item8 > 0, 1, 0) + IF(item9 > 0, 1, 0) + IF(item10 > 0, 1, 0)) ' .$this->int2Op($cr[1]).' '.intVal($cr[2]);
case 4: // bonustext [str]
return 'bonusText_loc'.User::$localeId.' LIKE \'%'.Util::sqlEscape($cr[2]).'%\'';
case 5: // heroic [y|n]
return 'heroic = '.($cr[1] == 1 ? '1' : '0');
case 6: // related event [int]
$hId = intVal($cr[1]); // >0:holidayId; -2323:any; -2324:none
if ($hId == -2323)
return 'holidayId <> 0';
if ($hId == -2324)
$hId = 0;
return 'holidayId = '.$hId;
// case 12: // available to players [y|n]
// return ''; // ugh .. scan loot, quest and vendor templates and write to ?_itemset
default:
return '1';
}
}
protected function createSQLForValues($vl)
{
$parts = [];
//string (extended)
if (isset($vl['na']))
$parts[] = 'name_loc'.User::$localeId.' LIKE "%'.Util::sqlEscape($vl['na']).'%"';
// quality [list]
if (isset($vl['qu']))
$parts[] = 'quality IN ('.implode(', ', (array)$vl['qu']).')';
// type
if (isset($vl['ty']))
$parts[] = 'type IN ('.implode(', ', (array)$vl['ty']).')';
// itemLevel min
if (isset($vl['minle']))
$parts[] = 'minLevel >= '.intVal($vl['minle']);
// itemLevel max
if (isset($vl['maxle']))
$parts[] = 'maxLevel <= '.intVal($vl['maxle']);
// reqLevel min
if (isset($vl['minrl']))
$parts[] = 'reqLevel <= '.intVal($vl['minrl']);
// reqLevel max
if (isset($vl['maxrl']))
$parts[] = 'reqLevel <= '.intVal($vl['maxrl']);
// class
if (isset($vl['cl']))
$parts[] = 'classMask & '.$this->list2Mask($vl['cl']);
// tag
if (isset($vl['ta']))
$parts[] = 'contentGroup = '.$vl['ta'];
return $parts;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,8 @@ class ItemsetList extends BaseType
public $pieceToSet = []; // used to build g_items and search
private $classes = []; // used to build g_classes
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_itemset WHERE [filter] [cond] ORDER BY maxlevel DESC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_itemset `set`';
protected $queryOpts = ['set' => ['o' => 'maxlevel DESC']];
public function __construct($conditions = [], $applyFilter = false)
{
@@ -82,4 +83,121 @@ class ItemsetList extends BaseType
public function renderTooltip() { }
}
// missing filter: "Available to Players"
class ItemsetListFilter extends Filter
{
// cr => [type, field, misc, extraCol]
protected $genericFilter = array( // misc (bool): _NUMERIC => useFloat; _STRING => localized; _FLAG => match Value; _BOOLEAN => stringSet
2 => [FILTER_CR_NUMERIC, 'id', null, true], // id
3 => [FILTER_CR_NUMERIC, 'npieces', ], // pieces
4 => [FILTER_CR_STRING, 'bonusText', true ], // bonustext
5 => [FILTER_CR_BOOLEAN, 'heroic', ], // heroic
6 => [FILTER_CR_ENUM, 'holidayId', ], // relatedevent
);
protected function createSQLForCriterium(&$cr)
{
if (in_array($cr[0], array_keys($this->genericFilter)))
{
if ($genCR = $this->genericCriterion($cr))
return $genCR;
unset($cr);
$this->error = true;
return [1];
}
switch ($cr[0])
{
case 12: // available to players [yn] ugh .. scan loot, quest and vendor templates and write to ?_itemset
/* todo */ return [1];
case 8: // hascomments [yn]
/* todo */ return [1];
case 9: // hasscreenshots [yn]
/* todo */ return [1];
case 10: // hasvideos [yn]
/* todo */ return [1];
}
unset($cr);
$this->error = 1;
return [1];
}
protected function createSQLForValues()
{
$parts = [];
$_v = &$this->fiData['v'];
// name [str]
if (isset($_v['na']))
$parts[] = ['name_loc'.User::$localeId, $_v['na']];
// quality [enum]
if (isset($_v['qu']))
$parts[] = ['quality', (array)$_v['qu']];
// type [enum]
if (isset($_v['ty']))
$parts[] = ['type', (array)$_v['ty']];
// itemLevel min [int]
if (isset($_v['minle']))
{
if (is_int($_v['minle']) && $_v['minle'] > 0)
$parts[] = ['minLevel', $_v['minle'], '>='];
else
unset($_v['minle']);
}
// itemLevel max [int]
if (isset($_v['maxle']))
{
if (is_int($_v['maxle']) && $_v['maxle'] > 0)
$parts[] = ['maxLevel', $_v['maxle'], '<='];
else
unset($_v['maxle']);
}
// reqLevel min [int]
if (isset($_v['minrl']))
{
if (is_int($_v['minrl']) && $_v['minrl'] > 0)
$parts[] = ['reqLevel', $_v['minrl'], '>='];
else
unset($_v['minrl']);
}
// reqLevel max [int]
if (isset($_v['maxrl']))
{
if (is_int($_v['maxrl']) && $_v['maxrl'] > 0)
$parts[] = ['reqLevel', $_v['maxrl'], '<='];
else
unset($_v['maxrl']);
}
// class [enum]
if (isset($_v['cl']))
{
if (in_array($_v['cl'], [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]))
$parts[] = ['classMask', $this->list2Mask($_v['cl']), '&'];
else
unset($_v['cl']);
}
// tag [enum]
if (isset($_v['ta']))
{
if ($_v['ta'] > 0 && $_v['ta'] < 31)
$parts[] = ['contentGroup', intVal($_v['ta'])];
else
unset($_v['ta']);
}
return $parts;
}
}
?>

View File

@@ -9,7 +9,7 @@ class PetList extends BaseType
public static $type = TYPE_PET;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_pet WHERE [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_pet p';
public function getListviewData()
{

View File

@@ -7,7 +7,11 @@ class QuestList extends BaseType
{
public static $type = TYPE_QUEST;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM quest_template qt LEFT JOIN locales_quest lq ON qt.Id = lq.entry WHERE [filter] [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM quest_template qt';
protected $queryOpts = array(
'qt' => [['lq']],
'lq' => ['j' => ['locales_quest lq ON qt.id = lq.entry', true]]
);
public function __construct($conditions = [])
{

View File

@@ -8,7 +8,7 @@ class SkillList extends BaseType
{
public static $type = TYPE_SKILL;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_skillLine sl WHERE [cond] ORDER BY id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_skillLine sl';
public function __construct($conditions = [])
{

View File

@@ -34,7 +34,7 @@ class SpellList extends BaseType
private $interactive = false;
private $charLevel = MAX_LEVEL;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_spell s WHERE [filter] [cond]';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_spell s';
public function __construct($conditions = [], $applyFilter = false)
{
@@ -107,7 +107,7 @@ class SpellList extends BaseType
}
if ($foo)
$this->relItems = new ItemList(array(['i.entry', array_unique($foo)], 0));
$this->relItems = new ItemList(array(['i.id', array_unique($foo)], 0));
}
// use if you JUST need the name
@@ -1345,7 +1345,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.]
if ($cId = $this->curTpl['effect'.$i.'CreateItemId'])
{
$createItem = (new ItemList(array(['i.entry', (int)$cId])))->renderTooltip([], true, true);
$createItem = (new ItemList(array(['i.id', (int)$cId])))->renderTooltip([], true, true);
break;
}
}
@@ -1622,15 +1622,18 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.]
if ($invType = $this->getField('equippedItemInventoryTypeMask'))
{
// remove some duplicated strings if both are used
if (($invType & 0x100020) == 0x100020) // Chest and Robe set
$invType &= ~0x20;
// remap some duplicated strings 'Off Hand' and 'Shield' are never used simultaneously
if ($invType & (1 << INVTYPE_ROBE)) // Robe => Chest
{
$invType &= ~(1 << INVTYPE_ROBE);
$invType &= (1 << INVTYPE_CHEST);
}
if (($invType & 0x404000) == 0x404000) // Off-hand and Shield set
$invType &= ~0x4000;
if (($invType & 0x4008000) == 0x4008000) // Ranged and Ranged (right) set
$invType &= ~0x8000;
if ($invType & (1 << INVTYPE_RANGEDRIGHT)) // Ranged2 => Ranged
{
$invType &= ~(1 << INVTYPE_RANGEDRIGHT);
$invType &= (1 << INVTYPE_RANGED);
}
$_ = [];
$strs = Lang::$item['inventoryType'];
@@ -1681,4 +1684,200 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.]
}
}
class SpellListFilter extends Filter
{
// sources in filter and general use different indizes
private $enums = array(
9 => array(
1 => true, // Any
2 => false, // None
3 => 1, // Crafted
4 => 2, // Drop
6 => 4, // Quest
7 => 5, // Vendor
8 => 6, // Trainer
9 => 7, // Discovery
10 => 9 // Talent
)
);
// cr => [type, field, misc, extraCol]
protected $genericFilter = array( // misc (bool): _NUMERIC => useFloat; _STRING => localized; _FLAG => match Value; _BOOLEAN => stringSet
2 => [FILTER_CR_NUMERIC, 'powerCostPercent', ], // prcntbasemanarequired
3 => [FILTER_CR_BOOLEAN, 'spellFocusObject' ], // requiresnearbyobject
4 => [FILTER_CR_NUMERIC, 'trainingcost' ], // trainingcost
5 => [FILTER_CR_BOOLEAN, 'reqSpellId' ], // requiresprofspec
10 => [FILTER_CR_FLAG, 'cuFlags', SPELL_CU_FIRST_RANK ], // firstrank
12 => [FILTER_CR_FLAG, 'cuFlags', SPELL_CU_LAST_RANK ], // lastrank
13 => [FILTER_CR_NUMERIC, 'rankId', ], // rankno
14 => [FILTER_CR_NUMERIC, 'id', null, true], // id
15 => [FILTER_CR_STRING, 'iconString', ], // icon
19 => [FILTER_CR_FLAG, 'attributes0', 0x80000 ], // scaling
25 => [FILTER_CR_BOOLEAN, 'skillLevelYellow' ] // rewardsskillups
);
protected function createSQLForCriterium(&$cr)
{
if (in_array($cr[0], array_keys($this->genericFilter)))
{
if ($genCR = $this->genericCriterion($cr))
return $genCR;
unset($cr);
$this->error = true;
return [1];
}
switch ($cr[0])
{
case 1: // costAbs [op] [int]
if (!$this->isSaneNumeric($cr[2]))
break;
if (!$this->int2Op($cr[1]))
break;
return ['OR', ['AND', ['powerType', [1, 6]], ['powerCost', (10 * $cr[2]), $cr[1]]], ['AND', ['powerType', [1, 6], '!'], ['powerCost', $cr[2], $cr[1]]]];
case 9: // Source [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
if ($_ !== null)
{
if (is_bool($_))
return ['source', 0, ($_ ? '!' : null)];
else if (is_int($_))
return ['source', $_.':'];
}
break;
case 20: // has Reagents [yn]
if ($this->int2Bool($cr[1]))
{
if ($cr[1])
return ['OR', ['reagent1', 0, '>'], ['reagent2', 0, '>'], ['reagent3', 0, '>'], ['reagent4', 0, '>'], ['reagent5', 0, '>'], ['reagent6', 0, '>'], ['reagent7', 0, '>'], ['reagent8', 0, '>']];
else
return ['AND', ['reagent1', 0], ['reagent2', 0], ['reagent3', 0], ['reagent4', 0], ['reagent5', 0], ['reagent6', 0], ['reagent7', 0], ['reagent8', 0]];
}
case 11: // hascomments [yn]
/* todo */ return [1];
case 8: // hasscreenshots [yn]
/* todo */ return [1];
case 17: // hasvideos [yn]
/* todo */ return [1];
}
unset($cr);
$this->error = 1;
return [1];
}
protected function createSQLForValues()
{
$parts = [];
$_v = &$this->fiData['v'];
//string (extended)
if (isset($_v['na']))
{
if (isset($_v['ex']) && $_v['ex'] == 'on')
$parts[] = ['OR', ['name_loc'.User::$localeId, $_v['na']], ['buff_loc'.User::$localeId, $_v['na']], ['description_loc'.User::$localeId, $_v['na']]];
else
$parts[] = ['name_loc'.User::$localeId, $_v['na']];
}
// spellLevel min
if (isset($_v['minle']))
{
if (is_int($_v['minle']) && $_v['minle'] > 0)
$parts[] = ['spellLevel', $_v['minle'], '>='];
else
unset($_v['minle']);
}
// spellLevel max
if (isset($_v['maxle']))
{
if (is_int($_v['maxle']) && $_v['maxle'] > 0)
$parts[] = ['spellLevel', $_v['maxle'], '<='];
else
unset($_v['maxle']);
}
// skillLevel min
if (isset($_v['minrs']))
{
if (is_int($_v['minrs']) && $_v['minrs'] > 0)
$parts[] = ['learnedAt', $_v['minrs'], '>='];
else
unset($_v['minrs']);
}
// skillLevel max
if (isset($_v['maxrs']))
{
if (is_int($_v['maxrs']) && $_v['maxrs'] > 0)
$parts[] = ['learnedAt', $_v['maxrs'], '<='];
else
unset($_v['maxrs']);
}
// race
if (isset($_v['ra']))
{
if (in_array($_v['ra'], [1, 2, 3, 4, 5, 6, 7, 8, 10, 11]))
$parts[] = ['AND', [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], ['reqRaceMask', $this->list2Mask($_v['ra']), '&']];
else
unset($_v['ra']);
}
// class [list]
if (isset($_v['cl']))
{
$_ = (array)$_v['cl'];
if (!array_diff($_, [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]))
$parts[] = ['reqClassMask', $this->list2Mask($_), '&'];
else
unset($_v['cl']);
}
// school [list]
if (isset($_v['sc']))
{
$_ = (array)$_v['sc'];
if (!array_diff($_, [0, 1, 2, 3, 4, 5, 6]))
$parts[] = ['schoolMask', $this->list2Mask($_, true), '&'];
else
unset($_v['sc']);
}
// glyph type [list] wonky, admittedly, but consult SPELL_CU_* in defines and it makes sense
if (isset($_v['gl']))
{
if (in_array($_v['gl'], [1, 2]))
$parts[] = ['cuFlags', ($this->list2Mask($_v['gl']) << 6), '&'];
else
unset($_v['gl']);
}
// dispel type
if (isset($_v['dt']))
{
if (in_array($_v['dt'], [1, 2, 3, 4, 5, 6, 9]))
$parts[] = ['dispelType', $_v['dt']];
else
unset($_v['dt']);
}
// mechanic
if (isset($_v['me']))
{
if ($_v['me'] > 0 && $_v['me'] < 32)
$parts[] = ['OR', ['mechanic', $_v['me']], ['effect1Mechanic', $_v['me']], ['effect2Mechanic', $_v['me']], ['effect3Mechanic', $_v['me']]];
else
unset($_v['me']);
}
return $parts;
}
}
?>

View File

@@ -11,7 +11,7 @@ class TitleList extends BaseType
public $sources = [];
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_titles WHERE [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_titles t';
public function __construct($conditions = [])
{

View File

@@ -50,7 +50,7 @@ class User
{
self::$id = $userId;
$ipBan = DB::Aowow()->SelectRow('SELECT count, unbanDate AS unbanDateIP FROM ?_account_bannedIPs WHERE ip = ?s AND type = 0',
$ipBan = DB::Aowow()->SelectRow('SELECT count, unbanDate AS unbanDateIP FROM ?_account_bannedIPs WHERE ip = ? AND type = 0',
$_SERVER['REMOTE_ADDR']
);
// explicit " > "; incremented first, checked after
@@ -247,7 +247,7 @@ class User
{
self::$passHash = self::hashCrypt($pass);
DB::Aowow()->query('UPDATE ?_account SET passHash = ?s WHERE id = ?d',
DB::Aowow()->query('UPDATE ?_account SET passHash = ? WHERE id = ?d',
self::$passHash,
self::$id
);

View File

@@ -7,7 +7,8 @@ class WorldEventList extends BaseType
{
public static $type = TYPE_WORLDEVENT;
protected $setupQuery = 'SELECT *, -e.id AS ARRAY_KEY, -e.id as id FROM ?_events e LEFT JOIN ?_holidays h ON e.holidayId = h.id WHERE [cond] ORDER BY -e.id ASC';
protected $queryBase = 'SELECT *, -e.id AS ARRAY_KEY, -e.id as id FROM ?_events e LEFT JOIN ?_holidays h ON e.holidayId = h.id';
protected $queryOpts = ['e' => ['o' => '-e.id ASC']];
public function __construct($conditions = [])
{

View File

@@ -13,7 +13,7 @@ class ZoneList extends BaseType
{
public static $type = TYPE_ZONE;
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_zones z WHERE [cond] ORDER BY Id ASC';
protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_zones z';
public function getListviewData()
{

View File

@@ -87,16 +87,24 @@ define('LOCALE_DE', 3);
define('LOCALE_ES', 6);
define('LOCALE_RU', 8);
define('FILTER_CR_BOOLEAN', 1);
define('FILTER_CR_FLAG', 2);
define('FILTER_CR_NUMERIC', 3);
define('FILTER_CR_STRING', 4);
define('FILTER_CR_ENUM', 5);
define('FILTER_CR_STAFFFLAG', 6);
// conditional information in template
define('GLOBALINFO_SELF', 0x1); // id, name, icon
define('GLOBALINFO_RELATED', 0x2); // spells used by pet, classes/races required by spell, ect
define('GLOBALINFO_REWARDS', 0x4); // items rewarded by achievement/quest, ect
define('GLOBALINFO_ANY', 0xF);
define('ITEMINFO_JSON', 0x1);
define('ITEMINFO_SUBITEMS', 0x2);
define('ITEMINFO_VENDOR', 0x4);
define('ITEMINFO_LOOT', 0x8);
define('ITEMINFO_JSON', 0x01);
define('ITEMINFO_SUBITEMS', 0x02);
define('ITEMINFO_VENDOR', 0x04);
define('ITEMINFO_LOOT', 0x08);
define('ITEMINFO_GEM', 0x10);
define('NPCINFO_TAMEABLE', 0x1);
define('NPCINFO_MODEL', 0x2);
@@ -324,7 +332,7 @@ define('OBJECT_DESTRUCTIBLE_BUILDING', 33);
define('OBJECT_GUILD_BANK', 34);
define('OBJECT_TRAPDOOR', 35);
// InventoryType
// InventoryType [slot]
define('INVTYPE_NON_EQUIP', 0);
define('INVTYPE_HEAD', 1);
define('INVTYPE_NECK', 2);
@@ -373,13 +381,27 @@ define('ITEM_QUALITY_ARTIFACT', 6); // LIGHT YELLOW
define('ITEM_QUALITY_HEIRLOOM', 7); // GOLD
// ItemClass
define('ITEM_CLASS_CONSUMABLE', 0);
define('ITEM_CLASS_CONTAINER', 1);
define('ITEM_CLASS_WEAPON', 2);
define('ITEM_CLASS_GEM', 3);
define('ITEM_CLASS_ARMOR', 4);
define('ITEM_CLASS_REAGENT', 5);
define('ITEM_CLASS_AMMUNITION', 6);
define('ITEM_CLASS_TRADEGOOD', 7);
// define('ITEM_CLASS_GENERIC', 8);
define('ITEM_CLASS_RECIPE', 9);
// define('ITEM_CLASS_MONEY', 10);
define('ITEM_CLASS_QUIVER', 11);
define('ITEM_CLASS_QUEST', 12);
define('ITEM_CLASS_KEY', 13);
// define('ITEM_CLASS_PERMANENT', 14);
define('ITEM_CLASS_MISC', 15);
define('ITEM_CLASS_GLYPH', 16);
// ItemFlags
define('ITEM_FLAG_CONJURED', 0x0000002);
define('ITEM_FLAG_OPENABLE', 0x0000004);
define('ITEM_FLAG_HEROIC', 0x0000008);
define('ITEM_FLAG_DEPRECATED', 0x0000010);
define('ITEM_FLAG_PARTYLOOT', 0x0000800);

View File

@@ -15,15 +15,21 @@ error_reporting($e);
define('STATIC_URL', substr('http://'.$_SERVER['SERVER_NAME'].strtr($_SERVER['SCRIPT_NAME'], ['index.php' => '']), 0, -1));
require 'includes/Smarty-2.6.26/libs/Smarty.class.php'; // Libraray: http://www.smarty.net/
require 'includes/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple
// require 'includes/Smarty-3.1.14/libs/Smarty.class.php'; // Libraray: http://www.smarty.net/
require 'includes/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple (mysqli: https://bitbucket.org/brainreaver/dbsimple/src)
require 'includes/utilities.php';
require 'includes/class.user.php';
require 'includes/class.database.php';
// autoload any List-Classes
// autoload List-Classes and Associated Filters
spl_autoload_register(function ($class) {
if (strpos($class, 'List') && !strpos($class, 'Filter'))
if (strpos($class, 'List') && !class_exists($class))
{
if (!class_exists('BaseType'))
require 'includes/class.basetype.php';
require 'includes/class.'.strtr($class, ['List' => '']).'.php';
}
});
// debug: measure execution times
@@ -82,5 +88,6 @@ User::assignUserToTemplate($smarty, true);
@list($str, $trash) = explode('&', $_SERVER['QUERY_STRING'], 2);
@list($pageCall, $pageParam) = explode('=', $str, 2);
$smarty->assign('query', [$pageCall, $pageParam]);
$smarty->assign('wowhead', 'http://'.Util::$subDomains[User::$localeId].'.wowhead.com/'.$str);
?>

View File

@@ -3,410 +3,6 @@
if (!defined('AOWOW_REVISION'))
die('invalid access');
abstract class BaseType
{
public $id = 0;
public $error = true;
protected $templates = [];
protected $curTpl = []; // lets iterate!
protected $filter = null;
protected $matches = null; // total matches unaffected by sqlLimit in config
protected $setupQuery = '';
/*
* condition as array [expression, value, operator]
* expression: str - must match fieldname;
* int - impl. 1: select everything
* array - another condition array
* value: str - operator defaults to: LIKE %<val>%
* int - operator defaults to: = <val>
* array - operator defaults to: IN (<val>)
* operator: modifies/overrides default
* ! - negated default value (NOT LIKE; <>; NOT IN)
* condition as str
* defines linking (AND || OR)
* condition as int
* defines LIMIT
*
* example:
* array(
* ['id', 45],
* ['name', 'test', '!'],
* [
* 'AND',
* ['flags', 0xFF, '&'],
* ['flags2', 0xF, '&'],
* ]
* [['mask', 0x3, '&'], 0]
* 'OR',
* 5
* )
* results in
* WHERE ((`id` = 45) OR (`name` NOT LIKE "%test%") OR ((`flags` & 255) AND (`flags2` & 15)) OR ((`mask` & 3) = 0)) LIMIT 5
*/
public function __construct($conditions = [], $applyFilter = false)
{
global $AoWoWconf; // yes i hate myself..
$sql = [];
$linking = ' AND ';
$limit = ' LIMIT '.$AoWoWconf['sqlLimit'];
$className = get_class($this);
if (!$this->setupQuery || $conditions === null)
return;
// may be called without filtering
if ($applyFilter && class_exists($className.'Filter'))
{
$fiName = $className.'Filter';
$this->filter = new $fiName();
if ($this->filter->init() === false)
return;
}
$resolveCondition = function ($c, $supLink) use (&$resolveCondition)
{
$subLink = '';
foreach ($c as $foo)
{
if ($foo === 'AND')
$subLink = ' AND ';
else if ($foo === 'OR') // nessi-bug: if (0 == 'OR') was true once... w/e
$subLink = ' OR ';
}
// need to manually set link for subgroups to be recognized as condition set
if ($subLink)
{
$sql = [];
foreach ($c as $foo)
if (is_array($foo))
if ($x = $resolveCondition($foo, $supLink))
$sql[] = $x;
return '('.implode($subLink, $sql).')';
}
else
{
if ($c[0] == '1')
return '1';
else if (is_array($c[0]))
$field = $resolveCondition($c[0], $supLink);
else if ($c[0])
$field = '`'.implode('`.`', explode('.', Util::sqlEscape($c[0]))).'`';
else
return null;
if (is_array($c[1]))
{
$val = implode(',', Util::sqlEscape($c[1]));
if ($val === '')
return null;
$op = (isset($c[2]) && $c[2] == '!') ? 'NOT IN' : 'IN';
$val = '('.$val.')';
}
else if (is_string($c[1]))
{
$val = Util::sqlEscape($c[1]);
if ($val === '')
return null;
$op = (isset($c[2]) && $c[2] == '!') ? 'NOT LIKE' : 'LIKE';
$val = '"%'.$val.'%"';
}
else if (is_numeric($c[1]))
{
$op = (isset($c[2]) && $c[2] == '!') ? '<>' : '=';
$val = Util::sqlEscape($c[1]);
}
else // null for example
return null;
if (isset($c[2]) && $c[2] != '!')
$op = $c[2];
return '('.$field.' '.$op.' '.$val.')';
}
};
foreach ($conditions as $i => $c)
{
switch(getType($c))
{
case 'array':
break;
case 'string':
case 'integer':
case 'double':
if (is_string($c))
$linking = $c == 'AND' ? ' AND ' : ' OR ';
else
$limit = $c > 0 ? ' LIMIT '.$c : '';
default:
unset($conditions[$i]);
}
}
foreach ($conditions as $c)
if ($c)
if ($x = $resolveCondition($c, $linking))
$sql[] = $x;
// todo: add strings propperly without them being escaped by simpleDB..?
$this->setupQuery = str_replace('[filter]', $this->filter && $this->filter->buildQuery() ? $this->filter->getQuery().' AND ' : NULL, $this->setupQuery);
$this->setupQuery = str_replace('[cond]', empty($sql) ? '1' : '('.implode($linking, $sql).')', $this->setupQuery);
$this->setupQuery .= $limit;
$rows = DB::Aowow()->SelectPage($this->matches, $this->setupQuery);
if (!$rows)
return;
foreach ($rows as $k => $tpl)
$this->templates[$k] = $tpl;
$this->reset(); // push first element for instant use
$this->error = false;
}
public function &iterate()
{
// reset on __construct
$this->reset();
while (list($id, $tpl) = each($this->templates))
{
$this->id = $id;
$this->curTpl = &$this->templates[$id]; // do not use $tpl as we want to be referenceable
yield $id => $this->curTpl;
unset($this->curTpl); // kill reference or it will 'bleed' into the next iteration
}
// reset on __destruct .. Generator, Y U NO HAVE __destruct ?!
$this->reset();
}
protected function reset()
{
unset($this->curTpl); // kill reference or strange stuff will happen
$this->curTpl = reset($this->templates);
$this->id = key($this->templates);
}
// read-access to templates
public function getField($field, $localized = false)
{
if (!$this->curTpl || (!$localized && !isset($this->curTpl[$field])))
return '';
if ($localized)
return Util::localizedString($this->curTpl, $field);
$value = $this->curTpl[$field];
return is_numeric($value) ? floatVal($value) : $value;
}
public function getRandomId()
{
$pattern = '/SELECT .* (-?[\w_]*\.?(id|entry)) AS ARRAY_KEY,?.* FROM (.*) WHERE .*/i';
$replace = 'SELECT $1 FROM $3 ORDER BY RAND() ASC LIMIT 1';
$query = preg_replace($pattern, $replace, $this->setupQuery);
return DB::Aowow()->selectCell($query);
}
public function getFoundIDs()
{
return array_keys($this->templates);
}
public function getMatches()
{
return $this->matches;
}
public function filterGetSetCriteria()
{
if ($this->filter)
return $this->filter->getSetCriteria();
else
return null;
}
public function filterGetForm()
{
if ($this->filter)
return $this->filter->getForm();
else
return [];
}
public function filterGetError()
{
if ($this->filter)
return $this->filter->error;
else
return false;
}
// should return data required to display a listview of any kind
// this is a rudimentary example, that will not suffice for most Types
abstract public function getListviewData();
// should return data to extend global js variables for a certain type (e.g. g_items)
abstract public function addGlobalsToJScript(&$smarty, $addMask = GLOBALINFO_ANY);
// NPC, GO, Item, Quest, Spell, Achievement, Profile would require this
abstract public function renderTooltip();
}
trait listviewHelper
{
public function hasSetFields($fields)
{
if (!is_array($fields))
return 0x0;
$result = 0x0;
foreach ($this->iterate() as $__)
{
foreach ($fields as $k => $str)
{
if ($this->getField($str))
{
$result |= 1 << $k;
unset($fields[$k]);
}
}
if (empty($fields)) // all set .. return early
{
$this->reset(); // Generators have no __destruct, reset manually, when not doing a full iteration
return $result;
}
}
return $result;
}
public function hasDiffFields($fields)
{
if (!is_array($fields))
return 0x0;
$base = [];
$result = 0x0;
foreach ($fields as $k => $str)
$base[$str] = $this->getField($str);
foreach ($this->iterate() as $__)
{
foreach ($fields as $k => $str)
{
if ($base[$str] != $this->getField($str))
{
$result |= 1 << $k;
unset($fields[$k]);
}
}
if (empty($fields)) // all fields diff .. return early
{
$this->reset(); // Generators have no __destruct, reset manually, when not doing a full iteration
return $result;
}
}
return $result;
}
public function hasAnySource()
{
if (!isset($this->sources))
return false;
foreach ($this->sources as $src)
{
if (!is_array($src))
continue;
if (!empty($src))
return true;
}
return false;
}
}
trait spawnHelper
{
private static $spawnQuery = " SELECT a.guid AS ARRAY_KEY, map, position_x, position_y, spawnMask, phaseMask, spawntimesecs, eventEntry, pool_entry AS pool FROM ?# a LEFT JOIN ?# b ON a.guid = b.guid LEFT JOIN ?# c ON a.guid = c.guid WHERE id = ?d";
private function fetch()
{
if (!$this->id)
return false;
switch (get_class($this))
{
case 'CreatureList':
return DB::Aowow()->select(self::$spawnQuery, 'creature', 'game_event_creature', 'pool_creature', $this->id);
case 'GameObjectList':
return DB::Aowow()->select(self::$spawnQuery, 'gameobject', 'game_event_gameobject', 'pool_gameobject', $this->id);
default:
return false;
}
}
/*
todo (med): implement this alpha-map-check-virtual-map-transform-wahey!
note: map in tooltips is activated by either '#map' as anchor (will automatic open mapviewer, when clicking link) in the href or as parameterless rel-parameter e.g. rel="map" in the anchor
*/
public function getSpawns($spawnInfo)
{
// SPAWNINFO_SHORT: true => only the most populated area and only coordinates
$data = [];
// $raw = $this->fetch();
// if (!$raw)
// return [];
/*
SPAWNINFO_FULL:
$data = array(
areaId => array(
floorNo => array (
posX =>
posY =>
respawn =>
phaseMask =>
spawnMask =>
eventId =>
poolId =>
)
)
)
SPAWNINFO_SHORT: [zoneId, [[x1, y1], [x2, y2], ..]] // only the most populated zone
SPAWNINFO_ZONES: [zoneId1, zoneId2, ..] // only zones
*/
return $data;
}
}
class Lang
{
public static $main;
@@ -436,11 +32,20 @@ class Lang
public static function load($loc)
{
if ((require 'localization/locale_'.$loc.'.php') !== 1)
die('File for localization '.$loc.' not found.');
if (!file_exists('localization/locale_'.$loc.'.php'))
die('File for localization '.strToUpper($loc).' not found.');
else
require 'localization/locale_'.$loc.'.php';
foreach ($lang as $k => $v)
self::$$k = $v;
// *cough* .. temp-hack
if (User::$localeId == LOCALE_EN)
{
self::$item['cat'][2] = [self::$item['cat'][2], self::$spell['weaponSubClass']];
self::$item['cat'][2][1][14] .= ' ('.self::$item['cat'][2][0].')';
}
}
// todo: expand
@@ -460,12 +65,14 @@ class Lang
public static function getLocks($lockId, $interactive = false)
{
$locks = [];
$lock = DB::Aowow()->selectRow('SELECT * FROM ?_lock WHERE id = ?d', $this->curTpl['lockid']);
$lock = DB::Aowow()->selectRow('SELECT * FROM ?_lock WHERE id = ?d', $lockId);
if (!$lock)
return '';
for ($i = 1; $i <= 5; $i++)
{
$prop = $lock['lockproperties'.$i];
$rnk = $lock['requiredskill'.$i];
$prop = $lock['properties'.$i];
$rnk = $lock['reqSkill'.$i];
$name = '';
if ($lock['type'.$i] == 1) // opened by item
@@ -479,17 +86,19 @@ class Lang
}
else if ($lock['type'.$i] == 2) // opened by skill
{
if (in_array($prop, [6, 7, 15, 19])) // dnd stuff
if (!in_array($prop, [1, 2, 3, 4, 9, 16, 20])) // exclude unusual stuff
continue;
$txt = DB::Aowow()->selectRow('SELECT * FROM ?_locktype WHERE id = ?d', $prop); // todo (low): convert to static text
$name = Util::localizedString($txts, 'name');
$name = Util::localizedString($txt, 'name');
if (!$name)
continue;
if ($rnk > 0)
$name .= ' ('.$rnk.')';
}
else
continue;
$locks[$lock['type'.$i] == 1 ? $i : -$i] = sprintf(Lang::$game['requires'], $name);
}
@@ -648,9 +257,10 @@ class SmartyAoWoW extends Smarty
public function __construct($config)
{
parent::__construct();
$cwd = str_replace("\\", "/", getcwd());
$this->Smarty();
$this->assign('appName', $config['page']['name']);
$this->assign('AOWOW_REVISION', AOWOW_REVISION);
$this->config = $config;
@@ -723,7 +333,7 @@ class SmartyAoWoW extends Smarty
// fetch announcements
if ($tv['query'][0] && !preg_match('/[^a-z]/i', $tv['query'][0]))
{
$ann = DB::Aowow()->Select('SELECT * FROM ?_announcements WHERE status = 1 AND (page = ?s OR page = "*")', $tv['query'][0]);
$ann = DB::Aowow()->Select('SELECT * FROM ?_announcements WHERE status = 1 AND (page = ? OR page = "*")', $tv['query'][0]);
foreach ($ann as $k => $v)
{
if ($t = Util::localizedString($v, 'text'))
@@ -815,7 +425,7 @@ class SmartyAoWoW extends Smarty
{
case TYPE_NPC: (new CreatureList(array(['ct.id', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
case TYPE_OBJECT: (new GameobjectList(array(['gt.entry', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
case TYPE_ITEM: (new ItemList(array(['i.entry', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
case TYPE_ITEM: (new ItemList(array(['i.id', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
case TYPE_QUEST: (new QuestList(array(['qt.entry', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
case TYPE_SPELL: (new SpellList(array(['s.id', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
case TYPE_ZONE: (new ZoneList(array(['z.id', $ids], 0)))->addGlobalsToJscript($this, GLOBALINFO_SELF); break;
@@ -856,6 +466,14 @@ class SmartyAoWoW extends Smarty
exit();
}
public function brb()
{
$this->assign('lang', array_merge(Lang::$main, Lang::$error));
$this->display('brb.tpl');
exit();
}
// creates the cache file
public function saveCache($key, $data, $filter = null)
{
@@ -901,10 +519,10 @@ class SmartyAoWoW extends Smarty
class Util
{
public static $resistanceFields = array(
null, 'holy_res', 'fire_res', 'nature_res', 'frost_res', 'shadow_res', 'arcane_res'
null, 'resHoly', 'resFire', 'resNature', 'resFrost', 'resShadow', 'resArcane'
);
private static $rarityColorStings = array( // zero-indexed
public static $rarityColorStings = array( // zero-indexed
'9d9d9d', 'ffffff', '1eff00', '0070dd', 'a335ee', 'ff8000', 'e5cc80', 'e6cc80'
);
@@ -912,6 +530,10 @@ class Util
'enus', null, 'frfr', 'dede', null, null, 'eses', null, 'ruru'
);
public static $subDomains = array(
'www', null, 'fr', 'de', null, null, 'es', null, 'ru'
);
public static $typeStrings = array( // zero-indexed
null, 'npc', 'object', 'item', 'itemset', 'quest', 'spell', 'zone', 'faction',
'pet', 'achievement', 'title', 'event', 'class', 'race', 'skill', null, 'currency'
@@ -1675,14 +1297,6 @@ class Util
return self::formatTime($tDiff * 1000, true);
}
public static function colorByRarity($idx)
{
if (!isset(self::$rarityColorStings))
$idx = 1;
return self::$rarityColorStings($idx);
}
public static function formatMoney($qty)
{
$money = '';
@@ -1827,13 +1441,16 @@ class Util
return 'b'.strToUpper($_);
}
public static function sqlEscape($data)
public static function sqlEscape($data, $relaxed = false)
{
if (!is_array($data))
return mysql_real_escape_string(trim($data));
// relaxed: expecting strings for fulltext search
$pattern = $relaxed ? ['/[;`´"\/\\\]/ui', '--'] : ['/[^\p{L}0-9\s_\-\.]/ui', '--'];
array_walk($data, function(&$item, $key) {
$item = Util::sqlEscape($item);
if (!is_array($data))
return preg_replace($pattern, '', trim($data));
array_walk($data, function(&$item, $key) use (&$relaxed) {
$item = self::sqlEscape($item, $relaxed);
});
return $data;
@@ -2054,6 +1671,38 @@ class Util
return mb_strtoupper($first, 'UTF-8') . $rest;
}
public static function checkNumeric(&$data)
{
if ($data === null)
return false;
else if (!is_array($data))
{
$data = trim($data);
if (is_numeric($data))
{
$_int = intVal($data);
$_float = floatVal($data);
$data = ($_int == $_float) ? $_int : $_float;
return true;
}
else if (preg_match('/^\d*,\d+$/', $data))
{
$data = floatVal(strtr($data, ',', '.'));
return true;
}
return false;
}
array_walk($data, function(&$item, $key) {
self::checkNumeric($item);
});
return false; // always false for passed arrays
}
}
?>

View File

@@ -12,6 +12,9 @@ if (!file_exists('config/config.php'))
// include all necessities, set up basics
require 'includes/kernel.php';
if ($AoWoWconf['maintenance'] && !User::isInGroup(U_GROUP_EMPLOYEE))
$smarty->brb();
switch ($pageCall)
{
/* called by user */

View File

@@ -12,6 +12,7 @@ if (!defined('AOWOW_REVISION'))
$lang = array(
// page variables
'main' => array(
'help' => "Hilfe",
'name' => "Name",
'link' => "Link",
'signIn' => "Anmelden",
@@ -82,6 +83,7 @@ $lang = array(
'links' => "Links",
'compare' => "Vergleichen",
'view3D' => "3D-Ansicht",
'findUpgrades' => "Bessere Gegenstände finden...",
// miscTools
'subscribe' => "Abonnieren",
@@ -95,6 +97,15 @@ $lang = array(
'englishOnly' => "Diese Seite ist nur in <b>Englisch</b> verfügbar.",
// calculators
'preset' => "Vorlage",
'addWeight' => "Weitere Gewichtung hinzufügen",
'createWS' => "Gewichtungsverteilung erstellen",
'jcGemsOnly' => "<span%s>JS-exklusive</span> Edelsteine einschließen",
'cappedHint' => 'Tipp: <a href="javascript:;" onclick="fi_presetDetails();">Entfernt</a> Gewichtungen für gedeckte Werte wie Trefferwertung.',
'groupBy' => "Ordnen nach",
'gb' => array(
['Nichts', 'none'], ['Platz', 'slot'], ['Stufe', 'level'], ['Quelle', 'source']
),
'compareTool' => "Gegenstandsvergleichswerkzeug",
'talentCalc' => "Talentrechner",
'petCalc' => "Begleiterrechner",
@@ -130,6 +141,8 @@ $lang = array(
'faction' => "Fraktion",
'factions' => "Fraktionen",
'cooldown' => "%s Abklingzeit",
'item' => "Gegenstand",
'items' => "Gegenstände",
'itemset' => "Ausrüstungsset",
'itemsets' => "Ausrüstungssets",
'mechanic' => "Auswirkung",
@@ -484,6 +497,11 @@ $lang = array(
'randEnchant' => "&lt;Zufällige Verzauberung&gt",
'readClick' => "&lt;Zum Lesen rechtsklicken&gt",
'set' => "Set",
'_reqLevel' => "Mindeststufe",
'slot' => "Platz",
'_quality' => "Qualität",
'usableBy' => "Benutzbar von",
'gems' => "Edelsteine",
'socketBonus' => "Sockelbonus",
'socket' => array (
"Metasockel", "Roter Sockel", "Gelber Sockel", "Blauer Sockel", -1 => "Prismatischer Sockel"
@@ -528,6 +546,10 @@ $lang = array(
'projectileSubClass' => array(
null, null, "Pfeil", "Kugel", null
),
'elixirType' => [null, "Kampf", "Wächter"],
'cat' => array(
// locale_dede.js zerparsen..
),
'statType' => array(
"Erhöht Euer Mana um %d.",
"Erhöht Eure Gesundheit um %d.",

View File

@@ -7,6 +7,7 @@ if (!defined('AOWOW_REVISION'))
$lang = array(
// page variables
'main' => array(
'help' => "Help",
'name' => "Name",
'link' => "Link",
'signIn' => "Sign in",
@@ -77,6 +78,7 @@ $lang = array(
'links' => "Links",
'compare' => "Compare",
'view3D' => "View in 3D",
'findUpgrades' => "Find upgrades...",
// misc Tools
'subscribe' => "Subscribe",
@@ -90,6 +92,15 @@ $lang = array(
'englishOnly' => "This page is only available in <b>English</b>.",
// calculators
'preset' => "Preset",
'addWeight' => "Add another weight",
'createWS' => "Create a weight scale",
'jcGemsOnly' => "Include <span%s>JC-only</span> gems",
'cappedHint' => 'Tip: <a href="javascript:;" onclick="fi_presetDetails();">Remove</a> weights for capped statistics such as Hit rating.',
'groupBy' => "Group By",
'gb' => array(
['None', 'none'], ['Slot', 'slot'], ['Level', 'level'], ['Source', 'source']
),
'compareTool' => "Item Comparison Tool",
'talentCalc' => "Talent Calculator",
'petCalc' => "Hunter Pet Calculator",
@@ -125,6 +136,8 @@ $lang = array(
'faction' => "faction",
'factions' => "Factions",
'cooldown' => "%s cooldown",
'item' => "item",
'items' => "Items",
'itemset' => "item Set",
'itemsets' => "Item Sets",
'mechanic' => "Mechanic",
@@ -164,7 +177,7 @@ $lang = array(
11 => "Draconic", 12 => "Kalimag", 13 => "Gnomish", 14 => "Troll", 33 => "Gutterspeak", 35 => "Draenei", 36 => "Zombie", 37 => "Gnomish Binary", 38 => "Goblin Binary"
),
'gl' => array(null, "Major", "Minor"),
'si' => array(-2 => "Horde only", -1 => "Alliance only", null, "Alliance", "Horde", "Both"),
'si' => array(1 => "Alliance", -1 => "Alliance only", 2 => "Horde", -2 => "Horde only", 3 => "Both"),
'resistances' => array(null, 'Holy Resistance', 'Fire Resistance', 'Nature Resistance', 'Frost Resistance', 'Shadow Resistance', 'Arcane Resistance'),
'dt' => array(null, "Magic", "Curse", "Disease", "Poison", "Stealth", "Invisibility", null, null, "Enrage"),
'sc' => array("Physical", "Holy", "Fire", "Nature", "Frost", "Shadow", "Arcane"),
@@ -431,15 +444,14 @@ $lang = array(
),
'armorSubClass' => array(
"Miscellaneous", "Cloth Armor", "Leather Armor", "Mail Armor", "Plate Armor",
null, "Shilds", "Librams", "Idols", "Totems",
null, "Shields", "Librams", "Idols", "Totems",
"Sigils"
),
'weaponSubClass' => array(
"One-Handed Axes", "Two-Handed Axes", "Bows", "Guns", "One-Handed Maces",
"Two-Handed Maces", "Polearms", "One-Handed Swords", "Two-Handed Swords", null,
"Staves", null, null, "Fist Weapons", "Miscellaneous",
"Daggers", "Thrown", null, "Crossbows", "Wands",
"Fishing Poles"
15 => "Daggers", 13 => "Fist Weapons", 0 => "One-Handed Axes", 4 => "One-Handed Maces", 7 => "One-Handed Swords",
6 => "Polearms", 10 => "Staves", 1 => "Two-Handed Axes", 5 => "Two-Handed Maces", 8 => "Two-Handed Swords",
2 => "Bows", 18 => "Crossbows", 3 => "Guns", 16 => "Thrown", 19 => "Wands",
10 => "Fishing Poles", 14 => "Miscellaneous"
),
'subClassMasks' => array(
0x02A5F3 => 'Melee Weapon', 0x0060 => 'Shield', 0x04000C => 'Ranged Weapon', 0xA091 => 'One-Handed Melee Weapon'
@@ -478,6 +490,11 @@ $lang = array(
'randEnchant' => "&lt;Random enchantment&gt",
'readClick' => "&lt;Right Click To Read&gt",
'set' => "Set",
'_reqLevel' => "Required level",
'slot' => "Slot",
'_quality' => "Quality",
'usableBy' => "Usable by",
'gems' => "Gems",
'socketBonus' => "Socket Bonus",
'socket' => array(
"Meta Socket", "Red Socket", "Yellow Socket", "Blue Socket", -1 => "Prismatic Socket"
@@ -496,20 +513,20 @@ $lang = array(
),
"bagFamily" => array(
"Bag", "Quiver", "Ammo Pouch", "Soul Bag", "Leatherworking Bag",
"Inscription Bag", "Herb Bag", "Enchanting Bag", "Engineering Bag", "Key",
"Inscription Bag", "Herb Bag", "Enchanting Bag", "Engineering Bag", null, /*Key*/
"Gem Bag", "Mining Bag"
),
'inventoryType' => array(
null, "Head", "Neck", "Shoulder", "Shirt",
"Chest", "Waist", "Legs", "Feet", "Wrist",
"Hands", "Finger", "Trinket", "One-Hand", "Off Hand",
"Hands", "Finger", "Trinket", "One-Hand", "Off Hand", /*Shield*/
"Ranged", "Back", "Two-Hand", "Bag", "Tabard",
"Chest", "Main Hand", "Off Hand", "Held In Off-Hand", "Projectile",
"Thrown", "Ranged", "Quiver", "Relic"
null, /*Robe*/ "Main Hand", "Off Hand", "Held In Off-Hand", "Projectile",
"Thrown", null, /*Ranged2*/ "Quiver", "Relic"
),
'armorSubClass' => array(
"Miscellaneous", "Cloth", "Leather", "Mail", "Plate",
null, "Shild", "Libram", "Idol", "Totem",
null, "Shield", "Libram", "Idol", "Totem",
"Sigil"
),
'weaponSubClass' => array(
@@ -522,6 +539,50 @@ $lang = array(
'projectileSubClass' => array(
null, null, "Arrow", "Bullet", null
),
'elixirType' => [null, "Battle", "Guardian"],
'cat' => array(
2 => "Weapons", // self::$spell['weaponSubClass']
4 => array("Armor", array(
1 => "Cloth Armor", 2 => "Leather Armor", 3 => "Mail Armor", 4 => "Plate Armor", 6 => "Shields", 7 => "Librams",
8 => "Idols", 9 => "Totems", 10 => "Sigils", -6 => "Cloaks", -5 => "Off-hand Frills", -8 => "Shirts",
-7 => "Tabards", -3 => "Amulets", -2 => "Rings", -4 => "Trinkets", 0 => "Miscellaneous (Armor)",
)),
1 => array("Containers", array(
0 => "Bags", 3 => "Enchanting Bags", 4 => "Engineering Bags", 5 => "Gem Bags", 2 => "Herb Bags", 8 => "Inscription Bags",
7 => "Leatherworking Bags", 6 => "Mining Bags", 1 => "Soul Bags"
)),
0 => array("Consumables", array(
7 => "Bandages", 0 => "Consumables", 2 => "Elixirs", 3 => "Flasks", 5 => "Food & Drinks", 6 => "Item Enhancements (Permanent)",
-3 => "Item Enhancements (Temporary)", 1 => "Potions", 4 => "Scrolls", 8 => "Other (Consumables)"
)),
16 => array("Glyphs", array(
1 => "Warrior Glyphs", 2 => "Paladin Glyphs", 3 => "Hunter Glyphs", 4 => "Rogue Glyphs", 5 => "Priest Glyphs", 6 => "Death Knight Glyphs",
7 => "Shaman Glyphs", 8 => "Mage Glyphs", 9 => "Warlock Glyphs", 11 => "Druid Glyphs"
)),
7 => array("Trade Goods", array(
14 => "Armor Enchantments", 5 => "Cloth", 3 => "Devices", 10 => "Elemental", 12 => "Enchanting", 2 => "Explosives",
9 => "Herbs", 4 => "Jewelcrafting", 6 => "Leather", 13 => "Materials", 8 => "Meat", 7 => "Metal & Stone",
1 => "Parts", 15 => "Weapon Enchantments", 11 => "Other (Trade Goods)"
)),
6 => ["Projectiles", [ 2 => "Arrows", 3 => "Bullets" ]],
11 => ["Quivers", [ 2 => "Quivers", 3 => "Ammo Pouches"]],
9 => array("Recipes", array(
0 => "Books", 6 => "Alchemy Recipes", 4 => "Blacksmithing Plans", 5 => "Cooking Recipes", 8 => "Enchanting Formulae", 3 => "Engineering Schematics",
7 => "First Aid Books", 9 => "Fishing Books", 11 => "Inscription Techniques", 10 => "Jewelcrafting Designs", 1 => "Leatherworking Patterns",12 => "Mining Guides",
2 => "Tailoring Patterns"
)),
3 => array("Gems", array(
6 => "Meta Gems", 0 => "Red Gems", 1 => "Blue Gems", 2 => "Yellow Gems", 3 => "Purple Gems", 4 => "Green Gems",
5 => "Orange Gems", 8 => "Prismatic Gems", 7 => "Simple Gems"
)),
15 => array("Miscellaneous", array(
-2 => "Armor Tokens", 3 => "Holiday", 0 => "Junk", 1 => "Reagents", 5 => "Mounts", -7 => "Flying Mounts",
2 => "Small Pets", 4 => "Other (Miscellaneous)"
)),
10 => "Currency",
12 => "Quest",
13 => "Keys",
),
'statType' => array(
"Increases your Mana by %d.",
"Increases your Health by %d.",

View File

@@ -12,6 +12,7 @@ if (!defined('AOWOW_REVISION'))
$lang = array(
// page variables
'main' => array(
'help' => "Ayuda",
'name' => "Nombre",
'link' => "Enlace",
'signIn' => "Iniciar sesión",
@@ -74,6 +75,7 @@ $lang = array(
'links' => "Enlaces",
'compare' => "Comparar",
'view3D' => "Ver en 3D",
'findUpgrades' => "Buscar mejoras...",
// misc Tools
'subscribe' => "Suscribirme",
@@ -87,6 +89,15 @@ $lang = array(
'englishOnly' => "Esta página sólo está disponible en <b>inglés</b>.",
// calculators
'preset' => "Predet.",
'addWeight' => "Añadir otro factor",
'createWS' => "Crear escala de valores",
'jcGemsOnly' => "Incluir solo <span%s>gemas de joyería</span>",
'cappedHint' => 'Consejo: <a href="javascript:;" onclick="fi_presetDetails();">Elimina</a> escalas para atributos al máximo como el Índice de Golpe.',
'groupBy' => "Agrupar por",
'gb' => array(
['Ninguno', 'none'], ['Casilla', 'slot'], ['Nivel', 'level'], ['Fuente', 'source']
),
'compareTool' => "Herramienta de comparación de objetos",
'talentCalc' => "Calculadora de talentos",
'petCalc' => "Calculadora de mascotas",
@@ -122,6 +133,8 @@ $lang = array(
'faction' => "facción",
'factions' => "Facciones",
'cooldown' => "%s de reutilización",
'item' => "objeto",
'items' => "Objetos",
'itemset' => "conjunto de objetos",
'itemsets' => "Conjuntos de objetos",
'mechanic' => "Mecanica",
@@ -437,6 +450,11 @@ $lang = array(
'randEnchant' => "&lt;Encantamiento aleatorio&gt",
'readClick' => "&lt;Click derecho para leer&gt",
'set' => "Conjunto",
'_reqLevel' => "Nivel requerido",
'slot' => "Casilla",
'_quality' => "Calidad",
'usableBy' => "Usable por",
'gems' => "Gemas",
'socketBonus' => "Bono de ranura",
'socket' => array(
"Ranura meta", "Ranura roja", "Ranura amarilla", "Ranura azul", -1 => "Ranura prismática "
@@ -481,6 +499,9 @@ $lang = array(
'projectileSubClass' => array(
null, null, "Flecha", "Bala", null
),
'elixirType' => [null, "Batalla", "Guardián"],
'cat' => array(
),
'statType' => array(
"Aumenta tu maná %d p.",
"Aumenta tu salud %d p.",

View File

@@ -12,6 +12,7 @@ if (!defined('AOWOW_REVISION'))
$lang = array(
// page variables
'main' => array(
'help' => "Aide",
'name' => "Nom",
'link' => "Lien",
'signIn' => "S'enregistrer",
@@ -74,6 +75,7 @@ $lang = array(
'links' => "Liens",
'compare' => "Comparer",
'view3D' => "Voir en 3D",
'findUpgrades' => "Trouver des améliorations...",
// misc Tools
'subscribe' => "S'abonner",
@@ -87,6 +89,15 @@ $lang = array(
'englishOnly' => "Cette page n'est disponible qu'en <b>anglais</b> pour le moment.",
// calculators
'preset' => "Prédéterminée",
'addWeight' => "Ajouter un autre facteur",
'createWS' => "Créer une échelle de valeurs",
'jcGemsOnly' => "Inclure les gemmes de <span%s>joaillier</span>",
'cappedHint' => 'Conseil: <a href="javascript:;" onclick="fi_presetDetails();">Enlever</a> un facteur pour les statistiques au maximum tel que le score de touche.',
'groupBy' => "Groupé par",
'gb' => array(
['Aucun', 'none'], ['Emplacement', 'slot'], ['Niveau', 'level'], ['Source', 'source']
),
'compareTool' => "Outil de comparaison d'objets",
'talentCalc' => "Calculateur de Talents",
'petCalc' => "Calculateur de familiers",
@@ -122,6 +133,8 @@ $lang = array(
'faction' => "faction",
'factions' => "Factions",
'cooldown' => "%s de recharge",
'item' => "objet",
'items' => "Objets",
'itemset' => "ensemble d'objets",
'itemsets' => "Ensembles d'objets",
'mechanic' => "Mécanique",
@@ -436,6 +449,11 @@ $lang = array(
'randEnchant' => "&lt;Enchantement aléatoire&gt",
'readClick' => "&lt;Clique Droit pour Lire&gt",
'set' => "Set",
'_reqLevel' => "Niveau requis",
'slot' => "Emplacement",
'_quality' => "Qualité",
'usableBy' => "Utilisable par",
'gems' => "Gemmes",
'socketBonus' => "Bonus de châsse",
'socket' => array(
"Méta-châsse", "Châsse rouge", "Châsse jaune", "Châsse bleue", -1 => "Châsse prismatique"
@@ -480,6 +498,9 @@ $lang = array(
'projectileSubClass' => array(
null, null, "Flèche", "Balle", null
),
'elixirType' => [null, "De bataille", "De gardien"],
'cat' => array(
),
'statType' => array(
"Augmente vos points de mana de %d.",
"Augmente vos points de vie de %d.",

View File

@@ -12,6 +12,7 @@ if (!defined('AOWOW_REVISION'))
$lang = array(
// page variables
'main' => array(
'help' => "Справка",
'name' => "Название",
'link' => "Ссылка",
'signIn' => "Войти",
@@ -74,6 +75,7 @@ $lang = array(
'links' => "Ссылки",
'compare' => "Сравнить",
'view3D' => "Посмотреть в 3D",
'findUpgrades' => "Найти лучше...",
// misc Tools
'subscribe' => "Подписаться",
@@ -87,6 +89,15 @@ $lang = array(
'englishOnly' => "Эта страница доступна только на <b>английском</b> языке.",
// calculators
'preset' => "Готовая таблица",
'addWeight' => "Добавить фильтр значимости",
'createWS' => "Отсортировать по значимости",
'jcGemsOnly' => "Использовать <span%s>ювелирские</span>",
'cappedHint' => 'Подсказка: <a href="javascript:;" onclick="fi_presetDetails();">Удалите</a> характеристики с капом (например, меткость).',
'groupBy' => "Группировать",
'gb' => array(
['Нет', 'none'], ['Слот', 'slot'], ['Уровень', 'level'], ['Источник', 'source']
),
'compareTool' => "Инструмент сравнения предметов",
'talentCalc' => "Расчёт талантов",
'petCalc' => "Расчёт умений питомцев",
@@ -122,6 +133,8 @@ $lang = array(
'faction' => "фракция",
'factions' => "Фракции",
'cooldown' => "Восстановление: %s",
'item' => "предмет",
'items' => "Предметы",
'itemset' => "комплект",
'itemsets' => "Комплекты",
'mechanic' => "Механика",
@@ -436,6 +449,11 @@ $lang = array(
'randEnchant' => "&lt;Случайное зачарование&gt",
'readClick' => "&lt;Щелкните правой кнопкой мыши, чтобы прочитать.&gt",
'set' => "Набор",
'_reqLevel' => "Требуется уровень",
'slot' => "Слот",
'_quality' => "Качество",
'usableBy' => "Используется (кем)",
'gems' => "Самоцветы",
'socketBonus' => "При соответствии цвета",
'socket' => array(
"Особое гнездо", "Красное гнездо", "Желтое гнездо", "Синее гнездо", -1 => "Бесцветное гнездо"
@@ -480,6 +498,9 @@ $lang = array(
'projectileSubClass' => array(
null, null, "Стрелы", "Пули", null
),
'elixirType' => [null, "Бой", "Охранный"],
'cat' => array(
),
'statType' => array(
"Увеличение запаса маны на %d ед.",
"Увеличение максимального запаса здоровья на %d ед.",

View File

@@ -39,22 +39,22 @@ function signin()
$remember = $_POST['remember_me'] == 'yes';
// handle login try limitation
$ipBan = DB::Aowow()->selectRow('SELECT ip, count, UNIX_TIMESTAMP(unbanDate) as unbanDate FROM ?_account_bannedIPs WHERE type = 0 AND ip = ?s',
$ipBan = DB::Aowow()->selectRow('SELECT ip, count, UNIX_TIMESTAMP(unbanDate) as unbanDate FROM ?_account_bannedIPs WHERE type = 0 AND ip = ?',
$_SERVER['REMOTE_ADDR']
);
if (!$ipBan) // no entry exists; set count to 1
DB::Aowow()->query('INSERT INTO ?_account_bannedIPs VALUES (?s, 0, 1, FROM_UNIXTIME(?))',
DB::Aowow()->query('INSERT INTO ?_account_bannedIPs VALUES (?, 0, 1, FROM_UNIXTIME(?))',
$_SERVER['REMOTE_ADDR'],
time() + $GLOBALS['AoWoWconf']['loginFailTime']
);
else if ($ipBan['unbanDate'] < time()) // ip has accumulated counts but time expired; reset count to 1
DB::Aowow()->query('INSERT IGNORE INTO ?_account_bannedIPs VALUES (?s, 0, 1, ?)',
DB::Aowow()->query('INSERT IGNORE INTO ?_account_bannedIPs VALUES (?, 0, 1, ?)',
$_SERVER['REMOTE_ADDR'],
time() + $GLOBALS['AoWoWconf']['loginFailTime']
);
else // entry already exists; increment count
DB::Aowow()->query('UPDATE ?_account_bannedIPs SET count = count + 1, unbanDate = FROM_UNIXTIME(?) WHERE ip = ?s',
DB::Aowow()->query('UPDATE ?_account_bannedIPs SET count = count + 1, unbanDate = FROM_UNIXTIME(?) WHERE ip = ?',
time() + $GLOBALS['AoWoWconf']['loginFailTime'],
$_SERVER['REMOTE_ADDR']
);
@@ -71,7 +71,7 @@ function signin()
switch (User::Auth($password))
{
case AUTH_OK:
DB::Aowow()->query('DELETE FROM ?_account_bannedIPs WHERE type = 0 AND ip = ?s',
DB::Aowow()->query('DELETE FROM ?_account_bannedIPs WHERE type = 0 AND ip = ?',
$_SERVER['REMOTE_ADDR']
);
DB::Aowow()->query('UPDATE ?_account SET lastLogin = FROM_UNIXTIME(?), timeout = FROM_UNIXTIME(?) WHERE id = ?',
@@ -97,6 +97,8 @@ function signin()
function signup()
{
global $AoWoWconf, $smarty;
/*
$username = Get(GET_STRING, 'username', 'POST');
$password = Get(GET_STRING, 'password', 'POST');
@@ -203,8 +205,9 @@ function signup()
return;
}
*/
// Account creation
if ($_REQUEST['account'] == 'signup' && isset($_POST['username']) && isset($_POST['password']) && isset($_POST['c_password']) && $AoWoWconf['register'] == true)
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['c_password']) && $AoWoWconf['register'] == true)
{
// password mismatch
if ($_POST['password'] != $_POST['c_password'])
@@ -212,7 +215,7 @@ function signup()
else
{
// AccName already in use
if ($rDB->selectCell('SELECT Count(id) FROM aowow_account WHERE username=? LIMIT 1', $_POST['username']) >= 1)
if (DB::Aowow()->selectCell('SELECT 1 FROM aowow_account WHERE user = ? LIMIT 1', $_POST['username']))
$smarty->assign('signup_error', Lang::$account['nameInUse']);
else
{
@@ -257,7 +260,7 @@ $smarty->updatePageVars(array(
),
));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$account));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$account, ['colon' => Lang::$colon]));
if (User::$id)
{
@@ -269,7 +272,7 @@ if (User::$id)
$next = !empty($next[1]) ? '?'.$next[1] : '.';
header('Location: '.$next);
case 'weightscales':
$post = Util::sqlEscape($_POST);
$post = Util::sqlEscape($_POST, true);
if (isset($post['save']))
{
@@ -282,7 +285,7 @@ if (User::$id)
die('0');
}
if (DB::Aowow()->query('REPLACE INTO ?_account_weightscales VALUES (?d, ?d, ?s, ?s)', $post['id'], User::$id, $post['name'], $post['scale']))
if (DB::Aowow()->query('REPLACE INTO ?_account_weightscales VALUES (?d, ?d, ?, ?)', intVal($post['id']), User::$id, $post['name'], $post['scale']))
die((string)$post['id']);
else
die('0');

View File

@@ -92,7 +92,19 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
'path' => $tmpPath,
'infobox' => array_merge($infobox, Lang::getInfoBoxForFlags($acv->getField('cuFlags'))),
'relTabs' => [],
'page' => $acv->getDetailedData()[$_id]
'page' => array(
'name' => $acv->getField('name', true),
'description' => $acv->getField('description', true),
'points' => $acv->getField('points'),
'iconname' => $acv->getField('iconString'),
'count' => $acv->getField('reqCriteriaCount'),
'reward' => $acv->getField('reward', true),
'nCriteria' => count($acv->getCriteria()),
'titleReward' => [],
'itemReward' => [],
'criteria' => [],
'icons' => []
)
);
// listview: "see also"
@@ -137,17 +149,14 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
}
// create rewards
$pageData['page']['titleReward'] = [];
$pageData['page']['itemReward'] = [];
if ($foo = $acv->getField('rewards')[TYPE_ITEM])
{
$bar = new ItemList(array(['i.entry', $foo]));
$bar = new ItemList(array(['i.id', $foo]));
foreach ($bar->iterate() as $__)
{
$pageData['page']['itemReward'][$bar->id] = array(
'name' => $bar->getField('name', true),
'quality' => $bar->getField('Quality')
'quality' => $bar->getField('quality')
);
}
}
@@ -163,14 +172,10 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
// ACHIEVEMENT CRITERIA
// *****
$pageData['page']['criteria'] = [];
$iconId = 1;
$tmp_arr = [];
$pageData['page']['icons'] = [];
$pageData['page']['total_criteria'] = count($acv->getCriteria());
$rightCol = [];
$i = 0; // stupid uninitialized iterator.....
foreach ($acv->getCriteria() as $crt)
foreach ($acv->getCriteria() as $i => $crt)
{
// hide hidden criteria for regular users (really do..?)
// if (($crt['complete_flags'] & ACHIEVEMENT_CRITERIA_FLAG_HIDDEN) && User::$perms > 0)
@@ -296,12 +301,12 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
$crtItm = new ItemList(array(['id', $obj]));
$crtItm = new ItemList(array(['i.id', $obj]));
$text = $crtName ? $crtName : $crtItm->getField('name', true);
$tmp['link'] = array(
'href' => '?item='.$obj,
'text' => $text,
'quality' => $crtItm->getField('Quality'),
'quality' => $crtItm->getField('quality'),
'count' => $qty,
);
$crtItm->addGlobalsToJscript($smarty);
@@ -337,15 +342,15 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
break;
}
// If the right column
if ($i++ % 2)
$tmp_arr[] = $tmp;
else
if ($i % 2)
$pageData['page']['criteria'][] = $tmp;
else
$rightCol[] = $tmp;
}
// If you found the second column - merge data from it to the end of the main body
if ($tmp_arr)
$pageData['page']['criteria'] = array_merge($pageData['page']['criteria'], $tmp_arr);
if ($rightCol)
$pageData['page']['criteria'] = array_merge($pageData['page']['criteria'], $rightCol);
// *****
// ACHIEVEMENT CHAIN
@@ -403,7 +408,7 @@ $smarty->updatePageVars(array(
'typeId' => $_id
));
$smarty->assign('community', CommunityContent::getAll(TYPE_ACHIEVEMENT, $_id)); // comments, screenshots, videos
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement, ['colon' => Lang::$colon]));
$smarty->assign('lvData', $pageData);
// load the page

View File

@@ -4,8 +4,6 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
require 'includes/class.filter.php';
$cats = Util::extractURLParams($pageParam);
$path = [0, 9];
$title = [];
@@ -56,9 +54,9 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter))
}
// recreate form selection
$filter = array_merge($acvList->filterGetForm('form'), $filter);
$filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
$filter['setCr'] = $acvList->filterGetSetCriteria();
$filter = array_merge($acvList->filterGetForm(), $filter);
$filter['fi'] = $acvList->filterGetForm();
// create page title and path
if (is_array($cats))
@@ -88,6 +86,9 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter))
if ($acvList->hasDiffFields(['category']))
$pageData['params']['visibleCols'] = "$['category']";
if (!empty($filter['fi']['extraCols']))
$pageData['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
// create note if search limit was exceeded
if ($acvList->getMatches() > $AoWoWconf['sqlLimit'])
{
@@ -117,7 +118,7 @@ $smarty->updatePageVars(array(
)
));
$smarty->assign('filter', $filter);
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement, ['colon' => Lang::$colon]));
$smarty->assign('lvData', $pageData);
// load the page

View File

@@ -104,9 +104,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
// Items
$conditions = array(
['allowableClass', 0, '>'],
['allowableClass', $_mask, '&'],
[['allowableClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'],
['requiredClass', 0, '>'],
['requiredClass', $_mask, '&'],
[['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'],
['itemset', 0], // hmm, do or dont..?
0
);
@@ -114,7 +114,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$items = new ItemList($conditions);
$items->addGlobalsToJscript($smarty);
if (!$items->hasDiffFields(['AllowableRace']))
if (!$items->hasDiffFields(['requiredRace']))
$hidden = "$['side']";
$pageData['relTabs'][] = array(
@@ -334,7 +334,7 @@ $smarty->updatePageVars(array(
)
));
$smarty->assign('community', CommunityContent::getAll(TYPE_CLASS, $_id)); // comments, screenshots, videos
$smarty->assign('lang', array_merge(Lang::$main, Lang::$talent));
$smarty->assign('lang', Lang::$main);
$smarty->assign('lvData', $pageData);
// load the page

View File

@@ -35,7 +35,7 @@ if ($compareString)
}
$pageData['summary'] = json_encode($outSet, JSON_NUMERIC_CHECK);
$iList = new ItemList(array(['i.entry', $items]));
$iList = new ItemList(array(['i.id', $items]));
$data = $iList->getListviewData(ITEMINFO_SUBITEMS | ITEMINFO_JSON);
foreach ($iList->iterate() as $itemId => $__)
@@ -46,8 +46,8 @@ if ($compareString)
$pageData['items'][] = [
$itemId,
Util::jsEscape($iList->getField('name', true)),
$iList->getField('Quality'),
$iList->getField('icon'),
$iList->getField('quality'),
$iList->getField('iconString'),
json_encode($data[$itemId], JSON_NUMERIC_CHECK)
];
}

View File

@@ -60,7 +60,7 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$pageData['listviews'][] = array(
'file' => 'calendar',
'data' => $events->getListviewData(),
'data' => array_filter($events->getListviewData(), function($x) {return $x['id'] > 0;}),
'params' => array(
'tabs' => '$myTabs',
'hideCount' => 1

View File

@@ -49,15 +49,15 @@ if (isset($_GET['power']))
// output json for tooltips
if (!$smarty->loadCache($cacheKeyTooltip, $x))
{
$item = new ItemList(array(['i.entry', $_id]));
$item = new ItemList(array(['i.id', $_id]));
if ($item->error)
die('$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.', {})');
$item->renderTooltip($enh);
$x .= '$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.", {\n";
$x .= "\tname_".User::$localeString.": '".Util::jsEscape($item->getField('name', true))."',\n";
$x .= "\tquality: ".$item->getField('Quality').",\n";
$x .= "\ticon: '".urlencode($item->getField('icon'))."',\n";
$x .= "\tquality: ".$item->getField('quality').",\n";
$x .= "\ticon: '".urlencode($item->getField('iconString'))."',\n";
$x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($item->tooltip[$_id])."'\n";
$x .= "});";
@@ -69,15 +69,22 @@ if (isset($_GET['power']))
// regular page
if (!$smarty->loadCache($cacheKeyPage, $item))
{
$item = new ItemList(array(['i.entry', $_id]));
$item = new ItemList(array(['i.id', $_id]));
if ($item->error)
$smarty->notFound(Lang::$game['item']);
$pageData = array(
'infobox' => [],
'relTabs' => [],
'tooltip' => $item->renderTooltip([], false),
'page' => $item->getDetailPageData(),
'path' => [0, 0, $item->getField('classs'), $item->getField('subClass')],
'title' => [Lang::$game['item'], $item->getField('name', true)],
'pagetext' => false, // Books
'buttons' => in_array($item->getField('class'), [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR]),
);
// not yet implemented -> chicken out
$smarty->error();
/*
<table class="infobox">
<tr><th>{#Quick_Facts#}</th></tr>
@@ -110,731 +117,85 @@ if (!$smarty->loadCache($cacheKeyPage, $item))
</table>
*/
unset($item);
/********/
/* TABS */
/********/
// Информация о вещи...
$item = iteminfo($_id, 1);
$path = [0, 0, $item['classs'], $item['subclass'], $item['type']];
// dropped by creature
// Поиск мобов с которых эта вещь лутится
$drops_cr = drop('creature_loot_template', $item['entry']);
if($drops_cr)
{
$item['droppedby'] = [];
foreach($drops_cr as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry
{
, l.name_loc?d AS name_loc
, l.subname_loc?d AS subname_loc
}
FROM ?_factiontemplate, creature_template c
{ LEFT JOIN (locales_creature l) ON l.entry=c.entry AND ? }
WHERE
lootid=?d
AND factiontemplateID=faction_A
',
$npc_cols[0],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['droppedby'][] = array_merge(creatureinfo2($row), $drop);
}
unset($rows);
unset($lootid);
unset($drop);
}
unset($drops_cr);
// GO-loot
// diff between gathered from / mined from / contained in
// foreach($rows as $row)
// {
// // Залежи руды
// if($row['lockproperties1'] == LOCK_PROPERTIES_MINING)
// $item['minedfromobject'][] = array_merge(objectinfo2($row), $drop);
// // Собирается с трав
// elseif($row['lockproperties1'] == LOCK_PROPERTIES_HERBALISM)
// $item['gatheredfromobject'][] = array_merge(objectinfo2($row), $drop);
// // Сундуки
// else
// $item['containedinobject'][] = array_merge(objectinfo2($row), $drop);
// }
// Поиск объектов, из которых лутится эта вещь
$drops_go = drop('gameobject_loot_template', $item['entry']);
if($drops_go)
{
$item['containedinobject'] = [];
$item['minedfromobject'] = [];
$item['gatheredfromobject'] = [];
foreach($drops_go as $lootid => $drop)
{
// Сундуки
$rows = $DB->select('
SELECT g.entry, g.name, g.type, a.lockproperties1 {, l.name_loc?d AS name_loc}
FROM gameobject_template g LEFT JOIN ?_lock a ON a.lockID=g.data0
{ LEFT JOIN (locales_gameobject l) ON l.entry=g.entry AND ? }
WHERE
g.data1=?d
AND g.type IN (?d, ?d)
',
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid,
GAMEOBJECT_TYPE_CHEST,
GAMEOBJECT_TYPE_FISHINGHOLE
);
foreach($rows as $row)
{
// Залежи руды
if($row['lockproperties1'] == LOCK_PROPERTIES_MINING)
$item['minedfromobject'][] = array_merge(objectinfo2($row), $drop);
// Собирается с трав
elseif($row['lockproperties1'] == LOCK_PROPERTIES_HERBALISM)
$item['gatheredfromobject'][] = array_merge(objectinfo2($row), $drop);
// Сундуки
else
$item['containedinobject'][] = array_merge(objectinfo2($row), $drop);
}
}
// sold by [consult itemExtendedCost]
if(!$item['containedinobject'])
unset($item['containedinobject']);
if(!$item['minedfromobject'])
unset($item['minedfromobject']);
if(!$item['gatheredfromobject'])
unset($item['gatheredfromobject']);
// Objective of (quest)
unset($rows);
}
unset($drops_go);
// provided for (quest)
// Поиск вендеров, которые эту вещь продают
$rows_soldby = $DB->select('
SELECT ?#, c.entry, v.ExtendedCost, v.maxcount AS stock
{
, l.name_loc?d AS name_loc
, l.subname_loc?d AS subname_loc
}
FROM npc_vendor v, ?_factiontemplate, creature_template c
{ LEFT JOIN (locales_creature l) ON l.entry=c.entry AND ? }
WHERE
v.item=?d
AND c.entry=v.entry
AND factiontemplateID=faction_A
ORDER BY 1 DESC, 2 DESC
',
$npc_cols['0'],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$item['entry']
);
if($rows_soldby)
{
$item['soldby'] = [];
foreach($rows_soldby as $i => $row)
{
$item['soldby'][$i] = [];
$item['soldby'][$i] = creatureinfo2($row);
$item['soldby'][$i]['stock'] = ($row['stock'] == 0 ? -1 : $row['stock']);
if($row['ExtendedCost'])
{
$item['soldby'][$i]['cost'] = [];
$extcost = $DB->selectRow('SELECT * FROM ?_item_extended_cost WHERE extendedcostID=?d LIMIT 1', abs($row['ExtendedCost']));
if($extcost['reqhonorpoints'])
$item['soldby'][$i]['cost']['honor'] = ($row['A'] == 1 ? 1 : -1) * $extcost['reqhonorpoints'];
if($extcost['reqarenapoints'])
$item['soldby'][$i]['cost']['arena'] = $extcost['reqarenapoints'];
$item['soldby'][$i]['cost']['items'] = [];
for ($j=1;$j<=5;$j++)
if(($extcost['reqitem'.$j]>0) and ($extcost['reqitemcount'.$j]>0))
{
allitemsinfo($extcost['reqitem'.$j], 0);
$item['soldby'][$i]['cost']['items'][] = array('item' => $extcost['reqitem'.$j], 'count' => $extcost['reqitemcount'.$j]);
}
}
else
$item['soldby'][$i]['cost']['money'] = $item['BuyPrice'];
}
unset($extcost);
}
unset($rows_soldby);
// reward of (quest)
// Поиск квестов, для выполнения которых нужен этот предмет
$rows_qr = $DB->select('
SELECT q.?# {, l.Title_loc?d AS Title_loc}
FROM quest_template q
{ LEFT JOIN (locales_quest l) ON l.entry=q.entry AND ? }
WHERE
ReqItemId1=?d
OR ReqItemId2=?d
OR ReqItemId3=?d
OR ReqItemId4=?d
',
$quest_cols[2],
$_SESSION['locale'] > 0 ? $_SESSION['locale'] : DBSIMPLE_SKIP,
$_SESSION['locale'] > 0 ? 1 : DBSIMPLE_SKIP,
$item['entry'], $item['entry'], $item['entry'], $item['entry']
);
if($rows_qr)
{
$item['objectiveof'] = [];
foreach($rows_qr as $row)
$item['objectiveof'][] = GetQuestInfo($row, 0xFFFFFF);
}
unset($rows_qr);
// reward of (quest) [from mail-loot]
// Поиск квестов, при взятии которых выдается этот предмет
$rows_qp = $DB->select('
SELECT q.?# {, l.Title_loc?d AS Title_loc}
FROM quest_template q
{ LEFT JOIN (locales_quest l) ON l.entry=q.entry AND ? }
WHERE SrcItemId=?d
',
$quest_cols[2],
$_SESSION['locale'] > 0 ? $_SESSION['locale'] : DBSIMPLE_SKIP,
$_SESSION['locale'] > 0 ? 1 : DBSIMPLE_SKIP,
$item['entry']
);
if($rows_qp)
{
$item['providedfor'] = [];
foreach($rows_qp as $row)
$item['providedfor'][] = GetQuestInfo($row, 0xFFFFFF);
}
unset($rows_qp);
// contained in (item) [item_loot]
// Поиск квестов, наградой за выполнение которых, является этот предмет
$rows_qrw = $DB->select('
SELECT q.?# {, l.Title_loc?d AS Title_loc}
FROM quest_template q
{ LEFT JOIN (locales_quest l) ON l.entry=q.entry AND ? }
WHERE
RewItemId1=?d
OR RewItemId2=?d
OR RewItemId3=?d
OR RewItemId4=?d
OR RewChoiceItemId1=?d
OR RewChoiceItemId2=?d
OR RewChoiceItemId3=?d
OR RewChoiceItemId4=?d
OR RewChoiceItemId5=?d
OR RewChoiceItemId6=?d
',
$quest_cols[2],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$item['entry'], $item['entry'], $item['entry'], $item['entry'], $item['entry'],
$item['entry'], $item['entry'], $item['entry'], $item['entry'], $item['entry']
);
if($rows_qrw)
{
$item['rewardof'] = [];
foreach($rows_qrw as $row)
$item['rewardof'][] = GetQuestInfo($row, 0xFFFFFF);
}
unset($rows_qrw);
// contains [item_loot]
// Поиск квестов, в награду за выполнение которых итем присылают почтой
$drops_qm = drop('mail_loot_template', $item['entry']);
if($drops_qm)
{
foreach($drops_qm as $lootid => $row)
{
$rows_qm = $DB->select('
SELECT q.?# {, l.Title_loc?d AS Title_loc}
FROM quest_template q
{ LEFT JOIN (locales_quest l) ON l.entry=q.entry AND ? }
WHERE RewMailTemplateId=?d
',
$quest_cols[2],
$_SESSION['locale'] > 0 ? $_SESSION['locale'] : DBSIMPLE_SKIP,
$_SESSION['locale'] > 0 ? 1 : DBSIMPLE_SKIP,
$lootid
);
if($rows_qm)
{
if (!isset($item['rewardof']))
$item['rewardof'] = [];
foreach($rows_qm as $row)
$item['rewardof'][] = GetQuestInfo($row, 0xFFFFFF);
}
unset($rows_qm);
}
}
unset($drops_qm);
// pickpocketed from
// Поиск вещей, в которых находятся эти вещи
$drops_cii = drop('item_loot_template', $item['entry']);
if($drops_cii)
{
$item['containedinitem'] = [];
foreach($drops_cii as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry, maxcount
{ , l.name_loc?d AS name_loc }
FROM ?_icons, item_template c
{ LEFT JOIN (locales_item l) ON l.entry=c.entry AND ? }
WHERE
c.entry=?d
AND id=displayid
',
$item_cols[2],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['containedinitem'][] = array_merge(iteminfo2($row, 0), $drop);
}
unset($drops_cii);
unset($rows);
unset($lootid);
unset($drop);
}
// skinning_loot skinned from & salvaged from
// Какие вещи содержатся в этой вещи
if(!($item['contains'] = loot('item_loot_template', $item['entry'])))
unset($item['contains']);
// prospecting & prospected from
// milling & milled from
// Поиск созданий, у которых воруется вещь
$drops_pp = drop('pickpocketing_loot_template', $item['entry']);
if($drops_pp)
{
$item['pickpocketingloot'] = [];
foreach($drops_pp as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry
{
, l.name_loc?d AS name_loc
, l.subname_loc?d AS subname_loc
}
FROM ?_factiontemplate, creature_template c
{ LEFT JOIN (locales_creature l) ON l.entry=c.entry AND ? }
WHERE
pickpocketloot=?d
AND factiontemplateID=faction_A
',
$npc_cols[0],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['pickpocketingloot'][] = array_merge(creatureinfo2($row), $drop);
}
unset($rows);
unset($lootid);
unset($drop);
}
unset($drops_pp);
// disentchanting from & to
// Поиск созданий, с которых сдираеццо эта шкура
$drops_sk = drop('skinning_loot_template', $item['entry']);
if($drops_sk)
{
$item['skinnedfrom'] = [];
foreach($drops_sk as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry
{
, l.name_loc?d AS name_loc
, l.subname_loc?d AS subname_loc
}
FROM ?_factiontemplate, creature_template c
{ LEFT JOIN (locales_creature l) ON l.entry=c.entry AND ? }
WHERE
skinloot=?d
AND factiontemplateID=faction_A
',
$npc_cols[0],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['skinnedfrom'][] = array_merge(creatureinfo2($row), $drop);
}
unset($rows);
unset($lootid);
unset($drop);
}
unset($drops_sk);
// can be placed in
// if($item['BagFamily'] == 256)
// {
// // Если это ключ
// $item['key'] = true;
// }
// Перерабатывается в:
if(!($item['prospecting'] = loot('prospecting_loot_template', $item['entry'])))
unset($item['prospecting']);
// reagent for
// Поиск вещей, из которых перерабатывается эта вещь
$drops_pr = drop('prospecting_loot_template', $item['entry']);
if($drops_pr)
{
$item['prospectingloot'] = [];
foreach($drops_pr as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry, maxcount
{
, l.name_loc?d AS name_loc
}
FROM ?_icons, item_template c
{ LEFT JOIN (locales_item l) ON l.entry=c.entry AND ? }
WHERE
c.entry = ?d
AND id = displayid
',
$item_cols[2],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['prospectingloot'][] = array_merge(iteminfo2($row, 0), $drop);
}
unset($rows);
unset($lootid);
unset($drop);
}
unset($drops_pr);
// created by [spell]
// Дизенчантитcя в:
if(!($item['disenchanting'] = loot('disenchant_loot_template', $item['DisenchantID'])))
unset($item['disenchanting']);
// fished in
// Получается дизэнчантом из..
$drops_de = drop('disenchant_loot_template', $item['entry']);
if($drops_de)
{
$item['disenchantedfrom'] = [];
foreach($drops_de as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry, maxcount
{
, l.name_loc?d AS name_loc
}
FROM ?_icons, item_template c
{ LEFT JOIN (locales_item l) ON l.entry=c.entry AND ? }
WHERE
DisenchantID=?d
AND id=displayid
',
$item_cols[2],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['disenchantedfrom'][] = array_merge(iteminfo2($row, 0), $drop);
}
unset($rows);
unset($lootid);
unset($drop);
}
unset($drops_de);
// currency for
// Поиск сумок в которые эту вещь можно положить
if($item['BagFamily'] == 256)
{
// Если это ключ
$item['key'] = true;
}
elseif($item['BagFamily'] > 0 and $item['ContainerSlots'] == 0)
{
$rows_cpi = $DB->select('
SELECT c.?#, c.entry, maxcount
{
, l.name_loc?d AS name_loc
}
FROM ?_icons, item_template c
{ LEFT JOIN (locales_item l) ON l.entry=c.entry AND ? }
WHERE
BagFamily=?d
AND ContainerSlots>0
AND id=displayid
',
$item_cols[2],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$item['BagFamily']
);
if($rows_cpi)
{
$item['canbeplacedin'] = [];
foreach($rows_cpi as $row)
$item['canbeplacedin'][] = iteminfo2($row, 0);
}
unset($rows_cpi);
}
// [spell_loot_template] ehh...
// Реагент для...
$rows_r = $DB->select('
SELECT ?#, spellID
FROM ?_spell s, ?_spellicons i
WHERE
(( reagent1=?d
OR reagent2=?d
OR reagent3=?d
OR reagent4=?d
OR reagent5=?d
OR reagent6=?d
OR reagent7=?d
OR reagent8=?d
) AND ( i.id=s.spellicon))
',
$spell_cols[2],
$item['entry'], $item['entry'], $item['entry'], $item['entry'],
$item['entry'], $item['entry'], $item['entry'], $item['entry']
);
if($rows_r)
{
$item['reagentfor'] = [];
$quality = 1;
foreach($rows_r as $i=>$row)
{
$item['reagentfor'][$i] = [];
$item['reagentfor'][$i]['entry'] = $row['spellID'];
$item['reagentfor'][$i]['name'] = $row['spellname_loc'.$_SESSION['locale']];
$item['reagentfor'][$i]['school'] = $row['resistancesID'];
$item['reagentfor'][$i]['level'] = $row['levelspell'];
$item['reagentfor'][$i]['quality'] = '@';
for ($j=1;$j<=8;$j++)
if($row['reagent'.$j])
{
$item['reagentfor'][$i]['reagents'][]['entry'] = $row['reagent'.$j];
$item['reagentfor'][$i]['reagents'][count($item['reagentfor'][$i]['reagents'])-1]['count'] = $row['reagentcount'.$j];
allitemsinfo($row['reagent'.$j], 0);
}
for ($j=1;$j<=3;$j++)
if($row['effect'.$j.'itemtype'])
{
$item['reagentfor'][$i]['creates'][]['entry'] = $row['effect'.$j.'itemtype'];
$item['reagentfor'][$i]['creates'][count($item['reagentfor'][$i]['creates'])-1]['count'] = 1 + $row['effect'.$j.'BasePoints'];
allitemsinfo($row['effect'.$j.'itemtype'], 0);
@$item['reagentfor'][$i]['quality'] = 7 - $allitems[$row['effect'.$j.'itemtype']]['quality'];
}
// Добавляем в таблицу спеллов
allspellsinfo2($row);
}
unset($quality);
}
unset($rows_r);
// criteria of
// array(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM),
// Создается из...
$rows_cf = $DB->select('
SELECT ?#, s.spellID
FROM ?_spell s, ?_spellicons i
WHERE
((s.effect1itemtype=?d
OR s.effect2itemtype=?d
OR s.effect3itemtype=?)
AND (i.id = s.spellicon))
',
$spell_cols[2],
$item['entry'], $item['entry'], $item['entry']
);
if($rows_cf)
{
$item['createdfrom'] = [];
foreach($rows_cf as $row)
{
$skillrow = $DB->selectRow('
SELECT skillID, min_value, max_value
FROM ?_skill_line_ability
WHERE spellID=?d
LIMIT 1
',
$row['spellID']
);
$item['createdfrom'][] = spellinfo2(array_merge($row, $skillrow));
}
unset($skillrow);
}
unset($rows_cf);
// teaches
// Ловится в ...
$drops_fi = drop('fishing_loot_template', $item['entry']);
if($drops_fi)
{
$item['fishedin'] = [];
foreach($drops_fi as $lootid => $drop)
{
// Обычные локации
$row = $DB->selectRow('
SELECT name_loc'.$_SESSION['locale'].' AS name, areatableID as id
FROM ?_zones
WHERE
areatableID=?d
/*AND (x_min!=0 AND x_max!=0 AND y_min!=0 AND y_max!=0)*/
LIMIT 1
',
$lootid
);
if($row)
{
$item['fishedin'][] = array_merge($row, $drop);
}
else
{
// Инсты
$row = $DB->selectRow('
SELECT name_loc'.$_SESSION['locale'].' AS name, mapID as id
FROM ?_zones
WHERE
areatableID=?d
LIMIT 1
',
$lootid
);
if($row)
$item['fishedin'][] = array_merge($row, $drop);
}
}
unset($row);
unset($num);
}
unset($drops_fi);
// Размалывается в
if(!$item['milling'] = loot('milling_loot_template', $item['entry']))
unset($item['milling']);
// Получается размалыванием из
$drops_mi = drop('milling_loot_template', $item['entry']);
if($drops_mi)
{
$item['milledfrom'] = [];
foreach($drops_mi as $lootid => $drop)
{
$rows = $DB->select('
SELECT c.?#, c.entry, maxcount
{
, l.name_loc?d AS name_loc
}
FROM ?_icons, item_template c
{ LEFT JOIN (locales_item l) ON l.entry=c.entry AND ? }
WHERE
c.entry=?d
AND id=displayid
',
$item_cols[2],
($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP,
$lootid
);
foreach($rows as $row)
$item['milledfrom'][] = array_merge(iteminfo2($row, 0), $drop);
}
unset($rows);
unset($lootid);
unset($drop);
}
unset($drops_mi);
// Валюта для...
$rows_cf = $DB->select('
SELECT ?#, i.entry, i.maxcount, n.`maxcount` as `drop-maxcount`, n.ExtendedCost,
{l.name_loc?d AS `name_loc`,}
reqitem1, reqitem2, reqitem3, reqitem4, reqitem5,
reqitemcount1, reqitemcount2, reqitemcount3, reqitemcount4, reqitemcount5,
reqhonorpoints, reqarenapoints
FROM npc_vendor n, ?_icons, ?_item_extended_cost iec, item_template i
{LEFT JOIN (locales_item l) ON l.entry=i.entry AND ?d}
WHERE (iec.reqitem1=?
OR iec.reqitem2=?
OR iec.reqitem3=?
OR iec.reqitem4=?
OR iec.reqitem5=?)
AND iec.extendedcostID=ABS(n.ExtendedCost)
AND i.entry=n.item
AND id=i.displayid
',
$item_cols[2],
($_SESSION['locale'])? $_SESSION['locale']: DBSIMPLE_SKIP,
($_SESSION['locale'])? 1: DBSIMPLE_SKIP,
$item['entry'], $item['entry'], $item['entry'], $item['entry'], $item['entry']
);
if($rows_cf)
{
$item['currencyfor'] = [];
foreach($rows_cf as $row)
{
$_id=$row['entry'];
$item['currencyfor'][$_id] = [];
$item['currencyfor'][$_id] = iteminfo2($row);
$item['currencyfor'][$_id]['maxcount'] = $row['drop-maxcount'];
$item['currencyfor'][$_id]['cost'] = [];
if($row['BuyPrice']>0)
$npc['sells'][$_id]['cost']['money'] = $row['BuyPrice'];
if($row['reqhonorpoints']>0)
$item['currencyfor'][$_id]['cost']['honor'] =/* ($row['A']==1?1:-1)* */$row['reqhonorpoints']; //FIXME_BUG
if($row['reqarenapoints']>0)
$item['currencyfor'][$_id]['cost']['arena'] = $row['reqarenapoints'];
$item['currencyfor'][$_id]['cost']['items'] = [];
for($j=1; $j<=5; $j++)
if(($row['reqitem'.$j]>0) and ($row['reqitemcount'.$j]>0))
{
allitemsinfo($row['reqitem'.$j], 0);
$item['currencyfor'][$_id]['cost']['items'][] = array(
'item' => $row['reqitem'.$j],
'count' => $row['reqitemcount'.$j]
);
}
}
}
unset($rows_cf);
// Добывается из спелла
$drops_sp = drop('spell_loot_template', $item['entry']);
if($drops_sp)
{
$item['containedinspell'] = [];
foreach($drops_sp as $lootid => $drop)
{
$rows = $DB->select('
SELECT s.?#, s.spellID
FROM ?_spell s, ?_spellicons i
WHERE
s.spellID = ?d
AND i.id = s.spellicon
',
$spell_cols[2],
$lootid
);
foreach($rows as $row)
$item['containedinspell'][] = array_merge(spellinfo2($row), $drop);
unset($rows);
}
}
unset($drops_sp);
// Цель критерии
$rows = $DB->select('
SELECT a.id, a.faction, a.name_loc?d AS name, a.description_loc?d AS description, a.category, a.points, s.iconname, z.areatableID
FROM ?_spellicons s, ?_achievementcriteria c, ?_achievement a
LEFT JOIN (?_zones z) ON a.map != -1 AND a.map = z.mapID
WHERE
a.icon = s.id
AND a.id = c.refAchievement
AND c.type IN (?a)
AND c.value1 = ?d
GROUP BY a.id
ORDER BY a.name_loc?d
',
$_SESSION['locale'],
$_SESSION['locale'],
array(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM),
$item['entry'],
$_SESSION['locale']
);
if($rows)
{
$item['criteria_of'] = [];
foreach($rows as $row)
{
allachievementsinfo2($row['id']);
$item['criteria_of'][] = achievementinfo2($row);
}
}
$item['color'] = colorByQuality($item['quality']);
// unlocks
// $locks_row = $DB->selectCol('
// SELECT lockID
// FROM ?_lock
// WHERE
// (type1=1 AND lockproperties1=?d) OR
// (type2=1 AND lockproperties2=?d) OR
// (type3=1 AND lockproperties3=?d) OR
// (type4=1 AND lockproperties4=?d) OR
// (type5=1 AND lockproperties5=?d)
// ',
// $item['entry'], $item['entry'], $item['entry'], $item['entry'], $item['entry']
// );
$smarty->saveCache($cacheKeyPage, $pageData);
}
@@ -843,12 +204,18 @@ if (!$smarty->loadCache($cacheKeyPage, $item))
// menuId 0: Item g_initPath()
// tabId 0: Database g_initHeader()
$smarty->updatePageVars(array(
'book' => $pageData['page']['pagetext'] ? true : false,
'book' => $pageData['pagetext'] ? true : false,
'title' => implode(" - ", $pageData['title']),
'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK),
'tab' => 0,
'type' => TYPE_ITEM,
'typeid' => $_id
'typeId' => $_id,
'reqJS' => array(
'template/js/swfobject.js',
'template/js/profile.js',
'template/js/filters.js',
'?data=weight-presets'
)
));
$smarty->assign('community', CommunityContent::getAll(TYPE_ITEM, $_id)); // comments, screenshots, videos
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$item, ['colon' => Lang::$colon]));

302
pages/items.php Normal file
View File

@@ -0,0 +1,302 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
/*
item upgrade search: !
<a href="javascript:;" class="button-red" onclick="this.blur(); pr_showClassPresetMenu(this, 45498, 2, 17, event);">
<em><b><i>Find upgrades...</i></b><span>Find upgrades...</span></em>
</a>
*/
$cats = Util::extractURLParams($pageParam);
$path = [0, 0];
$title = [Lang::$game['items']];
$filter = ['panel1' => false, 'panel2' => false];
$filterHash = !empty($_GET['filter']) ? '#'.sha1(serialize($_GET['filter'])) : null;
$cacheKey = implode('_', [CACHETYPE_PAGE, TYPE_ITEM, -1, implode('.', $cats).$filterHash, User::$localeId]);
$validCats = array( // if > 0 class => subclass
2 => [15, 13, 0, 4, 7, 6, 10, 1, 5, 8, 2, 18, 3, 16, 19, 20, 14],
4 => array(
0 => true,
1 => [1, 3, 5, 6, 7, 8, 9, 10],
2 => [1, 3, 5, 6, 7, 8, 9, 10],
3 => [1, 3, 5, 6, 7, 8, 9, 10],
4 => [1, 3, 5, 6, 7, 8, 9, 10],
6 => true,
7 => true,
8 => true,
9 => true,
10 => true,
-2 => true, // Rings
-3 => true, // Amulets
-4 => true, // Trinkets
-5 => true, // Off-hand Frills
-6 => true, // Cloaks
-7 => true, // Tabards
-8 => true // Shirts
),
1 => [0, 1, 2, 3, 4, 5, 6, 7, 8],
0 => array(
7 => true,
0 => true,
2 => [1, 2], // elixirs: [Battle, Guardian]
3 => true,
5 => true,
6 => true, // Item Enhancements (Permanent)
-3 => true, // Item Enhancements (Temporary)
1 => true,
4 => true,
8 => true
),
16 => array( // Glyphs by class: [major, minor]
1 => [1, 2],
2 => [1, 2],
3 => [1, 2],
4 => [1, 2],
5 => [1, 2],
6 => [1, 2],
7 => [1, 2],
8 => [1, 2],
9 => [1, 2],
11 => [1, 2]
),
7 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
6 => [2, 3],
11 => [2, 3],
9 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // some of the books to propper professions
3 => [0, 1, 2, 3, 4, 5, 6, 7, 8],
15 => [-2, -7, 0, 1, 2, 3, 4, 5], // -2: armor tokes, -7: flying mounts fuck it .. need major overhaul
10 => true,
12 => true, // todo: contains enchantments
13 => true
);
if (!Util::isValidPage($validCats, $cats))
$smarty->error();
if (!$smarty->loadCache($cacheKey, $pageData, $filter))
{
$conditions = [];
$visibleCols = [];
$hiddenCols = [];
if ($cats[0] !== null)
$path = array_merge($path, $cats);
/*
display available submenu and slot, if applicable
todo: 'type' gets ignored if cats[1] is set
[$strArr, $keyMask]
*/
$type = $slot = [[], null];
if ($cats[0] === null)
{
$slot = [Lang::$item['inventoryType'], null];
asort($slot[0]);
}
else
{
if (isset($cats[1]))
$catList = Lang::$item['cat'][$cats[0]][1][$cats[1]];
else
$catList = Lang::$item['cat'][$cats[0]];
array_unshift($title, is_array($catList) ? $catList[0] : $catList);
switch ($cats[0])
{
case 0:
if (!isset($cats[1]))
$type = [Lang::$item['cat'][0][1], null];
if (!isset($cats[1]) || in_array($cats[1], [6, -3]))
{
$slot = [Lang::$item['inventoryType'], 0x63EFEA];
asort($slot[0]);
}
break;
case 2:
if (!isset($cats[1]))
$type = [Lang::$item['cat'][2][1], null];
$slot = [Lang::$item['inventoryType'], 0x262A000];
asort($slot[0]);
break;
case 4:
if (!isset($cats[1]))
{
$slot = [Lang::$item['inventoryType'], 0x10895FFE];
$type = [Lang::$item['cat'][4][1], null];
}
else if (in_array($cats[1], [1, 2, 3, 4]))
$slot = [Lang::$item['inventoryType'], 0x7EA];
asort($slot[0]);
break;
case 3:
case 16:
if (!isset($cats[1]))
asort($catList[1]);
case 1:
case 7:
case 9:
case 15:
if (!isset($cats[1]))
$type = [$catList[1], null];
break;
}
}
foreach ($type[0] as $k => $str)
if ($str && (!$type[1] || ($type[1] & (1 << $k))))
$filter['type'][$k] = $str;
foreach ($slot[0] as $k => $str)
if ($str && (!$slot[1] || ($slot[1] & (1 << $k))))
$filter['slot'][$k] = $str;
if (isset($filter['slot'][INVTYPE_SHIELD])) // "Off Hand" => "Shield"
$filter['slot'][INVTYPE_SHIELD] = Lang::$item['armorSubClass'][6];
/*
set conditions
*/
$conditions[] = ['i.class', $cats[0]];
if (isset($cats[1]))
$conditions[] = ['i.subClass', $cats[1]];
if (isset($cats[2]))
$conditions[] = ['i.subSubClass', $cats[2]];
$items = new ItemList($conditions, true);
$items->addGlobalsToJscript($smarty);
// recreate form selection
$filter = array_merge($items->filterGetForm('form'), $filter);
$filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
$filter['fi'] = $items->filterGetForm();
// if slot-dropdown is available && Armor && $path points to Armor-Class
if (count($path) == 4 && $cats[0] == 4 && isset($filter['sl']) && !is_array($filter['sl']))
$path[] = $filter['sl'];
$pageData = array(
'page' => [],
'data' => $items->getListviewData(ITEMINFO_JSON),
'title' => $title,
'path' => $path,
'params' => []
);
if ($items->filterGetError())
$pageData['params']['_errors'] = '$1';
if (!empty($filter['upg']))
{
// uogarde-item got deleted by filter
if (empty($pageData['data'][$filter['upg']]))
{
$w = $items->filterGetForm('setWeights', true);
$upgItem = new ItemList(array(['id', $filter['upg']]), false, ['wt' => $w[0], 'wtv' => $w[1]]);
if (!$upgItem->error)
{
$upgItem->addGlobalsToJScript($smarty);
$pageData['data'][$filter['upg']] = $upgItem->getListviewData(ITEMINFO_JSON)[$filter['upg']];
}
}
if (!empty($filter['gb']))
$pageData['params']['customFilter'] = '$fi_filterUpgradeListview';
$pageData['params']['_upgradeIds'] = "$[".$filter['upg']."]";
}
if (!empty($filter['fi']['extraCols']))
$pageData['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, '.(empty($filter['gm']) ? 0 : $filter['gm']).', 0)';
if (!empty($filter['fi']['setWeights']))
{
if (!empty($filter['gm']))
{
$pageData['params']['computeDataFunc'] = '$fi_scoreSockets';
$w = $items->filterGetForm('setWeights', true);
$q = intVal($filter['gm']);
$mask = 14;
$cnd = [10, ['class', ITEM_CLASS_GEM], ['gemColorMask', &$mask, '&'], ['quality', &$q]];
if (!isset($filter['jc']))
$cnd[] = ['itemLimitCategory', 0]; // Jeweler's Gems
$anyColor = new ItemList($cnd, false, ['wt' => $w[0], 'wtv' => $w[1]]);
if (!$anyColor->error)
{
$anyColor->addGlobalsToJScript($smarty);
$pageData['page']['gemScores'][0] = array_values($anyColor->getListviewData(ITEMINFO_GEM));
}
for ($i = 0; $i < 4; $i++)
{
$mask = 1 << $i;
$q = !$i ? 3 : intVal($filter['gm']); // meta gems are always included..
$byColor = new ItemList($cnd, false, ['wt' => $w[0], 'wtv' => $w[1]]);
if (!$byColor->error)
{
$byColor->addGlobalsToJScript($smarty);
$pageData['page']['gemScores'][$mask] = array_values($byColor->getListviewData(ITEMINFO_GEM));
}
}
$pageData['page']['gemScores'] = json_encode($pageData['page']['gemScores'], JSON_NUMERIC_CHECK);
}
$pageData['params']['onBeforeCreate'] = '$fi_initWeightedListview';
$pageData['params']['onAfterCreate'] = '$fi_addUpgradeIndicator';
$pageData['params']['sort'] = "$['-score', 'name']";
if ($items->hasSetFields(['armor']))
$pageData['params']['visibleCols'] = "$['armor']";
$pageData['params']['hiddenCols'] = "$['type', 'source']";
}
// create note if search limit was exceeded; overwriting 'note' is intentional
if ($items->getMatches() > $AoWoWconf['sqlLimit'])
{
$pageData['params']['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_itemsfound', $items->getMatches(), $AoWoWconf['sqlLimit']);
$pageData['params']['_truncated'] = 1;
}
$smarty->saveCache($cacheKey, $pageData, $filter);
}
// sort for dropdown-menus
asort(Lang::$game['ra']);
asort(Lang::$game['cl']);
// menuId 0: Item g_initPath()
// tabId 0: Database g_initHeader()
$smarty->updatePageVars(array(
'title' => implode(' - ', $pageData['title']),
'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK),
'tab' => 0,
'subCat' => $pageParam !== null ? '='.$pageParam : '',
'reqJS' => array(
'template/js/filters.js',
'template/js/swfobject.js',
'?data=weight-presets'
)
));
$smarty->assign('filter', $filter);
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$item, ['colon' => Lang::$colon]));
$smarty->assign('lvData', $pageData);
// load the page
$smarty->display('items.tpl');
?>

View File

@@ -76,15 +76,15 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$pieces = [];
$eqList = [];
$compare = [];
$iList = new ItemList(array(['i.entry', array_keys($iSet->pieceToSet)]));
$iList = new ItemList(array(['i.id', array_keys($iSet->pieceToSet)]));
$data = $iList->getListviewData(ITEMINFO_SUBITEMS | ITEMINFO_JSON);
foreach ($iList->iterate() as $itemId => $__)
{
if (empty($data[$itemId]))
continue;
$slot = $iList->getField('InventoryType');
$disp = $iList->getField('displayid');
$slot = $iList->getField('slot');
$disp = $iList->getField('displayId');
if ($slot && $disp)
$eqList[] = [$slot, $disp];
@@ -93,8 +93,8 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$pieces[] = array(
'id' => $itemId,
'name' => $iList->getField('name', true),
'quality' => $iList->getField('Quality'),
'icon' => $iList->getField('icon'),
'quality' => $iList->getField('quality'),
'icon' => $iList->getField('iconString'),
'json' => json_encode($data[$itemId], JSON_NUMERIC_CHECK)
);
}
@@ -255,7 +255,7 @@ $smarty->updatePageVars(array(
)
));
$smarty->assign('community', CommunityContent::getAll(TYPE_ITEMSET, $_id)); // comments, screenshots, videos
$smarty->assign('lang', array_merge(Lang::$main, Lang::$itemset));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$itemset, ['colon' => Lang::$colon]));
$smarty->assign('lvData', $pageData);
// load the page

View File

@@ -4,14 +4,12 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
require 'includes/class.filter.php';
$filter = [];
$path = [0, 2];
$filterHash = !empty($_GET['filter']) ? sha1(serialize($_GET['filter'])) : -1;
$cacheKey = implode('_', [CACHETYPE_PAGE, TYPE_ITEMSET, -1, $filterHash, User::$localeId]);
if (!$smarty->loadCache($cacheKey, $pageData))
if (!$smarty->loadCache($cacheKey, $pageData, $filter))
{
$itemsets = new ItemsetList([], true); // class selection is via filter, nothing applies here
@@ -23,9 +21,12 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$itemsets->addGlobalsToJscript($smarty);
// recreate form selection
$filter = array_merge($itemsets->filterGetForm('form'), $filter);
$filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
$filter['setCr'] = $itemsets->filterGetSetCriteria();
$filter = array_merge($itemsets->filterGetForm(), $filter);
$filter['fi'] = $itemsets->filterGetForm();
if (!empty($filter['fi']['extraCols']))
$pageData['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
if (isset($filter['cl']))
$path[] = $filter['cl'];
@@ -40,7 +41,7 @@ if (!$smarty->loadCache($cacheKey, $pageData))
if ($itemsets->filterGetError())
$pageData['params']['_errors'] = '$1';
$smarty->saveCache($cacheKey, $pageData);
$smarty->saveCache($cacheKey, $pageData, $filter);
}
@@ -61,7 +62,7 @@ $smarty->updatePageVars(array(
)
));
$smarty->assign('filter', $filter);
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$itemset, Lang::$item));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$itemset, Lang::$item, ['colon' => lang::$colon]));
$smarty->assign('lvData', $pageData);
// load the page

View File

@@ -19,11 +19,11 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$infobox = [];
// level range
$infobox[] = '[li]'.Lang::$game['level'].Lang::$colon.$pet->getField('minLevel').' - '.$pet->getField('maxLevel').'[/li]';
$infobox[] = Lang::$game['level'].Lang::$colon.$pet->getField('minLevel').' - '.$pet->getField('maxLevel');
// exotic
if ($pet->getField('exotic'))
$infobox[] = '[li][url=?spell=53270]'.Lang::$pet['exotic'].'[/url][/li]';
$infobox[] = '[url=?spell=53270]'.Lang::$pet['exotic'].'[/url]';
$pageData = array(
'title' => $pet->getField('name', true),

View File

@@ -157,9 +157,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$items = isset($mountVendors[$_id]) ? DB::Aowow()->selectCol('SELECT item FROM npc_vendor WHERE entry IN (?a)', $mountVendors[$_id]) : 0;
$conditions = array(
['i.entry', $items],
['i.class', 15], // misc
['i.subclass', 5], // mounts
['i.id', $items],
['i.class', ITEM_CLASS_MISC],
['i.subClass', 5], // mounts
);
$mounts = new ItemList($conditions);

View File

@@ -60,7 +60,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
// 2 recipe Items [items] (Books)
$conditions = array(
['RequiredSkill', $_id],
['requiredSkill', $_id],
['class', ITEM_CLASS_RECIPE],
0
);
@@ -92,7 +92,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
if ($created)
{
$created = new ItemList(array(['i.entry', $created], 0));
$created = new ItemList(array(['i.id', $created], 0));
if (!$created->error)
{
$created->addGlobalsToJscript($smarty, GLOBALINFO_SELF);
@@ -112,7 +112,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
// 4a required by [item]
$conditions = array(
['RequiredSkill', $_id],
['requiredSkill', $_id],
['class', ITEM_CLASS_RECIPE, '!'],
0
);

View File

@@ -230,7 +230,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$pageData['page']['reagents'][] = array(
'name' => $spell->relItems->getField('name', true),
'quality' => $spell->relItems->getField('Quality'),
'quality' => $spell->relItems->getField('quality'),
'entry' => $itemId,
'count' => $_[$itemId],
);
@@ -270,9 +270,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
$foo['icon'] = array(
'id' => $spell->relItems->id,
'name' => $spell->relItems->getField('name', true),
'quality' => $spell->relItems->getField('Quality'),
'quality' => $spell->relItems->getField('quality'),
'count' => $effDS + $effBP,
'icon' => $spell->relItems->getField('icon')
'icon' => $spell->relItems->getField('iconString')
);
}
@@ -745,11 +745,11 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
// tab: used by - item
$conditions = array(
'OR', // 6: learn spell
['AND', ['spelltrigger_1', 6, '!'], ['spellid_1', $spell->id]],
['AND', ['spelltrigger_2', 6, '!'], ['spellid_2', $spell->id]],
['AND', ['spelltrigger_3', 6, '!'], ['spellid_3', $spell->id]],
['AND', ['spelltrigger_4', 6, '!'], ['spellid_4', $spell->id]],
['AND', ['spelltrigger_5', 6, '!'], ['spellid_5', $spell->id]]
['AND', ['spellTrigger1', 6, '!'], ['spellId1', $spell->id]],
['AND', ['spellTrigger2', 6, '!'], ['spellId2', $spell->id]],
['AND', ['spellTrigger3', 6, '!'], ['spellId3', $spell->id]],
['AND', ['spellTrigger4', 6, '!'], ['spellId4', $spell->id]],
['AND', ['spellTrigger5', 6, '!'], ['spellId5', $spell->id]]
);
$ubItems = new ItemList($conditions);
@@ -803,7 +803,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
if ($ids)
{
// todo (high): generic loot-processing function
$slItems = new ItemList(array(['i.entry', $ids]));
$slItems = new ItemList(array(['i.id', $ids]));
$slItems->addGlobalsToJscript($smarty);
$lv += $slItems->getListviewData();
@@ -837,7 +837,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
{
$lv[$bar] = $foo[$bar];
$lv[$bar]['percent'] = $extraItem['additionalCreateChance'];
$lv[$bar]['condition'] = json_encode(['type' => TYPE_SPELL, 'typeId' => $extraItem['requiredSpecialization'], 'status' => 2], JSON_NUMERIC_CHECK);
$lv[$bar]['condition'] = ['type' => TYPE_SPELL, 'typeId' => $extraItem['requiredSpecialization'], 'status' => 2];
$smarty->extendGlobalIds(TYPE_SPELL, $extraItem['requiredSpecialization']);
$extraCols[] = 'Listview.extraCols.condition';
@@ -1012,7 +1012,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData))
/* source item
first check source if not item : break
spellid_1 = id OR spellid_1 = "LEAR_SPELL_GENERIC" AND spellid_2 = id
spellId1 = id OR spellId1 = "LEAR_SPELL_GENERIC" AND spellId2 = id
spelltrigger_1/2 = 6
*/

View File

@@ -4,8 +4,6 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
require 'includes/class.filter.php';
$cats = Util::extractURLParams($pageParam);
$path = [0, 1];
$title = [Lang::$game['spells']]; // display max 2 cats, remove this base if nesecary
@@ -202,7 +200,7 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter))
break;
}
$pageData['params']['note'] = '$sprintf(LANG.lvnote_pettalents, "'.$url.'")';
$pageData['params']['note'] = '$$WH.sprintf(LANG.lvnote_pettalents, "'.$url.'")';
}
$pageData['params']['_petTalents'] = 1; // not conviced, this is correct, but .. it works
@@ -409,9 +407,12 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter))
$pageData['params']['hiddenCols'] = '$'.json_encode($hiddenCols);
// recreate form selection
$filter = array_merge($spells->filterGetForm('form'), $filter);
$filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
$filter['setCr'] = $spells->filterGetSetCriteria();
$filter = array_merge($spells->filterGetForm(), $filter);
$filter['fi'] = $spells->filterGetForm();
if (!empty($filter['fi']['extraCols']))
$pageData['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
$smarty->saveCache($cacheKey, $pageData, $filter);
}
@@ -430,7 +431,6 @@ asort(Lang::$game['ra']);
asort(Lang::$game['cl']);
asort(Lang::$game['sc']);
asort(Lang::$game['me']);
Lang::$game['race'] = Util::ucFirst(Lang::$game['race']);
// menuId 1: Spell g_initPath()
// tabId 0: Database g_initHeader()
@@ -444,7 +444,7 @@ $smarty->updatePageVars(array(
)
));
$smarty->assign('filter', $filter);
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement));
$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement, ['colon' => Lang::$colon]));
$smarty->assign('lvData', $pageData);
// load the page

View File

@@ -26,7 +26,7 @@ $smarty->updatePageVars(array(
)
));
$smarty->assign('tcType', $petCalc ? 'pc' : 'tc');
$smarty->assign('lang', Lang::$main);
$smarty->assign('lang', array_merge(Lang::$main, ['colon' => Lang::$colon]));
// load the page
$smarty->display('talent.tpl');

View File

@@ -37,7 +37,7 @@ if (!defined('AOWOW_REVISION'))
16: Listview - template: 'quest', id: 'quests', name: LANG.tab_quests,
17: Listview - template: 'achievement', id: 'achievements', name: LANG.tab_achievements,
18: Listview - template: 'achievement', id: 'statistics', name: LANG.tab_statistics,
todo 19: Listview - template: 'zone', id: 'zones', name: LANG.tab_zones,
19: Listview - template: 'zone', id: 'zones', name: LANG.tab_zones,
todo 20: Listview - template: 'object', id: 'objects', name: LANG.tab_objects,
todo 21: Listview - template: 'faction', id: 'factions', name: LANG.tab_factions,
22: Listview - template: 'skill', id: 'skills', name: LANG.tab_skills,
@@ -331,18 +331,18 @@ if ($searchMask & 0x40)
if (($searchMask & SEARCH_TYPE_JSON) && $type == TYPE_ITEMSET && isset($found['itemset']))
{
$conditions = [['i.entry', array_keys($found['itemset']['pcsToSet'])], 0];
$conditions = [['i.id', array_keys($found['itemset']['pcsToSet'])], 0];
$miscData = ['pcsToSet' => @$found['itemset']['pcsToSet']];
}
else if (($searchMask & SEARCH_TYPE_JSON) && $type == TYPE_ITEM)
{
$conditions = [['i.class', [2, 4]], [User::$localeId ? 'name_loc'.User::$localeId : 'name', $query], $AoWoWconf['sqlLimit']];
$conditions = [['i.class', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR]], ['name_loc'.User::$localeId, $query], $AoWoWconf['sqlLimit']];
$miscData = ['wt' => $_wt, 'wtv' => $_wtv];
}
else
$conditions = [[User::$localeId ? 'name_loc'.User::$localeId : 'name', $query], $maxResults];
$conditions = [['name_loc'.User::$localeId, $query], $maxResults];
$items = new ItemList($conditions, $miscData);
$items = new ItemList($conditions, false, $miscData);
if ($data = $items->getListviewData($searchMask & SEARCH_TYPE_JSON ? (ITEMINFO_SUBITEMS | ITEMINFO_JSON) : 0))
{
@@ -350,8 +350,8 @@ if ($searchMask & 0x40)
foreach ($items->iterate() as $__)
{
$data[$items->id]['param1'] = '"'.$items->getField('icon').'"';
$data[$items->id]['param2'] = $items->getField('Quality');
$data[$items->id]['param1'] = '"'.$items->getField('iconString').'"';
$data[$items->id]['param2'] = $items->getField('quality');
if ($searchMask & SEARCH_TYPE_OPEN)
$data[$items->id]['name'] = substr($data[$items->id]['name'], 1);
@@ -815,7 +815,37 @@ if ($searchMask & 0x20000)
}
// 19 Zones
// if ($searchMask & 0x40000)
if ($searchMask & 0x40000)
{
$conditions = array(
['name_loc'.User::$localeId, $query],
$maxResults
);
$zones = new ZoneList($conditions);
if ($data = $zones->getListviewData())
{
$zones->addGlobalsToJScript($smarty);
$found['zone'] = array(
'type' => TYPE_ZONE,
'appendix' => ' (Zone)',
'matches' => $zones->getMatches(),
'file' => 'zone',
'data' => $data,
'params' => [
'tabs' => '$myTabs',
]
);
if ($zones->getMatches() > $maxResults)
{
$found['zone']['params']['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_zonesfound', $zones->getMatches(), $maxResults);
$found['zone']['params']['_truncated'] = 1;
}
}
}
// 20 Objects
// if ($searchMask & 0x80000)

View File

@@ -142,28 +142,28 @@ if (!defined('AOWOW_REVISION'))
// check if this item can be cast via item -> Source:Item
if (!isset($castItems[$enchantSpells->id]))
$castItems[$enchantSpells->id] = new ItemList([['spellid_1', $enchantSpells->id], ['name', 'Scroll of Enchant%', '!']]); // do not reuse enchantment scrolls
$castItems[$enchantSpells->id] = new ItemList([['spellId1', $enchantSpells->id], ['name', 'Scroll of Enchant%', '!']]); // do not reuse enchantment scrolls
$cI = &$castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy
foreach ($cI->iterate() as $__)
{
$ench['name'][] = $cI->getField('name', true);
$ench['source'][] = -$cI->id;
$ench['icon'] = strTolower($cI->getField('icon'));
$ench['icon'] = strTolower($cI->getField('iconString'));
$ench['slots'][] = $slot;
if ($cI->getField('Quality') > $ench['quality'])
$ench['quality'] = $cI->getField('Quality');
if ($cI->getField('quality') > $ench['quality'])
$ench['quality'] = $cI->getField('quality');
if ($cI->getField('AllowableClass') > 0)
if ($cI->getField('requiredClass') > 0)
{
$ench['classes'] = $cI->getField('AllowableClass');
$ench['jsonequip']['classes'] = $cI->getField('AllowableClass');
$ench['classes'] = $cI->getField('requiredClass');
$ench['jsonequip']['classes'] = $cI->getField('requiredClass');
}
if (!isset($ench['jsonequip']['reqlevel']))
if ($cI->getField('RequiredLevel') > 0)
$ench['jsonequip']['reqlevel'] = $cI->getField('RequiredLevel');
if ($cI->getField('requiredLevel') > 0)
$ench['jsonequip']['reqlevel'] = $cI->getField('requiredLevel');
}
// enchant spell not in use

View File

@@ -37,7 +37,7 @@ if (!defined('AOWOW_REVISION'))
FROM
item_template it,
locales_item li,
?_gemProperties gp,
dbc.gemProperties gp,
?_icons i,
?_itemEnchantment ie
WHERE
@@ -45,7 +45,7 @@ if (!defined('AOWOW_REVISION'))
li.entry = it.entry AND
gp.Id = it.GemProperties AND
i.Id = it.displayid AND
gp.itemEnchantmentId = ie.Id
gp.spellItemEnchantmentId = ie.Id
ORDER BY
it.entry DESC
;

View File

@@ -82,7 +82,7 @@ if (!defined('AOWOW_REVISION'))
]]
];
$rows = DB::Auth()->select('SELECT id AS ARRAY_KEY, name, ?s AS battlegroup, IF(timezone IN (8, 9, 10, 11, 12), "eu", "us") AS region FROM realmlist WHERE allowedSecurityLevel = 0', $AoWoWconf['battlegroup']);
$rows = DB::Auth()->select('SELECT id AS ARRAY_KEY, name, ? AS battlegroup, IF(timezone IN (8, 9, 10, 11, 12), "eu", "us") AS region FROM realmlist WHERE allowedSecurityLevel = 0', $AoWoWconf['battlegroup']);
$str = 'var g_realms = '.json_encode($rows, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE).';';
$handle = fOpen('datasets\\realms', "w");

View File

@@ -3,6 +3,306 @@
if (!defined('AOWOW_REVISION'))
die('illegal access');
/*
-- custom itemSubClass
itemClass: itemSubClass - diff to Client
0: {
6: "Perm. Enhancement",
"-3": "Temp. Enhancement",
},
15: {
"-7": "Flying Mount",
"-6": "Combat Pet",
"-2": "Armor Token",
},
}
DROP TABLE IF EXISTS `aowow_item_stats`;
CREATE TABLE `aowow_item_stats` (
`id` mediumint(8) UNSIGNED NOT NULL ,
`nsockets` mediumint(8) NOT NULL ,
`dmgmin1` mediumint(8) NOT NULL ,
`dmgmax1` mediumint(8) NOT NULL ,
`speed` float(8,2) NOT NULL ,
`dps` float(8,2) NOT NULL ,
`mledmgmin` mediumint(8) NOT NULL ,
`mledmgmax` mediumint(8) NOT NULL ,
`mlespeed` float(8,2) NOT NULL ,
`mledps` float(8,2) NOT NULL ,
`rgddmgmin` mediumint(8) NOT NULL ,
`rgddmgmax` mediumint(8) NOT NULL ,
`rgdspeed` float(8,2) NOT NULL ,
`rgddps` float(8,2) NOT NULL ,
`dmg` float(8,2) NOT NULL ,
`damagetype` mediumint(8) NOT NULL ,
`mana` mediumint(8) NOT NULL ,
`health` mediumint(8) NOT NULL ,
`agi` mediumint(8) NOT NULL ,
`str` mediumint(8) NOT NULL ,
`int` mediumint(8) NOT NULL ,
`spi` mediumint(8) NOT NULL ,
`sta` mediumint(8) NOT NULL ,
`energy` mediumint(8) NOT NULL ,
`rage` mediumint(8) NOT NULL ,
`focus` mediumint(8) NOT NULL ,
`runicpwr` mediumint(8) NOT NULL ,
`defrtng` mediumint(8) NOT NULL ,
`dodgertng` mediumint(8) NOT NULL ,
`parryrtng` mediumint(8) NOT NULL ,
`blockrtng` mediumint(8) NOT NULL ,
`mlehitrtng` mediumint(8) NOT NULL ,
`rgdhitrtng` mediumint(8) NOT NULL ,
`splhitrtng` mediumint(8) NOT NULL ,
`mlecritstrkrtng` mediumint(8) NOT NULL ,
`rgdcritstrkrtng` mediumint(8) NOT NULL ,
`splcritstrkrtng` mediumint(8) NOT NULL ,
`_mlehitrtng` mediumint(8) NOT NULL ,
`_rgdhitrtng` mediumint(8) NOT NULL ,
`_splhitrtng` mediumint(8) NOT NULL ,
`_mlecritstrkrtng` mediumint(8) NOT NULL ,
`_rgdcritstrkrtng` mediumint(8) NOT NULL ,
`_splcritstrkrtng` mediumint(8) NOT NULL ,
`mlehastertng` mediumint(8) NOT NULL ,
`rgdhastertng` mediumint(8) NOT NULL ,
`splhastertng` mediumint(8) NOT NULL ,
`hitrtng` mediumint(8) NOT NULL ,
`critstrkrtng` mediumint(8) NOT NULL ,
`_hitrtng` mediumint(8) NOT NULL ,
`_critstrkrtng` mediumint(8) NOT NULL ,
`resirtng` mediumint(8) NOT NULL ,
`hastertng` mediumint(8) NOT NULL ,
`exprtng` mediumint(8) NOT NULL ,
`atkpwr` mediumint(8) NOT NULL ,
`mleatkpwr` mediumint(8) NOT NULL ,
`rgdatkpwr` mediumint(8) NOT NULL ,
`feratkpwr` mediumint(8) NOT NULL ,
`splheal` mediumint(8) NOT NULL ,
`spldmg` mediumint(8) NOT NULL ,
`manargn` mediumint(8) NOT NULL ,
`armorpenrtng` mediumint(8) NOT NULL ,
`splpwr` mediumint(8) NOT NULL ,
`healthrgn` mediumint(8) NOT NULL ,
`splpen` mediumint(8) NOT NULL ,
`block` mediumint(8) NOT NULL ,
`mastrtng` mediumint(8) NOT NULL ,
`armor` mediumint(8) NOT NULL ,
`armorbonus` mediumint(8) NOT NULL ,
`firres` mediumint(8) NOT NULL ,
`frores` mediumint(8) NOT NULL ,
`holres` mediumint(8) NOT NULL ,
`shares` mediumint(8) NOT NULL ,
`natres` mediumint(8) NOT NULL ,
`arcres` mediumint(8) NOT NULL ,
`firsplpwr` mediumint(8) NOT NULL ,
`frosplpwr` mediumint(8) NOT NULL ,
`holsplpwr` mediumint(8) NOT NULL ,
`shasplpwr` mediumint(8) NOT NULL ,
`natsplpwr` mediumint(8) NOT NULL ,
`arcsplpwr` mediumint(8) NOT NULL ,
PRIMARY KEY (`id`),
INDEX `item` (`id`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE aowow_items LIKE item_template;
INSERT INTO aowow_items SELECT * FROM item_template;
ALTER TABLE `aowow_items`
DROP COLUMN `SoundOverrideSubclass`,
DROP COLUMN `StatsCount`,
DROP COLUMN `Material`,
DROP COLUMN `sheath`,
DROP COLUMN `WDBVerified`,
CHANGE COLUMN `entry` `id` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 FIRST ,
CHANGE COLUMN `subclass` `subClass` tinyint(3) NOT NULL DEFAULT 0 AFTER `class`,
ADD COLUMN `subClassBak` tinyint(3) NOT NULL AFTER `subClass`,
ADD COLUMN `subSubClass` tinyint(3) NOT NULL AFTER `subClassBak`,
CHANGE COLUMN `name` `name_loc0` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' AFTER `subSubClass`,
ADD COLUMN `name_loc2` varchar(255) NOT NULL AFTER `name_loc0`,
ADD COLUMN `name_loc3` varchar(255) NOT NULL AFTER `name_loc2`,
ADD COLUMN `name_loc6` varchar(255) NOT NULL AFTER `name_loc3`,
ADD COLUMN `name_loc8` varchar(255) NOT NULL AFTER `name_loc6`,
CHANGE COLUMN `displayid` `displayId` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `name_loc8`,
ADD COLUMN `iconString` varchar(127) NOT NULL AFTER `displayid`,
CHANGE COLUMN `Quality` `quality` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `displayId`,
CHANGE COLUMN `Flags` `flags` bigint(20) NOT NULL DEFAULT 0 AFTER `quality`,
CHANGE COLUMN `FlagsExtra` `flagsExtra` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `flags`,
CHANGE COLUMN `BuyCount` `buyCount` tinyint(3) UNSIGNED NOT NULL DEFAULT 1 AFTER `flagsExtra`,
CHANGE COLUMN `BuyPrice` `buyPrice` bigint(20) NOT NULL DEFAULT 0 AFTER `buyCount`,
CHANGE COLUMN `SellPrice` `sellPrice` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `buyPrice`,
ADD COLUMN `slot` tinyint(3) NOT NULL AFTER `sellPrice`,
CHANGE COLUMN `InventoryType` `slotBak` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `slot`,
CHANGE COLUMN `AllowableClass` `requiredClass` int(11) NOT NULL DEFAULT '-1' AFTER `slotBak`,
CHANGE COLUMN `AllowableRace` `requiredRace` int(11) NOT NULL DEFAULT '-1' AFTER `requiredClass`,
CHANGE COLUMN `ItemLevel` `itemLevel` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredRace`,
CHANGE COLUMN `RequiredLevel` `requiredLevel` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `itemLevel`,
CHANGE COLUMN `RequiredSkill` `requiredSkill` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredLevel`,
CHANGE COLUMN `RequiredSkillRank` `requiredSkillRank` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredSkill`,
CHANGE COLUMN `requiredspell` `requiredSpell` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredSkillRank`,
CHANGE COLUMN `requiredhonorrank` `requiredHonorRank` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredSpell`,
CHANGE COLUMN `RequiredCityRank` `requiredCityRank` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredHonorRank`,
CHANGE COLUMN `RequiredReputationFaction` `requiredFaction` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredCityRank`,
CHANGE COLUMN `RequiredReputationRank` `requiredFactionRank` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredFaction`,
CHANGE COLUMN `maxcount` `maxCount` int(11) NOT NULL DEFAULT 0 AFTER `requiredFactionRank`,
CHANGE COLUMN `ContainerSlots` `slots` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `stackable`,
CHANGE COLUMN `stat_type1` `statType1` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `slots`,
CHANGE COLUMN `stat_value1` `statValue1` smallint(6) NOT NULL DEFAULT 0 AFTER `statType1`,
CHANGE COLUMN `stat_type2` `statType2` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue1`,
CHANGE COLUMN `stat_value2` `statValue2` smallint(6) NOT NULL DEFAULT 0 AFTER `statType2`,
CHANGE COLUMN `stat_type3` `statType3` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue2`,
CHANGE COLUMN `stat_value3` `statValue3` smallint(6) NOT NULL DEFAULT 0 AFTER `statType3`,
CHANGE COLUMN `stat_type4` `statType4` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue3`,
CHANGE COLUMN `stat_value4` `statValue4` smallint(6) NOT NULL DEFAULT 0 AFTER `statType4`,
CHANGE COLUMN `stat_type5` `statType5` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue4`,
CHANGE COLUMN `stat_value5` `statValue5` smallint(6) NOT NULL DEFAULT 0 AFTER `statType5`,
CHANGE COLUMN `stat_type6` `statType6` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue5`,
CHANGE COLUMN `stat_value6` `statValue6` smallint(6) NOT NULL DEFAULT 0 AFTER `statType6`,
CHANGE COLUMN `stat_type7` `statType7` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue6`,
CHANGE COLUMN `stat_value7` `statValue7` smallint(6) NOT NULL DEFAULT 0 AFTER `statType7`,
CHANGE COLUMN `stat_type8` `statType8` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue7`,
CHANGE COLUMN `stat_value8` `statValue8` smallint(6) NOT NULL DEFAULT 0 AFTER `statType8`,
CHANGE COLUMN `stat_type9` `statType9` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue8`,
CHANGE COLUMN `stat_value9` `statValue9` smallint(6) NOT NULL DEFAULT 0 AFTER `statType9`,
CHANGE COLUMN `stat_type10` `statType10` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `statValue9`,
CHANGE COLUMN `stat_value10` `statValue10` smallint(6) NOT NULL DEFAULT 0 AFTER `statType10`,
CHANGE COLUMN `ScalingStatDistribution` `scalingStatDistribution` smallint(6) NOT NULL DEFAULT 0 AFTER `statValue10`,
CHANGE COLUMN `ScalingStatValue` `scalingStatValue` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `scalingStatDistribution`,
CHANGE COLUMN `dmg_min1` `dmgMin1` float NOT NULL DEFAULT 0 AFTER `scalingStatValue`,
CHANGE COLUMN `dmg_max1` `dmgMax1` float NOT NULL DEFAULT 0 AFTER `dmgMin1`,
CHANGE COLUMN `dmg_type1` `dmgType1` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `dmgMax1`,
CHANGE COLUMN `dmg_min2` `dmgMin2` float NOT NULL DEFAULT 0 AFTER `dmgType1`,
CHANGE COLUMN `dmg_max2` `dmgMax2` float NOT NULL DEFAULT 0 AFTER `dmgMin2`,
CHANGE COLUMN `dmg_type2` `dmgType2` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `dmgMax2`,
MODIFY COLUMN `delay` smallint(5) UNSIGNED NOT NULL DEFAULT 1000 AFTER `dmgType2`,
MODIFY COLUMN `armor` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `delay`,
CHANGE COLUMN `ArmorDamageModifier` `armorDamageModifier` float NOT NULL DEFAULT 0 AFTER `armor`,
MODIFY COLUMN `block` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `armorDamageModifier`,
CHANGE COLUMN `holy_res` `resHoly` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `block`,
CHANGE COLUMN `fire_res` `resFire` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `resHoly`,
CHANGE COLUMN `nature_res` `resNature` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `resFire`,
CHANGE COLUMN `frost_res` `resFrost` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `resNature`,
CHANGE COLUMN `shadow_res` `resShadow` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `resFrost`,
CHANGE COLUMN `arcane_res` `resArcane` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `resShadow`,
CHANGE COLUMN `ammo_type` `ammoType` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `resArcane`,
CHANGE COLUMN `RangedModRange` `rangedModRange` float NOT NULL DEFAULT 0 AFTER `ammoType`,
CHANGE COLUMN `spellid_1` `spellId1` mediumint(8) NOT NULL DEFAULT 0 AFTER `rangedModRange`,
CHANGE COLUMN `spelltrigger_1` `spellTrigger1` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellId1`,
CHANGE COLUMN `spellcharges_1` `spellCharges1` smallint(6) NULL DEFAULT NULL AFTER `spellTrigger1`,
CHANGE COLUMN `spellppmRate_1` `spellppmRate1` float NOT NULL DEFAULT 0 AFTER `spellCharges1`,
CHANGE COLUMN `spellcooldown_1` `spellCooldown1` int(11) NOT NULL DEFAULT '-1' AFTER `spellppmRate1`,
CHANGE COLUMN `spellcategory_1` `spellCategory1` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellCooldown1`,
CHANGE COLUMN `spellcategorycooldown_1` `spellCategoryCooldown1` int(11) NOT NULL DEFAULT '-1' AFTER `spellCategory1`,
CHANGE COLUMN `spellid_2` `spellId2` mediumint(8) NOT NULL DEFAULT 0 AFTER `spellCategoryCooldown1`,
CHANGE COLUMN `spelltrigger_2` `spellTrigger2` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellId2`,
CHANGE COLUMN `spellcharges_2` `spellCharges2` smallint(6) NULL DEFAULT NULL AFTER `spellTrigger2`,
CHANGE COLUMN `spellppmRate_2` `spellppmRate2` float NOT NULL DEFAULT 0 AFTER `spellCharges2`,
CHANGE COLUMN `spellcooldown_2` `spellCooldown2` int(11) NOT NULL DEFAULT '-1' AFTER `spellppmRate2`,
CHANGE COLUMN `spellcategory_2` `spellCategory2` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellCooldown2`,
CHANGE COLUMN `spellcategorycooldown_2` `spellCategoryCooldown2` int(11) NOT NULL DEFAULT '-1' AFTER `spellCategory2`,
CHANGE COLUMN `spellid_3` `spellId3` mediumint(8) NOT NULL DEFAULT 0 AFTER `spellCategoryCooldown2`,
CHANGE COLUMN `spelltrigger_3` `spellTrigger3` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellId3`,
CHANGE COLUMN `spellcharges_3` `spellCharges3` smallint(6) NULL DEFAULT NULL AFTER `spellTrigger3`,
CHANGE COLUMN `spellppmRate_3` `spellppmRate3` float NOT NULL DEFAULT 0 AFTER `spellCharges3`,
CHANGE COLUMN `spellcooldown_3` `spellCooldown3` int(11) NOT NULL DEFAULT '-1' AFTER `spellppmRate3`,
CHANGE COLUMN `spellcategory_3` `spellCategory3` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellCooldown3`,
CHANGE COLUMN `spellcategorycooldown_3` `spellCategoryCooldown3` int(11) NOT NULL DEFAULT '-1' AFTER `spellCategory3`,
CHANGE COLUMN `spellid_4` `spellId4` mediumint(8) NOT NULL DEFAULT 0 AFTER `spellCategoryCooldown3`,
CHANGE COLUMN `spelltrigger_4` `spellTrigger4` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellId4`,
CHANGE COLUMN `spellcharges_4` `spellCharges4` smallint(6) NULL DEFAULT NULL AFTER `spellTrigger4`,
CHANGE COLUMN `spellppmRate_4` `spellppmRate4` float NOT NULL DEFAULT 0 AFTER `spellCharges4`,
CHANGE COLUMN `spellcooldown_4` `spellCooldown4` int(11) NOT NULL DEFAULT '-1' AFTER `spellppmRate4`,
CHANGE COLUMN `spellcategory_4` `spellCategory4` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellCooldown4`,
CHANGE COLUMN `spellcategorycooldown_4` `spellCategoryCooldown4` int(11) NOT NULL DEFAULT '-1' AFTER `spellCategory4`,
CHANGE COLUMN `spellid_5` `spellId5` mediumint(8) NOT NULL DEFAULT 0 AFTER `spellCategoryCooldown4`,
CHANGE COLUMN `spelltrigger_5` `spellTrigger5` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellId5`,
CHANGE COLUMN `spellcharges_5` `spellCharges5` smallint(6) NULL DEFAULT NULL AFTER `spellTrigger5`,
CHANGE COLUMN `spellppmRate_5` `spellppmRate5` float NOT NULL DEFAULT 0 AFTER `spellCharges5`,
CHANGE COLUMN `spellcooldown_5` `spellCooldown5` int(11) NOT NULL DEFAULT '-1' AFTER `spellppmRate5`,
CHANGE COLUMN `spellcategory_5` `spellCategory5` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `spellCooldown5`,
CHANGE COLUMN `spellcategorycooldown_5` `spellCategoryCooldown5` int(11) NOT NULL DEFAULT '-1' AFTER `spellCategory5`,
CHANGE COLUMN `description` `description_loc0` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' AFTER `bonding`,
ADD COLUMN `description_loc2` varchar(255) NOT NULL AFTER `description_loc0`,
ADD COLUMN `description_loc3` varchar(255) NOT NULL AFTER `description_loc2`,
ADD COLUMN `description_loc6` varchar(255) NOT NULL AFTER `description_loc3`,
ADD COLUMN `description_loc8` varchar(255) NOT NULL AFTER `description_loc6`,
CHANGE COLUMN `PageText` `pageTextId` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `description_loc8`,
CHANGE COLUMN `LanguageID` `languageId` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `pageTextId`,
CHANGE COLUMN `PageMaterial` `pageMaterial` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `languageId`,
CHANGE COLUMN `startquest` `startQuest` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `pageMaterial`,
CHANGE COLUMN `lockid` `lockId` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `startQuest`,
CHANGE COLUMN `RandomProperty` `randomProperty` mediumint(8) NOT NULL DEFAULT 0 AFTER `lockId`,
CHANGE COLUMN `RandomSuffix` `randomSuffix` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `randomProperty`,
MODIFY COLUMN `itemset` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `randomSuffix`,
CHANGE COLUMN `MaxDurability` `durability` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `itemset`,
CHANGE COLUMN `Map` `map` smallint(6) NOT NULL DEFAULT 0 AFTER `area`,
CHANGE COLUMN `BagFamily` `bagFamily` mediumint(8) NOT NULL DEFAULT 0 AFTER `map`,
CHANGE COLUMN `TotemCategory` `totemCategory` mediumint(8) NOT NULL DEFAULT 0 AFTER `bagFamily`,
CHANGE COLUMN `socketColor_1` `socketColor1` tinyint(4) NOT NULL DEFAULT 0 AFTER `totemCategory`,
CHANGE COLUMN `socketContent_1` `socketContent1` mediumint(8) NOT NULL DEFAULT 0 AFTER `socketColor1`,
CHANGE COLUMN `socketColor_2` `socketColor2` tinyint(4) NOT NULL DEFAULT 0 AFTER `socketContent1`,
CHANGE COLUMN `socketContent_2` `socketContent2` mediumint(8) NOT NULL DEFAULT 0 AFTER `socketColor2`,
CHANGE COLUMN `socketColor_3` `socketColor3` tinyint(4) NOT NULL DEFAULT 0 AFTER `socketContent2`,
CHANGE COLUMN `socketContent_3` `socketContent3` mediumint(8) NOT NULL DEFAULT 0 AFTER `socketColor3`,
CHANGE COLUMN `GemProperties` `gemColorMask` mediumint(8) NOT NULL DEFAULT 0 AFTER `socketBonus`,
ADD COLUMN `gemEnchantmentId` mediumint(8) NOT NULL AFTER `gemColorMask`,
CHANGE COLUMN `RequiredDisenchantSkill` `requiredDisenchantSkill` smallint(6) NOT NULL DEFAULT '-1' AFTER `gemProperties`,
CHANGE COLUMN `DisenchantID` `disenchantId` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `requiredDisenchantSkill`,
MODIFY COLUMN `duration` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `disenchantId`,
CHANGE COLUMN `ItemLimitCategory` `itemLimitCategory` smallint(6) NOT NULL DEFAULT 0 AFTER `duration`,
CHANGE COLUMN `HolidayId` `holidayId` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `itemLimitCategory`,
CHANGE COLUMN `ScriptName` `scriptName` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' AFTER `holidayId`,
CHANGE COLUMN `FoodType` `foodType` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `scriptName`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- localization
UPDATE aowow_items a, locales_item b SET
a.name_loc2 = b.name_loc2,
a.name_loc3 = b.name_loc3,
a.name_loc6 = b.name_loc6,
a.name_loc8 = b.name_loc8,
a.description_loc2 = b.description_loc2,
a.description_loc3 = b.description_loc3,
a.description_loc6 = b.description_loc6,
a.description_loc8 = b.description_loc8
WHERE a.id = b.entry;
-- merge with gemProperties
UPDATE aowow_items a, dbc.gemProperties b SET
a.gemEnchantmentId = b.spellItemEnchantmentId,
a.gemColorMask = b.colorMask
WHERE a.gemColorMask = b.id;
-- icon
UPDATE aowow_items a, dbc.itemDisplayInfo b SET
a.iconString = b.inventoryIcon1
WHERE a.displayId = b.id;
-- Robes => Chest and Ranged (right) => Ranged
UPDATE aowow_items SET slot = 15 WHERE slotbak = 26;
UPDATE aowow_items SET slot = 5 WHERE slotbak = 20;
-- custom sub-classes
UPDATE aowow_items SET subClassBak = subClass, slot = slotBak;
UPDATE aowow_items SET subclass = IF(
slot = 4, -8, IF( -- shirt
slot = 19, -7, IF( -- tabard
slot = 16, -6, IF( -- cloak
slot = 23, -5, IF( -- held in offhand
slot = 12, -4, IF( -- trinket
slot = 2, -3, IF( -- amulet
slot = 11, -2, subClassBak -- ring
)
)
)
)
)
)
)
WHERE class = 4;
*/
class ItemSetup extends ItemList
{
@@ -14,13 +314,9 @@ class ItemSetup extends ItemList
set_time_limit(300);
$conditions = array(
['i.entry', $start, '>'],
['i.entry', $end, '<='],
[
'OR',
['class', 4],
['class', 2]
],
['i.id', $start, '>'],
['i.id', $end, '<='],
['class', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR]],
0
);
@@ -36,10 +332,10 @@ class ItemSetup extends ItemList
foreach (@$this->json[$this->id] as $k => $v)
{
if (!in_array($k, $this->cols) || !$v)
if (!in_array($k, $this->cols) || !$v || $k == 'id')
continue;
$updateFields[$k] = number_format($v, 2, ',', '');
$updateFields[$k] = number_format($v, 2, '.', '');
}
if (isset($this->itemMods[$this->id]))
@@ -48,15 +344,14 @@ class ItemSetup extends ItemList
{
if (!$v)
continue;
if ($str = Util::$itemMods[$k])
$updateFields[$str] = number_format($v, 2, ',', '');
$updateFields[$str] = number_format($v, 2, '.', '');
}
}
if ($updateFields)
DB::Aowow()->query('REPLACE INTO ?_item_stats (`itemid`, `'.implode('`, `', array_keys($updateFields)).'`) VALUES (?d, "'.implode('", "', $updateFields).'")', $this->id);
DB::Aowow()->query('REPLACE INTO ?_item_stats (`id`, `'.implode('`, `', array_keys($updateFields)).'`) VALUES (?d, "'.implode('", "', $updateFields).'")', $this->id);
}
}
}

View File

@@ -12,6 +12,13 @@ if (!defined('AOWOW_REVISION'))
and i have no idea how to merge the prefixes/suffixes for wotlk-raidsets and arena-sets in gereral onto the name.. at least not for all locales and i'll be damned if i have to skip one
*/
/*
ALTER TABLE `aowow_itemset` ADD COLUMN `npieces` tinyint(3) NOT NULL AFTER `bonusParsed`;
UPDATE `aowow_itemset`SET npieces = (
IF(item1 > 0, 1, 0) + IF(item2 > 0, 1, 0) + IF(item3 > 0, 1, 0) + IF(item4 > 0, 1, 0) + IF(item5 > 0, 1, 0) +
IF(item6 > 0, 1, 0) + IF(item7 > 0, 1, 0) + IF(item8 > 0, 1, 0) + IF(item9 > 0, 1, 0) + IF(item10 > 0, 1, 0)
);
*/
// script terminates self unexpectedly.. i don't know why..; split calls via ajax
if (!isset($_GET['setId']))
@@ -159,7 +166,7 @@ $tagsById = array(
12 => [621,624,625,626,631,632,633,638,639,640,645,648,651,654,655,663,664], // "Tier 4 Raid Set"
13 => [622,627,628,629,634,635,636,641,642,643,646,649,652,656,657,665,666], // "Tier 5 Raid Set",
14 => [620,623,630,637,644,647,650,653,658,659,660,661,662], // "Dungeon Set 3",
15 => [467,468,469,470,471,472,473483,484,485,486,487,488, 908], // "Arathi Basin Set",
15 => [467,468,469,470,471,472,473,483,484,485,486,487,488, 908], // "Arathi Basin Set",
16 => [587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,688,689,691,692,693,694,695,696], // "Level 70 PvP Rare Set",
18 => [668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684], // "Tier 6 Raid Set",
21 => [738,739,740,741,742,743,744,745,746,747,748,749,750,751,752], // "Level 70 PvP Rare Set 2",

View File

@@ -22,7 +22,7 @@
<tr><th>{$lang.quickFacts}</th></tr>
<tr><td><div class="infobox-spacer"></div>
<ul>
{if $lvData.page.points}<li><div>{$lang.points}: <span class="moneyachievement tip" onmouseover="Listview.funcBox.moneyAchievementOver(event)" onmousemove="$WH.Tooltip.cursorUpdate(event)" onmouseout="$WH.Tooltip.hide()">{$lvData.page.points}</span></div></li>{/if}
{if $lvData.page.points}<li><div>{$lang.points}{$lang.colon}<span class="moneyachievement tip" onmouseover="Listview.funcBox.moneyAchievementOver(event)" onmousemove="$WH.Tooltip.cursorUpdate(event)" onmouseout="$WH.Tooltip.hide()">{$lvData.page.points}</span></div></li>{/if}
{foreach from=$lvData.infobox item=info}
<li><div>{$info}</div></li>
{/foreach}
@@ -38,7 +38,7 @@
<tr>
<th>{$smarty.section.i.index+1}.</th>
<td>
{if ($lvData.page.series[i].id == $lvData.page.id)}
{if ($lvData.page.series[i].id == $page.typeId)}
<b>{$lvData.page.series[i].name}</b>
{else}
<div><a href="?achievement={$lvData.page.series[i].id}">{$lvData.page.series[i].name}</a></div>
@@ -67,13 +67,13 @@
$WH.ge('h1-icon-generic').appendChild(Icon.create('{$lvData.page.iconname|escape:"javascript"}', 1));
//]]></script>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: 10, typeId: {$lvData.page.id}, linkColor: 'ffffff00', linkId: '{$lvData.page.id}:&quot;..UnitGUID(&quot;player&quot;)..&quot;:0:0:0:0:0:0:0:0', linkName: '{$lvData.page.name|escape:'javascript'}' {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId}, linkColor: 'ffffff00', linkId: '{$page.typeId}:&quot;..UnitGUID(&quot;player&quot;)..&quot;:0:0:0:0:0:0:0:0', linkName: '{$lvData.page.name|escape:'javascript'}' {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<h1 class="h1-icon">{$lvData.page.name}</h1>
{$lvData.page.description}
{if !empty($lvData.page.criteria)}<h3>{$lang.criteria}{if $lvData.page.count} &ndash; <small><b>{$lang.requires} {$lvData.page.count} {$lang.outOf} {$lvData.page.total_criteria}</b></small>{/if}</h3>{/if}
{if !empty($lvData.page.criteria)}<h3>{$lang.criteria}{if $lvData.page.count} &ndash; <small><b>{$lang.requires} {$lvData.page.count} {$lang.outOf} {$lvData.page.nCriteria}</b></small>{/if}</h3>{/if}
<div style="float: left; margin-right: 25px">
<table class="iconlist">
@@ -107,15 +107,14 @@
</div>
<script type="text/javascript">//<![CDATA[
{foreach from=$lvData.page.icons item=ic}
{foreach from=$lvData.page.icons key=k item=ic}
$WH.ge('iconlist-icon{$ic.itr}').appendChild({$ic.type}.createIcon({$ic.id}, 0, {if isset($ic.count) && $ic.count > 0}{$ic.count}{else}0{/if}));
{/foreach}
//]]></script>
<div style="clear: left"></div>
{* for items *}
{if $lvData.page.itemReward}
{if $lvData.page.itemReward} {* for items *}
<h3>{$lang.rewards}</h3>
{$lang.itemReward}<table class="icontab">
<tr>
@@ -131,8 +130,7 @@
</table>
{/if}
{* for titles *}
{if $lvData.page.titleReward}
{if $lvData.page.titleReward} {* for titles *}
<h3>{$lang.gains}</h3>
<ul>
{foreach from=$lvData.page.titleReward item=i}
@@ -141,6 +139,14 @@
</ul>
{/if}
{if !$lvData.page.titleReward && !$lvData.page.itemReward && $lvData.page.reward}
<h3>{$lang.rewards}</h3>
<ul>
<li><div>{$lvData.page.reward}</div></li>
</ul>
{/if}
<h2>{$lang.related}</h2>
</div>

View File

@@ -1,8 +1,8 @@
{include file='header.tpl'}
<div id="main">
<div id="main-precontents"></div>
<div id="main-contents" class="main-contents">
<div class="main" id="main">
<div class="main-precontents" id="main-precontents"></div>
<div class="main-contents" id="main-contents">
{if !empty($announcements)}
{foreach from=$announcements item=item}
@@ -11,17 +11,17 @@
{/if}
<script type="text/javascript">
g_initPath({$page.path}, {if empty($filter.query)} 0 {else} 1 {/if});
g_initPath({$page.path}, {if empty($filter.query)}0{else}1{/if});
{if isset($filter.query)}
Menu.modifyUrl(Menu.findItem(mn_database, [9]), {ldelim} filter: '+={$filter.query|escape:'quotes'}' {rdelim}, {ldelim} onAppendCollision: fi_mergeFilterParams, onAppendEmpty: fi_setFilterParams, menuUrl: Menu.getItemUrl(Menu.findItem(mn_database, [9])) {rdelim});
{/if}
</script>
<div id="fi" style="display:{if empty($filter.query)}none{else}block{/if};">
<div id="fi" style="display: {if empty($filter.query)}none{else}block{/if};">
<form action="?achievements{$page.subCat}&filter" method="post" name="fi" onsubmit="return fi_submit(this)" onreset="return fi_reset(this)">
<table>
<tr>
<td>{$lang.name}: </td>
<td>{$lang.name}{$lang.colon}</td>
<td colspan="3">
<table><tr>
<td>&nbsp;<input type="text" name="na" size="30" {if isset($filter.na)}value="{$filter.na}"{/if}/></td>
@@ -29,45 +29,52 @@
<td><label for="achievement-ex"><span class="tip" onmouseover="$WH.Tooltip.showAtCursor(event, LANG.tooltip_extendedachievementsearch, 0, 0, 'q')" onmousemove="$WH.Tooltip.cursorUpdate(event)" onmouseout="$WH.Tooltip.hide()">{$lang.extSearch}</span></label></td>
</tr></table>
</td>
</tr>
<tr>
<td class="padded">{$lang.side}: </td>
</tr><tr>
<td class="padded">{$lang.side}{$lang.colon}</td>
<td class="padded">&nbsp;<select name="si">
<option></option>
{foreach from=$lang.si key=i item=str}{if $str}
{foreach from=$lang.si key=i item=str}{if $str}
<option value="{$i}" {if isset($filter.si) && $filter.si == $i}selected{/if}>{$str}</option>
{/if}{/foreach}
{/if}{/foreach}
</select>
</td>
<td class="padded"><table><tr>
<td>&nbsp;&nbsp;&nbsp;{$lang.points}: </td>
<td>&nbsp;&nbsp;&nbsp;{$lang.points}{$lang.colon}</td>
<td>&nbsp;<input type="text" name="minpt" maxlength="2" class="smalltextbox" {if isset($filter.minpt)}value="{$filter.minpt}"{/if}/> - <input type="text" name="maxpt" maxlength="2" class="smalltextbox" {if isset($filter.maxpt)}value="{$filter.maxpt}"{/if}/></td>
</tr></table></td>
</tr>
</table>
<div id="fi_criteria" class="padded criteria"><div></div></div>
<div><a href="javascript:;" id="fi_addcriteria" onclick="fi_addCriterion(this); return false">{$lang.addFilter}</a></div>
<div class="padded2">{$lang.match}: <input type="radio" name="ma" value="" id="ma-0" {if !isset($filter.ma)}checked="checked"{/if} /><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" {if isset($filter.ma)}checked="checked"{/if} /><label for="ma-1">{$lang.oneFilter}</label></div>
<div class="padded2">
<div style="float: right">{$lang.refineSearch}</div>
{$lang.match}{$lang.colon}<input type="radio" name="ma" value="" id="ma-0" {if !isset($filter.ma)}checked="checked"{/if} /><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" {if isset($filter.ma)}checked="checked"{/if} /><label for="ma-1">{$lang.oneFilter}</label>
</div>
<div class="clear"></div>
<div class="padded"></div>
<div class="padded">
<input type="submit" value="{$lang.applyFilter}" />
<input type="reset" value="{$lang.resetForm}" />
<div style="float: right">{$lang.refineSearch}</div>
</div>
</form>
<div class="pad"></div>
</div>
<script type="text/javascript">//<![CDATA[
fi_init('achievements');
{if isset($filter.setCr)}{$filter.setCr}{/if}
{foreach from=$filter.fi item=str}
{$str}
{/foreach}
//]]></script>
<div id="lv-generic" class="listview"></div>
<script type="text/javascript">
{include file='bricks/listviews/achievement.tpl' data=$lvData.data params=$lvData.params}
</script>
<script type="text/javascript">//<![CDATA[
{include file='bricks/listviews/achievement.tpl' data=$lvData.data params=$lvData.params}
//]]></script>
<div class="clear"></div>
</div><!-- main-contents -->

14
template/brb.tpl Normal file
View File

@@ -0,0 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
{include file='head.tpl'}
</head>
<body>
<div style="text-align:center; margin:auto; width:75%; padding-top:150px">
<div style="background-image:url(template/images/logo.png); width:261px; height:119px; margin:auto;"></div>
<h1>Maintenance</h1>
<div style="background-image:url(template/images/maintenance/brbgnomes.jpg); width:618px; height:282px; margin:auto;"></div>
<div style="padding-top:50px">We will be back soon..ish!</div>
</div>
<body>
<html>

View File

@@ -35,9 +35,9 @@
<form action="?screenshot=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return ss_validateForm(this)">
File: <input type="file" name="screenshotfile" style="width: 35%"/><br />
File{$lang.colon}<input type="file" name="screenshotfile" style="width: 35%"/><br />
<div class="pad2"></div>
Caption: <input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Caption{$lang.colon}<input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad2"></div>
<input type="submit" value="Submit" />
@@ -54,9 +54,9 @@
<div class="pad2"></div>
<form action="?video=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return vi_validateForm(this)">
URL: <input type="text" name="videourl" style="width: 35%" /> <small>Supported: YouTube only</small>
URL{$lang.colon}<input type="text" name="videourl" style="width: 35%" /> <small>Supported: YouTube only</small>
<div class="pad2"></div>
Title: <input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Title{$lang.colon}<input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad"></div>
<input type="submit" value="Submit" />

View File

@@ -35,9 +35,9 @@
<form action="?screenshot=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return ss_validateForm(this)">
File: <input type="file" name="screenshotfile" style="width: 35%"/><br />
File{$lang.colon}<input type="file" name="screenshotfile" style="width: 35%"/><br />
<div class="pad2"></div>
Caption: <input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Caption{$lang.colon}<input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad2"></div>
<input type="submit" value="Submit" />
@@ -54,9 +54,9 @@
<div class="pad2"></div>
<form action="?video=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return vi_validateForm(this)">
URL: <input type="text" name="videourl" style="width: 35%" /> <small>Supporté: Youtube seulement</small>
URL{$lang.colon}<input type="text" name="videourl" style="width: 35%" /> <small>Supporté: Youtube seulement</small>
<div class="pad2"></div>
Title: <input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Title{$lang.colon}<input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad"></div>
<input type="submit" value="Submit" />

View File

@@ -36,9 +36,9 @@
<form action="?screenshot=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return ss_validateForm(this)">
Datei: <input type="file" name="screenshotfile" style="width: 35%"/><br />
Datei{$lang.colon}<input type="file" name="screenshotfile" style="width: 35%"/><br />
<div class="pad2"></div>
Titel: <input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, bis zu 200 Zeichen</small><br />
Titel{$lang.colon}<input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, bis zu 200 Zeichen</small><br />
<div class="pad2"></div>
<input type="submit" value="Senden" />
@@ -56,9 +56,9 @@
<div class="pad2"></div>
<form action="?video=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return vi_validateForm(this)">
URL: <input type="text" name="videourl" style="width: 35%" /> <small>Unterstützt: nur YouTube</small>
URL{$lang.colon}<input type="text" name="videourl" style="width: 35%" /> <small>Unterstützt: nur YouTube</small>
<div class="pad2"></div>
Titel: <input type="text" name="videotitle" maxlength="200" /> <small>Optional, bis zu 200 Zeichen</small><br />
Titel{$lang.colon}<input type="text" name="videotitle" maxlength="200" /> <small>Optional, bis zu 200 Zeichen</small><br />
<div class="pad"></div>
<input type="submit" value="Senden" />
@@ -115,7 +115,7 @@
<div class="pad2"></div>
<form action="/video=add&amp;13.7" method="post" enctype="multipart/form-data" onsubmit="return vi_validateForm(this)">
URL: <input type="text" name="videourl" style="width: 35%" /> <small>Unterstützt: nur YouTube</small>
URL{$lang.colon}<input type="text" name="videourl" style="width: 35%" /> <small>Unterstützt: nur YouTube</small>
<div class="pad"></div>
<input type="submit" value="Senden" />

View File

@@ -35,9 +35,9 @@
<form action="?screenshot=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return ss_validateForm(this)">
File: <input type="file" name="screenshotfile" style="width: 35%"/><br />
File{$lang.colon}<input type="file" name="screenshotfile" style="width: 35%"/><br />
<div class="pad2"></div>
Caption: <input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Caption{$lang.colon}<input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad2"></div>
<input type="submit" value="Submit" />
@@ -54,9 +54,9 @@
<div class="pad2"></div>
<form action="?video=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return vi_validateForm(this)">
URL: <input type="text" name="videourl" style="width: 35%" /> <small>Soportado: Sólo YouTube</small>
URL{$lang.colon}<input type="text" name="videourl" style="width: 35%" /> <small>Soportado: Sólo YouTube</small>
<div class="pad2"></div>
Title: <input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Title{$lang.colon}<input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad"></div>
<input type="submit" value="Submit" />

View File

@@ -35,9 +35,9 @@
<form action="?screenshot=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return ss_validateForm(this)">
File: <input type="file" name="screenshotfile" style="width: 35%"/><br />
File{$lang.colon}<input type="file" name="screenshotfile" style="width: 35%"/><br />
<div class="pad2"></div>
Caption: <input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Caption{$lang.colon}<input type="text" name="screenshotcaption" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad2"></div>
<input type="submit" value="Submit" />
@@ -54,9 +54,9 @@
<div class="pad2"></div>
<form action="?video=add&{$page.type}.{$page.typeId}" method="post" enctype="multipart/form-data" onsubmit="return vi_validateForm(this)">
URL: <input type="text" name="videourl" style="width: 35%" /> <small>Поддерживается: только YouTube</small>
URL{$lang.colon}<input type="text" name="videourl" style="width: 35%" /> <small>Поддерживается: только YouTube</small>
<div class="pad2"></div>
Title: <input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
Title{$lang.colon}<input type="text" name="videotitle" maxlength="200" /> <small>Optional, up to 200 characters</small><br />
<div class="pad"></div>
<input type="submit" value="Submit" />

View File

@@ -14,22 +14,13 @@
data:[
{foreach name=i from=$data item=curr}
{ldelim}
{foreach from=$curr key='name' item=val}
{if $name != 'id' && $name != 'name' && $name != 'heroic' && $name != 'mincount' && $name != 'maxcount' && $name != 'group' && $name != 'groupcount' && $name != 'cost'}
{$name}:{$val|@json_encode:$smarty.const.JSON_NUMERIC_CHECK},
{/if}
{/foreach}
name:'{$curr.name|escape:"quotes"}',
{if isset($curr.level)}
level:{$curr.level},
{/if}
{if isset($curr.reqlevel)}
reqlevel:{$curr.reqlevel},
{/if}
classs:{$curr.classs},
subclass:{$curr.subclass},
side:{$curr.side},
{if isset($curr.reqclass)}
reqclass:{$curr.reqclass},
{/if}
{if isset($curr.reqrace)}
reqrace:{$curr.reqrace},
{/if}
{if isset($curr.heroic)}
heroic:1,
{/if}
@@ -38,12 +29,6 @@
stack:[{$curr.mincount},{$curr.maxcount}],
{/if}
{/if}
{if isset($curr.percent)}
percent:{$curr.percent},
{/if}
{if isset($curr.condition)}
condition:{$curr.condition},
{/if}
{if isset($curr.group) and isset($curr.groupcount)}
group:'({$curr.group}){if $curr.groupcount!=1} x{$curr.groupcount}{/if}',
{/if}
@@ -67,23 +52,6 @@
{/if}
],
{/if}
{if isset($curr.displayid)}
displayid:{$curr.displayid},
{/if}
{if isset($curr.nslots)}
nslots:{$curr.nslots},
{/if}
{if isset($curr.dps)}
dps:{$curr.dps},
speed:{$curr.speed},
{/if}
{if isset($curr.armor)}
armor:{$curr.armor},
{/if}
{if isset($curr.slot)}
slot:{$curr.slot},
slotbak:{$curr.slotbak},
{/if}
id:{$curr.id}
{rdelim}
{if $smarty.foreach.i.last}{else},{/if}

View File

@@ -23,7 +23,7 @@
<script type="text/javascript">
$WH.ge('headicon-generic').appendChild(Icon.create('{$lvData.page.icon}', 1));
</script>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="?talent#{$lvData.page.talentCalc}" class="button-red"><em><b><i>{$lang.talentCalc}</i></b><span>{$lang.talentCalc}</span></em></a>
<a href="{if !empty($page.boardUrl)}{$page.boardUrl}{else}javascript:;{/if}" class="button-red{if empty($page.boardUrl)} button-red-disabled{/if}"><em><b><i>{$lang.forum}</i></b><span>{$lang.forum}</span></em></a>

View File

@@ -615,6 +615,72 @@ span.breadcrumb-ellipsis {
right: 2px;
}
/*************/
/* INDICATOR */
/*************/
.indicator {
float: left;
display: block;
background-color: #141414;
border: 1px solid #101010;
padding: 6px 10px;
margin: 0 5px 10px 0;
white-space: nowrap;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.indicator-x {
font-size: 11px;
padding: 10px;
margin-right: -10px;
}
.listview-band-top .indicator { /* Makes it less contrasty */
background-color: #181818;
border-color: #141414;
}
.indicator-mode {
display: block;
margin: 0 auto;
text-align: center;
}
.indicator-mode a {
color: #CCCCCC;
}
.indicator-mode a span {
text-decoration: underline;
color: #FFD100;
}
.indicator-mode a.selected span {
text-decoration: none;
}
.indicator:hover .indicator-mode a span,
.indicator-mode a.selected,
.indicator-mode a.selected span {
color: white;
}
.indicator-mode b { /* Placeholder text */
display: block;
visibility: hidden;
height: 0;
overflow: hidden;
font-weight: bold;
}
/************/
/* INFO BOX */
/************/
.infobox
{
float: right;
@@ -643,6 +709,11 @@ span.breadcrumb-ellipsis {
font-weight: bold;
}
.infobox th small
{
font-weight: normal;
}
.infobox th a
{
text-decoration: none;
@@ -665,10 +736,22 @@ span.breadcrumb-ellipsis {
.infobox ul
{
margin: 0;
padding-left: 13px;
padding: 0;
}
#infobox-sticky img
.infobox li
{
list-style:none;
background: url(../images/ui/redbullet.png) no-repeat left 10px;
padding-left:10px;
}
.infobox li div
{
color: white;
}
#infobox-sticky-ss img, #infobox-sticky-vi img
{
margin-bottom: 4px;
}
@@ -692,6 +775,11 @@ span.breadcrumb-ellipsis {
vertical-align: top;
}
.series td
{
padding: 0;
}
.minibox
{
float: right;
@@ -1096,52 +1184,52 @@ span.icontiny, a.tinyspecial
.iconsmall-socket-meta var
{
background-image: url(../../images/sockets/small/anim_meta.gif);
background-image: url(../../images/sockets/small/anim-meta.gif);
}
.iconsmall-socket-yellow var
{
background-image: url(../../images/sockets/small/anim_yellow.gif);
background-image: url(../../images/sockets/small/anim-yellow.gif);
}
.iconsmall-socket-red var
{
background-image: url(../../images/sockets/small/anim_red.gif);
background-image: url(../../images/sockets/small/anim-red.gif);
}
.iconsmall-socket-blue var
{
background-image: url(../../images/sockets/small/anim_blue.gif);
background-image: url(../../images/sockets/small/anim-blue.gif);
}
.iconsmall-socket-prismatic var
{
background-image: url(../../images/sockets/small/anim_prismatic.gif);
background-image: url(../../images/sockets/small/anim-prismatic.gif);
}
.iconmedium-socket-meta var
{
background-image: url(../../images/sockets/medium/anim_meta.gif);
background-image: url(../../images/sockets/medium/anim-meta.gif);
}
.iconmedium-socket-yellow var
{
background-image: url(../../images/sockets/medium/anim_yellow.gif);
background-image: url(../../images/sockets/medium/anim-yellow.gif);
}
.iconmedium-socket-red var
{
background-image: url(../../images/sockets/medium/anim_red.gif);
background-image: url(../../images/sockets/medium/anim-red.gif);
}
.iconmedium-socket-blue var
{
background-image: url(../../images/sockets/medium/anim_blue.gif);
background-image: url(../../images/sockets/medium/anim-blue.gif);
}
.iconmedium-socket-prismatic var
{
background-image: url(../../images/sockets/medium/anim_prismatic.gif);
background-image: url(../../images/sockets/medium/anim-prismatic.gif);
}
.iconsmall del, .iconmedium del, .iconlarge del
@@ -1851,7 +1939,7 @@ a.star-icon-right span
{
/* Bottom bar */
padding-left: 33px;
background: url(../images/listview-withselected.gif) 11px -35px no-repeat;
background: url(../images/Listview/withselected.gif) 11px -35px no-repeat;
}
.listview-nav
@@ -3129,7 +3217,7 @@ div.h1-icon
padding-bottom: 4px;
}
#tw5ekjm9wex1
#statweight-disclosure
{
padding: 10px;
border: 1px solid #363636;
@@ -3137,7 +3225,7 @@ div.h1-icon
float: left;
}
#lnewwegnwe53 div
#statweight-help div
{
position: absolute;
right: -9px;
@@ -3182,7 +3270,7 @@ a:hover, a.open, .infobox li div, .text b
color: #E5CC80;
}
.text ul li, .infobox li, .comment-body ul li
.text ul li, .comment-body ul li
{
color: #c3030b;
list-style-type: square;
@@ -3206,7 +3294,7 @@ a:hover, a.open, .infobox li div, .text b
top: -2323px;
}
#header, #sidebar, .rcorners, #lnewwegnwe53
#header, #sidebar, .rcorners, #statweight-help
{
position: relative;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

67
template/item.tpl Normal file
View File

@@ -0,0 +1,67 @@
{include file='header.tpl'}
<div class="main" id="main">
<div class="main-precontents" id="main-precontents"></div>
<div class="main-contents" id="main-contents">
{if !empty($announcements)}
{foreach from=$announcements item=item}
{include file='bricks/announcement.tpl' an=$item}
{/foreach}
{/if}
<script type="text/javascript">//<![CDATA[
{include file='bricks/community.tpl'}
var g_pageInfo = {ldelim}type: {$page.type}, typeId: {$page.typeId}, name: '$lvData.name|escape:"quotes"}'{rdelim};
g_initPath({$page.path});
//]]></script>
{include file='bricks/infobox.tpl' info=$lvData.infobox}
<div class="text">
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId}, linkColor: 'ff{$lvData.page.color}', linkId: 'item:{$page.typeId}:0:0:0:0:0:0:0:0', linkName: '{$lvData.page.name}' {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="javascript:;" id="view3D-button" class="button-red{if $lvData.page.displayId}" onclick="this.blur(); ModelViewer.show({ldelim} type: {$page.type}, typeId: {$page.typeId}, displayId: {$lvData.page.displayId}, slot: {$lvData.page.slot} {rdelim}){else} button-red-disabled{/if}"><em><b><i>{$lang.view3D}</i></b><span>{$lang.view3D}</span></em></a>
<a href="javascript:;" class="button-red{if $lvData.buttons}" onclick="this.blur(); su_addToSaved('{$page.typeId}', 1){else} button-red-disabled{/if}"><em><b><i>{$lang.compare}</i></b><span>{$lang.compare}</span></em></a>
<a href="javascript:;" class="button-red{if $lvData.buttons}" onclick="this.blur(); pr_showClassPresetMenu(this, {$page.typeId}, {$lvData.page.class}, {$lvData.page.slot}, event);{else} button-red-disabled{/if}"><em><b><i>{$lang.findUpgrades}</i></b><span>{$lang.findUpgrades}</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
{* <div id="sdlkgnfdlkgndfg4"></div> what the heck.. this div has neither data nor style or script associated with *}
<h1>{$lvData.page.name}</h1>
<div id="icon{$page.typeId}-generic" style="float: left"></div>
<div id="tooltip{$page.typeId}-generic" class="tooltip" style="float: left; padding-top: 1px">
<table><tr><td>{$lvData.tooltip}</td><th style="background-position: top right"></th></tr><tr><th style="background-position: bottom left"></th><th style="background-position: bottom right"></th></tr></table>
</div>
<div style="clear: left"></div>
<script type="text/javascript">
$WH.ge('icon{$page.typeId}-generic').appendChild(Icon.create('{$lvData.page.icon}', 2, 0, 0, {$lvData.page.stack}));
$WH.Tooltip.fix($WH.ge('tooltip{$page.typeId}-generic'), 1, 1);
</script>
{if !empty($lvData.page.pagetext)}
<h3>Content</h3>
<div id="book-generic"></div>
{strip}
<script>
new Book({ldelim} parent: 'book-generic', pages: [
{foreach from=$lvData.page.pagetext item=pagetext name=j}
'{$pagetext|escape:"javascript"}'
{if $smarty.foreach.j.last}{else},{/if}
{/foreach}
]{rdelim})
</script>
{/strip}
{/if}
<h2>{$lang.related}</h2>
</div>
{include file='bricks/tabsRelated.tpl' tabs=$lvData.relTabs}
{include file='bricks/contribute.tpl'}
</div><!-- main-contents -->
</div><!-- main -->
{include file='footer.tpl'}

184
template/items.tpl Normal file
View File

@@ -0,0 +1,184 @@
{include file='header.tpl'}
<div class="main" id="main">
<div class="main-precontents" id="main-precontents"></div>
<div class="main-contents" id="main-contents">
{if !empty($announcements)}
{foreach from=$announcements item=item}
{include file='bricks/announcement.tpl' an=$item}
{/foreach}
{/if}
<script type="text/javascript">
g_initPath({$page.path}, {if empty($filter.query)}0{else}1{/if});
{if isset($filter.query)}
Menu.modifyUrl(Menu.findItem(mn_database, [0]), {ldelim} filter: '+={$filter.query|escape:'quotes'}' {rdelim}, {ldelim} onAppendCollision: fi_mergeFilterParams, onAppendEmpty: fi_setFilterParams, menuUrl: Menu.getItemUrl(Menu.findItem(mn_database, [0])) {rdelim});
{/if}
</script>
<div id="fi" style="display: {if empty($filter.query)}none{else}block{/if}">
<form action="?items{$page.subCat}&filter" method="post" name="fi" onsubmit="return fi_submit(this)" onreset="return fi_reset(this)">
<div class="rightpanel">
<div style="float: left">{$lang._quality}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['qu[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="qu[]" size="7" multiple="multiple" class="rightselect" style="background-color: #181818">
{foreach from=$lang.quality key=k item=str}
<option value="{$k}" class="q{$k}"{if isset($filter.qu) && in_array($k, (array)$filter.qu)} selected{/if}>{$str}</option>
{/foreach}
</select>
</div>
{if !empty($filter.slot)}
<div class="rightpanel2">
<div style="float: left">{$lang.slot}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['sl[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="sl[]" size="{if $filter.slot|@count < 7}{$filter.slot|@count}{else}7{/if}" multiple="multiple" class="rightselect">
{foreach from=$filter.slot key=k item=str}
<option value="{$k}"{if isset($filter.sl) && in_array($k, (array)$filter.sl)} selected{/if}>{$str}</option>
{/foreach}
</select>
</div>
{/if}
{if !empty($filter.type)}
<div class="rightpanel2">
<div style="float: left">{$lang.type}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['ty[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="ty[]" size="{if $filter.type|@count < 7}{$filter.type|@count}{else}7{/if}" multiple="multiple" class="rightselect">
{foreach from=$filter.type key=k item=str}
<option value="{$k}"{if isset($filter.ty) && in_array($k, (array)$filter.ty)} selected{/if}>{$str}</option>
{/foreach}
</select>
</div>
{/if}
<table>
<tr>
<td>{$lang.name}{$lang.colon}</td>
<td colspan="2">&nbsp;<input type="text" name="na" size="30" {if isset($filter.na)}value="{$filter.na|escape:'html'}" {/if}/></td>
<td></td>
</tr><tr>
<td class="padded">Level{$lang.colon}</td>
<td class="padded">&nbsp;<input type="text" name="minle" maxlength="3" class="smalltextbox2" {if isset($filter.minle)}value="{$filter.minle}" {/if}/> - <input type="text" name="maxle" maxlength="3" class="smalltextbox2" {if isset($filter.maxle)}value="{$filter.maxle}" {/if}/></td>
<td class="padded">
<table>
<tr>
<td>&nbsp;&nbsp;&nbsp;{$lang._reqLevel}{$lang.colon}</td>
<td>&nbsp;<input type="text" name="minrl" maxlength="2" class="smalltextbox" {if isset($filter.minrl)}value="{$filter.minrl}" {/if}/> - <input type="text" name="maxrl" maxlength="2" class="smalltextbox" {if isset($filter.maxrl)}value="{$filter.maxrl}" {/if}/></td>
</tr>
</table>
</td>
<td></td>
</tr><tr>
<td class="padded">{$lang.usableBy}{$lang.colon}</td>
<td class="padded">&nbsp;<select name="si" style="margin-right: 0.5em">
<option></option>
{foreach from=$lang.si key=k item=str}
<option value="{$k}"{if isset($filter.si) && $k == $filter.si} selected{/if}>{$str}</option>
{/foreach}
</select></td>
<td class="padded">
&nbsp;<select name="ub">
<option></option>
{foreach from=$lang.cl key=k item=str}{if $str}
<option value="{$k}"{if isset($filter.ub) && $k == $filter.ub} selected{/if}>{$str}</option>
{/if}{/foreach}
</select></td>
</td>
</tr>
</table>
<div id="fi_criteria" class="padded criteria"><div></div></div>
<div><a href="javascript:;" id="fi_addcriteria" onclick="fi_addCriterion(this); return false">{$lang.addFilter}</a></div>
<div class="padded2">
<div style="float: right">{$lang.refineSearch}</div>
{$lang.match}{$lang.colon}<input type="radio" name="ma" value="" id="ma-0" {if !isset($filter.ma)}checked="checked" {/if}/><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" {if isset($filter.ma)}checked="checked" {/if}/><label for="ma-1">{$lang.oneFilter}</label>
</div>
<div class="pad3"></div>
<div class="text">
<h3 class="first"><a id="fi_weight_toggle" href="javascript:;" class="disclosure-off" onclick="return g_disclose($WH.ge('statweight-disclosure'), this)">{$lang.createWS}</a></h3>
</div>
<div id="statweight-disclosure" style="display: none">
<div id="statweight-help">
<div><a href="?help=stat-weighting" target="_blank" id="statweight-help" class="icon-help" style="font-size: 13px; font-weight: normal; background: url(template/images/help.gif) no-repeat left center; padding-left: 20px">{$lang.help}</a></div>
</div>
<table>
<tr>
<td>{$lang.preset}{$lang.colon}</td>
<td id="fi_presets"></td>
</tr>
<tr>
<td class="padded">{$lang.gems}{$lang.colon}</td>
<td class="padded">
<select name="gm">
<option {if !isset($filter.gm)}selected{/if}></option>
<option value="2" {if isset($filter.gm) && $filter.gm == 2}selected{/if}>{$lang.quality[2]}</option>
<option value="3" {if isset($filter.gm) && $filter.gm == 3}selected{/if}>{$lang.quality[3]}</option>
<option value="4" {if isset($filter.gm) && $filter.gm == 4}selected{/if}>{$lang.quality[4]}</option>
</select>
&nbsp; <input type="checkbox" name="jc" value="1" id="jc" /><label for="jc">{$lang.jcGemsOnly|sprintf:' class="tip" onmouseover="$WH.Tooltip.showAtCursor(event, LANG.tooltip_jconlygems, 0, 0, \'q\')" onmousemove="$WH.Tooltip.cursorUpdate(event)" onmouseout="$WH.Tooltip.hide()"'}</label>
</td>
</tr>
</table>
<div id="fi_weight" class="criteria" style="display: none"><div></div></div>
<div><a href="javascript:;" id="fi_addweight" onclick="fi_addCriterion(this); return false" style="display: none">{$lang.addWeight}</a></div>
<div class="pad2"></div>
<small>{$lang.cappedHint}</small>
</div>
<div class="clear"></div>
<div class="padded">{$lang.groupBy}{$lang.colon}
{foreach from=$lang.gb key=k item=str}
{if $k == 0}
<input type="radio" name="gb" value="" id="gb-{$str[1]}" {if empty($filter.gb)}checked="checked" {/if}/><label for="gb-{$str[1]}">{$str[0]}</label>
{else}
<input type="radio" name="gb" value="{$k}" id="gb-{$str[1]}" {if !empty($filter.gb) && $filter.gb == $k}checked="checked" {/if}/><label for="gb-{$str[1]}">{$str[0]}</label>
{/if}
{/foreach}
</div>
<div class="clear"></div>
<div class="padded">
<input type="submit" value="{$lang.applyFilter}" />
<input type="reset" value="{$lang.resetForm}" />
</div>
<input type="hidden" name="upg"{if !empty($filter.upg)} value="{$filter.upg}"{/if}/>
<div class="pad"></div>
</form>
<div class="pad"></div>
</div>
<script type="text/javascript">//<![CDATA[
fi_init('items');
{foreach from=$filter.fi item=str}
{$str}
{/foreach}
//]]></script>
<div id="lv-generic" class="listview"></div>
<script type="text/javascript">//<![CDATA[
{if !empty($lvData.page.gemScores)}var fi_gemScores = {$lvData.page.gemScores};{/if}
{include file='bricks/listviews/item.tpl' data=$lvData.data params=$lvData.params}
//]]></script>
<div class="clear"></div>
</div><!-- main-contents -->
</div><!-- main -->
{include file='footer.tpl'}

View File

@@ -19,10 +19,10 @@
{include file='bricks/infobox.tpl' info=$lvData.infobox}
<div class="text">
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: 4, typeId: {$lvData.page.id} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="javascript:;" id="view3D-button" class="button-red" onclick="this.blur(); ModelViewer.show({ldelim} type: 4, typeId: {$lvData.page.id}, equipList: {$lvData.view3D} {rdelim})"><em><b><i>{$lang.view3D}</i></b><span>{$lang.view3D}</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="javascript:;" id="view3D-button" class="button-red" onclick="this.blur(); ModelViewer.show({ldelim} type: {$page.type}, typeId: {$page.typeId}, equipList: {$lvData.view3D} {rdelim})"><em><b><i>{$lang.view3D}</i></b><span>{$lang.view3D}</span></em></a>
<a href="javascript:;" class="button-red" onclick="this.blur(); su_addToSaved('{':'|implode:$lvData.compare.items}', {$lvData.compare.qty})"><em><b><i>{$lang.compare}</i></b><span>{$lang.compare}</span></em></a>
<a href="{if $lvData.page.id > 0}http://old.wowhead.com/?{$query[0]}={$query[1]}{else}javascript:;{/if}" class="button-red{if $lvData.page.id < 0} button-red-disabled{/if}"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="{if $page.typeId > 0}{$wowhead}{else}javascript:;{/if}" class="button-red{if $lvData.page.id < 0} button-red-disabled{/if}"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<h1>{$lvData.page.name}</h1>
{include file='bricks/article.tpl'}
@@ -56,7 +56,7 @@
{$lang._conveyBonus}
<ul>
{section name=i loop=$lvData.spells}
<li><div>{$lvData.spells[i].bonus} {$lang._pieces}: <a href="?spell={$lvData.spells[i].id}">{$lvData.spells[i].desc}</a></div></li>
<li><div>{$lvData.spells[i].bonus} {$lang._pieces}{$lang.colon}<a href="?spell={$lvData.spells[i].id}">{$lvData.spells[i].desc}</a></div></li>
{/section}
</ul>

View File

@@ -1,8 +1,8 @@
{include file='header.tpl'}
<div id="main">
<div id="main-precontents"></div>
<div id="main-contents" class="main-contents">
<div class="main" id="main">
<div class="main-precontents" id="main-precontents"></div>
<div class="main-contents" id="main-contents">
{if !empty($announcements)}
{foreach from=$announcements item=item}
@@ -12,66 +12,65 @@
<script type="text/javascript">
g_initPath({$page.path}, {if empty($filter.query)} 0 {else} 1 {/if});
{if isset($filter.query)}
Menu.modifyUrl(Menu.findItem(mn_database, [2]), {ldelim} filter: '+={$filter.query|escape:'quotes'}' {rdelim}, {ldelim} onAppendCollision: fi_mergeFilterParams {rdelim});
{if !empty($filter.query)}
Menu.modifyUrl(Menu.findItem(mn_database, [2]), {ldelim} filter: '+={$filter.query|escape:'quotes'}' {rdelim}, {ldelim} onAppendCollision: fi_mergeFilterParams, onAppendEmpty: fi_setFilterParams, menuUrl: Menu.getItemUrl(Menu.findItem(mn_database, [2])) {rdelim});
{/if}
</script>
<div id="fi" style="display:{if empty($filter.query)}none{else}block{/if};">
<form action="?itemsets&filter" method="post" name="fi" onsubmit="return fi_submit(this)" onreset="return fi_reset(this)">
<div class="rightpanel">
<div style="float: left">Quality: </div><small><a href="javascript:;" onclick="document.forms['fi'].elements['qu[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div style="float: left">{$lang._quality}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['qu[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="qu[]" size="7" multiple="multiple" class="rightselect" style="background-color: #181818">
{foreach from=$lang.quality key=i item=str}{if $str}
{foreach from=$lang.quality key=i item=str}{if $str}
<option value="{$i}" class="q{$i}" {if isset($filter.qu) && in_array($i, (array)$filter.qu)}selected{/if}>{$str}</option>
{/if}{/foreach}
{/if}{/foreach}
</select>
</div>
<div class="rightpanel2">
<div style="float: left">Type: </div><small><a href="javascript:;" onclick="document.forms['fi'].elements['ty[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div style="float: left">{$lang.type}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['ty[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="ty[]" size="7" multiple="multiple" class="rightselect">
{foreach from=$lang.types key=i item=str}{if $str}
{foreach from=$lang.types key=i item=str}{if $str}
<option value="{$i}" {if isset($filter.ty) && in_array($i, (array)$filter.ty)}selected{/if}>{$str}</option>
{/if}{/foreach}
{/if}{/foreach}
</select>
</div>
<table>
<tr>
<td>{$lang.name}: </td>
<td>{$lang.name}{$lang.colon}</td>
<td colspan="3">&nbsp;<input type="text" name="na" size="30" {if isset($filter.na)}value="{$filter.na}" {/if}/></td>
</tr><tr>
<td class="padded">Level: </td>
<td class="padded">{$lang.level}{$lang.colon}</td>
<td class="padded">&nbsp;<input type="text" name="minle" maxlength="3" class="smalltextbox2"{if isset($filter.minle)} value="{$filter.minle}"{/if} /> - <input type="text" name="maxle" maxlength="3" class="smalltextbox2"{if isset($filter.maxle)} value="{$filter.maxle}"{/if} /></td>
<td class="padded" width="100%">
<table><tr>
<td>&nbsp;&nbsp;&nbsp;Required level: </td>
<td>&nbsp;&nbsp;&nbsp;{$lang._reqLevel}{$lang.colon}</td>
<td>&nbsp;<input type="text" name="minrl" maxlength="2" class="smalltextbox"{if isset($filter.minrl)} value="{$filter.minrl}"{/if} /> - <input type="text" name="maxrl" maxlength="2" class="smalltextbox"{if isset($filter.maxrl)} value="{$filter.maxrl}"{/if} /></td>
</tr></table>
</td>
</tr><tr>
<td class="padded">Class: </td>
<td class="padded">
<select name="cl">
<td class="padded">{$lang.class|ucfirst}{$lang.colon}</td>
<td class="padded">&nbsp;<select name="cl">
<option></option>
{foreach from=$lang.cl key=i item=str}{if $str}
{foreach from=$lang.cl key=i item=str}{if $str}
<option value="{$i}" {if isset($filter.cl) && $filter.cl == $i}selected{/if}>{$str}</option>
{/if}{/foreach}
</select>
</td>
{/if}{/foreach}
</select></td>
<td class="padded">
<table><tr>
<td>&nbsp;&nbsp;&nbsp;Tag: </td>
<td>&nbsp;&nbsp;&nbsp;{$lang._tag}{$lang.colon}</td>
<td>&nbsp;<select name="ta">
<option></option>
{foreach from=$lang.notes key=i item=str}{if $str}
{foreach from=$lang.notes key=i item=str}{if $str}
<option value="{$i}" {if isset($filter.ta) && $filter.ta == $i}selected{/if}>{$str}</option>
{/if}{/foreach}
</select>
</td>
{/if}{/foreach}
</select></td>
</tr></table>
</td>
</tr>
@@ -79,12 +78,18 @@
<div id="fi_criteria" class="padded criteria"><div></div></div>
<div><a href="javascript:;" id="fi_addcriteria" onclick="fi_addCriterion(this); return false">{$lang.addFilter}</a></div>
<div class="padded2">{$lang.match}: <input type="radio" name="ma" value="" id="ma-0" {if !isset($filter.ma)}checked="checked"{/if} /><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" {if isset($filter.ma)}checked="checked"{/if} /><label for="ma-1">{$lang.oneFilter}</label></div>
<div class="padded2">
<div style="float: right">{$lang.refineSearch}</div>
{$lang.match}{$lang.colon}<input type="radio" name="ma" value="" id="ma-0" {if !isset($filter.ma)}checked="checked"{/if} /><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" {if isset($filter.ma)}checked="checked"{/if} /><label for="ma-1">{$lang.oneFilter}</label>
</div>
<div class="clear"></div>
<div class="padded"></div>
<input type="submit" value="{$lang.applyFilter}" /><input type="reset" value="{$lang.resetForm}" /><div style="float: right">{$lang.refineSearch}</div>
<div class="padded">
<input type="submit" value="{$lang.applyFilter}" />
<input type="reset" value="{$lang.resetForm}" />
</div>
</form>
<div class="pad"></div>
@@ -92,13 +97,15 @@
<script type="text/javascript">//<![CDATA[
fi_init('itemsets');
{if isset($filter.setCr)}{$filter.setCr}{/if}
{foreach from=$filter.fi item=str}
{$str}
{/foreach}
//]]></script>
<div id="lv-generic" class="listview"></div>
<script type="text/javascript">
<script type="text/javascript">//<![CDATA[
{include file='bricks/listviews/itemset.tpl' data=$lvData.data params=$lvData.params}
</script>
//]]></script>
<div class="clear"></div>
</div>

View File

@@ -88,7 +88,7 @@ var fi_filters = {
{ id: 121, name: 'sepresistances' },
{ id: 25, name: 'arcres', type: 'num' },
{ id: 26, name: 'firres', type: 'num' },
{ id: 28, name: 'frores', ype: 'num' },
{ id: 28, name: 'frores', type: 'num' },
{ id: 30, name: 'holres', type: 'num' },
{ id: 27, name: 'natres', type: 'num' },
{ id: 29, name: 'shares', type: 'num' },
@@ -194,7 +194,7 @@ var fi_filters = {
{ id: 4, name: 'bonustext', type: 'str' },
{ id: 5, name: 'heroic', type: 'yn' },
{ id: 6, name: 'relatedevent', type: 'event-any+none' },
{ id: 2, name: 'id', type: 'num' },
{ id: 2, name: 'id', type: 'num', before: 'name' },
{ id: 9999,name: 'sepcommunity' },
{ id: 8, name: 'hascomments', type: 'yn' },
@@ -215,7 +215,7 @@ var fi_filters = {
{ id: 8, name: 'endsquest', type: 'side' },
{ id: 34, name: 'usemodel', type: 'str-small' },
{ id: 35, name: 'useskin', type: 'str' },
{ id: 37, name: 'id', type: 'num' },
{ id: 37, name: 'id', type: 'num', before: 'name' },
{ id: 14, name: 'seploot' },
{ id: 12, name: 'averagemoneydropped', type: 'num' },
@@ -253,7 +253,7 @@ var fi_filters = {
objects: [
{ id: 8, name: 'sepgeneral' },
{ id: 1, name: 'foundin', type: 'zone' },
{ id: 15, name: 'id', type: 'num' },
{ id: 15, name: 'id', type: 'num', before: 'name' },
{ id: 16, name: 'relatedevent', type: 'event-any+none' },
{ id: 7, name: 'requiredskilllevel', type: 'num' },
{ id: 2, name: 'startsquest', type: 'side' },
@@ -277,7 +277,7 @@ var fi_filters = {
{ id: 27, name: 'daily', type: 'yn' },
{ id: 28, name: 'weekly', type: 'yn' },
{ id: 29, name: 'repeatable', type: 'yn' },
{ id: 30, name: 'id', type: 'num' },
{ id: 30, name: 'id', type: 'num', before: 'name' },
{ id: 44, name: 'countsforloremaster_stc', type: 'yn' },
{ id: 9, name: 'objectiveearnrepwith', type: 'faction-any+none' },
{ id: 33, name: 'relatedevent', type: 'event-any+none' },
@@ -319,7 +319,7 @@ var fi_filters = {
{ id: 6, name: 'sepgeneral' },
{ id: 1, name: 'manaenergyragecost', type: 'num' },
{ id: 2, name: 'prcntbasemanarequired', type: 'num' },
{ id: 14, name: 'id', type: 'num' },
{ id: 14, name: 'id', type: 'num', before: 'name' },
{ id: 15, name: 'icon', type: 'str' },
{ id: 10, name: 'firstrank', type: 'yn' },
{ id: 20, name: 'hasreagents', type: 'yn' },
@@ -344,7 +344,7 @@ var fi_filters = {
{ id: 3, name: 'rewardtext', type: 'str' },
{ id: 4, name: 'location', type: 'zone' },
{ id: 10, name: 'icon', type: 'str' },
{ id: 9, name: 'id', type: 'num' },
{ id: 9, name: 'id', type: 'num', before: 'name' },
{ id: 11, name: 'relatedevent', type: 'event-any+none' },
{ id: 8, name: 'sepseries' },
@@ -413,7 +413,7 @@ function fi_toggle() {
if (b) {
// Set focus on first textbox
d.firstChild.nodeValue = LANG.fihide;
c = (c.parentNode.tagName == 'FORM' ? c.parentNode: $WH.gE(c, 'form')[0]);
c = (c.parentNode.tagName == 'FORM' ? c.parentNode : $WH.gE(c, 'form')[0]);
c = c.elements.na ? c.elements.na: c.elements.ti;
c.focus();
c.select();
@@ -477,7 +477,6 @@ function fi_initWeightedListview() {
}
if (this._upgradeIds && this._minScore) {
setTimeout(Listview.headerFilter.bind(this, this.columns[this.columns.length - 1], '>=' + this._minScore), 1);
this._maxScore = this._minScore; // Makes percentages relative to upgraded item
}
}
@@ -1449,7 +1448,7 @@ function fi_scoreSockets(item) {
this._maxScore = item.score;
}
if(this._upgradeIds && $WH.in_array(this._upgradeIds, item.id) != -1) {
if (this._upgradeIds && $WH.in_array(this._upgradeIds, item.id) != -1) {
this._minScore = item.score;
item.upgraded = 1;
}
@@ -1666,6 +1665,17 @@ function fi_getExtraCols(wt, gm, pu) {
}
}
// Fix display of money columns
if (a.name.indexOf('money') != -1) {
b.compute = function (item, td) {
td.innerHTML = g_getMoneyHtml(item[a.name] || 0);
}
}
if (a.name == 'id') {
b.width = '5%';
}
res.push(b);
}
}

View File

@@ -7207,6 +7207,10 @@ Listview.templates = {
span: 2,
value: 'name',
compute: function(item, td, tr) {
if (item.upgraded) {
tr.className = 'upgraded';
}
var i = $WH.ce('td');
i.style.width = '1px';
i.style.padding = '0';
@@ -7727,7 +7731,7 @@ Listview.templates = {
for (var i = 0, len = this.data.length; i < len; ++i) {
var item = this.data[i];
if ((item.slot > 0 && item.slot != 18) || ($WH.in_array(ModelViewer.validSlots, item.slotbak) >= 0 && item.displayid > 0) || item.modelviewer) { // Equippable, and not a bag, or has a model
if ((item.slot > 0 && item.slot != 18) || (item.classs == 3 && item.subclass != 7) || ($WH.in_array(ModelViewer.validSlots, item.slotbak) >= 0 && item.displayid > 0) || item.modelviewer) { // Equippable, and not a bag, or has a model
++nComparable;
}
else {
@@ -7736,7 +7740,7 @@ Listview.templates = {
}
if (nComparable > 0) {
this.mode = 1;
this.mode = Listview.MODE_CHECKBOX;
this._nComparable = nComparable;
}
},
@@ -7746,6 +7750,10 @@ Listview.templates = {
return;
}
if (this.mode != Listview.MODE_CHECKBOX) {
return;
}
var
iCompare = $WH.ce('input'),
iViewIn3d = $WH.ce('input'),
@@ -17447,8 +17455,8 @@ $WH.cO(g_holidays, {
});
function g_getIngameLink(color, id, name) {
// prompt(LANG.prompt_ingamelink, '/script DEFAULT_CHAT_FRAME:AddMessa$WH.ge("\\124c' + a + "\\124H" + c + "\\124h[" + b + ']\\124h\\124r");')
return '/script DEFAULT_CHAT_FRAME:AddMessa$WH.ge("\\124c' + color + '\\124H' + id + '\\124h[' + name + ']\\124h\\124r");';
// prompt(LANG.prompt_ingamelink, '/script DEFAULT_CHAT_FRAME:AddMessage("\\124c' + a + "\\124H" + c + "\\124h[" + b + ']\\124h\\124r");')
return '/script DEFAULT_CHAT_FRAME:AddMessage("\\124c' + color + '\\124H' + id + '\\124h[' + name + ']\\124h\\124r");';
}
/*

View File

@@ -170,7 +170,7 @@ var mn_items = [
[3,"Ingenieurskunst",,,{tinyIcon:"trade_engineering"}],
[7,"Erste Hilfe",,,{tinyIcon:"spell_holy_sealofsacrifice"}],
[9,"Angeln",,,{tinyIcon:"trade_fishing"}],
[11,"Inscription",,,{tinyIcon:'inv_inscription_tradeskill01'}],
[11,"Inschriftenkunde",,,{tinyIcon:'inv_inscription_tradeskill01'}],
[10,"Juwelenschleifen",,,{tinyIcon:"inv_misc_gem_01"}],
[1,"Lederverarbeitung",,,{tinyIcon:"inv_misc_armorkit_17"}],
[12,"Bergbau",,,{tinyIcon:'trade_mining'}],

View File

@@ -170,7 +170,7 @@ var mn_items = [
[3,"Engineering",,,{tinyIcon:"trade_engineering"}],
[7,"First Aid",,,{tinyIcon:"spell_holy_sealofsacrifice"}],
[9,"Fishing",,,{tinyIcon:"trade_fishing"}],
[11,"Inscripción",,,{tinyIcon:'inv_inscription_tradeskill01'}],
[11,"Inscription",,,{tinyIcon:'inv_inscription_tradeskill01'}],
[10,"Jewelcrafting",,,{tinyIcon:"inv_misc_gem_01"}],
[1,"Leatherworking",,,{tinyIcon:"inv_misc_armorkit_17"}],
[12,"Mining",,,{tinyIcon:'trade_mining'}],

View File

@@ -19,9 +19,9 @@
{include file='bricks/infobox.tpl' info=$lvData.infobox}
<div class="text">
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: 9, typeId: {$lvData.page.id} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="?petcalc#{$lvData.page.petCalc}" class="button-red"><em><b><i>{$lang.petCalc}</i></b><span>{$lang.petCalc}</span></em></a>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<div id="h1-icon-generic" class="h1-icon"></div>
<script type="text/javascript">//<![CDATA[

View File

@@ -26,7 +26,7 @@
$WH.ge('race-icon-female').appendChild(Icon.create('race_{$lvData.page.icon}_female', 1));
</script>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<h1 class="h1-icon">{if $lvData.page.expansion}<span class="{$lvData.page.expansion}-icon-right">{$lvData.page.name}</span>{else}{$lvData.page.name}{/if}</h1>

View File

@@ -25,8 +25,8 @@
$WH.ge('h1-icon-generic').appendChild(Icon.create('{$lvData.page.icon|escape:"javascript"}', 1));
//]]></script>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: 15, typeId: {$lvData.page.id} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<h1 class="h1-icon">{$lvData.page.name}</h1>
{include file='bricks/article.tpl'}

View File

@@ -12,20 +12,18 @@
{/foreach}
{/if}
<script type="text/javascript">
<script type="text/javascript">//<![CDATA[
{include file='bricks/community.tpl'}
var g_pageInfo = {ldelim}type: {$page.type}, typeId: {$page.typeId}, name: '{$lvData.page.name|escape:"javascript"}'{rdelim};
g_initPath({$page.path});
</script>
//]]></script>
{include file='bricks/infobox.tpl' info=$lvData.infobox}
</table>
<div class="text">
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: 6, typeId: {$lvData.page.id}, linkColor: 'ff71d5ff', linkId: 'spell:{$lvData.page.id}', linkName: '{$lvData.page.name}' {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} {$page.type}, typeId: {$page.typeId}, linkColor: 'ff71d5ff', linkId: 'spell:{$page.typeId}', linkName: '{$lvData.page.name}' {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="javascript:;" id="view3D-button" class="button-red{if $lvData.view3D}" onclick="this.blur(); ModelViewer.show({ldelim} type: 1, displayId: {$lvData.view3D} {rdelim}){else} button-red-disabled{/if}"><em><b><i>View in 3D</i></b><span>View in 3D</span></em></a>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<h1>{$lvData.page.name}</h1>
<div id="headicon-generic" style="float: left"></div>

View File

@@ -12,68 +12,68 @@
<script type="text/javascript">
g_initPath({$page.path}, {if empty($filter.query)} 0 {else} 1 {/if});
{if isset($filter.query)}
{if !empty($filter.query)}
Menu.modifyUrl(Menu.findItem(mn_database, [1]), {ldelim} filter: '+={$filter.query|escape:'quotes'}' {rdelim}, {ldelim} onAppendCollision: fi_mergeFilterParams, onAppendEmpty: fi_setFilterParams, menuUrl: Menu.getItemUrl(Menu.findItem(mn_database, [1])) {rdelim});
{/if}
</script>
<div id="fi" style="display:{if empty($filter.query)}none{else}block{/if};">
<div id="fi" style="display: {if empty($filter.query)}none{else}block{/if};">
<form action="?spells{$page.subCat}&filter" method="post" name="fi" onsubmit="return fi_submit(this)" onreset="return fi_reset(this)">
<div class="rightpanel">
<div style="float: left">{$lang.school}:</div>
<div style="float: left">{$lang.school}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['sc[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="sc[]" size="7" multiple="multiple" class="rightselect" style="width: 8em">
{foreach from=$lang.sc key=i item=str}{if $str}
<option value="{$i}" {if isset($filter.sc) && ($filter.sc == $i || @in_array($i, $filter.sc))}selected{/if}>{$str}</option>
<option value="{$i}" {if isset($filter.sc) && in_array($i, (array)$filter.sc)}selected{/if}>{$str}</option>
{/if}{/foreach}
</select>
</div>
{if $filter.classPanel}
<div class="rightpanel2">
<div style="float: left">{$lang.class|ucfirst}: </div>
<div style="float: left">{$lang.class|ucfirst}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['cl[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="cl[]" size="8" multiple="multiple" class="rightselect" style="width: 8em; background-color: #181818">
{foreach from=$lang.cl key=i item=str}{if $str}
<option value="{$i}"{if isset($filter.cl) && ($filter.cl == $i || @in_array($i, $filter.cl))} selected{/if} class="c{$i}">{$str}</option>
<option value="{$i}"{if isset($filter.cl) && in_array($i, (array)$filter.cl)} selected{/if} class="c{$i}">{$str}</option>
{/if}{/foreach}
</select>
</div>
{/if}
{if $filter.glyphPanel}
<div class="rightpanel2">
<div style="float: left">{$lang.glyphType|ucfirst}: </div>
<div style="float: left">{$lang.glyphType|ucfirst}{$lang.colon}</div>
<small><a href="javascript:;" onclick="document.forms['fi'].elements['gl[]'].selectedIndex = -1; return false" onmousedown="return false">{$lang.clear}</a></small>
<div class="clear"></div>
<select name="gl[]" size="2" multiple="multiple" class="rightselect" style="width: 8em">
{foreach from=$lang.gl key=i item=str}{if $str}
<option value="{$i}"{if isset($filter.gl) && ($filter.gl == $i || @in_array($i, $filter.gl))} selected{/if}>{$str}</option>
<option value="{$i}"{if isset($filter.gl) && in_array($i, (array)$filter.gl)} selected{/if}>{$str}</option>
{/if}{/foreach}
</select>
</div>
{/if}
<table>
<tr>
<td>{$lang.name}:</td>
<td>{$lang.name}{$lang.colon}</td>
<td colspan="2">
<table><tr>
<td>&nbsp;<input type="text" name="na" size="30" {if isset($filter.na)}value="{$filter.na|escape:'html'}"{/if}/></td>
<td>&nbsp; <input type="checkbox" name="ex" value="on" id="spell-ex" {if isset($filter.ex)}checked="checked"{/if}/></td>
<td>&nbsp;<input type="text" name="na" size="30" {if isset($filter.na)}value="{$filter.na|escape:'html'}" {/if}/></td>
<td>&nbsp; <input type="checkbox" name="ex" value="on" id="spell-ex" {if isset($filter.ex)}checked="checked" {/if}/></td>
<td><label for="spell-ex"><span class="tip" onmouseover="$WH.Tooltip.showAtCursor(event, LANG.tooltip_extendedspellsearch, 0, 0, 'q')" onmousemove="$WH.Tooltip.cursorUpdate(event)" onmouseout="$WH.Tooltip.hide()">{$lang.extSearch}</span></label></td>
</tr></table>
</td>
</tr>
<tr>
<td class="padded">{$lang.level}:</td>
<td class="padded">&nbsp;<input type="text" name="minle" maxlength="2" class="smalltextbox" {if isset($filter.minle)}value="{$filter.minle}"{/if}/> - <input type="text" name="maxle" maxlength="2" class="smalltextbox" {if isset($filter.maxle)}value="{$filter.maxle}"{/if}/></td>
<td class="padded"><table cellpadding="0" cellspacing="0" border="0"><tr>
<td>&nbsp;&nbsp;&nbsp;{$lang.reqSkillLevel}:</td>
<td>&nbsp;<input type="text" name="minrs" maxlength="3" class="smalltextbox2" {if isset($filter.minrs)}value="{$filter.minrs}"{/if}/> - <input type="text" name="maxrs" maxlength="3" class="smalltextbox2" {if isset($filter.maxrs)}value="{$filter.maxrs}"{/if}/></td>
</tr></table></td>
</tr>
<tr>
<td class="padded">{$lang.race}:</td>
</tr><tr>
<td class="padded">{$lang.level}{$lang.colon}</td>
<td class="padded">&nbsp;<input type="text" name="minle" maxlength="2" class="smalltextbox" {if isset($filter.minle)}value="{$filter.minle}" {/if}/> - <input type="text" name="maxle" maxlength="2" class="smalltextbox" {if isset($filter.maxle)}value="{$filter.maxle}" {/if}/></td>
<td class="padded">
<table cellpadding="0" cellspacing="0" border="0"><tr>
<td>&nbsp;&nbsp;&nbsp;{$lang.reqSkillLevel}{$lang.colon}</td>
<td>&nbsp;<input type="text" name="minrs" maxlength="3" class="smalltextbox2" {if isset($filter.minrs)}value="{$filter.minrs}" {/if}/> - <input type="text" name="maxrs" maxlength="3" class="smalltextbox2" {if isset($filter.maxrs)}value="{$filter.maxrs}" {/if}/></td>
</tr></table>
</td>
</tr><tr>
<td class="padded">{$lang.race|ucfirst}{$lang.colon}</td>
<td class="padded">&nbsp;<select name="ra">
<option></option>
{foreach from=$lang.ra key=i item=str}{if $str}{if $i > 0}
@@ -81,9 +81,8 @@
{/if}{/if}{/foreach}
</select></td>
<td class="padded"></td>
</tr>
<tr>
<td class="padded">{$lang.mechAbbr}:</td>
</tr><tr>
<td class="padded">{$lang.mechAbbr}{$lang.colon}</td>
<td class="padded">&nbsp;<select name="me">
<option></option>
{foreach from=$lang.me key=i item=str}{if $str}
@@ -92,7 +91,7 @@
</select></td>
<td>
<table cellpadding="0" cellspacing="0" border="0"><tr>
<td>&nbsp;&nbsp;&nbsp;{$lang.dispelType}:</td>
<td>&nbsp;&nbsp;&nbsp;{$lang.dispelType}{$lang.colon}</td>
<td>&nbsp;<select name="dt">
<option></option>
{foreach from=$lang.dt key=i item=str}{if $str}
@@ -108,7 +107,8 @@
<div><a href="javascript:;" id="fi_addcriteria" onclick="fi_addCriterion(this); return false">{$lang.addFilter}</a></div>
<div class="padded2">
{$lang.match}:<input type="radio" name="ma" value="" id="ma-0" checked="checked" /><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" /><label for="ma-1">{$lang.oneFilter}</label>
<div style="float: right">{$lang.refineSearch}</div>
{$lang.match}{$lang.colon}<input type="radio" name="ma" value="" id="ma-0" {if !isset($filter.ma)}checked="checked" {/if}/><label for="ma-0">{$lang.allFilter}</label><input type="radio" name="ma" value="1" id="ma-1" {if isset($filter.ma)}checked="checked" {/if}/><label for="ma-1">{$lang.oneFilter}</label>
</div>
<div class="clear"></div>
@@ -116,7 +116,6 @@
<div class="padded">
<input type="submit" value="{$lang.applyFilter}" />
<input type="reset" value="{$lang.resetForm}" />
<div style="float: right">{$lang.refineSearch}</div>
</div>
</form>
@@ -125,7 +124,9 @@
<script type="text/javascript">//<![CDATA[
fi_init('spells');
{if isset($filter.setCr)}{$filter.setCr}{/if}
{foreach from=$filter.fi item=str}
{$str}
{/foreach}
//]]></script>
<div id="lv-generic" class="listview"></div>

View File

@@ -10,7 +10,7 @@
{/if}
<div id="{$tcType}-classes">
<div id="{$tcType}-classes-outer">
<div id="{$tcType}-classes-inner"><p>{if $tcType == 'tc'}{$lang.chooseClass}{else}{$lang.chooseFamily}{/if}:</p></div>
<div id="{$tcType}-classes-inner"><p>{if $tcType == 'tc'}{$lang.chooseClass}{else}{$lang.chooseFamily}{/if}{$lang.colon}</p></div>
</div>
</div>
<div id="{$tcType}-itself"></div>

View File

@@ -19,8 +19,8 @@
{include file='bricks/infobox.tpl' info=$lvData.infobox}
<div class="text">
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: 11, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="http://old.wowhead.com/?{$query[0]}={$query[1]}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<a href="javascript:;" id="open-links-button" class="button-red" onclick="this.blur(); Links.show({ldelim} type: {$page.type}, typeId: {$page.typeId} {rdelim});"><em><b><i>{$lang.links}</i></b><span>{$lang.links}</span></em></a>
<a href="{$wowhead}" class="button-red"><em><b><i>Wowhead</i></b><span>Wowhead</span></em></a>
<h1 class="h1-icon">{if isset($lvData.page.expansion)}<span class="{$lvData.page.expansion}-icon-right">{$lvData.page.name}</span>{else}{$lvData.page.name}{/if}</h1>
{include file='bricks/article.tpl'}