mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
323 lines
11 KiB
PHP
323 lines
11 KiB
PHP
<?php
|
|
|
|
if (!defined('AOWOW_REVISION'))
|
|
die('illegal access');
|
|
|
|
class AjaxProfile extends AjaxHandler
|
|
{
|
|
protected $validParams = ['link', 'unlink', 'pin', 'unpin', 'public', 'private', 'avatar', 'resync', 'status', 'delete', 'purge', 'summary', 'load'];
|
|
protected $_get = array(
|
|
'id' => [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: <prId1,prId2,..,prIdN>
|
|
user: <string> [optional]
|
|
return: null
|
|
*/
|
|
}
|
|
|
|
protected function handlePin($id, $mode) // (un)favorite
|
|
{
|
|
/* params
|
|
id: <prId1,prId2,..,prIdN>
|
|
user: <string> [optional]
|
|
return: null
|
|
*/
|
|
}
|
|
|
|
protected function handlePrivacy($id, $mode) // public visibility
|
|
{
|
|
/* params
|
|
id: <prId1,prId2,..,prIdN>
|
|
user: <string> [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: <prId1,prId2,..,prIdN>
|
|
user: <string> [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],
|
|
[<anotherStatus>]...
|
|
]
|
|
*/
|
|
return '[0, [4, 10000, 1, 2]]';
|
|
}
|
|
}
|
|
|
|
protected function handleSave() // unKill a profile
|
|
{
|
|
/* params GET
|
|
id: <prId1,prId2,..,prIdN>
|
|
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: <prId1,prId2,..,prIdN>
|
|
return
|
|
null
|
|
*/
|
|
|
|
return 'NYI';
|
|
}
|
|
|
|
protected function handlePurge() // removes certain saved information but not the entire character
|
|
{
|
|
/* params
|
|
id: <prId1,prId2,..,prIdN>
|
|
data: <mode> [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 = @Game::$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;
|
|
}
|
|
|
|
}
|
|
|
|
?>
|