2017-01-14 04:56:47 +01:00

612 lines
21 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/*
* UDWBase: WOWDB Web Interface
*
* © UDW 2009-2011
*
* Released under the terms and conditions of the
* GNU General Public License (http://gnu.org).
*
*/
require_once ('includes/allitems.php');
require_once ('includes/alllocales.php');
// Available character classes
define("CLASS_WARRIOR", 1);
define("CLASS_PALADIN", 2);
define("CLASS_HUNTER", 4);
define("CLASS_ROGUE", 8);
define("CLASS_PRIEST", 16);
define("CLASS_SHAMAN", 64);
define("CLASS_MAGE", 128);
define("CLASS_WARLOCK", 256);
define("CLASS_DRUID", 1024);
// Character classes
$classes = array(
1 => LOCALE_WARRIOR,
2 => LOCALE_PALADIN,
3 => LOCALE_HUNTER,
4 => LOCALE_ROGUE,
5 => LOCALE_PRIEST,
7 => LOCALE_SHAMAN,
8 => LOCALE_MAGE,
9 => LOCALE_WARLOCK,
11 => LOCALE_DRUID
);
// Available character races
define("RACE_HUMAN", 1);
define("RACE_ORC", 2);
define("RACE_DWARF", 4);
define("RACE_NIGHTELF", 8);
define("RACE_UNDEAD", 16);
define("RACE_TAUREN", 32);
define("RACE_GNOME", 64);
define("RACE_TROLL", 128);
// Object types
global $types;
$types = array(
1 => 'npc',
2 => 'object',
3 => 'item',
4 => 'itemset',
5 => 'quest',
6 => 'spell',
7 => 'zone',
8 => 'faction'
);
// Reputation levels
$reputations = array(
1 => LOCALE_NEUTRAL,
3000 => LOCALE_FRIENDLY,
9000 => LOCALE_HONORED,
21000 => LOCALE_REVERED,
42000 => LOCALE_EXALTED
);
/**
*
* @param int $secs
* @return int
*/
function sec_to_time($secs) {
$time = array();
if ($secs >= 3600) {
$time['h'] = floor($secs / 3600);
$secs = $secs - $time['h'] * 3600;
}
if ($secs >= 60) {
$time['m'] = floor($secs / 60);
$secs = $secs - $time['m'] * 60;
}
if ($secs > 0)
$time['s'] = $secs;
return $time;
}
/**
*
* @param int $money
* @return array $coins
*/
function money2coins($money) {
$coins = array();
if ($money >= 10000) {
$coins['moneygold'] = floor($money / 10000);
$money = $money - $coins['moneygold'] * 10000;
}
if ($money >= 100) {
$coins['moneysilver'] = floor($money / 100);
$money = $money - $coins['moneysilver'] * 100;
}
if ($money > 0)
$coins['moneycopper'] = $money;
return $coins;
}
/**
* Determine class
*
* @param type $class
* @return string
*/
function classes($class) {
$tmp = '';
if ($class & CLASS_WARRIOR)
$tmp = LOCALE_WARRIOR;
if ($class & CLASS_PALADIN)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_PALADIN; else
$tmp = LOCALE_PALADIN;
if ($class & CLASS_HUNTER)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_HUNTER; else
$tmp = LOCALE_HUNTER;
if ($class & CLASS_ROGUE)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_ROGUE; else
$tmp = LOCALE_ROGUE;
if ($class & CLASS_PRIEST)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_PRIEST; else
$tmp = LOCALE_PRIEST;
if ($class & CLASS_SHAMAN)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_SHAMAN; else
$tmp = LOCALE_SHAMAN;
if ($class & CLASS_MAGE)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_MAGE; else
$tmp = LOCALE_MAGE;
if ($class & CLASS_WARLOCK)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_WARLOCK; else
$tmp = LOCALE_WARLOCK;
if ($class & CLASS_DRUID)
if ($tmp)
$tmp = $tmp . ', ' . LOCALE_DRUID; else
$tmp = LOCALE_DRUID;
if ($tmp == LOCALE_WARRIOR . ', ' . LOCALE_PALADIN . ', ' . LOCALE_HUNTER . ', ' . LOCALE_ROGUE
. ', ' . LOCALE_PRIEST . ', ' . LOCALE_SHAMAN . ', ' . LOCALE_MAGE . ', ' . LOCALE_WARLOCK . ', ' . LOCALE_DRUID)
return;
else
return $tmp;
}
function classes_array($class) {
$tmp = array();
if($class == 1503 || $class == -1 || $class == 32767 || $class == 1535){ //ALL
return NULL;}
if ($class & CLASS_WARRIOR)
$tmp[] = 1;
if ($class & CLASS_PALADIN)
$tmp[] = 2;
if ($class & CLASS_HUNTER)
$tmp[] = 3;
if ($class & CLASS_ROGUE)
$tmp[] = 4;
if ($class & CLASS_PRIEST)
$tmp[] = 5;
if ($class & CLASS_SHAMAN)
$tmp[] = 7;
if ($class & CLASS_MAGE)
$tmp[] = 8;
if ($class & CLASS_WARLOCK)
$tmp[] = 9;
if ($class & CLASS_DRUID)
$tmp[] = 11;
return $tmp;
}
/**
* Determine race
*
* @param type $race
* @return string
*/
function races($race) {
if ($race == RACE_HUMAN | RACE_ORC | RACE_DWARF | RACE_NIGHTELF | RACE_UNDEAD | RACE_TAUREN | RACE_GNOME | RACE_TROLL || $race == 0)
return array('side' => 3, 'name' => LOCALE_BOTH);
elseif ($race == RACE_ORC | RACE_UNDEAD | RACE_TAUREN | RACE_TROLL)
return array('side' => 2, 'name' => LOCALE_HORDE);
elseif ($race == RACE_HUMAN | RACE_DWARF | RACE_NIGHTELF | RACE_GNOME)
return array('side' => 1, 'name' => LOCALE_ALLIANCE);
else {
$races = array('name' => '', 'side' => 0);
if ($race & RACE_HUMAN) {
(($races['side'] == 2) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 1;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_HUMAN;
}
if ($race & RACE_ORC) {
(($races['side'] == 1) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 2;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_ORC;
}
if ($race & RACE_DWARF) {
(($races['side'] == 2) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 1;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_DWARF;
}
if ($race & RACE_NIGHTELF) {
(($races['side'] == 2) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 1;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_NIGHT_ELF;
}
if ($race & RACE_UNDEAD) {
(($races['side'] == 1) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 2;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_UNDEAD;
}
if ($race & RACE_TAUREN) {
(($races['side'] == 1) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 2;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_TAUREN;
}
if ($race & RACE_GNOME) {
(($races['side'] == 2) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 1;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_GNOME;
}
if ($race & RACE_TROLL) {
(($races['side'] == 1) or ($races['side'] == 3)) ? $races['side'] = 3 : $races['side'] = 2;
if ($races['name'])
$races['name'] .= ', '; $races['name'] .= LOCALE_TROLL;
}
return $races;
}
}
/**
*
* @param type $tab
* @param type $key
* @return type
*/
function sum_subarrays_by_key($tab, $key) {
$sum = 0;
foreach ($tab as $sub_array) {
$sum += $sub_array[$key];
}
return $sum;
}
/**
*
* @param type $mapid
* @param type $x
* @param type $y
* @param type $global
* @return type
*/
function coord_db2wow($mapid, $x, $y, $global) {
// Карты
global $map_images;
// Подключение к базе
global $DB;
global $UDWBaseconf;
$rows = $DB->select('SELECT * FROM '.$UDWBaseconf['aowow']['db'].'.?_aowow_zones WHERE (mapID=? and x_min<? and x_max>? and y_min<? and y_max>?)', $mapid, $x, $x, $y, $y);
foreach ($rows as $numRow => $row) {
// Сохраяняем имя карты и координаты
$wow['zone'] = $row['areatableID'];
$wow['name'] = $row['name'];
// Т.к. в игре координаты начинают отсчёт с левого верхнего угла
// а в системе координат сервера с правого нижнего,
// делаем соответствующее преобразование.
$tx = 100 - ($y - $row["y_min"]) / (($row["y_max"] - $row["y_min"]) / 100);
$ty = 100 - ($x - $row["x_min"]) / (($row["x_max"] - $row["x_min"]) / 100);
// А если ещё и с цветом совпала - нах цикл, это всё наше :) Оо
// Если ещё не загружена - загружаем.
if (!isset($map_images[$wow['zone']])) {
$mapname = str_replace("\\", "/", getcwd()) . '/images/tmp/' . $row['areatableID'] . '.png';
if (file_exists($mapname)) {
$map_images[$wow['zone']] = @ImageCreateFromPNG($mapname);
} else {
echo "<font color=red>....Map $mapname not found (ID=" . $wow['zone'] . ")</font><br>";
}
}
// Если так и не загрузилась... Возможно такой карты ещё просто нету :)
if ($map_images[$wow['zone']]) {
if (@ImageColorAt($map_images[$wow['zone']], round($tx * 10), round($ty * 10)) === 0) {
break;
}
}
}
if (count($rows) == 0) {
// Ничего не найдено. Мб инста??
$row = $DB->selectRow('SELECT * FROM '.$UDWBaseconf['aowow']['db'].'.?_aowow_zones WHERE (mapID=? and x_min=0 and x_max=0 and y_min=0 and y_max=0)', $mapid);
if ($row) {
$wow['zone'] = $row['areatableID'];
$wow['name'] = $row['name'];
} else {
echo "<font color=red>....Location for Map with ID=$mapid not found</font><br>";
return;
}
}
$wow['x'] = round($tx, 4);
$wow['y'] = round($ty, 4);
return $wow;
}
// Преобразование целого массива координат
// Всегда пользовацца только им!
/**
*
* @param type $data
* @return type
*/
function mass_coord(&$data) {
// Карты
global $map_images;
// Гуиды для эвента
$guids = array();
// Объявляем новый массив с преобразованными данными
$xdata = array();
// Перебираем по порядку все координаты, посланные функции
// Если таких же координат (уже преобразованных) ещё нет, добавляем в новый массив
foreach ($data as $ndata) {
// Если помимо координат есть ещё данные о респауне, преобразуем их к удобочитаемому виду:
if (isset($ndata['spawntimesecs']))
{
$coord_db2wow = coord_db2wow($ndata['m'], $ndata['x'], $ndata['y'], false) ?: array();
$tmp = array_merge($coord_db2wow, array('r' => sec_to_time($ndata['spawntimesecs'])));
}
else
{
$tmp = coord_db2wow($ndata['m'], $ndata['x'], $ndata['y'], false);
}
$tmp['t'] = $ndata['type'];
$xdata[] = $tmp;
}
// Освобождаем всю память выделенную под карты
if ($map_images)
foreach ($map_images as $map_image)
imagedestroy($map_image);
// Возвращаем новый массив
return $xdata;
}
// Функция информации о фракции
/**
*
* @global type $DB
* @param type $id
* @return type
*/
function factioninfo($id) {
global $DB;
global $UDWBaseconf;
$faction['name'] = $DB->selectCell('SELECT name' . ' FROM '.$UDWBaseconf['aowow']['db'].'.?_aowow_factions WHERE factionID = ?d LIMIT 1', $id);
$faction['entry'] = $id;
return $faction;
}
// Function, that creates loot_table (without references) from lootid
// $table - table, in which we search
// $lootid - loot ident
// $repetition_factor - repetition factor
/**
*
* @param type $table
* @param type $lootid
* @param type $max_percent
* @return type
*/
function loot_table($table, $lootid, $max_percent=100) {
// Все элементы
global $DB;
global $loot_groups;
global $item_cols;
global $UDWBaseconf;
$loot = array();
$groups = array();
// Мего запрос :)
$rows = $DB->select('
SELECT l.ChanceOrQuestChance, l.mincountOrRef, l.maxcount as `d-max`, l.groupid, ?#, i.entry, i.maxcount
{, loc.name_loc?d AS `name_loc`}
FROM ' . $table . ' l
LEFT JOIN ('.$UDWBaseconf['aowow']['db'].'.?_aowow_icons a, ?_item_template i) ON l.item=i.entry AND a.id=i.displayid
{LEFT JOIN (?_locales_item loc) ON loc.entry=i.entry AND ?d}
WHERE
l.entry=?d
{LIMIT ?d}
', $item_cols[2], ($_SESSION['locale']) ? $_SESSION['locale'] : DBSIMPLE_SKIP, ($_SESSION['locale']) ? 1 : DBSIMPLE_SKIP, $lootid, ($UDWBaseconf['limit'] != 0) ? $UDWBaseconf['limit'] : DBSIMPLE_SKIP
);
// Перебираем
foreach ($rows as $i => $row) {
if ($row['mincountOrRef'] > 0) {
// Не ссылка!
if ($row['groupid'] > 0) {
// Групповой лут!
$groups[$row['groupid']][] = array(
'mincount' => $row['mincountOrRef'],
'maxcount' => $row['d-max'],
'percent' => $row['ChanceOrQuestChance'] * $max_percent / 100,
'item' => iteminfo2($row, 0)
);
// Общее число элементов группы с равнозначным шансом
if (!(IsSet($group_idx[$row['groupid']]['num-equal'])))
$group_idx[$row['groupid']]['num-equal'] = 0;
// Общий шанс дропа для группового лута
if (!(IsSet($group_idx[$row['groupid']]['percent'])))
$group_idx[$row['groupid']]['percent'] = 0;
// Если шанс дропа=0, значит это равнозначный лут в группе
// Иначе, увеличиваем зарезервированный шанс для элементов лута с четко определенным шансом дропа
if ($row['ChanceOrQuestChance'] == 0)
$group_idx[$row['groupid']]['num-equal']++;
else
$group_idx[$row['groupid']]['percent'] += abs($row['ChanceOrQuestChance']);
} else {
// old common loot
$loot[] = array_merge(array(
'percent' => ($max_percent != 100) ? $max_percent : $row['ChanceOrQuestChance'],
'mincount' => $row['mincountOrRef'],
'maxcount' => $row['d-max'],
'group' => 0
), iteminfo2($row, 0));
}
} else {
// Ссылка!
// Вот если это ссылка, то ######
// Наша задача - вызвать эту же функцию, но с предопределенным значением percent и maxcount
for ($j = 1; $j <= $row['d-max']; $j++)
$loot = array_merge($loot, loot_table('?_reference_loot_template', -$row['mincountOrRef'], $row['ChanceOrQuestChance']));
}
}
// Iterate group loot
foreach ($groups as $groupid => $group) {
foreach ($group as $field => $group_item) {
if (isset($group_item['item']))
$loot[] = array_merge(array(
'mincount' => $group_item['mincount'],
'maxcount' => $group_item['maxcount'],
'percent' => ($group_item['percent'] == 0) ? (($max_percent - $group_idx[$groupid]['percent']) / $group_idx[$groupid]['num-equal']) : $group_item['percent'],
'group' => $loot_groups,
'grouppercent' => ($group_idx[$groupid]['num-equal'] > 0) ? $max_percent : $group_idx[$groupid]['percent']
), $group_item['item']);
}
$loot_groups++;
}
return $loot;
}
/**
*
* @param type $table
* @param type $lootid
* @return type
*/
function loot($table, $lootid) {
global $loot_groups;
$loot_groups = 1;
$loot = loot_table($table, $lootid);
return $loot;
}
// Кто дропает
/**
*
* @param type $table
* @param type $item
* @return type
*/
function drop($table, $item) {
global $DB;
global $UDWBaseconf;
$rows = $DB->select('
SELECT l.ChanceOrQuestChance, l.mincountOrRef, l.maxcount, l.entry
FROM ' . $table . ' l
WHERE
l.item=?
{LIMIT ?d}
', $item, ($UDWBaseconf['limit'] != 0) ? $UDWBaseconf['limit'] : DBSIMPLE_SKIP
);
$drop = array();
foreach ($rows as $i => $row) {
if ($row['mincountOrRef'] > 0) {
$num = $row['entry'];
$drop[$num] = array();
$drop[$num]['percent'] = abs($row['ChanceOrQuestChance']);
$drop[$num]['mincount'] = $row['mincountOrRef'];
$drop[$num]['maxcount'] = $row['maxcount'];
// We are looking for loot, which refers to this loot
$refrows = $DB->select('SELECT entry FROM ' . $table . ' WHERE mincountOrRef=? LIMIT 200', $table, -$num);
foreach ($refrows as $i => $refrow) {
$num = $refrow['entry'];
$drop[$num] = array();
$drop[$num]['percent'] = abs($row['ChanceOrQuestChance']);
$drop[$num]['mincount'] = $row['mincountOrRef'];
$drop[$num]['maxcount'] = $row['maxcount'];
}
}
}
return $drop;
}
// позиция
/**
*
* @param type $id
* @param type $type
*/
function position($id, $type) {
global $smarty, $exdata, $zonedata, $DB;
$data = $DB->select('SELECT guid, map AS m, position_x AS x, position_y AS y, spawntimesecs, {MovementType AS ?#, }"0" AS `type` FROM ?_' . $type . ' WHERE id = ?d GROUP BY ROUND(x,-2), ROUND(y,-2) ORDER BY x,y', ($type == 'gameobject' ? DBSIMPLE_SKIP : 'mt'), $id);
if ($type <> 'gameobject') {
$wpWalkingCreaturesGuids = array();
foreach ($data as $spawnid => $spawn) {
if ($spawn['mt'] == 2)
$wpWalkingCreaturesGuids[] = $spawn['guid'];
}
if ($wpWalkingCreaturesGuids) {
$wps = $DB->select('SELECT c.map AS m, m.position_x AS x, m.position_y AS y, "3" AS `type` FROM ?_creature_movement m, ?_creature c WHERE m.id = c.guid AND m.id IN (?a) GROUP BY ROUND(x,-2), ROUND(y,-2) ORDER BY x,y', $wpWalkingCreaturesGuids);
$data = array_merge($data, $wps);
}
}
if (count($data) > 0) {
$data = mass_coord($data);
// Сортируем массив. Зачем???
if ($data)
sort($data);
// Во временную переменную tmp заносим номер локации
$j = 0;
$tmp = $data[$j]['zone'];
// Номер массива
$n = 0;
$k = 0;
$real_count = 0;
$zonedata[$n] = array();
$zonedata[$n]['zone'] = $data[$j]['zone'];
$zonedata[$n]['name'] = $data[$j]['name'];
for ($j = 0; $j < count($data); $j++) {
// Если изменился номер карты, то начинаем новый массив
if ($tmp != $data[$j]['zone']) {
// Количество объектов на зоне
$zonedata[$n]['count'] = $k;
$n++;
$exdata[$n] = array();
$zonedata[$n] = array();
$tmp = $data[$j]['zone'];
// Заносим номер зоны в список зон
$zonedata[$n]['zone'] = $data[$j]['zone'];
// TODO: Заносим название зоны в список зон
$zonedata[$n]['name'] = $data[$j]['name'];
$k = 0;
$real_count = 0;
}
$exdata[$n][$k] = array();
$exdata[$n][$k] = $data[$j];
$k++;
if ($data[$j]['t'] <> 3) // Waypoint
$real_count++;
}
// Количество объектов на зоне
$zonedata[$n]['count'] = $real_count;
// Сортировка массивов по количеству объектов на зоне.
for ($i = 0; $i <= $n; $i++) {
for ($j = $i; $j <= $n; $j++) {
if ($zonedata[$j]['count'] > $zonedata[$i]['count']) {
unset($tmp);
$tmp = $zonedata[$i];
$zonedata[$i] = $zonedata[$j];
$zonedata[$j] = $tmp;
unset($tmp);
$tmp = $exdata[$i];
$exdata[$i] = $exdata[$j];
$exdata[$j] = $tmp;
}
}
}
$smarty->assign('zonedata', $zonedata);
$smarty->assign('exdata', $exdata);
}
}