From da5944010686a5fe9bdf301f6cfbdd4c6de5af33 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Fri, 24 Feb 2017 18:36:46 +0100 Subject: [PATCH] Fixup * access class property in screenshot/comment-admin by function. Aowow is compatible with PHP 5.5 again * changed line-endings across the board from \r\n to \n --- README.md | Bin 9920 -> 9684 bytes aowow | 24 +- includes/ajaxHandler/account.class.php | 208 +- includes/ajaxHandler/admin.class.php | 892 ++++---- includes/ajaxHandler/comment.class.php | 810 +++---- includes/ajaxHandler/contactus.class.php | 198 +- includes/ajaxHandler/cookie.class.php | 72 +- includes/ajaxHandler/data.class.php | 274 +-- includes/ajaxHandler/gotocomment.class.php | 70 +- includes/ajaxHandler/locale.class.php | 66 +- includes/ajaxHandler/profile.class.php | 644 +++--- includes/shared.php | 52 +- includes/types/emote.class.php | 116 +- includes/types/enchantment.class.php | 690 +++--- localization/locale_dede.php | 2164 +++++++++---------- localization/locale_enus.php | 2154 +++++++++--------- pages/emote.php | 212 +- pages/emotes.php | 88 +- pages/enchantment.php | 648 +++--- pages/enchantments.php | 210 +- pages/user.php | 526 ++--- static/js/staff.js | 602 +++--- template/listviews/emote.tpl.php | 144 +- template/listviews/enchantment.tpl.php | 280 +-- template/listviews/petFoodCol.tpl.php | 24 +- template/localized/ssReminder_0.tpl.php | 20 +- template/localized/ssReminder_3.tpl.php | 20 +- template/pages/admin/siteconfig.tpl.php | 560 ++--- template/pages/admin/weight-presets.tpl.php | 1182 +++++----- template/pages/enchantment.tpl.php | 236 +- template/pages/enchantments.tpl.php | 150 +- template/pages/guilds.tpl | 6 +- template/pages/user.tpl.php | 92 +- 33 files changed, 6717 insertions(+), 6717 deletions(-) diff --git a/README.md b/README.md index 89861d88d5262c4759031419888821e52226f182..a803038e9e46844f55330f7cecf6cf2017ca458c 100644 GIT binary patch delta 534 zcmX@$d&PS~05cZ@*ThK0i8Zr8tjY3>ii}*7T^TzkUtruexrgb&xqT;l z@%SlnLHIy(xfqmzP=Ub{XkIbU# z;h!WZU|>NL!jJ(BmOO@RU;uGVmQ~s~`GV54$r;KSU_);zt4>l`w0Vh22gpQ2wQeRZ F1^{qSWk0$DCY#gtj+BbjoP6=uqF)?7!Bc?t~LKpf1F$&kxXz>vd`$`HZe%isfc z2Sm=D!3Bxu%TUQs%uonanF+MJmrWArmZfaUK=L@-QXrYlzLOhaZuI1O4#~-G93kvb zvB`{F?vo2R1SWsukOHda=PU)1&75DM?ylrA1oBsMedUFyPhbE+-pR|keSzYix&5_4 z;!sg&Xel!&1AXAhkOy>E2}2^#WjT;goSe)v7pUt$&rL?&&DVM7GXgoK{O5tBv%o_j zsVry-l!z9TW`u@SsZb<8I7|_COfD3Yo%~5i2B^GH%y6=uun?GKJh@5O2<%Uo3wH|_ zqVPegQ$!@7`qqfRO!y(f0~Iq76@juU;H*Azp2;Uf6`D*Q(>R$oyRs=`%qBT&az#pyt@TPYJs&37eLpqRAs TVxX(`DtE%HbXV + diff --git a/includes/ajaxHandler/account.class.php b/includes/ajaxHandler/account.class.php index 8f14b614..e2438401 100644 --- a/includes/ajaxHandler/account.class.php +++ b/includes/ajaxHandler/account.class.php @@ -1,104 +1,104 @@ - [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'save' => [FILTER_SANITIZE_NUMBER_INT, null], - 'delete' => [FILTER_SANITIZE_NUMBER_INT, null], - 'id' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'name' => [FILTER_CALLBACK, ['options' => 'AjaxAccount::checkName']], - 'scale' => [FILTER_CALLBACK, ['options' => 'AjaxAccount::checkScale']], - ); - protected $_get = array( - 'locale' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkLocale']] - ); - - public function __construct(array $params) - { - parent::__construct($params); - - if (is_numeric($this->_get['locale'])) - User::useLocale($this->_get['locale']); - - if (!$this->params || !User::$id) - return; - - // select handler - if ($this->params[0] == 'exclude') - $this->handler = 'handleExclude'; - else if ($this->params[0] == 'weightscales') - $this->handler = 'handleWeightscales'; - } - - protected function handleExclude() - { - // profiler completion exclude handler - // $this->_post['groups'] = bitMask of excludeGroupIds when using .. excludeGroups .. duh - // should probably occur in g_user.excludegroups (dont forget to also set g_users.settings = {}) - return ''; - } - - protected function handleWeightscales() - { - if ($this->_post['save']) - { - if (!$this->_post['scale']) - return 0; - - $id = 0; - - if ($id = $this->_post['id']) - { - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account_weightscales WHERE userId = ?d AND id = ?d', User::$id, $id)) - return 0; - - DB::Aowow()->query('UPDATE ?_account_weightscales SET `name` = ? WHERE id = ?d', $this->_post['name'], $id); - } - else - { - $nScales = DB::Aowow()->selectCell('SELECT COUNT(id) FROM ?_account_weightscales WHERE userId = ?d', User::$id); - if ($nScales >= 5) // more or less hard-defined in LANG.message_weightscalesaveerror - return 0; - - $id = DB::Aowow()->query('INSERT INTO ?_account_weightscales (`userId`, `name`) VALUES (?d, ?)', User::$id, $this->_post['name']); - } - - DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE id = ?d', $id); - - foreach (explode(',', $this->_post['scale']) as $s) - { - list($k, $v) = explode(':', $s); - if (!in_array($k, Util::$weightScales) || $v < 1) - continue; - - DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $id, $k, $v); - } - - return $id; - } - else if ($this->_post['delete'] && $this->_post['id']) - DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE id = ?d AND userId = ?d', $this->_post['id'], User::$id); - else - return 0; - } - - protected function checkScale($val) - { - if (preg_match('/^((\w+:\d+)(,\w+:\d+)*)$/', $val)) - return $val; - - return null; - } - - protected function checkName($val) - { - $var = trim(urldecode($val)); - - return filter_var($var, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); - } -} + [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'save' => [FILTER_SANITIZE_NUMBER_INT, null], + 'delete' => [FILTER_SANITIZE_NUMBER_INT, null], + 'id' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'name' => [FILTER_CALLBACK, ['options' => 'AjaxAccount::checkName']], + 'scale' => [FILTER_CALLBACK, ['options' => 'AjaxAccount::checkScale']], + ); + protected $_get = array( + 'locale' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkLocale']] + ); + + public function __construct(array $params) + { + parent::__construct($params); + + if (is_numeric($this->_get['locale'])) + User::useLocale($this->_get['locale']); + + if (!$this->params || !User::$id) + return; + + // select handler + if ($this->params[0] == 'exclude') + $this->handler = 'handleExclude'; + else if ($this->params[0] == 'weightscales') + $this->handler = 'handleWeightscales'; + } + + protected function handleExclude() + { + // profiler completion exclude handler + // $this->_post['groups'] = bitMask of excludeGroupIds when using .. excludeGroups .. duh + // should probably occur in g_user.excludegroups (dont forget to also set g_users.settings = {}) + return ''; + } + + protected function handleWeightscales() + { + if ($this->_post['save']) + { + if (!$this->_post['scale']) + return 0; + + $id = 0; + + if ($id = $this->_post['id']) + { + if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account_weightscales WHERE userId = ?d AND id = ?d', User::$id, $id)) + return 0; + + DB::Aowow()->query('UPDATE ?_account_weightscales SET `name` = ? WHERE id = ?d', $this->_post['name'], $id); + } + else + { + $nScales = DB::Aowow()->selectCell('SELECT COUNT(id) FROM ?_account_weightscales WHERE userId = ?d', User::$id); + if ($nScales >= 5) // more or less hard-defined in LANG.message_weightscalesaveerror + return 0; + + $id = DB::Aowow()->query('INSERT INTO ?_account_weightscales (`userId`, `name`) VALUES (?d, ?)', User::$id, $this->_post['name']); + } + + DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE id = ?d', $id); + + foreach (explode(',', $this->_post['scale']) as $s) + { + list($k, $v) = explode(':', $s); + if (!in_array($k, Util::$weightScales) || $v < 1) + continue; + + DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $id, $k, $v); + } + + return $id; + } + else if ($this->_post['delete'] && $this->_post['id']) + DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE id = ?d AND userId = ?d', $this->_post['id'], User::$id); + else + return 0; + } + + protected function checkScale($val) + { + if (preg_match('/^((\w+:\d+)(,\w+:\d+)*)$/', $val)) + return $val; + + return null; + } + + protected function checkName($val) + { + $var = trim(urldecode($val)); + + return filter_var($var, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); + } +} diff --git a/includes/ajaxHandler/admin.class.php b/includes/ajaxHandler/admin.class.php index 42ce2f97..43c450c6 100644 --- a/includes/ajaxHandler/admin.class.php +++ b/includes/ajaxHandler/admin.class.php @@ -1,446 +1,446 @@ - [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH - 'id' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkId']], - 'key' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkKey']], - 'all' => [FILTER_UNSAFE_RAW, null], - 'type' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'typeid' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'user' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkUser']], - 'val' => [FILTER_UNSAFE_RAW, null] - ); - protected $_post = array( - 'alt' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], - 'id' => [FILTER_SANITIZE_NUMBER_INT, null], - 'scale' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkScale']], - '__icon' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkKey']], - ); - - public function __construct(array $params) - { - parent::__construct($params); - - // requires 'action' parameter in any case - if (!$this->_get['action'] || !$this->params) - return; - - if ($this->params[0] == 'screenshots') - { - if (!User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SCREENSHOT)) - return; - - if ($this->_get['action'] == 'list') - $this->handler = 'ssList'; - else if ($this->_get['action'] == 'manage') - $this->handler = 'ssManage'; - else if ($this->_get['action'] == 'editalt') - $this->handler = 'ssEditAlt'; - else if ($this->_get['action'] == 'approve') - $this->handler = 'ssApprove'; - else if ($this->_get['action'] == 'sticky') - $this->handler = 'ssSticky'; - else if ($this->_get['action'] == 'delete') - $this->handler = 'ssDelete'; - else if ($this->_get['action'] == 'relocate') - $this->handler = 'ssRelocate'; - } - else if ($this->params[0] == 'siteconfig') - { - if (!User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN)) - return; - - if ($this->_get['action'] == 'add') - $this->handler = 'confAdd'; - else if ($this->_get['action'] == 'remove') - $this->handler = 'confRemove'; - else if ($this->_get['action'] == 'update') - $this->handler = 'confUpdate'; - } - else if ($this->params[0] == 'weight-presets') - { - if (!User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN | U_GROUP_BUREAU)) - return; - - if ($this->_get['action'] == 'save') - $this->handler = 'wtSave'; - } - } - - // get all => null (optional) - // evaled response .. UNK - protected function ssList() - { - // ssm_screenshotPages - // ssm_numPagesFound - - $pages = CommunityContent::getScreenshotPagesForManager($this->_get['all'], $nPages); - $buff = 'ssm_screenshotPages = '.Util::toJSON($pages).";\n"; - $buff .= 'ssm_numPagesFound = '.$nPages.';'; - - return $buff; - } - - // get: [type => type, typeId => typeId] || [user => username] - // evaled response .. UNK - protected function ssManage() - { - $res = []; - - if ($this->_get['type'] && $this->_get['type'] && $this->_get['typeid'] && $this->_get['typeid']) - $res = CommunityContent::getScreenshotsForManager($this->_get['type'], $this->_get['typeid']); - else if ($this->_get['user']) - if ($uId = DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE displayName = ?', $this->_get['user'])) - $res = CommunityContent::getScreenshotsForManager(0, 0, $uId); - - return 'ssm_screenshotData = '.Util::toJSON($res); - } - - // get: id => SSid - // resp: '' - protected function ssEditAlt() - { - // doesn't need to be htmlEscaped, ths javascript does that - if ($this->_get['id'] && $this->_post['alt'] !== null) - DB::Aowow()->query('UPDATE ?_screenshots SET caption = ? WHERE id = ?d', trim($this->_post['alt']), $this->_get['id'][0]); - - return ''; - } - - // get: id => comma-separated SSids - // resp: '' - protected function ssApprove() - { - if (!$this->_get['id']) - return ''; - - // create resized and thumb version of screenshot - $resized = [772, 618]; - $thumb = [150, 150]; - $path = 'static/uploads/screenshots/%s/%d.jpg'; - - foreach ($this->_get['id'] as $id) - { - // must not be already approved - if ($_ = DB::Aowow()->selectRow('SELECT userIdOwner, date, type, typeId FROM ?_screenshots WHERE (status & ?d) = 0 AND id = ?d', CC_FLAG_APPROVED, $id)) - { - // should also error-log - if (!file_exists(sprintf($path, 'pending', $id))) - continue; - - $srcImg = imagecreatefromjpeg(sprintf($path, 'pending', $id)); - $srcW = imagesx($srcImg); - $srcH = imagesy($srcImg); - - // write thumb - $scale = min(1.0, min($thumb[0] / $srcW, $thumb[1] / $srcH)); - $destW = $srcW * $scale; - $destH = $srcH * $scale; - $destImg = imagecreatetruecolor($destW, $destH); - - imagefill($destImg, 0, 0, imagecolorallocate($destImg, 255, 255, 255)); - imagecopyresampled($destImg, $srcImg, 0, 0, 0, 0, $destW, $destH, $srcW, $srcH); - - imagejpeg($destImg, sprintf($path, 'thumb', $id), 100); - - // write resized (only if required) - if ($srcW > $resized[0] || $srcH > $resized[1]) - { - $scale = min(1.0, min($resized[0] / $srcW, $resized[1] / $srcH)); - $destW = $srcW * $scale; - $destH = $srcH * $scale; - $destImg = imagecreatetruecolor($destW, $destH); - - imagefill($destImg, 0, 0, imagecolorallocate($destImg, 255, 255, 255)); - imagecopyresampled($destImg, $srcImg, 0, 0, 0, 0, $destW, $destH, $srcW, $srcH); - - imagejpeg($destImg, sprintf($path, 'resized', $id), 100); - } - - imagedestroy($srcImg); - - // move screenshot from pending to normal - rename(sprintf($path, 'pending', $id), sprintf($path, 'normal', $id)); - - // set as approved in DB and gain rep (once!) - DB::Aowow()->query('UPDATE ?_screenshots SET status = ?d, userIdApprove = ?d WHERE id = ?d', CC_FLAG_APPROVED, User::$id, $id); - Util::gainSiteReputation($_['userIdOwner'], SITEREP_ACTION_UPLOAD, ['id' => $id, 'what' => 1, 'date' => $_['date']]); - // flag DB entry as having screenshots - if (Util::$typeClasses[$_['type']] && ($tbl = (new Util::$typeClasses[$_['type']])::$dataTable)) - DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_SCREENSHOT, $_['typeId']); - } - } - - return ''; - } - - // get: id => comma-separated SSids - // resp: '' - protected function ssSticky() - { - if (!$this->_get['id']) - return ''; - - // approve soon to be sticky screenshots - $this->ssApprove(); - - // this one is a bit strange: as far as i've seen, the only thing a 'sticky' screenshot does is show up in the infobox - // this also means, that only one screenshot per page should be sticky - // so, handle it one by one and the last one affecting one particular type/typId-key gets the cake - foreach ($this->_get['id'] as $id) - { - // reset all others - DB::Aowow()->query('UPDATE ?_screenshots a, ?_screenshots b SET a.status = a.status & ~?d WHERE a.type = b.type AND a.typeId = b.typeId AND a.id <> b.id AND b.id = ?d', CC_FLAG_STICKY, $id); - - // toggle sticky status - DB::Aowow()->query('UPDATE ?_screenshots SET `status` = IF(`status` & ?d, `status` & ~?d, `status` | ?d) WHERE id = ?d AND `status` & ?d', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED); - } - - return ''; - } - - // get: id => comma-separated SSids - // resp: '' - // 2 steps: 1) remove from sight, 2) remove from disk - protected function ssDelete() - { - if (!$this->_get['id']) - return ''; - - $path = 'static/uploads/screenshots/%s/%d.jpg'; - - foreach ($this->_get['id'] as $id) - { - // irrevocably remove already deleted files - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_screenshots WHERE status & ?d AND id = ?d', CC_FLAG_DELETED, $id)) - { - DB::Aowow()->query('DELETE FROM ?_screenshots WHERE id = ?d', $id); - if (file_exists(sprintf($path, 'pending', $id))) - unlink(sprintf($path, 'pending', $id)); - - continue; - } - - // move pending or normal to pending - if (file_exists(sprintf($path, 'normal', $id))) - rename(sprintf($path, 'normal', $id), sprintf($path, 'pending', $id)); - - // remove resized and thumb - if (file_exists(sprintf($path, 'thumb', $id))) - unlink(sprintf($path, 'thumb', $id)); - - if (file_exists(sprintf($path, 'resized', $id))) - unlink(sprintf($path, 'resized', $id)); - } - - // flag as deleted if not aready - $oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(typeId) FROM ?_screenshots WHERE id IN (?a) GROUP BY `type`', $this->_get['id']); - DB::Aowow()->query('UPDATE ?_screenshots SET status = ?d, userIdDelete = ?d WHERE id IN (?a)', CC_FLAG_DELETED, User::$id, $this->_get['id']); - // deflag db entry as having screenshots - foreach ($oldEntries as $type => $typeIds) - { - $typeIds = explode(',', $typeIds); - $toUnflag = DB::Aowow()->selectCol('SELECT typeId AS ARRAY_KEY, IF(BIT_OR(`status`) & ?d, 1, 0) AS hasMore FROM ?_screenshots WHERE `type` = ?d AND typeId IN (?a) GROUP BY typeId HAVING hasMore = 0', CC_FLAG_APPROVED, $type, $typeIds); - if ($toUnflag && Util::$typeClasses[$type] && ($tbl = (new Util::$typeClasses[$type](null))::$dataTable)) - DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags & ~?d WHERE id IN (?a)', CUSTOM_HAS_SCREENSHOT, array_keys($toUnflag)); - } - - return ''; - } - - // get: id => ssId, typeid => typeId (but not type..?) - // resp: '' - protected function ssRelocate() - { - if (!$this->_get['id'] || !$this->_get['typeid']) - return ''; - - $id = $this->_get['id'][0]; - list($type, $oldTypeId) = array_values(DB::Aowow()->selectRow('SELECT type, typeId FROM ?_screenshots WHERE id = ?d', $id)); - $typeId = (int)$this->_get['typeid']; - - $tc = new Util::$typeClasses[$type]([['id', $typeId]]); - if (!$tc->error) - { - // move screenshot - DB::Aowow()->query('UPDATE ?_screenshots SET typeId = ?d WHERE id = ?d', $typeId, $id); - - // flag target as having screenshot - DB::Aowow()->query('UPDATE '.$tc::$dataTable.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_SCREENSHOT, $typeId); - - // deflag source for having had screenshots (maybe) - $ssInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~status) & ?d, 1, 0) AS hasMore FROM ?_screenshots WHERE `status`& ?d AND `type` = ?d AND typeId = ?d', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId); - if($ssInfo || !$ssInfo['hasMore']) - DB::Aowow()->query('UPDATE '.$tc::$dataTable.' SET cuFlags = cuFlags & ~?d WHERE id = ?d', CUSTOM_HAS_SCREENSHOT, $oldTypeId); - } - - return ''; - } - - protected function confAdd() - { - $key = $this->_get['key']; - $val = $this->_get['val']; - - if ($key === null) - return 'empty option name given'; - - if (!strlen($key)) - return 'invalid chars in option name: [a-z 0-9 _ . -] are allowed'; - - if (ini_get($key) === false || ini_set($key, $val) === false) - return 'this configuration option cannot be set'; - - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_config WHERE `flags` & ?d AND `key` = ?', CON_FLAG_PHP, $key)) - return 'this configuration option is already in use'; - - DB::Aowow()->query('INSERT IGNORE INTO ?_config (`key`, `value`, `flags`) VALUES (?, ?, ?d)', $key, $val, CON_FLAG_TYPE_STRING | CON_FLAG_PHP); - return ''; - } - - protected function confRemove() - { - if (!$this->_get['key']) - return 'invalid configuration option given'; - - if (DB::Aowow()->query('DELETE FROM ?_config WHERE `key` = ? AND (`flags` & ?d) = 0', $this->_get['key'], CON_FLAG_PERSISTENT)) - return ''; - else - return 'option name is either protected or was not found'; - } - - protected function confUpdate() - { - $key = trim($this->_get['key']); - $val = trim($this->_get['val']); - - if (!strlen($key)) - return 'empty option name given'; - - $flags = DB::Aowow()->selectCell('SELECT `flags` FROM ?_config WHERE `key` = ?', $key); - if (!$flags) - return 'configuration option not found'; - - if (!($flags & CON_FLAG_TYPE_STRING) && !strlen($val)) - return 'empty value given'; - else if ($flags & CON_FLAG_TYPE_INT && !preg_match('/^-?\d+$/i', $val)) - return "value must be integer"; - else if ($flags & CON_FLAG_TYPE_FLOAT && !preg_match('/^-?\d*(,|.)?\d+$/i', $val)) - return "value must be float"; - else if ($flags & CON_FLAG_TYPE_BOOL) - $val = (int)!!$val; // *snort* bwahahaa - - DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $val, $key); - return ''; - } - - protected function wtSave() - { - if (!$this->_post['id'] || !$this->_post['__icon']) - return 3; - - $writeFile = function($file, $content) - { - $success = false; - if ($handle = @fOpen($file, "w")) - { - if (fWrite($handle, $content)) - $success = true; - - fClose($handle); - } - else - die('me no file'); - - if ($success) - @chmod($file, Util::FILE_ACCESS); - - return $success; - }; - - - // save to db - - DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE id = ?d', $this->_post['id']); - DB::Aowow()->query('UPDATE ?_account_weightscales SET `icon`= ? WHERE `id` = ?d', $this->_post['__icon'], $this->_post['id']); - - foreach (explode(',', $this->_post['scale']) as $s) - { - list($k, $v) = explode(':', $s); - - if (!in_array($k, Util::$weightScales) || $v < 1) - continue; - - if (DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $this->_post['id'], $k, $v) === null) - return 1; - } - - - // write dataset - - $wtPresets = []; - $scales = DB::Aowow()->select('SELECT id, name, icon, class FROM ?_account_weightscales WHERE userId = 0 ORDER BY class, id ASC'); - - foreach ($scales as $s) - { - $weights = DB::Aowow()->selectCol('SELECT field AS ARRAY_KEY, val FROM ?_account_weightscale_data WHERE id = ?d', $s['id']); - if (!$weights) - continue; - - $wtPresets[$s['class']]['pve'][$s['name']] = array_merge(['__icon' => $s['icon']], $weights); - } - - $toFile = "var wt_presets = ".Util::toJSON($wtPresets).";"; - $file = 'datasets/weight-presets'; - - if (!$writeFile($file, $toFile)) - return 2; - - - // all done - - return 0; - } - - protected function checkId($val) - { - // expecting id-list - if (preg_match('/\d+(,\d+)*/', $val)) - return array_map('intVal', explode(',', $val)); - - return null; - } - - protected function checkKey($val) - { - // expecting string - if (preg_match('/[^a-z0-9_\.\-]/i', $val)) - return ''; - - return strtolower($val); - } - - protected function checkUser($val) - { - $n = Util::lower(trim(urldecode($val))); - - if (User::isValidName($n)) - return $n; - - return null; - } - - protected function checkScale($val) - { - if (preg_match('/^((\w+:\d+)(,\w+:\d+)*)$/', $val)) - return $val; - - return null; - } -} + [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH + 'id' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkId']], + 'key' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkKey']], + 'all' => [FILTER_UNSAFE_RAW, null], + 'type' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'typeid' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'user' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkUser']], + 'val' => [FILTER_UNSAFE_RAW, null] + ); + protected $_post = array( + 'alt' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], + 'id' => [FILTER_SANITIZE_NUMBER_INT, null], + 'scale' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkScale']], + '__icon' => [FILTER_CALLBACK, ['options' => 'AjaxAdmin::checkKey']], + ); + + public function __construct(array $params) + { + parent::__construct($params); + + // requires 'action' parameter in any case + if (!$this->_get['action'] || !$this->params) + return; + + if ($this->params[0] == 'screenshots') + { + if (!User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SCREENSHOT)) + return; + + if ($this->_get['action'] == 'list') + $this->handler = 'ssList'; + else if ($this->_get['action'] == 'manage') + $this->handler = 'ssManage'; + else if ($this->_get['action'] == 'editalt') + $this->handler = 'ssEditAlt'; + else if ($this->_get['action'] == 'approve') + $this->handler = 'ssApprove'; + else if ($this->_get['action'] == 'sticky') + $this->handler = 'ssSticky'; + else if ($this->_get['action'] == 'delete') + $this->handler = 'ssDelete'; + else if ($this->_get['action'] == 'relocate') + $this->handler = 'ssRelocate'; + } + else if ($this->params[0] == 'siteconfig') + { + if (!User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN)) + return; + + if ($this->_get['action'] == 'add') + $this->handler = 'confAdd'; + else if ($this->_get['action'] == 'remove') + $this->handler = 'confRemove'; + else if ($this->_get['action'] == 'update') + $this->handler = 'confUpdate'; + } + else if ($this->params[0] == 'weight-presets') + { + if (!User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN | U_GROUP_BUREAU)) + return; + + if ($this->_get['action'] == 'save') + $this->handler = 'wtSave'; + } + } + + // get all => null (optional) + // evaled response .. UNK + protected function ssList() + { + // ssm_screenshotPages + // ssm_numPagesFound + + $pages = CommunityContent::getScreenshotPagesForManager($this->_get['all'], $nPages); + $buff = 'ssm_screenshotPages = '.Util::toJSON($pages).";\n"; + $buff .= 'ssm_numPagesFound = '.$nPages.';'; + + return $buff; + } + + // get: [type => type, typeId => typeId] || [user => username] + // evaled response .. UNK + protected function ssManage() + { + $res = []; + + if ($this->_get['type'] && $this->_get['type'] && $this->_get['typeid'] && $this->_get['typeid']) + $res = CommunityContent::getScreenshotsForManager($this->_get['type'], $this->_get['typeid']); + else if ($this->_get['user']) + if ($uId = DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE displayName = ?', $this->_get['user'])) + $res = CommunityContent::getScreenshotsForManager(0, 0, $uId); + + return 'ssm_screenshotData = '.Util::toJSON($res); + } + + // get: id => SSid + // resp: '' + protected function ssEditAlt() + { + // doesn't need to be htmlEscaped, ths javascript does that + if ($this->_get['id'] && $this->_post['alt'] !== null) + DB::Aowow()->query('UPDATE ?_screenshots SET caption = ? WHERE id = ?d', trim($this->_post['alt']), $this->_get['id'][0]); + + return ''; + } + + // get: id => comma-separated SSids + // resp: '' + protected function ssApprove() + { + if (!$this->_get['id']) + return ''; + + // create resized and thumb version of screenshot + $resized = [772, 618]; + $thumb = [150, 150]; + $path = 'static/uploads/screenshots/%s/%d.jpg'; + + foreach ($this->_get['id'] as $id) + { + // must not be already approved + if ($_ = DB::Aowow()->selectRow('SELECT userIdOwner, date, type, typeId FROM ?_screenshots WHERE (status & ?d) = 0 AND id = ?d', CC_FLAG_APPROVED, $id)) + { + // should also error-log + if (!file_exists(sprintf($path, 'pending', $id))) + continue; + + $srcImg = imagecreatefromjpeg(sprintf($path, 'pending', $id)); + $srcW = imagesx($srcImg); + $srcH = imagesy($srcImg); + + // write thumb + $scale = min(1.0, min($thumb[0] / $srcW, $thumb[1] / $srcH)); + $destW = $srcW * $scale; + $destH = $srcH * $scale; + $destImg = imagecreatetruecolor($destW, $destH); + + imagefill($destImg, 0, 0, imagecolorallocate($destImg, 255, 255, 255)); + imagecopyresampled($destImg, $srcImg, 0, 0, 0, 0, $destW, $destH, $srcW, $srcH); + + imagejpeg($destImg, sprintf($path, 'thumb', $id), 100); + + // write resized (only if required) + if ($srcW > $resized[0] || $srcH > $resized[1]) + { + $scale = min(1.0, min($resized[0] / $srcW, $resized[1] / $srcH)); + $destW = $srcW * $scale; + $destH = $srcH * $scale; + $destImg = imagecreatetruecolor($destW, $destH); + + imagefill($destImg, 0, 0, imagecolorallocate($destImg, 255, 255, 255)); + imagecopyresampled($destImg, $srcImg, 0, 0, 0, 0, $destW, $destH, $srcW, $srcH); + + imagejpeg($destImg, sprintf($path, 'resized', $id), 100); + } + + imagedestroy($srcImg); + + // move screenshot from pending to normal + rename(sprintf($path, 'pending', $id), sprintf($path, 'normal', $id)); + + // set as approved in DB and gain rep (once!) + DB::Aowow()->query('UPDATE ?_screenshots SET status = ?d, userIdApprove = ?d WHERE id = ?d', CC_FLAG_APPROVED, User::$id, $id); + Util::gainSiteReputation($_['userIdOwner'], SITEREP_ACTION_UPLOAD, ['id' => $id, 'what' => 1, 'date' => $_['date']]); + // flag DB entry as having screenshots + if (Util::$typeClasses[$_['type']] && ($tbl = get_class_vars(Util::$typeClasses[$_['type'])['dataTable'])) + DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_SCREENSHOT, $_['typeId']); + } + } + + return ''; + } + + // get: id => comma-separated SSids + // resp: '' + protected function ssSticky() + { + if (!$this->_get['id']) + return ''; + + // approve soon to be sticky screenshots + $this->ssApprove(); + + // this one is a bit strange: as far as i've seen, the only thing a 'sticky' screenshot does is show up in the infobox + // this also means, that only one screenshot per page should be sticky + // so, handle it one by one and the last one affecting one particular type/typId-key gets the cake + foreach ($this->_get['id'] as $id) + { + // reset all others + DB::Aowow()->query('UPDATE ?_screenshots a, ?_screenshots b SET a.status = a.status & ~?d WHERE a.type = b.type AND a.typeId = b.typeId AND a.id <> b.id AND b.id = ?d', CC_FLAG_STICKY, $id); + + // toggle sticky status + DB::Aowow()->query('UPDATE ?_screenshots SET `status` = IF(`status` & ?d, `status` & ~?d, `status` | ?d) WHERE id = ?d AND `status` & ?d', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED); + } + + return ''; + } + + // get: id => comma-separated SSids + // resp: '' + // 2 steps: 1) remove from sight, 2) remove from disk + protected function ssDelete() + { + if (!$this->_get['id']) + return ''; + + $path = 'static/uploads/screenshots/%s/%d.jpg'; + + foreach ($this->_get['id'] as $id) + { + // irrevocably remove already deleted files + if (DB::Aowow()->selectCell('SELECT 1 FROM ?_screenshots WHERE status & ?d AND id = ?d', CC_FLAG_DELETED, $id)) + { + DB::Aowow()->query('DELETE FROM ?_screenshots WHERE id = ?d', $id); + if (file_exists(sprintf($path, 'pending', $id))) + unlink(sprintf($path, 'pending', $id)); + + continue; + } + + // move pending or normal to pending + if (file_exists(sprintf($path, 'normal', $id))) + rename(sprintf($path, 'normal', $id), sprintf($path, 'pending', $id)); + + // remove resized and thumb + if (file_exists(sprintf($path, 'thumb', $id))) + unlink(sprintf($path, 'thumb', $id)); + + if (file_exists(sprintf($path, 'resized', $id))) + unlink(sprintf($path, 'resized', $id)); + } + + // flag as deleted if not aready + $oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(typeId) FROM ?_screenshots WHERE id IN (?a) GROUP BY `type`', $this->_get['id']); + DB::Aowow()->query('UPDATE ?_screenshots SET status = ?d, userIdDelete = ?d WHERE id IN (?a)', CC_FLAG_DELETED, User::$id, $this->_get['id']); + // deflag db entry as having screenshots + foreach ($oldEntries as $type => $typeIds) + { + $typeIds = explode(',', $typeIds); + $toUnflag = DB::Aowow()->selectCol('SELECT typeId AS ARRAY_KEY, IF(BIT_OR(`status`) & ?d, 1, 0) AS hasMore FROM ?_screenshots WHERE `type` = ?d AND typeId IN (?a) GROUP BY typeId HAVING hasMore = 0', CC_FLAG_APPROVED, $type, $typeIds); + if ($toUnflag && Util::$typeClasses[$type] && ($tbl = get_class_vars(Util::$typeClasses[$type])['dataTable'])) + DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags & ~?d WHERE id IN (?a)', CUSTOM_HAS_SCREENSHOT, array_keys($toUnflag)); + } + + return ''; + } + + // get: id => ssId, typeid => typeId (but not type..?) + // resp: '' + protected function ssRelocate() + { + if (!$this->_get['id'] || !$this->_get['typeid']) + return ''; + + $id = $this->_get['id'][0]; + list($type, $oldTypeId) = array_values(DB::Aowow()->selectRow('SELECT type, typeId FROM ?_screenshots WHERE id = ?d', $id)); + $typeId = (int)$this->_get['typeid']; + + $tc = new Util::$typeClasses[$type]([['id', $typeId]]); + if (!$tc->error) + { + // move screenshot + DB::Aowow()->query('UPDATE ?_screenshots SET typeId = ?d WHERE id = ?d', $typeId, $id); + + // flag target as having screenshot + DB::Aowow()->query('UPDATE '.$tc::$dataTable.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_SCREENSHOT, $typeId); + + // deflag source for having had screenshots (maybe) + $ssInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~status) & ?d, 1, 0) AS hasMore FROM ?_screenshots WHERE `status`& ?d AND `type` = ?d AND typeId = ?d', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId); + if($ssInfo || !$ssInfo['hasMore']) + DB::Aowow()->query('UPDATE '.$tc::$dataTable.' SET cuFlags = cuFlags & ~?d WHERE id = ?d', CUSTOM_HAS_SCREENSHOT, $oldTypeId); + } + + return ''; + } + + protected function confAdd() + { + $key = $this->_get['key']; + $val = $this->_get['val']; + + if ($key === null) + return 'empty option name given'; + + if (!strlen($key)) + return 'invalid chars in option name: [a-z 0-9 _ . -] are allowed'; + + if (ini_get($key) === false || ini_set($key, $val) === false) + return 'this configuration option cannot be set'; + + if (DB::Aowow()->selectCell('SELECT 1 FROM ?_config WHERE `flags` & ?d AND `key` = ?', CON_FLAG_PHP, $key)) + return 'this configuration option is already in use'; + + DB::Aowow()->query('INSERT IGNORE INTO ?_config (`key`, `value`, `flags`) VALUES (?, ?, ?d)', $key, $val, CON_FLAG_TYPE_STRING | CON_FLAG_PHP); + return ''; + } + + protected function confRemove() + { + if (!$this->_get['key']) + return 'invalid configuration option given'; + + if (DB::Aowow()->query('DELETE FROM ?_config WHERE `key` = ? AND (`flags` & ?d) = 0', $this->_get['key'], CON_FLAG_PERSISTENT)) + return ''; + else + return 'option name is either protected or was not found'; + } + + protected function confUpdate() + { + $key = trim($this->_get['key']); + $val = trim($this->_get['val']); + + if (!strlen($key)) + return 'empty option name given'; + + $flags = DB::Aowow()->selectCell('SELECT `flags` FROM ?_config WHERE `key` = ?', $key); + if (!$flags) + return 'configuration option not found'; + + if (!($flags & CON_FLAG_TYPE_STRING) && !strlen($val)) + return 'empty value given'; + else if ($flags & CON_FLAG_TYPE_INT && !preg_match('/^-?\d+$/i', $val)) + return "value must be integer"; + else if ($flags & CON_FLAG_TYPE_FLOAT && !preg_match('/^-?\d*(,|.)?\d+$/i', $val)) + return "value must be float"; + else if ($flags & CON_FLAG_TYPE_BOOL) + $val = (int)!!$val; // *snort* bwahahaa + + DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $val, $key); + return ''; + } + + protected function wtSave() + { + if (!$this->_post['id'] || !$this->_post['__icon']) + return 3; + + $writeFile = function($file, $content) + { + $success = false; + if ($handle = @fOpen($file, "w")) + { + if (fWrite($handle, $content)) + $success = true; + + fClose($handle); + } + else + die('me no file'); + + if ($success) + @chmod($file, Util::FILE_ACCESS); + + return $success; + }; + + + // save to db + + DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE id = ?d', $this->_post['id']); + DB::Aowow()->query('UPDATE ?_account_weightscales SET `icon`= ? WHERE `id` = ?d', $this->_post['__icon'], $this->_post['id']); + + foreach (explode(',', $this->_post['scale']) as $s) + { + list($k, $v) = explode(':', $s); + + if (!in_array($k, Util::$weightScales) || $v < 1) + continue; + + if (DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $this->_post['id'], $k, $v) === null) + return 1; + } + + + // write dataset + + $wtPresets = []; + $scales = DB::Aowow()->select('SELECT id, name, icon, class FROM ?_account_weightscales WHERE userId = 0 ORDER BY class, id ASC'); + + foreach ($scales as $s) + { + $weights = DB::Aowow()->selectCol('SELECT field AS ARRAY_KEY, val FROM ?_account_weightscale_data WHERE id = ?d', $s['id']); + if (!$weights) + continue; + + $wtPresets[$s['class']]['pve'][$s['name']] = array_merge(['__icon' => $s['icon']], $weights); + } + + $toFile = "var wt_presets = ".Util::toJSON($wtPresets).";"; + $file = 'datasets/weight-presets'; + + if (!$writeFile($file, $toFile)) + return 2; + + + // all done + + return 0; + } + + protected function checkId($val) + { + // expecting id-list + if (preg_match('/\d+(,\d+)*/', $val)) + return array_map('intVal', explode(',', $val)); + + return null; + } + + protected function checkKey($val) + { + // expecting string + if (preg_match('/[^a-z0-9_\.\-]/i', $val)) + return ''; + + return strtolower($val); + } + + protected function checkUser($val) + { + $n = Util::lower(trim(urldecode($val))); + + if (User::isValidName($n)) + return $n; + + return null; + } + + protected function checkScale($val) + { + if (preg_match('/^((\w+:\d+)(,\w+:\d+)*)$/', $val)) + return $val; + + return null; + } +} diff --git a/includes/ajaxHandler/comment.class.php b/includes/ajaxHandler/comment.class.php index d8da5295..e84fb0be 100644 --- a/includes/ajaxHandler/comment.class.php +++ b/includes/ajaxHandler/comment.class.php @@ -1,405 +1,405 @@ - [FILTER_CALLBACK, ['options' => 'AjaxComment::checkId']], - 'body' => [FILTER_UNSAFE_RAW, null],// escaped by json_encode - 'commentbody' => [FILTER_UNSAFE_RAW, null],// escaped by json_encode - 'response' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], - 'reason' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], - 'remove' => [FILTER_SANITIZE_NUMBER_INT, null], - 'commentId' => [FILTER_SANITIZE_NUMBER_INT, null], - 'replyId' => [FILTER_SANITIZE_NUMBER_INT, null], - // 'username' => [FILTER_SANITIZE_STRING, 0xC] // FILTER_FLAG_STRIP_LOW | *_HIGH - ); - - protected $_get = array( - 'id' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'type' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'typeid' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], - 'rating' => [FILTER_SANITIZE_NUMBER_INT, null] - ); - - public function __construct(array $params) - { - parent::__construct($params); - - if (!$this->params || count($this->params) != 1) - return; - - // note: return values must be formated as STRICT json! - - // select handler - if ($this->params[0] == 'add') - $this->handler = 'handleCommentAdd'; - else if ($this->params[0] == 'edit') - $this->handler = 'handleCommentEdit'; - else if ($this->params[0] == 'delete') - $this->handler = 'handleCommentDelete'; - else if ($this->params[0] == 'undelete') - $this->handler = 'handleCommentUndelete'; - else if ($this->params[0] == 'rating') // up/down - distribution - $this->handler = 'handleCommentRating'; - else if ($this->params[0] == 'vote') // up, down and remove - $this->handler = 'handleCommentVote'; - else if ($this->params[0] == 'sticky') // toggle flag - $this->handler = 'handleCommentSticky'; - else if ($this->params[0] == 'out-of-date') // toggle flag - $this->handler = 'handleCommentOutOfDate'; - else if ($this->params[0] == 'show-replies') - $this->handler = 'handleCommentShowReplies'; - else if ($this->params[0] == 'add-reply') // also returns all replies on success - $this->handler = 'handleReplyAdd'; - else if ($this->params[0] == 'edit-reply') // also returns all replies on success - $this->handler = 'handleReplyEdit'; - else if ($this->params[0] == 'detach-reply') - $this->handler = 'handleReplyDetach'; - else if ($this->params[0] == 'delete-reply') - $this->handler = 'handleReplyDelete'; - else if ($this->params[0] == 'flag-reply') - $this->handler = 'handleReplyFlag'; - else if ($this->params[0] == 'upvote-reply') - $this->handler = 'handleReplyUpvote'; - else if ($this->params[0] == 'downvote-reply') - $this->handler = 'handleReplyDownvote'; - } - - // i .. have problems believing, that everything uses nifty ajax while adding comments requires a brutal header(Loacation: ), yet, thats how it is - protected function handleCommentAdd() - { - if (!$this->_get['typeid'] || !$this->_get['type'] || !isset(Util::$typeStrings[$this->_get['type']])) - return; // whatever, we cant even send him back - - // trim to max length - if (!User::isInGroup(U_GROUP_MODERATOR) && mb_strlen($this->_post['commentbody']) > (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))) - $this->post['commentbody'] = mb_substr($this->_post['commentbody'], 0, (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))); - - if (User::canComment() && !empty($this->_post['commentbody']) && mb_strlen($this->_post['commentbody']) >= self::COMMENT_LENGTH_MIN) - { - if ($postIdx = DB::Aowow()->query('INSERT INTO ?_comments (type, typeId, userId, roles, body, date) VALUES (?d, ?d, ?d, ?d, ?, UNIX_TIMESTAMP())', $this->_get['type'], $this->_get['typeid'], User::$id, User::$groups, $this->_post['commentbody'])) - { - Util::gainSiteReputation(User::$id, SITEREP_ACTION_COMMENT, ['id' => $postIdx]); - - // every comment starts with a rating of +1 and i guess the simplest thing to do is create a db-entry with the system as owner - DB::Aowow()->query('INSERT INTO ?_comments_rates (commentId, userId, value) VALUES (?d, 0, 1)', $postIdx); - - // flag target with hasComment - if (Util::$typeClasses[$this->_get['type']] && ($tbl = (new Util::$typeClasses[$this->_get['type']](null))::$dataTable)) - DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_COMMENT, $this->_get['typeid']); - } - } - - $this->doRedirect = true; - return '?'.Util::$typeStrings[$this->_get['type']].'='.$this->_get['typeid'].'#comments'; - } - - protected function handleCommentEdit() - { - if ((!User::canComment() && !User::isInGroup(U_GROUP_MODERATOR)) || !$this->_get['id'] || !$this->_post['body']) - return; - - if (mb_strlen($this->_post['body']) < self::COMMENT_LENGTH_MIN) - return; - - // trim to max length - if (!User::isInGroup(U_GROUP_MODERATOR) && mb_strlen($this->_post['body']) > (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))) - $this->post['body'] = mb_substr($this->_post['body'], 0, (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))); - - $update = array( - 'body' => $this->_post['body'], - 'editUserId' => User::$id, - 'editDate' => time() - ); - - if (User::isInGroup(U_GROUP_MODERATOR)) - { - $update['responseBody'] = !$this->_post['response'] ? '' : $this->_post['response']; - $update['responseUserId'] = !$this->_post['response'] ? 0 : User::$id; - $update['responseRoles'] = !$this->_post['response'] ? 0 : User::$groups; - } - - DB::Aowow()->query('UPDATE ?_comments SET editCount = editCount + 1, ?a WHERE id = ?d', $update, $this->_get['id']); - } - - protected function handleCommentDelete() - { - if (!$this->_post['id'] || !User::$id) - return; - - // in theory, there is a username passed alongside... lets just use the current user (see user.js) - $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags | ?d, deleteUserId = ?d, deleteDate = UNIX_TIMESTAMP() WHERE id IN (?a){ AND userId = ?d}', - CC_FLAG_DELETED, - User::$id, - $this->_post['id'], - User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id - ); - - // deflag hasComment - if ($ok) - { - $coInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~b.flags) & ?d, 1, 0) as hasMore, b.type, b.typeId FROM ?_comments a JOIN ?_comments b ON a.type = b.type AND a.typeId = b.typeId WHERE a.id = ?d', - CC_FLAG_DELETED, - $this->_post['id'] - ); - - if (!$coInfo['hasMore'] && Util::$typeClasses[$coInfo['type']] && ($tbl = (new Util::$typeClasses[$coInfo['type']](null))::$dataTable)) - DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags & ~?d WHERE id = ?d', CUSTOM_HAS_COMMENT, $coInfo['typeId']); - } - } - - protected function handleCommentUndelete() - { - if (!$this->_post['id'] || !User::$id) - return; - - // in theory, there is a username passed alongside... lets just use the current user (see user.js) - $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags & ~?d WHERE id IN (?a){ AND userId = deleteUserId AND deleteUserId = ?d}', - CC_FLAG_DELETED, - $this->_post['id'], - User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id - ); - - // reflag hasComment - if ($ok) - { - $coInfo = DB::Aowow()->selectRow('SELECT type, typeId FROM ?_comments WHERE id = ?d', $this->_post['id']); - if (Util::$typeClasses[$coInfo['type']] && ($tbl = (new Util::$typeClasses[$coInfo['type']](null))::$dataTable)) - DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_COMMENT, $coInfo['typeId']); - } - } - - protected function handleCommentRating() - { - if (!$this->_get['id']) - return Util::toJSON(['success' => 0]); - - if ($votes = DB::Aowow()->selectRow('SELECT 1 AS success, SUM(IF(value > 0, value, 0)) AS up, SUM(IF(value < 0, -value, 0)) AS down FROM ?_comments_rates WHERE commentId = ?d and userId <> 0 GROUP BY commentId', $this->_get['id'])) - return Util::toJSON($votes); - else - return Util::toJSON(['success' => 1, 'up' => 0, 'down' => 0]); - } - - protected function handleCommentVote() - { - if (!User::$id || !$this->_get['id'] || !$this->_get['rating']) - return Util::toJSON(['error' => 1, 'message' => Lang::main('genericError')]); - - $target = DB::Aowow()->selectRow('SELECT c.userId AS owner, cr.value FROM ?_comments c LEFT JOIN ?_comments_rates cr ON cr.commentId = c.id AND cr.userId = ?d WHERE c.id = ?d', User::$id, $this->_get['id']); - $val = User::canSupervote() ? 2 : 1; - if ($this->_get['rating'] < 0) - $val *= -1; - - if (User::getCurDailyVotes() <= 0) - return Util::toJSON(['error' => 1, 'message' => Lang::main('tooManyVotes')]); - else if (!$target || $val != $this->_get['rating']) - return Util::toJSON(['error' => 1, 'message' => Lang::main('genericError')]); - else if (($val > 0 && !User::canUpvote()) || ($val < 0 && !User::canDownvote())) - return Util::toJSON(['error' => 1, 'message' => Lang::main('bannedRating')]); - - $ok = false; - // old and new have same sign; undo vote (user may have gained/lost access to superVote in the meantime) - if ($target['value'] && ($target['value'] < 0) == ($val < 0)) - $ok = DB::Aowow()->query('DELETE FROM ?_comments_rates WHERE commentId = ?d AND userId = ?d', $this->_get['id'], User::$id); - else // replace, because we may be overwriting an old, opposing vote - if ($ok = DB::Aowow()->query('REPLACE INTO ?_comments_rates (commentId, userId, value) VALUES (?d, ?d, ?d)', (int)$this->_get['id'], User::$id, $val)) - User::decrementDailyVotes(); // do not refund retracted votes! - - if (!$ok) - return Util::toJSON(['error' => 1, 'message' => Lang::main('genericError')]); - - if ($val > 0) // gain rep - Util::gainSiteReputation($target['owner'], SITEREP_ACTION_UPVOTED, ['id' => $this->_get['id'], 'voterId' => User::$id]); - else if ($val < 0) - Util::gainSiteReputation($target['owner'], SITEREP_ACTION_DOWNVOTED, ['id' => $this->_get['id'], 'voterId' => User::$id]); - - return Util::toJSON(['error' => 0]); - } - - protected function handleCommentSticky() - { - if (!$this->_post['id'] || !User::isInGroup(U_GROUP_MODERATOR)) - return; - - if ($this->_post['sticky']) - DB::Aowow()->query('UPDATE ?_comments SET flags = flags | ?d WHERE id = ?d', CC_FLAG_STICKY, $this->_post['id'][0]); - else - DB::Aowow()->query('UPDATE ?_comments SET flags = flags & ~?d WHERE id = ?d', CC_FLAG_STICKY, $this->_post['id'][0]); - } - - protected function handleCommentOutOfDate() - { - $this->contentType = 'text/plain'; - - if (!$this->_post['id']) - return 'The comment does not exist.'; - - $ok = false; - if (User::isInGroup(U_GROUP_MODERATOR)) // directly mark as outdated - { - if (!$this->_post['remove']) - $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags | 0x4 WHERE id = ?d', $this->_post['id'][0]); - else - $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags & ~0x4 WHERE id = ?d', $this->_post['id'][0]); - } - else if (User::$id && !$this->_post['reason'] || mb_strlen($this->_post['reason']) < self::REPLY_LENGTH_MIN) - return 'Your message is too short.'; - else if (User::$id) // only report as outdated - { - $ok = DB::Aowow()->query( - 'INSERT INTO ?_reports (userId, mode, reason, subject, ip, description, userAgent, appName) VALUES (?d, 1, 17, ?d, ?, "", ?, ?)', - User::$id, - $this->_post['id'][0], - User::$ip, - $_SERVER['HTTP_USER_AGENT'], - get_browser(null, true)['browser'] - ); - } - - if ($ok) // this one is very special; as in: completely retarded - return 'ok'; // the script expects the actual characters 'ok' not some string like "ok" - - return Lang::main('genericError'); - } - - protected function handleCommentShowReplies() - { - return Util::toJSON(!$this->_get['id'] ? [] : CommunityContent::getCommentReplies($this->_get['id'])); - } - - protected function handleReplyAdd() - { - $this->contentType = 'text/plain'; - - if (!User::canComment()) - return 'You are not allowed to reply.'; - - else if (!$this->_post['commentId'] || !DB::Aowow()->selectCell('SELECT 1 FROM ?_comments WHERE id = ?d', $this->_post['commentId'])) - return Lang::main('genericError'); - - else if (!$this->_post['body'] || mb_strlen($this->_post['body']) < self::REPLY_LENGTH_MIN || mb_strlen($this->_post['body']) > self::REPLY_LENGTH_MAX) - return 'Your reply has '.mb_strlen($this->_post['body']).' characters and must have at least '.self::REPLY_LENGTH_MIN.' and at most '.self::REPLY_LENGTH_MAX.'.'; - - else if (DB::Aowow()->query('INSERT INTO ?_comments (`userId`, `roles`, `body`, `date`, `replyTo`) VALUES (?d, ?d, ?, UNIX_TIMESTAMP(), ?d)', User::$id, User::$groups, $this->_post['body'], $this->_post['commentId'])) - return Util::toJSON(CommunityContent::getCommentReplies($this->_post['commentId'])); - - else - return Lang::main('genericError'); - } - - protected function handleReplyEdit() - { - $this->contentType = 'text/plain'; - - if (!User::canComment()) - return 'You are not allowed to reply.'; - - else if (!$this->_post['replyId'] || !$this->_post['commentId']) - return Lang::main('genericError'); - - else if (!$this->_post['body'] || mb_strlen($this->_post['body']) < self::REPLY_LENGTH_MIN || mb_strlen($this->_post['body']) > self::REPLY_LENGTH_MAX) - return 'Your reply has '.mb_strlen($this->_post['body']).' characters and must have at least '.self::REPLY_LENGTH_MIN.' and at most '.self::REPLY_LENGTH_MAX.'.'; - - if (DB::Aowow()->query('UPDATE ?_comments SET body = ?, editUserId = ?d, editDate = UNIX_TIMESTAMP(), editCount = editCount + 1 WHERE id = ?d AND replyTo = ?d{ AND userId = ?d}', - $this->_post['body'], User::$id, $this->_post['replyId'], $this->_post['commentId'], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id)) - return Util::toJSON(CommunityContent::getCommentReplies($this->_post['commentId'])); - else - return Lang::main('genericError'); - } - - protected function handleReplyDetach() - { - if (!User::isInGroup(U_GROUP_MODERATOR) || !$this->_post['id']) - return; - - DB::Aowow()->query('UPDATE ?_comments c1, ?_comments c2 SET c1.replyTo = 0, c1.type = c2.type, c1.typeId = c2.typeId WHERE c1.replyTo = c2.id AND c1.id = ?d', $this->_post['id'][0]); - } - - protected function handleReplyDelete() - { - if (!User::$id || !$this->_post['id']) - return; - - if (DB::Aowow()->query('DELETE FROM ?_comments WHERE id = ?d{ AND userId = ?d}', $this->_post['id'][0], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id)) - DB::Aowow()->query('DELETE FROM ?_comments_rates WHERE commentId = ?d', $this->_post['id'][0]); - } - - protected function handleReplyFlag() - { - if (!User::$id || !$this->_post['id']) - return; - - DB::Aowow()->query( - 'INSERT INTO ?_reports (userId, mode, reason, subject, ip, description, userAgent, appName) VALUES (?d, 1, 19, ?d, ?, "", ?, ?)', - User::$id, - $this->_post['id'][0], - User::$ip, - $_SERVER['HTTP_USER_AGENT'], - get_browser(null, true)['browser'] - ); - } - - protected function handleReplyUpvote() - { - if (!$this->_post['id'] || !User::canUpvote()) - return; - - $owner = DB::Aowow()->selectCell('SELECT userId FROM ?_comments WHERE id = ?d', $this->_post['id'][0]); - if (!$owner) - return; - - $ok = DB::Aowow()->query( - 'INSERT INTO ?_comments_rates (commentId, userId, value) VALUES (?d, ?d, ?d)', - $this->_post['id'][0], - User::$id, - User::canSupervote() ? 2 : 1 - ); - - if ($ok) - { - Util::gainSiteReputation($owner, SITEREP_ACTION_UPVOTED, ['id' => $this->_post['id'][0], 'voterId' => User::$id]); - User::decrementDailyVotes(); - } - } - - protected function handleReplyDownvote() - { - if (!$this->_post['id'] || !User::canDownvote()) - return; - - $owner = DB::Aowow()->selectCell('SELECT userId FROM ?_comments WHERE id = ?d', $this->_post['id'][0]); - if (!$owner) - return; - - $ok = DB::Aowow()->query( - 'INSERT INTO ?_comments_rates (commentId, userId, value) VALUES (?d, ?d, ?d)', - $this->_post['id'][0], - User::$id, - User::canSupervote() ? -2 : -1 - ); - - if ($ok) - { - Util::gainSiteReputation($owner, SITEREP_ACTION_DOWNVOTED, ['id' => $this->_post['id'][0], 'voterId' => User::$id]); - User::decrementDailyVotes(); - } - } - - protected function checkId($val) - { - // expecting id-list - if (preg_match('/\d+(,\d+)*/', $val)) - return array_map('intVal', explode(',', $val)); - - return null; - } -} -?> \ No newline at end of file + [FILTER_CALLBACK, ['options' => 'AjaxComment::checkId']], + 'body' => [FILTER_UNSAFE_RAW, null],// escaped by json_encode + 'commentbody' => [FILTER_UNSAFE_RAW, null],// escaped by json_encode + 'response' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], + 'reason' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], + 'remove' => [FILTER_SANITIZE_NUMBER_INT, null], + 'commentId' => [FILTER_SANITIZE_NUMBER_INT, null], + 'replyId' => [FILTER_SANITIZE_NUMBER_INT, null], + // 'username' => [FILTER_SANITIZE_STRING, 0xC] // FILTER_FLAG_STRIP_LOW | *_HIGH + ); + + protected $_get = array( + 'id' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'type' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'typeid' => [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']], + 'rating' => [FILTER_SANITIZE_NUMBER_INT, null] + ); + + public function __construct(array $params) + { + parent::__construct($params); + + if (!$this->params || count($this->params) != 1) + return; + + // note: return values must be formated as STRICT json! + + // select handler + if ($this->params[0] == 'add') + $this->handler = 'handleCommentAdd'; + else if ($this->params[0] == 'edit') + $this->handler = 'handleCommentEdit'; + else if ($this->params[0] == 'delete') + $this->handler = 'handleCommentDelete'; + else if ($this->params[0] == 'undelete') + $this->handler = 'handleCommentUndelete'; + else if ($this->params[0] == 'rating') // up/down - distribution + $this->handler = 'handleCommentRating'; + else if ($this->params[0] == 'vote') // up, down and remove + $this->handler = 'handleCommentVote'; + else if ($this->params[0] == 'sticky') // toggle flag + $this->handler = 'handleCommentSticky'; + else if ($this->params[0] == 'out-of-date') // toggle flag + $this->handler = 'handleCommentOutOfDate'; + else if ($this->params[0] == 'show-replies') + $this->handler = 'handleCommentShowReplies'; + else if ($this->params[0] == 'add-reply') // also returns all replies on success + $this->handler = 'handleReplyAdd'; + else if ($this->params[0] == 'edit-reply') // also returns all replies on success + $this->handler = 'handleReplyEdit'; + else if ($this->params[0] == 'detach-reply') + $this->handler = 'handleReplyDetach'; + else if ($this->params[0] == 'delete-reply') + $this->handler = 'handleReplyDelete'; + else if ($this->params[0] == 'flag-reply') + $this->handler = 'handleReplyFlag'; + else if ($this->params[0] == 'upvote-reply') + $this->handler = 'handleReplyUpvote'; + else if ($this->params[0] == 'downvote-reply') + $this->handler = 'handleReplyDownvote'; + } + + // i .. have problems believing, that everything uses nifty ajax while adding comments requires a brutal header(Loacation: ), yet, thats how it is + protected function handleCommentAdd() + { + if (!$this->_get['typeid'] || !$this->_get['type'] || !isset(Util::$typeStrings[$this->_get['type']])) + return; // whatever, we cant even send him back + + // trim to max length + if (!User::isInGroup(U_GROUP_MODERATOR) && mb_strlen($this->_post['commentbody']) > (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))) + $this->post['commentbody'] = mb_substr($this->_post['commentbody'], 0, (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))); + + if (User::canComment() && !empty($this->_post['commentbody']) && mb_strlen($this->_post['commentbody']) >= self::COMMENT_LENGTH_MIN) + { + if ($postIdx = DB::Aowow()->query('INSERT INTO ?_comments (type, typeId, userId, roles, body, date) VALUES (?d, ?d, ?d, ?d, ?, UNIX_TIMESTAMP())', $this->_get['type'], $this->_get['typeid'], User::$id, User::$groups, $this->_post['commentbody'])) + { + Util::gainSiteReputation(User::$id, SITEREP_ACTION_COMMENT, ['id' => $postIdx]); + + // every comment starts with a rating of +1 and i guess the simplest thing to do is create a db-entry with the system as owner + DB::Aowow()->query('INSERT INTO ?_comments_rates (commentId, userId, value) VALUES (?d, 0, 1)', $postIdx); + + // flag target with hasComment + if (Util::$typeClasses[$this->_get['type']] && ($tbl = get_class_vars(Util::$typeClasses[$this->_get['type'])['dataTable'])) + DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_COMMENT, $this->_get['typeid']); + } + } + + $this->doRedirect = true; + return '?'.Util::$typeStrings[$this->_get['type']].'='.$this->_get['typeid'].'#comments'; + } + + protected function handleCommentEdit() + { + if ((!User::canComment() && !User::isInGroup(U_GROUP_MODERATOR)) || !$this->_get['id'] || !$this->_post['body']) + return; + + if (mb_strlen($this->_post['body']) < self::COMMENT_LENGTH_MIN) + return; + + // trim to max length + if (!User::isInGroup(U_GROUP_MODERATOR) && mb_strlen($this->_post['body']) > (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))) + $this->post['body'] = mb_substr($this->_post['body'], 0, (self::COMMENT_LENGTH_MAX * (User::isPremium() ? 3 : 1))); + + $update = array( + 'body' => $this->_post['body'], + 'editUserId' => User::$id, + 'editDate' => time() + ); + + if (User::isInGroup(U_GROUP_MODERATOR)) + { + $update['responseBody'] = !$this->_post['response'] ? '' : $this->_post['response']; + $update['responseUserId'] = !$this->_post['response'] ? 0 : User::$id; + $update['responseRoles'] = !$this->_post['response'] ? 0 : User::$groups; + } + + DB::Aowow()->query('UPDATE ?_comments SET editCount = editCount + 1, ?a WHERE id = ?d', $update, $this->_get['id']); + } + + protected function handleCommentDelete() + { + if (!$this->_post['id'] || !User::$id) + return; + + // in theory, there is a username passed alongside... lets just use the current user (see user.js) + $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags | ?d, deleteUserId = ?d, deleteDate = UNIX_TIMESTAMP() WHERE id IN (?a){ AND userId = ?d}', + CC_FLAG_DELETED, + User::$id, + $this->_post['id'], + User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id + ); + + // deflag hasComment + if ($ok) + { + $coInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~b.flags) & ?d, 1, 0) as hasMore, b.type, b.typeId FROM ?_comments a JOIN ?_comments b ON a.type = b.type AND a.typeId = b.typeId WHERE a.id = ?d', + CC_FLAG_DELETED, + $this->_post['id'] + ); + + if (!$coInfo['hasMore'] && Util::$typeClasses[$coInfo['type']] && ($tbl = get_class_vars(Util::$typeClasses[$coInfo['type'])['dataTable'])) + DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags & ~?d WHERE id = ?d', CUSTOM_HAS_COMMENT, $coInfo['typeId']); + } + } + + protected function handleCommentUndelete() + { + if (!$this->_post['id'] || !User::$id) + return; + + // in theory, there is a username passed alongside... lets just use the current user (see user.js) + $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags & ~?d WHERE id IN (?a){ AND userId = deleteUserId AND deleteUserId = ?d}', + CC_FLAG_DELETED, + $this->_post['id'], + User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id + ); + + // reflag hasComment + if ($ok) + { + $coInfo = DB::Aowow()->selectRow('SELECT type, typeId FROM ?_comments WHERE id = ?d', $this->_post['id']); + if (Util::$typeClasses[$coInfo['type']] && ($tbl = (new get_class_vars(Util::$typeClasses[$coInfo['type'])['dataTable'])) + DB::Aowow()->query('UPDATE '.$tbl.' SET cuFlags = cuFlags | ?d WHERE id = ?d', CUSTOM_HAS_COMMENT, $coInfo['typeId']); + } + } + + protected function handleCommentRating() + { + if (!$this->_get['id']) + return Util::toJSON(['success' => 0]); + + if ($votes = DB::Aowow()->selectRow('SELECT 1 AS success, SUM(IF(value > 0, value, 0)) AS up, SUM(IF(value < 0, -value, 0)) AS down FROM ?_comments_rates WHERE commentId = ?d and userId <> 0 GROUP BY commentId', $this->_get['id'])) + return Util::toJSON($votes); + else + return Util::toJSON(['success' => 1, 'up' => 0, 'down' => 0]); + } + + protected function handleCommentVote() + { + if (!User::$id || !$this->_get['id'] || !$this->_get['rating']) + return Util::toJSON(['error' => 1, 'message' => Lang::main('genericError')]); + + $target = DB::Aowow()->selectRow('SELECT c.userId AS owner, cr.value FROM ?_comments c LEFT JOIN ?_comments_rates cr ON cr.commentId = c.id AND cr.userId = ?d WHERE c.id = ?d', User::$id, $this->_get['id']); + $val = User::canSupervote() ? 2 : 1; + if ($this->_get['rating'] < 0) + $val *= -1; + + if (User::getCurDailyVotes() <= 0) + return Util::toJSON(['error' => 1, 'message' => Lang::main('tooManyVotes')]); + else if (!$target || $val != $this->_get['rating']) + return Util::toJSON(['error' => 1, 'message' => Lang::main('genericError')]); + else if (($val > 0 && !User::canUpvote()) || ($val < 0 && !User::canDownvote())) + return Util::toJSON(['error' => 1, 'message' => Lang::main('bannedRating')]); + + $ok = false; + // old and new have same sign; undo vote (user may have gained/lost access to superVote in the meantime) + if ($target['value'] && ($target['value'] < 0) == ($val < 0)) + $ok = DB::Aowow()->query('DELETE FROM ?_comments_rates WHERE commentId = ?d AND userId = ?d', $this->_get['id'], User::$id); + else // replace, because we may be overwriting an old, opposing vote + if ($ok = DB::Aowow()->query('REPLACE INTO ?_comments_rates (commentId, userId, value) VALUES (?d, ?d, ?d)', (int)$this->_get['id'], User::$id, $val)) + User::decrementDailyVotes(); // do not refund retracted votes! + + if (!$ok) + return Util::toJSON(['error' => 1, 'message' => Lang::main('genericError')]); + + if ($val > 0) // gain rep + Util::gainSiteReputation($target['owner'], SITEREP_ACTION_UPVOTED, ['id' => $this->_get['id'], 'voterId' => User::$id]); + else if ($val < 0) + Util::gainSiteReputation($target['owner'], SITEREP_ACTION_DOWNVOTED, ['id' => $this->_get['id'], 'voterId' => User::$id]); + + return Util::toJSON(['error' => 0]); + } + + protected function handleCommentSticky() + { + if (!$this->_post['id'] || !User::isInGroup(U_GROUP_MODERATOR)) + return; + + if ($this->_post['sticky']) + DB::Aowow()->query('UPDATE ?_comments SET flags = flags | ?d WHERE id = ?d', CC_FLAG_STICKY, $this->_post['id'][0]); + else + DB::Aowow()->query('UPDATE ?_comments SET flags = flags & ~?d WHERE id = ?d', CC_FLAG_STICKY, $this->_post['id'][0]); + } + + protected function handleCommentOutOfDate() + { + $this->contentType = 'text/plain'; + + if (!$this->_post['id']) + return 'The comment does not exist.'; + + $ok = false; + if (User::isInGroup(U_GROUP_MODERATOR)) // directly mark as outdated + { + if (!$this->_post['remove']) + $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags | 0x4 WHERE id = ?d', $this->_post['id'][0]); + else + $ok = DB::Aowow()->query('UPDATE ?_comments SET flags = flags & ~0x4 WHERE id = ?d', $this->_post['id'][0]); + } + else if (User::$id && !$this->_post['reason'] || mb_strlen($this->_post['reason']) < self::REPLY_LENGTH_MIN) + return 'Your message is too short.'; + else if (User::$id) // only report as outdated + { + $ok = DB::Aowow()->query( + 'INSERT INTO ?_reports (userId, mode, reason, subject, ip, description, userAgent, appName) VALUES (?d, 1, 17, ?d, ?, "", ?, ?)', + User::$id, + $this->_post['id'][0], + User::$ip, + $_SERVER['HTTP_USER_AGENT'], + get_browser(null, true)['browser'] + ); + } + + if ($ok) // this one is very special; as in: completely retarded + return 'ok'; // the script expects the actual characters 'ok' not some string like "ok" + + return Lang::main('genericError'); + } + + protected function handleCommentShowReplies() + { + return Util::toJSON(!$this->_get['id'] ? [] : CommunityContent::getCommentReplies($this->_get['id'])); + } + + protected function handleReplyAdd() + { + $this->contentType = 'text/plain'; + + if (!User::canComment()) + return 'You are not allowed to reply.'; + + else if (!$this->_post['commentId'] || !DB::Aowow()->selectCell('SELECT 1 FROM ?_comments WHERE id = ?d', $this->_post['commentId'])) + return Lang::main('genericError'); + + else if (!$this->_post['body'] || mb_strlen($this->_post['body']) < self::REPLY_LENGTH_MIN || mb_strlen($this->_post['body']) > self::REPLY_LENGTH_MAX) + return 'Your reply has '.mb_strlen($this->_post['body']).' characters and must have at least '.self::REPLY_LENGTH_MIN.' and at most '.self::REPLY_LENGTH_MAX.'.'; + + else if (DB::Aowow()->query('INSERT INTO ?_comments (`userId`, `roles`, `body`, `date`, `replyTo`) VALUES (?d, ?d, ?, UNIX_TIMESTAMP(), ?d)', User::$id, User::$groups, $this->_post['body'], $this->_post['commentId'])) + return Util::toJSON(CommunityContent::getCommentReplies($this->_post['commentId'])); + + else + return Lang::main('genericError'); + } + + protected function handleReplyEdit() + { + $this->contentType = 'text/plain'; + + if (!User::canComment()) + return 'You are not allowed to reply.'; + + else if (!$this->_post['replyId'] || !$this->_post['commentId']) + return Lang::main('genericError'); + + else if (!$this->_post['body'] || mb_strlen($this->_post['body']) < self::REPLY_LENGTH_MIN || mb_strlen($this->_post['body']) > self::REPLY_LENGTH_MAX) + return 'Your reply has '.mb_strlen($this->_post['body']).' characters and must have at least '.self::REPLY_LENGTH_MIN.' and at most '.self::REPLY_LENGTH_MAX.'.'; + + if (DB::Aowow()->query('UPDATE ?_comments SET body = ?, editUserId = ?d, editDate = UNIX_TIMESTAMP(), editCount = editCount + 1 WHERE id = ?d AND replyTo = ?d{ AND userId = ?d}', + $this->_post['body'], User::$id, $this->_post['replyId'], $this->_post['commentId'], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id)) + return Util::toJSON(CommunityContent::getCommentReplies($this->_post['commentId'])); + else + return Lang::main('genericError'); + } + + protected function handleReplyDetach() + { + if (!User::isInGroup(U_GROUP_MODERATOR) || !$this->_post['id']) + return; + + DB::Aowow()->query('UPDATE ?_comments c1, ?_comments c2 SET c1.replyTo = 0, c1.type = c2.type, c1.typeId = c2.typeId WHERE c1.replyTo = c2.id AND c1.id = ?d', $this->_post['id'][0]); + } + + protected function handleReplyDelete() + { + if (!User::$id || !$this->_post['id']) + return; + + if (DB::Aowow()->query('DELETE FROM ?_comments WHERE id = ?d{ AND userId = ?d}', $this->_post['id'][0], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id)) + DB::Aowow()->query('DELETE FROM ?_comments_rates WHERE commentId = ?d', $this->_post['id'][0]); + } + + protected function handleReplyFlag() + { + if (!User::$id || !$this->_post['id']) + return; + + DB::Aowow()->query( + 'INSERT INTO ?_reports (userId, mode, reason, subject, ip, description, userAgent, appName) VALUES (?d, 1, 19, ?d, ?, "", ?, ?)', + User::$id, + $this->_post['id'][0], + User::$ip, + $_SERVER['HTTP_USER_AGENT'], + get_browser(null, true)['browser'] + ); + } + + protected function handleReplyUpvote() + { + if (!$this->_post['id'] || !User::canUpvote()) + return; + + $owner = DB::Aowow()->selectCell('SELECT userId FROM ?_comments WHERE id = ?d', $this->_post['id'][0]); + if (!$owner) + return; + + $ok = DB::Aowow()->query( + 'INSERT INTO ?_comments_rates (commentId, userId, value) VALUES (?d, ?d, ?d)', + $this->_post['id'][0], + User::$id, + User::canSupervote() ? 2 : 1 + ); + + if ($ok) + { + Util::gainSiteReputation($owner, SITEREP_ACTION_UPVOTED, ['id' => $this->_post['id'][0], 'voterId' => User::$id]); + User::decrementDailyVotes(); + } + } + + protected function handleReplyDownvote() + { + if (!$this->_post['id'] || !User::canDownvote()) + return; + + $owner = DB::Aowow()->selectCell('SELECT userId FROM ?_comments WHERE id = ?d', $this->_post['id'][0]); + if (!$owner) + return; + + $ok = DB::Aowow()->query( + 'INSERT INTO ?_comments_rates (commentId, userId, value) VALUES (?d, ?d, ?d)', + $this->_post['id'][0], + User::$id, + User::canSupervote() ? -2 : -1 + ); + + if ($ok) + { + Util::gainSiteReputation($owner, SITEREP_ACTION_DOWNVOTED, ['id' => $this->_post['id'][0], 'voterId' => User::$id]); + User::decrementDailyVotes(); + } + } + + protected function checkId($val) + { + // expecting id-list + if (preg_match('/\d+(,\d+)*/', $val)) + return array_map('intVal', explode(',', $val)); + + return null; + } +} +?> diff --git a/includes/ajaxHandler/contactus.class.php b/includes/ajaxHandler/contactus.class.php index 3bc04b88..5039a53f 100644 --- a/includes/ajaxHandler/contactus.class.php +++ b/includes/ajaxHandler/contactus.class.php @@ -1,100 +1,100 @@ - [FILTER_SANITIZE_NUMBER_INT, null], - 'reason' => [FILTER_SANITIZE_NUMBER_INT, null], - 'ua' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], - 'appname' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], - 'page' => [FILTER_SANITIZE_URL, null], - 'desc' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], - 'id' => [FILTER_SANITIZE_NUMBER_INT, null], - 'relatedurl' => [FILTER_SANITIZE_URL, null], - 'email' => [FILTER_SANITIZE_EMAIL, null] - ); - - public function __construct(array $params) - { - parent::__construct($params); - - // always this one - $this->handler = 'handleContactUs'; - } - - /* responses - 0: success - 1: captcha invalid - 2: description too long - 3: reason missing - 7: already reported - $: prints response - */ - protected function handleContactUs() - { - $mode = $this->_post['mode']; - $rsn = $this->_post['reason']; - $ua = $this->_post['ua']; - $app = $this->_post['appname']; - $url = $this->_post['page']; - $desc = $this->_post['desc']; - - $contexts = array( - [1, 2, 3, 4, 5, 6, 7, 8], - [15, 16, 17, 18, 19, 20], - [30, 31, 32, 33, 34, 35, 36, 37], - [45, 46, 47, 48], - [60, 61], - [45, 46, 47, 48], - [45, 46, 48] - ); - - if ($mode === null || $rsn === null || $ua === null || $app === null || $url === null) - return 'required field missing'; - - if (!isset($contexts[$mode]) || !in_array($rsn, $contexts[$mode])) - return 'mode invalid'; - - if (!$desc) - return 3; - - if (mb_strlen($desc) > 500) - return 2; - - if (!User::$id && !User::$ip) - return 'your ip could not be determined'; - - // check already reported - $field = User::$id ? 'userId' : 'ip'; - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_reports WHERE `mode` = ?d AND `reason`= ?d AND `subject` = ?d AND ?# = ?', $mode, $rsn, $this->_post['id'], $field, User::$id ?: User::$ip)) - return 7; - - $update = array( - 'userId' => User::$id, - 'mode' => $mode, - 'reason' => $rsn, - 'ip' => User::$ip, - 'description' => $desc, - 'userAgent' => $ua, - 'appName' => $app, - 'url' => $url - ); - - if ($_ = $this->_post['id']) - $update['subject'] = $_; - - if ($_ = $this->_post['relatedurl']) - $update['relatedurl'] = $_; - - if ($_ = $this->_post['email']) - $update['email'] = $_; - - if (DB::Aowow()->query('INSERT INTO ?_reports (?#) VALUES (?a)', array_keys($update), array_values($update))) - return 0; - - return 'save to db unsuccessful'; - } + [FILTER_SANITIZE_NUMBER_INT, null], + 'reason' => [FILTER_SANITIZE_NUMBER_INT, null], + 'ua' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], + 'appname' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], + 'page' => [FILTER_SANITIZE_URL, null], + 'desc' => [FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW], + 'id' => [FILTER_SANITIZE_NUMBER_INT, null], + 'relatedurl' => [FILTER_SANITIZE_URL, null], + 'email' => [FILTER_SANITIZE_EMAIL, null] + ); + + public function __construct(array $params) + { + parent::__construct($params); + + // always this one + $this->handler = 'handleContactUs'; + } + + /* responses + 0: success + 1: captcha invalid + 2: description too long + 3: reason missing + 7: already reported + $: prints response + */ + protected function handleContactUs() + { + $mode = $this->_post['mode']; + $rsn = $this->_post['reason']; + $ua = $this->_post['ua']; + $app = $this->_post['appname']; + $url = $this->_post['page']; + $desc = $this->_post['desc']; + + $contexts = array( + [1, 2, 3, 4, 5, 6, 7, 8], + [15, 16, 17, 18, 19, 20], + [30, 31, 32, 33, 34, 35, 36, 37], + [45, 46, 47, 48], + [60, 61], + [45, 46, 47, 48], + [45, 46, 48] + ); + + if ($mode === null || $rsn === null || $ua === null || $app === null || $url === null) + return 'required field missing'; + + if (!isset($contexts[$mode]) || !in_array($rsn, $contexts[$mode])) + return 'mode invalid'; + + if (!$desc) + return 3; + + if (mb_strlen($desc) > 500) + return 2; + + if (!User::$id && !User::$ip) + return 'your ip could not be determined'; + + // check already reported + $field = User::$id ? 'userId' : 'ip'; + if (DB::Aowow()->selectCell('SELECT 1 FROM ?_reports WHERE `mode` = ?d AND `reason`= ?d AND `subject` = ?d AND ?# = ?', $mode, $rsn, $this->_post['id'], $field, User::$id ?: User::$ip)) + return 7; + + $update = array( + 'userId' => User::$id, + 'mode' => $mode, + 'reason' => $rsn, + 'ip' => User::$ip, + 'description' => $desc, + 'userAgent' => $ua, + 'appName' => $app, + 'url' => $url + ); + + if ($_ = $this->_post['id']) + $update['subject'] = $_; + + if ($_ = $this->_post['relatedurl']) + $update['relatedurl'] = $_; + + if ($_ = $this->_post['email']) + $update['email'] = $_; + + if (DB::Aowow()->query('INSERT INTO ?_reports (?#) VALUES (?a)', array_keys($update), array_values($update))) + return 0; + + return 'save to db unsuccessful'; + } } \ No newline at end of file diff --git a/includes/ajaxHandler/cookie.class.php b/includes/ajaxHandler/cookie.class.php index f548abb9..b824f325 100644 --- a/includes/ajaxHandler/cookie.class.php +++ b/includes/ajaxHandler/cookie.class.php @@ -1,37 +1,37 @@ -_get = array( - this->params[0] => [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH - ); - - // NOW we know, what to expect and sanitize - parent::__construct($params); - - // always this one - $this->handler = 'handleCookie'; - } - - /* responses - 0: success - $: silent error - */ - protected function handleCookie() - { - if (User::$id && $this->params && $this->_get[$this->params[0]]) - if (DB::Aowow()->query('REPLACE INTO ?_account_cookies VALUES (?d, ?, ?)', User::$id, $this->params[0], $this->_get[$this->params[0]])) - return 0; - - return null; - } +_get = array( + this->params[0] => [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH + ); + + // NOW we know, what to expect and sanitize + parent::__construct($params); + + // always this one + $this->handler = 'handleCookie'; + } + + /* responses + 0: success + $: silent error + */ + protected function handleCookie() + { + if (User::$id && $this->params && $this->_get[$this->params[0]]) + if (DB::Aowow()->query('REPLACE INTO ?_account_cookies VALUES (?d, ?, ?)', User::$id, $this->params[0], $this->_get[$this->params[0]])) + return 0; + + return null; + } } \ No newline at end of file diff --git a/includes/ajaxHandler/data.class.php b/includes/ajaxHandler/data.class.php index ab022fab..ca5fb30e 100644 --- a/includes/ajaxHandler/data.class.php +++ b/includes/ajaxHandler/data.class.php @@ -1,138 +1,138 @@ - [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkLocale']], - 't' => [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH - 'catg' => [FILTER_SANITIZE_NUMBER_INT, null], - 'skill' => [FILTER_CALLBACK, ['options' => 'AjaxData::checkSkill']], - 'class' => [FILTER_SANITIZE_NUMBER_INT, null], - 'callback' => [FILTER_CALLBACK, ['options' => 'AjaxData::checkCallback']] - ); - - public function __construct(array $params) - { - parent::__construct($params); - - if (is_numeric($this->_get['locale'])) - User::useLocale($this->_get['locale']); - - // always this one - $this->handler = 'handleData'; - } - - /* responses - - */ - protected function handleData() - { - $result = ''; - - // different data can be strung together - foreach ($this->params as $set) - { - // requires valid token to hinder automated access - if ($set != 'item-scaling') - if (!$this->_get['t'] || empty($_SESSION['dataKey']) || $this->_get['t'] != $_SESSION['dataKey']) - continue; - - switch ($set) - { - /* issue on no initial data: - when we loadOnDemand, the jScript tries to generate the catg-tree before it is initialized - it cant be initialized, without loading the data as empty catg are omitted - loading the data triggers the generation of the catg-tree - */ - case 'factions': - $result .= $this->loadProfilerData($set); - break; - case 'companions': - $result .= $this->loadProfilerData($set, '778'); - break; - case 'mounts': - $result .= $this->loadProfilerData($set, '777'); - break; - case 'quests': - // &partial: im not doing this right - // it expects a full quest dump on first lookup but will query subCats again if clicked..? - // for now omiting the detail clicks with empty results and just set catg update - $catg = $this->_get['catg'] ?: 'null'; - if ($catg == 'null') - $result .= $this->loadProfilerData($set); - else if ($this->_get['callback']) - $result .= "\n\$WowheadProfiler.loadOnDemand('quests', ".$catg.");\n"; - - break; - case 'recipes': - if (!$this->_get['callback'] || !$this->_get['skill']) - break; - - foreach ($this->_get['skill'] as $s) - Util::loadStaticFile('p-recipes-'.$s, $result, true); - - Util::loadStaticFile('p-recipes-sec', $result, true); - $result .= "\n\$WowheadProfiler.loadOnDemand('recipes', null);\n"; - - break; - // locale independant - case 'quick-excludes': // generated per character in profiler - case 'zones': - case 'weight-presets': - case 'item-scaling': - case 'realms': - case 'statistics': - if (!Util::loadStaticFile($set, $result) && CFG_DEBUG) - $result .= "alert('could not fetch static data: ".$set."');"; - - $result .= "\n\n"; - break; - // localized - case 'talents': - if ($_ = $this->_get['class']) - $set .= "-".$_; - case 'pet-talents': - case 'glyphs': - case 'gems': - case 'enchants': - case 'itemsets': - case 'pets': - if (!Util::loadStaticFile($set, $result, true) && CFG_DEBUG) - $result .= "alert('could not fetch static data: ".$set." for locale: ".User::$localeString."');"; - - $result .= "\n\n"; - break; - default: - break; - } - } - - return $result; - } - - private function checkSkill($val) - { - return array_intersect([171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, 185, 129, 356], explode(',', $val)); - } - - private function checkCallback($val) - { - return substr($val, 0, 29) == '$WowheadProfiler.loadOnDemand'; - } - - private function loadProfilerData($file, $catg = 'null') - { - $result = ''; - if ($this->_get['callback']) - if (Util::loadStaticFile('p-'.$file, $result, true)) - $result .= "\n\$WowheadProfiler.loadOnDemand('".$file."', ".$catg.");\n"; - - return $result; - } - -} - + [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkLocale']], + 't' => [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH + 'catg' => [FILTER_SANITIZE_NUMBER_INT, null], + 'skill' => [FILTER_CALLBACK, ['options' => 'AjaxData::checkSkill']], + 'class' => [FILTER_SANITIZE_NUMBER_INT, null], + 'callback' => [FILTER_CALLBACK, ['options' => 'AjaxData::checkCallback']] + ); + + public function __construct(array $params) + { + parent::__construct($params); + + if (is_numeric($this->_get['locale'])) + User::useLocale($this->_get['locale']); + + // always this one + $this->handler = 'handleData'; + } + + /* responses + + */ + protected function handleData() + { + $result = ''; + + // different data can be strung together + foreach ($this->params as $set) + { + // requires valid token to hinder automated access + if ($set != 'item-scaling') + if (!$this->_get['t'] || empty($_SESSION['dataKey']) || $this->_get['t'] != $_SESSION['dataKey']) + continue; + + switch ($set) + { + /* issue on no initial data: + when we loadOnDemand, the jScript tries to generate the catg-tree before it is initialized + it cant be initialized, without loading the data as empty catg are omitted + loading the data triggers the generation of the catg-tree + */ + case 'factions': + $result .= $this->loadProfilerData($set); + break; + case 'companions': + $result .= $this->loadProfilerData($set, '778'); + break; + case 'mounts': + $result .= $this->loadProfilerData($set, '777'); + break; + case 'quests': + // &partial: im not doing this right + // it expects a full quest dump on first lookup but will query subCats again if clicked..? + // for now omiting the detail clicks with empty results and just set catg update + $catg = $this->_get['catg'] ?: 'null'; + if ($catg == 'null') + $result .= $this->loadProfilerData($set); + else if ($this->_get['callback']) + $result .= "\n\$WowheadProfiler.loadOnDemand('quests', ".$catg.");\n"; + + break; + case 'recipes': + if (!$this->_get['callback'] || !$this->_get['skill']) + break; + + foreach ($this->_get['skill'] as $s) + Util::loadStaticFile('p-recipes-'.$s, $result, true); + + Util::loadStaticFile('p-recipes-sec', $result, true); + $result .= "\n\$WowheadProfiler.loadOnDemand('recipes', null);\n"; + + break; + // locale independant + case 'quick-excludes': // generated per character in profiler + case 'zones': + case 'weight-presets': + case 'item-scaling': + case 'realms': + case 'statistics': + if (!Util::loadStaticFile($set, $result) && CFG_DEBUG) + $result .= "alert('could not fetch static data: ".$set."');"; + + $result .= "\n\n"; + break; + // localized + case 'talents': + if ($_ = $this->_get['class']) + $set .= "-".$_; + case 'pet-talents': + case 'glyphs': + case 'gems': + case 'enchants': + case 'itemsets': + case 'pets': + if (!Util::loadStaticFile($set, $result, true) && CFG_DEBUG) + $result .= "alert('could not fetch static data: ".$set." for locale: ".User::$localeString."');"; + + $result .= "\n\n"; + break; + default: + break; + } + } + + return $result; + } + + private function checkSkill($val) + { + return array_intersect([171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, 185, 129, 356], explode(',', $val)); + } + + private function checkCallback($val) + { + return substr($val, 0, 29) == '$WowheadProfiler.loadOnDemand'; + } + + private function loadProfilerData($file, $catg = 'null') + { + $result = ''; + if ($this->_get['callback']) + if (Util::loadStaticFile('p-'.$file, $result, true)) + $result .= "\n\$WowheadProfiler.loadOnDemand('".$file."', ".$catg.");\n"; + + return $result; + } + +} + ?> \ No newline at end of file diff --git a/includes/ajaxHandler/gotocomment.class.php b/includes/ajaxHandler/gotocomment.class.php index 2df0031f..aa9ff36b 100644 --- a/includes/ajaxHandler/gotocomment.class.php +++ b/includes/ajaxHandler/gotocomment.class.php @@ -1,36 +1,36 @@ - [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']] - ); - - public function __construct(array $params) - { - parent::__construct($params); - - // always this one - $this->handler = 'handleGoToComment'; - $this->doRedirect = true; - } - - /* responses - header() - */ - protected function handleGoToComment() - { - if (!$this->_get['id']) - exit; // just be blank - - if ($_ = DB::Aowow()->selectRow('SELECT IFNULL(c2.id, c1.id) AS id, IFNULL(c2.type, c1.type) AS type, IFNULL(c2.typeId, c1.typeId) AS typeId FROM ?_comments c1 LEFT JOIN ?_comments c2 ON c1.replyTo = c2.id WHERE c1.id = ?d', $this->_get['id'])) - return '?'.Util::$typeStrings[$_['type']].'='.$_['typeId'].'#comments:id='.$_['id'].($_['id'] != $this->_get['id'] ? ':reply='.$this->_get['id'] : null); - else - exit; - } -} - + [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkInt']] + ); + + public function __construct(array $params) + { + parent::__construct($params); + + // always this one + $this->handler = 'handleGoToComment'; + $this->doRedirect = true; + } + + /* responses + header() + */ + protected function handleGoToComment() + { + if (!$this->_get['id']) + exit; // just be blank + + if ($_ = DB::Aowow()->selectRow('SELECT IFNULL(c2.id, c1.id) AS id, IFNULL(c2.type, c1.type) AS type, IFNULL(c2.typeId, c1.typeId) AS typeId FROM ?_comments c1 LEFT JOIN ?_comments c2 ON c1.replyTo = c2.id WHERE c1.id = ?d', $this->_get['id'])) + return '?'.Util::$typeStrings[$_['type']].'='.$_['typeId'].'#comments:id='.$_['id'].($_['id'] != $this->_get['id'] ? ':reply='.$this->_get['id'] : null); + else + exit; + } +} + ?> \ No newline at end of file diff --git a/includes/ajaxHandler/locale.class.php b/includes/ajaxHandler/locale.class.php index 2bfd1e1d..226d638e 100644 --- a/includes/ajaxHandler/locale.class.php +++ b/includes/ajaxHandler/locale.class.php @@ -1,33 +1,33 @@ - [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkLocale']] - ); - - public function __construct(array $params) - { - parent::__construct($params); - - // always this one - $this->handler = 'handleLocale'; - $this->doRedirect = true; - } - - /* responses - header() - */ - protected function handleLocale() - { - User::setLocale($this->_get['locale']); - User::save(); - - return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '.'; - } -} - -?> \ No newline at end of file + [FILTER_CALLBACK, ['options' => 'AjaxHandler::checkLocale']] + ); + + public function __construct(array $params) + { + parent::__construct($params); + + // always this one + $this->handler = 'handleLocale'; + $this->doRedirect = true; + } + + /* responses + header() + */ + protected function handleLocale() + { + User::setLocale($this->_get['locale']); + User::save(); + + return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '.'; + } +} + +?> diff --git a/includes/ajaxHandler/profile.class.php b/includes/ajaxHandler/profile.class.php index fd02a1b2..11b011e1 100644 --- a/includes/ajaxHandler/profile.class.php +++ b/includes/ajaxHandler/profile.class.php @@ -1,323 +1,323 @@ - [FILTER_CALLBACK, ['options' => 'AjaxProfile::checkId']], - // 'items' => [FILTER_CALLBACK, ['options' => 'AjaxProfile::checkItems']], - 'size' => [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH - ); - - public function __construct(array $params) - { - parent::__construct($params); - - if (!$this->params) - return; - - switch ($this->params[0]) - { - case 'link': - case 'unlink': - $this->handler = 'handleLink'; // always returns null - break; - case 'pin': - case 'unpin': - $this->handler = 'handlePin'; // always returns null - break; - case 'public': - case 'private': - $this->handler = 'handlePrivacy'; // always returns null - break; - case 'avatar': - $this->handler = 'handleAvatar'; // sets an image header - break; // so it has to die here or another header will be set - case 'resync': - case 'status': - $this->handler = 'handleResync'; - break; - case 'save': - $this->handler = 'handleSave'; - break; - case 'delete': - $this->handler = 'handleDelete'; - break; - case 'purge': - $this->handler = 'handlePurge'; - break; - case 'summary': // page is generated by jScript - die(); // just be empty - case 'load': - $this->handler = 'handleLoad'; - break; - } - } - - protected function handleLink($id, $mode) // links char with account - { - /* params - id: - user: [optional] - return: null - */ - } - - protected function handlePin($id, $mode) // (un)favorite - { - /* params - id: - user: [optional] - return: null - */ - } - - protected function handlePrivacy($id, $mode) // public visibility - { - /* params - id: - user: [optional] - return: null - */ - } - - protected function handleAvatar() // image - { - // something happened in the last years: those textures do not include tiny icons - $sizes = [/* 'tiny' => 15, */'small' => 18, 'medium' => 36, 'large' => 56]; - $aPath = 'uploads/avatars/%d.jpg'; - $s = $this->_get['size'] ?: 'medium'; - - if (!$this->_get['id'] || !preg_match('/^([0-9]+)\.(jpg|gif)$/', $this->_get['id'][0], $matches) || !in_array($s, array_keys($sizes))) - return; - - $this->contentType = 'image/'.$matches[2]; - - $id = $matches[1]; - $dest = imageCreateTruecolor($sizes[$s], $sizes[$s]); - - if (file_exists(sprintf($aPath, $id))) - { - $offsetX = $offsetY = 0; - - switch ($s) - { - case 'tiny': - $offsetX += $sizes['small']; - case 'small': - $offsetY += $sizes['medium']; - case 'medium': - $offsetX += $sizes['large']; - } - - $src = imageCreateFromJpeg(printf($aPath, $id)); - imagecopymerge($dest, $src, 0, 0, $offsetX, $offsetY, $sizes[$s], $sizes[$s], 100); - } - - if ($matches[2] == 'gif') - imageGif($dest); - else - imageJpeg($dest); - - return; - } - - protected function handleResync() // resync init and status requests - { - /* params - id: - user: [optional] - return - null [onOK] - int or str [onError] - */ - - if ($this->params[0] == 'resync') - return '1'; - else // $this->params[0] == 'status' - { - /* - not all fields are required, if zero they are omitted - statusCode: - 0: end the request - 1: waiting - 2: working... - 3: ready; click to view - 4: error / retry - errorCode: - 0: unk error - 1: char does not exist - 2: armory gone - - [ - processId, - [StatusCode, timeToRefresh, iCount, errorCode, iNResyncs], - []... - ] - */ - return '[0, [4, 10000, 1, 2]]'; - } - } - - protected function handleSave() // unKill a profile - { - /* params GET - id: - params POST - name, level, class, race, gender, nomodel, talenttree1, talenttree2, talenttree3, activespec, talentbuild1, glyphs1, talentbuild2, glyphs2, gearscore, icon, public [always] - description, source, copy, inv { inventory: array containing itemLinks } [optional] - } - return - int > 0 [profileId, if we came from an armoryProfile create a new one] - int < 0 [onError] - str [onError] - */ - - return 'NYI'; - } - - protected function handleDelete() // kill a profile - { - /* params - id: - return - null - */ - - return 'NYI'; - } - - protected function handlePurge() // removes certain saved information but not the entire character - { - /* params - id: - data: [string, tabName?] - return - null - */ - - return 'NYI'; - } - - protected function handleLoad() - { - /* params - id: profileId - items: string [itemIds.join(':')] - unnamed: unixtime [only to force the browser to reload instead of cache] - return - lots... - */ - - // titles, achievements, characterData, talents (, pets) - // and some onLoad-hook to .. load it registerProfile($data) - // everything else goes through data.php .. strangely enough - - if (!$this->_get['id']) - return; - - $char = new ProfileList(array(['id', $this->_get['id'][0]])); // or string or whatever - - $buff = ''; - - if ($it = array_column($char->getField('inventory'), 0)) - { - $itemz = new ItemList(array(['id', $it, CFG_SQL_LIMIT_NONE])); - $data = $itemz->getListviewData(ITEMINFO_JSON | ITEMINFO_SUBITEMS); - - // get and apply inventory - foreach ($itemz->iterate() as $iId => $__) - $buff .= 'g_items.add('.$iId.', {name_'.User::$localeString.":'".Util::jsEscape($itemz->getField('name', true))."', quality:".$itemz->getField('quality').", icon:'".$itemz->getField('iconString')."', jsonequip:".Util::toJSON($data[$iId])."});\n"; - - $buff .= "\n"; - } - - if ($au = $char->getField('auras')) - { - $auraz = new SpellList(array(['id', $char->getField('auras')], CFG_SQL_LIMIT_NONE)); - $dataz = $auraz->getListviewData(); - $modz = $auraz->getProfilerMods(); - - // get and apply aura-mods - foreach ($dataz as $id => $data) - { - $mods = []; - if (!empty($modz[$id])) - { - foreach ($modz[$id] as $k => $v) - { - if (is_array($v)) - $mods[] = $v; - else if ($str = @Util::$itemMods[$k]) - $mods[$str] = $v; - } - } - - $buff .= 'g_spells.add('.$id.", {id:".$id.", name:'".Util::jsEscape(mb_substr($data['name'], 1))."', icon:'".$data['icon']."', modifier:".Util::toJSON($mods)."});\n"; - } - $buff .= "\n"; - } - - /* depending on progress-achievements - // required by progress in JScript move to handleLoad()? - Util::$pageTemplate->extendGlobalIds(TYPE_NPC, [29120, 31134, 29306, 29311, 23980, 27656, 26861, 26723, 28923, 15991]); - */ - - // load available titles - Util::loadStaticFile('p-titles-'.$char->getField('gender'), $buff, true); - - // load available achievements - if (!Util::loadStaticFile('p-achievements', $buff, true)) - { - $buff .= "\n\ng_achievement_catorder = [];"; - $buff .= "\n\ng_achievement_points = [0];"; - } - - // excludes; structure UNK type => [maskBit => [typeIds]] ? - /* - g_user.excludes = [type:[typeIds]] - g_user.includes = [type:[typeIds]] - g_user.excludegroups = groupMask // requires g_user.settings != null - - maskBit are matched against fieldId from excludeGroups - id: 1, label: LANG.dialog_notavail - id: 2, label: LANG.dialog_tcg - id: 4, label: LANG.dialog_collector - id: 8, label: LANG.dialog_promo - id: 16, label: LANG.dialog_nonus - id: 96, label: LANG.dialog_faction - id: 896, label: LANG.dialog_profession - id: 1024, label: LANG.dialog_noexalted - */ - // $buff .= "\n\ng_excludes = {};"; - - // add profile to buffer - $buff .= "\n\n\$WowheadProfiler.registerProfile(".Util::toJSON($char->getEntry(2)).");"; // can't use JSON_NUMERIC_CHECK or the talent-string becomes a float - - return $buff."\n"; - } - - protected function checkId($val) - { - // expecting id-list - if (preg_match('/\d+(,\d+)*/', $val)) - return array_map('intVal', explode(',', $val)); - - return null; - } - - protected function checkItems($val) - { - // expecting item-list - if (preg_match('/\d+(:\d+)*/', $val)) - return array_map('intVal', explode(': ', $val)); - - return null; - } - -} - + [FILTER_CALLBACK, ['options' => 'AjaxProfile::checkId']], + // 'items' => [FILTER_CALLBACK, ['options' => 'AjaxProfile::checkItems']], + 'size' => [FILTER_SANITIZE_STRING, 0xC], // FILTER_FLAG_STRIP_LOW | *_HIGH + ); + + public function __construct(array $params) + { + parent::__construct($params); + + if (!$this->params) + return; + + switch ($this->params[0]) + { + case 'link': + case 'unlink': + $this->handler = 'handleLink'; // always returns null + break; + case 'pin': + case 'unpin': + $this->handler = 'handlePin'; // always returns null + break; + case 'public': + case 'private': + $this->handler = 'handlePrivacy'; // always returns null + break; + case 'avatar': + $this->handler = 'handleAvatar'; // sets an image header + break; // so it has to die here or another header will be set + case 'resync': + case 'status': + $this->handler = 'handleResync'; + break; + case 'save': + $this->handler = 'handleSave'; + break; + case 'delete': + $this->handler = 'handleDelete'; + break; + case 'purge': + $this->handler = 'handlePurge'; + break; + case 'summary': // page is generated by jScript + die(); // just be empty + case 'load': + $this->handler = 'handleLoad'; + break; + } + } + + protected function handleLink($id, $mode) // links char with account + { + /* params + id: + user: [optional] + return: null + */ + } + + protected function handlePin($id, $mode) // (un)favorite + { + /* params + id: + user: [optional] + return: null + */ + } + + protected function handlePrivacy($id, $mode) // public visibility + { + /* params + id: + user: [optional] + return: null + */ + } + + protected function handleAvatar() // image + { + // something happened in the last years: those textures do not include tiny icons + $sizes = [/* 'tiny' => 15, */'small' => 18, 'medium' => 36, 'large' => 56]; + $aPath = 'uploads/avatars/%d.jpg'; + $s = $this->_get['size'] ?: 'medium'; + + if (!$this->_get['id'] || !preg_match('/^([0-9]+)\.(jpg|gif)$/', $this->_get['id'][0], $matches) || !in_array($s, array_keys($sizes))) + return; + + $this->contentType = 'image/'.$matches[2]; + + $id = $matches[1]; + $dest = imageCreateTruecolor($sizes[$s], $sizes[$s]); + + if (file_exists(sprintf($aPath, $id))) + { + $offsetX = $offsetY = 0; + + switch ($s) + { + case 'tiny': + $offsetX += $sizes['small']; + case 'small': + $offsetY += $sizes['medium']; + case 'medium': + $offsetX += $sizes['large']; + } + + $src = imageCreateFromJpeg(printf($aPath, $id)); + imagecopymerge($dest, $src, 0, 0, $offsetX, $offsetY, $sizes[$s], $sizes[$s], 100); + } + + if ($matches[2] == 'gif') + imageGif($dest); + else + imageJpeg($dest); + + return; + } + + protected function handleResync() // resync init and status requests + { + /* params + id: + user: [optional] + return + null [onOK] + int or str [onError] + */ + + if ($this->params[0] == 'resync') + return '1'; + else // $this->params[0] == 'status' + { + /* + not all fields are required, if zero they are omitted + statusCode: + 0: end the request + 1: waiting + 2: working... + 3: ready; click to view + 4: error / retry + errorCode: + 0: unk error + 1: char does not exist + 2: armory gone + + [ + processId, + [StatusCode, timeToRefresh, iCount, errorCode, iNResyncs], + []... + ] + */ + return '[0, [4, 10000, 1, 2]]'; + } + } + + protected function handleSave() // unKill a profile + { + /* params GET + id: + params POST + name, level, class, race, gender, nomodel, talenttree1, talenttree2, talenttree3, activespec, talentbuild1, glyphs1, talentbuild2, glyphs2, gearscore, icon, public [always] + description, source, copy, inv { inventory: array containing itemLinks } [optional] + } + return + int > 0 [profileId, if we came from an armoryProfile create a new one] + int < 0 [onError] + str [onError] + */ + + return 'NYI'; + } + + protected function handleDelete() // kill a profile + { + /* params + id: + return + null + */ + + return 'NYI'; + } + + protected function handlePurge() // removes certain saved information but not the entire character + { + /* params + id: + data: [string, tabName?] + return + null + */ + + return 'NYI'; + } + + protected function handleLoad() + { + /* params + id: profileId + items: string [itemIds.join(':')] + unnamed: unixtime [only to force the browser to reload instead of cache] + return + lots... + */ + + // titles, achievements, characterData, talents (, pets) + // and some onLoad-hook to .. load it registerProfile($data) + // everything else goes through data.php .. strangely enough + + if (!$this->_get['id']) + return; + + $char = new ProfileList(array(['id', $this->_get['id'][0]])); // or string or whatever + + $buff = ''; + + if ($it = array_column($char->getField('inventory'), 0)) + { + $itemz = new ItemList(array(['id', $it, CFG_SQL_LIMIT_NONE])); + $data = $itemz->getListviewData(ITEMINFO_JSON | ITEMINFO_SUBITEMS); + + // get and apply inventory + foreach ($itemz->iterate() as $iId => $__) + $buff .= 'g_items.add('.$iId.', {name_'.User::$localeString.":'".Util::jsEscape($itemz->getField('name', true))."', quality:".$itemz->getField('quality').", icon:'".$itemz->getField('iconString')."', jsonequip:".Util::toJSON($data[$iId])."});\n"; + + $buff .= "\n"; + } + + if ($au = $char->getField('auras')) + { + $auraz = new SpellList(array(['id', $char->getField('auras')], CFG_SQL_LIMIT_NONE)); + $dataz = $auraz->getListviewData(); + $modz = $auraz->getProfilerMods(); + + // get and apply aura-mods + foreach ($dataz as $id => $data) + { + $mods = []; + if (!empty($modz[$id])) + { + foreach ($modz[$id] as $k => $v) + { + if (is_array($v)) + $mods[] = $v; + else if ($str = @Util::$itemMods[$k]) + $mods[$str] = $v; + } + } + + $buff .= 'g_spells.add('.$id.", {id:".$id.", name:'".Util::jsEscape(mb_substr($data['name'], 1))."', icon:'".$data['icon']."', modifier:".Util::toJSON($mods)."});\n"; + } + $buff .= "\n"; + } + + /* depending on progress-achievements + // required by progress in JScript move to handleLoad()? + Util::$pageTemplate->extendGlobalIds(TYPE_NPC, [29120, 31134, 29306, 29311, 23980, 27656, 26861, 26723, 28923, 15991]); + */ + + // load available titles + Util::loadStaticFile('p-titles-'.$char->getField('gender'), $buff, true); + + // load available achievements + if (!Util::loadStaticFile('p-achievements', $buff, true)) + { + $buff .= "\n\ng_achievement_catorder = [];"; + $buff .= "\n\ng_achievement_points = [0];"; + } + + // excludes; structure UNK type => [maskBit => [typeIds]] ? + /* + g_user.excludes = [type:[typeIds]] + g_user.includes = [type:[typeIds]] + g_user.excludegroups = groupMask // requires g_user.settings != null + + maskBit are matched against fieldId from excludeGroups + id: 1, label: LANG.dialog_notavail + id: 2, label: LANG.dialog_tcg + id: 4, label: LANG.dialog_collector + id: 8, label: LANG.dialog_promo + id: 16, label: LANG.dialog_nonus + id: 96, label: LANG.dialog_faction + id: 896, label: LANG.dialog_profession + id: 1024, label: LANG.dialog_noexalted + */ + // $buff .= "\n\ng_excludes = {};"; + + // add profile to buffer + $buff .= "\n\n\$WowheadProfiler.registerProfile(".Util::toJSON($char->getEntry(2)).");"; // can't use JSON_NUMERIC_CHECK or the talent-string becomes a float + + return $buff."\n"; + } + + protected function checkId($val) + { + // expecting id-list + if (preg_match('/\d+(,\d+)*/', $val)) + return array_map('intVal', explode(',', $val)); + + return null; + } + + protected function checkItems($val) + { + // expecting item-list + if (preg_match('/\d+(:\d+)*/', $val)) + return array_map('intVal', explode(': ', $val)); + + return null; + } + +} + ?> \ No newline at end of file diff --git a/includes/shared.php b/includes/shared.php index 1f54171f..132fdced 100644 --- a/includes/shared.php +++ b/includes/shared.php @@ -1,26 +1,26 @@ -'.$r." was not found. Please check if it should exist, using \"php -m\"\n\n"; - -if (version_compare(PHP_VERSION, '5.5.0') < 0) - $error .= 'PHP Version 5.5.0 or higher required! Your version is '.PHP_VERSION.".\nCore functions are unavailable!\n"; - -if ($error) -{ - echo CLI ? strip_tags($error) : $error; - die(); -} - - -// include all necessities, set up basics -require_once 'includes/kernel.php'; - -?> +'.$r." was not found. Please check if it should exist, using \"php -m\"\n\n"; + +if (version_compare(PHP_VERSION, '5.5.0') < 0) + $error .= 'PHP Version 5.5.0 or higher required! Your version is '.PHP_VERSION.".\nCore functions are unavailable!\n"; + +if ($error) +{ + echo CLI ? strip_tags($error) : $error; + die(); +} + + +// include all necessities, set up basics +require_once 'includes/kernel.php'; + +?> diff --git a/includes/types/emote.class.php b/includes/types/emote.class.php index 6739bc65..523777d9 100644 --- a/includes/types/emote.class.php +++ b/includes/types/emote.class.php @@ -1,58 +1,58 @@ -iterate() as &$curTpl) - { - // remap for generic access - $curTpl['name'] = $curTpl['cmd']; - } - } - - public function getListviewData() - { - $data = []; - - foreach ($this->iterate() as $__) - { - $data[$this->id] = array( - 'id' => $this->curTpl['id'], - 'name' => $this->curTpl['cmd'], - 'preview' => $this->getField('self', true) ?: ($this->getField('noTarget', true) ?: $this->getField('target', true)) - ); - - // [nyi] sounds - } - - return $data; - } - - public function getJSGlobals($addMask = GLOBALINFO_ANY) - { - $data = []; - - foreach ($this->iterate() as $__) - $data[TYPE_EMOTE][$this->id] = ['name' => $this->getField('cmd')]; - - return $data; - } - - public function renderTooltip() { } -} - -?> +iterate() as &$curTpl) + { + // remap for generic access + $curTpl['name'] = $curTpl['cmd']; + } + } + + public function getListviewData() + { + $data = []; + + foreach ($this->iterate() as $__) + { + $data[$this->id] = array( + 'id' => $this->curTpl['id'], + 'name' => $this->curTpl['cmd'], + 'preview' => $this->getField('self', true) ?: ($this->getField('noTarget', true) ?: $this->getField('target', true)) + ); + + // [nyi] sounds + } + + return $data; + } + + public function getJSGlobals($addMask = GLOBALINFO_ANY) + { + $data = []; + + foreach ($this->iterate() as $__) + $data[TYPE_EMOTE][$this->id] = ['name' => $this->getField('cmd')]; + + return $data; + } + + public function renderTooltip() { } +} + +?> diff --git a/includes/types/enchantment.class.php b/includes/types/enchantment.class.php index 7002e4e4..464bc6b3 100644 --- a/includes/types/enchantment.class.php +++ b/includes/types/enchantment.class.php @@ -1,345 +1,345 @@ - TYPE_ENCHANTMENT - 'ie' => [['is']], - 'is' => ['j' => ['?_item_stats `is` ON `is`.`type` = 502 AND `is`.`typeId` = `ie`.`id`', true], 's' => ', `is`.*'], - ); - - public function __construct($conditions = []) - { - parent::__construct($conditions); - - // post processing - foreach ($this->iterate() as &$curTpl) - { - $curTpl['spells'] = []; // [spellId, triggerType, charges, chanceOrPpm] - for ($i = 1; $i <=3; $i++) - { - if ($curTpl['object'.$i] <= 0) - continue; - - switch ($curTpl['type'.$i]) - { - case 1: - $proc = -$this->getField('ppmRate') ?: ($this->getField('procChance') ?: $this->getField('amount'.$i)); - $curTpl['spells'][$i] = [$curTpl['object'.$i], 2, $curTpl['charges'], $proc]; - $this->relSpells[] = $curTpl['object'.$i]; - break; - case 3: - $curTpl['spells'][$i] = [$curTpl['object'.$i], 1, $curTpl['charges'], 0]; - $this->relSpells[] = $curTpl['object'.$i]; - break; - case 7: - $curTpl['spells'][$i] = [$curTpl['object'.$i], 0, $curTpl['charges'], 0]; - $this->relSpells[] = $curTpl['object'.$i]; - break; - } - } - - // floats are fetched as string from db :< - $curTpl['dmg'] = floatVal($curTpl['dmg']); - $curTpl['dps'] = floatVal($curTpl['dps']); - - // remove zero-stats - foreach (Util::$itemMods as $str) - if ($curTpl[$str] == 0) // empty(0.0f) => true .. yeah, sure - unset($curTpl[$str]); - - if ($curTpl['dps'] == 0) - unset($curTpl['dps']); - } - - if ($this->relSpells) - $this->relSpells = new SpellList(array(['id', $this->relSpells])); - } - - // use if you JUST need the name - public static function getName($id) - { - $n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_itemenchantment WHERE id = ?d', $id ); - return Util::localizedString($n, 'name'); - } - // end static use - - public function getListviewData($addInfoMask = 0x0) - { - $data = []; - - foreach ($this->iterate() as $__) - { - $data[$this->id] = array( - 'id' => $this->id, - 'name' => $this->getField('name', true), - 'spells' => [] - ); - - if ($this->curTpl['skillLine'] > 0) - $data[$this->id]['reqskill'] = $this->curTpl['skillLine']; - - if ($this->curTpl['skillLevel'] > 0) - $data[$this->id]['reqskillrank'] = $this->curTpl['skillLevel']; - - if ($this->curTpl['requiredLevel'] > 0) - $data[$this->id]['reqlevel'] = $this->curTpl['requiredLevel']; - - foreach ($this->curTpl['spells'] as $s) - { - // enchant is procing or onUse - if ($s[1] == 2 || $s[1] == 0) - $data[$this->id]['spells'][$s[0]] = $s[2]; - // spell is procing - else if ($this->relSpells && $this->relSpells->getEntry($s[0]) && ($_ = $this->relSpells->canTriggerSpell())) - { - foreach ($_ as $idx) - { - $this->triggerIds[] = $this->relSpells->getField('effect'.$idx.'TriggerSpell'); - $data[$this->id]['spells'][$this->relSpells->getField('effect'.$idx.'TriggerSpell')] = $s[2]; - } - } - } - - if (!$data[$this->id]['spells']) - unset($data[$this->id]['spells']); - - Util::arraySumByKey($data[$this->id], $this->getStatGain()); - } - - return $data; - } - - public function getStatGain($addScalingKeys = false) - { - $data = []; - - foreach (Util::$itemMods as $str) - if (isset($this->curTpl[$str])) - $data[$str] = $this->curTpl[$str]; - - if (isset($this->curTpl['dps'])) - $data['dps'] = $this->curTpl['dps']; - - // scaling enchantments are saved as 0 to item_stats, thus return empty - if ($addScalingKeys) - { - $spellStats = []; - if ($this->relSpells) - $spellStats = $this->relSpells->getStatGain(); - - for ($h = 1; $h <= 3; $h++) - { - $obj = (int)$this->curTpl['object'.$h]; - - switch ($this->curTpl['type'.$h]) - { - case 3: // TYPE_EQUIP_SPELL Spells from ObjectX (use of amountX?) - if (!empty($spellStats[$obj])) - foreach ($spellStats[$obj] as $mod => $_) - if ($str = Util::$itemMods[$mod]) - Util::arraySumByKey($data, [$str => 0]); - - $obj = null; - break; - case 4: // TYPE_RESISTANCE +AmountX resistance for ObjectX School - switch ($obj) - { - case 0: // Physical - $obj = ITEM_MOD_ARMOR; - break; - case 1: // Holy - $obj = ITEM_MOD_HOLY_RESISTANCE; - break; - case 2: // Fire - $obj = ITEM_MOD_FIRE_RESISTANCE; - break; - case 3: // Nature - $obj = ITEM_MOD_NATURE_RESISTANCE; - break; - case 4: // Frost - $obj = ITEM_MOD_FROST_RESISTANCE; - break; - case 5: // Shadow - $obj = ITEM_MOD_SHADOW_RESISTANCE; - break; - case 6: // Arcane - $obj = ITEM_MOD_ARCANE_RESISTANCE; - break; - default: - $obj = null; - } - break; - case 5: // TYPE_STAT +AmountX for Statistic by type of ObjectX - if ($obj < 2) // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. - $obj++; // 0 is weaponDmg .. ehh .. i messed up somewhere - - break; // stats are directly assigned below - default: // TYPE_NONE dnd stuff; skip assignment below - $obj = null; - } - - if ($obj !== null) - if ($str = Util::$itemMods[$obj]) // check if we use these mods - Util::arraySumByKey($data, [$str => 0]); - } - } - - return $data; - } - - public function getRelSpell($id) - { - if ($this->relSpells) - return $this->relSpells->getEntry($id); - - return null; - } - - public function getJSGlobals($addMask = GLOBALINFO_ANY) - { - $data = []; - - if ($addMask & GLOBALINFO_SELF) - foreach ($this->iterate() as $__) - $data[TYPE_ENCHANTMENT][$this->id] = ['name' => $this->getField('name', true)]; - - if ($addMask & GLOBALINFO_RELATED) - { - if ($this->relSpells) - $data = $this->relSpells->getJSGlobals(GLOBALINFO_SELF); - - foreach ($this->triggerIds as $tId) - if (empty($data[TYPE_SPELL][$tId])) - $data[TYPE_SPELL][$tId] = $tId; - } - - return $data; - } - - public function renderTooltip() { } -} - - -class EnchantmentListFilter extends Filter -{ - protected $enums = array( - 3 => array( // requiresprof - null, 171, 164, 185, 333, 202, 129, 755, 165, 186, 197, true, false, 356, 182, 773 - ) - ); - - 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_ENUM, 'skillLine' ], // requiresprof - 4 => [FILTER_CR_NUMERIC, 'skillLevel', ], // reqskillrank - 5 => [FILTER_CR_BOOLEAN, 'conditionId' ], // hascondition - 10 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments - 11 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots - 12 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos - 21 => [FILTER_CR_NUMERIC, 'is.agi', null, true], // agi - 23 => [FILTER_CR_NUMERIC, 'is.int', null, true], // int - 22 => [FILTER_CR_NUMERIC, 'is.sta', null, true], // sta - 24 => [FILTER_CR_NUMERIC, 'is.spi', null, true], // spi - 20 => [FILTER_CR_NUMERIC, 'is.str', null, true], // str - 115 => [FILTER_CR_NUMERIC, 'is.health', null, true], // health - 116 => [FILTER_CR_NUMERIC, 'is.mana', null, true], // mana - 60 => [FILTER_CR_NUMERIC, 'is.healthrgn', null, true], // healthrgn - 61 => [FILTER_CR_NUMERIC, 'is.manargn', null, true], // manargn - 41 => [FILTER_CR_NUMERIC, 'is.armor' , null, true], // armor - 44 => [FILTER_CR_NUMERIC, 'is.blockrtng', null, true], // blockrtng - 43 => [FILTER_CR_NUMERIC, 'is.block', null, true], // block - 42 => [FILTER_CR_NUMERIC, 'is.defrtng', null, true], // defrtng - 45 => [FILTER_CR_NUMERIC, 'is.dodgertng', null, true], // dodgertng - 46 => [FILTER_CR_NUMERIC, 'is.parryrtng', null, true], // parryrtng - 79 => [FILTER_CR_NUMERIC, 'is.resirtng', null, true], // resirtng - 77 => [FILTER_CR_NUMERIC, 'is.atkpwr', null, true], // atkpwr - 97 => [FILTER_CR_NUMERIC, 'is.feratkpwr', null, true], // feratkpwr - 114 => [FILTER_CR_NUMERIC, 'is.armorpenrtng', null, true], // armorpenrtng - 96 => [FILTER_CR_NUMERIC, 'is.critstrkrtng', null, true], // critstrkrtng - 117 => [FILTER_CR_NUMERIC, 'is.exprtng', null, true], // exprtng - 103 => [FILTER_CR_NUMERIC, 'is.hastertng', null, true], // hastertng - 119 => [FILTER_CR_NUMERIC, 'is.hitrtng', null, true], // hitrtng - 94 => [FILTER_CR_NUMERIC, 'is.splpen', null, true], // splpen - 123 => [FILTER_CR_NUMERIC, 'is.splpwr', null, true], // splpwr - 52 => [FILTER_CR_NUMERIC, 'is.arcsplpwr', null, true], // arcsplpwr - 53 => [FILTER_CR_NUMERIC, 'is.firsplpwr', null, true], // firsplpwr - 54 => [FILTER_CR_NUMERIC, 'is.frosplpwr', null, true], // frosplpwr - 55 => [FILTER_CR_NUMERIC, 'is.holsplpwr', null, true], // holsplpwr - 56 => [FILTER_CR_NUMERIC, 'is.natsplpwr', null, true], // natsplpwr - 57 => [FILTER_CR_NUMERIC, 'is.shasplpwr', null, true], // shasplpwr - 32 => [FILTER_CR_NUMERIC, 'is.dps', true, true], // dps - 34 => [FILTER_CR_NUMERIC, 'is.dmg', true, true], // dmg - 25 => [FILTER_CR_NUMERIC, 'is.arcres', null, true], // arcres - 26 => [FILTER_CR_NUMERIC, 'is.firres', null, true], // firres - 28 => [FILTER_CR_NUMERIC, 'is.frores', null, true], // frores - 30 => [FILTER_CR_NUMERIC, 'is.holres', null, true], // holres - 27 => [FILTER_CR_NUMERIC, 'is.natres', null, true], // natres - 29 => [FILTER_CR_NUMERIC, 'is.shares', null, true], // shares - 37 => [FILTER_CR_NUMERIC, 'is.mleatkpwr', null, true], // mleatkpwr - 84 => [FILTER_CR_NUMERIC, 'is.mlecritstrkrtng', null, true], // mlecritstrkrtng - 78 => [FILTER_CR_NUMERIC, 'is.mlehastertng', null, true], // mlehastertng - 95 => [FILTER_CR_NUMERIC, 'is.mlehitrtng', null, true], // mlehitrtng - 38 => [FILTER_CR_NUMERIC, 'is.rgdatkpwr', null, true], // rgdatkpwr - 40 => [FILTER_CR_NUMERIC, 'is.rgdcritstrkrtng', null, true], // rgdcritstrkrtng - 101 => [FILTER_CR_NUMERIC, 'is.rgdhastertng', null, true], // rgdhastertng - 39 => [FILTER_CR_NUMERIC, 'is.rgdhitrtng', null, true], // rgdhitrtng - 49 => [FILTER_CR_NUMERIC, 'is.splcritstrkrtng', null, true], // splcritstrkrtng - 102 => [FILTER_CR_NUMERIC, 'is.splhastertng', null, true], // splhastertng - 48 => [FILTER_CR_NUMERIC, 'is.splhitrtng', null, true], // splhitrtng - 51 => [FILTER_CR_NUMERIC, 'is.spldmg', null, true], // spldmg - 50 => [FILTER_CR_NUMERIC, 'is.splheal', null, true] // splheal - ); - - 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]; - } - } - - protected function createSQLForValues() - { - $parts = []; - $_v = &$this->fiData['v']; - - //string - if (isset($_v['na'])) - if ($_ = $this->modularizeString(['name_loc'.User::$localeId])) - $parts[] = $_; - - // type - if (isset($_v['ty'])) - { - $_ = (array)$_v['ty']; - if (!array_diff($_, [1, 2, 3, 4, 5, 6, 7, 8])) - $parts[] = ['OR', ['type1', $_], ['type2', $_], ['type3', $_]]; - else - unset($_v['ty']); - } - - return $parts; - } -} - -?> + TYPE_ENCHANTMENT + 'ie' => [['is']], + 'is' => ['j' => ['?_item_stats `is` ON `is`.`type` = 502 AND `is`.`typeId` = `ie`.`id`', true], 's' => ', `is`.*'], + ); + + public function __construct($conditions = []) + { + parent::__construct($conditions); + + // post processing + foreach ($this->iterate() as &$curTpl) + { + $curTpl['spells'] = []; // [spellId, triggerType, charges, chanceOrPpm] + for ($i = 1; $i <=3; $i++) + { + if ($curTpl['object'.$i] <= 0) + continue; + + switch ($curTpl['type'.$i]) + { + case 1: + $proc = -$this->getField('ppmRate') ?: ($this->getField('procChance') ?: $this->getField('amount'.$i)); + $curTpl['spells'][$i] = [$curTpl['object'.$i], 2, $curTpl['charges'], $proc]; + $this->relSpells[] = $curTpl['object'.$i]; + break; + case 3: + $curTpl['spells'][$i] = [$curTpl['object'.$i], 1, $curTpl['charges'], 0]; + $this->relSpells[] = $curTpl['object'.$i]; + break; + case 7: + $curTpl['spells'][$i] = [$curTpl['object'.$i], 0, $curTpl['charges'], 0]; + $this->relSpells[] = $curTpl['object'.$i]; + break; + } + } + + // floats are fetched as string from db :< + $curTpl['dmg'] = floatVal($curTpl['dmg']); + $curTpl['dps'] = floatVal($curTpl['dps']); + + // remove zero-stats + foreach (Util::$itemMods as $str) + if ($curTpl[$str] == 0) // empty(0.0f) => true .. yeah, sure + unset($curTpl[$str]); + + if ($curTpl['dps'] == 0) + unset($curTpl['dps']); + } + + if ($this->relSpells) + $this->relSpells = new SpellList(array(['id', $this->relSpells])); + } + + // use if you JUST need the name + public static function getName($id) + { + $n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_itemenchantment WHERE id = ?d', $id ); + return Util::localizedString($n, 'name'); + } + // end static use + + public function getListviewData($addInfoMask = 0x0) + { + $data = []; + + foreach ($this->iterate() as $__) + { + $data[$this->id] = array( + 'id' => $this->id, + 'name' => $this->getField('name', true), + 'spells' => [] + ); + + if ($this->curTpl['skillLine'] > 0) + $data[$this->id]['reqskill'] = $this->curTpl['skillLine']; + + if ($this->curTpl['skillLevel'] > 0) + $data[$this->id]['reqskillrank'] = $this->curTpl['skillLevel']; + + if ($this->curTpl['requiredLevel'] > 0) + $data[$this->id]['reqlevel'] = $this->curTpl['requiredLevel']; + + foreach ($this->curTpl['spells'] as $s) + { + // enchant is procing or onUse + if ($s[1] == 2 || $s[1] == 0) + $data[$this->id]['spells'][$s[0]] = $s[2]; + // spell is procing + else if ($this->relSpells && $this->relSpells->getEntry($s[0]) && ($_ = $this->relSpells->canTriggerSpell())) + { + foreach ($_ as $idx) + { + $this->triggerIds[] = $this->relSpells->getField('effect'.$idx.'TriggerSpell'); + $data[$this->id]['spells'][$this->relSpells->getField('effect'.$idx.'TriggerSpell')] = $s[2]; + } + } + } + + if (!$data[$this->id]['spells']) + unset($data[$this->id]['spells']); + + Util::arraySumByKey($data[$this->id], $this->getStatGain()); + } + + return $data; + } + + public function getStatGain($addScalingKeys = false) + { + $data = []; + + foreach (Util::$itemMods as $str) + if (isset($this->curTpl[$str])) + $data[$str] = $this->curTpl[$str]; + + if (isset($this->curTpl['dps'])) + $data['dps'] = $this->curTpl['dps']; + + // scaling enchantments are saved as 0 to item_stats, thus return empty + if ($addScalingKeys) + { + $spellStats = []; + if ($this->relSpells) + $spellStats = $this->relSpells->getStatGain(); + + for ($h = 1; $h <= 3; $h++) + { + $obj = (int)$this->curTpl['object'.$h]; + + switch ($this->curTpl['type'.$h]) + { + case 3: // TYPE_EQUIP_SPELL Spells from ObjectX (use of amountX?) + if (!empty($spellStats[$obj])) + foreach ($spellStats[$obj] as $mod => $_) + if ($str = Util::$itemMods[$mod]) + Util::arraySumByKey($data, [$str => 0]); + + $obj = null; + break; + case 4: // TYPE_RESISTANCE +AmountX resistance for ObjectX School + switch ($obj) + { + case 0: // Physical + $obj = ITEM_MOD_ARMOR; + break; + case 1: // Holy + $obj = ITEM_MOD_HOLY_RESISTANCE; + break; + case 2: // Fire + $obj = ITEM_MOD_FIRE_RESISTANCE; + break; + case 3: // Nature + $obj = ITEM_MOD_NATURE_RESISTANCE; + break; + case 4: // Frost + $obj = ITEM_MOD_FROST_RESISTANCE; + break; + case 5: // Shadow + $obj = ITEM_MOD_SHADOW_RESISTANCE; + break; + case 6: // Arcane + $obj = ITEM_MOD_ARCANE_RESISTANCE; + break; + default: + $obj = null; + } + break; + case 5: // TYPE_STAT +AmountX for Statistic by type of ObjectX + if ($obj < 2) // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. + $obj++; // 0 is weaponDmg .. ehh .. i messed up somewhere + + break; // stats are directly assigned below + default: // TYPE_NONE dnd stuff; skip assignment below + $obj = null; + } + + if ($obj !== null) + if ($str = Util::$itemMods[$obj]) // check if we use these mods + Util::arraySumByKey($data, [$str => 0]); + } + } + + return $data; + } + + public function getRelSpell($id) + { + if ($this->relSpells) + return $this->relSpells->getEntry($id); + + return null; + } + + public function getJSGlobals($addMask = GLOBALINFO_ANY) + { + $data = []; + + if ($addMask & GLOBALINFO_SELF) + foreach ($this->iterate() as $__) + $data[TYPE_ENCHANTMENT][$this->id] = ['name' => $this->getField('name', true)]; + + if ($addMask & GLOBALINFO_RELATED) + { + if ($this->relSpells) + $data = $this->relSpells->getJSGlobals(GLOBALINFO_SELF); + + foreach ($this->triggerIds as $tId) + if (empty($data[TYPE_SPELL][$tId])) + $data[TYPE_SPELL][$tId] = $tId; + } + + return $data; + } + + public function renderTooltip() { } +} + + +class EnchantmentListFilter extends Filter +{ + protected $enums = array( + 3 => array( // requiresprof + null, 171, 164, 185, 333, 202, 129, 755, 165, 186, 197, true, false, 356, 182, 773 + ) + ); + + 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_ENUM, 'skillLine' ], // requiresprof + 4 => [FILTER_CR_NUMERIC, 'skillLevel', ], // reqskillrank + 5 => [FILTER_CR_BOOLEAN, 'conditionId' ], // hascondition + 10 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments + 11 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots + 12 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos + 21 => [FILTER_CR_NUMERIC, 'is.agi', null, true], // agi + 23 => [FILTER_CR_NUMERIC, 'is.int', null, true], // int + 22 => [FILTER_CR_NUMERIC, 'is.sta', null, true], // sta + 24 => [FILTER_CR_NUMERIC, 'is.spi', null, true], // spi + 20 => [FILTER_CR_NUMERIC, 'is.str', null, true], // str + 115 => [FILTER_CR_NUMERIC, 'is.health', null, true], // health + 116 => [FILTER_CR_NUMERIC, 'is.mana', null, true], // mana + 60 => [FILTER_CR_NUMERIC, 'is.healthrgn', null, true], // healthrgn + 61 => [FILTER_CR_NUMERIC, 'is.manargn', null, true], // manargn + 41 => [FILTER_CR_NUMERIC, 'is.armor' , null, true], // armor + 44 => [FILTER_CR_NUMERIC, 'is.blockrtng', null, true], // blockrtng + 43 => [FILTER_CR_NUMERIC, 'is.block', null, true], // block + 42 => [FILTER_CR_NUMERIC, 'is.defrtng', null, true], // defrtng + 45 => [FILTER_CR_NUMERIC, 'is.dodgertng', null, true], // dodgertng + 46 => [FILTER_CR_NUMERIC, 'is.parryrtng', null, true], // parryrtng + 79 => [FILTER_CR_NUMERIC, 'is.resirtng', null, true], // resirtng + 77 => [FILTER_CR_NUMERIC, 'is.atkpwr', null, true], // atkpwr + 97 => [FILTER_CR_NUMERIC, 'is.feratkpwr', null, true], // feratkpwr + 114 => [FILTER_CR_NUMERIC, 'is.armorpenrtng', null, true], // armorpenrtng + 96 => [FILTER_CR_NUMERIC, 'is.critstrkrtng', null, true], // critstrkrtng + 117 => [FILTER_CR_NUMERIC, 'is.exprtng', null, true], // exprtng + 103 => [FILTER_CR_NUMERIC, 'is.hastertng', null, true], // hastertng + 119 => [FILTER_CR_NUMERIC, 'is.hitrtng', null, true], // hitrtng + 94 => [FILTER_CR_NUMERIC, 'is.splpen', null, true], // splpen + 123 => [FILTER_CR_NUMERIC, 'is.splpwr', null, true], // splpwr + 52 => [FILTER_CR_NUMERIC, 'is.arcsplpwr', null, true], // arcsplpwr + 53 => [FILTER_CR_NUMERIC, 'is.firsplpwr', null, true], // firsplpwr + 54 => [FILTER_CR_NUMERIC, 'is.frosplpwr', null, true], // frosplpwr + 55 => [FILTER_CR_NUMERIC, 'is.holsplpwr', null, true], // holsplpwr + 56 => [FILTER_CR_NUMERIC, 'is.natsplpwr', null, true], // natsplpwr + 57 => [FILTER_CR_NUMERIC, 'is.shasplpwr', null, true], // shasplpwr + 32 => [FILTER_CR_NUMERIC, 'is.dps', true, true], // dps + 34 => [FILTER_CR_NUMERIC, 'is.dmg', true, true], // dmg + 25 => [FILTER_CR_NUMERIC, 'is.arcres', null, true], // arcres + 26 => [FILTER_CR_NUMERIC, 'is.firres', null, true], // firres + 28 => [FILTER_CR_NUMERIC, 'is.frores', null, true], // frores + 30 => [FILTER_CR_NUMERIC, 'is.holres', null, true], // holres + 27 => [FILTER_CR_NUMERIC, 'is.natres', null, true], // natres + 29 => [FILTER_CR_NUMERIC, 'is.shares', null, true], // shares + 37 => [FILTER_CR_NUMERIC, 'is.mleatkpwr', null, true], // mleatkpwr + 84 => [FILTER_CR_NUMERIC, 'is.mlecritstrkrtng', null, true], // mlecritstrkrtng + 78 => [FILTER_CR_NUMERIC, 'is.mlehastertng', null, true], // mlehastertng + 95 => [FILTER_CR_NUMERIC, 'is.mlehitrtng', null, true], // mlehitrtng + 38 => [FILTER_CR_NUMERIC, 'is.rgdatkpwr', null, true], // rgdatkpwr + 40 => [FILTER_CR_NUMERIC, 'is.rgdcritstrkrtng', null, true], // rgdcritstrkrtng + 101 => [FILTER_CR_NUMERIC, 'is.rgdhastertng', null, true], // rgdhastertng + 39 => [FILTER_CR_NUMERIC, 'is.rgdhitrtng', null, true], // rgdhitrtng + 49 => [FILTER_CR_NUMERIC, 'is.splcritstrkrtng', null, true], // splcritstrkrtng + 102 => [FILTER_CR_NUMERIC, 'is.splhastertng', null, true], // splhastertng + 48 => [FILTER_CR_NUMERIC, 'is.splhitrtng', null, true], // splhitrtng + 51 => [FILTER_CR_NUMERIC, 'is.spldmg', null, true], // spldmg + 50 => [FILTER_CR_NUMERIC, 'is.splheal', null, true] // splheal + ); + + 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]; + } + } + + protected function createSQLForValues() + { + $parts = []; + $_v = &$this->fiData['v']; + + //string + if (isset($_v['na'])) + if ($_ = $this->modularizeString(['name_loc'.User::$localeId])) + $parts[] = $_; + + // type + if (isset($_v['ty'])) + { + $_ = (array)$_v['ty']; + if (!array_diff($_, [1, 2, 3, 4, 5, 6, 7, 8])) + $parts[] = ['OR', ['type1', $_], ['type2', $_], ['type3', $_]]; + else + unset($_v['ty']); + } + + return $parts; + } +} + +?> diff --git a/localization/locale_dede.php b/localization/locale_dede.php index af5b0040..e591f46c 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -1,1082 +1,1082 @@ -\World of Warcraft\Data\deDE\patch-deDE-3.MPQ\Interface\FrameXML\GlobalStrings.lua - like: ITEM_MOD_*, POWER_TYPE_*, ITEM_BIND_*, PVP_RANK_* -*/ - -$lang = array( - // page variables - 'timeUnits' => array( - 'sg' => ["Jahr", "Monat", "Woche", "Tag", "Stunde", "Minute", "Sekunde", "Millisekunde"], - 'pl' => ["Jahre", "Monate", "Wochen", "Tage", "Stunden", "Minuten", "Sekunden", "Millisekunden"], - 'ab' => ["J.", "M.", "W.", "Tag", "Std.", "Min.", "Sek.", "Ms."] - ), - 'main' => array( - 'name' => "Name", - 'link' => "Link", - 'signIn' => "Anmelden / Registrieren", - 'jsError' => "Stelle bitte sicher, dass JavaScript aktiviert ist.", - 'language' => "Sprache", - 'feedback' => "Rückmeldung", - 'numSQL' => "Anzahl an MySQL-Queries", - 'timeSQL' => "Zeit für MySQL-Queries", - 'noJScript' => 'Diese Seite macht ausgiebigen Gebrauch von JavaScript.
Bitte aktiviert JavaScript in Eurem Browser.', - 'userProfiles' => "Deine Charaktere", - 'pageNotFound' => "Dies %s existiert nicht.", - 'gender' => "Geschlecht", - 'sex' => [null, "Mann", "Frau"], - 'players' => "Spieler", - 'quickFacts' => "Kurzübersicht", - 'screenshots' => "Screenshots", - 'videos' => "Videos", - 'side' => "Seite", - 'related' => "Weiterführende Informationen", - 'contribute' => "Beitragen", - // 'replyingTo' => "Antwort zu einem Kommentar von", - 'submit' => "Absenden", - 'cancel' => "Abbrechen", - 'rewards' => "Belohnungen", - 'gains' => "Belohnungen", - 'login' => "Login", - 'forum' => "Forum", - 'n_a' => "n. v.", - 'siteRep' => "Ruf", - 'aboutUs' => "Über Aowow", - 'and' => " und ", - 'or' => " oder ", - 'back' => "Zurück", - 'reputationTip' => "Rufpunkte", - 'byUserTimeAgo' => 'Von %1$s vor %s', - - // filter - 'extSearch' => "Erweiterte Suche", - 'addFilter' => "Weiteren Filter hinzufügen", - 'match' => "Verwendete Filter", - 'allFilter' => "Alle Filters", - 'oneFilter' => "Mindestens einer", - 'applyFilter' => "Filter anwenden", - 'resetForm' => "Formular zurücksetzen", - 'refineSearch' => 'Tipp: Präzisiere deine Suche mit Durchsuchen einer Unterkategorie.', - 'clear' => "leeren", - 'exactMatch' => "Exakt passend", - '_reqLevel' => "Mindeststufe", - - // infobox - 'unavailable' => "Nicht für Spieler verfügbar", - 'disabled' => "Deaktiviert", - 'disabledHint' => "Kann nicht erhalten oder abgeschlossen werden.", - 'serverside' => "Serverseitig", - 'serversideHint'=> "Diese Informationen sind nicht im Client enthalten und wurden gesnifft und/oder erraten.", - - // red buttons - 'links' => "Links", - 'compare' => "Vergleichen", - 'view3D' => "3D-Ansicht", - 'findUpgrades' => "Bessere Gegenstände finden...", - - // miscTools - 'errPageTitle' => "Seite nicht gefunden", - 'nfPageTitle' => "Fehler", - 'subscribe' => "Abonnieren", - 'mostComments' => ["Gestern", "Vergangene %d Tage"], - 'utilities' => array( - "Neueste Ergänzungen", "Neueste Artikel", "Neueste Kommentare", "Neueste Screenshots", null, - "Nicht bewertete Kommentare", 11 => "Neueste Videos", 12 => "Meiste Kommentare", 13 => "Fehlende Screenshots" - ), - - // article & infobox - 'englishOnly' => "Diese Seite ist nur in Englisch verfügbar.", - - // calculators - 'preset' => "Vorlage", - 'addWeight' => "Weitere Gewichtung hinzufügen", - 'createWS' => "Gewichtungsverteilung erstellen", - 'jcGemsOnly' => "JS-exklusive Edelsteine einschließen", - 'cappedHint' => 'Tipp: Entfernt 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", - 'chooseClass' => "Wählt eine Klasse", - 'chooseFamily' => "Wählt eine Tierart", - - // profiler - 'realm' => "Realm", - 'region' => "Region", - 'viewCharacter' => "Charakter anzeigen", - '_cpHead' => "Charakter-Profiler", - '_cpHint' => "Der Charakter-Profiler gibt Euch die Möglichkeit, Euren Charakter zu editieren, bessere Ausrüstung zu finden, Eure Gearscore zu überprüfen, und mehr!", - '_cpHelp' => "Um loszulegen, folgt einfach den untenstehenden Schritten. Falls Ihr mehr Informationen benötigt, schaut auf unserer ausführlichen Hilfeseite nach.", - '_cpFooter' => "Falls Ihr eine genauere Suche möchtet, probiert unsere erweiterten Suchoptionen. Ihr könnt außerdem ein neues individuelles Profil erstellen.", - - // help - 'help' => "Hilfe", - 'helpTopics' => array( - "Wie man Kommentare schreibt", "Modellviewer", "Screenshots: Tipps & Tricks", "Gewichtung von Werten", - "Talentrechner", "Gegenstandsvergleich", "Profiler", "Markup Guide" - ), - - // search - 'search' => "Suche", - 'searchButton' => "Suche", - 'foundResult' => "Suchergebnisse für", - 'noResult' => "Keine Ergebnisse für", - 'tryAgain' => "Bitte versucht es mit anderen Suchbegriffen oder überprüft deren Schreibweise.", - 'ignoredTerms' => "Die folgenden Wörter wurden in Eurer Suche ignoriert: %s", - - // formating - 'colon' => ': ', - 'dateFmtShort' => "d.m.Y", - 'dateFmtLong' => "d.m.Y \u\m H:i", - - // error - 'intError' => "Ein interner Fehler ist aufgetreten.", - 'intError2' => "Ein interner Fehler ist aufgetreten. (%s)", - 'genericError' => "Ein Fehler trat auf; aktualisiert die Seite und versucht es nochmal. Wenn der Fehler bestehen bleibt, bitte meldet es bei feedback", # LANG.genericerror - 'bannedRating' => "Ihr wurdet davon gesperrt, Kommentare zu bewerten.", # LANG.tooltip_banned_rating - 'tooManyVotes' => "Ihr habt die tägliche Grenze für erlaubte Bewertungen erreicht. Kommt morgen mal wieder!", # LANG.tooltip_too_many_votes - ), - 'screenshot' => array( - 'submission' => "Screenshot-Einsendung", - 'selectAll' => "Alles auswählen", - 'cropHint' => "Ihr könnt Euren Screenshot zuschneiden und beschriften.", - 'displayOn' => "Hochgeladen für:[br]%s - [%s=%d]", - 'caption' => "Kurzbeschreibung", - 'charLimit' => "Optional, bis zu 200 Zeichen", - 'thanks' => array( - 'contrib' => "Vielen Dank für Euren Beitrag!", - 'goBack' => 'Klickt hier, um zu der vorherigen Seite zurückzukehren.', - 'note' => "Hinweis: Euer Screenshot muss zunächst zugelassen werden, bevor es auf der Seite erscheint. Dies kann bis zu 72 Stunden dauern." - ), - 'error' => array( - 'unkFormat' => "Unbekanntes Bildformat.", - 'tooSmall' => "Euer Screenshot ist viel zu klein. (< ".CFG_SCREENSHOT_MIN_SIZE."x".CFG_SCREENSHOT_MIN_SIZE.").", - 'selectSS' => "Wählt bitte den Screenshot aus, den Ihr hochladen möchtet.", - 'notAllowed' => "Es ist euch nicht erlaubt einen Screenshot hochzuladen!", - ) - ), - 'game' => array( - 'achievement' => "Erfolg", - 'achievements' => "Erfolge", - 'class' => "Klasse", - 'classes' => "Klassen", - 'currency' => "Währung", - 'currencies' => "Währungen", - 'difficulty' => "Modus", - 'dispelType' => "Bannart", - 'duration' => "Dauer", - 'emote' => "Emote", - 'emotes' => "Emotes", - 'enchantment' => "Verzauberung", - 'enchantments' => "Verzauberungen", - 'object' => "Objekt", - 'objects' => "Objekte", - 'glyphType' => "Glyphenart", - 'race' => "Volk", - 'races' => "Völker", - 'title' => "Titel", - 'titles' => "Titel", - 'eventShort' => "Ereignis", - 'event' => "Weltereigniss", - 'events' => "Weltereignisse", - 'faction' => "Fraktion", - 'factions' => "Fraktionen", - 'cooldown' => "%s Abklingzeit", - 'item' => "Gegenstand", - 'items' => "Gegenstände", - 'itemset' => "Ausrüstungsset", - 'itemsets' => "Ausrüstungssets", - 'mechanic' => "Auswirkung", - 'mechAbbr' => "Ausw.", - 'meetingStone' => "Versammlungsstein", - 'npc' => "NPC", - 'npcs' => "NPCs", - 'pet' => "Begleiter", - 'pets' => "Begleiter", - 'profile' => "", - 'profiles' => "Profile", - 'quest' => "Quest", - 'quests' => "Quests", - 'requires' => "Benötigt %s", - 'requires2' => "Benötigt", - 'reqLevel' => "Benötigt Stufe %s", - 'reqLevelHlm' => "Benötigt Stufe %s", - 'reqSkillLevel' => "Benötigte Fertigkeitsstufe", - 'level' => "Stufe", - 'school' => "Magieart", - 'skill' => "Fertigkeit", - 'skills' => "Fertigkeiten", - 'spell' => "Zauber", - 'spells' => "Zauber", - 'type' => "Art", - 'valueDelim' => " - ", // " bis " - 'zone' => "Zone", - 'zones' => "Gebiete", - - 'pvp' => "PvP", - 'honorPoints' => "Ehrenpunkte", - 'arenaPoints' => "Arenapunkte", - 'heroClass' => "Heldenklasse", - 'resource' => "Ressource", - 'resources' => "Ressourcen", - 'role' => "Rolle", - 'roles' => "Rollen", - 'specs' => "Spezialisierungen", - '_roles' => ["Heiler", "Nahkampf-DPS", "Distanz-DPS", "Tank"], - - 'phases' => "Phasen", - 'mode' => "Modus", - 'modes' => [-1 => "Beliebig", "Normal / Normal 10", "Heroisch / Normal 25", "Heroisch 10", "Heroisch 25"], - 'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"], - 'stats' => ["Stärke", "Beweglichkeit", "Ausdauer", "Intelligenz", "Willenskraft"], - 'sources' => array( - "Unbekannt", "Hergestellt", "Drop", "PvP", "Quest", "Händler", - "Lehrer", "Entdeckung", "Einlösung", "Talent", "Startausrüstung", "Ereignis", - "Erfolg", null, "Schwarzmarkt", "Entzaubert", "Geangelt", "Gesammelt", - "Gemahlen", "Abgebaut", "Sondiert", "Aus Taschendiebstahl", "Geborgen", "Gehäutet", - "In-Game-Store" - ), - 'languages' => array( - 1 => "Orcisch", 2 => "Darnassisch", 3 => "Taurisch", 6 => "Zwergisch", 7 => "Gemeinsprache", 8 => "Dämonisch", - 9 => "Titanisch", 10 => "Thalassisch", 11 => "Drachisch", 12 => "Kalimagisch", 13 => "Gnomisch", 14 => "Trollisch", - 33 => "Gossensprache", 35 => "Draeneiisch", 36 => "Zombie", 37 => "Gnomenbinär", 38 => "Goblinbinär" - ), - 'gl' => [null, "Erhebliche", "Geringe"], - 'si' => [1 => "Allianz", -1 => "Nur für Allianz", 2 => "Horde", -2 => "Nur für Horde", 3 => "Beide"], - 'resistances' => [null, 'Heiligwiderstand', 'Feuerwiderstand', 'Naturwiderstand', 'Frostwiderstand', 'Schattenwiderstand', 'Arkanwiderstand'], - 'sc' => ["Körperlich", "Heilig", "Feuer", "Natur", "Frost", "Schatten", "Arkan"], - 'dt' => [null, "Magie", "Fluch", "Krankheit", "Gift", "Verstohlenheit", "Unsichtbarkeit", null, null, "Wut"], - 'cl' => [null, "Krieger", "Paladin", "Jäger", "Schurke", "Priester", "Todesritter", "Schamane", "Magier", "Hexenmeister", null, "Druide"], - 'ra' => [-2 => "Horde", -1 => "Allianz", "Beide", "Mensch", "Orc", "Zwerg", "Nachtelf", "Untoter", "Tauren", "Gnom", "Troll", null, "Blutelf", "Draenei"], - 'rep' => ["Hasserfüllt", "Feindselig", "Unfreundlich", "Neutral", "Freundlich", "Wohlwollend", "Respektvoll", "Ehrfürchtig"], - 'st' => array( - "Vorgabe", "Katzengestalt", "Baum des Lebens", "Reisegestalt", "Wassergestalt", "Bärengestalt", - null, null, "Terrorbärengestalt", null, null, null, - null, "Schattentanz", null, null, "Geisterwolf", "Kampfhaltung", - "Verteidigungshaltung", "Berserkerhaltung", null, null, "Metamorphosis", null, - null, null, null, "Schnelle Fluggestalt", "Schattengestalt", "Fluggestalt", - "Verstohlenheit", "Mondkingestalt", "Geist der Erlösung" - ), - 'me' => array( - null, "Bezaubert", "Desorientiert", "Entwaffnet", "Abgelenkt", "Flüchtend", - "Ergriffen", "Unbeweglich", "Befriedet", "Schweigend", "Schlafend", "Verlangsamt", - "Betäubt", "Eingefroren", "Handlungsunfähig", "Blutend", "Heilung", "Verwandelt", - "Verbannt", "Abgeschirmt", "Gefesselt", "Reitend", "Verführt", "Vertrieben", - "Entsetzt", "Unverwundbar", "Unterbrochen", "Benommen", "Entdeckung", "Unverwundbar", - "Kopfnuss", "Wütend" - ), - 'ct' => array( - "Nicht kategorisiert", "Wildtier", "Drachkin", "Dämon", "Elementar", "Riese", - "Untoter", "Humanoid", "Tier", "Mechanisch", "Nicht spezifiziert", "Totem", - "Haustier", "Gaswolke" - ), - 'fa' => array( - 1 => "Wolf", 2 => "Katze", 3 => "Spinne", 4 => "Bär", 5 => "Eber", 6 => "Krokilisk", - 7 => "Aasvogel", 8 => "Krebs", 9 => "Gorilla", 11 => "Raptor", 12 => "Weitschreiter", 20 => "Skorpid", - 21 => "Schildkröte", 24 => "Fledermaus", 25 => "Hyäne", 26 => "Raubvogel", 27 => "Windnatter", 30 => "Drachenfalke", - 31 => "Felshetzer", 32 => "Sphärenjäger", 33 => "Sporensegler", 34 => "Netherrochen", 35 => "Schlange", 37 => "Motte", - 38 => "Schimäre", 39 => "Teufelssaurier", 41 => "Silithid", 42 => "Wurm", 43 => "Rhinozeros", 44 => "Wespe", - 45 => "Kernhund", 46 => "Geisterbestie" - ), - 'pvpRank' => array( - null, "Gefreiter / Späher", "Fußknecht / Grunzer", - "Landsknecht / Waffenträger", "Feldwebel / Schlachtrufer", "Fähnrich / Rottenmeister", - "Leutnant / Steingardist", "Hauptmann / Blutgardist", "Kürassier / Zornbringer", - "Ritter der Allianz / Klinge der Horde", "Feldkomandant / Feldherr", "Rittmeister / Sturmreiter", - "Marschall / Kriegsherr", "Feldmarschall / Kriegsfürst", "Großmarschall / Oberster Kriegsfürst" - ), - ), - 'account' => array( - 'title' => "Aowow-Konto", - 'email' => "E-Mail-Adresse", - 'continue' => "Fortsetzen", - 'groups' => array( - -1 => "Keine", "Tester", "Administrator", "Editor", "Moderator", "Bürokrat", - "Entwickler", "VIP", "Blogger", "Premium", "Übersetzer", "Handelsvertreter", - "Screenshot-Verwalter", "Video-Verwalter", "API-Partner", "Ausstehend" - ), - // signIn - 'doSignIn' => "Mit Eurem AoWoW-Konto anmelden", - 'signIn' => "Anmelden", - 'user' => "Benutzername", - 'pass' => "Kennwort", - 'rememberMe' => "Angemeldet bleiben", - 'forgot' => "Vergessen", - 'forgotUser' => "Benutzername", - 'forgotPass' => "Kennwort", - 'accCreate' => 'Noch kein Konto? Jetzt eins erstellen!', - - // recovery - 'recoverUser' => "Benutzernamenanfrage", - 'recoverPass' => "Kennwort zurücksetzen: Schritt %s von 2", - 'newPass' => "Neues Kennwort", - - // creation - 'register' => "Registrierung: Schritt %s von 2", - 'passConfirm' => "Kennwort bestätigen", - - // dashboard - 'ipAddress' => "IP-Adresse", - 'lastIP' => "Letzte bekannte IP", - 'myAccount' => "Mein Account", - 'editAccount' => "Benutze die folgenden Formulare um deine Account-Informationen zu aktualisieren", - 'viewPubDesc' => 'Die Beschreibung in deinem öffentlichen Profil ansehen', - - // bans - 'accBanned' => "Dieses Konto wurde geschlossen", - 'bannedBy' => "Gebannt durch", - 'ends' => "Endet am", - 'permanent' => "Der Bann ist permanent", - 'reason' => "Grund", - 'noReason' => "Es wurde kein Grund angegeben.", - - // form-text - 'emailInvalid' => "Diese E-Mail-Adresse ist ungültig.", // message_emailnotvalid - 'emailNotFound' => "Die E-Mail-Adresse, die Ihr eingegeben habt, ist mit keinem Konto verbunden.

Falls Ihr die E-Mail-Adresse vergessen habt, mit der Ihr Euer Konto erstellt habt, kontaktiert Ihr bitte ".CFG_CONTACT_EMAIL." für Hilfestellung.", - 'createAccSent' => "Eine Nachricht wurde soeben an %s versandt. Folgt den Anweisungen um euer Konto zu erstellen.", - 'recovUserSent' => "Eine Nachricht wurde soeben an %s versandt. Folgt den Anweisungen um euren Benutzernamen zu erhalten.", - 'recovPassSent' => "Eine Nachricht wurde soeben an %s versandt. Folgt den Anweisungen um euer Kennwort zurückzusetzen.", - 'accActivated' => 'Euer Konto wurde soeben aktiviert.
Ihr könnt euch nun anmelden', - 'userNotFound' => "Ein Konto mit diesem Namen existiert nicht.", - 'wrongPass' => "Dieses Kennwort ist ungültig.", - // 'accInactive' => "Dieses Konto wurde bisher nicht aktiviert.", - 'loginExceeded' => "Die maximale Anzahl an Anmelde-Versuchen von dieser IP wurde überschritten. Bitte versucht es in %s erneut.", - 'signupExceeded'=> "Die maximale Anzahl an Regustrierungen von dieser IP wurde überschritten. Bitte versucht es in %s erneut.", - 'errNameLength' => "Euer Benutzername muss mindestens 4 Zeichen lang sein.", // message_usernamemin - 'errNameChars' => "Euer Benutzername kann nur aus Buchstaben und Zahlen bestehen.", // message_usernamenotvalid - 'errPassLength' => "Euer Kennwort muss mindestens 6 Zeichen lang sein.", // message_passwordmin - 'passMismatch' => "Die eingegebenen Kennworte stimmen nicht überein.", - 'nameInUse' => "Es existiert bereits ein Konto mit diesem Namen.", - 'mailInUse' => "Diese E-Mail-Adresse ist bereits mit einem Konto verbunden.", - 'isRecovering' => "Dieses Konto wird bereits wiederhergestellt. Folgt den Anweisungen in der Nachricht oder wartet %s bis das Token verfällt.", - 'passCheckFail' => "Die Kennwörter stimmen nicht überein.", // message_passwordsdonotmatch - 'newPassDiff' => "Euer neues Kennwort muss sich von eurem alten Kennwort unterscheiden." // message_newpassdifferent - ), - 'user' => array( - 'notFound' => "Der Benutzer \"%s\" wurde nicht gefunden!", - 'removed' => "(Entfernt)", - 'joinDate' => "Mitglied seit", - 'lastLogin' => "Letzter Besuch", - 'userGroups' => "Rolle", - 'consecVisits' => "Aufeinanderfolgende Besuche", - 'publicDesc' => "Öffentliche Beschreibung", - 'profileTitle' => "Profil von %s", - 'contributions' => "Beiträge", - 'uploads' => "Hochladevorgänge", - 'comments' => "Kommentare", - 'screenshots' => "Screenshots", - 'videos' => "Videos", - 'posts' => "Forenbeiträge" - ), - 'mail' => array( - 'tokenExpires' => "Das Token wird in %s verfallen.", - 'accConfirm' => ["Kontobestätigung", "Willkommen bei ".CFG_NAME_SHORT."!\r\n\r\nKlicke auf den Link um euren Account zu aktivieren.\r\n\r\n".HOST_URL."?account=signup&token=%s\r\n\r\nFalls Ihr diese Mail nicht angefordert habt kann sie einfach ignoriert werden."], - 'recoverUser' => ["Benutzernamenanfrage", "Folgt diesem Link um euch anzumelden.\r\n\r\n".HOST_URL."?account=signin&token=%s\r\n\r\nFalls Ihr diese Mail nicht angefordert habt kann sie einfach ignoriert werden."], - 'resetPass' => ["Kennwortreset", "Folgt diesem Link um euer Kennwort zurückzusetzen.\r\n\r\n".HOST_URL."?account=forgotpassword&token=%s\r\n\r\nFalls Ihr diese Mail nicht angefordert habt kann sie einfach ignoriert werden."] - ), - 'emote' => array( - 'notFound' => "Dieses Emote existiert nicht.", - 'self' => "An Euch selbst", - 'target' => "An Andere mit Ziel", - 'noTarget' => "An Andere ohne Ziel", - 'isAnimated' => "Besitzt eine Animation", - 'aliases' => "Aliasse", - 'noText' => "Dieses Emote besitzt keinen Text.", - ), - 'enchantment' => array( - 'details' => "Details", - 'activation' => "Aktivierung", - 'notFound' => "Diese Verzauberung existiert nicht.", - 'types' => array( - 1 => "Zauber (Auslösung)", 3 => "Zauber (Anlegen)", 7 => "Zauber (Benutzen)", 8 => "Prismatischer Sockel", - 5 => "Statistik", 2 => "Waffenschaden", 6 => "DPS", 4 => "Verteidigung" - ) - ), - 'gameObject' => array( - 'notFound' => "Dieses Objekt existiert nicht.", - 'cat' => [0 => "Anderes", 9 => "Bücher", 3 => "Behälter", -5 => "Truhen", 25 => "Fischschwärme", -3 => "Kräuter", -4 => "Erzadern", -2 => "Quest", -6 => "Werkzeuge"], - 'type' => [ 9 => "Buch", 3 => "Behälter", -5 => "Truhe", 25 => "", -3 => "Kraut", -4 => "Erzvorkommen", -2 => "Quest", -6 => ""], - 'unkPosition' => "Der Standort dieses Objekts ist nicht bekannt.", - 'npcLootPH' => 'Der Behälter %s beinhaltet die Beute vom Kampf gegen %s. Er erscheint nach seinem Tod.', - 'key' => "Schlüssel", - 'focus' => "Zauberfokus", - 'focusDesc' => "Zauber, die diesen Fokus benötigen, können an diesem Objekt gewirkt werden.", - 'trap' => "Falle", - 'triggeredBy' => "Ausgelöst durch", - 'capturePoint' => "Eroberungspunkt", - 'foundIn' => "Dieses Objekt befindet sich in", - 'restock' => "Wird alle %s wieder aufgefüllt." - ), - 'npc' => array( - 'notFound' => "Dieser NPC existiert nicht.", - 'classification'=> "Einstufung", - 'petFamily' => "Tierart", - 'react' => "Reaktion", - 'worth' => "Wert", - 'unkPosition' => "Der Aufenthaltsort dieses NPCs ist nicht bekannt.", - 'difficultyPH' => "Dieser NPC ist ein Platzhalter für einen anderen Modus von", - 'seat' => "Sitz", - 'accessory' => "Zusätze", - 'accessoryFor' => "Dieser NPC ist Zusatz für Fahrzeug", - 'quotes' => "Zitate", - 'gainsDesc' => "Nach dem Töten dieses NPCs erhaltet Ihr", - 'repWith' => "Ruf mit der Fraktion", - 'stopsAt' => "Endet bei %s", - 'vehicle' => "Fahrzeug", - 'stats' => "Werte", - 'melee' => "Nahkampf", - 'ranged' => "Fernkampf", - 'armor' => "Rüstung", - 'foundIn' => "Dieser NPC befindet sich in", - 'tameable' => "Zähmbar (%s)", - 'waypoint' => "Wegpunkt", - 'wait' => "Wartezeit", - 'respawnIn' => "Wiedereinstieg in", - 'rank' => [0 => "Normal", 1 => "Elite", 4 => "Rar", 2 => "Rar Elite", 3 => "Boss"], - 'textRanges' => [null, "an das Gebiet gesendet", "an die Zone gesendet", "an die Map gesendet", "an die Welt gesendet"], - 'textTypes' => [null, "schreit", "sagt", "flüstert"], - 'modes' => array( - 1 => ["Normal", "Heroisch"], - 2 => ["10-Spieler Normal", "25-Spieler Normal", "10-Spieler Heroisch", "25-Spieler Heroisch"] - ), - 'cat' => array( - "Nicht kategorisiert", "Wildtiere", "Drachkin", "Dämonen", "Elementare", "Riesen", "Untote", "Humanoide", - "Tiere", "Mechanisch", "Nicht spezifiziert", "Totems", "Haustiere", "Gaswolken" - ) - ), - 'event' => array( - 'notFound' => "Dieses Weltereignis existiert nicht.", - 'start' => "Anfang", - 'end' => "Ende", - 'interval' => "Intervall", - 'inProgress' => "Ereignis findet gerade statt", - 'category' => ["Nicht kategorisiert", "Feiertage", "Wiederkehrend", "Spieler vs. Spieler"] - ), - 'achievement' => array( - 'notFound' => "Dieser Erfolg existiert nicht.", - 'criteria' => "Kriterien", - 'points' => "Punkte", - 'series' => "Reihe", - 'outOf' => "von", - 'criteriaType' => "Criterium Typ-Id:", - 'itemReward' => "Ihr bekommt", - 'titleReward' => 'Euch wird der Titel "%s" verliehen', - 'slain' => "getötet", - 'reqNumCrt' => "Benötigt", - 'rfAvailable' => "Verfügbar auf Realm: ", - '_transfer' => 'Dieser Erfolg wird mit %s vertauscht, wenn Ihr zur %s wechselt.', - ), - 'chrClass' => array( - 'notFound' => "Diese Klasse existiert nicht." - ), - 'race' => array( - 'notFound' => "Dieses Volk existiert nicht.", - 'racialLeader' => "Volksanführer", - 'startZone' => "Startgebiet", - ), - 'maps' => array( - 'maps' => "Karten", - 'linkToThisMap' => "Link zu dieser Karte", - 'clear' => "Zurücksetzen", - 'EasternKingdoms' => "Östliche Königreiche", - 'Kalimdor' => "Kalimdor", - 'Outland' => "Scherbenwelt", - 'Northrend' => "Nordend", - 'Instances' => "Instanzen", - 'Dungeons' => "Dungeons", - 'Raids' => "Schlachtzüge", - 'More' => "Weitere", - 'Battlegrounds' => "Schlachtfelder", - 'Miscellaneous' => "Diverse", - 'Azeroth' => "Azeroth", - 'CosmicMap' => "Kosmische Karte", - ), - 'zone' => array( - 'notFound' => "Dieses Gebiet existiert nicht.", - 'attunement' => ["Einstimmung", "Heroische Einstimmung"], - 'key' => ["Schlüssel", "Heroischer Schlüssel"], - 'location' => "Ort", - 'raidFaction' => "Schlachtzugsfraktion", - 'boss' => "Endboss", - 'reqLevels' => "Mindeststufe: [tooltip=instancereqlevel_tip]%d[/tooltip], [tooltip=lfgreqlevel_tip]%d[/tooltip]", - 'zonePartOf' => "Diese Zone ist Teil von [zone=%d].", - 'autoRez' => "Automatische Wiederbelebung", - 'city' => "Stadt", - 'territory' => "Territorium", - 'instanceType' => "Instanzart", - 'hcAvailable' => "Heroischer Modus verfügbar (%d)", - 'numPlayers' => "Anzahl an Spielern", - 'noMap' => "Für dieses Gebiet steht keine Karte zur Verfügung.", - 'instanceTypes' => ["Zone", "Durchgang", "Dungeon", "Schlachtzug", "Battleground", "Dungeon", "Arena", "Schlachtzug", "Schlachtzug"], - 'territories' => ["Allianz", "Horde", "Umkämpft", "Sicheres Gebiet", "PvP", "Welt-PvP"], - 'cat' => array( - "Östliche Königreiche", "Kalimdor", "Dungeons", "Schlachtzüge", "Unbenutzt", null, - "Schlachtfelder", null, "Scherbenwelt", "Arenen", "Nordend" - ) - ), - 'quest' => array( - 'notFound' => "Diese Quest existiert nicht.", - '_transfer' => 'Dieses Quest wird mit %s vertauscht, wenn Ihr zur %s wechselt.', - 'questLevel' => "Stufe %s", - 'requirements' => "Anforderungen", - 'reqMoney' => "Benötigtes Geld", - 'money' => "Geld", - 'additionalReq' => "Zusätzliche Anforderungen um das Quest zu erhalten", - 'reqRepWith' => 'Eure Reputation mit %s %s %s sein', - 'reqRepMin' => "muss mindestens", - 'reqRepMax' => "darf höchstens", - 'progress' => "Fortschritt", - 'provided' => "Bereitgestellt", - 'providedItem' => "Bereitgestellter Gegenstand", - 'completion' => "Abschluss", - 'description' => "Beschreibung", - 'playerSlain' => "Spieler getötet", - 'profession' => "Beruf", - 'timer' => "Zeitbegrenzung", - 'loremaster' => "Meister der Lehren", - 'suggestedPl' => "Empfohlene Spielerzahl", - 'keepsPvpFlag' => "Hält Euch im PvP", - 'daily' => 'Täglich', - 'weekly' => "Wöchentlich", - 'monthly' => "Monatlich", - 'sharable' => "Teilbar", - 'notSharable' => "Nicht teilbar", - 'repeatable' => "Wiederholbar", - 'reqQ' => "Benötigt", - 'reqQDesc' => "Um diese Quest zu erhalten, müsst ihr alle der nachfolgenden Quests abschließen", - 'reqOneQ' => "Benötigt eins von", - 'reqOneQDesc' => "Um diese Quest zu erhalten, müsst ihr eines der nachfolgenden Quests abschließen", - 'opensQ' => "Öffnet Quests", - 'opensQDesc' => "Es ist notwendig, diese Quest zu beenden, um die nachfolgenden Quests zu erhalten", - 'closesQ' => "Schließt Quests", - 'closesQDesc' => "Wenn ihr diese Quest beendet, sind die nachfolgenden Quests nicht mehr verfügbar", - 'enablesQ' => "Aktiviert", - 'enablesQDesc' => "Wenn diese Quest aktiv ist, sind die nachfolgenden Quests ebenfalls verfügbar", - 'enabledByQ' => "Aktiviert durch", - 'enabledByQDesc'=> "Ihr könnt diese Quest nur annehmen, wenn eins der nachfolgenden Quests aktiv ist", - 'gainsDesc' => "Bei Abschluss dieser Quest erhaltet Ihr", - 'theTitle' => 'den Titel "%s"', - 'mailDelivery' => "Ihr werdet diesen Brief%s%s erhalten", - 'mailBy' => ' von %s', - 'mailIn' => " nach %s", - 'unavailable' => "Diese Quest wurde als nicht genutzt markiert und kann weder erhalten noch vollendet werden.", - 'experience' => "Erfahrung", - 'expConvert' => "(oder %s, wenn auf Stufe %d vollendet)", - 'expConvert2' => "%s, wenn auf Stufe %d vollendet", - 'chooseItems' => "Auf Euch wartet eine dieser Belohnungen", - 'receiveItems' => "Ihr bekommt", - 'receiveAlso' => "Ihr bekommt außerdem", - 'spellCast' => "Der folgende Zauber wird auf Euch gewirkt", - 'spellLearn' => "Ihr erlernt", - 'bonusTalents' => "Talentpunkte", - 'spellDisplayed'=> ' (%s wird angezeigt)', - 'attachment' => "Anlage", - 'questInfo' => array( - 0 => "Normal", 1 => "Gruppe", 21 => "Leben", 41 => "PvP", 62 => "Schlachtzug", 81 => "Dungeon", 82 => "Weltereignis", - 83 => "Legendär", 84 => "Eskorte", 85 => "Heroisch", 88 => "Schlachtzug (10)", 89 => "Schlachtzug (25)" - ), - 'cat' => array( - 0 => array( "Östliche Königreiche", - 36 => "Alteracgebirge", 45 => "Arathihochland", 46 => "Brennende Steppe", 279 => "Dalarankrater", 25 => "Der Schwarzfels", - 2257 => "Die Tiefenbahn", 1 => "Dun Morogh", 10 => "Dämmerwald", 1537 => "Eisenschmiede", 41 => "Gebirgspass der Totenwinde", - 3433 => "Geisterlande", 47 => "Hinterland", 3430 => "Immersangwald", 4080 => "Insel von Quel'Danas", 38 => "Loch Modan", - 4298 => "Pestländer: Die Scharlachrote Enklave", 44 => "Rotkammgebirge", 33 => "Schlingendorntal", 51 => "Sengende Schlucht", 3487 => "Silbermond", - 130 => "Silberwald", 1519 => "Sturmwind", 11 => "Sumpfland", 8 => "Sümpfe des Elends", 85 => "Tirisfal", - 1497 => "Unterstadt", 4 => "Verwüstete Lande", 267 => "Vorgebirge des Hügellands", 12 => "Wald von Elwynn", 40 => "Westfall", - 28 => "Westliche Pestländer", 3 => "Ödland", 139 => "Östliche Pestländer" - ), - 1 => array( "Kalimdor", - 16 => "Azshara", 3524 => "Azurmythosinsel", 3525 => "Blutmythosinsel", 17 => "Brachland", 1657 => "Darnassus", - 405 => "Desolace", 3557 => "Die Exodar", 1638 => "Donnerfels", 148 => "Dunkelküste", 14 => "Durotar", - 15 => "Düstermarschen", 331 => "Eschental", 357 => "Feralas", 1216 => "Holzschlundfeste", 490 => "Krater von Un'Goro", - 493 => "Mondlichtung", 215 => "Mulgore", 1637 => "Orgrimmar", 1377 => "Silithus", 406 => "Steinkrallengebirge", - 440 => "Tanaris", 400 => "Tausend Nadeln", 141 => "Teldrassil", 361 => "Teufelswald", 618 => "Winterquell" - ), - 8 => array( "Scherbenwelt", - 3483 => "Höllenfeuerhalbinsel", 3518 => "Nagrand", 3523 => "Nethersturm", 3520 => "Schattenmondtal", 3522 => "Schergrat", - 3703 => "Shattrath", 3679 => "Skettis", 3519 => "Wälder von Terokkar", 3521 => "Zangarmarschen" - ), - 10 => array( "Nordend", - 3537 => "Boreanische Tundra", 4395 => "Dalaran", 495 => "Der heulende Fjord", 4742 => "Hrothgar's Landeplatz", 67 => "Die Sturmgipfel", - 65 => "Drachenöde", 210 => "Eiskrone", 394 => "Grizzlyhügel", 4024 => "Kaltarra", 3711 => "Sholazarbecken", - 4197 => "Tausendwintersee", 66 => "Zul'Drak" - ), - 2 => array( "Dungeons", - 4494 => "Ahn'kahet: Das Alte Königreich", 3790 => "Auchenaikrypta", 4277 => "Azjol-Nerub", 209 => "Burg Schattenfang", 206 => "Burg Utgarde", - 4100 => "Das Ausmerzen von Stratholme", 4228 => "Das Oculus", 796 => "Das Scharlachrote Kloster", 717 => "Das Verlies", 3713 => "Der Blutkessel", - 3905 => "Der Echsenkessel", 2437 => "Der Flammenschlund", 4120 => "Der Nexus", 3716 => "Der Tiefensumpf", 2366 => "Der schwarze Morast", - 3848 => "Die Arkatraz", 3847 => "Die Botanika", 3715 => "Die Dampfkammer", 4272 => "Die Hallen der Blitze", 4264 => "Die Hallen des Steins", - 718 => "Die Höhlen des Wehklagens", 3849 => "Die Mechanar", 4809 => "Die Seelenschmiede", 3717 => "Die Sklavenunterkünfte", 1581 => "Die Todesminen", - 4415 => "Die Violette Festung", 3714 => "Die zerschmetterten Hallen", 2557 => "Düsterbruch", 4196 => "Feste Drak'Tharon", 3845 => "Festung der Stürme", - 721 => "Gnomeregan", 4813 => "Grube von Saron", 4416 => "Gundrak", 4820 => "Hallen der Reflexion", 1941 => "Höhlen der Zeit", - 3562 => "Höllenfeuerbollwerk", 3535 => "Höllenfeuerzitadelle", 722 => "Hügel der Klingenhauer", 491 => "Kral der Klingenhauer", 3792 => "Managruft", - 2100 => "Maraudon", 4723 => "Prüfung des Champions", 3789 => "Schattenlabyrinth", 2057 => "Scholomance", 1583 => "Schwarzfelsspitze", - 1584 => "Schwarzfelstiefen", 3791 => "Sethekkhallen", 2017 => "Stratholme", 4131 => "Terrasse der Magister", 719 => "Tiefschwarze Grotte", - 1196 => "Turm Utgarde", 1337 => "Uldaman", 1477 => "Versunkener Tempel", 2367 => "Vorgebirge des Alten Hügellands", 1176 => "Zul'Farrak" - ), - 3 => array( "Schlachtzüge", - 4603 => "Archavon's Kammer", 3842 => "Das Auge", 4500 => "Das Auge der Ewigkeit", 4493 => "Das Obsidiansanktum", 3959 => "Der Schwarze Tempel", - 4812 => "Eiskronenzitadelle", 2717 => "Geschmolzener Kern", 3923 => "Gruul's Unterschlupf", 3607 => "Höhle des Schlangenschreins", 3606 => "Hyjalgipfel", - 3457 => "Karazhan", 3836 => "Magtheridons Kammer", 3456 => "Naxxramas", 2159 => "Onyxias Hort", 2677 => "Pechschwingenhort", - 4722 => "Prüfung des Kreuzfahrers", 3429 => "Ruinen von Ahn'Qiraj", 4075 => "Sonnenbrunnenplateau", 3428 => "Tempel von Ahn'Qiraj", 4273 => "Ulduar", - 3805 => "Zul'Aman", 1977 => "Zul'Gurub" - ), - 4 => array( "Klassen", - -263 => "Druide", -61 => "Hexenmeister", -261 => "Jäger", -81 => "Krieger", -161 => "Magier", - -141 => "Paladin", -262 => "Priester", -82 => "Schamane", -162 => "Schurke", -372 => "Todesritter" - ), - 5 => array( "Berufe", - -181 => "Alchemie", -101 => "Angeln", -324 => "Erste Hilfe", -201 => "Ingenieurskunst", -371 => "Inschriftenkunde", - -373 => "Juwelenschleifen", -304 => "Kochkunst", -24 => "Kräuterkunde", -182 => "Lederverarbeitung", -121 => "Schmiedekunst", - -264 => "Schneiderei" - ), - 6 => array( "Schlachtfelder", - 2597 => "Alteractal", 3358 => "Arathibecken", 3820 => "Auge des Sturms", 4710 => "Insel der Eroberung", 3277 => "Kriegshymnenschlucht", - -25 => "Schlachtfelder", 4384 => "Strand der Uralten" - ), - 9 => array( "Weltereignisse", - -370 => "Braufest", -1002 => "Kinderwoche", -364 => "Dunkelmond-Jahrmarkt", -41 => "Tag der Toten", -1003 => "Schlotternächte", - -1005 => "Erntedankfest", -376 => "Liebe liegt in der Luft", -366 => "Mondfest", -369 => "Sonnenwende", -1006 => "Neujahr", - -375 => "Die Pilgerfreuden", -374 => "Nobelgarten", -1001 => "Winterhauch" - ), - 7 => array( "Verschiedenes", - -365 => "Krieg von Ahn'Qiraj", -1010 => "Dungeonfinder", -1 => "Episch", -344 => "Legendär", -367 => "Ruf", - -368 => "Invasion der Geißel", -241 => "Turnier" - ), - -2 => "Nicht kategorisiert" - ) - ), - 'title' => array( - 'notFound' => "Dieser Titel existiert nicht.", - '_transfer' => 'Dieser Titel wird mit %s vertauscht, wenn Ihr zur %s wechselt.', - 'cat' => array( - "Allgemein", "Spieler gegen Spieler", "Ruf", "Dungeon & Schlachtzug", "Quests", "Berufe", "Weltereignisse" - ) - ), - 'skill' => array( - 'notFound' => "Diese Fertigkeit existiert nicht.", - 'cat' => array( - -6 => "Haustiere", -5 => "Reittiere", -4 => "Völkerfertigkeiten", 5 => "Attribute", 6 => "Waffenfertigkeiten", 7 => "Klassenfertigkeiten", 8 => "Rüstungssachverstand", - 9 => "Nebenberufe", 10 => "Sprachen", 11 => "Berufe" - ) - ), - 'currency' => array( - 'notFound' => "Diese Währung existiert nicht.", - 'cap' => "Obergrenze", - 'cat' => array( - 1 => "Verschiedenes", 2 => "Spieler gegen Spieler", 4 => "Classic", 21 => "Wrath of the Lich King", 22 => "Dungeon und Schlachtzug", 23 => "Burning Crusade", 41 => "Test", 3 => "Unbenutzt" - ) - ), - 'pet' => array( - 'notFound' => "Diese Tierart existiert nicht.", - 'exotic' => "Exotisch", - 'cat' => ["Wildheit", "Hartnäckigkeit", "Gerissenheit"] - ), - 'faction' => array( - 'notFound' => "Diese Fraktion existiert nicht.", - 'spillover' => "Reputationsüberlauf", - 'spilloverDesc' => "Für diese Fraktion erhaltener Ruf wird zusätzlich mit den unten aufgeführten Fraktionen anteilig verrechnet.", - 'maxStanding' => "Max. Ruf", - 'quartermaster' => "Rüstmeister", - 'customRewRate' => "Abweichende Belohnungsraten", - '_transfer' => 'Die Reputation mit dieser Fraktion wird mit dem für %s vertauscht, wenn Ihr zur %s wechselt.', - 'cat' => array( - 1118 => ["Classic", 469 => "Allianz", 169 => "Dampfdruckkartell", 67 => "Horde", 891 => "Streitkräfte der Allianz", 892 => "Streitkräfte der Horde"], - 980 => ["The Burning Crusade", 936 => "Shattrath"], - 1097 => ["Wrath of the Lich King", 1052 => "Expedition der Horde", 1117 => "Sholazarbecken", 1037 => "Vorposten der Allianz"], - 0 => "Sonstige" - ) - ), - 'itemset' => array( - 'notFound' => "Dieses Ausrüstungsset existiert nicht.", - '_desc' => "%s ist das %s. Es enthält %s Teile.", - '_descTagless' => "%s ist ein Ausrüstungsset, das %s Teile enthält.", - '_setBonuses' => "Setboni", - '_conveyBonus' => "Das Tragen mehrerer Gegenstände aus diesem Set gewährt Eurem Charakter Boni.", - '_pieces' => "Teile", - '_unavailable' => "Dieses Ausrüstungsset ist nicht für Spieler verfügbar.", - '_tag' => "Tag", - 'summary' => "Zusammenfassung", - 'notes' => array( - null, "Dungeon-Set 1", "Dungeon-Set 2", "Tier 1 Raid-Set", - "Tier 2 Raid-Set", "Tier 3 Raid-Set", "Level 60 PvP-Set (Rar)", "Level 60 PvP-Set (Rar, alt)", - "Level 60 PvP-Set (Episch)", "Set der Ruinen von Ahn'Qiraj", "Set des Tempels von Ahn'Qiraj", "Set von Zul'Gurub", - "Tier 4 Raid-Set", "Tier 5 Raid-Set", "Dungeon-Set 3", "Set des Arathibeckens", - "Level 70 PvP-Set (Rar)", "Arena-Set Saison 1", "Tier 6 Raid-Set", "Arena-Set Saison 2", - "Arena-Set Saison 3", "Level 70 PvP-Set 2 (Rar)", "Arena-Set Saison 4", "Tier 7 Raid-Set", - "Arena-Set Saison 5", "Tier 8 Raid-Set", "Arena-Set Saison 6", "Tier 9 Raid-Set", - "Arena-Set Saison 7", "Tier 10 Raid-Set", "Arena-Set Saison 8" - ), - 'types' => array( - null, "Stoff", "Leder", "Schwere Rüstung", "Platte", "Dolch", "Ring", - "Faustwaffe", "Einhandaxt", "Einhandstreitkolben", "Einhandschwert", "Schmuck", "Amulett" - ) - ), - 'spell' => array( - 'notFound' => "Dieser Zauber existiert nicht.", - '_spellDetails' => "Zauberdetails", - '_cost' => "Kosten", - '_range' => "Reichweite", - '_castTime' => "Zauberzeit", - '_cooldown' => "Abklingzeit", - '_distUnit' => "Meter", - '_forms' => "Gestalten", - '_aura' => "Aura", - '_effect' => "Effekt", - '_none' => "Nichts", - '_gcd' => "GCD", - '_globCD' => "Globale Abklingzeit", - '_gcdCategory' => "GCD-Kategorie", - '_value' => "Wert", - '_radius' => "Radius", - '_interval' => "Interval", - '_inSlot' => "im Platz", - '_collapseAll' => "Alle einklappen", - '_expandAll' => "Alle ausklappen", - '_transfer' => 'Dieser Zauber wird mit %s vertauscht, wenn Ihr zur %s wechselt.', - 'discovered' => "Durch Geistesblitz erlernt", - 'ppm' => "%s Auslösungen pro Minute", - 'procChance' => "Procchance", - 'starter' => "Basiszauber", - 'trainingCost' => "Trainingskosten", - 'remaining' => "Noch %s", - 'untilCanceled' => "bis Abbruch", - 'castIn' => "Wirken in %s Sek.", - 'instantPhys' => "Sofort", - 'instantMagic' => "Spontanzauber", - 'channeled' => "Kanalisiert", - 'range' => "%s Meter Reichweite", - 'meleeRange' => "Nahkampfreichweite", - 'unlimRange' => "Unbegrenzte Reichweite", - 'reagents' => "Reagenzien", - 'tools' => "Extras", - 'home' => "<Gasthaus>", - 'pctCostOf' => "vom Grund%s", - 'costPerSec' => ", plus %s pro Sekunde", - 'costPerLevel' => ", plus %s pro Stufe", - 'stackGroup' => "Stack Gruppierung", - 'linkedWith' => "Verknüpft mit", - '_scaling' => "Skalierung", - 'scaling' => array( - 'directSP' => "+%.2f%% der Zaubermacht zum direkten Effekt", 'directAP' => "+%.2f%% der Angriffskraft zum direkten Effekt", - 'dotSP' => "+%.2f%% der Zaubermacht pro Tick", 'dotAP' => "+%.2f%% der Angriffskraft pro Tick" - ), - 'powerRunes' => ["Frost", "Unheilig", "Blut", "Tod"], - 'powerTypes' => array( - // conventional - -2 => "Gesundheit", 0 => "Mana", 1 => "Wut", 2 => "Fokus", 3 => "Energie", 4 => "Zufriedenheit", - 5 => "Runen", 6 => "Runenmacht", - // powerDisplay - -1 => "Munition", -41 => "Pyrit", -61 => "Dampfdruck", -101 => "Hitze", -121 => "Schlamm", -141 => "Blutmacht", - -142 => "Wrath" - ), - 'relItems' => array( - 'base' => "%s im Zusammenhang mit %s anzeigen", - 'link' => " oder ", - 'recipes' => 'Rezeptgegenstände', - 'crafted' => 'Hergestellte Gegenstände' - ), - 'cat' => array( - 7 => "Klassenfertigkeiten", - -13 => "Glyphen", - -11 => ["Sachverstand", 8 => "Rüstung", 6 => "Waffen", 10 => "Sprachen"], - -4 => "Völkerfertigkeiten", - -2 => "Talente", - -6 => "Haustiere", - -5 => "Reittiere", - -3 => array( - "Begleiterfertigkeiten", 782 => "Ghul", 270 => "Allgemein", 213 => "Aasvogel", 210 => "Bär", 763 => "Drachenfalke", 211 => "Eber", - 767 => "Felshetzer", 653 => "Fledermaus", 788 => "Geisterbestie", 215 => "Gorilla", 654 => "Hyäne", 209 => "Katze", 787 => "Kernhund", - 214 => "Krebs", 212 => "Krokilisk", 775 => "Motte", 764 => "Netherrochen", 217 => "Raptor", 655 => "Raubvogel", 786 => "Rhinozeros", - 251 => "Schildkröte", 780 => "Schimäre", 768 => "Schlange", 783 => "Silithid", 236 => "Skorpid", 766 => "Sphärenjäger", 203 => "Spinne", - 765 => "Sporensegler", 781 => "Teufelssaurier", 218 => "Weitschreiter", 785 => "Wespe", 656 => "Windnatter", 208 => "Wolf", 784 => "Wurm", - 204 => "Leerwandler", 205 => "Sukkubus", 189 => "Teufelsjäger", 761 => "Teufelswache", 188 => "Wichtel", - ), - -7 => ["Begleitertalente", 410 => "Gerissenheit", 411 => "Wildheit", 409 => "Hartnäckigkeit"], - 11 => array( - "Berufe", - 171 => "Alchemie", - 164 => ["Schmiedekunst", 9788 => "Rüstungsschmied", 9787 => "Waffenschmied", 17041 => "Axtschmiedemeister", 17040 => "Hammerschmiedemeister", 17039 => "Schwertschmiedemeister"], - 333 => "Verzauberkunst", - 202 => ["Ingenieurskunst", 20219 => "Gnomeningenieurskunst", 20222 => "Gobliningenieurskunst"], - 182 => "Kräuterkunde", - 773 => "Inschriftenkunde", - 755 => "Juwelenschleifen", - 165 => ["Lederverarbeitung", 10656 => "Drachenschuppenlederverarbeitung", 10658 => "Elementarlederverarbeitung", 10660 => "Stammeslederverarbeitung"], - 186 => "Bergbau", - 393 => "Kürschnerei", - 197 => ["Schneiderei", 26798 => "Mondstoffschneiderei", 26801 => "Schattenstoffschneiderei", 26797 => "Zauberfeuerschneiderei"], - ), - 9 => ["Nebenberufe", 185 => "Kochkunst", 129 => "Erste Hilfe", 356 => "Angeln", 762 => "Reiten"], - -8 => "NPC-Fähigkeiten", - -9 => "GM-Fähigkeiten", - 0 => "Nicht kategorisiert" - ), - 'armorSubClass' => array( - "Sonstiges", "Stoffrüstung", "Lederrüstung", "Schwere Rüstung", "Plattenrüstung", - null, "Schilde", "Buchbände", "Götzen", "Totems", - "Siegel" - ), - 'weaponSubClass' => array( - 15 => "Dolche", 0 => "Einhandäxte", 7 => "Einhandschwerter", 4 => "Einhandstreitkolben", 13 => "Faustwaffen", - 6 => "Stangenwaffen", 10 => "Stäbe", 1 => "Zweihandäxte", 8 => "Zweihandschwerter", 5 => "Zweihandstreitkolben", - 18 => "Armbrüste", 2 => "Bögen", 3 => "Schusswaffen", 16 => "Wurfwaffen", 19 => "Zauberstäbe", - 20 => "Angelruten", 14 => "Diverse" - ), - 'subClassMasks' => array( - 0x02A5F3 => "Nahkampfwaffe", 0x0060 => "Schild", 0x04000C => "Distanzwaffe", 0xA091 => "Einhandnahkampfwaffe" - ), - 'traitShort' => array( - 'atkpwr' => "Angr", 'rgdatkpwr' => "DAngr", 'splpwr' => "ZMacht", 'arcsplpwr' => "ArkM", 'firsplpwr' => "FeuM", - 'frosplpwr' => "FroM", 'holsplpwr' => "HeiM", 'natsplpwr' => "NatM", 'shasplpwr' => "SchM", 'splheal' => "Heil" - ), - 'spellModOp' => array( - "Schaden", "Dauer", "Bedrohung", "Effekt 1", "Aufladungen", - "Reichweite", "Radius", "kritische Trefferchance", "Alle Effekte", "Zauberzeitverlust", - "Zauberzeit", "Abklingzeit", "Effekt 2", "Ignoriere Rüstung", "Kosten", - "Kritischer Bonusschaden", "Chance auf Fehlschlag", "Sprung-Ziele", "Chance auf Auslösung", "Intervall", - "Multiplikator (Schaden)", "Globale Abklingzeit", "Schaden über Zeit", "Effekt 3", "Multiplikator (Bonus)", - null, "Auslösungen pro Minute", "Multiplikator (Betrag)", "Widerstand gegen Bannung", "kritischer Bonusschaden2", - "Kostenrückerstattung bei Fehlschlag" - ), - 'combatRating' => array( - "Waffenfertigkeit", "Verteidigungsfertigkeit", "Ausweichen", "Parrieren", "Blocken", - "Nahkampftrefferchance", "Fernkampftrefferchance", "Zaubertrefferchance", "kritische Nahkampftrefferchance", "kritische Fernkampftrefferchance", - "kritische Zaubertrefferchance", "erhaltene Nahkampftreffer", "erhaltene Fernkampftreffer", "erhaltene Zaubertreffer", "erhaltene kritische Nahkampftreffer", - "erhaltene kritische Fernkampftreffer", "erhaltene kritische Zaubertreffer", "Nahkampftempo", "Fernkampftempo", "Zaubertempo", - "Waffenfertigkeit Haupthand", "Waffenfertigkeit Nebenhand", "Waffenfertigkeit Fernkampf", "Waffenkunde", "Rüstungsdurchschlag" - ), - 'lockType' => array( - null, "Schlossknacken", "Kräuterkunde", "Bergbau", "Falle entschärfen", - "Öffnen", "Schatz (DND)", "Verkalkte Elfenedelsteine (DND)", "Schließen", "Falle scharf machen", - "Schnell öffnen", "Schnell schließen", "Offenes Tüfteln", "Offenes Knien", "Offenes Angreifen", - "Gahz'ridian (DND)", "Schlagen", "PvP öffnen", "PvP schließen", "Angeln", - "Inschriftenkunde", "Vom Fahrzeug öffnen" - ), - 'stealthType' => ["Allgemein", "Falle"], - 'invisibilityType' => ["Allgemein", 3 => "Falle", 6 => "Trunkenheit"] - ), - 'item' => array( - 'notFound' => "Dieser Gegenstand existiert nicht .", - 'armor' => "%s Rüstung", - 'block' => "%s Blocken", - 'charges' => "Aufladungen", - 'locked' => "Verschlossen", - 'ratingString' => "%s @ L%s", - 'heroic' => "Heroisch", - 'unique' => "Einzigartig", - 'uniqueEquipped'=> "Einzigartig anlegbar", - 'startQuest' => "Dieser Gegenstand startet eine Quest", - 'bagSlotString' => "%d Platz %s", - 'dps' => "Schaden pro Sekunde", - 'dps2' => "Schaden pro Sekunde", - 'addsDps' => "Adds", - 'fap' => "Angriffskraft in Tiergestalt", - 'durability' => "Haltbarkeit", - 'realTime' => "Realzeit", - 'conjured' => "Herbeigezauberter Gegenstand", - 'damagePhys' => "%s Schaden", - 'damageMagic' => "%s %sschaden", - 'speed' => "Tempo", - 'sellPrice' => "Verkaufspreis", - 'itemLevel' => "Gegenstandsstufe", - 'randEnchant' => "<Zufällige Verzauberung>", - 'readClick' => "<Zum Lesen rechtsklicken>", - 'openClick' => "<Zum Öffnen rechtsklicken>", - 'set' => "Set", - 'partyLoot' => "Gruppenloot", - 'smartLoot' => "Intelligente Beuteverteilung", - 'indestructible'=> "Kann nicht zerstört werden", - 'deprecated' => "Nicht benutzt", - 'useInShape' => "Benutzbar in Gestaltwandlung", - 'useInArena' => "Benutzbar in Arenen", - 'refundable' => "Rückzahlbar", - 'noNeedRoll' => "Kann nicht für Bedarf werfen", - 'atKeyring' => "Passt in den Schlüsselbund", - 'worth' => "Wert", - 'consumable' => "Verbrauchbar", - 'nonConsumable' => "Nicht verbrauchbar", - 'accountWide' => "Accountweit", - 'millable' => "Mahlbar", - 'noEquipCD' => "Keine Anlegabklingzeit", - 'prospectable' => "Sondierbar", - 'disenchantable'=> "Kann entzaubert werden", - 'cantDisenchant'=> "Kann nicht entzaubert werden", - 'repairCost' => "Reparaturkosten", - 'tool' => "Werkzeug", - 'cost' => "Preis", - 'content' => "Inhalt", - '_transfer' => 'Dieser Gegenstand wird mit %s vertauscht, wenn Ihr zur %s wechselt.', - '_unavailable' => "Dieser Gegenstand ist nicht für Spieler verfügbar.", - '_rndEnchants' => "Zufällige Verzauberungen", - '_chance' => "(Chance von %s%%)", - 'slot' => "Platz", - '_quality' => "Qualität", - 'usableBy' => "Benutzbar von", - 'buyout' => "Sofortkaufpreis", - 'each' => "Stück", - 'tabOther' => "Anderes", - 'gems' => "Edelsteine", - 'socketBonus' => "Sockelbonus", - 'socket' => array( - "Metasockel", "Roter Sockel", "Gelber Sockel", "Blauer Sockel", -1 => "Prismatischer Sockel" - ), - 'gemColors' => array( // *_GEM - "Meta", "Rot", "Gelb", "Blau" - ), - 'gemConditions' => array( // ENCHANT_CONDITION_* in GlobalStrings.lua; 2 not in use (use as PH) - 2 => ["weniger als %d Edelstein der Kategorie %s", "weniger als %d Edelsteine der Kategorie %s"], - 3 => "mehr Edelsteine der Kategorie %s als Edelsteine der Kategorie %s", - 5 => ["mindestens %d Edelstein der Kategorie %s", "mindestens %d Edelsteine der Kategorie %s"] - ), - 'reqRating' => array( // ITEM_REQ_ARENA_RATING* - "Benötigt eine persönliche Arenawertung und Teamwertung von %d.", - "Benötigt eine persönliche und eine Teamwertung von %d
in 3v3- oder 5v5-Turnieren", - "Benötigt eine persönliche und eine Teamwertung von %d
in 5v5-Turnieren" - ), - 'quality' => array( - "Schlecht", "Verbreitet", "Selten", "Rar", - "Episch", "Legendär", "Artefakt", "Erbstücke", - ), - 'trigger' => array( - "Benutzen: ", "Anlegen: ", "Chance bei Treffer: ", "", "", - "", "" - ), - 'bonding' => array( - "Accountgebunden", "Wird beim Aufheben gebunden", "Wird beim Anlegen gebunden", - "Wird bei Benutzung gebunden", "Questgegenstand", "Questgegenstand" - ), - 'bagFamily' => array( - "Tasche", "Köcher", "Munitionsbeutel", "Seelentasche", "Lederertasche", - "Schreibertasche", "Kräutertasche", "Verzauberertasche", "Ingenieurstasche", null, /*Schlüssel*/ - "Edelsteintasche", "Bergbautasche" - ), - 'inventoryType' => array( - null, "Kopf", "Hals", "Schulter", "Hemd", - "Brust", "Taille", "Beine", "Füße", "Handgelenke", - "Hände", "Finger", "Schmuck", "Einhändig", "Schildhand", /*Schild*/ - "Distanz", "Rücken", "Zweihändig", "Tasche", "Wappenrock", - null, /*Robe*/ "Waffenhand", "Schildhand", "In der Schildhand geführt", "Projektil", - "Wurfwaffe", null, /*Ranged2*/ "Köcher", "Relikt" - ), - 'armorSubClass' => array( - "Sonstiges", "Stoff", "Leder", "Schwere Rüstung", "Platte", - null, "Schild", "Buchband", "Götze", "Totem", - "Sigel" - ), - 'weaponSubClass' => array( - "Axt", "Axt", "Bogen", "Schusswaffe", "Streitkolben", - "Streitkolben", "Stangenwaffe", "Schwert", "Schwert", null, - "Stab", null, null, "Faustwaffe", "Diverse", - "Dolche", "Wurfwaffe", null, "Armbrust", "Zauberstab", - "Angelrute" - ), - 'projectileSubClass' => array( - null, null, "Pfeil", "Kugel", null - ), - 'elixirType' => [null, "Kampf", "Wächter"], - 'cat' => array( - 2 => "Waffen", // self::$spell['weaponSubClass'] - 4 => array("Rüstung", array( - 1 => "Stoffrüstung", 2 => "Lederrüstung", 3 => "Schwere Rüstung", 4 => "Plattenrüstung", 6 => "Schilde", 7 => "Buchbände", - 8 => "Götzen", 9 => "Totems", 10 => "Siegel", -6 => "Umhänge", -5 => "Nebenhandgegenstände", -8 => "Hemden", - -7 => "Wappenröcke", -3 => "Amulette", -2 => "Ringe", -4 => "Schmuckstücke", 0 => "Verschiedenes (Rüstung)", - )), - 1 => array("Behälter", array( - 0 => "Taschen", 3 => "Verzauberertaschen", 4 => "Ingenieurstaschen", 5 => "Edelsteintaschen", 2 => "Kräutertaschen", 8 => "Schreibertaschen", - 7 => "Lederertaschen", 6 => "Bergbautaschen", 1 => "Seelentaschen" - )), - 0 => array("Verbrauchbar", array( - -3 => "Gegenstandsverzauberungen (Temporäre)", 6 => "Gegenstandsverzauberungen (Dauerhafte)", 2 => ["Elixire", [1 => "Kampfelixire", 2 => "Wächterelixire"]], - 1 => "Tränke", 4 => "Schriftrollen", 7 => "Verbände", 0 => "Verbrauchbar", 3 => "Fläschchen", 5 => "Essen & Trinken", - 8 => "Andere (Verbrauchbar)" - )), - 16 => array("Glyphen", array( - 1 => "Kriegerglyphen", 2 => "Paladinglyphen", 3 => "Jägerglyphen", 4 => "Schurkenglyphen", 5 => "Priesterglyphen", 6 => "Todesritterglyphen", - 7 => "Schamanenglyphen", 8 => "Magierglyphen", 9 => "Hexenmeisterglyphen", 11 => "Druidenglyphen" - )), - 7 => array("Handwerkswaren", array( - 14 => "Rüstungsverzauberungen", 5 => "Stoff", 3 => "Geräte", 10 => "Elementar", 12 => "Verzauberkunst", 2 => "Sprengstoff", - 9 => "Kräuter", 4 => "Juwelenschleifen", 6 => "Leder", 13 => "Materialien", 8 => "Fleisch", 7 => "Metall & Stein", - 1 => "Teile", 15 => "Waffenverzauberungen", 11 => "Andere (Handwerkswaren)" - )), - 6 => ["Projektile", [ 2 => "Pfeile", 3 => "Kugeln" ]], - 11 => ["Köcher", [ 2 => "Köcher", 3 => "Munitionsbeutel" ]], - 9 => array("Rezepte", array( - 0 => "Bücher", 6 => "Alchemierezepte", 4 => "Schmiedekunstpläne", 5 => "Kochrezepte", 8 => "Verzauberkunstformeln", 3 => "Ingenieurschemata", - 7 => "Erste Hilfe-Bücher", 9 => "Angelbücher", 11 => "Inschriftenkundetechniken",10 => "Juwelenschleifen-Vorlagen",1 => "Lederverarbeitungsmuster",12 => "Bergbauleitfäden", - 2 => "Schneidereimuster" - )), - 3 => array("Edelsteine", array( - 6 => "Meta-Edelsteine", 0 => "Rote Edelsteine", 1 => "Blaue Edelsteine", 2 => "Gelbe Edelsteine", 3 => "Violette Edelsteine", 4 => "Grüne Edelsteine", - 5 => "Orange Edelsteine", 8 => "Prismatische Edelsteine", 7 => "Einfache Edelsteine" - )), - 15 => array("Verschiedenes", array( - -2 => "Rüstungsmarken", 3 => "Feiertag", 0 => "Plunder", 1 => "Reagenzien", 5 => "Reittiere", -7 => "Flugtiere", - 2 => "Haustiere", 4 => "Andere (Verschiedenes)" - )), - 10 => "Währung", - 12 => "Quest", - 13 => "Schlüssel", - ), - 'statType' => array( - "Erhöht Euer Mana um %d.", - "Erhöht Eure Gesundheit um %d.", - null, - "Beweglichkeit", - "Stärke", - "Intelligenz", - "Willenskraft", - "Ausdauer", - null, null, null, null, - "Erhöht die Verteidigungswertung um %d.", - "Erhöht Eure Ausweichwertung um %d.", - "Erhöht Eure Parierwertung um %d.", - "Erhöht Eure Blockwertung um %d.", - "Erhöht Nahkampftrefferwertung um %d.", - "Erhöht Fernkampftrefferwertung um %d.", - "Erhöht Zaubertrefferwertung um %d.", - "Erhöht kritische Nahkampftrefferwertung um %d.", - "Erhöht kritische Fernkampftrefferwertung um %d.", - "Erhöht kritische Zaubertrefferwertung um %d.", - "Erhöht Vermeidungswertung für Nahkampftreffer um +3.", - "Erhöht Vermeidungswertung für Distanztreffer um %d.", - "Erhöht Vermeidungswertung für Zaubertreffer um %d.", - "Erhöht Vermeidungswertung für kritische Nahkampftreffer um %d.", - "Erhöht Vermeidungswertung für kritische Distanztreffer um %d.", - "Erhöht Vermeidungswertung für kritische Zaubertreffer um %d.", - "Erhöht Nahkampftempowertung um %d.", - "Erhöht Fernkampftempowertung um %d.", - "Erhöht Zaubertempowertung um %d.", - "Erhöht Eure Trefferwertung um %d.", - "Erhöht Eure kritische Trefferwertung um %d.", - "Erhöht Vermeidungswertung um %d.", - "Erhöht Vermeidungswertung für kritische Treffer um %d.", - "Erhöht Eure Abhärtungswertung um %d.", - "Erhöht Eure Tempowertung um %d.", - "Erhöht Waffenkundewertung um %d.", - "Erhöht Angriffskraft um %d.", - "Erhöht Distanzangriffskraft um %d.", - "Erhöht die Angriffskraft in Katzen-, Bären-, Terrorbären- und Mondkingestalt um %d.", - "Erhöht den von Zaubern und Effekten verursachten Schaden um bis zu %d.", - "Erhöht die von Zaubern und Effekten verursachte Heilung um bis zu %d.", - "Stellt alle 5 Sek. %d Mana wieder her.", - "Erhöht Euren Rüstungsdurchschlagwert um %d.", - "Erhöht die Zaubermacht um %d.", - "Stellt alle 5 Sek. %d Gesundheit wieder her.", - "Erhöht den Zauberdurchschlag um %d.", - "Erhöht Blockwert um %d.", - "Unbekannter Bonus #%d (%d)", - ) - ) -); - -?> +\World of Warcraft\Data\deDE\patch-deDE-3.MPQ\Interface\FrameXML\GlobalStrings.lua + like: ITEM_MOD_*, POWER_TYPE_*, ITEM_BIND_*, PVP_RANK_* +*/ + +$lang = array( + // page variables + 'timeUnits' => array( + 'sg' => ["Jahr", "Monat", "Woche", "Tag", "Stunde", "Minute", "Sekunde", "Millisekunde"], + 'pl' => ["Jahre", "Monate", "Wochen", "Tage", "Stunden", "Minuten", "Sekunden", "Millisekunden"], + 'ab' => ["J.", "M.", "W.", "Tag", "Std.", "Min.", "Sek.", "Ms."] + ), + 'main' => array( + 'name' => "Name", + 'link' => "Link", + 'signIn' => "Anmelden / Registrieren", + 'jsError' => "Stelle bitte sicher, dass JavaScript aktiviert ist.", + 'language' => "Sprache", + 'feedback' => "Rückmeldung", + 'numSQL' => "Anzahl an MySQL-Queries", + 'timeSQL' => "Zeit für MySQL-Queries", + 'noJScript' => 'Diese Seite macht ausgiebigen Gebrauch von JavaScript.
Bitte aktiviert JavaScript in Eurem Browser.', + 'userProfiles' => "Deine Charaktere", + 'pageNotFound' => "Dies %s existiert nicht.", + 'gender' => "Geschlecht", + 'sex' => [null, "Mann", "Frau"], + 'players' => "Spieler", + 'quickFacts' => "Kurzübersicht", + 'screenshots' => "Screenshots", + 'videos' => "Videos", + 'side' => "Seite", + 'related' => "Weiterführende Informationen", + 'contribute' => "Beitragen", + // 'replyingTo' => "Antwort zu einem Kommentar von", + 'submit' => "Absenden", + 'cancel' => "Abbrechen", + 'rewards' => "Belohnungen", + 'gains' => "Belohnungen", + 'login' => "Login", + 'forum' => "Forum", + 'n_a' => "n. v.", + 'siteRep' => "Ruf", + 'aboutUs' => "Über Aowow", + 'and' => " und ", + 'or' => " oder ", + 'back' => "Zurück", + 'reputationTip' => "Rufpunkte", + 'byUserTimeAgo' => 'Von %1$s vor %s', + + // filter + 'extSearch' => "Erweiterte Suche", + 'addFilter' => "Weiteren Filter hinzufügen", + 'match' => "Verwendete Filter", + 'allFilter' => "Alle Filters", + 'oneFilter' => "Mindestens einer", + 'applyFilter' => "Filter anwenden", + 'resetForm' => "Formular zurücksetzen", + 'refineSearch' => 'Tipp: Präzisiere deine Suche mit Durchsuchen einer Unterkategorie.', + 'clear' => "leeren", + 'exactMatch' => "Exakt passend", + '_reqLevel' => "Mindeststufe", + + // infobox + 'unavailable' => "Nicht für Spieler verfügbar", + 'disabled' => "Deaktiviert", + 'disabledHint' => "Kann nicht erhalten oder abgeschlossen werden.", + 'serverside' => "Serverseitig", + 'serversideHint'=> "Diese Informationen sind nicht im Client enthalten und wurden gesnifft und/oder erraten.", + + // red buttons + 'links' => "Links", + 'compare' => "Vergleichen", + 'view3D' => "3D-Ansicht", + 'findUpgrades' => "Bessere Gegenstände finden...", + + // miscTools + 'errPageTitle' => "Seite nicht gefunden", + 'nfPageTitle' => "Fehler", + 'subscribe' => "Abonnieren", + 'mostComments' => ["Gestern", "Vergangene %d Tage"], + 'utilities' => array( + "Neueste Ergänzungen", "Neueste Artikel", "Neueste Kommentare", "Neueste Screenshots", null, + "Nicht bewertete Kommentare", 11 => "Neueste Videos", 12 => "Meiste Kommentare", 13 => "Fehlende Screenshots" + ), + + // article & infobox + 'englishOnly' => "Diese Seite ist nur in Englisch verfügbar.", + + // calculators + 'preset' => "Vorlage", + 'addWeight' => "Weitere Gewichtung hinzufügen", + 'createWS' => "Gewichtungsverteilung erstellen", + 'jcGemsOnly' => "JS-exklusive Edelsteine einschließen", + 'cappedHint' => 'Tipp: Entfernt 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", + 'chooseClass' => "Wählt eine Klasse", + 'chooseFamily' => "Wählt eine Tierart", + + // profiler + 'realm' => "Realm", + 'region' => "Region", + 'viewCharacter' => "Charakter anzeigen", + '_cpHead' => "Charakter-Profiler", + '_cpHint' => "Der Charakter-Profiler gibt Euch die Möglichkeit, Euren Charakter zu editieren, bessere Ausrüstung zu finden, Eure Gearscore zu überprüfen, und mehr!", + '_cpHelp' => "Um loszulegen, folgt einfach den untenstehenden Schritten. Falls Ihr mehr Informationen benötigt, schaut auf unserer ausführlichen Hilfeseite nach.", + '_cpFooter' => "Falls Ihr eine genauere Suche möchtet, probiert unsere erweiterten Suchoptionen. Ihr könnt außerdem ein neues individuelles Profil erstellen.", + + // help + 'help' => "Hilfe", + 'helpTopics' => array( + "Wie man Kommentare schreibt", "Modellviewer", "Screenshots: Tipps & Tricks", "Gewichtung von Werten", + "Talentrechner", "Gegenstandsvergleich", "Profiler", "Markup Guide" + ), + + // search + 'search' => "Suche", + 'searchButton' => "Suche", + 'foundResult' => "Suchergebnisse für", + 'noResult' => "Keine Ergebnisse für", + 'tryAgain' => "Bitte versucht es mit anderen Suchbegriffen oder überprüft deren Schreibweise.", + 'ignoredTerms' => "Die folgenden Wörter wurden in Eurer Suche ignoriert: %s", + + // formating + 'colon' => ': ', + 'dateFmtShort' => "d.m.Y", + 'dateFmtLong' => "d.m.Y \u\m H:i", + + // error + 'intError' => "Ein interner Fehler ist aufgetreten.", + 'intError2' => "Ein interner Fehler ist aufgetreten. (%s)", + 'genericError' => "Ein Fehler trat auf; aktualisiert die Seite und versucht es nochmal. Wenn der Fehler bestehen bleibt, bitte meldet es bei feedback", # LANG.genericerror + 'bannedRating' => "Ihr wurdet davon gesperrt, Kommentare zu bewerten.", # LANG.tooltip_banned_rating + 'tooManyVotes' => "Ihr habt die tägliche Grenze für erlaubte Bewertungen erreicht. Kommt morgen mal wieder!", # LANG.tooltip_too_many_votes + ), + 'screenshot' => array( + 'submission' => "Screenshot-Einsendung", + 'selectAll' => "Alles auswählen", + 'cropHint' => "Ihr könnt Euren Screenshot zuschneiden und beschriften.", + 'displayOn' => "Hochgeladen für:[br]%s - [%s=%d]", + 'caption' => "Kurzbeschreibung", + 'charLimit' => "Optional, bis zu 200 Zeichen", + 'thanks' => array( + 'contrib' => "Vielen Dank für Euren Beitrag!", + 'goBack' => 'Klickt hier, um zu der vorherigen Seite zurückzukehren.', + 'note' => "Hinweis: Euer Screenshot muss zunächst zugelassen werden, bevor es auf der Seite erscheint. Dies kann bis zu 72 Stunden dauern." + ), + 'error' => array( + 'unkFormat' => "Unbekanntes Bildformat.", + 'tooSmall' => "Euer Screenshot ist viel zu klein. (< ".CFG_SCREENSHOT_MIN_SIZE."x".CFG_SCREENSHOT_MIN_SIZE.").", + 'selectSS' => "Wählt bitte den Screenshot aus, den Ihr hochladen möchtet.", + 'notAllowed' => "Es ist euch nicht erlaubt einen Screenshot hochzuladen!", + ) + ), + 'game' => array( + 'achievement' => "Erfolg", + 'achievements' => "Erfolge", + 'class' => "Klasse", + 'classes' => "Klassen", + 'currency' => "Währung", + 'currencies' => "Währungen", + 'difficulty' => "Modus", + 'dispelType' => "Bannart", + 'duration' => "Dauer", + 'emote' => "Emote", + 'emotes' => "Emotes", + 'enchantment' => "Verzauberung", + 'enchantments' => "Verzauberungen", + 'object' => "Objekt", + 'objects' => "Objekte", + 'glyphType' => "Glyphenart", + 'race' => "Volk", + 'races' => "Völker", + 'title' => "Titel", + 'titles' => "Titel", + 'eventShort' => "Ereignis", + 'event' => "Weltereigniss", + 'events' => "Weltereignisse", + 'faction' => "Fraktion", + 'factions' => "Fraktionen", + 'cooldown' => "%s Abklingzeit", + 'item' => "Gegenstand", + 'items' => "Gegenstände", + 'itemset' => "Ausrüstungsset", + 'itemsets' => "Ausrüstungssets", + 'mechanic' => "Auswirkung", + 'mechAbbr' => "Ausw.", + 'meetingStone' => "Versammlungsstein", + 'npc' => "NPC", + 'npcs' => "NPCs", + 'pet' => "Begleiter", + 'pets' => "Begleiter", + 'profile' => "", + 'profiles' => "Profile", + 'quest' => "Quest", + 'quests' => "Quests", + 'requires' => "Benötigt %s", + 'requires2' => "Benötigt", + 'reqLevel' => "Benötigt Stufe %s", + 'reqLevelHlm' => "Benötigt Stufe %s", + 'reqSkillLevel' => "Benötigte Fertigkeitsstufe", + 'level' => "Stufe", + 'school' => "Magieart", + 'skill' => "Fertigkeit", + 'skills' => "Fertigkeiten", + 'spell' => "Zauber", + 'spells' => "Zauber", + 'type' => "Art", + 'valueDelim' => " - ", // " bis " + 'zone' => "Zone", + 'zones' => "Gebiete", + + 'pvp' => "PvP", + 'honorPoints' => "Ehrenpunkte", + 'arenaPoints' => "Arenapunkte", + 'heroClass' => "Heldenklasse", + 'resource' => "Ressource", + 'resources' => "Ressourcen", + 'role' => "Rolle", + 'roles' => "Rollen", + 'specs' => "Spezialisierungen", + '_roles' => ["Heiler", "Nahkampf-DPS", "Distanz-DPS", "Tank"], + + 'phases' => "Phasen", + 'mode' => "Modus", + 'modes' => [-1 => "Beliebig", "Normal / Normal 10", "Heroisch / Normal 25", "Heroisch 10", "Heroisch 25"], + 'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"], + 'stats' => ["Stärke", "Beweglichkeit", "Ausdauer", "Intelligenz", "Willenskraft"], + 'sources' => array( + "Unbekannt", "Hergestellt", "Drop", "PvP", "Quest", "Händler", + "Lehrer", "Entdeckung", "Einlösung", "Talent", "Startausrüstung", "Ereignis", + "Erfolg", null, "Schwarzmarkt", "Entzaubert", "Geangelt", "Gesammelt", + "Gemahlen", "Abgebaut", "Sondiert", "Aus Taschendiebstahl", "Geborgen", "Gehäutet", + "In-Game-Store" + ), + 'languages' => array( + 1 => "Orcisch", 2 => "Darnassisch", 3 => "Taurisch", 6 => "Zwergisch", 7 => "Gemeinsprache", 8 => "Dämonisch", + 9 => "Titanisch", 10 => "Thalassisch", 11 => "Drachisch", 12 => "Kalimagisch", 13 => "Gnomisch", 14 => "Trollisch", + 33 => "Gossensprache", 35 => "Draeneiisch", 36 => "Zombie", 37 => "Gnomenbinär", 38 => "Goblinbinär" + ), + 'gl' => [null, "Erhebliche", "Geringe"], + 'si' => [1 => "Allianz", -1 => "Nur für Allianz", 2 => "Horde", -2 => "Nur für Horde", 3 => "Beide"], + 'resistances' => [null, 'Heiligwiderstand', 'Feuerwiderstand', 'Naturwiderstand', 'Frostwiderstand', 'Schattenwiderstand', 'Arkanwiderstand'], + 'sc' => ["Körperlich", "Heilig", "Feuer", "Natur", "Frost", "Schatten", "Arkan"], + 'dt' => [null, "Magie", "Fluch", "Krankheit", "Gift", "Verstohlenheit", "Unsichtbarkeit", null, null, "Wut"], + 'cl' => [null, "Krieger", "Paladin", "Jäger", "Schurke", "Priester", "Todesritter", "Schamane", "Magier", "Hexenmeister", null, "Druide"], + 'ra' => [-2 => "Horde", -1 => "Allianz", "Beide", "Mensch", "Orc", "Zwerg", "Nachtelf", "Untoter", "Tauren", "Gnom", "Troll", null, "Blutelf", "Draenei"], + 'rep' => ["Hasserfüllt", "Feindselig", "Unfreundlich", "Neutral", "Freundlich", "Wohlwollend", "Respektvoll", "Ehrfürchtig"], + 'st' => array( + "Vorgabe", "Katzengestalt", "Baum des Lebens", "Reisegestalt", "Wassergestalt", "Bärengestalt", + null, null, "Terrorbärengestalt", null, null, null, + null, "Schattentanz", null, null, "Geisterwolf", "Kampfhaltung", + "Verteidigungshaltung", "Berserkerhaltung", null, null, "Metamorphosis", null, + null, null, null, "Schnelle Fluggestalt", "Schattengestalt", "Fluggestalt", + "Verstohlenheit", "Mondkingestalt", "Geist der Erlösung" + ), + 'me' => array( + null, "Bezaubert", "Desorientiert", "Entwaffnet", "Abgelenkt", "Flüchtend", + "Ergriffen", "Unbeweglich", "Befriedet", "Schweigend", "Schlafend", "Verlangsamt", + "Betäubt", "Eingefroren", "Handlungsunfähig", "Blutend", "Heilung", "Verwandelt", + "Verbannt", "Abgeschirmt", "Gefesselt", "Reitend", "Verführt", "Vertrieben", + "Entsetzt", "Unverwundbar", "Unterbrochen", "Benommen", "Entdeckung", "Unverwundbar", + "Kopfnuss", "Wütend" + ), + 'ct' => array( + "Nicht kategorisiert", "Wildtier", "Drachkin", "Dämon", "Elementar", "Riese", + "Untoter", "Humanoid", "Tier", "Mechanisch", "Nicht spezifiziert", "Totem", + "Haustier", "Gaswolke" + ), + 'fa' => array( + 1 => "Wolf", 2 => "Katze", 3 => "Spinne", 4 => "Bär", 5 => "Eber", 6 => "Krokilisk", + 7 => "Aasvogel", 8 => "Krebs", 9 => "Gorilla", 11 => "Raptor", 12 => "Weitschreiter", 20 => "Skorpid", + 21 => "Schildkröte", 24 => "Fledermaus", 25 => "Hyäne", 26 => "Raubvogel", 27 => "Windnatter", 30 => "Drachenfalke", + 31 => "Felshetzer", 32 => "Sphärenjäger", 33 => "Sporensegler", 34 => "Netherrochen", 35 => "Schlange", 37 => "Motte", + 38 => "Schimäre", 39 => "Teufelssaurier", 41 => "Silithid", 42 => "Wurm", 43 => "Rhinozeros", 44 => "Wespe", + 45 => "Kernhund", 46 => "Geisterbestie" + ), + 'pvpRank' => array( + null, "Gefreiter / Späher", "Fußknecht / Grunzer", + "Landsknecht / Waffenträger", "Feldwebel / Schlachtrufer", "Fähnrich / Rottenmeister", + "Leutnant / Steingardist", "Hauptmann / Blutgardist", "Kürassier / Zornbringer", + "Ritter der Allianz / Klinge der Horde", "Feldkomandant / Feldherr", "Rittmeister / Sturmreiter", + "Marschall / Kriegsherr", "Feldmarschall / Kriegsfürst", "Großmarschall / Oberster Kriegsfürst" + ), + ), + 'account' => array( + 'title' => "Aowow-Konto", + 'email' => "E-Mail-Adresse", + 'continue' => "Fortsetzen", + 'groups' => array( + -1 => "Keine", "Tester", "Administrator", "Editor", "Moderator", "Bürokrat", + "Entwickler", "VIP", "Blogger", "Premium", "Übersetzer", "Handelsvertreter", + "Screenshot-Verwalter", "Video-Verwalter", "API-Partner", "Ausstehend" + ), + // signIn + 'doSignIn' => "Mit Eurem AoWoW-Konto anmelden", + 'signIn' => "Anmelden", + 'user' => "Benutzername", + 'pass' => "Kennwort", + 'rememberMe' => "Angemeldet bleiben", + 'forgot' => "Vergessen", + 'forgotUser' => "Benutzername", + 'forgotPass' => "Kennwort", + 'accCreate' => 'Noch kein Konto? Jetzt eins erstellen!', + + // recovery + 'recoverUser' => "Benutzernamenanfrage", + 'recoverPass' => "Kennwort zurücksetzen: Schritt %s von 2", + 'newPass' => "Neues Kennwort", + + // creation + 'register' => "Registrierung: Schritt %s von 2", + 'passConfirm' => "Kennwort bestätigen", + + // dashboard + 'ipAddress' => "IP-Adresse", + 'lastIP' => "Letzte bekannte IP", + 'myAccount' => "Mein Account", + 'editAccount' => "Benutze die folgenden Formulare um deine Account-Informationen zu aktualisieren", + 'viewPubDesc' => 'Die Beschreibung in deinem öffentlichen Profil ansehen', + + // bans + 'accBanned' => "Dieses Konto wurde geschlossen", + 'bannedBy' => "Gebannt durch", + 'ends' => "Endet am", + 'permanent' => "Der Bann ist permanent", + 'reason' => "Grund", + 'noReason' => "Es wurde kein Grund angegeben.", + + // form-text + 'emailInvalid' => "Diese E-Mail-Adresse ist ungültig.", // message_emailnotvalid + 'emailNotFound' => "Die E-Mail-Adresse, die Ihr eingegeben habt, ist mit keinem Konto verbunden.

Falls Ihr die E-Mail-Adresse vergessen habt, mit der Ihr Euer Konto erstellt habt, kontaktiert Ihr bitte ".CFG_CONTACT_EMAIL." für Hilfestellung.", + 'createAccSent' => "Eine Nachricht wurde soeben an %s versandt. Folgt den Anweisungen um euer Konto zu erstellen.", + 'recovUserSent' => "Eine Nachricht wurde soeben an %s versandt. Folgt den Anweisungen um euren Benutzernamen zu erhalten.", + 'recovPassSent' => "Eine Nachricht wurde soeben an %s versandt. Folgt den Anweisungen um euer Kennwort zurückzusetzen.", + 'accActivated' => 'Euer Konto wurde soeben aktiviert.
Ihr könnt euch nun anmelden', + 'userNotFound' => "Ein Konto mit diesem Namen existiert nicht.", + 'wrongPass' => "Dieses Kennwort ist ungültig.", + // 'accInactive' => "Dieses Konto wurde bisher nicht aktiviert.", + 'loginExceeded' => "Die maximale Anzahl an Anmelde-Versuchen von dieser IP wurde überschritten. Bitte versucht es in %s erneut.", + 'signupExceeded'=> "Die maximale Anzahl an Regustrierungen von dieser IP wurde überschritten. Bitte versucht es in %s erneut.", + 'errNameLength' => "Euer Benutzername muss mindestens 4 Zeichen lang sein.", // message_usernamemin + 'errNameChars' => "Euer Benutzername kann nur aus Buchstaben und Zahlen bestehen.", // message_usernamenotvalid + 'errPassLength' => "Euer Kennwort muss mindestens 6 Zeichen lang sein.", // message_passwordmin + 'passMismatch' => "Die eingegebenen Kennworte stimmen nicht überein.", + 'nameInUse' => "Es existiert bereits ein Konto mit diesem Namen.", + 'mailInUse' => "Diese E-Mail-Adresse ist bereits mit einem Konto verbunden.", + 'isRecovering' => "Dieses Konto wird bereits wiederhergestellt. Folgt den Anweisungen in der Nachricht oder wartet %s bis das Token verfällt.", + 'passCheckFail' => "Die Kennwörter stimmen nicht überein.", // message_passwordsdonotmatch + 'newPassDiff' => "Euer neues Kennwort muss sich von eurem alten Kennwort unterscheiden." // message_newpassdifferent + ), + 'user' => array( + 'notFound' => "Der Benutzer \"%s\" wurde nicht gefunden!", + 'removed' => "(Entfernt)", + 'joinDate' => "Mitglied seit", + 'lastLogin' => "Letzter Besuch", + 'userGroups' => "Rolle", + 'consecVisits' => "Aufeinanderfolgende Besuche", + 'publicDesc' => "Öffentliche Beschreibung", + 'profileTitle' => "Profil von %s", + 'contributions' => "Beiträge", + 'uploads' => "Hochladevorgänge", + 'comments' => "Kommentare", + 'screenshots' => "Screenshots", + 'videos' => "Videos", + 'posts' => "Forenbeiträge" + ), + 'mail' => array( + 'tokenExpires' => "Das Token wird in %s verfallen.", + 'accConfirm' => ["Kontobestätigung", "Willkommen bei ".CFG_NAME_SHORT."!\r\n\r\nKlicke auf den Link um euren Account zu aktivieren.\r\n\r\n".HOST_URL."?account=signup&token=%s\r\n\r\nFalls Ihr diese Mail nicht angefordert habt kann sie einfach ignoriert werden."], + 'recoverUser' => ["Benutzernamenanfrage", "Folgt diesem Link um euch anzumelden.\r\n\r\n".HOST_URL."?account=signin&token=%s\r\n\r\nFalls Ihr diese Mail nicht angefordert habt kann sie einfach ignoriert werden."], + 'resetPass' => ["Kennwortreset", "Folgt diesem Link um euer Kennwort zurückzusetzen.\r\n\r\n".HOST_URL."?account=forgotpassword&token=%s\r\n\r\nFalls Ihr diese Mail nicht angefordert habt kann sie einfach ignoriert werden."] + ), + 'emote' => array( + 'notFound' => "Dieses Emote existiert nicht.", + 'self' => "An Euch selbst", + 'target' => "An Andere mit Ziel", + 'noTarget' => "An Andere ohne Ziel", + 'isAnimated' => "Besitzt eine Animation", + 'aliases' => "Aliasse", + 'noText' => "Dieses Emote besitzt keinen Text.", + ), + 'enchantment' => array( + 'details' => "Details", + 'activation' => "Aktivierung", + 'notFound' => "Diese Verzauberung existiert nicht.", + 'types' => array( + 1 => "Zauber (Auslösung)", 3 => "Zauber (Anlegen)", 7 => "Zauber (Benutzen)", 8 => "Prismatischer Sockel", + 5 => "Statistik", 2 => "Waffenschaden", 6 => "DPS", 4 => "Verteidigung" + ) + ), + 'gameObject' => array( + 'notFound' => "Dieses Objekt existiert nicht.", + 'cat' => [0 => "Anderes", 9 => "Bücher", 3 => "Behälter", -5 => "Truhen", 25 => "Fischschwärme", -3 => "Kräuter", -4 => "Erzadern", -2 => "Quest", -6 => "Werkzeuge"], + 'type' => [ 9 => "Buch", 3 => "Behälter", -5 => "Truhe", 25 => "", -3 => "Kraut", -4 => "Erzvorkommen", -2 => "Quest", -6 => ""], + 'unkPosition' => "Der Standort dieses Objekts ist nicht bekannt.", + 'npcLootPH' => 'Der Behälter %s beinhaltet die Beute vom Kampf gegen %s. Er erscheint nach seinem Tod.', + 'key' => "Schlüssel", + 'focus' => "Zauberfokus", + 'focusDesc' => "Zauber, die diesen Fokus benötigen, können an diesem Objekt gewirkt werden.", + 'trap' => "Falle", + 'triggeredBy' => "Ausgelöst durch", + 'capturePoint' => "Eroberungspunkt", + 'foundIn' => "Dieses Objekt befindet sich in", + 'restock' => "Wird alle %s wieder aufgefüllt." + ), + 'npc' => array( + 'notFound' => "Dieser NPC existiert nicht.", + 'classification'=> "Einstufung", + 'petFamily' => "Tierart", + 'react' => "Reaktion", + 'worth' => "Wert", + 'unkPosition' => "Der Aufenthaltsort dieses NPCs ist nicht bekannt.", + 'difficultyPH' => "Dieser NPC ist ein Platzhalter für einen anderen Modus von", + 'seat' => "Sitz", + 'accessory' => "Zusätze", + 'accessoryFor' => "Dieser NPC ist Zusatz für Fahrzeug", + 'quotes' => "Zitate", + 'gainsDesc' => "Nach dem Töten dieses NPCs erhaltet Ihr", + 'repWith' => "Ruf mit der Fraktion", + 'stopsAt' => "Endet bei %s", + 'vehicle' => "Fahrzeug", + 'stats' => "Werte", + 'melee' => "Nahkampf", + 'ranged' => "Fernkampf", + 'armor' => "Rüstung", + 'foundIn' => "Dieser NPC befindet sich in", + 'tameable' => "Zähmbar (%s)", + 'waypoint' => "Wegpunkt", + 'wait' => "Wartezeit", + 'respawnIn' => "Wiedereinstieg in", + 'rank' => [0 => "Normal", 1 => "Elite", 4 => "Rar", 2 => "Rar Elite", 3 => "Boss"], + 'textRanges' => [null, "an das Gebiet gesendet", "an die Zone gesendet", "an die Map gesendet", "an die Welt gesendet"], + 'textTypes' => [null, "schreit", "sagt", "flüstert"], + 'modes' => array( + 1 => ["Normal", "Heroisch"], + 2 => ["10-Spieler Normal", "25-Spieler Normal", "10-Spieler Heroisch", "25-Spieler Heroisch"] + ), + 'cat' => array( + "Nicht kategorisiert", "Wildtiere", "Drachkin", "Dämonen", "Elementare", "Riesen", "Untote", "Humanoide", + "Tiere", "Mechanisch", "Nicht spezifiziert", "Totems", "Haustiere", "Gaswolken" + ) + ), + 'event' => array( + 'notFound' => "Dieses Weltereignis existiert nicht.", + 'start' => "Anfang", + 'end' => "Ende", + 'interval' => "Intervall", + 'inProgress' => "Ereignis findet gerade statt", + 'category' => ["Nicht kategorisiert", "Feiertage", "Wiederkehrend", "Spieler vs. Spieler"] + ), + 'achievement' => array( + 'notFound' => "Dieser Erfolg existiert nicht.", + 'criteria' => "Kriterien", + 'points' => "Punkte", + 'series' => "Reihe", + 'outOf' => "von", + 'criteriaType' => "Criterium Typ-Id:", + 'itemReward' => "Ihr bekommt", + 'titleReward' => 'Euch wird der Titel "%s" verliehen', + 'slain' => "getötet", + 'reqNumCrt' => "Benötigt", + 'rfAvailable' => "Verfügbar auf Realm: ", + '_transfer' => 'Dieser Erfolg wird mit %s vertauscht, wenn Ihr zur %s wechselt.', + ), + 'chrClass' => array( + 'notFound' => "Diese Klasse existiert nicht." + ), + 'race' => array( + 'notFound' => "Dieses Volk existiert nicht.", + 'racialLeader' => "Volksanführer", + 'startZone' => "Startgebiet", + ), + 'maps' => array( + 'maps' => "Karten", + 'linkToThisMap' => "Link zu dieser Karte", + 'clear' => "Zurücksetzen", + 'EasternKingdoms' => "Östliche Königreiche", + 'Kalimdor' => "Kalimdor", + 'Outland' => "Scherbenwelt", + 'Northrend' => "Nordend", + 'Instances' => "Instanzen", + 'Dungeons' => "Dungeons", + 'Raids' => "Schlachtzüge", + 'More' => "Weitere", + 'Battlegrounds' => "Schlachtfelder", + 'Miscellaneous' => "Diverse", + 'Azeroth' => "Azeroth", + 'CosmicMap' => "Kosmische Karte", + ), + 'zone' => array( + 'notFound' => "Dieses Gebiet existiert nicht.", + 'attunement' => ["Einstimmung", "Heroische Einstimmung"], + 'key' => ["Schlüssel", "Heroischer Schlüssel"], + 'location' => "Ort", + 'raidFaction' => "Schlachtzugsfraktion", + 'boss' => "Endboss", + 'reqLevels' => "Mindeststufe: [tooltip=instancereqlevel_tip]%d[/tooltip], [tooltip=lfgreqlevel_tip]%d[/tooltip]", + 'zonePartOf' => "Diese Zone ist Teil von [zone=%d].", + 'autoRez' => "Automatische Wiederbelebung", + 'city' => "Stadt", + 'territory' => "Territorium", + 'instanceType' => "Instanzart", + 'hcAvailable' => "Heroischer Modus verfügbar (%d)", + 'numPlayers' => "Anzahl an Spielern", + 'noMap' => "Für dieses Gebiet steht keine Karte zur Verfügung.", + 'instanceTypes' => ["Zone", "Durchgang", "Dungeon", "Schlachtzug", "Battleground", "Dungeon", "Arena", "Schlachtzug", "Schlachtzug"], + 'territories' => ["Allianz", "Horde", "Umkämpft", "Sicheres Gebiet", "PvP", "Welt-PvP"], + 'cat' => array( + "Östliche Königreiche", "Kalimdor", "Dungeons", "Schlachtzüge", "Unbenutzt", null, + "Schlachtfelder", null, "Scherbenwelt", "Arenen", "Nordend" + ) + ), + 'quest' => array( + 'notFound' => "Diese Quest existiert nicht.", + '_transfer' => 'Dieses Quest wird mit %s vertauscht, wenn Ihr zur %s wechselt.', + 'questLevel' => "Stufe %s", + 'requirements' => "Anforderungen", + 'reqMoney' => "Benötigtes Geld", + 'money' => "Geld", + 'additionalReq' => "Zusätzliche Anforderungen um das Quest zu erhalten", + 'reqRepWith' => 'Eure Reputation mit %s %s %s sein', + 'reqRepMin' => "muss mindestens", + 'reqRepMax' => "darf höchstens", + 'progress' => "Fortschritt", + 'provided' => "Bereitgestellt", + 'providedItem' => "Bereitgestellter Gegenstand", + 'completion' => "Abschluss", + 'description' => "Beschreibung", + 'playerSlain' => "Spieler getötet", + 'profession' => "Beruf", + 'timer' => "Zeitbegrenzung", + 'loremaster' => "Meister der Lehren", + 'suggestedPl' => "Empfohlene Spielerzahl", + 'keepsPvpFlag' => "Hält Euch im PvP", + 'daily' => 'Täglich', + 'weekly' => "Wöchentlich", + 'monthly' => "Monatlich", + 'sharable' => "Teilbar", + 'notSharable' => "Nicht teilbar", + 'repeatable' => "Wiederholbar", + 'reqQ' => "Benötigt", + 'reqQDesc' => "Um diese Quest zu erhalten, müsst ihr alle der nachfolgenden Quests abschließen", + 'reqOneQ' => "Benötigt eins von", + 'reqOneQDesc' => "Um diese Quest zu erhalten, müsst ihr eines der nachfolgenden Quests abschließen", + 'opensQ' => "Öffnet Quests", + 'opensQDesc' => "Es ist notwendig, diese Quest zu beenden, um die nachfolgenden Quests zu erhalten", + 'closesQ' => "Schließt Quests", + 'closesQDesc' => "Wenn ihr diese Quest beendet, sind die nachfolgenden Quests nicht mehr verfügbar", + 'enablesQ' => "Aktiviert", + 'enablesQDesc' => "Wenn diese Quest aktiv ist, sind die nachfolgenden Quests ebenfalls verfügbar", + 'enabledByQ' => "Aktiviert durch", + 'enabledByQDesc'=> "Ihr könnt diese Quest nur annehmen, wenn eins der nachfolgenden Quests aktiv ist", + 'gainsDesc' => "Bei Abschluss dieser Quest erhaltet Ihr", + 'theTitle' => 'den Titel "%s"', + 'mailDelivery' => "Ihr werdet diesen Brief%s%s erhalten", + 'mailBy' => ' von %s', + 'mailIn' => " nach %s", + 'unavailable' => "Diese Quest wurde als nicht genutzt markiert und kann weder erhalten noch vollendet werden.", + 'experience' => "Erfahrung", + 'expConvert' => "(oder %s, wenn auf Stufe %d vollendet)", + 'expConvert2' => "%s, wenn auf Stufe %d vollendet", + 'chooseItems' => "Auf Euch wartet eine dieser Belohnungen", + 'receiveItems' => "Ihr bekommt", + 'receiveAlso' => "Ihr bekommt außerdem", + 'spellCast' => "Der folgende Zauber wird auf Euch gewirkt", + 'spellLearn' => "Ihr erlernt", + 'bonusTalents' => "Talentpunkte", + 'spellDisplayed'=> ' (%s wird angezeigt)', + 'attachment' => "Anlage", + 'questInfo' => array( + 0 => "Normal", 1 => "Gruppe", 21 => "Leben", 41 => "PvP", 62 => "Schlachtzug", 81 => "Dungeon", 82 => "Weltereignis", + 83 => "Legendär", 84 => "Eskorte", 85 => "Heroisch", 88 => "Schlachtzug (10)", 89 => "Schlachtzug (25)" + ), + 'cat' => array( + 0 => array( "Östliche Königreiche", + 36 => "Alteracgebirge", 45 => "Arathihochland", 46 => "Brennende Steppe", 279 => "Dalarankrater", 25 => "Der Schwarzfels", + 2257 => "Die Tiefenbahn", 1 => "Dun Morogh", 10 => "Dämmerwald", 1537 => "Eisenschmiede", 41 => "Gebirgspass der Totenwinde", + 3433 => "Geisterlande", 47 => "Hinterland", 3430 => "Immersangwald", 4080 => "Insel von Quel'Danas", 38 => "Loch Modan", + 4298 => "Pestländer: Die Scharlachrote Enklave", 44 => "Rotkammgebirge", 33 => "Schlingendorntal", 51 => "Sengende Schlucht", 3487 => "Silbermond", + 130 => "Silberwald", 1519 => "Sturmwind", 11 => "Sumpfland", 8 => "Sümpfe des Elends", 85 => "Tirisfal", + 1497 => "Unterstadt", 4 => "Verwüstete Lande", 267 => "Vorgebirge des Hügellands", 12 => "Wald von Elwynn", 40 => "Westfall", + 28 => "Westliche Pestländer", 3 => "Ödland", 139 => "Östliche Pestländer" + ), + 1 => array( "Kalimdor", + 16 => "Azshara", 3524 => "Azurmythosinsel", 3525 => "Blutmythosinsel", 17 => "Brachland", 1657 => "Darnassus", + 405 => "Desolace", 3557 => "Die Exodar", 1638 => "Donnerfels", 148 => "Dunkelküste", 14 => "Durotar", + 15 => "Düstermarschen", 331 => "Eschental", 357 => "Feralas", 1216 => "Holzschlundfeste", 490 => "Krater von Un'Goro", + 493 => "Mondlichtung", 215 => "Mulgore", 1637 => "Orgrimmar", 1377 => "Silithus", 406 => "Steinkrallengebirge", + 440 => "Tanaris", 400 => "Tausend Nadeln", 141 => "Teldrassil", 361 => "Teufelswald", 618 => "Winterquell" + ), + 8 => array( "Scherbenwelt", + 3483 => "Höllenfeuerhalbinsel", 3518 => "Nagrand", 3523 => "Nethersturm", 3520 => "Schattenmondtal", 3522 => "Schergrat", + 3703 => "Shattrath", 3679 => "Skettis", 3519 => "Wälder von Terokkar", 3521 => "Zangarmarschen" + ), + 10 => array( "Nordend", + 3537 => "Boreanische Tundra", 4395 => "Dalaran", 495 => "Der heulende Fjord", 4742 => "Hrothgar's Landeplatz", 67 => "Die Sturmgipfel", + 65 => "Drachenöde", 210 => "Eiskrone", 394 => "Grizzlyhügel", 4024 => "Kaltarra", 3711 => "Sholazarbecken", + 4197 => "Tausendwintersee", 66 => "Zul'Drak" + ), + 2 => array( "Dungeons", + 4494 => "Ahn'kahet: Das Alte Königreich", 3790 => "Auchenaikrypta", 4277 => "Azjol-Nerub", 209 => "Burg Schattenfang", 206 => "Burg Utgarde", + 4100 => "Das Ausmerzen von Stratholme", 4228 => "Das Oculus", 796 => "Das Scharlachrote Kloster", 717 => "Das Verlies", 3713 => "Der Blutkessel", + 3905 => "Der Echsenkessel", 2437 => "Der Flammenschlund", 4120 => "Der Nexus", 3716 => "Der Tiefensumpf", 2366 => "Der schwarze Morast", + 3848 => "Die Arkatraz", 3847 => "Die Botanika", 3715 => "Die Dampfkammer", 4272 => "Die Hallen der Blitze", 4264 => "Die Hallen des Steins", + 718 => "Die Höhlen des Wehklagens", 3849 => "Die Mechanar", 4809 => "Die Seelenschmiede", 3717 => "Die Sklavenunterkünfte", 1581 => "Die Todesminen", + 4415 => "Die Violette Festung", 3714 => "Die zerschmetterten Hallen", 2557 => "Düsterbruch", 4196 => "Feste Drak'Tharon", 3845 => "Festung der Stürme", + 721 => "Gnomeregan", 4813 => "Grube von Saron", 4416 => "Gundrak", 4820 => "Hallen der Reflexion", 1941 => "Höhlen der Zeit", + 3562 => "Höllenfeuerbollwerk", 3535 => "Höllenfeuerzitadelle", 722 => "Hügel der Klingenhauer", 491 => "Kral der Klingenhauer", 3792 => "Managruft", + 2100 => "Maraudon", 4723 => "Prüfung des Champions", 3789 => "Schattenlabyrinth", 2057 => "Scholomance", 1583 => "Schwarzfelsspitze", + 1584 => "Schwarzfelstiefen", 3791 => "Sethekkhallen", 2017 => "Stratholme", 4131 => "Terrasse der Magister", 719 => "Tiefschwarze Grotte", + 1196 => "Turm Utgarde", 1337 => "Uldaman", 1477 => "Versunkener Tempel", 2367 => "Vorgebirge des Alten Hügellands", 1176 => "Zul'Farrak" + ), + 3 => array( "Schlachtzüge", + 4603 => "Archavon's Kammer", 3842 => "Das Auge", 4500 => "Das Auge der Ewigkeit", 4493 => "Das Obsidiansanktum", 3959 => "Der Schwarze Tempel", + 4812 => "Eiskronenzitadelle", 2717 => "Geschmolzener Kern", 3923 => "Gruul's Unterschlupf", 3607 => "Höhle des Schlangenschreins", 3606 => "Hyjalgipfel", + 3457 => "Karazhan", 3836 => "Magtheridons Kammer", 3456 => "Naxxramas", 2159 => "Onyxias Hort", 2677 => "Pechschwingenhort", + 4722 => "Prüfung des Kreuzfahrers", 3429 => "Ruinen von Ahn'Qiraj", 4075 => "Sonnenbrunnenplateau", 3428 => "Tempel von Ahn'Qiraj", 4273 => "Ulduar", + 3805 => "Zul'Aman", 1977 => "Zul'Gurub" + ), + 4 => array( "Klassen", + -263 => "Druide", -61 => "Hexenmeister", -261 => "Jäger", -81 => "Krieger", -161 => "Magier", + -141 => "Paladin", -262 => "Priester", -82 => "Schamane", -162 => "Schurke", -372 => "Todesritter" + ), + 5 => array( "Berufe", + -181 => "Alchemie", -101 => "Angeln", -324 => "Erste Hilfe", -201 => "Ingenieurskunst", -371 => "Inschriftenkunde", + -373 => "Juwelenschleifen", -304 => "Kochkunst", -24 => "Kräuterkunde", -182 => "Lederverarbeitung", -121 => "Schmiedekunst", + -264 => "Schneiderei" + ), + 6 => array( "Schlachtfelder", + 2597 => "Alteractal", 3358 => "Arathibecken", 3820 => "Auge des Sturms", 4710 => "Insel der Eroberung", 3277 => "Kriegshymnenschlucht", + -25 => "Schlachtfelder", 4384 => "Strand der Uralten" + ), + 9 => array( "Weltereignisse", + -370 => "Braufest", -1002 => "Kinderwoche", -364 => "Dunkelmond-Jahrmarkt", -41 => "Tag der Toten", -1003 => "Schlotternächte", + -1005 => "Erntedankfest", -376 => "Liebe liegt in der Luft", -366 => "Mondfest", -369 => "Sonnenwende", -1006 => "Neujahr", + -375 => "Die Pilgerfreuden", -374 => "Nobelgarten", -1001 => "Winterhauch" + ), + 7 => array( "Verschiedenes", + -365 => "Krieg von Ahn'Qiraj", -1010 => "Dungeonfinder", -1 => "Episch", -344 => "Legendär", -367 => "Ruf", + -368 => "Invasion der Geißel", -241 => "Turnier" + ), + -2 => "Nicht kategorisiert" + ) + ), + 'title' => array( + 'notFound' => "Dieser Titel existiert nicht.", + '_transfer' => 'Dieser Titel wird mit %s vertauscht, wenn Ihr zur %s wechselt.', + 'cat' => array( + "Allgemein", "Spieler gegen Spieler", "Ruf", "Dungeon & Schlachtzug", "Quests", "Berufe", "Weltereignisse" + ) + ), + 'skill' => array( + 'notFound' => "Diese Fertigkeit existiert nicht.", + 'cat' => array( + -6 => "Haustiere", -5 => "Reittiere", -4 => "Völkerfertigkeiten", 5 => "Attribute", 6 => "Waffenfertigkeiten", 7 => "Klassenfertigkeiten", 8 => "Rüstungssachverstand", + 9 => "Nebenberufe", 10 => "Sprachen", 11 => "Berufe" + ) + ), + 'currency' => array( + 'notFound' => "Diese Währung existiert nicht.", + 'cap' => "Obergrenze", + 'cat' => array( + 1 => "Verschiedenes", 2 => "Spieler gegen Spieler", 4 => "Classic", 21 => "Wrath of the Lich King", 22 => "Dungeon und Schlachtzug", 23 => "Burning Crusade", 41 => "Test", 3 => "Unbenutzt" + ) + ), + 'pet' => array( + 'notFound' => "Diese Tierart existiert nicht.", + 'exotic' => "Exotisch", + 'cat' => ["Wildheit", "Hartnäckigkeit", "Gerissenheit"] + ), + 'faction' => array( + 'notFound' => "Diese Fraktion existiert nicht.", + 'spillover' => "Reputationsüberlauf", + 'spilloverDesc' => "Für diese Fraktion erhaltener Ruf wird zusätzlich mit den unten aufgeführten Fraktionen anteilig verrechnet.", + 'maxStanding' => "Max. Ruf", + 'quartermaster' => "Rüstmeister", + 'customRewRate' => "Abweichende Belohnungsraten", + '_transfer' => 'Die Reputation mit dieser Fraktion wird mit dem für %s vertauscht, wenn Ihr zur %s wechselt.', + 'cat' => array( + 1118 => ["Classic", 469 => "Allianz", 169 => "Dampfdruckkartell", 67 => "Horde", 891 => "Streitkräfte der Allianz", 892 => "Streitkräfte der Horde"], + 980 => ["The Burning Crusade", 936 => "Shattrath"], + 1097 => ["Wrath of the Lich King", 1052 => "Expedition der Horde", 1117 => "Sholazarbecken", 1037 => "Vorposten der Allianz"], + 0 => "Sonstige" + ) + ), + 'itemset' => array( + 'notFound' => "Dieses Ausrüstungsset existiert nicht.", + '_desc' => "%s ist das %s. Es enthält %s Teile.", + '_descTagless' => "%s ist ein Ausrüstungsset, das %s Teile enthält.", + '_setBonuses' => "Setboni", + '_conveyBonus' => "Das Tragen mehrerer Gegenstände aus diesem Set gewährt Eurem Charakter Boni.", + '_pieces' => "Teile", + '_unavailable' => "Dieses Ausrüstungsset ist nicht für Spieler verfügbar.", + '_tag' => "Tag", + 'summary' => "Zusammenfassung", + 'notes' => array( + null, "Dungeon-Set 1", "Dungeon-Set 2", "Tier 1 Raid-Set", + "Tier 2 Raid-Set", "Tier 3 Raid-Set", "Level 60 PvP-Set (Rar)", "Level 60 PvP-Set (Rar, alt)", + "Level 60 PvP-Set (Episch)", "Set der Ruinen von Ahn'Qiraj", "Set des Tempels von Ahn'Qiraj", "Set von Zul'Gurub", + "Tier 4 Raid-Set", "Tier 5 Raid-Set", "Dungeon-Set 3", "Set des Arathibeckens", + "Level 70 PvP-Set (Rar)", "Arena-Set Saison 1", "Tier 6 Raid-Set", "Arena-Set Saison 2", + "Arena-Set Saison 3", "Level 70 PvP-Set 2 (Rar)", "Arena-Set Saison 4", "Tier 7 Raid-Set", + "Arena-Set Saison 5", "Tier 8 Raid-Set", "Arena-Set Saison 6", "Tier 9 Raid-Set", + "Arena-Set Saison 7", "Tier 10 Raid-Set", "Arena-Set Saison 8" + ), + 'types' => array( + null, "Stoff", "Leder", "Schwere Rüstung", "Platte", "Dolch", "Ring", + "Faustwaffe", "Einhandaxt", "Einhandstreitkolben", "Einhandschwert", "Schmuck", "Amulett" + ) + ), + 'spell' => array( + 'notFound' => "Dieser Zauber existiert nicht.", + '_spellDetails' => "Zauberdetails", + '_cost' => "Kosten", + '_range' => "Reichweite", + '_castTime' => "Zauberzeit", + '_cooldown' => "Abklingzeit", + '_distUnit' => "Meter", + '_forms' => "Gestalten", + '_aura' => "Aura", + '_effect' => "Effekt", + '_none' => "Nichts", + '_gcd' => "GCD", + '_globCD' => "Globale Abklingzeit", + '_gcdCategory' => "GCD-Kategorie", + '_value' => "Wert", + '_radius' => "Radius", + '_interval' => "Interval", + '_inSlot' => "im Platz", + '_collapseAll' => "Alle einklappen", + '_expandAll' => "Alle ausklappen", + '_transfer' => 'Dieser Zauber wird mit %s vertauscht, wenn Ihr zur %s wechselt.', + 'discovered' => "Durch Geistesblitz erlernt", + 'ppm' => "%s Auslösungen pro Minute", + 'procChance' => "Procchance", + 'starter' => "Basiszauber", + 'trainingCost' => "Trainingskosten", + 'remaining' => "Noch %s", + 'untilCanceled' => "bis Abbruch", + 'castIn' => "Wirken in %s Sek.", + 'instantPhys' => "Sofort", + 'instantMagic' => "Spontanzauber", + 'channeled' => "Kanalisiert", + 'range' => "%s Meter Reichweite", + 'meleeRange' => "Nahkampfreichweite", + 'unlimRange' => "Unbegrenzte Reichweite", + 'reagents' => "Reagenzien", + 'tools' => "Extras", + 'home' => "<Gasthaus>", + 'pctCostOf' => "vom Grund%s", + 'costPerSec' => ", plus %s pro Sekunde", + 'costPerLevel' => ", plus %s pro Stufe", + 'stackGroup' => "Stack Gruppierung", + 'linkedWith' => "Verknüpft mit", + '_scaling' => "Skalierung", + 'scaling' => array( + 'directSP' => "+%.2f%% der Zaubermacht zum direkten Effekt", 'directAP' => "+%.2f%% der Angriffskraft zum direkten Effekt", + 'dotSP' => "+%.2f%% der Zaubermacht pro Tick", 'dotAP' => "+%.2f%% der Angriffskraft pro Tick" + ), + 'powerRunes' => ["Frost", "Unheilig", "Blut", "Tod"], + 'powerTypes' => array( + // conventional + -2 => "Gesundheit", 0 => "Mana", 1 => "Wut", 2 => "Fokus", 3 => "Energie", 4 => "Zufriedenheit", + 5 => "Runen", 6 => "Runenmacht", + // powerDisplay + -1 => "Munition", -41 => "Pyrit", -61 => "Dampfdruck", -101 => "Hitze", -121 => "Schlamm", -141 => "Blutmacht", + -142 => "Wrath" + ), + 'relItems' => array( + 'base' => "%s im Zusammenhang mit %s anzeigen", + 'link' => " oder ", + 'recipes' => 'Rezeptgegenstände', + 'crafted' => 'Hergestellte Gegenstände' + ), + 'cat' => array( + 7 => "Klassenfertigkeiten", + -13 => "Glyphen", + -11 => ["Sachverstand", 8 => "Rüstung", 6 => "Waffen", 10 => "Sprachen"], + -4 => "Völkerfertigkeiten", + -2 => "Talente", + -6 => "Haustiere", + -5 => "Reittiere", + -3 => array( + "Begleiterfertigkeiten", 782 => "Ghul", 270 => "Allgemein", 213 => "Aasvogel", 210 => "Bär", 763 => "Drachenfalke", 211 => "Eber", + 767 => "Felshetzer", 653 => "Fledermaus", 788 => "Geisterbestie", 215 => "Gorilla", 654 => "Hyäne", 209 => "Katze", 787 => "Kernhund", + 214 => "Krebs", 212 => "Krokilisk", 775 => "Motte", 764 => "Netherrochen", 217 => "Raptor", 655 => "Raubvogel", 786 => "Rhinozeros", + 251 => "Schildkröte", 780 => "Schimäre", 768 => "Schlange", 783 => "Silithid", 236 => "Skorpid", 766 => "Sphärenjäger", 203 => "Spinne", + 765 => "Sporensegler", 781 => "Teufelssaurier", 218 => "Weitschreiter", 785 => "Wespe", 656 => "Windnatter", 208 => "Wolf", 784 => "Wurm", + 204 => "Leerwandler", 205 => "Sukkubus", 189 => "Teufelsjäger", 761 => "Teufelswache", 188 => "Wichtel", + ), + -7 => ["Begleitertalente", 410 => "Gerissenheit", 411 => "Wildheit", 409 => "Hartnäckigkeit"], + 11 => array( + "Berufe", + 171 => "Alchemie", + 164 => ["Schmiedekunst", 9788 => "Rüstungsschmied", 9787 => "Waffenschmied", 17041 => "Axtschmiedemeister", 17040 => "Hammerschmiedemeister", 17039 => "Schwertschmiedemeister"], + 333 => "Verzauberkunst", + 202 => ["Ingenieurskunst", 20219 => "Gnomeningenieurskunst", 20222 => "Gobliningenieurskunst"], + 182 => "Kräuterkunde", + 773 => "Inschriftenkunde", + 755 => "Juwelenschleifen", + 165 => ["Lederverarbeitung", 10656 => "Drachenschuppenlederverarbeitung", 10658 => "Elementarlederverarbeitung", 10660 => "Stammeslederverarbeitung"], + 186 => "Bergbau", + 393 => "Kürschnerei", + 197 => ["Schneiderei", 26798 => "Mondstoffschneiderei", 26801 => "Schattenstoffschneiderei", 26797 => "Zauberfeuerschneiderei"], + ), + 9 => ["Nebenberufe", 185 => "Kochkunst", 129 => "Erste Hilfe", 356 => "Angeln", 762 => "Reiten"], + -8 => "NPC-Fähigkeiten", + -9 => "GM-Fähigkeiten", + 0 => "Nicht kategorisiert" + ), + 'armorSubClass' => array( + "Sonstiges", "Stoffrüstung", "Lederrüstung", "Schwere Rüstung", "Plattenrüstung", + null, "Schilde", "Buchbände", "Götzen", "Totems", + "Siegel" + ), + 'weaponSubClass' => array( + 15 => "Dolche", 0 => "Einhandäxte", 7 => "Einhandschwerter", 4 => "Einhandstreitkolben", 13 => "Faustwaffen", + 6 => "Stangenwaffen", 10 => "Stäbe", 1 => "Zweihandäxte", 8 => "Zweihandschwerter", 5 => "Zweihandstreitkolben", + 18 => "Armbrüste", 2 => "Bögen", 3 => "Schusswaffen", 16 => "Wurfwaffen", 19 => "Zauberstäbe", + 20 => "Angelruten", 14 => "Diverse" + ), + 'subClassMasks' => array( + 0x02A5F3 => "Nahkampfwaffe", 0x0060 => "Schild", 0x04000C => "Distanzwaffe", 0xA091 => "Einhandnahkampfwaffe" + ), + 'traitShort' => array( + 'atkpwr' => "Angr", 'rgdatkpwr' => "DAngr", 'splpwr' => "ZMacht", 'arcsplpwr' => "ArkM", 'firsplpwr' => "FeuM", + 'frosplpwr' => "FroM", 'holsplpwr' => "HeiM", 'natsplpwr' => "NatM", 'shasplpwr' => "SchM", 'splheal' => "Heil" + ), + 'spellModOp' => array( + "Schaden", "Dauer", "Bedrohung", "Effekt 1", "Aufladungen", + "Reichweite", "Radius", "kritische Trefferchance", "Alle Effekte", "Zauberzeitverlust", + "Zauberzeit", "Abklingzeit", "Effekt 2", "Ignoriere Rüstung", "Kosten", + "Kritischer Bonusschaden", "Chance auf Fehlschlag", "Sprung-Ziele", "Chance auf Auslösung", "Intervall", + "Multiplikator (Schaden)", "Globale Abklingzeit", "Schaden über Zeit", "Effekt 3", "Multiplikator (Bonus)", + null, "Auslösungen pro Minute", "Multiplikator (Betrag)", "Widerstand gegen Bannung", "kritischer Bonusschaden2", + "Kostenrückerstattung bei Fehlschlag" + ), + 'combatRating' => array( + "Waffenfertigkeit", "Verteidigungsfertigkeit", "Ausweichen", "Parrieren", "Blocken", + "Nahkampftrefferchance", "Fernkampftrefferchance", "Zaubertrefferchance", "kritische Nahkampftrefferchance", "kritische Fernkampftrefferchance", + "kritische Zaubertrefferchance", "erhaltene Nahkampftreffer", "erhaltene Fernkampftreffer", "erhaltene Zaubertreffer", "erhaltene kritische Nahkampftreffer", + "erhaltene kritische Fernkampftreffer", "erhaltene kritische Zaubertreffer", "Nahkampftempo", "Fernkampftempo", "Zaubertempo", + "Waffenfertigkeit Haupthand", "Waffenfertigkeit Nebenhand", "Waffenfertigkeit Fernkampf", "Waffenkunde", "Rüstungsdurchschlag" + ), + 'lockType' => array( + null, "Schlossknacken", "Kräuterkunde", "Bergbau", "Falle entschärfen", + "Öffnen", "Schatz (DND)", "Verkalkte Elfenedelsteine (DND)", "Schließen", "Falle scharf machen", + "Schnell öffnen", "Schnell schließen", "Offenes Tüfteln", "Offenes Knien", "Offenes Angreifen", + "Gahz'ridian (DND)", "Schlagen", "PvP öffnen", "PvP schließen", "Angeln", + "Inschriftenkunde", "Vom Fahrzeug öffnen" + ), + 'stealthType' => ["Allgemein", "Falle"], + 'invisibilityType' => ["Allgemein", 3 => "Falle", 6 => "Trunkenheit"] + ), + 'item' => array( + 'notFound' => "Dieser Gegenstand existiert nicht .", + 'armor' => "%s Rüstung", + 'block' => "%s Blocken", + 'charges' => "Aufladungen", + 'locked' => "Verschlossen", + 'ratingString' => "%s @ L%s", + 'heroic' => "Heroisch", + 'unique' => "Einzigartig", + 'uniqueEquipped'=> "Einzigartig anlegbar", + 'startQuest' => "Dieser Gegenstand startet eine Quest", + 'bagSlotString' => "%d Platz %s", + 'dps' => "Schaden pro Sekunde", + 'dps2' => "Schaden pro Sekunde", + 'addsDps' => "Adds", + 'fap' => "Angriffskraft in Tiergestalt", + 'durability' => "Haltbarkeit", + 'realTime' => "Realzeit", + 'conjured' => "Herbeigezauberter Gegenstand", + 'damagePhys' => "%s Schaden", + 'damageMagic' => "%s %sschaden", + 'speed' => "Tempo", + 'sellPrice' => "Verkaufspreis", + 'itemLevel' => "Gegenstandsstufe", + 'randEnchant' => "<Zufällige Verzauberung>", + 'readClick' => "<Zum Lesen rechtsklicken>", + 'openClick' => "<Zum Öffnen rechtsklicken>", + 'set' => "Set", + 'partyLoot' => "Gruppenloot", + 'smartLoot' => "Intelligente Beuteverteilung", + 'indestructible'=> "Kann nicht zerstört werden", + 'deprecated' => "Nicht benutzt", + 'useInShape' => "Benutzbar in Gestaltwandlung", + 'useInArena' => "Benutzbar in Arenen", + 'refundable' => "Rückzahlbar", + 'noNeedRoll' => "Kann nicht für Bedarf werfen", + 'atKeyring' => "Passt in den Schlüsselbund", + 'worth' => "Wert", + 'consumable' => "Verbrauchbar", + 'nonConsumable' => "Nicht verbrauchbar", + 'accountWide' => "Accountweit", + 'millable' => "Mahlbar", + 'noEquipCD' => "Keine Anlegabklingzeit", + 'prospectable' => "Sondierbar", + 'disenchantable'=> "Kann entzaubert werden", + 'cantDisenchant'=> "Kann nicht entzaubert werden", + 'repairCost' => "Reparaturkosten", + 'tool' => "Werkzeug", + 'cost' => "Preis", + 'content' => "Inhalt", + '_transfer' => 'Dieser Gegenstand wird mit %s vertauscht, wenn Ihr zur %s wechselt.', + '_unavailable' => "Dieser Gegenstand ist nicht für Spieler verfügbar.", + '_rndEnchants' => "Zufällige Verzauberungen", + '_chance' => "(Chance von %s%%)", + 'slot' => "Platz", + '_quality' => "Qualität", + 'usableBy' => "Benutzbar von", + 'buyout' => "Sofortkaufpreis", + 'each' => "Stück", + 'tabOther' => "Anderes", + 'gems' => "Edelsteine", + 'socketBonus' => "Sockelbonus", + 'socket' => array( + "Metasockel", "Roter Sockel", "Gelber Sockel", "Blauer Sockel", -1 => "Prismatischer Sockel" + ), + 'gemColors' => array( // *_GEM + "Meta", "Rot", "Gelb", "Blau" + ), + 'gemConditions' => array( // ENCHANT_CONDITION_* in GlobalStrings.lua; 2 not in use (use as PH) + 2 => ["weniger als %d Edelstein der Kategorie %s", "weniger als %d Edelsteine der Kategorie %s"], + 3 => "mehr Edelsteine der Kategorie %s als Edelsteine der Kategorie %s", + 5 => ["mindestens %d Edelstein der Kategorie %s", "mindestens %d Edelsteine der Kategorie %s"] + ), + 'reqRating' => array( // ITEM_REQ_ARENA_RATING* + "Benötigt eine persönliche Arenawertung und Teamwertung von %d.", + "Benötigt eine persönliche und eine Teamwertung von %d
in 3v3- oder 5v5-Turnieren", + "Benötigt eine persönliche und eine Teamwertung von %d
in 5v5-Turnieren" + ), + 'quality' => array( + "Schlecht", "Verbreitet", "Selten", "Rar", + "Episch", "Legendär", "Artefakt", "Erbstücke", + ), + 'trigger' => array( + "Benutzen: ", "Anlegen: ", "Chance bei Treffer: ", "", "", + "", "" + ), + 'bonding' => array( + "Accountgebunden", "Wird beim Aufheben gebunden", "Wird beim Anlegen gebunden", + "Wird bei Benutzung gebunden", "Questgegenstand", "Questgegenstand" + ), + 'bagFamily' => array( + "Tasche", "Köcher", "Munitionsbeutel", "Seelentasche", "Lederertasche", + "Schreibertasche", "Kräutertasche", "Verzauberertasche", "Ingenieurstasche", null, /*Schlüssel*/ + "Edelsteintasche", "Bergbautasche" + ), + 'inventoryType' => array( + null, "Kopf", "Hals", "Schulter", "Hemd", + "Brust", "Taille", "Beine", "Füße", "Handgelenke", + "Hände", "Finger", "Schmuck", "Einhändig", "Schildhand", /*Schild*/ + "Distanz", "Rücken", "Zweihändig", "Tasche", "Wappenrock", + null, /*Robe*/ "Waffenhand", "Schildhand", "In der Schildhand geführt", "Projektil", + "Wurfwaffe", null, /*Ranged2*/ "Köcher", "Relikt" + ), + 'armorSubClass' => array( + "Sonstiges", "Stoff", "Leder", "Schwere Rüstung", "Platte", + null, "Schild", "Buchband", "Götze", "Totem", + "Sigel" + ), + 'weaponSubClass' => array( + "Axt", "Axt", "Bogen", "Schusswaffe", "Streitkolben", + "Streitkolben", "Stangenwaffe", "Schwert", "Schwert", null, + "Stab", null, null, "Faustwaffe", "Diverse", + "Dolche", "Wurfwaffe", null, "Armbrust", "Zauberstab", + "Angelrute" + ), + 'projectileSubClass' => array( + null, null, "Pfeil", "Kugel", null + ), + 'elixirType' => [null, "Kampf", "Wächter"], + 'cat' => array( + 2 => "Waffen", // self::$spell['weaponSubClass'] + 4 => array("Rüstung", array( + 1 => "Stoffrüstung", 2 => "Lederrüstung", 3 => "Schwere Rüstung", 4 => "Plattenrüstung", 6 => "Schilde", 7 => "Buchbände", + 8 => "Götzen", 9 => "Totems", 10 => "Siegel", -6 => "Umhänge", -5 => "Nebenhandgegenstände", -8 => "Hemden", + -7 => "Wappenröcke", -3 => "Amulette", -2 => "Ringe", -4 => "Schmuckstücke", 0 => "Verschiedenes (Rüstung)", + )), + 1 => array("Behälter", array( + 0 => "Taschen", 3 => "Verzauberertaschen", 4 => "Ingenieurstaschen", 5 => "Edelsteintaschen", 2 => "Kräutertaschen", 8 => "Schreibertaschen", + 7 => "Lederertaschen", 6 => "Bergbautaschen", 1 => "Seelentaschen" + )), + 0 => array("Verbrauchbar", array( + -3 => "Gegenstandsverzauberungen (Temporäre)", 6 => "Gegenstandsverzauberungen (Dauerhafte)", 2 => ["Elixire", [1 => "Kampfelixire", 2 => "Wächterelixire"]], + 1 => "Tränke", 4 => "Schriftrollen", 7 => "Verbände", 0 => "Verbrauchbar", 3 => "Fläschchen", 5 => "Essen & Trinken", + 8 => "Andere (Verbrauchbar)" + )), + 16 => array("Glyphen", array( + 1 => "Kriegerglyphen", 2 => "Paladinglyphen", 3 => "Jägerglyphen", 4 => "Schurkenglyphen", 5 => "Priesterglyphen", 6 => "Todesritterglyphen", + 7 => "Schamanenglyphen", 8 => "Magierglyphen", 9 => "Hexenmeisterglyphen", 11 => "Druidenglyphen" + )), + 7 => array("Handwerkswaren", array( + 14 => "Rüstungsverzauberungen", 5 => "Stoff", 3 => "Geräte", 10 => "Elementar", 12 => "Verzauberkunst", 2 => "Sprengstoff", + 9 => "Kräuter", 4 => "Juwelenschleifen", 6 => "Leder", 13 => "Materialien", 8 => "Fleisch", 7 => "Metall & Stein", + 1 => "Teile", 15 => "Waffenverzauberungen", 11 => "Andere (Handwerkswaren)" + )), + 6 => ["Projektile", [ 2 => "Pfeile", 3 => "Kugeln" ]], + 11 => ["Köcher", [ 2 => "Köcher", 3 => "Munitionsbeutel" ]], + 9 => array("Rezepte", array( + 0 => "Bücher", 6 => "Alchemierezepte", 4 => "Schmiedekunstpläne", 5 => "Kochrezepte", 8 => "Verzauberkunstformeln", 3 => "Ingenieurschemata", + 7 => "Erste Hilfe-Bücher", 9 => "Angelbücher", 11 => "Inschriftenkundetechniken",10 => "Juwelenschleifen-Vorlagen",1 => "Lederverarbeitungsmuster",12 => "Bergbauleitfäden", + 2 => "Schneidereimuster" + )), + 3 => array("Edelsteine", array( + 6 => "Meta-Edelsteine", 0 => "Rote Edelsteine", 1 => "Blaue Edelsteine", 2 => "Gelbe Edelsteine", 3 => "Violette Edelsteine", 4 => "Grüne Edelsteine", + 5 => "Orange Edelsteine", 8 => "Prismatische Edelsteine", 7 => "Einfache Edelsteine" + )), + 15 => array("Verschiedenes", array( + -2 => "Rüstungsmarken", 3 => "Feiertag", 0 => "Plunder", 1 => "Reagenzien", 5 => "Reittiere", -7 => "Flugtiere", + 2 => "Haustiere", 4 => "Andere (Verschiedenes)" + )), + 10 => "Währung", + 12 => "Quest", + 13 => "Schlüssel", + ), + 'statType' => array( + "Erhöht Euer Mana um %d.", + "Erhöht Eure Gesundheit um %d.", + null, + "Beweglichkeit", + "Stärke", + "Intelligenz", + "Willenskraft", + "Ausdauer", + null, null, null, null, + "Erhöht die Verteidigungswertung um %d.", + "Erhöht Eure Ausweichwertung um %d.", + "Erhöht Eure Parierwertung um %d.", + "Erhöht Eure Blockwertung um %d.", + "Erhöht Nahkampftrefferwertung um %d.", + "Erhöht Fernkampftrefferwertung um %d.", + "Erhöht Zaubertrefferwertung um %d.", + "Erhöht kritische Nahkampftrefferwertung um %d.", + "Erhöht kritische Fernkampftrefferwertung um %d.", + "Erhöht kritische Zaubertrefferwertung um %d.", + "Erhöht Vermeidungswertung für Nahkampftreffer um +3.", + "Erhöht Vermeidungswertung für Distanztreffer um %d.", + "Erhöht Vermeidungswertung für Zaubertreffer um %d.", + "Erhöht Vermeidungswertung für kritische Nahkampftreffer um %d.", + "Erhöht Vermeidungswertung für kritische Distanztreffer um %d.", + "Erhöht Vermeidungswertung für kritische Zaubertreffer um %d.", + "Erhöht Nahkampftempowertung um %d.", + "Erhöht Fernkampftempowertung um %d.", + "Erhöht Zaubertempowertung um %d.", + "Erhöht Eure Trefferwertung um %d.", + "Erhöht Eure kritische Trefferwertung um %d.", + "Erhöht Vermeidungswertung um %d.", + "Erhöht Vermeidungswertung für kritische Treffer um %d.", + "Erhöht Eure Abhärtungswertung um %d.", + "Erhöht Eure Tempowertung um %d.", + "Erhöht Waffenkundewertung um %d.", + "Erhöht Angriffskraft um %d.", + "Erhöht Distanzangriffskraft um %d.", + "Erhöht die Angriffskraft in Katzen-, Bären-, Terrorbären- und Mondkingestalt um %d.", + "Erhöht den von Zaubern und Effekten verursachten Schaden um bis zu %d.", + "Erhöht die von Zaubern und Effekten verursachte Heilung um bis zu %d.", + "Stellt alle 5 Sek. %d Mana wieder her.", + "Erhöht Euren Rüstungsdurchschlagwert um %d.", + "Erhöht die Zaubermacht um %d.", + "Stellt alle 5 Sek. %d Gesundheit wieder her.", + "Erhöht den Zauberdurchschlag um %d.", + "Erhöht Blockwert um %d.", + "Unbekannter Bonus #%d (%d)", + ) + ) +); + +?> diff --git a/localization/locale_enus.php b/localization/locale_enus.php index f2b7f8bf..d95880c3 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -1,1077 +1,1077 @@ - array( - 'sg' => ["year", "month", "week", "day", "hour", "minute", "second", "millisecond"], - 'pl' => ["years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds"], - 'ab' => ["yr", "mo", "wk", "day", "hr", "min", "sec", "ms"] - ), - 'main' => array( - 'name' => "name", - 'link' => "Link", - 'signIn' => "Log in / Register", - 'jsError' => "Please make sure you have javascript enabled.", - 'language' => "Language", - 'feedback' => "Feedback", - 'numSQL' => "Number of MySQL queries", - 'timeSQL' => "Time of MySQL queries", - 'noJScript' => 'This site makes extensive use of JavaScript.
Please enable JavaScript in your browser.', - 'userProfiles' => "My Profiles", - 'pageNotFound' => "This %s doesn't exist.", - 'gender' => "Gender", - 'sex' => [null, "Male", "Female"], - 'players' => "Players", - 'quickFacts' => "Quick Facts", - 'screenshots' => "Screenshots", - 'videos' => "Videos", - 'side' => "Side", - 'related' => "Related", - 'contribute' => "Contribute", - // 'replyingTo' => "The answer to a comment from", - 'submit' => "Submit", - 'cancel' => "Cancel", - 'rewards' => "Rewards", - 'gains' => "Gains", - 'login' => "Login", - 'forum' => "Forum", - 'n_a' => "n/a", - 'siteRep' => "Reputation", - 'aboutUs' => "About us & contact", - 'and' => " and ", - 'or' => " or ", - 'back' => "Back", - 'reputationTip' => "Reputation points", - 'byUserTimeAgo' => 'By %1$s %s ago', - - // filter - 'extSearch' => "Extended search", - 'addFilter' => "Add another Filter", - 'match' => "Match", - 'allFilter' => "All filters", - 'oneFilter' => "At least one", - 'applyFilter' => "Apply filter", - 'resetForm' => "Reset Form", - 'refineSearch' => 'Tip: Refine your search by browsing a subcategory.', - 'clear' => "clear", - 'exactMatch' => "Exact match", - '_reqLevel' => "Required level", - - // infobox - 'unavailable' => "Not available to players", // alternative wording found: "No longer available to players" ... aw screw it <_< - 'disabled' => "Disabled", - 'disabledHint' => "Cannot be attained or completed", - 'serverside' => "Serverside", - 'serversideHint'=> "These informations are not in the Client and have been provided by sniffing and/or guessing.", - - // red buttons - 'links' => "Links", - 'compare' => "Compare", - 'view3D' => "View in 3D", - 'findUpgrades' => "Find upgrades...", - - // misc Tools - 'errPageTitle' => "Page not found", - 'nfPageTitle' => "Error", - 'subscribe' => "Subscribe", - 'mostComments' => ["Yesterday", "Past %d Days"], - 'utilities' => array( - "Latest Additions", "Latest Articles", "Latest Comments", "Latest Screenshots", null, - "Unrated Comments", 11 => "Latest Videos", 12 => "Most Comments", 13 => "Missing Screenshots" - ), - - // article & infobox - 'englishOnly' => "This page is only available in English.", - - // calculators - 'preset' => "Preset", - 'addWeight' => "Add another weight", - 'createWS' => "Create a weight scale", - 'jcGemsOnly' => "Include JC-only gems", - 'cappedHint' => 'Tip: Remove 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", - 'chooseClass' => "Choose a class", - 'chooseFamily' => "Choose a pet family", - - // profiler - 'realm' => "Realm", - 'region' => "Region", - 'viewCharacter' => "View Character", - '_cpHead' => "Character Profiler", - '_cpHint' => "The Character Profiler lets you edit your character, find gear upgrades, check your gearscore and more!", - '_cpHelp' => "To get started, just follow the steps below. If you'd like more information, check out our extensive help page.", - '_cpFooter' => "If you want a more refined search try out our advanced search options. You can also create a new custom profile.", - - // help - 'help' => "Help", - 'helpTopics' => array( - "Commenting and You", "Model Viewer", "Screenshots: Tips & Tricks", "Stat Weighting", - "Talent Calculator", "Item Comparison", "Profiler", "Markup Guide" - ), - - // search - 'search' => "Search", - 'searchButton' => "Search", - 'foundResult' => "Search Results for", - 'noResult' => "No Results for", - 'tryAgain' => "Please try some different keywords or check your spelling.", - 'ignoredTerms' => "The following words were ignored in your search: %s", - - // formating - 'colon' => ': ', - 'dateFmtShort' => "Y/m/d", - 'dateFmtLong' => "Y/m/d \a\\t H:i", - - // error - 'intError' => "An internal error has occurred.", - 'intError2' => "An internal error has occurred. (%s)", - 'genericError' => "An error has occurred; refresh the page and try again. If the error persists email feedback", # LANG.genericerror - 'bannedRating' => "You have been banned from rating comments.", # LANG.tooltip_banned_rating - 'tooManyVotes' => "You have reached the daily voting cap. Come back tomorrow!", # LANG.tooltip_too_many_votes - ), - 'screenshot' => array( - 'submission' => "Screenshot Submission", - 'selectAll' => "Select all", - 'cropHint' => "You may crop your screenshot and enter a caption.", - 'displayOn' => "Displayed on:[br]%s - [%s=%d]", - 'caption' => "Caption", - 'charLimit' => "Optional, up to 200 characters", - 'thanks' => array( - 'contrib' => "Thanks a lot for your contribution!", - 'goBack' => 'Click here to go back to the page you came from.', - 'note' => "Note: Your screenshot will need to be approved before appearing on the site. This can take up to 72 hours." - ), - 'error' => array( - 'unkFormat' => "Unknown image format.", - 'tooSmall' => "Your screenshot is way too small. (< ".CFG_SCREENSHOT_MIN_SIZE."x".CFG_SCREENSHOT_MIN_SIZE.").", - 'selectSS' => "Please select the screenshot to upload.", - 'notAllowed' => "You are not allowed to upload screenshots!", - ) - ), - 'game' => array( - 'achievement' => "achievement", - 'achievements' => "Achievements", - 'class' => "class", - 'classes' => "Classes", - 'currency' => "currency", - 'currencies' => "Currencies", - 'difficulty' => "Difficulty", - 'dispelType' => "Dispel type", - 'duration' => "Duration", - 'emote' => "emote", - 'emotes' => "Emotes", - 'enchantment' => "enchantment", - 'enchantments' => "Enchantments", - 'object' => "object", - 'objects' => "Objects", - 'glyphType' => "Glyph type", - 'race' => "race", - 'races' => "Races", - 'title' => "title", - 'titles' => "Titles", - 'eventShort' => "Event", - 'event' => "World Event", - 'events' => "World Events", - 'faction' => "faction", - 'factions' => "Factions", - 'cooldown' => "%s cooldown", - 'item' => "item", - 'items' => "Items", - 'itemset' => "item Set", - 'itemsets' => "Item Sets", - 'mechanic' => "Mechanic", - 'mechAbbr' => "Mech.", - 'meetingStone' => "Meeting Stone", - 'npc' => "NPC", - 'npcs' => "NPCs", - 'pet' => "Pet", - 'pets' => "Hunter Pets", - 'profile' => "profile", - 'profiles' => "Profiles", - 'quest' => "quest", - 'quests' => "Quests", - 'requires' => "Requires %s", - 'requires2' => "Requires", - 'reqLevel' => "Requires Level %s", - 'reqLevelHlm' => "Requires Level %s", - 'reqSkillLevel' => "Required skill level", - 'level' => "Level", - 'school' => "School", - 'skill' => "skill", - 'skills' => "Skills", - 'spell' => "spell", - 'spells' => "Spells", - 'type' => "Type", - 'valueDelim' => " to ", - 'zone' => "zone", - 'zones' => "Zones", - - 'pvp' => "PvP", - 'honorPoints' => "Honor Points", - 'arenaPoints' => "Arena Points", - 'heroClass' => "Hero class", - 'resource' => "Resource", - 'resources' => "Resources", - 'role' => "Role", - 'roles' => "Roles", - 'specs' => "Specs", - '_roles' => ["Healer", "Melee DPS", "Ranged DPS", "Tank"], - - 'phases' => "Phases", - 'mode' => "Mode", - 'modes' => [-1 => "Any", "Normal / Normal 10", "Heroic / Normal 25", "Heroic 10", "Heroic 25"], - 'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"], - 'stats' => ["Strength", "Agility", "Stamina", "Intellect", "Spirit"], - 'sources' => array( - "Unknown", "Crafted", "Drop", "PvP", "Quest", "Vendor", - "Trainer", "Discovery", "Redemption", "Talent", "Starter", "Event", - "Achievement", null, "Black Market", "Disenchanted", "Fished", "Gathered", - "Milled", "Mined", "Prospected", "Pickpocketed", "Salvaged", "Skinned", - "In-Game Store" - ), - 'languages' => array( - 1 => "Orcish", 2 => "Darnassian", 3 => "Taurahe", 6 => "Dwarvish", 7 => "Common", 8 => "Demonic", - 9 => "Titan", 10 => "Thalassian", 11 => "Draconic", 12 => "Kalimag", 13 => "Gnomish", 14 => "Troll", - 33 => "Gutterspeak", 35 => "Draenei", 36 => "Zombie", 37 => "Gnomish Binary", 38 => "Goblin Binary" - ), - 'gl' => [null, "Major", "Minor"], - 'si' => [1 => "Alliance", -1 => "Alliance only", 2 => "Horde", -2 => "Horde only", 3 => "Both"], - 'resistances' => [null, 'Holy Resistance', 'Fire Resistance', 'Nature Resistance', 'Frost Resistance', 'Shadow Resistance', 'Arcane Resistance'], - 'dt' => [null, "Magic", "Curse", "Disease", "Poison", "Stealth", "Invisibility", null, null, "Enrage"], - 'sc' => ["Physical", "Holy", "Fire", "Nature", "Frost", "Shadow", "Arcane"], - 'cl' => [null, "Warrior", "Paladin", "Hunter", "Rogue", "Priest", "Death Knight", "Shaman", "Mage", "Warlock", null, "Druid"], - 'ra' => [-2 => "Horde", -1 => "Alliance", "Both", "Human", "Orc", "Dwarf", "Night Elf", "Undead", "Tauren", "Gnome", "Troll", null, "Blood Elf", "Draenei"], - 'rep' => ["Hated", "Hostile", "Unfriendly", "Neutral", "Friendly", "Honored", "Revered", "Exalted"], - 'st' => array( - "Default", "Cat Form", "Tree of Life", "Travel Form", "Aquatic Form", "Bear From", - null, null, "Dire Bear Form", null, null, null, - null, "Shadowdance", null, null, "Ghostwolf", "Battle Stance", - "Defensive Stance", "Berserker Stance", null, null, "Metamorphosis", null, - null, null, null, "Swift Flight Form", "Shadow Form", "Flight Form", - "Stealth", "Moonkin Form", "Spirit of Redemption" - ), - 'me' => array( - null, "Charmed", "Disoriented", "Disarmed", "Distracted", "Fleeing", - "Gripped", "Rooted", "Pacified", "Silenced", "Asleep", "Ensnared", - "Stunned", "Frozen", "Incapacitated", "Bleeding", "Healing", "Polymorphed", - "Banished", "Shielded", "Shackled", "Mounted", "Seduced", "Turned", - "Horrified", "Invulnerable", "Interrupted", "Dazed", "Discovery", "Invulnerable", - "Sapped", "Enraged" - ), - 'ct' => array( - "Uncategorized", "Beast", "Dragonkin", "Demon", "Elemental", "Giant", - "Undead", "Humanoid", "Critter", "Mechanical", "Not specified", "Totem", - "Non-combat Pet", "Gas Cloud" - ), - 'fa' => array( - 1 => "Wolf", 2 => "Cat", 3 => "Spider", 4 => "Bear", 5 => "Boar", 6 => "Crocolisk", - 7 => "Carrion Bird", 8 => "Crab", 9 => "Gorilla", 11 => "Raptor", 12 => "Tallstrider", 20 => "Scorpid", - 21 => "Turtle", 24 => "Bat", 25 => "Hyena", 26 => "Bird of Prey", 27 => "Wind Serpent", 30 => "Dragonhawk", - 31 => "Ravager", 32 => "Warp Stalker", 33 => "Sporebat", 34 => "Nether Ray", 35 => "Serpent", 37 => "Moth", - 38 => "Chimaera", 39 => "Devilsaur", 41 => "Silithid", 42 => "Worm", 43 => "Rhino", 44 => "Wasp", - 45 => "Core Hound", 46 => "Spirit Beast" - ), - 'pvpRank' => array( - null, "Private / Scout", "Corporal / Grunt", - "Sergeant / Sergeant", "Master Sergeant / Senior Sergeant", "Sergeant Major / First Sergeant", - "Knight / Stone Guard", "Knight-Lieutenant / Blood Guard", "Knight-Captain / Legionnare", - "Knight-Champion / Centurion", "Lieutenant Commander / Champion", "Commander / Lieutenant General", - "Marshal / General", "Field Marshal / Warlord", "Grand Marshal / High Warlord" - ), - ), - 'account' => array( - 'title' => "Aowow Account", - 'email' => "Email address", - 'continue' => "Continue", - 'groups' => array( - -1 => "None", "Tester", "Administrator", "Editor", "Moderator", "Bureaucrat", - "Developer", "VIP", "Blogger", "Premium", "Localizer", "Sales agent", - "Screenshot manager", "Video manager", "API partner", "Pending" - ), - // signIn - 'doSignIn' => "Log in to your AoWoW Account", - 'signIn' => "Log In", - 'user' => "Username", - 'pass' => "Password", - 'rememberMe' => "Stay logged in", - 'forgot' => "Forgot", - 'forgotUser' => "Username", - 'forgotPass' => "Password", - 'accCreate' => 'Don\'t have an account? Create one now!', - - // recovery - 'recoverUser' => "Username Request", - 'recoverPass' => "Password Reset: Step %s of 2", - 'newPass' => "New Password", - - // creation - 'register' => "Registration - Step %s of 2", - 'passConfirm' => "Confirm password", - - // dashboard - 'ipAddress' => "IP-Adress", - 'lastIP' => "last used IP", - 'myAccount' => "My Account", - 'editAccount' => "Simply use the forms below to update your account information", - 'viewPubDesc' => 'View your Public Description in your Profile Page', - - // bans - 'accBanned' => "This Account was closed", - 'bannedBy' => "Banned by", - 'ends' => "Ends on", - 'permanent' => "The ban is permanent", - 'reason' => "Reason", - 'noReason' => "No reason was given.", - - // form-text - 'emailInvalid' => "That email address is not valid.", // message_emailnotvalid - 'emailNotFound' => "The email address you entered is not associated with any account.

If you forgot the email you registered your account with email ".CFG_CONTACT_EMAIL." for assistance.", - 'createAccSent' => "An email was sent to %s. Simply follow the instructions to create your account.", - 'recovUserSent' => "An email was sent to %s. Simply follow the instructions to recover your username.", - 'recovPassSent' => "An email was sent to %s. Simply follow the instructions to reset your password.", - 'accActivated' => 'Your account has been activated.
Proceed to sign in', - 'userNotFound' => "The username you entered does not exists.", - 'wrongPass' => "That password is not vaild.", - // 'accInactive' => "That account has not yet been confirmed active.", - 'loginExceeded' => "The maximum number of logins from this IP has been exceeded. Please try again in %s.", - 'signupExceeded'=> "The maximum number of signups from this IP has been exceeded. Please try again in %s.", - 'errNameLength' => "Your username must be at least 4 characters long.", // message_usernamemin - 'errNameChars' => "Your username can only contain letters and numbers.", // message_usernamenotvalid - 'errPassLength' => "Your password must be at least 6 characters long.", // message_passwordmin - 'passMismatch' => "The passwords you entered do not match.", - 'nameInUse' => "That username is already taken.", - 'mailInUse' => "That email is already registered to an account.", - 'isRecovering' => "This account is already recovering. Follow the instructions in your email or wait %s for the token to expire.", - 'passCheckFail' => "Passwords do not match.", // message_passwordsdonotmatch - 'newPassDiff' => "Your new password must be different than your previous one." // message_newpassdifferent - ), - 'user' => array( - 'notFound' => "User \"%s\" not found!", - 'removed' => "(Removed)", - 'joinDate' => "Joined", - 'lastLogin' => "Last visit", - 'userGroups' => "Role", - 'consecVisits' => "Consecutive visits", - 'publicDesc' => "Public Description", - 'profileTitle' => "%s's Profile", - 'contributions' => "Contributions", - 'uploads' => "Data uploads", - 'comments' => "Comments", - 'screenshots' => "Screenshots", - 'videos' => "Videos", - 'posts' => "Forum posts" - ), - 'mail' => array( - 'tokenExpires' => "This token expires in %s.", - 'accConfirm' => ["Account Confirmation", "Welcome to ".CFG_NAME_SHORT."!\r\n\r\nClick the Link below to activate your account.\r\n\r\n".HOST_URL."?account=signup&token=%s\r\n\r\nIf you did not request this mail simply ignore it."], - 'recoverUser' => ["User Recovery", "Follow this link to log in.\r\n\r\n".HOST_URL."?account=signin&token=%s\r\n\r\nIf you did not request this mail simply ignore it."], - 'resetPass' => ["Password Reset", "Follow this link to reset your password.\r\n\r\n".HOST_URL."?account=forgotpassword&token=%s\r\n\r\nIf you did not request this mail simply ignore it."] - ), - 'emote' => array( - 'notFound' => "This Emote doesn't exist.", - 'self' => "To Yourself", - 'target' => "To others with a target", - 'noTarget' => "To others without a target", - 'isAnimated' => "Uses an animation", - 'aliases' => "Aliases", - 'noText' => "This Emote has no text.", - ), - 'enchantment' => array( - 'details' => "Details", - 'activation' => "Activation", - 'notFound' => "This enchantment doesn't exist.", - 'types' => array( - 1 => "Proc Spell", 3 => "Equip Spell", 7 => "Use Spell", 8 => "Prismatic Socket", - 5 => "Statistics", 2 => "Weapon Damage", 6 => "DPS", 4 => "Defense" - ) - ), - 'gameObject' => array( - 'notFound' => "This object doesn't exist.", - 'cat' => [0 => "Other", 9 => "Books", 3 => "Containers", -5 => "Chests", 25 => "Fishing Pools", -3 => "Herbs", -4 => "Mineral Veins", -2 => "Quest", -6 => "Tools"], - 'type' => [ 9 => "Book", 3 => "Container", -5 => "Chest", 25 => "", -3 => "Herb", -4 => "Mineral Vein", -2 => "Quest", -6 => ""], - 'unkPosition' => "The location of this object is unknown.", - 'npcLootPH' => 'The %s contains the loot from the fight against %s. It spawns after his death.', - 'key' => "Key", - 'focus' => "Spell Focus", - 'focusDesc' => "Spells requiring this Focus can be cast near this Object", - 'trap' => "Trap", - 'triggeredBy' => "Triggered by", - 'capturePoint' => "Capture Point", - 'foundIn' => "This object can be found in", - 'restock' => "Restocks every %s." - ), - 'npc' => array( - 'notFound' => "This NPC doesn't exist.", - 'classification'=> "Classification", - 'petFamily' => "Pet familiy", - 'react' => "React", - 'worth' => "Worth", - 'unkPosition' => "The location of this NPC is unknown.", - 'difficultyPH' => "This NPC is a placeholder for a different mode of", - 'seat' => "Seat", - 'accessory' => "Accessories", - 'accessoryFor' => "This NPC is an accessory for vehicle", - 'quotes' => "Quotes", - 'gainsDesc' => "After killing this NPC you will gain", - 'repWith' => "reputation with", - 'stopsAt' => "stops at %s", - 'vehicle' => "Vehicle", - 'stats' => "Stats", - 'melee' => "Melee", - 'ranged' => "Ranged", - 'armor' => "Armor", - 'foundIn' => "This NPC can be found in", - 'tameable' => "Tameable (%s)", - 'waypoint' => "Waypoint", - 'wait' => "Wait", - 'respawnIn' => "Respawn in", - 'rank' => [0 => "Normal", 1 => "Elite", 4 => "Rare", 2 => "Rare Elite", 3 => "Boss"], - 'textRanges' => [null, "sent to area", "sent to zone", "sent to map", "sent to world"], - 'textTypes' => [null, "yells", "says", "whispers"], - 'modes' => array( - 1 => ["Normal", "Heroic"], - 2 => ["10-player Normal", "25-player Normal", "10-player Heroic", "25-player Heroic"] - ), - 'cat' => array( - "Uncategorized", "Beasts", "Dragonkins", "Demons", "Elementals", "Giants", "Undead", "Humanoids", - "Critters", "Mechanicals", "Not specified", "Totems", "Non-combat Pets", "Gas Clouds" - ), - ), - 'event' => array( - 'notFound' => "This world event doesn't exist.", - 'start' => "Start", - 'end' => "End", - 'interval' => "Interval", - 'inProgress' => "Event is currently in progress", - 'category' => ["Uncategorized", "Holidays", "Recurring", "Player vs. Player"] - ), - 'achievement' => array( - 'notFound' => "This achievement doesn't exist.", - 'criteria' => "Criteria", - 'points' => "Points", - 'series' => "Series", - 'outOf' => "out of", - 'criteriaType' => "Criterium Type-Id:", - 'itemReward' => "You will receive", - 'titleReward' => 'You shall be granted the title "%s"', - 'slain' => "slain", - 'reqNumCrt' => "Requires", - 'rfAvailable' => "Available on realm: ", - '_transfer' => 'This achievement will be converted to %s if you transfer to %s.', - ), - 'chrClass' => array( - 'notFound' => "This class doesn't exist." - ), - 'race' => array( - 'notFound' => "This race doesn't exist.", - 'racialLeader' => "Racial leader", - 'startZone' => "Starting zone", - ), - 'maps' => array( - 'maps' => "Maps", - 'linkToThisMap' => "Link to this map", - 'clear' => "Clear", - 'EasternKingdoms' => "Eastern Kingdoms", - 'Kalimdor' => "Kalimdor", - 'Outland' => "Outland", - 'Northrend' => "Northrend", - 'Instances' => "Instances", - 'Dungeons' => "Dungeons", - 'Raids' => "Raids", - 'More' => "More ", - 'Battlegrounds' => "Battlegrounds", - 'Miscellaneous' => "Miscellaneous", - 'Azeroth' => "Azeroth", - 'CosmicMap' => "Cosmic Map", - ), - 'zone' => array( - 'notFound' => "This zone doesn't exist.", - 'attunement' => ["Attunement", "Heroic attunement"], - 'key' => ["Key", "Heroic key"], - 'location' => "Location", - 'raidFaction' => "Raid faction", - 'boss' => "Final boss", - 'reqLevels' => "Required levels: [tooltip=instancereqlevel_tip]%d[/tooltip], [tooltip=lfgreqlevel_tip]%d[/tooltip]", - 'zonePartOf' => "This zone is part of [zone=%s].", - 'autoRez' => "Automatic resurrection", - 'city' => "City", - 'territory' => "Territory", - 'instanceType' => "Instance type", - 'hcAvailable' => "Heroic mode available (%d)", - 'numPlayers' => "Number of players", - 'noMap' => "There is no map available for this zone.", - 'instanceTypes' => ["Zone", "Transit", "Dungeon", "Raid", "Battleground", "Dungeon", "Arena", "Raid", "Raid"], - 'territories' => ["Alliance", "Horde", "Contested", "Sanctuary", "PvP", "World PvP"], - 'cat' => array( - "Eastern Kingdoms", "Kalimdor", "Dungeons", "Raids", "Unused", null, - "Battlegrounds", null, "Outland", "Arenas", "Northrend" - ) - ), - 'quest' => array( - 'notFound' => "This quest doesn't exist.", - '_transfer' => 'This quest will be converted to %s if you transfer to %s.', - 'questLevel' => "Level %s", - 'requirements' => "Requirements", - 'reqMoney' => "Required money", - 'money' => "Money", - 'additionalReq' => "Additional requirements to obtain this quest", - 'reqRepWith' => 'Your reputation with %s must be %s %s', - 'reqRepMin' => "at least", - 'reqRepMax' => "lower than", - 'progress' => "Progress", - 'provided' => "Provided", - 'providedItem' => "Provided item", - 'completion' => "Completion", - 'description' => "Description", - 'playerSlain' => "Players slain", - 'profession' => "Profession", - 'timer' => "Timer", - 'loremaster' => "Loremaster", - 'suggestedPl' => "Suggested players", - 'keepsPvpFlag' => "Keeps you PvP flagged", - 'daily' => "Daily", - 'weekly' => "Weekly", - 'monthly' => "Monthly", - 'sharable' => "Sharable", - 'notSharable' => "Not sharable", - 'repeatable' => "Repeatable", - 'reqQ' => "Requires", - 'reqQDesc' => "To take this quest, you must complete all these quests", - 'reqOneQ' => "Requires one of", - 'reqOneQDesc' => "To take this quest, you must complete one of the following quests", - 'opensQ' => "Opens Quests", - 'opensQDesc' => "Completing this quest is requires to take this quests", - 'closesQ' => "Closes Quests", - 'closesQDesc' => "After completing this quest, you will not be able to take these quests", - 'enablesQ' => "Enables", - 'enablesQDesc' => "When this quest is active, these quests are also available", - 'enabledByQ' => "Enabled by", - 'enabledByQDesc'=> "This quest is available only, when one of these quests are active", - 'gainsDesc' => "Upon completion of this quest you will gain", - 'theTitle' => 'the title "%s"', - 'mailDelivery' => "You will receive this letter%s%s", - 'mailBy' => ' by %s', - 'mailIn' => " after %s", - 'unavailable' => "This quest was marked obsolete and cannot be obtained or completed.", - 'experience' => "experience", - 'expConvert' => "(or %s if completed at level %d)", - 'expConvert2' => "%s if completed at level %d", - 'chooseItems' => "You will be able to choose one of these rewards", - 'receiveItems' => "You will receive", - 'receiveAlso' => "You will also receive", - 'spellCast' => "The following spell will be cast on you", - 'spellLearn' => "You will learn", - 'bonusTalents' => "talent points", - 'spellDisplayed'=> ' (%s is displayed)', - 'attachment' => "Attachment", - 'questInfo' => array( - 0 => "Normal", 1 => "Group", 21 => "Life", 41 => "PvP", 62 => "Raid", 81 => "Dungeon", 82 => "World Event", - 83 => "Legendary", 84 => "Escort", 85 => "Heroic", 88 => "Raid (10)", 89 => "Raid (25)" - ), - 'cat' => array( - 0 => array( "Eastern Kingdoms", - 36 => "Alterac Mountains", 45 => "Arathi Highlands", 3 => "Badlands", 25 => "Blackrock Mountain", 4 => "Blasted Lands", - 46 => "Burning Steppes", 279 => "Dalaran Crater", 41 => "Deadwind Pass", 2257 => "Deeprun Tram", 1 => "Dun Morogh", - 10 => "Duskwood", 139 => "Eastern Plaguelands", 12 => "Elwynn Forest", 3430 => "Eversong Woods", 3433 => "Ghostlands", - 267 => "Hillsbrad Foothills", 1537 => "Ironforge", 4080 => "Isle of Quel'Danas", 38 => "Loch Modan", 44 => "Redridge Mountains", - 51 => "Searing Gorge", 3487 => "Silvermoon City", 130 => "Silverpine Forest", 1519 => "Stormwind City", 33 => "Stranglethorn Vale", - 8 => "Swamp of Sorrows", 47 => "The Hinterlands", 4298 => "The Scarlet Enclave", 85 => "Tirisfal Glades", 1497 => "Undercity", - 28 => "Western Plaguelands", 40 => "Westfall", 11 => "Wetlands" - ), - 1 => array( "Kalimdor", - 331 => "Ashenvale", 16 => "Azshara", 3524 => "Azuremyst Isle", 3525 => "Bloodmyst Isle", 148 => "Darkshore", - 1657 => "Darnassus", 405 => "Desolace", 14 => "Durotar", 15 => "Dustwallow Marsh", 361 => "Felwood", - 357 => "Feralas", 493 => "Moonglade", 215 => "Mulgore", 1637 => "Orgrimmar", 1377 => "Silithus", - 406 => "Stonetalon Mountains", 440 => "Tanaris", 141 => "Teldrassil", 17 => "The Barrens", 3557 => "The Exodar", - 457 => "The Veiled Sea", 400 => "Thousand Needles", 1638 => "Thunder Bluff", 490 => "Un'Goro Crater", 618 => "Winterspring" - ), - 8 => array( "Outland", - 3522 => "Blade's Edge Mountains", 3483 => "Hellfire Peninsula", 3518 => "Nagrand", 3523 => "Netherstorm", 3520 => "Shadowmoon Valley", - 703 => "Shattrath City", 3679 => "Skettis", 3519 => "Terokkar Forest", 3521 => "Zangarmarsh" - ), - 10 => array( "Northrend", - 3537 => "Borean Tundra", 2817 => "Crystalsong Forest", 4395 => "Dalaran", 65 => "Dragonblight", 394 => "Grizzly Hills", - 495 => "Howling Fjord", 4742 => "Hrothgar's Landing", 210 => "Icecrown", 3711 => "Sholazar Basin", 67 => "The Storm Peaks", - 4197 => "Wintergrasp", 66 => "Zul'Drak" - ), - 2 => array( "Dungeons", - 4494 => "Ahn'kahet: The Old Kingdom", 3790 => "Auchenai Crypts", 4277 => "Azjol-Nerub", 719 => "Blackfathom Deeps", 1584 => "Blackrock Depths", - 1583 => "Blackrock Spire", 1941 => "Caverns of Time", 3905 => "Coilfang Reservoir", 2557 => "Dire Maul", 4196 => "Drak'Tharon Keep", - 721 => "Gnomeregan", 4416 => "Gundrak", 4272 => "Halls of Lightning", 4820 => "Halls of Reflection", 4264 => "Halls of Stone", - 3562 => "Hellfire Ramparts", 3535 => "Hellfire Citadel", 4131 => "Magisters' Terrace", 3792 => "Mana-Tombs", 2100 => "Maraudon", - 2367 => "Old Hillsbrad Foothills", 4813 => "Pit of Saron", 2437 => "Ragefire Chasm", 722 => "Razorfen Downs", 491 => "Razorfen Kraul", - 796 => "Scarlet Monastery", 2057 => "Scholomance", 3791 => "Sethekk Halls", 3789 => "Shadow Labyrinth", 209 => "Shadowfang Keep", - 2017 => "Stratholme", 1477 => "Sunken Temple", 3845 => "Tempest Keep", 3848 => "The Arcatraz", 2366 => "The Black Morass", - 3713 => "The Blood Furnace", 3847 => "The Botanica", 4100 => "The Culling of Stratholme", 1581 => "The Deadmines", 4809 => "The Forge of Souls", - 3849 => "The Mechanar", 4120 => "The Nexus", 4228 => "The Oculus", 3714 => "The Shattered Halls", 3717 => "The Slave Pens", - 3715 => "The Steamvault", 717 => "The Stockade", 3716 => "The Underbog", 4415 => "The Violet Hold", 4723 => "Trial of the Champion", - 1337 => "Uldaman", 206 => "Utgarde Keep", 1196 => "Utgarde Pinnacle", 718 => "Wailing Caverns", 1176 => "Zul'Farrak" - ), - 3 => array( "Raids", - 3959 => "Black Temple", 2677 => "Blackwing Lair", 3923 => "Gruul's Lair", 3606 => "Hyjal Summit", 4812 => "Icecrown Citadel", - 3457 => "Karazhan", 3836 => "Magtheridon's Lair", 2717 => "Molten Core", 3456 => "Naxxramas", 2159 => "Onyxia's Lair", - 3429 => "Ruins of Ahn'Qiraj", 3607 => "Serpentshrine Cavern", 4075 => "Sunwell Plateau", 3428 => "Temple of Ahn'Qiraj", 3842 => "The Eye", - 4500 => "The Eye of Eternity", 4493 => "The Obsidian Sanctum", 4722 => "Trial of the Crusader", 4273 => "Ulduar", 4603 => "Vault of Archavon", - 3805 => "Zul'Aman", 1977 => "Zul'Gurub" - ), - 4 => array( "Classes", - -372 => "Death Knight", -263 => "Druid", -261 => "Hunter", -161 => "Mage", -141 => "Paladin", - -262 => "Priest", -162 => "Rogue", -82 => "Shaman", -61 => "Warlock", -81 => "Warrior" - ), - 5 => array( "Professions", - -181 => "Alchemy", -121 => "Blacksmithing", -304 => "Cooking", -201 => "Engineering", -324 => "First Aid", - -101 => "Fishing", -24 => "Herbalism", -371 => "Inscription", -373 => "Jewelcrafting", -182 => "Leatherworking", - -264 => "Tailoring" - ), - 6 => array( "Battlegrounds", - -25 => "All", 2597 => "Alterac Valley", 3358 => "Arathi Basin", 3820 => "Eye of the Storm", 4710 => "Isle of Conquest", - 4384 => "Strand of the Ancients", 3277 => "Warsong Gulch" - ), - 9 => array( "Seasonal", - -370 => "Brewfest", -1002 => "Children's Week", -364 => "Darkmoon Faire", -41 => "Day of the Dead", -1003 => "Hallow's End", - -1005 => "Harvest Festival", -376 => "Love is in the Air", -366 => "Lunar Festival", -369 => "Midsummer", -1006 => "New Year's Eve", - -375 => "Pilgrim's Bounty", -374 => "Noblegarden", -1001 => "Winter Veil" - ), - 7 => array( "Miscellaneous", - -365 => "Ahn'Qiraj War Effort", -241 => "Argent Tournament", -1010 => "Dungeon Finder", -1 => "Epic", -344 => "Legendary", - -367 => "Reputation", -368 => "Scourge Invasion" - ), - -2 => "Uncategorized" - ) - ), - 'title' => array( - 'notFound' => "This title doesn't exist.", - '_transfer' => 'This title will be converted to %s if you transfer to %s.', - 'cat' => array( - "General", "Player vs. Player", "Reputation", "Dungeons & Raids", "Quests", "Professions", "World Events" - ) - ), - 'skill' => array( - 'notFound' => "This skill doesn't exist.", - 'cat' => array( - -6 => "Companions", -5 => "Mounts", -4 => "Racial Traits", 5 => "Attributes", 6 => "Weapon Skills", 7 => "Class Skills", 8 => "Armor Proficiencies", - 9 => "Secondary Skills", 10 => "Languages", 11 => "Professions" - ) - ), - 'currency' => array( - 'notFound' => "This currency doesn't exist.", - 'cap' => "Total cap", - 'cat' => array( - 1 => "Miscellaneous", 2 => "Player vs. Player", 4 => "Classic", 21 => "Wrath of the Lich King", 22 => "Dungeon and Raid", 23 => "Burning Crusade", 41 => "Test", 3 => "Unused" - ) - ), - 'pet' => array( - 'notFound' => "This pet family doesn't exist.", - 'exotic' => "Exotic", - 'cat' => ["Ferocity", "Tenacity", "Cunning"] - ), - 'faction' => array( - 'notFound' => "This faction doesn't exist.", - 'spillover' => "Reputation Spillover", - 'spilloverDesc' => "Gaining reputation with this faction also yields a proportional gain with the factions listed below.", - 'maxStanding' => "Max. Standing", - 'quartermaster' => "Quartermaster", - 'customRewRate' => "Custom Reward Rate", - '_transfer' => 'The reputation with this faction will be converted to %s if you transfer to %s.', - 'cat' => array( - 1118 => ["Classic", 469 => "Alliance", 169 => "Steamwheedle Cartel", 67 => "Horde", 891 => "Alliance Forces", 892 => "Horde Forces"], - 980 => ["The Burning Crusade", 936 => "Shattrath City"], - 1097 => ["Wrath of the Lich King", 1052 => "Horde Expedition", 1117 => "Sholazar Basin", 1037 => "Alliance Vanguard"], - 0 => "Other" - ) - ), - 'itemset' => array( - 'notFound' => "This item set doesn't exist.", - '_desc' => "%s is the %s. It contains %s pieces.", - '_descTagless' => "%s is an item set that contains %s pieces.", - '_setBonuses' => "Set Bonuses", - '_conveyBonus' => "Wearing more pieces of this set will convey bonuses to your character.", - '_pieces' => "pieces", - '_unavailable' => "This item set is not available to players.", - '_tag' => "Tag", - 'summary' => "Summary", - 'notes' => array( - null, "Dungeon Set 1", "Dungeon Set 2", "Tier 1 Raid Set", - "Tier 2 Raid Set", "Tier 3 Raid Set", "Level 60 PvP Rare Set", "Level 60 PvP Rare Set (Old)", - "Level 60 PvP Epic Set", "Ruins of Ahn'Qiraj Set", "Temple of Ahn'Qiraj Set", "Zul'Gurub Set", - "Tier 4 Raid Set", "Tier 5 Raid Set", "Dungeon Set 3", "Arathi Basin Set", - "Level 70 PvP Rare Set", "Arena Season 1 Set", "Tier 6 Raid Set", "Arena Season 2 Set", - "Arena Season 3 Set", "Level 70 PvP Rare Set 2", "Arena Season 4 Set", "Tier 7 Raid Set", - "Arena Season 5 Set", "Tier 8 Raid Set", "Arena Season 6 Set", "Tier 9 Raid Set", - "Arena Season 7 Set", "Tier 10 Raid Set", "Arena Season 8 Set" - ), - 'types' => array( - null, "Cloth", "Leather", "Mail", "Plate", "Dagger", "Ring", - "Fist Weapon", "One-Handed Axe", "One-Handed Mace", "One-Handed Sword", "Trinket", "Amulet" - ) - ), - 'spell' => array( - 'notFound' => "This spell doesn't exist.", - '_spellDetails' => "Spell Details", - '_cost' => "Cost", - '_range' => "Range", - '_castTime' => "Cast time", - '_cooldown' => "Cooldown", - '_distUnit' => "yards", - '_forms' => "Forms", - '_aura' => "Aura", - '_effect' => "Effect", - '_none' => "None", - '_gcd' => "GCD", - '_globCD' => "Global Cooldown", - '_gcdCategory' => "GCD category", - '_value' => "Value", - '_radius' => "Radius", - '_interval' => "Interval", - '_inSlot' => "in slot", - '_collapseAll' => "Collapse All", - '_expandAll' => "Expand All", - '_transfer' => 'This spell will be converted to %s if you transfer to %s.', - 'discovered' => "Learned via discovery", - 'ppm' => "%s procs per minute", - 'procChance' => "Proc chance", - 'starter' => "Starter spell", - 'trainingCost' => "Training cost", - 'remaining' => "%s remaining", - 'untilCanceled' => "until canceled", - 'castIn' => "%s sec cast", - 'instantPhys' => "Instant", - 'instantMagic' => "Instant cast", - 'channeled' => "Channeled", - 'range' => "%s yd range", - 'meleeRange' => "Melee Range", - 'unlimRange' => "Unlimited Range", - 'reagents' => "Reagents", - 'tools' => "Tools", - 'home' => "<Inn>", - 'pctCostOf' => "of base %s", - 'costPerSec' => ", plus %s per sec", - 'costPerLevel' => ", plus %s per level", - 'stackGroup' => "Stack Group", - 'linkedWith' => "Linked with", - '_scaling' => "Scaling", - 'scaling' => array( - 'directSP' => "+%.2f%% of spell power to direct component", 'directAP' => "+%.2f%% of attack power to direct component", - 'dotSP' => "+%.2f%% of spell power per tick", 'dotAP' => "+%.2f%% of attack power per tick" - ), - 'powerRunes' => ["Frost", "Unholy", "Blood", "Death"], - 'powerTypes' => array( - // conventional - -2 => "Health", 0 => "Mana", 1 => "Rage", 2 => "Focus", 3 => "Energy", 4 => "Happiness", - 5 => "Rune", 6 => "Runic Power", - // powerDisplay - -1 => "Ammo", -41 => "Pyrite", -61 => "Steam Pressure", -101 => "Heat", -121 => "Ooze", -141 => "Blood Power", - -142 => "Wrath" - ), - 'relItems' => array( - 'base' => "Show %s related to %s", - 'link' => " or ", - 'recipes' => 'recipe items', - 'crafted' => 'crafted items' - ), - 'cat' => array( - 7 => "Class Skills", // classList - -13 => "Glyphs", // classList - -11 => array("Proficiencies", 8 => "Armor", 6 => "Weapon", 10 => "Languages"), - -4 => "Racial Traits", - -2 => "Talents", // classList - -6 => "Companions", - -5 => "Mounts", - -3 => array( - "Pet Skills", 782 => "Ghoul", 270 => "Generic", 653 => "Bat", 210 => "Bear", 655 => "Bird of Prey", 211 => "Boar", - 213 => "Carrion Bird", 209 => "Cat", 780 => "Chimaera", 787 => "Core Hound", 214 => "Crab", 212 => "Crocolisk", 781 => "Devilsaur", - 763 => "Dragonhawk", 215 => "Gorilla", 654 => "Hyena", 775 => "Moth", 764 => "Nether Ray", 217 => "Raptor", 767 => "Ravager", - 786 => "Rhino", 236 => "Scorpid", 768 => "Serpent", 783 => "Silithid", 203 => "Spider", 788 => "Spirit Beast", 765 => "Sporebat", - 218 => "Tallstrider", 251 => "Turtle", 766 => "Warp Stalker", 785 => "Wasp", 656 => "Wind Serpent", 208 => "Wolf", 784 => "Worm", - 761 => "Felguard", 189 => "Felhunter", 188 => "Imp", 205 => "Succubus", 204 => "Voidwalker" - ), - -7 => ["Pet Talents", 410 => "Cunning", 411 => "Ferocity", 409 => "Tenacity"], - 11 => array( - "Professions", - 171 => "Alchemy", - 164 => ["Blacksmithing", 9788 => "Armorsmithing", 9787 => "Weaponsmithing", 17041 => "Master Axesmithing", 17040 => "Master Hammersmithing", 17039 => "Master Swordsmithing"], - 333 => "Enchanting", - 202 => ["Engineering", 20219 => "Gnomish Engineering", 20222 => "Goblin Engineering"], - 182 => "Herbalism", - 773 => "Inscription", - 755 => "Jewelcrafting", - 165 => ["Leatherworking", 10656 => "Dragonscale Leatherworking", 10658 => "Elemental Leatherworking", 10660 => "Tribal Leatherworking"], - 186 => "Mining", - 393 => "Skinning", - 197 => ["Tailoring", 26798 => "Mooncloth Tailoring", 26801 => "Shadoweave Tailoring", 26797 => "Spellfire Tailoring"], - ), - 9 => ["Secondary Skills", 185 => "Cooking", 129 => "First Aid", 356 => "Fishing", 762 => "Riding"], - -8 => "NPC Abilities", - -9 => "GM Abilities", - 0 => "Uncategorized" - ), - 'armorSubClass' => array( - "Miscellaneous", "Cloth Armor", "Leather Armor", "Mail Armor", "Plate Armor", - null, "Shields", "Librams", "Idols", "Totems", - "Sigils" - ), - 'weaponSubClass' => array( // ordered by content firts, then alphabeticaly - 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", - 20 => "Fishing Poles", 14 => "Miscellaneous" - ), - 'subClassMasks' => array( - 0x02A5F3 => "Melee Weapon", 0x0060 => "Shield", 0x04000C => "Ranged Weapon", 0xA091 => "One-Handed Melee Weapon" - ), - 'traitShort' => array( - 'atkpwr' => "AP", 'rgdatkpwr' => "RAP", 'splpwr' => "SP", 'arcsplpwr' => "ArcP", 'firsplpwr' => "FireP", - 'frosplpwr' => "FroP", 'holsplpwr' => "HolP", 'natsplpwr' => "NatP", 'shasplpwr' => "ShaP", 'splheal' => "Heal" - ), - 'spellModOp' => array( - "Damage", "Duration", "Thread", "Effect 1", "Charges", - "Range", "Radius", "Critical Hit Chance", "All Effects", "Casting Time loss", - "Casting Time", "Cooldown", "Effect 2", "Ignore Armor", "Cost", - "Critical Damage Bonus", "Chance to Fail", "Jump Targets", "Proc Chance", "Intervall", - "Multiplier (Damage)", "Global Cooldown", "Damage over Time", "Effect 3", "Multiplier (Bonus)", - null, "Procs per Minute", "Multiplier (Value)", "Chance to Resist Dispel", "Critical Damage Bonus2", - "Refund Cost on Fail" - ), - 'combatRating' => array( - "Weapon Skill", "Defense Skill", "Dodge", "Parry", "Block", - "Melee Hit Chance", "Ranged Hit Chance", "Spell Hit Chance", "Critical Melee Hit Chance", "Critical Ranged Hit Chance", - "Critical Spell Hit Chance", "Taken Melee Hit Chance", "Taken Ranged Hit Chance", "Taken Spell Hit Chance", "Taken Critical Melee Hit Chance", - "Taken Critical Ranged Hit Chance", "Taken Critical Spell Hit Chance", "Melee Haste", "Ranged Haste", "Spell Haste", - "Mainhand Weapon Skill", "Offhand Weapon Skill", "Ranged Weapon Skill", "Expertise", "Armor Penetration" - ), - 'lockType' => array( - null, "Lockpicking", "Herbalism", "Mining", "Disarm Trap", - "Open", "Treasure (DND)", "Calcified Elven Gems (DND)", "Close", "Arm Trap", - "Quick Open", "Quick Close", "Open Tinkering", "Open Kneeling", "Open Attacking", - "Gahz'ridian (DND)", "Blasting", "PvP Open", "PvP Close", "Fishing (DND)", - "Inscription", "Open From Vehicle" - ), - 'stealthType' => ["General", "Trap"], - 'invisibilityType' => ["General", 3 => "Trap", 6 => "Drunk"] - ), - 'item' => array( - 'notFound' => "This item doesn't exist.", - 'armor' => "%s Armor", - 'block' => "%s Block", - 'charges' => "Charges", - 'locked' => "Locked", - 'ratingString' => "%s @ L%s", - 'heroic' => "Heroic", - 'unique' => "Unique", - 'uniqueEquipped'=> "Unique-Equipped", - 'startQuest' => "This Item Begins a Quest", - 'bagSlotString' => "%d Slot %s", - 'dps' => "damage per second", - 'dps2' => "damage per second", - 'addsDps' => "Adds", - 'fap' => "Feral Attack Power", - 'durability' => "Durability", - 'realTime' => "real time", - 'conjured' => "Conjured Item", - 'damagePhys' => "%s Damage", - 'damageMagic' => "%s %s Damage", - 'speed' => "Speed", - 'sellPrice' => "Sell Price", - 'itemLevel' => "Item Level", - 'randEnchant' => "<Random enchantment>", - 'readClick' => "<Right Click To Read>", - 'openClick' => "<Right Click To Open>", - 'set' => "Set", - 'partyLoot' => "Party loot", - 'smartLoot' => "Smart loot", - 'indestructible'=> "Cannot be destroyed", - 'deprecated' => "Deprecated", - 'useInShape' => "Usable when shapeshifted", - 'useInArena' => "Usable in arenas", - 'refundable' => "Refundable", - 'noNeedRoll' => "Cannot roll Need", - 'atKeyring' => "Can be placed in the keyring", - 'worth' => "Worth", - 'consumable' => "Consumable", - 'nonConsumable' => "Non-consumable", - 'accountWide' => "Account-wide", - 'millable' => "Millable", - 'noEquipCD' => "No equip cooldown", - 'prospectable' => "Prospectable", - 'disenchantable'=> "Disenchantable", - 'cantDisenchant'=> "Cannot be disenchanted", - 'repairCost' => "Repair cost", - 'tool' => "Tool", - 'cost' => "Cost", - 'content' => "Content", - '_transfer' => 'This item will be converted to %s if you transfer to %s.', - '_unavailable' => "This item is not available to players.", - '_rndEnchants' => "Random Enchantments", - '_chance' => "(%s%% chance)", - 'slot' => "Slot", - '_quality' => "Quality", - 'usableBy' => "Usable by", - 'buyout' => "Buyout price", - 'each' => "each", - 'tabOther' => "Other", - 'gems' => "Gems", - 'socketBonus' => "Socket Bonus", - 'socket' => array( - "Meta Socket", "Red Socket", "Yellow Socket", "Blue Socket", -1 => "Prismatic Socket" - ), - 'gemColors' => array( - "meta", "red", "yellow", "blue" - ), - 'gemConditions' => array( // ENCHANT_CONDITION_* in GlobalStrings.lua - 2 => ["less than %d %s gem", "less than %d %s gems"], - 3 => "more %s gems than %s gems", - 5 => ["at least %d %s gem", "at least %d %s gems"] - ), - 'reqRating' => array( // ITEM_REQ_ARENA_RATING* - "Requires personal and team arena rating of %d", - "Requires personal and team arena rating of %d
in 3v3 or 5v5 brackets", - "Requires personal and team arena rating of %d
in 5v5 brackets" - ), - 'quality' => array( - "Poor", "Common", "Uncommon", "Rare", - "Epic", "Legendary", "Artifact", "Heirloom" - ), - 'trigger' => array( - "Use: ", "Equip: ", "Chance on hit: ", "", "", - "", "" - ), - 'bonding' => array( - "Binds to account", "Binds when picked up", "Binds when equipped", - "Binds when used", "Quest Item", "Quest Item" - ), - "bagFamily" => array( - "Bag", "Quiver", "Ammo Pouch", "Soul Bag", "Leatherworking Bag", - "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", /*Shield*/ - "Ranged", "Back", "Two-Hand", "Bag", "Tabard", - null, /*Robe*/ "Main Hand", "Off Hand", "Held In Off-Hand", "Projectile", - "Thrown", null, /*Ranged2*/ "Quiver", "Relic" - ), - 'armorSubClass' => array( - "Miscellaneous", "Cloth", "Leather", "Mail", "Plate", - null, "Shield", "Libram", "Idol", "Totem", - "Sigil" - ), - 'weaponSubClass'=> array( - "Axe", "Axe", "Bow", "Gun", "Mace", - "Mace", "Polearm", "Sword", "Sword", null, - "Staff", null, null, "Fist Weapon", "Miscellaneous", - "Dagger", "Thrown", null, "Crossbow", "Wand", - "Fishing Pole" - ), - 'projectileSubClass' => array( - null, null, "Arrow", "Bullet", null - ), - 'elixirType' => [null, "Battle", "Guardian"], - 'cat' => array( // ordered by content first, then alphabeticaly - 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( - -3 => "Item Enhancements (Temporary)", 6 => "Item Enhancements (Permanent)", 2 => ["Elixirs", [1 => "Battle Elixirs", 2 => "Guardian Elixirs"]], - 1 => "Potions", 4 => "Scrolls", 7 => "Bandages", 0 => "Consumables", 3 => "Flasks", 5 => "Food & Drinks", - 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.", - null, - "Agility", - "Strength", - "Intellect", - "Spirit", - "Stamina", - null, null, null, null, - "Improves defense rating by %d.", - "Increases your dodge rating by %d.", - "Increases your parry rating by %d.", - "Increases your shield block rating by %d.", - "Improves melee hit rating by %d.", - "Improves ranged hit rating by %d.", - "Improves spell hit rating by %d.", - "Improves melee critical strike rating by %d.", - "Improves ranged critical strike rating by %d.", - "Improves spell critical strike rating by %d.", - "Improves melee hit avoidance rating by %d.", - "Improves ranged hit avoidance rating by %d.", - "Improves spell hit avoidance rating by %d.", - "Improves melee critical avoidance rating by %d.", - "Improves ranged critical avoidance rating by %d.", - "Improves spell critical avoidance rating by %d.", - "Improves melee haste rating by %d.", - "Improves ranged haste rating by %d.", - "Improves spell haste rating by %d.", - "Improves hit rating by %d.", - "Improves critical strike rating by %d.", - "Improves hit avoidance rating by %d.", - "Improves critical avoidance rating by %d.", - "Increases your resilience rating by %d.", - "Increases your haste rating by %d.", - "Improves expertise rating by %d.", - "Improves attack power by %d.", - "Improves ranged attack power by %d.", - "Improves attack power by %d in Cat, Bear, Dire Bear, and Moonkin forms only.", - "Improves damage done by magical spells and effects by up to %d.", - "Improves healing done by magical spells and effects by up to %d.", - "Restores %d mana per 5 sec.", - "Increases your armor penetration rating by %d.", - "Improves spell power by %d.", - "Restores %d health per 5 sec.", - "Improves spell penetration by %d.", - "Increases the block value of your shield by %d.", - "Unknown Bonus #%d (%d)", - ) - ) -); - -?> + array( + 'sg' => ["year", "month", "week", "day", "hour", "minute", "second", "millisecond"], + 'pl' => ["years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds"], + 'ab' => ["yr", "mo", "wk", "day", "hr", "min", "sec", "ms"] + ), + 'main' => array( + 'name' => "name", + 'link' => "Link", + 'signIn' => "Log in / Register", + 'jsError' => "Please make sure you have javascript enabled.", + 'language' => "Language", + 'feedback' => "Feedback", + 'numSQL' => "Number of MySQL queries", + 'timeSQL' => "Time of MySQL queries", + 'noJScript' => 'This site makes extensive use of JavaScript.
Please enable JavaScript in your browser.', + 'userProfiles' => "My Profiles", + 'pageNotFound' => "This %s doesn't exist.", + 'gender' => "Gender", + 'sex' => [null, "Male", "Female"], + 'players' => "Players", + 'quickFacts' => "Quick Facts", + 'screenshots' => "Screenshots", + 'videos' => "Videos", + 'side' => "Side", + 'related' => "Related", + 'contribute' => "Contribute", + // 'replyingTo' => "The answer to a comment from", + 'submit' => "Submit", + 'cancel' => "Cancel", + 'rewards' => "Rewards", + 'gains' => "Gains", + 'login' => "Login", + 'forum' => "Forum", + 'n_a' => "n/a", + 'siteRep' => "Reputation", + 'aboutUs' => "About us & contact", + 'and' => " and ", + 'or' => " or ", + 'back' => "Back", + 'reputationTip' => "Reputation points", + 'byUserTimeAgo' => 'By %1$s %s ago', + + // filter + 'extSearch' => "Extended search", + 'addFilter' => "Add another Filter", + 'match' => "Match", + 'allFilter' => "All filters", + 'oneFilter' => "At least one", + 'applyFilter' => "Apply filter", + 'resetForm' => "Reset Form", + 'refineSearch' => 'Tip: Refine your search by browsing a subcategory.', + 'clear' => "clear", + 'exactMatch' => "Exact match", + '_reqLevel' => "Required level", + + // infobox + 'unavailable' => "Not available to players", // alternative wording found: "No longer available to players" ... aw screw it <_< + 'disabled' => "Disabled", + 'disabledHint' => "Cannot be attained or completed", + 'serverside' => "Serverside", + 'serversideHint'=> "These informations are not in the Client and have been provided by sniffing and/or guessing.", + + // red buttons + 'links' => "Links", + 'compare' => "Compare", + 'view3D' => "View in 3D", + 'findUpgrades' => "Find upgrades...", + + // misc Tools + 'errPageTitle' => "Page not found", + 'nfPageTitle' => "Error", + 'subscribe' => "Subscribe", + 'mostComments' => ["Yesterday", "Past %d Days"], + 'utilities' => array( + "Latest Additions", "Latest Articles", "Latest Comments", "Latest Screenshots", null, + "Unrated Comments", 11 => "Latest Videos", 12 => "Most Comments", 13 => "Missing Screenshots" + ), + + // article & infobox + 'englishOnly' => "This page is only available in English.", + + // calculators + 'preset' => "Preset", + 'addWeight' => "Add another weight", + 'createWS' => "Create a weight scale", + 'jcGemsOnly' => "Include JC-only gems", + 'cappedHint' => 'Tip: Remove 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", + 'chooseClass' => "Choose a class", + 'chooseFamily' => "Choose a pet family", + + // profiler + 'realm' => "Realm", + 'region' => "Region", + 'viewCharacter' => "View Character", + '_cpHead' => "Character Profiler", + '_cpHint' => "The Character Profiler lets you edit your character, find gear upgrades, check your gearscore and more!", + '_cpHelp' => "To get started, just follow the steps below. If you'd like more information, check out our extensive help page.", + '_cpFooter' => "If you want a more refined search try out our advanced search options. You can also create a new custom profile.", + + // help + 'help' => "Help", + 'helpTopics' => array( + "Commenting and You", "Model Viewer", "Screenshots: Tips & Tricks", "Stat Weighting", + "Talent Calculator", "Item Comparison", "Profiler", "Markup Guide" + ), + + // search + 'search' => "Search", + 'searchButton' => "Search", + 'foundResult' => "Search Results for", + 'noResult' => "No Results for", + 'tryAgain' => "Please try some different keywords or check your spelling.", + 'ignoredTerms' => "The following words were ignored in your search: %s", + + // formating + 'colon' => ': ', + 'dateFmtShort' => "Y/m/d", + 'dateFmtLong' => "Y/m/d \a\\t H:i", + + // error + 'intError' => "An internal error has occurred.", + 'intError2' => "An internal error has occurred. (%s)", + 'genericError' => "An error has occurred; refresh the page and try again. If the error persists email feedback", # LANG.genericerror + 'bannedRating' => "You have been banned from rating comments.", # LANG.tooltip_banned_rating + 'tooManyVotes' => "You have reached the daily voting cap. Come back tomorrow!", # LANG.tooltip_too_many_votes + ), + 'screenshot' => array( + 'submission' => "Screenshot Submission", + 'selectAll' => "Select all", + 'cropHint' => "You may crop your screenshot and enter a caption.", + 'displayOn' => "Displayed on:[br]%s - [%s=%d]", + 'caption' => "Caption", + 'charLimit' => "Optional, up to 200 characters", + 'thanks' => array( + 'contrib' => "Thanks a lot for your contribution!", + 'goBack' => 'Click here to go back to the page you came from.', + 'note' => "Note: Your screenshot will need to be approved before appearing on the site. This can take up to 72 hours." + ), + 'error' => array( + 'unkFormat' => "Unknown image format.", + 'tooSmall' => "Your screenshot is way too small. (< ".CFG_SCREENSHOT_MIN_SIZE."x".CFG_SCREENSHOT_MIN_SIZE.").", + 'selectSS' => "Please select the screenshot to upload.", + 'notAllowed' => "You are not allowed to upload screenshots!", + ) + ), + 'game' => array( + 'achievement' => "achievement", + 'achievements' => "Achievements", + 'class' => "class", + 'classes' => "Classes", + 'currency' => "currency", + 'currencies' => "Currencies", + 'difficulty' => "Difficulty", + 'dispelType' => "Dispel type", + 'duration' => "Duration", + 'emote' => "emote", + 'emotes' => "Emotes", + 'enchantment' => "enchantment", + 'enchantments' => "Enchantments", + 'object' => "object", + 'objects' => "Objects", + 'glyphType' => "Glyph type", + 'race' => "race", + 'races' => "Races", + 'title' => "title", + 'titles' => "Titles", + 'eventShort' => "Event", + 'event' => "World Event", + 'events' => "World Events", + 'faction' => "faction", + 'factions' => "Factions", + 'cooldown' => "%s cooldown", + 'item' => "item", + 'items' => "Items", + 'itemset' => "item Set", + 'itemsets' => "Item Sets", + 'mechanic' => "Mechanic", + 'mechAbbr' => "Mech.", + 'meetingStone' => "Meeting Stone", + 'npc' => "NPC", + 'npcs' => "NPCs", + 'pet' => "Pet", + 'pets' => "Hunter Pets", + 'profile' => "profile", + 'profiles' => "Profiles", + 'quest' => "quest", + 'quests' => "Quests", + 'requires' => "Requires %s", + 'requires2' => "Requires", + 'reqLevel' => "Requires Level %s", + 'reqLevelHlm' => "Requires Level %s", + 'reqSkillLevel' => "Required skill level", + 'level' => "Level", + 'school' => "School", + 'skill' => "skill", + 'skills' => "Skills", + 'spell' => "spell", + 'spells' => "Spells", + 'type' => "Type", + 'valueDelim' => " to ", + 'zone' => "zone", + 'zones' => "Zones", + + 'pvp' => "PvP", + 'honorPoints' => "Honor Points", + 'arenaPoints' => "Arena Points", + 'heroClass' => "Hero class", + 'resource' => "Resource", + 'resources' => "Resources", + 'role' => "Role", + 'roles' => "Roles", + 'specs' => "Specs", + '_roles' => ["Healer", "Melee DPS", "Ranged DPS", "Tank"], + + 'phases' => "Phases", + 'mode' => "Mode", + 'modes' => [-1 => "Any", "Normal / Normal 10", "Heroic / Normal 25", "Heroic 10", "Heroic 25"], + 'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"], + 'stats' => ["Strength", "Agility", "Stamina", "Intellect", "Spirit"], + 'sources' => array( + "Unknown", "Crafted", "Drop", "PvP", "Quest", "Vendor", + "Trainer", "Discovery", "Redemption", "Talent", "Starter", "Event", + "Achievement", null, "Black Market", "Disenchanted", "Fished", "Gathered", + "Milled", "Mined", "Prospected", "Pickpocketed", "Salvaged", "Skinned", + "In-Game Store" + ), + 'languages' => array( + 1 => "Orcish", 2 => "Darnassian", 3 => "Taurahe", 6 => "Dwarvish", 7 => "Common", 8 => "Demonic", + 9 => "Titan", 10 => "Thalassian", 11 => "Draconic", 12 => "Kalimag", 13 => "Gnomish", 14 => "Troll", + 33 => "Gutterspeak", 35 => "Draenei", 36 => "Zombie", 37 => "Gnomish Binary", 38 => "Goblin Binary" + ), + 'gl' => [null, "Major", "Minor"], + 'si' => [1 => "Alliance", -1 => "Alliance only", 2 => "Horde", -2 => "Horde only", 3 => "Both"], + 'resistances' => [null, 'Holy Resistance', 'Fire Resistance', 'Nature Resistance', 'Frost Resistance', 'Shadow Resistance', 'Arcane Resistance'], + 'dt' => [null, "Magic", "Curse", "Disease", "Poison", "Stealth", "Invisibility", null, null, "Enrage"], + 'sc' => ["Physical", "Holy", "Fire", "Nature", "Frost", "Shadow", "Arcane"], + 'cl' => [null, "Warrior", "Paladin", "Hunter", "Rogue", "Priest", "Death Knight", "Shaman", "Mage", "Warlock", null, "Druid"], + 'ra' => [-2 => "Horde", -1 => "Alliance", "Both", "Human", "Orc", "Dwarf", "Night Elf", "Undead", "Tauren", "Gnome", "Troll", null, "Blood Elf", "Draenei"], + 'rep' => ["Hated", "Hostile", "Unfriendly", "Neutral", "Friendly", "Honored", "Revered", "Exalted"], + 'st' => array( + "Default", "Cat Form", "Tree of Life", "Travel Form", "Aquatic Form", "Bear From", + null, null, "Dire Bear Form", null, null, null, + null, "Shadowdance", null, null, "Ghostwolf", "Battle Stance", + "Defensive Stance", "Berserker Stance", null, null, "Metamorphosis", null, + null, null, null, "Swift Flight Form", "Shadow Form", "Flight Form", + "Stealth", "Moonkin Form", "Spirit of Redemption" + ), + 'me' => array( + null, "Charmed", "Disoriented", "Disarmed", "Distracted", "Fleeing", + "Gripped", "Rooted", "Pacified", "Silenced", "Asleep", "Ensnared", + "Stunned", "Frozen", "Incapacitated", "Bleeding", "Healing", "Polymorphed", + "Banished", "Shielded", "Shackled", "Mounted", "Seduced", "Turned", + "Horrified", "Invulnerable", "Interrupted", "Dazed", "Discovery", "Invulnerable", + "Sapped", "Enraged" + ), + 'ct' => array( + "Uncategorized", "Beast", "Dragonkin", "Demon", "Elemental", "Giant", + "Undead", "Humanoid", "Critter", "Mechanical", "Not specified", "Totem", + "Non-combat Pet", "Gas Cloud" + ), + 'fa' => array( + 1 => "Wolf", 2 => "Cat", 3 => "Spider", 4 => "Bear", 5 => "Boar", 6 => "Crocolisk", + 7 => "Carrion Bird", 8 => "Crab", 9 => "Gorilla", 11 => "Raptor", 12 => "Tallstrider", 20 => "Scorpid", + 21 => "Turtle", 24 => "Bat", 25 => "Hyena", 26 => "Bird of Prey", 27 => "Wind Serpent", 30 => "Dragonhawk", + 31 => "Ravager", 32 => "Warp Stalker", 33 => "Sporebat", 34 => "Nether Ray", 35 => "Serpent", 37 => "Moth", + 38 => "Chimaera", 39 => "Devilsaur", 41 => "Silithid", 42 => "Worm", 43 => "Rhino", 44 => "Wasp", + 45 => "Core Hound", 46 => "Spirit Beast" + ), + 'pvpRank' => array( + null, "Private / Scout", "Corporal / Grunt", + "Sergeant / Sergeant", "Master Sergeant / Senior Sergeant", "Sergeant Major / First Sergeant", + "Knight / Stone Guard", "Knight-Lieutenant / Blood Guard", "Knight-Captain / Legionnare", + "Knight-Champion / Centurion", "Lieutenant Commander / Champion", "Commander / Lieutenant General", + "Marshal / General", "Field Marshal / Warlord", "Grand Marshal / High Warlord" + ), + ), + 'account' => array( + 'title' => "Aowow Account", + 'email' => "Email address", + 'continue' => "Continue", + 'groups' => array( + -1 => "None", "Tester", "Administrator", "Editor", "Moderator", "Bureaucrat", + "Developer", "VIP", "Blogger", "Premium", "Localizer", "Sales agent", + "Screenshot manager", "Video manager", "API partner", "Pending" + ), + // signIn + 'doSignIn' => "Log in to your AoWoW Account", + 'signIn' => "Log In", + 'user' => "Username", + 'pass' => "Password", + 'rememberMe' => "Stay logged in", + 'forgot' => "Forgot", + 'forgotUser' => "Username", + 'forgotPass' => "Password", + 'accCreate' => 'Don\'t have an account? Create one now!', + + // recovery + 'recoverUser' => "Username Request", + 'recoverPass' => "Password Reset: Step %s of 2", + 'newPass' => "New Password", + + // creation + 'register' => "Registration - Step %s of 2", + 'passConfirm' => "Confirm password", + + // dashboard + 'ipAddress' => "IP-Adress", + 'lastIP' => "last used IP", + 'myAccount' => "My Account", + 'editAccount' => "Simply use the forms below to update your account information", + 'viewPubDesc' => 'View your Public Description in your Profile Page', + + // bans + 'accBanned' => "This Account was closed", + 'bannedBy' => "Banned by", + 'ends' => "Ends on", + 'permanent' => "The ban is permanent", + 'reason' => "Reason", + 'noReason' => "No reason was given.", + + // form-text + 'emailInvalid' => "That email address is not valid.", // message_emailnotvalid + 'emailNotFound' => "The email address you entered is not associated with any account.

If you forgot the email you registered your account with email ".CFG_CONTACT_EMAIL." for assistance.", + 'createAccSent' => "An email was sent to %s. Simply follow the instructions to create your account.", + 'recovUserSent' => "An email was sent to %s. Simply follow the instructions to recover your username.", + 'recovPassSent' => "An email was sent to %s. Simply follow the instructions to reset your password.", + 'accActivated' => 'Your account has been activated.
Proceed to sign in', + 'userNotFound' => "The username you entered does not exists.", + 'wrongPass' => "That password is not vaild.", + // 'accInactive' => "That account has not yet been confirmed active.", + 'loginExceeded' => "The maximum number of logins from this IP has been exceeded. Please try again in %s.", + 'signupExceeded'=> "The maximum number of signups from this IP has been exceeded. Please try again in %s.", + 'errNameLength' => "Your username must be at least 4 characters long.", // message_usernamemin + 'errNameChars' => "Your username can only contain letters and numbers.", // message_usernamenotvalid + 'errPassLength' => "Your password must be at least 6 characters long.", // message_passwordmin + 'passMismatch' => "The passwords you entered do not match.", + 'nameInUse' => "That username is already taken.", + 'mailInUse' => "That email is already registered to an account.", + 'isRecovering' => "This account is already recovering. Follow the instructions in your email or wait %s for the token to expire.", + 'passCheckFail' => "Passwords do not match.", // message_passwordsdonotmatch + 'newPassDiff' => "Your new password must be different than your previous one." // message_newpassdifferent + ), + 'user' => array( + 'notFound' => "User \"%s\" not found!", + 'removed' => "(Removed)", + 'joinDate' => "Joined", + 'lastLogin' => "Last visit", + 'userGroups' => "Role", + 'consecVisits' => "Consecutive visits", + 'publicDesc' => "Public Description", + 'profileTitle' => "%s's Profile", + 'contributions' => "Contributions", + 'uploads' => "Data uploads", + 'comments' => "Comments", + 'screenshots' => "Screenshots", + 'videos' => "Videos", + 'posts' => "Forum posts" + ), + 'mail' => array( + 'tokenExpires' => "This token expires in %s.", + 'accConfirm' => ["Account Confirmation", "Welcome to ".CFG_NAME_SHORT."!\r\n\r\nClick the Link below to activate your account.\r\n\r\n".HOST_URL."?account=signup&token=%s\r\n\r\nIf you did not request this mail simply ignore it."], + 'recoverUser' => ["User Recovery", "Follow this link to log in.\r\n\r\n".HOST_URL."?account=signin&token=%s\r\n\r\nIf you did not request this mail simply ignore it."], + 'resetPass' => ["Password Reset", "Follow this link to reset your password.\r\n\r\n".HOST_URL."?account=forgotpassword&token=%s\r\n\r\nIf you did not request this mail simply ignore it."] + ), + 'emote' => array( + 'notFound' => "This Emote doesn't exist.", + 'self' => "To Yourself", + 'target' => "To others with a target", + 'noTarget' => "To others without a target", + 'isAnimated' => "Uses an animation", + 'aliases' => "Aliases", + 'noText' => "This Emote has no text.", + ), + 'enchantment' => array( + 'details' => "Details", + 'activation' => "Activation", + 'notFound' => "This enchantment doesn't exist.", + 'types' => array( + 1 => "Proc Spell", 3 => "Equip Spell", 7 => "Use Spell", 8 => "Prismatic Socket", + 5 => "Statistics", 2 => "Weapon Damage", 6 => "DPS", 4 => "Defense" + ) + ), + 'gameObject' => array( + 'notFound' => "This object doesn't exist.", + 'cat' => [0 => "Other", 9 => "Books", 3 => "Containers", -5 => "Chests", 25 => "Fishing Pools", -3 => "Herbs", -4 => "Mineral Veins", -2 => "Quest", -6 => "Tools"], + 'type' => [ 9 => "Book", 3 => "Container", -5 => "Chest", 25 => "", -3 => "Herb", -4 => "Mineral Vein", -2 => "Quest", -6 => ""], + 'unkPosition' => "The location of this object is unknown.", + 'npcLootPH' => 'The %s contains the loot from the fight against %s. It spawns after his death.', + 'key' => "Key", + 'focus' => "Spell Focus", + 'focusDesc' => "Spells requiring this Focus can be cast near this Object", + 'trap' => "Trap", + 'triggeredBy' => "Triggered by", + 'capturePoint' => "Capture Point", + 'foundIn' => "This object can be found in", + 'restock' => "Restocks every %s." + ), + 'npc' => array( + 'notFound' => "This NPC doesn't exist.", + 'classification'=> "Classification", + 'petFamily' => "Pet familiy", + 'react' => "React", + 'worth' => "Worth", + 'unkPosition' => "The location of this NPC is unknown.", + 'difficultyPH' => "This NPC is a placeholder for a different mode of", + 'seat' => "Seat", + 'accessory' => "Accessories", + 'accessoryFor' => "This NPC is an accessory for vehicle", + 'quotes' => "Quotes", + 'gainsDesc' => "After killing this NPC you will gain", + 'repWith' => "reputation with", + 'stopsAt' => "stops at %s", + 'vehicle' => "Vehicle", + 'stats' => "Stats", + 'melee' => "Melee", + 'ranged' => "Ranged", + 'armor' => "Armor", + 'foundIn' => "This NPC can be found in", + 'tameable' => "Tameable (%s)", + 'waypoint' => "Waypoint", + 'wait' => "Wait", + 'respawnIn' => "Respawn in", + 'rank' => [0 => "Normal", 1 => "Elite", 4 => "Rare", 2 => "Rare Elite", 3 => "Boss"], + 'textRanges' => [null, "sent to area", "sent to zone", "sent to map", "sent to world"], + 'textTypes' => [null, "yells", "says", "whispers"], + 'modes' => array( + 1 => ["Normal", "Heroic"], + 2 => ["10-player Normal", "25-player Normal", "10-player Heroic", "25-player Heroic"] + ), + 'cat' => array( + "Uncategorized", "Beasts", "Dragonkins", "Demons", "Elementals", "Giants", "Undead", "Humanoids", + "Critters", "Mechanicals", "Not specified", "Totems", "Non-combat Pets", "Gas Clouds" + ), + ), + 'event' => array( + 'notFound' => "This world event doesn't exist.", + 'start' => "Start", + 'end' => "End", + 'interval' => "Interval", + 'inProgress' => "Event is currently in progress", + 'category' => ["Uncategorized", "Holidays", "Recurring", "Player vs. Player"] + ), + 'achievement' => array( + 'notFound' => "This achievement doesn't exist.", + 'criteria' => "Criteria", + 'points' => "Points", + 'series' => "Series", + 'outOf' => "out of", + 'criteriaType' => "Criterium Type-Id:", + 'itemReward' => "You will receive", + 'titleReward' => 'You shall be granted the title "%s"', + 'slain' => "slain", + 'reqNumCrt' => "Requires", + 'rfAvailable' => "Available on realm: ", + '_transfer' => 'This achievement will be converted to %s if you transfer to %s.', + ), + 'chrClass' => array( + 'notFound' => "This class doesn't exist." + ), + 'race' => array( + 'notFound' => "This race doesn't exist.", + 'racialLeader' => "Racial leader", + 'startZone' => "Starting zone", + ), + 'maps' => array( + 'maps' => "Maps", + 'linkToThisMap' => "Link to this map", + 'clear' => "Clear", + 'EasternKingdoms' => "Eastern Kingdoms", + 'Kalimdor' => "Kalimdor", + 'Outland' => "Outland", + 'Northrend' => "Northrend", + 'Instances' => "Instances", + 'Dungeons' => "Dungeons", + 'Raids' => "Raids", + 'More' => "More ", + 'Battlegrounds' => "Battlegrounds", + 'Miscellaneous' => "Miscellaneous", + 'Azeroth' => "Azeroth", + 'CosmicMap' => "Cosmic Map", + ), + 'zone' => array( + 'notFound' => "This zone doesn't exist.", + 'attunement' => ["Attunement", "Heroic attunement"], + 'key' => ["Key", "Heroic key"], + 'location' => "Location", + 'raidFaction' => "Raid faction", + 'boss' => "Final boss", + 'reqLevels' => "Required levels: [tooltip=instancereqlevel_tip]%d[/tooltip], [tooltip=lfgreqlevel_tip]%d[/tooltip]", + 'zonePartOf' => "This zone is part of [zone=%s].", + 'autoRez' => "Automatic resurrection", + 'city' => "City", + 'territory' => "Territory", + 'instanceType' => "Instance type", + 'hcAvailable' => "Heroic mode available (%d)", + 'numPlayers' => "Number of players", + 'noMap' => "There is no map available for this zone.", + 'instanceTypes' => ["Zone", "Transit", "Dungeon", "Raid", "Battleground", "Dungeon", "Arena", "Raid", "Raid"], + 'territories' => ["Alliance", "Horde", "Contested", "Sanctuary", "PvP", "World PvP"], + 'cat' => array( + "Eastern Kingdoms", "Kalimdor", "Dungeons", "Raids", "Unused", null, + "Battlegrounds", null, "Outland", "Arenas", "Northrend" + ) + ), + 'quest' => array( + 'notFound' => "This quest doesn't exist.", + '_transfer' => 'This quest will be converted to %s if you transfer to %s.', + 'questLevel' => "Level %s", + 'requirements' => "Requirements", + 'reqMoney' => "Required money", + 'money' => "Money", + 'additionalReq' => "Additional requirements to obtain this quest", + 'reqRepWith' => 'Your reputation with %s must be %s %s', + 'reqRepMin' => "at least", + 'reqRepMax' => "lower than", + 'progress' => "Progress", + 'provided' => "Provided", + 'providedItem' => "Provided item", + 'completion' => "Completion", + 'description' => "Description", + 'playerSlain' => "Players slain", + 'profession' => "Profession", + 'timer' => "Timer", + 'loremaster' => "Loremaster", + 'suggestedPl' => "Suggested players", + 'keepsPvpFlag' => "Keeps you PvP flagged", + 'daily' => "Daily", + 'weekly' => "Weekly", + 'monthly' => "Monthly", + 'sharable' => "Sharable", + 'notSharable' => "Not sharable", + 'repeatable' => "Repeatable", + 'reqQ' => "Requires", + 'reqQDesc' => "To take this quest, you must complete all these quests", + 'reqOneQ' => "Requires one of", + 'reqOneQDesc' => "To take this quest, you must complete one of the following quests", + 'opensQ' => "Opens Quests", + 'opensQDesc' => "Completing this quest is requires to take this quests", + 'closesQ' => "Closes Quests", + 'closesQDesc' => "After completing this quest, you will not be able to take these quests", + 'enablesQ' => "Enables", + 'enablesQDesc' => "When this quest is active, these quests are also available", + 'enabledByQ' => "Enabled by", + 'enabledByQDesc'=> "This quest is available only, when one of these quests are active", + 'gainsDesc' => "Upon completion of this quest you will gain", + 'theTitle' => 'the title "%s"', + 'mailDelivery' => "You will receive this letter%s%s", + 'mailBy' => ' by %s', + 'mailIn' => " after %s", + 'unavailable' => "This quest was marked obsolete and cannot be obtained or completed.", + 'experience' => "experience", + 'expConvert' => "(or %s if completed at level %d)", + 'expConvert2' => "%s if completed at level %d", + 'chooseItems' => "You will be able to choose one of these rewards", + 'receiveItems' => "You will receive", + 'receiveAlso' => "You will also receive", + 'spellCast' => "The following spell will be cast on you", + 'spellLearn' => "You will learn", + 'bonusTalents' => "talent points", + 'spellDisplayed'=> ' (%s is displayed)', + 'attachment' => "Attachment", + 'questInfo' => array( + 0 => "Normal", 1 => "Group", 21 => "Life", 41 => "PvP", 62 => "Raid", 81 => "Dungeon", 82 => "World Event", + 83 => "Legendary", 84 => "Escort", 85 => "Heroic", 88 => "Raid (10)", 89 => "Raid (25)" + ), + 'cat' => array( + 0 => array( "Eastern Kingdoms", + 36 => "Alterac Mountains", 45 => "Arathi Highlands", 3 => "Badlands", 25 => "Blackrock Mountain", 4 => "Blasted Lands", + 46 => "Burning Steppes", 279 => "Dalaran Crater", 41 => "Deadwind Pass", 2257 => "Deeprun Tram", 1 => "Dun Morogh", + 10 => "Duskwood", 139 => "Eastern Plaguelands", 12 => "Elwynn Forest", 3430 => "Eversong Woods", 3433 => "Ghostlands", + 267 => "Hillsbrad Foothills", 1537 => "Ironforge", 4080 => "Isle of Quel'Danas", 38 => "Loch Modan", 44 => "Redridge Mountains", + 51 => "Searing Gorge", 3487 => "Silvermoon City", 130 => "Silverpine Forest", 1519 => "Stormwind City", 33 => "Stranglethorn Vale", + 8 => "Swamp of Sorrows", 47 => "The Hinterlands", 4298 => "The Scarlet Enclave", 85 => "Tirisfal Glades", 1497 => "Undercity", + 28 => "Western Plaguelands", 40 => "Westfall", 11 => "Wetlands" + ), + 1 => array( "Kalimdor", + 331 => "Ashenvale", 16 => "Azshara", 3524 => "Azuremyst Isle", 3525 => "Bloodmyst Isle", 148 => "Darkshore", + 1657 => "Darnassus", 405 => "Desolace", 14 => "Durotar", 15 => "Dustwallow Marsh", 361 => "Felwood", + 357 => "Feralas", 493 => "Moonglade", 215 => "Mulgore", 1637 => "Orgrimmar", 1377 => "Silithus", + 406 => "Stonetalon Mountains", 440 => "Tanaris", 141 => "Teldrassil", 17 => "The Barrens", 3557 => "The Exodar", + 457 => "The Veiled Sea", 400 => "Thousand Needles", 1638 => "Thunder Bluff", 490 => "Un'Goro Crater", 618 => "Winterspring" + ), + 8 => array( "Outland", + 3522 => "Blade's Edge Mountains", 3483 => "Hellfire Peninsula", 3518 => "Nagrand", 3523 => "Netherstorm", 3520 => "Shadowmoon Valley", + 703 => "Shattrath City", 3679 => "Skettis", 3519 => "Terokkar Forest", 3521 => "Zangarmarsh" + ), + 10 => array( "Northrend", + 3537 => "Borean Tundra", 2817 => "Crystalsong Forest", 4395 => "Dalaran", 65 => "Dragonblight", 394 => "Grizzly Hills", + 495 => "Howling Fjord", 4742 => "Hrothgar's Landing", 210 => "Icecrown", 3711 => "Sholazar Basin", 67 => "The Storm Peaks", + 4197 => "Wintergrasp", 66 => "Zul'Drak" + ), + 2 => array( "Dungeons", + 4494 => "Ahn'kahet: The Old Kingdom", 3790 => "Auchenai Crypts", 4277 => "Azjol-Nerub", 719 => "Blackfathom Deeps", 1584 => "Blackrock Depths", + 1583 => "Blackrock Spire", 1941 => "Caverns of Time", 3905 => "Coilfang Reservoir", 2557 => "Dire Maul", 4196 => "Drak'Tharon Keep", + 721 => "Gnomeregan", 4416 => "Gundrak", 4272 => "Halls of Lightning", 4820 => "Halls of Reflection", 4264 => "Halls of Stone", + 3562 => "Hellfire Ramparts", 3535 => "Hellfire Citadel", 4131 => "Magisters' Terrace", 3792 => "Mana-Tombs", 2100 => "Maraudon", + 2367 => "Old Hillsbrad Foothills", 4813 => "Pit of Saron", 2437 => "Ragefire Chasm", 722 => "Razorfen Downs", 491 => "Razorfen Kraul", + 796 => "Scarlet Monastery", 2057 => "Scholomance", 3791 => "Sethekk Halls", 3789 => "Shadow Labyrinth", 209 => "Shadowfang Keep", + 2017 => "Stratholme", 1477 => "Sunken Temple", 3845 => "Tempest Keep", 3848 => "The Arcatraz", 2366 => "The Black Morass", + 3713 => "The Blood Furnace", 3847 => "The Botanica", 4100 => "The Culling of Stratholme", 1581 => "The Deadmines", 4809 => "The Forge of Souls", + 3849 => "The Mechanar", 4120 => "The Nexus", 4228 => "The Oculus", 3714 => "The Shattered Halls", 3717 => "The Slave Pens", + 3715 => "The Steamvault", 717 => "The Stockade", 3716 => "The Underbog", 4415 => "The Violet Hold", 4723 => "Trial of the Champion", + 1337 => "Uldaman", 206 => "Utgarde Keep", 1196 => "Utgarde Pinnacle", 718 => "Wailing Caverns", 1176 => "Zul'Farrak" + ), + 3 => array( "Raids", + 3959 => "Black Temple", 2677 => "Blackwing Lair", 3923 => "Gruul's Lair", 3606 => "Hyjal Summit", 4812 => "Icecrown Citadel", + 3457 => "Karazhan", 3836 => "Magtheridon's Lair", 2717 => "Molten Core", 3456 => "Naxxramas", 2159 => "Onyxia's Lair", + 3429 => "Ruins of Ahn'Qiraj", 3607 => "Serpentshrine Cavern", 4075 => "Sunwell Plateau", 3428 => "Temple of Ahn'Qiraj", 3842 => "The Eye", + 4500 => "The Eye of Eternity", 4493 => "The Obsidian Sanctum", 4722 => "Trial of the Crusader", 4273 => "Ulduar", 4603 => "Vault of Archavon", + 3805 => "Zul'Aman", 1977 => "Zul'Gurub" + ), + 4 => array( "Classes", + -372 => "Death Knight", -263 => "Druid", -261 => "Hunter", -161 => "Mage", -141 => "Paladin", + -262 => "Priest", -162 => "Rogue", -82 => "Shaman", -61 => "Warlock", -81 => "Warrior" + ), + 5 => array( "Professions", + -181 => "Alchemy", -121 => "Blacksmithing", -304 => "Cooking", -201 => "Engineering", -324 => "First Aid", + -101 => "Fishing", -24 => "Herbalism", -371 => "Inscription", -373 => "Jewelcrafting", -182 => "Leatherworking", + -264 => "Tailoring" + ), + 6 => array( "Battlegrounds", + -25 => "All", 2597 => "Alterac Valley", 3358 => "Arathi Basin", 3820 => "Eye of the Storm", 4710 => "Isle of Conquest", + 4384 => "Strand of the Ancients", 3277 => "Warsong Gulch" + ), + 9 => array( "Seasonal", + -370 => "Brewfest", -1002 => "Children's Week", -364 => "Darkmoon Faire", -41 => "Day of the Dead", -1003 => "Hallow's End", + -1005 => "Harvest Festival", -376 => "Love is in the Air", -366 => "Lunar Festival", -369 => "Midsummer", -1006 => "New Year's Eve", + -375 => "Pilgrim's Bounty", -374 => "Noblegarden", -1001 => "Winter Veil" + ), + 7 => array( "Miscellaneous", + -365 => "Ahn'Qiraj War Effort", -241 => "Argent Tournament", -1010 => "Dungeon Finder", -1 => "Epic", -344 => "Legendary", + -367 => "Reputation", -368 => "Scourge Invasion" + ), + -2 => "Uncategorized" + ) + ), + 'title' => array( + 'notFound' => "This title doesn't exist.", + '_transfer' => 'This title will be converted to %s if you transfer to %s.', + 'cat' => array( + "General", "Player vs. Player", "Reputation", "Dungeons & Raids", "Quests", "Professions", "World Events" + ) + ), + 'skill' => array( + 'notFound' => "This skill doesn't exist.", + 'cat' => array( + -6 => "Companions", -5 => "Mounts", -4 => "Racial Traits", 5 => "Attributes", 6 => "Weapon Skills", 7 => "Class Skills", 8 => "Armor Proficiencies", + 9 => "Secondary Skills", 10 => "Languages", 11 => "Professions" + ) + ), + 'currency' => array( + 'notFound' => "This currency doesn't exist.", + 'cap' => "Total cap", + 'cat' => array( + 1 => "Miscellaneous", 2 => "Player vs. Player", 4 => "Classic", 21 => "Wrath of the Lich King", 22 => "Dungeon and Raid", 23 => "Burning Crusade", 41 => "Test", 3 => "Unused" + ) + ), + 'pet' => array( + 'notFound' => "This pet family doesn't exist.", + 'exotic' => "Exotic", + 'cat' => ["Ferocity", "Tenacity", "Cunning"] + ), + 'faction' => array( + 'notFound' => "This faction doesn't exist.", + 'spillover' => "Reputation Spillover", + 'spilloverDesc' => "Gaining reputation with this faction also yields a proportional gain with the factions listed below.", + 'maxStanding' => "Max. Standing", + 'quartermaster' => "Quartermaster", + 'customRewRate' => "Custom Reward Rate", + '_transfer' => 'The reputation with this faction will be converted to %s if you transfer to %s.', + 'cat' => array( + 1118 => ["Classic", 469 => "Alliance", 169 => "Steamwheedle Cartel", 67 => "Horde", 891 => "Alliance Forces", 892 => "Horde Forces"], + 980 => ["The Burning Crusade", 936 => "Shattrath City"], + 1097 => ["Wrath of the Lich King", 1052 => "Horde Expedition", 1117 => "Sholazar Basin", 1037 => "Alliance Vanguard"], + 0 => "Other" + ) + ), + 'itemset' => array( + 'notFound' => "This item set doesn't exist.", + '_desc' => "%s is the %s. It contains %s pieces.", + '_descTagless' => "%s is an item set that contains %s pieces.", + '_setBonuses' => "Set Bonuses", + '_conveyBonus' => "Wearing more pieces of this set will convey bonuses to your character.", + '_pieces' => "pieces", + '_unavailable' => "This item set is not available to players.", + '_tag' => "Tag", + 'summary' => "Summary", + 'notes' => array( + null, "Dungeon Set 1", "Dungeon Set 2", "Tier 1 Raid Set", + "Tier 2 Raid Set", "Tier 3 Raid Set", "Level 60 PvP Rare Set", "Level 60 PvP Rare Set (Old)", + "Level 60 PvP Epic Set", "Ruins of Ahn'Qiraj Set", "Temple of Ahn'Qiraj Set", "Zul'Gurub Set", + "Tier 4 Raid Set", "Tier 5 Raid Set", "Dungeon Set 3", "Arathi Basin Set", + "Level 70 PvP Rare Set", "Arena Season 1 Set", "Tier 6 Raid Set", "Arena Season 2 Set", + "Arena Season 3 Set", "Level 70 PvP Rare Set 2", "Arena Season 4 Set", "Tier 7 Raid Set", + "Arena Season 5 Set", "Tier 8 Raid Set", "Arena Season 6 Set", "Tier 9 Raid Set", + "Arena Season 7 Set", "Tier 10 Raid Set", "Arena Season 8 Set" + ), + 'types' => array( + null, "Cloth", "Leather", "Mail", "Plate", "Dagger", "Ring", + "Fist Weapon", "One-Handed Axe", "One-Handed Mace", "One-Handed Sword", "Trinket", "Amulet" + ) + ), + 'spell' => array( + 'notFound' => "This spell doesn't exist.", + '_spellDetails' => "Spell Details", + '_cost' => "Cost", + '_range' => "Range", + '_castTime' => "Cast time", + '_cooldown' => "Cooldown", + '_distUnit' => "yards", + '_forms' => "Forms", + '_aura' => "Aura", + '_effect' => "Effect", + '_none' => "None", + '_gcd' => "GCD", + '_globCD' => "Global Cooldown", + '_gcdCategory' => "GCD category", + '_value' => "Value", + '_radius' => "Radius", + '_interval' => "Interval", + '_inSlot' => "in slot", + '_collapseAll' => "Collapse All", + '_expandAll' => "Expand All", + '_transfer' => 'This spell will be converted to %s if you transfer to %s.', + 'discovered' => "Learned via discovery", + 'ppm' => "%s procs per minute", + 'procChance' => "Proc chance", + 'starter' => "Starter spell", + 'trainingCost' => "Training cost", + 'remaining' => "%s remaining", + 'untilCanceled' => "until canceled", + 'castIn' => "%s sec cast", + 'instantPhys' => "Instant", + 'instantMagic' => "Instant cast", + 'channeled' => "Channeled", + 'range' => "%s yd range", + 'meleeRange' => "Melee Range", + 'unlimRange' => "Unlimited Range", + 'reagents' => "Reagents", + 'tools' => "Tools", + 'home' => "<Inn>", + 'pctCostOf' => "of base %s", + 'costPerSec' => ", plus %s per sec", + 'costPerLevel' => ", plus %s per level", + 'stackGroup' => "Stack Group", + 'linkedWith' => "Linked with", + '_scaling' => "Scaling", + 'scaling' => array( + 'directSP' => "+%.2f%% of spell power to direct component", 'directAP' => "+%.2f%% of attack power to direct component", + 'dotSP' => "+%.2f%% of spell power per tick", 'dotAP' => "+%.2f%% of attack power per tick" + ), + 'powerRunes' => ["Frost", "Unholy", "Blood", "Death"], + 'powerTypes' => array( + // conventional + -2 => "Health", 0 => "Mana", 1 => "Rage", 2 => "Focus", 3 => "Energy", 4 => "Happiness", + 5 => "Rune", 6 => "Runic Power", + // powerDisplay + -1 => "Ammo", -41 => "Pyrite", -61 => "Steam Pressure", -101 => "Heat", -121 => "Ooze", -141 => "Blood Power", + -142 => "Wrath" + ), + 'relItems' => array( + 'base' => "Show %s related to %s", + 'link' => " or ", + 'recipes' => 'recipe items', + 'crafted' => 'crafted items' + ), + 'cat' => array( + 7 => "Class Skills", // classList + -13 => "Glyphs", // classList + -11 => array("Proficiencies", 8 => "Armor", 6 => "Weapon", 10 => "Languages"), + -4 => "Racial Traits", + -2 => "Talents", // classList + -6 => "Companions", + -5 => "Mounts", + -3 => array( + "Pet Skills", 782 => "Ghoul", 270 => "Generic", 653 => "Bat", 210 => "Bear", 655 => "Bird of Prey", 211 => "Boar", + 213 => "Carrion Bird", 209 => "Cat", 780 => "Chimaera", 787 => "Core Hound", 214 => "Crab", 212 => "Crocolisk", 781 => "Devilsaur", + 763 => "Dragonhawk", 215 => "Gorilla", 654 => "Hyena", 775 => "Moth", 764 => "Nether Ray", 217 => "Raptor", 767 => "Ravager", + 786 => "Rhino", 236 => "Scorpid", 768 => "Serpent", 783 => "Silithid", 203 => "Spider", 788 => "Spirit Beast", 765 => "Sporebat", + 218 => "Tallstrider", 251 => "Turtle", 766 => "Warp Stalker", 785 => "Wasp", 656 => "Wind Serpent", 208 => "Wolf", 784 => "Worm", + 761 => "Felguard", 189 => "Felhunter", 188 => "Imp", 205 => "Succubus", 204 => "Voidwalker" + ), + -7 => ["Pet Talents", 410 => "Cunning", 411 => "Ferocity", 409 => "Tenacity"], + 11 => array( + "Professions", + 171 => "Alchemy", + 164 => ["Blacksmithing", 9788 => "Armorsmithing", 9787 => "Weaponsmithing", 17041 => "Master Axesmithing", 17040 => "Master Hammersmithing", 17039 => "Master Swordsmithing"], + 333 => "Enchanting", + 202 => ["Engineering", 20219 => "Gnomish Engineering", 20222 => "Goblin Engineering"], + 182 => "Herbalism", + 773 => "Inscription", + 755 => "Jewelcrafting", + 165 => ["Leatherworking", 10656 => "Dragonscale Leatherworking", 10658 => "Elemental Leatherworking", 10660 => "Tribal Leatherworking"], + 186 => "Mining", + 393 => "Skinning", + 197 => ["Tailoring", 26798 => "Mooncloth Tailoring", 26801 => "Shadoweave Tailoring", 26797 => "Spellfire Tailoring"], + ), + 9 => ["Secondary Skills", 185 => "Cooking", 129 => "First Aid", 356 => "Fishing", 762 => "Riding"], + -8 => "NPC Abilities", + -9 => "GM Abilities", + 0 => "Uncategorized" + ), + 'armorSubClass' => array( + "Miscellaneous", "Cloth Armor", "Leather Armor", "Mail Armor", "Plate Armor", + null, "Shields", "Librams", "Idols", "Totems", + "Sigils" + ), + 'weaponSubClass' => array( // ordered by content firts, then alphabeticaly + 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", + 20 => "Fishing Poles", 14 => "Miscellaneous" + ), + 'subClassMasks' => array( + 0x02A5F3 => "Melee Weapon", 0x0060 => "Shield", 0x04000C => "Ranged Weapon", 0xA091 => "One-Handed Melee Weapon" + ), + 'traitShort' => array( + 'atkpwr' => "AP", 'rgdatkpwr' => "RAP", 'splpwr' => "SP", 'arcsplpwr' => "ArcP", 'firsplpwr' => "FireP", + 'frosplpwr' => "FroP", 'holsplpwr' => "HolP", 'natsplpwr' => "NatP", 'shasplpwr' => "ShaP", 'splheal' => "Heal" + ), + 'spellModOp' => array( + "Damage", "Duration", "Thread", "Effect 1", "Charges", + "Range", "Radius", "Critical Hit Chance", "All Effects", "Casting Time loss", + "Casting Time", "Cooldown", "Effect 2", "Ignore Armor", "Cost", + "Critical Damage Bonus", "Chance to Fail", "Jump Targets", "Proc Chance", "Intervall", + "Multiplier (Damage)", "Global Cooldown", "Damage over Time", "Effect 3", "Multiplier (Bonus)", + null, "Procs per Minute", "Multiplier (Value)", "Chance to Resist Dispel", "Critical Damage Bonus2", + "Refund Cost on Fail" + ), + 'combatRating' => array( + "Weapon Skill", "Defense Skill", "Dodge", "Parry", "Block", + "Melee Hit Chance", "Ranged Hit Chance", "Spell Hit Chance", "Critical Melee Hit Chance", "Critical Ranged Hit Chance", + "Critical Spell Hit Chance", "Taken Melee Hit Chance", "Taken Ranged Hit Chance", "Taken Spell Hit Chance", "Taken Critical Melee Hit Chance", + "Taken Critical Ranged Hit Chance", "Taken Critical Spell Hit Chance", "Melee Haste", "Ranged Haste", "Spell Haste", + "Mainhand Weapon Skill", "Offhand Weapon Skill", "Ranged Weapon Skill", "Expertise", "Armor Penetration" + ), + 'lockType' => array( + null, "Lockpicking", "Herbalism", "Mining", "Disarm Trap", + "Open", "Treasure (DND)", "Calcified Elven Gems (DND)", "Close", "Arm Trap", + "Quick Open", "Quick Close", "Open Tinkering", "Open Kneeling", "Open Attacking", + "Gahz'ridian (DND)", "Blasting", "PvP Open", "PvP Close", "Fishing (DND)", + "Inscription", "Open From Vehicle" + ), + 'stealthType' => ["General", "Trap"], + 'invisibilityType' => ["General", 3 => "Trap", 6 => "Drunk"] + ), + 'item' => array( + 'notFound' => "This item doesn't exist.", + 'armor' => "%s Armor", + 'block' => "%s Block", + 'charges' => "Charges", + 'locked' => "Locked", + 'ratingString' => "%s @ L%s", + 'heroic' => "Heroic", + 'unique' => "Unique", + 'uniqueEquipped'=> "Unique-Equipped", + 'startQuest' => "This Item Begins a Quest", + 'bagSlotString' => "%d Slot %s", + 'dps' => "damage per second", + 'dps2' => "damage per second", + 'addsDps' => "Adds", + 'fap' => "Feral Attack Power", + 'durability' => "Durability", + 'realTime' => "real time", + 'conjured' => "Conjured Item", + 'damagePhys' => "%s Damage", + 'damageMagic' => "%s %s Damage", + 'speed' => "Speed", + 'sellPrice' => "Sell Price", + 'itemLevel' => "Item Level", + 'randEnchant' => "<Random enchantment>", + 'readClick' => "<Right Click To Read>", + 'openClick' => "<Right Click To Open>", + 'set' => "Set", + 'partyLoot' => "Party loot", + 'smartLoot' => "Smart loot", + 'indestructible'=> "Cannot be destroyed", + 'deprecated' => "Deprecated", + 'useInShape' => "Usable when shapeshifted", + 'useInArena' => "Usable in arenas", + 'refundable' => "Refundable", + 'noNeedRoll' => "Cannot roll Need", + 'atKeyring' => "Can be placed in the keyring", + 'worth' => "Worth", + 'consumable' => "Consumable", + 'nonConsumable' => "Non-consumable", + 'accountWide' => "Account-wide", + 'millable' => "Millable", + 'noEquipCD' => "No equip cooldown", + 'prospectable' => "Prospectable", + 'disenchantable'=> "Disenchantable", + 'cantDisenchant'=> "Cannot be disenchanted", + 'repairCost' => "Repair cost", + 'tool' => "Tool", + 'cost' => "Cost", + 'content' => "Content", + '_transfer' => 'This item will be converted to %s if you transfer to %s.', + '_unavailable' => "This item is not available to players.", + '_rndEnchants' => "Random Enchantments", + '_chance' => "(%s%% chance)", + 'slot' => "Slot", + '_quality' => "Quality", + 'usableBy' => "Usable by", + 'buyout' => "Buyout price", + 'each' => "each", + 'tabOther' => "Other", + 'gems' => "Gems", + 'socketBonus' => "Socket Bonus", + 'socket' => array( + "Meta Socket", "Red Socket", "Yellow Socket", "Blue Socket", -1 => "Prismatic Socket" + ), + 'gemColors' => array( + "meta", "red", "yellow", "blue" + ), + 'gemConditions' => array( // ENCHANT_CONDITION_* in GlobalStrings.lua + 2 => ["less than %d %s gem", "less than %d %s gems"], + 3 => "more %s gems than %s gems", + 5 => ["at least %d %s gem", "at least %d %s gems"] + ), + 'reqRating' => array( // ITEM_REQ_ARENA_RATING* + "Requires personal and team arena rating of %d", + "Requires personal and team arena rating of %d
in 3v3 or 5v5 brackets", + "Requires personal and team arena rating of %d
in 5v5 brackets" + ), + 'quality' => array( + "Poor", "Common", "Uncommon", "Rare", + "Epic", "Legendary", "Artifact", "Heirloom" + ), + 'trigger' => array( + "Use: ", "Equip: ", "Chance on hit: ", "", "", + "", "" + ), + 'bonding' => array( + "Binds to account", "Binds when picked up", "Binds when equipped", + "Binds when used", "Quest Item", "Quest Item" + ), + "bagFamily" => array( + "Bag", "Quiver", "Ammo Pouch", "Soul Bag", "Leatherworking Bag", + "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", /*Shield*/ + "Ranged", "Back", "Two-Hand", "Bag", "Tabard", + null, /*Robe*/ "Main Hand", "Off Hand", "Held In Off-Hand", "Projectile", + "Thrown", null, /*Ranged2*/ "Quiver", "Relic" + ), + 'armorSubClass' => array( + "Miscellaneous", "Cloth", "Leather", "Mail", "Plate", + null, "Shield", "Libram", "Idol", "Totem", + "Sigil" + ), + 'weaponSubClass'=> array( + "Axe", "Axe", "Bow", "Gun", "Mace", + "Mace", "Polearm", "Sword", "Sword", null, + "Staff", null, null, "Fist Weapon", "Miscellaneous", + "Dagger", "Thrown", null, "Crossbow", "Wand", + "Fishing Pole" + ), + 'projectileSubClass' => array( + null, null, "Arrow", "Bullet", null + ), + 'elixirType' => [null, "Battle", "Guardian"], + 'cat' => array( // ordered by content first, then alphabeticaly + 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( + -3 => "Item Enhancements (Temporary)", 6 => "Item Enhancements (Permanent)", 2 => ["Elixirs", [1 => "Battle Elixirs", 2 => "Guardian Elixirs"]], + 1 => "Potions", 4 => "Scrolls", 7 => "Bandages", 0 => "Consumables", 3 => "Flasks", 5 => "Food & Drinks", + 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.", + null, + "Agility", + "Strength", + "Intellect", + "Spirit", + "Stamina", + null, null, null, null, + "Improves defense rating by %d.", + "Increases your dodge rating by %d.", + "Increases your parry rating by %d.", + "Increases your shield block rating by %d.", + "Improves melee hit rating by %d.", + "Improves ranged hit rating by %d.", + "Improves spell hit rating by %d.", + "Improves melee critical strike rating by %d.", + "Improves ranged critical strike rating by %d.", + "Improves spell critical strike rating by %d.", + "Improves melee hit avoidance rating by %d.", + "Improves ranged hit avoidance rating by %d.", + "Improves spell hit avoidance rating by %d.", + "Improves melee critical avoidance rating by %d.", + "Improves ranged critical avoidance rating by %d.", + "Improves spell critical avoidance rating by %d.", + "Improves melee haste rating by %d.", + "Improves ranged haste rating by %d.", + "Improves spell haste rating by %d.", + "Improves hit rating by %d.", + "Improves critical strike rating by %d.", + "Improves hit avoidance rating by %d.", + "Improves critical avoidance rating by %d.", + "Increases your resilience rating by %d.", + "Increases your haste rating by %d.", + "Improves expertise rating by %d.", + "Improves attack power by %d.", + "Improves ranged attack power by %d.", + "Improves attack power by %d in Cat, Bear, Dire Bear, and Moonkin forms only.", + "Improves damage done by magical spells and effects by up to %d.", + "Improves healing done by magical spells and effects by up to %d.", + "Restores %d mana per 5 sec.", + "Increases your armor penetration rating by %d.", + "Improves spell power by %d.", + "Restores %d health per 5 sec.", + "Improves spell penetration by %d.", + "Increases the block value of your shield by %d.", + "Unknown Bonus #%d (%d)", + ) + ) +); + +?> diff --git a/pages/emote.php b/pages/emote.php index 9490f7d6..28a23284 100644 --- a/pages/emote.php +++ b/pages/emote.php @@ -1,106 +1,106 @@ -typeId = intVal($id); - - $this->subject = new EmoteList(array(['id', $this->typeId])); - if ($this->subject->error) - $this->notFound(Util::ucFirst(Lang::game('emote')), Lang::emote('notFound')); - - $this->name = Util::ucFirst($this->subject->getField('cmd')); - } - - protected function generatePath() { } - - protected function generateTitle() - { - array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('emote'))); - } - - protected function generateContent() - { - /***********/ - /* Infobox */ - /***********/ - - $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); - - // has Animation - if ($this->subject->getField('isAnimated')) - $infobox[] = Lang::emote('isAnimated'); - - /****************/ - /* Main Content */ - /****************/ - - $text = ''; - if ($aliasses = DB::Aowow()->selectCol('SELECT command FROM ?_emotes_aliasses WHERE id = ?d AND locales & ?d', $this->typeId, 1 << User::$localeId)) - { - $text .= '[h3]'.Lang::emote('aliases').'[/h3][ul]'; - foreach ($aliasses as $a) - $text .= '[li]/'.$a.'[/li]'; - - $text .= '[/ul][br][br]'; - } - - $texts = []; - if ($_ = $this->subject->getField('self', true)) - $texts[Lang::emote('self')] = $_; - - if ($_ = $this->subject->getField('target', true)) - $texts[Lang::emote('target')] = $_; - - if ($_ = $this->subject->getField('noTarget', true)) - $texts[Lang::emote('noTarget')] = $_; - - if (!$texts) - $text .= '[div][i class=q0]'.Lang::emote('noText').'[/i][/div]'; - else - foreach ($texts as $h => $t) - $text .= '[pad][b]'.$h.'[/b][ul][li][span class=s4]'.preg_replace('/%\d?\$?s/', '<'.Util::ucFirst(Lang::main('name')).'>', $t).'[/span][/li][/ul]'; - - $this->extraText = $text; - $this->infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : null; - $this->redButtons = array( - BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId], - BUTTON_WOWHEAD => false - ); - - /**************/ - /* Extra Tabs */ - /**************/ - - // tab: achievement - $condition = array( - ['ac.type', ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE], - ['ac.value1', $this->typeId], - ); - $acv = new AchievementList($condition); - - $this->lvTabs[] = ['achievement', ['data' => array_values($acv->getListviewData())]]; - - $this->extendGlobalData($acv->getJsGlobals()); - } -} - -?> +typeId = intVal($id); + + $this->subject = new EmoteList(array(['id', $this->typeId])); + if ($this->subject->error) + $this->notFound(Util::ucFirst(Lang::game('emote')), Lang::emote('notFound')); + + $this->name = Util::ucFirst($this->subject->getField('cmd')); + } + + protected function generatePath() { } + + protected function generateTitle() + { + array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('emote'))); + } + + protected function generateContent() + { + /***********/ + /* Infobox */ + /***********/ + + $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); + + // has Animation + if ($this->subject->getField('isAnimated')) + $infobox[] = Lang::emote('isAnimated'); + + /****************/ + /* Main Content */ + /****************/ + + $text = ''; + if ($aliasses = DB::Aowow()->selectCol('SELECT command FROM ?_emotes_aliasses WHERE id = ?d AND locales & ?d', $this->typeId, 1 << User::$localeId)) + { + $text .= '[h3]'.Lang::emote('aliases').'[/h3][ul]'; + foreach ($aliasses as $a) + $text .= '[li]/'.$a.'[/li]'; + + $text .= '[/ul][br][br]'; + } + + $texts = []; + if ($_ = $this->subject->getField('self', true)) + $texts[Lang::emote('self')] = $_; + + if ($_ = $this->subject->getField('target', true)) + $texts[Lang::emote('target')] = $_; + + if ($_ = $this->subject->getField('noTarget', true)) + $texts[Lang::emote('noTarget')] = $_; + + if (!$texts) + $text .= '[div][i class=q0]'.Lang::emote('noText').'[/i][/div]'; + else + foreach ($texts as $h => $t) + $text .= '[pad][b]'.$h.'[/b][ul][li][span class=s4]'.preg_replace('/%\d?\$?s/', '<'.Util::ucFirst(Lang::main('name')).'>', $t).'[/span][/li][/ul]'; + + $this->extraText = $text; + $this->infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : null; + $this->redButtons = array( + BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId], + BUTTON_WOWHEAD => false + ); + + /**************/ + /* Extra Tabs */ + /**************/ + + // tab: achievement + $condition = array( + ['ac.type', ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE], + ['ac.value1', $this->typeId], + ); + $acv = new AchievementList($condition); + + $this->lvTabs[] = ['achievement', ['data' => array_values($acv->getListviewData())]]; + + $this->extendGlobalData($acv->getJsGlobals()); + } +} + +?> diff --git a/pages/emotes.php b/pages/emotes.php index 68a3a37a..753dcd62 100644 --- a/pages/emotes.php +++ b/pages/emotes.php @@ -1,44 +1,44 @@ -name = Util::ucFirst(Lang::game('emotes')); - } - - protected function generateContent() - { - $tabData = array( - 'data' => array_values((new EmoteList())->getListviewData()), - 'name' => Util::ucFirst(Lang::game('emotes')) - ); - - $this->lvTabs[] = ['emote', $tabData, 'emote']; - } - - protected function generateTitle() - { - array_unshift($this->title, $this->name); - } - - protected function generatePath() { } -} - -?> +name = Util::ucFirst(Lang::game('emotes')); + } + + protected function generateContent() + { + $tabData = array( + 'data' => array_values((new EmoteList())->getListviewData()), + 'name' => Util::ucFirst(Lang::game('emotes')) + ); + + $this->lvTabs[] = ['emote', $tabData, 'emote']; + } + + protected function generateTitle() + { + array_unshift($this->title, $this->name); + } + + protected function generatePath() { } +} + +?> diff --git a/pages/enchantment.php b/pages/enchantment.php index 56a182dd..ce4bbb3d 100644 --- a/pages/enchantment.php +++ b/pages/enchantment.php @@ -1,324 +1,324 @@ -typeId = intVal($id); - - $this->subject = new EnchantmentList(array(['id', $this->typeId])); - if ($this->subject->error) - $this->notFound(Util::ucFirst(Lang::game('enchantment')), Lang::enchantment('notFound')); - - $this->extendGlobalData($this->subject->getJSGlobals()); - - $this->name = Util::ucFirst($this->subject->getField('name', true)); - } - - private function getDistinctType() - { - $type = 0; - for ($i = 1; $i < 4; $i++) - { - if ($_ = $this->subject->getField('type'.$i)) - { - if ($type) // already set - return 0; - else - $type = $_; - } - } - - return $type; - } - - protected function generateContent() - { - /***********/ - /* Infobox */ - /***********/ - - $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); - - // reqLevel - if ($_ = $this->subject->getField('requiredLevel')) - $infobox[] = sprintf(Lang::game('reqLevel'), $_); - - // reqskill - if ($_ = $this->subject->getField('skillLine')) - { - $this->extendGlobalIds(TYPE_SKILL, $_); - - $foo = sprintf(Lang::game('requires'), ' [skill='.$_.']'); - if ($_ = $this->subject->getField('skillLevel')) - $foo .= ' ('.$_.')'; - - $infobox[] = $foo; - } - - - /****************/ - /* Main Content */ - /****************/ - - - $this->infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : null; - $this->redButtons = array( - BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId], - BUTTON_WOWHEAD => false - ); - - $this->effects = []; - // 3 effects - for ($i = 1; $i < 4; $i++) - { - $_ty = $this->subject->getField('type'.$i); - $_qty = $this->subject->getField('amount'.$i); - $_obj = $this->subject->getField('object'.$i); - - switch ($_ty) - { - case 1: - case 3: - case 7: - $sArr = $this->subject->getField('spells')[$i]; - $spl = $this->subject->getRelSpell($sArr[0]); - $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: '.$_ty, Lang::item('trigger', $sArr[1])) : Lang::item('trigger', $sArr[1]); - $this->effects[$i]['proc'] = $sArr[3]; - $this->effects[$i]['value'] = $_qty ?: null; - $this->effects[$i]['icon'] = array( - 'name' => !$spl ? Util::ucFirst(Lang::game('spell')).' #'.$sArr[0] : Util::localizedString($spl, 'name'), - 'id' => $sArr[0], - 'count' => $sArr[2] - ); - break; - case 5: - if ($_obj < 2) // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. - $_obj++; // 0 is weaponDmg .. ehh .. i messed up somewhere - - $this->effects[$i]['tip'] = [$_obj, Util::$itemMods[$_obj]]; - // DO NOT BREAK! - case 2: - case 6: - case 8: - case 4: - $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: '.$_ty, Lang::enchantment('types', $_ty)) : Lang::enchantment('types', $_ty); - $this->effects[$i]['value'] = $_qty; - if ($_ty == 4) - $this->effects[$i]['name'] .= Lang::main('colon').'('.(User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Object: '.$_obj, Lang::getMagicSchools(1 << $_obj)) : Lang::getMagicSchools(1 << $_obj)).')'; - } - } - - // activation conditions - if ($_ = $this->subject->getField('conditionId')) - { - $x = ''; - - if ($gemCnd = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantmentcondition WHERE id = ?d', $_)) - { - for ($i = 1; $i < 6; $i++) - { - if (!$gemCnd['color'.$i]) - continue; - - $fiColors = function ($idx) - { - $foo = ''; - switch ($idx) - { - case 2: $foo = '0:3:5'; break; // red - case 3: $foo = '2:4:5'; break; // yellow - case 4: $foo = '1:3:4'; break; // blue - } - - return $foo; - }; - - $bLink = $gemCnd['color'.$i] ? ''.Lang::item('gemColors', $gemCnd['color'.$i] - 1).'' : ''; - $cLink = $gemCnd['cmpColor'.$i] ? ''.Lang::item('gemColors', $gemCnd['cmpColor'.$i] - 1).'' : ''; - - switch ($gemCnd['comparator'.$i]) - { - case 2: // requires less than ( || ) gems - case 5: // requires at least than ( || ) gems - $sp = (int)$gemCnd['value'.$i] > 1; - $x .= ''.Lang::achievement('reqNumCrt').' '.sprintf(Lang::item('gemConditions', $gemCnd['comparator'.$i], $sp), $gemCnd['value'.$i], $bLink).'
'; - break; - case 3: // requires more than ( || ) gems - $link = ''.Lang::item('gemColors', $gemCnd['cmpColor'.$i] - 1).''; - $x .= ''.Lang::achievement('reqNumCrt').' '.sprintf(Lang::item('gemConditions', 3), $bLink, $cLink).'
'; - break; - } - } - } - - $this->activateCondition = $x; - } - - /**************/ - /* Extra Tabs */ - /**************/ - - // used by gem - $gemList = new ItemList(array(['gemEnchantmentId', $this->typeId])); - if (!$gemList->error) - { - $this->lvTabs[] = ['item', array( - 'data' => array_values($gemList->getListviewData()), - 'name' => '$LANG.tab_usedby + \' \' + LANG.gems', - 'id' => 'used-by-gem', - )]; - - $this->extendGlobalData($gemList->getJsGlobals()); - } - - // used by socket bonus - $socketsList = new ItemList(array(['socketBonus', $this->typeId])); - if (!$socketsList->error) - { - $this->lvTabs[] = ['item', array( - 'data' => array_values($socketsList->getListviewData()), - 'name' => '$LANG.tab_usedby + \' \' + \''.Lang::item('socketBonus').'\'', - 'id' => 'used-by-socketbonus', - )]; - - $this->extendGlobalData($socketsList->getJsGlobals()); - } - - // used by spell - // used by useItem - $cnd = array( - 'OR', - ['AND', ['effect1Id', [53, 54, 156, 92]], ['effect1MiscValue', $this->typeId]], - ['AND', ['effect2Id', [53, 54, 156, 92]], ['effect2MiscValue', $this->typeId]], - ['AND', ['effect3Id', [53, 54, 156, 92]], ['effect3MiscValue', $this->typeId]], - ); - $spellList = new SpellList($cnd); - if (!$spellList->error) - { - $spellData = $spellList->getListviewData(); - $this->extendGlobalData($spellList->getJsGlobals()); - - $spellIds = $spellList->getFoundIDs(); - $conditions = array( - 'OR', // [use, useUndelayed] - ['AND', ['spellTrigger1', [0, 5]], ['spellId1', $spellIds]], - ['AND', ['spellTrigger2', [0, 5]], ['spellId2', $spellIds]], - ['AND', ['spellTrigger3', [0, 5]], ['spellId3', $spellIds]], - ['AND', ['spellTrigger4', [0, 5]], ['spellId4', $spellIds]], - ['AND', ['spellTrigger5', [0, 5]], ['spellId5', $spellIds]] - ); - - $ubItems = new ItemList($conditions); - if (!$ubItems->error) - { - $this->lvTabs[] = ['item', array( - 'data' => array_values($ubItems->getListviewData()), - 'name' => '$LANG.tab_usedby + \' \' + LANG.types[3][0]', - 'id' => 'used-by-item', - )]; - - $this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF)); - } - - // remove found spells if they are used by an item - if (!$ubItems->error) - { - foreach ($spellList->iterate() as $sId => $__) - { - // if Perm. Enchantment has a createItem its a Scroll of Enchantment (display both) - for ($i = 1; $i < 4; $i++) - if ($spellList->getField('effect'.$i.'Id') == 53 && $spellList->getField('effect'.$i.'CreateItemId')) - continue 2; - - foreach ($ubItems->iterate() as $__) - { - for ($i = 1; $i < 6; $i++) - { - if ($ubItems->getField('spellId'.$i) == $sId) - { - unset($spellData[$sId]); - break 2; - } - } - } - } - } - - $this->lvTabs[] = ['spell', array( - 'data' => array_values($spellData), - 'name' => '$LANG.tab_usedby + \' \' + LANG.types[6][0]', - 'id' => 'used-by-spell', - )]; - } - - // used by randomAttrItem - $ire = DB::Aowow()->select( - 'SELECT *, ABS(id) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE enchantId1 = ?d OR enchantId2 = ?d OR enchantId3 = ?d OR enchantId4 = ?d OR enchantId5 = ?d', - $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId - ); - if ($ire) - { - if ($iet = DB::World()->select('SELECT entry AS ARRAY_KEY, ench, chance FROM item_enchantment_template WHERE ench IN (?a)', array_keys($ire))) - { - $randIds = []; // transform back to signed format - foreach ($iet as $tplId => $data) - $randIds[$ire[$data['ench']]['id'] > 0 ? $tplId : -$tplId] = $ire[$data['ench']]['id']; - - $randItems = new ItemList(array(CFG_SQL_LIMIT_NONE, ['randomEnchant', array_keys($randIds)])); - if (!$randItems->error) - { - $data = $randItems->getListviewData(); - foreach ($randItems->iterate() as $iId => $__) - { - $re = $randItems->getField('randomEnchant'); - - $data[$iId]['percent'] = $iet[abs($re)]['chance']; - $data[$iId]['count'] = 1; // expected by js or the pct-col becomes unsortable - $data[$iId]['rel'] = 'rand='.$ire[$iet[abs($re)]['ench']]['id']; - $data[$iId]['name'] .= ' '.Util::localizedString($ire[$iet[abs($re)]['ench']], 'name'); - } - - $this->lvTabs[] = ['item', array( - 'data' => array_values($data), - 'id' => 'used-by-rand', - 'name' => '$LANG.tab_usedby + \' \' + \''.Lang::item('_rndEnchants').'\'', - 'extraCols' => ['$Listview.extraCols.percent'] - )]; - - $this->extendGlobalData($randItems->getJSGlobals(GLOBALINFO_SELF)); - } - } - } - } - - protected function generateTitle() - { - array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('enchantment'))); - } - - protected function generatePath() - { - if ($_ = $this->getDistinctType()) - $this->path[] = $_; - } -} - -?> +typeId = intVal($id); + + $this->subject = new EnchantmentList(array(['id', $this->typeId])); + if ($this->subject->error) + $this->notFound(Util::ucFirst(Lang::game('enchantment')), Lang::enchantment('notFound')); + + $this->extendGlobalData($this->subject->getJSGlobals()); + + $this->name = Util::ucFirst($this->subject->getField('name', true)); + } + + private function getDistinctType() + { + $type = 0; + for ($i = 1; $i < 4; $i++) + { + if ($_ = $this->subject->getField('type'.$i)) + { + if ($type) // already set + return 0; + else + $type = $_; + } + } + + return $type; + } + + protected function generateContent() + { + /***********/ + /* Infobox */ + /***********/ + + $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); + + // reqLevel + if ($_ = $this->subject->getField('requiredLevel')) + $infobox[] = sprintf(Lang::game('reqLevel'), $_); + + // reqskill + if ($_ = $this->subject->getField('skillLine')) + { + $this->extendGlobalIds(TYPE_SKILL, $_); + + $foo = sprintf(Lang::game('requires'), ' [skill='.$_.']'); + if ($_ = $this->subject->getField('skillLevel')) + $foo .= ' ('.$_.')'; + + $infobox[] = $foo; + } + + + /****************/ + /* Main Content */ + /****************/ + + + $this->infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : null; + $this->redButtons = array( + BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId], + BUTTON_WOWHEAD => false + ); + + $this->effects = []; + // 3 effects + for ($i = 1; $i < 4; $i++) + { + $_ty = $this->subject->getField('type'.$i); + $_qty = $this->subject->getField('amount'.$i); + $_obj = $this->subject->getField('object'.$i); + + switch ($_ty) + { + case 1: + case 3: + case 7: + $sArr = $this->subject->getField('spells')[$i]; + $spl = $this->subject->getRelSpell($sArr[0]); + $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: '.$_ty, Lang::item('trigger', $sArr[1])) : Lang::item('trigger', $sArr[1]); + $this->effects[$i]['proc'] = $sArr[3]; + $this->effects[$i]['value'] = $_qty ?: null; + $this->effects[$i]['icon'] = array( + 'name' => !$spl ? Util::ucFirst(Lang::game('spell')).' #'.$sArr[0] : Util::localizedString($spl, 'name'), + 'id' => $sArr[0], + 'count' => $sArr[2] + ); + break; + case 5: + if ($_obj < 2) // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. + $_obj++; // 0 is weaponDmg .. ehh .. i messed up somewhere + + $this->effects[$i]['tip'] = [$_obj, Util::$itemMods[$_obj]]; + // DO NOT BREAK! + case 2: + case 6: + case 8: + case 4: + $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: '.$_ty, Lang::enchantment('types', $_ty)) : Lang::enchantment('types', $_ty); + $this->effects[$i]['value'] = $_qty; + if ($_ty == 4) + $this->effects[$i]['name'] .= Lang::main('colon').'('.(User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Object: '.$_obj, Lang::getMagicSchools(1 << $_obj)) : Lang::getMagicSchools(1 << $_obj)).')'; + } + } + + // activation conditions + if ($_ = $this->subject->getField('conditionId')) + { + $x = ''; + + if ($gemCnd = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantmentcondition WHERE id = ?d', $_)) + { + for ($i = 1; $i < 6; $i++) + { + if (!$gemCnd['color'.$i]) + continue; + + $fiColors = function ($idx) + { + $foo = ''; + switch ($idx) + { + case 2: $foo = '0:3:5'; break; // red + case 3: $foo = '2:4:5'; break; // yellow + case 4: $foo = '1:3:4'; break; // blue + } + + return $foo; + }; + + $bLink = $gemCnd['color'.$i] ? ''.Lang::item('gemColors', $gemCnd['color'.$i] - 1).'' : ''; + $cLink = $gemCnd['cmpColor'.$i] ? ''.Lang::item('gemColors', $gemCnd['cmpColor'.$i] - 1).'' : ''; + + switch ($gemCnd['comparator'.$i]) + { + case 2: // requires less than ( || ) gems + case 5: // requires at least than ( || ) gems + $sp = (int)$gemCnd['value'.$i] > 1; + $x .= ''.Lang::achievement('reqNumCrt').' '.sprintf(Lang::item('gemConditions', $gemCnd['comparator'.$i], $sp), $gemCnd['value'.$i], $bLink).'
'; + break; + case 3: // requires more than ( || ) gems + $link = ''.Lang::item('gemColors', $gemCnd['cmpColor'.$i] - 1).''; + $x .= ''.Lang::achievement('reqNumCrt').' '.sprintf(Lang::item('gemConditions', 3), $bLink, $cLink).'
'; + break; + } + } + } + + $this->activateCondition = $x; + } + + /**************/ + /* Extra Tabs */ + /**************/ + + // used by gem + $gemList = new ItemList(array(['gemEnchantmentId', $this->typeId])); + if (!$gemList->error) + { + $this->lvTabs[] = ['item', array( + 'data' => array_values($gemList->getListviewData()), + 'name' => '$LANG.tab_usedby + \' \' + LANG.gems', + 'id' => 'used-by-gem', + )]; + + $this->extendGlobalData($gemList->getJsGlobals()); + } + + // used by socket bonus + $socketsList = new ItemList(array(['socketBonus', $this->typeId])); + if (!$socketsList->error) + { + $this->lvTabs[] = ['item', array( + 'data' => array_values($socketsList->getListviewData()), + 'name' => '$LANG.tab_usedby + \' \' + \''.Lang::item('socketBonus').'\'', + 'id' => 'used-by-socketbonus', + )]; + + $this->extendGlobalData($socketsList->getJsGlobals()); + } + + // used by spell + // used by useItem + $cnd = array( + 'OR', + ['AND', ['effect1Id', [53, 54, 156, 92]], ['effect1MiscValue', $this->typeId]], + ['AND', ['effect2Id', [53, 54, 156, 92]], ['effect2MiscValue', $this->typeId]], + ['AND', ['effect3Id', [53, 54, 156, 92]], ['effect3MiscValue', $this->typeId]], + ); + $spellList = new SpellList($cnd); + if (!$spellList->error) + { + $spellData = $spellList->getListviewData(); + $this->extendGlobalData($spellList->getJsGlobals()); + + $spellIds = $spellList->getFoundIDs(); + $conditions = array( + 'OR', // [use, useUndelayed] + ['AND', ['spellTrigger1', [0, 5]], ['spellId1', $spellIds]], + ['AND', ['spellTrigger2', [0, 5]], ['spellId2', $spellIds]], + ['AND', ['spellTrigger3', [0, 5]], ['spellId3', $spellIds]], + ['AND', ['spellTrigger4', [0, 5]], ['spellId4', $spellIds]], + ['AND', ['spellTrigger5', [0, 5]], ['spellId5', $spellIds]] + ); + + $ubItems = new ItemList($conditions); + if (!$ubItems->error) + { + $this->lvTabs[] = ['item', array( + 'data' => array_values($ubItems->getListviewData()), + 'name' => '$LANG.tab_usedby + \' \' + LANG.types[3][0]', + 'id' => 'used-by-item', + )]; + + $this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF)); + } + + // remove found spells if they are used by an item + if (!$ubItems->error) + { + foreach ($spellList->iterate() as $sId => $__) + { + // if Perm. Enchantment has a createItem its a Scroll of Enchantment (display both) + for ($i = 1; $i < 4; $i++) + if ($spellList->getField('effect'.$i.'Id') == 53 && $spellList->getField('effect'.$i.'CreateItemId')) + continue 2; + + foreach ($ubItems->iterate() as $__) + { + for ($i = 1; $i < 6; $i++) + { + if ($ubItems->getField('spellId'.$i) == $sId) + { + unset($spellData[$sId]); + break 2; + } + } + } + } + } + + $this->lvTabs[] = ['spell', array( + 'data' => array_values($spellData), + 'name' => '$LANG.tab_usedby + \' \' + LANG.types[6][0]', + 'id' => 'used-by-spell', + )]; + } + + // used by randomAttrItem + $ire = DB::Aowow()->select( + 'SELECT *, ABS(id) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE enchantId1 = ?d OR enchantId2 = ?d OR enchantId3 = ?d OR enchantId4 = ?d OR enchantId5 = ?d', + $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId + ); + if ($ire) + { + if ($iet = DB::World()->select('SELECT entry AS ARRAY_KEY, ench, chance FROM item_enchantment_template WHERE ench IN (?a)', array_keys($ire))) + { + $randIds = []; // transform back to signed format + foreach ($iet as $tplId => $data) + $randIds[$ire[$data['ench']]['id'] > 0 ? $tplId : -$tplId] = $ire[$data['ench']]['id']; + + $randItems = new ItemList(array(CFG_SQL_LIMIT_NONE, ['randomEnchant', array_keys($randIds)])); + if (!$randItems->error) + { + $data = $randItems->getListviewData(); + foreach ($randItems->iterate() as $iId => $__) + { + $re = $randItems->getField('randomEnchant'); + + $data[$iId]['percent'] = $iet[abs($re)]['chance']; + $data[$iId]['count'] = 1; // expected by js or the pct-col becomes unsortable + $data[$iId]['rel'] = 'rand='.$ire[$iet[abs($re)]['ench']]['id']; + $data[$iId]['name'] .= ' '.Util::localizedString($ire[$iet[abs($re)]['ench']], 'name'); + } + + $this->lvTabs[] = ['item', array( + 'data' => array_values($data), + 'id' => 'used-by-rand', + 'name' => '$LANG.tab_usedby + \' \' + \''.Lang::item('_rndEnchants').'\'', + 'extraCols' => ['$Listview.extraCols.percent'] + )]; + + $this->extendGlobalData($randItems->getJSGlobals(GLOBALINFO_SELF)); + } + } + } + } + + protected function generateTitle() + { + array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('enchantment'))); + } + + protected function generatePath() + { + if ($_ = $this->getDistinctType()) + $this->path[] = $_; + } +} + +?> diff --git a/pages/enchantments.php b/pages/enchantments.php index 1052eee8..44a73f75 100644 --- a/pages/enchantments.php +++ b/pages/enchantments.php @@ -1,105 +1,105 @@ -filterObj = new EnchantmentListFilter(); - $this->getCategoryFromUrl($pageParam);; - - parent::__construct($pageCall, $pageParam); - - $this->name = Util::ucFirst(Lang::game('enchantments')); - $this->subCat = $pageParam !== null ? '='.$pageParam : ''; - } - - protected function generateContent() - { - $tabData = array( - 'data' => [], - 'name' => Util::ucFirst(Lang::game('enchantments')) - ); - - $conditions = []; - - if (!User::isInGroup(U_GROUP_EMPLOYEE)) - $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; - - if ($_ = $this->filterObj->getConditions()) - $conditions[] = $_; - - $ench = new EnchantmentList($conditions); - - $tabData['data'] = array_values($ench->getListviewData()); - $this->extendGlobalData($ench->getJSGlobals()); - - // recreate form selection - $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter); - $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL; - $this->filter['fi'] = $this->filterObj->getForm(); - - $xCols = $this->filterObj->getForm('extraCols', true); - foreach (Util::$itemFilter as $fiId => $str) - if (array_column($tabData['data'], $str)) - $xCols[] = $fiId; - - if (array_column($tabData['data'], 'dmg')) - $xCols[] = 34; - - if ($xCols) - $this->filter['fi']['extraCols'] = "fi_extraCols = ".Util::toJSON(array_values(array_unique($xCols))).";"; - - if (!empty($this->filter['fi']['extraCols'])) - $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)'; - - if ($ench->getMatches() > CFG_SQL_LIMIT_DEFAULT) - { - $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_enchantmentsfound', $ench->getMatches(), CFG_SQL_LIMIT_DEFAULT); - $tabData['_truncated'] = 1; - } - - if (array_filter(array_column($tabData['data'], 'spells'))) - $tabData['visibleCols'] = ['trigger']; - - if (!$ench->hasSetFields(['skillLine'])) - $tabData['hiddenCols'] = ['skill']; - - if ($this->filterObj->error) - $tabData['_errors'] = '$1'; - - $this->lvTabs[] = ['enchantment', $tabData, 'enchantment']; - } - - protected function generateTitle() - { - $form = $this->filterObj->getForm('form'); - if (!empty($form['ty']) && intVal($form['ty']) && $form['ty'] > 0 && $form['ty'] < 9) - array_unshift($this->title, Lang::enchantment('types', $form['ty'])); - - array_unshift($this->title, $this->name); - } - - protected function generatePath() - { - $form = $this->filterObj->getForm('form'); - if (isset($form['ty']) && !is_array($form['ty'])) - $this->path[] = $form['ty']; - } -} - -?> +filterObj = new EnchantmentListFilter(); + $this->getCategoryFromUrl($pageParam);; + + parent::__construct($pageCall, $pageParam); + + $this->name = Util::ucFirst(Lang::game('enchantments')); + $this->subCat = $pageParam !== null ? '='.$pageParam : ''; + } + + protected function generateContent() + { + $tabData = array( + 'data' => [], + 'name' => Util::ucFirst(Lang::game('enchantments')) + ); + + $conditions = []; + + if (!User::isInGroup(U_GROUP_EMPLOYEE)) + $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; + + if ($_ = $this->filterObj->getConditions()) + $conditions[] = $_; + + $ench = new EnchantmentList($conditions); + + $tabData['data'] = array_values($ench->getListviewData()); + $this->extendGlobalData($ench->getJSGlobals()); + + // recreate form selection + $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter); + $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL; + $this->filter['fi'] = $this->filterObj->getForm(); + + $xCols = $this->filterObj->getForm('extraCols', true); + foreach (Util::$itemFilter as $fiId => $str) + if (array_column($tabData['data'], $str)) + $xCols[] = $fiId; + + if (array_column($tabData['data'], 'dmg')) + $xCols[] = 34; + + if ($xCols) + $this->filter['fi']['extraCols'] = "fi_extraCols = ".Util::toJSON(array_values(array_unique($xCols))).";"; + + if (!empty($this->filter['fi']['extraCols'])) + $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)'; + + if ($ench->getMatches() > CFG_SQL_LIMIT_DEFAULT) + { + $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_enchantmentsfound', $ench->getMatches(), CFG_SQL_LIMIT_DEFAULT); + $tabData['_truncated'] = 1; + } + + if (array_filter(array_column($tabData['data'], 'spells'))) + $tabData['visibleCols'] = ['trigger']; + + if (!$ench->hasSetFields(['skillLine'])) + $tabData['hiddenCols'] = ['skill']; + + if ($this->filterObj->error) + $tabData['_errors'] = '$1'; + + $this->lvTabs[] = ['enchantment', $tabData, 'enchantment']; + } + + protected function generateTitle() + { + $form = $this->filterObj->getForm('form'); + if (!empty($form['ty']) && intVal($form['ty']) && $form['ty'] > 0 && $form['ty'] < 9) + array_unshift($this->title, Lang::enchantment('types', $form['ty'])); + + array_unshift($this->title, $this->name); + } + + protected function generatePath() + { + $form = $this->filterObj->getForm('form'); + if (isset($form['ty']) && !is_array($form['ty'])) + $this->path[] = $form['ty']; + } +} + +?> diff --git a/pages/user.php b/pages/user.php index cb5b69c5..4650f12d 100644 --- a/pages/user.php +++ b/pages/user.php @@ -1,263 +1,263 @@ - 'Profiler.css']]; - protected $mode = CACHE_TYPE_NONE; - - protected $typeId = 0; - protected $pageName = ''; - - public function __construct($pageCall, $pageParam) - { - parent::__construct($pageCall, $pageParam); - - if ($pageParam) - { - // todo: check if account is disabled or something - if ($user = DB::Aowow()->selectRow('SELECT a.id, a.user, a.displayName, a.consecutiveVisits, a.userGroups, a.avatar, a.title, a.description, a.joinDate, a.prevLogin, IFNULL(SUM(ar.amount), 0) AS sumRep FROM ?_account a LEFT JOIN ?_account_reputation ar ON a.id = ar.userId WHERE a.user = ? GROUP BY a.id', $pageParam)) - $this->user = $user; - else - $this->notFound(sprintf(Lang::user('notFound'), $pageParam)); - } - else if (User::$id) - { - header('Location: ?user='.User::$displayName, true, 302); - die(); - } - else - $this->forwardToSignIn('user'); - } - - protected function generateContent() - { - /***********/ - /* Infobox */ - /***********/ - - $infobox = $contrib = $groups = []; - foreach (Lang::account('groups') as $idx => $key) - if ($idx >= 0 && $this->user['userGroups'] & (1 << $idx)) - $groups[] = (!fMod(count($groups) + 1, 3) ? '[br]' : null).Lang::account('groups', $idx); - - $infobox[] = Lang::user('joinDate'). Lang::main('colon').'[tooltip name=joinDate]'. date('l, G:i:s', $this->user['joinDate']). '[/tooltip][span class=tip tooltip=joinDate]'. date(Lang::main('dateFmtShort'), $this->user['joinDate']). '[/span]'; - $infobox[] = Lang::user('lastLogin').Lang::main('colon').'[tooltip name=lastLogin]'.date('l, G:i:s', $this->user['prevLogin']).'[/tooltip][span class=tip tooltip=lastLogin]'.date(Lang::main('dateFmtShort'), $this->user['prevLogin']).'[/span]'; - $infobox[] = Lang::user('userGroups').Lang::main('colon').($groups ? implode(', ', $groups) : Lang::account('groups', -1)); - $infobox[] = Lang::user('consecVisits').Lang::main('colon').$this->user['consecutiveVisits']; - $infobox[] = Util::ucFirst(Lang::main('siteRep')).Lang::main('colon').Lang::nf($this->user['sumRep']); - - // contrib -> [url=http://www.wowhead.com/client]Data uploads: n [small]([tooltip=tooltip_totaldatauploads]xx.y MB[/tooltip])[/small][/url] - - $co = DB::Aowow()->selectRow( - 'SELECT COUNT(DISTINCT c.id) AS sum, SUM(IFNULL(cr.value, 0)) AS nRates FROM ?_comments c LEFT JOIN ?_comments_rates cr ON cr.commentId = c.id AND cr.userId <> 0 WHERE c.replyTo = 0 AND c.userId = ?d', - $this->user['id'] - ); - if ($co['sum']) - $contrib[] = Lang::user('comments').Lang::main('colon').$co['sum'].($co['nRates'] ? ' [small]([tooltip=tooltip_totalratings]'.$co['nRates'].'[/tooltip])[/small]' : null); - - $ss = DB::Aowow()->selectRow('SELECT COUNT(*) AS sum, SUM(IF(status & ?d, 1, 0)) AS nSticky, SUM(IF(status & ?d, 0, 1)) AS nPending FROM ?_screenshots WHERE userIdOwner = ?d AND (status & ?d) = 0', - CC_FLAG_STICKY, - CC_FLAG_APPROVED, - $this->user['id'], - CC_FLAG_DELETED - ); - if ($ss['sum']) - { - $buff = []; - if ($ss['nSticky'] || $ss['nPending']) - { - if ($normal = ($ss['sum'] - $ss['nSticky'] - $ss['nPending'])) - $buff[] = '[tooltip=tooltip_normal]'.$normal.'[/tooltip]'; - - if ($ss['nSticky']) - $buff[] = '[tooltip=tooltip_sticky]'.$ss['nSticky'].'[/tooltip]'; - - if ($ss['nPending']) - $buff[] = '[tooltip=tooltip_pending]'.$ss['nPending'].'[/tooltip]'; - } - - $contrib[] = Lang::user('screenshots').Lang::main('colon').$ss['sum'].($buff ? ' [small]('.implode($buff, ' + ').')[/small]' : null); - } - - $vi = DB::Aowow()->selectRow('SELECT COUNT(id) AS sum, SUM(IF(status & ?d, 1, 0)) AS nSticky, SUM(IF(status & ?d, 0, 1)) AS nPending FROM ?_videos WHERE userIdOwner = ?d AND (status & ?d) = 0', - CC_FLAG_STICKY, - CC_FLAG_APPROVED, - $this->user['id'], - CC_FLAG_DELETED - ); - if ($vi['sum']) - { - $buff = []; - if ($vi['nSticky'] || $vi['nPending']) - { - if ($normal = ($vi['sum'] - $vi['nSticky'] - $vi['nPending'])) - $buff[] = '[tooltip=tooltip_normal]'.$normal.'[/tooltip]'; - - if ($vi['nSticky']) - $buff[] = '[tooltip=tooltip_sticky]'.$vi['nSticky'].'[/tooltip]'; - - if ($vi['nPending']) - $buff[] = '[tooltip=tooltip_pending]'.$vi['nPending'].'[/tooltip]'; - } - - $contrib[] = Lang::user('videos').Lang::main('colon').$vi['sum'].($buff ? ' [small]('.implode($buff, ' + ').')[/small]' : null); - } - - // contrib -> Forum posts: 5769 [small]([tooltip=topics]579[/tooltip] + [tooltip=replies]5190[/tooltip])[/small] - - $this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]'; - - if ($contrib) - $this->contributions = '[ul][li]'.implode('[/li][li]', $contrib).'[/li][/ul]'; - - - /****************/ - /* Main Content */ - /****************/ - - $this->name = $this->user['title'] ? $this->user['displayName'].' <'.$this->user['title'].'>' : sprintf(Lang::user('profileTitle'), $this->user['displayName']); - - /**************/ - /* Extra Tabs */ - /**************/ - - $this->lvTabs = []; - $this->forceTabs = true; - - // [unused] Site Achievements - - // Reputation changelog (params only for comment-events) - if ($repData = DB::Aowow()->select('SELECT action, amount, date AS \'when\', IF(action IN (3, 4, 5), sourceA, 0) AS param FROM ?_account_reputation WHERE userId = ?d', $this->user['id'])) - { - foreach ($repData as &$r) - $r['when'] = date(Util::$dateFormatInternal, $r['when']); - - $this->lvTabs[] = ['reputationhistory', ['data' => $repData]]; - } - - // Comments - if ($_ = CommunityContent::getCommentPreviews(['user' => $this->user['id'], 'replies' => false], $nFound)) - { - $tabData = array( - 'data' => $_, - 'hiddenCols' => ['author'], - 'onBeforeCreate' => '$Listview.funcBox.beforeUserComments', - '_totalCount' => $nFound - ); - - if ($nFound > CFG_SQL_LIMIT_DEFAULT) - { - $tabData['name'] = '$LANG.tab_latestcomments'; - $tabData['note'] = '$$WH.sprintf(LANG.lvnote_usercomments, '.$nFound.')'; - } - - $this->lvTabs[] = ['commentpreview', $tabData]; - } - - // Comment Replies - if ($_ = CommunityContent::getCommentPreviews(['user' => $this->user['id'], 'replies' => true], $nFound)) - { - $tabData = array( - 'data' => $_, - 'hiddenCols' => ['author'], - 'onBeforeCreate' => '$Listview.funcBox.beforeUserComments', - '_totalCount' => $nFound - ); - - if ($nFound > CFG_SQL_LIMIT_DEFAULT) - { - $tabData['name'] = '$LANG.tab_latestreplies'; - $tabData['note'] = '$$WH.sprintf(LANG.lvnote_userreplies, '.$nFound.')'; - } - - $this->lvTabs[] = ['replypreview', $tabData]; - } - - // Screenshots - if ($_ = CommunityContent::getScreenshots(-$this->user['id'], 0, $nFound)) - { - $tabData = array( - 'data' => $_, - '_totalCount' => $nFound - ); - - if ($nFound > CFG_SQL_LIMIT_DEFAULT) - { - $tabData['name'] = '$LANG.tab_latestscreenshots'; - $tabData['note'] = '$$WH.sprintf(LANG.lvnote_userscreenshots, '.$nFound.')'; - } - - $this->lvTabs[] = ['screenshot', $tabData]; - } - - // Videos - if ($_ = CommunityContent::getVideos(-$this->user['id'], 0, $nFound)) - { - $tabData = array( - 'data' => $_, - '_totalCount' => $nFound - ); - - if ($nFound > CFG_SQL_LIMIT_DEFAULT) - { - $tabData['name'] = '$LANG.tab_latestvideos'; - $tabData['note'] = '$$WH.sprintf(LANG.lvnote_uservideos, '.$nFound.')'; - } - - $this->lvTabs[] = ['video', $tabData]; - } - - // forum -> latest topics [unused] - - // forum -> latest replies [unused] - - // Characters [todo] - $this->user['characterData'] = []; - /* - us_addCharactersTab([ - { - id:763, - "name":"Lilywhite", - "achievementpoints":"0", - "guild":"whatever", - "guildrank":"0", - "realm":"draenor", - "realmname":"Draenor", - "battlegroup":"cyclone", - "battlegroupname":"Cyclone", - "region":"us", - "level":"10", - "race":"7", - "gender":"0", - "classs":"1", - "faction":"0", - "gearscore":"0", - "talenttree1":"0", - "talenttree2":"0", - "talenttree3":"0", - "talentspec":0, - "published":1, - "pinned":0 - } - ]); - */ - - // Profiles [todo] - $this->user['profileData'] = []; - } - - protected function generateTitle() - { - array_unshift($this->title, sprintf(Lang::user('profileTitle'), $this->user['displayName'])); - } - - protected function generatePath() { } -} - -?> + 'Profiler.css']]; + protected $mode = CACHE_TYPE_NONE; + + protected $typeId = 0; + protected $pageName = ''; + + public function __construct($pageCall, $pageParam) + { + parent::__construct($pageCall, $pageParam); + + if ($pageParam) + { + // todo: check if account is disabled or something + if ($user = DB::Aowow()->selectRow('SELECT a.id, a.user, a.displayName, a.consecutiveVisits, a.userGroups, a.avatar, a.title, a.description, a.joinDate, a.prevLogin, IFNULL(SUM(ar.amount), 0) AS sumRep FROM ?_account a LEFT JOIN ?_account_reputation ar ON a.id = ar.userId WHERE a.user = ? GROUP BY a.id', $pageParam)) + $this->user = $user; + else + $this->notFound(sprintf(Lang::user('notFound'), $pageParam)); + } + else if (User::$id) + { + header('Location: ?user='.User::$displayName, true, 302); + die(); + } + else + $this->forwardToSignIn('user'); + } + + protected function generateContent() + { + /***********/ + /* Infobox */ + /***********/ + + $infobox = $contrib = $groups = []; + foreach (Lang::account('groups') as $idx => $key) + if ($idx >= 0 && $this->user['userGroups'] & (1 << $idx)) + $groups[] = (!fMod(count($groups) + 1, 3) ? '[br]' : null).Lang::account('groups', $idx); + + $infobox[] = Lang::user('joinDate'). Lang::main('colon').'[tooltip name=joinDate]'. date('l, G:i:s', $this->user['joinDate']). '[/tooltip][span class=tip tooltip=joinDate]'. date(Lang::main('dateFmtShort'), $this->user['joinDate']). '[/span]'; + $infobox[] = Lang::user('lastLogin').Lang::main('colon').'[tooltip name=lastLogin]'.date('l, G:i:s', $this->user['prevLogin']).'[/tooltip][span class=tip tooltip=lastLogin]'.date(Lang::main('dateFmtShort'), $this->user['prevLogin']).'[/span]'; + $infobox[] = Lang::user('userGroups').Lang::main('colon').($groups ? implode(', ', $groups) : Lang::account('groups', -1)); + $infobox[] = Lang::user('consecVisits').Lang::main('colon').$this->user['consecutiveVisits']; + $infobox[] = Util::ucFirst(Lang::main('siteRep')).Lang::main('colon').Lang::nf($this->user['sumRep']); + + // contrib -> [url=http://www.wowhead.com/client]Data uploads: n [small]([tooltip=tooltip_totaldatauploads]xx.y MB[/tooltip])[/small][/url] + + $co = DB::Aowow()->selectRow( + 'SELECT COUNT(DISTINCT c.id) AS sum, SUM(IFNULL(cr.value, 0)) AS nRates FROM ?_comments c LEFT JOIN ?_comments_rates cr ON cr.commentId = c.id AND cr.userId <> 0 WHERE c.replyTo = 0 AND c.userId = ?d', + $this->user['id'] + ); + if ($co['sum']) + $contrib[] = Lang::user('comments').Lang::main('colon').$co['sum'].($co['nRates'] ? ' [small]([tooltip=tooltip_totalratings]'.$co['nRates'].'[/tooltip])[/small]' : null); + + $ss = DB::Aowow()->selectRow('SELECT COUNT(*) AS sum, SUM(IF(status & ?d, 1, 0)) AS nSticky, SUM(IF(status & ?d, 0, 1)) AS nPending FROM ?_screenshots WHERE userIdOwner = ?d AND (status & ?d) = 0', + CC_FLAG_STICKY, + CC_FLAG_APPROVED, + $this->user['id'], + CC_FLAG_DELETED + ); + if ($ss['sum']) + { + $buff = []; + if ($ss['nSticky'] || $ss['nPending']) + { + if ($normal = ($ss['sum'] - $ss['nSticky'] - $ss['nPending'])) + $buff[] = '[tooltip=tooltip_normal]'.$normal.'[/tooltip]'; + + if ($ss['nSticky']) + $buff[] = '[tooltip=tooltip_sticky]'.$ss['nSticky'].'[/tooltip]'; + + if ($ss['nPending']) + $buff[] = '[tooltip=tooltip_pending]'.$ss['nPending'].'[/tooltip]'; + } + + $contrib[] = Lang::user('screenshots').Lang::main('colon').$ss['sum'].($buff ? ' [small]('.implode($buff, ' + ').')[/small]' : null); + } + + $vi = DB::Aowow()->selectRow('SELECT COUNT(id) AS sum, SUM(IF(status & ?d, 1, 0)) AS nSticky, SUM(IF(status & ?d, 0, 1)) AS nPending FROM ?_videos WHERE userIdOwner = ?d AND (status & ?d) = 0', + CC_FLAG_STICKY, + CC_FLAG_APPROVED, + $this->user['id'], + CC_FLAG_DELETED + ); + if ($vi['sum']) + { + $buff = []; + if ($vi['nSticky'] || $vi['nPending']) + { + if ($normal = ($vi['sum'] - $vi['nSticky'] - $vi['nPending'])) + $buff[] = '[tooltip=tooltip_normal]'.$normal.'[/tooltip]'; + + if ($vi['nSticky']) + $buff[] = '[tooltip=tooltip_sticky]'.$vi['nSticky'].'[/tooltip]'; + + if ($vi['nPending']) + $buff[] = '[tooltip=tooltip_pending]'.$vi['nPending'].'[/tooltip]'; + } + + $contrib[] = Lang::user('videos').Lang::main('colon').$vi['sum'].($buff ? ' [small]('.implode($buff, ' + ').')[/small]' : null); + } + + // contrib -> Forum posts: 5769 [small]([tooltip=topics]579[/tooltip] + [tooltip=replies]5190[/tooltip])[/small] + + $this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]'; + + if ($contrib) + $this->contributions = '[ul][li]'.implode('[/li][li]', $contrib).'[/li][/ul]'; + + + /****************/ + /* Main Content */ + /****************/ + + $this->name = $this->user['title'] ? $this->user['displayName'].' <'.$this->user['title'].'>' : sprintf(Lang::user('profileTitle'), $this->user['displayName']); + + /**************/ + /* Extra Tabs */ + /**************/ + + $this->lvTabs = []; + $this->forceTabs = true; + + // [unused] Site Achievements + + // Reputation changelog (params only for comment-events) + if ($repData = DB::Aowow()->select('SELECT action, amount, date AS \'when\', IF(action IN (3, 4, 5), sourceA, 0) AS param FROM ?_account_reputation WHERE userId = ?d', $this->user['id'])) + { + foreach ($repData as &$r) + $r['when'] = date(Util::$dateFormatInternal, $r['when']); + + $this->lvTabs[] = ['reputationhistory', ['data' => $repData]]; + } + + // Comments + if ($_ = CommunityContent::getCommentPreviews(['user' => $this->user['id'], 'replies' => false], $nFound)) + { + $tabData = array( + 'data' => $_, + 'hiddenCols' => ['author'], + 'onBeforeCreate' => '$Listview.funcBox.beforeUserComments', + '_totalCount' => $nFound + ); + + if ($nFound > CFG_SQL_LIMIT_DEFAULT) + { + $tabData['name'] = '$LANG.tab_latestcomments'; + $tabData['note'] = '$$WH.sprintf(LANG.lvnote_usercomments, '.$nFound.')'; + } + + $this->lvTabs[] = ['commentpreview', $tabData]; + } + + // Comment Replies + if ($_ = CommunityContent::getCommentPreviews(['user' => $this->user['id'], 'replies' => true], $nFound)) + { + $tabData = array( + 'data' => $_, + 'hiddenCols' => ['author'], + 'onBeforeCreate' => '$Listview.funcBox.beforeUserComments', + '_totalCount' => $nFound + ); + + if ($nFound > CFG_SQL_LIMIT_DEFAULT) + { + $tabData['name'] = '$LANG.tab_latestreplies'; + $tabData['note'] = '$$WH.sprintf(LANG.lvnote_userreplies, '.$nFound.')'; + } + + $this->lvTabs[] = ['replypreview', $tabData]; + } + + // Screenshots + if ($_ = CommunityContent::getScreenshots(-$this->user['id'], 0, $nFound)) + { + $tabData = array( + 'data' => $_, + '_totalCount' => $nFound + ); + + if ($nFound > CFG_SQL_LIMIT_DEFAULT) + { + $tabData['name'] = '$LANG.tab_latestscreenshots'; + $tabData['note'] = '$$WH.sprintf(LANG.lvnote_userscreenshots, '.$nFound.')'; + } + + $this->lvTabs[] = ['screenshot', $tabData]; + } + + // Videos + if ($_ = CommunityContent::getVideos(-$this->user['id'], 0, $nFound)) + { + $tabData = array( + 'data' => $_, + '_totalCount' => $nFound + ); + + if ($nFound > CFG_SQL_LIMIT_DEFAULT) + { + $tabData['name'] = '$LANG.tab_latestvideos'; + $tabData['note'] = '$$WH.sprintf(LANG.lvnote_uservideos, '.$nFound.')'; + } + + $this->lvTabs[] = ['video', $tabData]; + } + + // forum -> latest topics [unused] + + // forum -> latest replies [unused] + + // Characters [todo] + $this->user['characterData'] = []; + /* + us_addCharactersTab([ + { + id:763, + "name":"Lilywhite", + "achievementpoints":"0", + "guild":"whatever", + "guildrank":"0", + "realm":"draenor", + "realmname":"Draenor", + "battlegroup":"cyclone", + "battlegroupname":"Cyclone", + "region":"us", + "level":"10", + "race":"7", + "gender":"0", + "classs":"1", + "faction":"0", + "gearscore":"0", + "talenttree1":"0", + "talenttree2":"0", + "talenttree3":"0", + "talentspec":0, + "published":1, + "pinned":0 + } + ]); + */ + + // Profiles [todo] + $this->user['profileData'] = []; + } + + protected function generateTitle() + { + array_unshift($this->title, sprintf(Lang::user('profileTitle'), $this->user['displayName'])); + } + + protected function generatePath() { } +} + +?> diff --git a/static/js/staff.js b/static/js/staff.js index 6518e139..8bfbc198 100644 --- a/static/js/staff.js +++ b/static/js/staff.js @@ -1,301 +1,301 @@ -var mn_content = [ -// [22, 'Achievements', '?admin=achievements', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV | U_GROUP_BUREAU}], - [3, 'Announcements', '?admin=announcements', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], -// [25, 'Guides Awaiting Approval', '?admin=guides', null, {requiredAccess: U_GROUP_STAFF}], -// [20, 'Global Images & Headers', '?admin=headers', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], -// [21, 'Modelviewer', '?admin=modelviewer', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], - [23, 'Out of Date Comments', '?admin=out-of-date', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_MOD}], - [5, 'Screenshots', '?admin=screenshots', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SCREENSHOT}], -// [18, 'Upload Image', '?npc=15384#submit-a-screenshot', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_EDITOR, rel: 'np'}], - [17, 'Videos', '?admin=videos', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_VIDEO}], - - [, 'Homepage'], - [13, 'Featured Box', '?admin=home-featuredbox', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU, breadcrumb: 'Homepage Featured Box'}], - [14, 'Oneliners', '?admin=home-oneliners', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU, breadcrumb: 'Homepage Oneliners'}], -// [15, 'Skins', '?admin=home-skins', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SALESAGENT, breadcrumb: 'Homepage Skins'}], - [16, 'Titles', '?admin=home-titles', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU, breadcrumb: 'Homepage Titles'}], - -// [, 'Articles'], -// [8, 'List', '?admin=articles', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV | U_GROUP_EDITOR | U_GROUP_LOCALIZER, breadcrumb: 'List of Articles'}], -// [9, 'Editors\' Lounge', '?admin=editors-lounge', null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_EDITOR | U_GROUP_LOCALIZER}], -// [23, 'Related Links', '?admin=related-links', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], - -// [, 'News'], -// [10, 'New Post', '?edit=news', null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_BLOGGER, breadcrumb: 'News Post'}], -// [11, 'Content Corner', '?admin=content-corner', null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_BLOGGER}], -// [12, 'Tags', '?admin=newstag', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV | U_GROUP_BLOGGER, breadcrumb: 'News Tags'}], -// [24, 'Patch Updates', '?admin=patch-updates', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], -// [26, 'Featured Guides', '?admin=featuredguides', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU, breadcrumb: 'Featured Guides'}], - -// [, 'Community'], -// [4, 'Contests', '?admin=contests', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SALESAGENT}], -// [27, 'Top User Contest', '?admin=topuser-contest', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SALESAGENT}], -// [19, 'Forums', '?admin=forums', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], -// [6, 'Profanity Filter', '?admin=profanity', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], - -// [, 'Other'], -// [7, 'Holiday Gift Guide', '?admin=holidaygift', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}] -]; - -var mn_dev = [ -// [17, 'Cookies', '?admin=cookies', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], - [21, 'PHP Information', '?admin=phpinfo', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], - [18, 'Site Configuration', '?admin=siteconfig', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], - [16, 'Weight Presets', '?admin=weight-presets', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV}], -// [22, 'API Keys', '?admin=apikey', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV}], - -// [, 'Cache'], -// [2, 'Create Folders', '?admin=cache-folder', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Create Cache Folders'}], -// [3, 'Expire Range', '?admin=cache-expire', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Expire Cache Range'}], -// [1, 'Manage', '?admin=cache-manage', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Manage Cache'}], -// [20, 'Memcached', '?admin=memcached', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Manage Memcached'}], - -// [, 'Database'], -// [8, 'Add Fake Item', '?admin=fakeitem', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [10, 'Add Fake NPC', '?admin=fakenpc', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [19, 'Check Consistency', '?admin=db-check-consistency', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Check Database Consistency'}], -// [4, 'Execute SQL', '?admin=sql', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [9, 'Export Fake Item', '?admin=luaitem', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [26, 'Denormalized Fields Fix', '?admin=denormalized-fix', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [11, 'Minimum & Maximum Values', '?admin=minmax', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [7, 'SQL Find & Replace', '?admin=sql-replace', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [25, 'Switch Active Database', '?admin=active-db', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], -// [5, 'Updates', '?admin=db-update', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Database Updates'}], - -// [, 'Generators'], -// [12, 'Talent Calculator Icons', '?admin=talentcalc-icons', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}] -]; - -var mn_localization = [ - [1, 'Generate Files', '?admin=locale-export', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Generate Localization Files'}], - - [, 'Terms'], - [4, 'Check Integrity', '?admin=locale-integrity', null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_LOCALIZER, breadcrumb: 'Check Term Integrity'}], - [2, 'Manage', '?admin=locale-search', null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_LOCALIZER, breadcrumb: 'Manage Terms'}], - - [, 'Deprecated'], - [6, 'Create Template', '?admin=locale-template', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV, breadcrumb: 'Create Localization Template'}], - [5, 'Import Old Localized File', '?admin=locale-import', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}], - [7, 'Upload Global Strings', '?admin=locale-upload', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV}] -]; - -var mn_statistics = [ - [1, 'Comments', '?admin=stats&table=comments'], - [2, 'Comment Votes', '?admin=stats&table=commentratings'], - [3, 'Forum Posts', '?admin=stats&table=forumposts'], - [5, 'Registrations', '?admin=stats&table=registrations'], - [4, 'Screenshots', '?admin=stats&table=screenshots'], - [7, 'Uploads', '?admin=stats&table=uploads'], - [6, 'Videos', '?admin=stats&table=videos'], - [8, 'Vists by Registered Users', '?admin=stats&table=visits-by-registered'] -]; - -var mn_users = [ - [2, 'Action Log', '?admin=log', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], - [3, 'Banned IPs', '?admin=bannedip', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}], - [1, 'Manage', '?admin=finduser', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_MODERATOR, breadcrumb: 'Manage Users'}], - [5, 'Roles', '?admin=staff', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_MODERATOR}], - - [, 'Deprecated'], - [4, 'Get Registration Email', '?admin=getregistrationemail', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU}] -]; - -var mn_staff = [ - [1, 'Content', null, mn_content], - [2, 'Development', null, mn_dev], -// [3, 'Localization', null, mn_localization], -// [7, 'Statistics', null, mn_statistics, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV}], -// [4, 'Users', null, mn_users], -// [5, 'View Reports', '?admin=reports', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_EDITOR | U_GROUP_MOD | U_GROUP_LOCALIZER | U_GROUP_SCREENSHOT | U_GROUP_VIDEO} ], - - [, 'Page'], - [102, 'Validate', 'http://validator.w3.org/check/referer', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV | U_GROUP_TESTER}]]; - -mn_path.push([4, 'Staff', null, mn_staff]); - -$(document).ready(function () { - var footer = $('div.stafffooter'); - if (footer.length > 0) { - var totalHeight = $(window).height(); - if (footer.offset().top < (totalHeight - 100)) { - var offset = footer.offset(); - offset.top = totalHeight - 100; - footer.offset(offset); - } - } - var articleAccess = U_GROUP_EMPLOYEE | U_GROUP_EDITOR | (Locale.getId() != LOCALE_ENUS ? U_GROUP_LOCALIZER : 0); - var urlParams = $WH.g_getGets(); - var buff; - var refresh = {}; - var subMenu = null; - if (urlParams.refresh != null) { - buff = 'See Cached'; - refresh.refresh = null - } - else { - var mCached = {}; - var fiCache = {}; - buff = 'Refresh'; - if (PageTemplate.get('pageName') == 'home') { - refresh.home = ''; - mCached.home = ''; - fiCache.home = '' - } - refresh.refresh = ''; - mCached.refresh = 'memcached'; - fiCache.refresh = 'filecache'; - subMenu = [ - [1, 'Memcached', g_modifyUrl(location.href, mCached), null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV}], - [2, 'File cache', g_modifyUrl(location.href, fiCache), null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV}] - ] - } - mn_staff.push([100, buff, g_modifyUrl(location.href, refresh), subMenu, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_DEV}]); - if (location.href.match(/website-achievement=([0-9]+)(\/.*)?/i)) { - mn_staff.push([, 'Achievement']); - mn_staff.push([200, 'Manage', '?admin=achievements&action=edit&id=' + RegExp.$1, null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV | U_GROUP_BUREAU}]) - } - if (location.href.match(/website-achievements(\/.*)?/i)) { - mn_staff.push([, 'Achievements']); - mn_staff.push([200, 'Manage', '?admin=achievements', null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_DEV | U_GROUP_BUREAU}]) - } - if (location.href.match(/news=([0-9]+)(\/.*)/i)) { - mn_staff.push([, 'News Post']); - mn_staff.push([200, 'Edit', '?edit=news&id=' + RegExp.$1, null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_BLOGGER}]); - mn_staff.push([203, 'View forum topic', '/forums&topic=' + RegExp.$1, null, {requiredAccess: U_GROUP_EMPLOYEE | U_GROUP_BLOGGER}]) - } - if (location.href.match(/user=([a-z0-9]+)/i)) { - mn_staff.push([, 'User']); - mn_staff.push([201, 'Manage', '?admin=manageuser&name=' + RegExp.$1, null, {requiredAccess: U_GROUP_MODERATOR}]) - } - if ($WH.isset('g_pageInfo')) { - if (g_pageInfo.type && g_pageInfo.typeId) { - mn_staff.push([, 'DB Entry']); -// mn_staff.push([1001, 'Edit Article', '?edit=article&type=' + g_pageInfo.type + '&typeid=' + g_pageInfo.typeId, null, {requiredAccess: articleAccess}]); - mn_staff.push([1000, 'Manage Screenshots', '?admin=screenshots&type=' + g_pageInfo.type + '&typeid=' + g_pageInfo.typeId, null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_SCREENSHOT}]); - mn_staff.push([1000, 'Manage Videos', '?admin=videos&type=' + g_pageInfo.type + '&typeid=' + g_pageInfo.typeId, null, {requiredAccess: U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_VIDEO}]) - } - if (g_pageInfo.articleUrl) { - mn_staff.push([, 'Article']); - mn_staff.push([1002, 'Edit', '?edit=article&' + g_pageInfo.articleUrl, null, {requiredAccess: (g_pageInfo.editAccess ? g_pageInfo.editAccess: articleAccess)}]); - mn_staff.push([1003, 'Options', '?edit=article-options&url=' + g_pageInfo.articleUrl, null, {requiredAccess: articleAccess}]) - } - } - Menu.sort(mn_staff) -}); - -var staff_deleteCacheKey = function (b, key) { - var div = $('#purge-memcache' + b); - var url = '?purgekey=' + key; - var data = {}; - - if ($.isArray(key)) { - url = '?purgekey'; - data.keys = key; - } - - $.ajax({ - method: 'GET', - url: url, - data: data, - success: function (x) { - if (x == 0) { - this.replaceWith('Key successfully deleted!'); - } - else { - this.replaceWith('Key deletion failed: ' + x + ''); - } - }.bind(div) - }) -}; - -$(document).ready(function () { - $('#save-blog-form').submit(function () { - var form = $(this); - var blogId = form.find('input[name=blog-id]').val(); - form.find('.spinning-circle').show(); - form.find('input[type=submit]').attr('disabled', 'disabled').val('Saving..'); - form.find('#save-status').html(''); - leavePage(1); - $.ajax({ - url: '?edit=news&id=' + blogId, - async: true, - cache: false, - data: $(this).serialize(), - type: 'POST', - error: function () { - alert('An error has occured. The news was not saved.') - }, - success: function (data) { - var response = eval(data); - if (!response.success) { - alert('An error has occured, the news was not saved: ' + response.message); - return - } - form.find('input[name=blog-id]').val(response.entry); - form.find('#save-status').html('Your news has been saved! [link]') - }, - complete: function () { - form.find('.spinning-circle').hide(); - form.find('input[type=submit]').attr('disabled', '').val('Save') - } - }); - return false - }) -}); - -var listviewIdList = new function () { - function onShow(container, i, str) { - Lightbox.setSize(950, 590); - - if (i) { - container.className = 'modelviewer'; - - var div = $WH.ce('div'); - var pre = $WH.ce('pre'); - container.debug = pre; - pre.className = 'code'; - $WH.ae(div, pre); - $WH.ae(container, div); - - var a = $WH.ce('a'); - a.className = 'modelviewer-close'; - a.href = 'javascript:;'; - a.onclick = Lightbox.hide; - $WH.ae(a, $WH.ce('span')); - $WH.ae(container, a); - - clear = $WH.ce('div'); - clear.className = 'clear'; - $WH.ae(container, clear); - } - - var ta = $('