/** * получение данных по модераторам и запись их в memfs и memcache * moderatorsDetails[ uid ] = array( name => '', bansCount => '' ) * содержит uid, имя модератора и, возможно, кол-во банов bansCount, * которое устанавливается в chat.php при бане */ function DumpModeratorsDetails() { global $memcache; //$memcache->Delete( MODERATORS_DETAILS_MEMCACHE_KEY ); $moderatorsDetails = $memcache->Get(MODERATORS_DETAILS_MEMCACHE_KEY); //SaveForDebug( 'cron dump moder details debug, get from memcache: ' . var_export( $moderatorsDetails, true ) ); // попытка считать статистику из файла, если ее нет в memcache if ($moderatorsDetails === FALSE) { $moderatorsDetails = GetModeratorDetailsFromFile(); } if ($moderatorsDetails === FALSE) { //получаем из базы $queryString = ' SELECT users.uid, name FROM users INNER JOIN users_roles using(uid) WHERE rid IN (3,4,5) AND status = 1 GROUP BY users.uid'; $db = GetDb(); $queryResult = $db->Query($queryString); if ($queryResult === FALSE) { SaveForDebug(CHAT_RUNTIME_ERROR . ' cron dump moderrators details 1'); } while ($moderatorDetail = $queryResult->fetch_assoc()) { $moderatorsDetails[$moderatorDetail['uid']]['name'] = $moderatorDetail['name']; } //SaveForDebug( 'moderatorsDetails dump from bd' ); } $memcache->Set(MODERATORS_DETAILS_MEMCACHE_KEY, $moderatorsDetails, CHAT_MODERATORS_DETAILS_TTL); //SaveForDebug( 'send to memcache: ' . var_export( $moderatorsDetails, true ) ); $dataJS = 'var moderatorsDetails = ' . json_encode($moderatorsDetails); file_put_contents(CHAT_MODERATORS_DETAILS, $dataJS); }
function SaveNextNum($lastGeneratedSigId, $lastSigId = 0, $debugOutput) { global $sigUpdatedCount, $db; if ($lastSigId == 0) { $lastSigId = $lastGeneratedSigId + $sigUpdatedCount; } $queryString = "UPDATE " . DB_TABLE_PREFIX . "options SET value='{$lastSigId}'\r\n\t\tWHERE name='lastSigId'"; $result = $db->Query($queryString); $debugOutput .= $sigUpdatedCount . ' ' . date('H:i', time()) . ' lastSigId = ' . $lastSigId; echo $debugOutput; SaveForDebug($debugOutput); }
<?php require_once 'config.php'; require_once 'utils.php'; require_once 'db.php'; $db = new MySqlDb(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD); $queryString = 'DELETE FROM ' . DB_TABLE_PREFIX . 'data WHERE '; $debugOutput = ''; $doesOldSigExist = false; foreach (glob(SIG_BASEDIR . '*.png') as $filename) { if (time() - filemtime($filename) > SIG_TTL) { $doesOldSigExist = true; // echo "$filename - ".date( 'd M H:i:s', filemtime( $filename ) ). "\n"; preg_match("#/([\\d]+).png#", $filename, $match); if ($match[1] !== '') { $queryString .= 'sigId="' . $match[1] . '" OR '; $debugOutput .= $match[1] . ', '; } @unlink($filename); } } if ($doesOldSigExist) { $queryString = substr($queryString, 0, strlen($queryString) - 4); $queryResult = $db->Query($queryString); if ($queryResult) { $debugOutput = 'Cleaner delete sigs:' . $debugOutput; SaveForDebug($debugOutput); } } else { SaveForDebug('Cleaner doesn\'t found old sigs.'); }
require_once 'core.php'; header('Content-Type: application/javascript'); $db = GetDb(); $smilesResult = $db->Query('SELECT * FROM chat_smile ORDER BY `page` ASC, `sid` ASC'); if ($smilesResult === FALSE) { SaveForDebug('Fetching smiles failed'); return; } $smiles = array(); while ($smile = $smilesResult->fetch_assoc()) { $smile['roles'] = array(); $smiles[$smile['code']] = $smile; } $rolesResult = $db->Query('SELECT * FROM role_smiles'); if ($rolesResult === FALSE) { SaveForDebug('Fetching role smiles failed'); return; } $smile_roles = array(); while ($role = $rolesResult->fetch_assoc()) { $rid = intval($role['rid']); foreach (explode(',', $role['smiles']) as $smile) { if (array_key_exists($smile, $smiles)) { $smiles[$smile]['roles'][] = $rid; } } } $public = array(); $private = array(); foreach ($smiles as $smile) { /*if ( count( array_diff( $smile['roles'], array( 2 ) ) ) > 0 ) {
<?php require_once 'core.php'; require_once 'utils.php'; global $memcache; $memcache->Delete(MODERATORS_DETAILS_MEMCACHE_KEY); unlink(CHAT_MODERATORS_DETAILS); SaveForDebug('cron clear moderators details');
/** * бан пользователя * @param int banUid id пользователя, которого баним * @param string banUserName его имя * @param int banDurationInMin длительность бана в минутах * @param int banMessageId id сообщения, за которое выдается бан * @param int channelId id канала юзера * @param int banReasonId id причины бана, для модеров 0 * @param bool isAutoBan если автобан, TRUE, иначе FALSE * @return array возвращает массив вида * array( 'code' => 0,// код результата: 0 для ошибки | 1 для успеха 'error' => 'hack';// текст ошибки ) */ public function BanUser($banUid, $banUserName, $banDurationInMin, $banMessageId, $channelId, $banReasonId = 0, $isAutoBan = FALSE) { $banUid = (int) $banUid; $banMessageId = (int) $banMessageId; $banReasonId = (int) $banReasonId; $banDurationInMin = (int) $banDurationInMin; $channelId = (int) $channelId; // выдаем ошибку, если есть права, но неправильный id сообщения if ($this->user['rights'] === 1 && $banMessageId < 0 || $this->user['rights'] != 1 && $isAutoBan === FALSE || $banUid === 0 || $banUserName === '' || $banDurationInMin === 0 || $banReasonId < 0) { SaveForDebug(var_export($_REQUEST, TRUE)); $result = array('code' => 0, 'error' => CHAT_RUNTIME_ERROR . '2'); return $result; } $banDuration = $banDurationInMin * 60; $banExpirationTime = CURRENT_TIME + $banDuration; // проверяем флаг в memcache на случай бана от модератора или граждан $banInfoMemcacheKey = 'Chat_uid_' . $banUid . '_BanInfo'; // делаем через Add, чтобы одновременно проверить отсутствие флага // и установить его $isUserBanned = $this->memcache->Add($banInfoMemcacheKey, array('banTime' => CURRENT_TIME, 'banExpirationTime' => $banExpirationTime), $banDuration); if ($isUserBanned === FALSE) { $result = array('code' => 0, 'error' => 'Уже забанен'); return $result; } list($banUserName) = $this->db->PrepareParams($banUserName); $moderatorName = $this->user['name']; $moderatorId = $this->user['uid']; $queryString = ' INSERT INTO chat_ban ( uid, moderatorId, banExpirationTime, banMessageId, banReasonId, banTime, banDuration ) VALUES( "' . $banUid . '", "' . $moderatorId . '", "' . $banExpirationTime . '", "' . $banMessageId . '", "' . $banReasonId . '", "' . CURRENT_TIME . '", "' . $banDuration . '")'; $queryResult = $this->db->Query($queryString); if ($queryResult === FALSE) { // в случае ошибки с запросом удаляем флаг в мемкеше, // чтобы юзера можно было забанить в следующий раз $this->memcache->Delete($banInfoMemcacheKey); $result = array('code' => 0, 'error' => CHAT_RUNTIME_ERROR . '3'); return $result; } if (CHAT_DELETE_BANNED_USERS_MESSAGE && $isAutoBan === FALSE) { $queryString = ' UPDATE chat_message SET deletedBy = "' . $moderatorId . '" WHERE id = "' . $banMessageId . '"'; $queryResult = $this->db->Query($queryString); if ($queryResult === FALSE) { $this->memcache->Delete($banInfoMemcacheKey); $result = array('code' => 0, 'error' => CHAT_RUNTIME_ERROR . '4'); return $result; } } // сохраняем для модераторов кол-во банов if ($this->user['type'] === 'chatAdmin') { $moderatorsDetails = $this->memcache->Get(MODERATORS_DETAILS_MEMCACHE_KEY); // попытка считать статистику из файла, если ее нет в memcache if ($moderatorsDetails === FALSE) { $moderatorsDetails = GetModeratorDetailsFromFile(); } if ($moderatorsDetails !== FALSE) { if (isset($moderatorsDetails[$moderatorId])) { // TODO += ? if (isset($moderatorsDetails[$moderatorId]['bansCount'])) { $moderatorsDetails[$moderatorId]['bansCount'] = $moderatorsDetails[$moderatorId]['bansCount'] + 1; } else { $moderatorsDetails[$moderatorId]['bansCount'] = 1; } } else { $moderatorsDetails[$moderatorId] = array('name' => $moderatorName, 'bansCount' => 1); } $this->memcache->Set(MODERATORS_DETAILS_MEMCACHE_KEY, $moderatorsDetails, CHAT_MODERATORS_DETAILS_TTL); } } if (!$isAutoBan) { // кэш текущего канала $this->WriteChannelCache($channelId); // кэш модераторов $this->WriteChannelCache(-1); } $message = $moderatorName . ' забанил ' . $banUserName . ' на ' . $banDurationInMin . ' минут.'; $this->WriteSystemMessage($message); $result = array('code' => 1, 'error' => ''); return $result; }
/** * Определение длительности нового бана с учетом количества предыдущих и * причины бана * @param int uid - id пользователя, которого банят * @param int reasonId - id причины * @return array массив с ключами banDuration - длительность нового бана и * banSerialNumber - порядковый номер этого бана за просматриваемый период */ private function GetBanDuration($uid, $reasonId) { $banSerialNumber = 1; $timePenaltyForBan = CURRENT_TIME - CITIZEN_REPEATED_BAN_TTL * 86400; $queryString = ' SELECT uid FROM chat_ban WHERE uid = "' . $uid . '" AND status = 1 AND banReasonId = "' . $reasonId . '" AND banTime > ' . $timePenaltyForBan . ' GROUP BY banExpirationTime'; $queryResult = $this->db->Query($queryString); if ($queryResult === FALSE) { SaveForDebug($queryString); exit; } $banSerialNumber += $queryResult->num_rows; // геометрическая прогрессия 2^( n-1 ) * base, // где n - порядковый номер бана, base - длительность 1го бана // попросту - удвоение $banDuration = pow(2, $banSerialNumber - 1) * $this->GetBanDurationByReasonId($reasonId); $result = array('banDuration' => $banDuration, 'banSerialNumber' => $banSerialNumber); return $result; }
/** * получение истории * @param channelId id канала * @param startDate дата начала * @param endDate дата конца * @param userNames имена пользователей, разделенные ; * @param boolean isModeratorRequest флаг true, если запрос от модератора, иначе false * @param historyCache имя файла для сохранения кэша, если не задано, будет * использоваться */ public function Get($channelId, $startDate, $endDate, $userNames = '', $isModeratorRequest = false, $historyCache = '') { if ($isModeratorRequest == true) { $timeDifference = CHAT_HISTORY_MAX_TIME_DIFFERENCE_MODERATOR; } else { $timeDifference = CHAT_HISTORY_MAX_TIME_DIFFERENCE; } $startDate = $this->PrepareDate($startDate); $endDate = $this->PrepareDate($endDate); $startTime = strtotime($startDate); $endTime = strtotime($endDate); if ($startTime === FALSE || $endTime === FALSE || $endTime - $startTime > $timeDifference) { $result = array('messages' => '', 'error' => CHAT_HISTORY_CHECK_PARAMS); return $result; } $options = ''; $userNamesCopy = ''; if ($userNames != '') { $userNames = $this->PrepareUserNames($userNames); $userNamesCopy = $userNames; $userNames = explode(';', $userNames); if (count($userNames) > 0) { $options = '('; $operator = ''; $this->db = GetDb(); foreach ($userNames as $userName) { list($userName) = $this->db->PrepareParams($userName); // если длина логина больше максимальной, прислали что-то не то if (mb_strlen($userName) > CHAT_MAX_USERNAME_LENGTH) { SaveForDebug($userNamesCopy . "\n\n" . $userName); $result = array('messages' => '', 'error' => CHAT_USERNAME_TOO_LONG); return $result; } $options .= $operator . 'name="' . $userName . '"'; if ($operator === '') { $operator = ' OR '; } } $options .= ') AND '; } } if (!($channelId == '' || $channelId == 'all')) { $channelId = (int) $channelId; $options .= 'channelId = "' . $channelId . '" AND '; } $queryString = ' SELECT id, chat_message.uid, name, message, date, channelId, ( SELECT IFNULL(( SELECT min(rid) FROM users_roles WHERE users_roles.uid = chat_message.uid), 2 ) ) as rid FROM chat_message INNER JOIN users using(uid) WHERE ' . $options . ' date BETWEEN STR_TO_DATE("' . $startDate . '", "%Y-%m-%d %H:%i:%s") AND STR_TO_DATE("' . $endDate . '", "%Y-%m-%d %H:%i:%s") AND deletedBy is NULL'; //echo '<!--' . $queryString . '-->';exit; $this->db = GetDb(); $queryResult = $this->db->Query($queryString); if ($queryResult === false) { SaveForDebug($queryResult); $result = array('messages' => '', 'error' => CHAT_RUNTIME_ERROR . ' history 1'); return $result; } $messages = array(); while ($msg = $queryResult->fetch_assoc()) { $messages[] = $msg; } $dataJson = json_encode(array('messages' => $messages)); if ($historyCache == '') { $historyCache = $channelId . '_' . $startDate . '_' . $endDate . '_' . $userNamesCopy . '.json'; $historyCache = preg_replace('#[\\s]+#uis', '_', $historyCache); } $historyCache = CHAT_HISTORY_MEMFS_DIR . '/' . $historyCache; file_put_contents($historyCache, $dataJson); $historyCacheGz = $historyCache . '.gz'; $historyCacheGzFile = gzopen($historyCacheGz, 'w'); gzwrite($historyCacheGzFile, $dataJson); gzclose($historyCacheGzFile); $result = array('messages' => $messages, 'error' => ''); return $result; }
/** * получение истории автомодерации * @param int channelId id канала * @param string startDate дата начала * @param string endDate дата конца * @param string userNames имена модераторов, разделенные ; * @param string bannedNickNames имена забаненных пользователей, разделенные ; * @param boolean isModeratorRequest флаг true, если запрос от модератора, иначе false * @param string historyCache имя файла для сохранения кэша, если не задано, будет * использоваться last.json */ public function Get($channelId, $startDate, $endDate, $userNames = '', $bannedNickNames = '', $isModeratorRequest = false, $historyCache = '') { if ($isModeratorRequest == true) { $timeDifference = CHAT_HISTORY_MAX_TIME_DIFFERENCE_MODERATOR; } else { $timeDifference = CHAT_HISTORY_MAX_TIME_DIFFERENCE; } $startDate = $this->PrepareDate($startDate); $endDate = $this->PrepareDate($endDate); $startTime = strtotime($startDate); $endTime = strtotime($endDate); if ($startTime === FALSE || $endTime === FALSE || $endTime - $startTime > $timeDifference) { $result = array('messages' => '', 'error' => CHAT_HISTORY_CHECK_PARAMS); return $result; } $options = ''; $userNamesCopy = ''; if ($userNames != '') { $userNames = $this->PrepareNickNames($userNames); $userNamesCopy = $userNames; $userNames = explode(';', $userNames); if (count($userNames) > 0) { $options = '('; $operator = ''; $this->db = GetDb(); foreach ($userNames as $currentNick) { list($currentNick) = $this->db->PrepareParams($currentNick); // если длина логина больше максимальной, прислали что-то не то if (mb_strlen($currentNick) > CHAT_MAX_USERNAME_LENGTH) { SaveForDebug($userNamesCopy . "\n\n" . $currentNick); $result = array('messages' => '', 'error' => CHAT_USERNAME_TOO_LONG); return $result; } $options .= $operator . ' mu.name = "' . $currentNick . '"'; if ($operator === '') { $operator = ' OR '; } } $options .= ') AND '; } } $bannedNickNamesCopy = ''; if ($bannedNickNames != '') { $bannedNickNames = $this->PrepareNickNames($bannedNickNames); $bannedNickNamesCopy = $bannedNickNames; $bannedNickNames = explode(';', $bannedNickNames); if (count($bannedNickNames) > 0) { $options .= '('; $operator = ''; $this->db = GetDb(); foreach ($bannedNickNames as $currentNick) { list($currentNick) = $this->db->PrepareParams($currentNick); // если длина логина больше максимальной, прислали что-то не то if (mb_strlen($currentNick) > CHAT_MAX_USERNAME_LENGTH) { SaveForDebug($userNamesCopy . "\n\n" . $currentNick); $result = array('messages' => '', 'error' => CHAT_USERNAME_TOO_LONG); return $result; } $options .= $operator . ' ru.name = "' . $currentNick . '"'; if ($operator === '') { $operator = ' OR '; } } $options .= ') AND '; } } $channelOptions = ''; if (!($channelId == '' || $channelId == 'all')) { $channelId = (int) $channelId; $options .= 'channelId = "' . $channelId . '" AND '; } $queryString = ' SELECT chat_ban.id, ru.uid as bannedUserId, ru.name as userName, chat_ban.banExpirationTime, chat_ban.banMessageId, chat_ban.banTime, chat_ban.banDuration, chat_ban.banModificationUserId, chat_message.message as bannedForMessage, chat_ban.status as chatBanStatus, chat_ban.banReasonId, mu.name as moderatorName, banModificationReason FROM chat_ban INNER JOIN users AS ru ON ru.uid = chat_ban.uid INNER JOIN users AS mu ON mu.uid = chat_ban. moderatorId LEFT OUTER JOIN chat_message on chat_message.id = banMessageId WHERE ' . $options . ' banTime BETWEEN "' . strtotime($startDate) . '" AND "' . strtotime($endDate) . '"'; //echo '<!--' . $queryString . '-->'; $this->db = GetDb(); $queryResult = $this->db->Query($queryString); if ($queryResult === false) { SaveForDebug($queryResult); $result = array('messages' => '', 'error' => CHAT_RUNTIME_ERROR . ' am history 1'); return $result; } $messages = array(); while ($msg = $queryResult->fetch_assoc()) { $messages[] = $msg; } $dataJson = json_encode(array('messages' => $messages)); if ($historyCache == '') { $historyCache = $channelId . '_' . $startDate . '_' . $endDate . '_' . $userNamesCopy . '_' . $bannedNickNamesCopy . '.json'; $historyCache = preg_replace('#[\\s]+#uis', '_', $historyCache); } $historyCache = CHAT_AUTOMODERATION_HISTORY_MEMFS_DIR . '/' . $historyCache; file_put_contents($historyCache, $dataJson); $historyCacheGz = $historyCache . '.gz'; $historyCacheGzFile = gzopen($historyCacheGz, 'w'); gzwrite($historyCacheGzFile, $dataJson); gzclose($historyCacheGzFile); $result = array('messages' => $messages, 'error' => ''); return $result; }
/** * @param int $sigId * @param int $playerId * @param int $bnetServerNum * @param string $playerAccount * @param int $sigBackgroundIndex * @param int $playerStatsIndex * @param string $lang * @param string $region * @param int $characterCode * @return boolean */ public static function Create($sigId, $playerId, $bnetServerNum, $playerAccount, $sigBackgroundIndex = 1, $playerStatsIndex, $lang, $region, $characterCode) { // ник preg_match('/[^a-z0-9\\-ǂ]*/ui', $playerAccount, $match); if ($match[0]) { // с русскими символами $fontAccount = 'calibri.ttf'; } else { $fontAccount = 'eurostile_ext_med.otf'; } $fontAccount = SIG_BASEDIR . 'php/' . $fontAccount; // echo $playerAccount.' '.$fontAccount."\n"; // языки \ локали $locale['ru']['notRanked'] = ' НЕТ РЕЙТИНГА'; $locale['ru']['place'] = 'МЕСТО'; $locale['ru']['points'] = 'ОЧКИ'; $locale['ru']['region'] = 'РЕГИОН'; $locale['ru']['wins'] = 'ПОБЕД'; $locale['en']['notRanked'] = ' NOT YET RANKED'; $locale['en']['place'] = 'PLACE'; $locale['en']['points'] = 'POINTS'; $locale['en']['region'] = 'REGION'; $locale['en']['wins'] = 'WINS'; if (!($lang == 'ru' || $lang == 'en')) { $lang = 'ru'; } $bnetSubDomain = 'eu'; if ($region === 'US' || $region === 'KR') { $bnetSubDomain = strtolower($region); } elseif ($region === 0) { $region = false; } $sigPath = SIG_BASEDIR . $sigId . '.png'; require_once 'network.php'; $playerAccountUrl = urlencode($playerAccount); $relativePlayerAccountUrl = "/sc2/en/profile/{$playerId}/{$bnetServerNum}/{$playerAccountUrl}/"; $relativePlayerAccountUrlForRegExp = "/sc2/en/profile/{$playerId}/{$bnetServerNum}/{$playerAccount}/"; $data = Network::GetHTTPData("http://{$bnetSubDomain}.battle.net" . $relativePlayerAccountUrl . 'ladder/', 'id="portrait', 'class="module-right'); if (!$data) { return false; } switch ($playerStatsIndex) { case 0: $playerStatsType = '1v1'; break; case 1: $playerStatsType = '2v2'; break; case 2: $playerStatsType = '3v3'; break; case 3: $playerStatsType = '4v4'; break; default: $playerStatsType = '1v1'; break; } if ($characterCode) { $regionX = 133; } else { $regionX = 170; } if ($characterCode || $region) { $playerAccountY = 19; } else { $playerAccountY = 24; } // получаем число ачивок preg_match('/h3>([\\d]*)</si', $data, $match); $playerAchievements = $match[1]; // определяем координаты портрета персонажа if (preg_match("#portraits/([-\\d]+).jpg.*?'\\) ([-\\d]+)px ([-\\d]+)px no#si", $data, $match)) { // из какой заготовки будем брать $portraitImg = 'portraits-' . $match[1]; // координаты, откуда будем брать $portraitX = abs($match[2] * PORTRAIT_KOEFICENT); $portraitY = abs($match[3] * PORTRAIT_KOEFICENT); } else { SaveForDebug("portraitImg is empty, http://{$bnetSubDomain}.battle.net" . $relativePlayerAccountUrl . 'ladder/'); return FALSE; } if (preg_match('#<a class="league" href="([\\d]+)\\#current-rank">[\\w\\s]+<strong>' . $playerStatsType . '[\\w\\s]*</strong>.*?<a href="' . $relativePlayerAccountUrlForRegExp . '"[\\s]+class="race-([\\w]+)".*?Rank[\\s]+([\\d]+)#si', $data, $match)) { $currentRankUrl = $match[1]; // место $isPlayerHasRank = true; $playerRank = $locale[$lang]['place'] . ': ' . $match[3]; // раса $playerRace = $match[2]; } else { $playerStats = ' ' . $playerStatsType . $locale[$lang]['notRanked']; $leagueImg = 'none'; $isPlayerHasRank = false; $playerRace = 'random'; } if ($isPlayerHasRank) { $data = Network::GetHTTPData('http://' . $bnetSubDomain . '.battle.net' . $relativePlayerAccountUrl . 'ladder/' . $currentRankUrl, '<head.*>', 'id="current-rank".*?tr class="row2"'); if (!$data) { return false; } // лига if (preg_match_all('|<title>' . $playerStatsType . ' ([\\w]+) |si', $data, $match)) { $leagueImg = strtolower($match[1][0]); } else { $leagueImg = 'none'; } if (preg_match('|id="current-rank"(.*?)tr class|si', $data, $match)) { $data = $match[1]; if (preg_match_all('|<td class="align-center">([\\d]+)</td>|si', $data, $match)) { $playerPoints = $locale[$lang]['points'] . ': ' . $match[1][0]; $wins = $match[1][1]; if (isset($match[1][2])) { $lose = $match[1][2]; $playerStats = "{$wins} / {$lose}"; $playerWinRate = round($wins * 100 / ($wins + $lose)) . ' %'; } else { $playerStats = $locale[$lang]['wins'] . ': ' . $wins; } } } } $playerImgResource = imagecreatetruecolor(358, 68); // берем шаблон $templateImg = imagecreatefrompng(SIG_BASEDIR . 'img/sig/med_back_' . $sigBackgroundIndex . '.png'); // белый цвет по контуру становится прозрачным $transparentColor = imagecolorallocate($playerImgResource, 255, 255, 255); imagecolortransparent($playerImgResource, $transparentColor); // берем портрет $portrait = imagecreatefrompng(SIG_BASEDIR . 'img/sig/' . $portraitImg . '.png'); // лигу $league = imagecreatefrompng(SIG_BASEDIR . 'img/sig/leg_' . $leagueImg . '.png'); // расу $raceTemplateImg = imagecreatefrompng(SIG_BASEDIR . "img/sig/race_{$playerRace}.png"); // выбираем подходящий цвет текста и фон для bnetId list($textColor, $bnetIdTpl) = Sig::SelectTextColorAndBnetIdTplByBackgroundIndex($templateImg, $sigBackgroundIndex); // выводим все // первая строка, первый блок if (isset($playerRank)) { imagettftext($templateImg, TEXT_FONT_SIZE, 0, 101, 46, $textColor, FONT_STATS_RANK, $playerRank); } // первая строка, второй блок if (isset($playerPoints)) { imagettftext($templateImg, TEXT_FONT_SIZE, 0, 162, 46, $textColor, FONT_STATS_RANK, $playerPoints); } // вторая строка, первый блок if (isset($playerStats)) { imagettftext($templateImg, TEXT_FONT_SIZE, 0, 101, 57, $textColor, FONT_STATS_RANK, $playerStats); } // вторая строка, второй блок if (isset($playerWinRate)) { imagettftext($templateImg, TEXT_FONT_SIZE, 0, 162, 57, $textColor, FONT_STATS_RANK, $playerWinRate); } $box_nik = imagettfbbox(11, 0, $fontAccount, $playerAccount); // 237 - 12 - $box_nik[ 2 ] = 225 - $box_nik[ 2 ] imagettftext($templateImg, 11, 0, 223 - $box_nik[2], $playerAccountY, $textColor, $fontAccount, $playerAccount); if (isset($playerAchievements)) { imagettftext($templateImg, 9, 0, 302, 19, $textColor, FONT_ACHIEVEMENTS, $playerAchievements); } if (isset($playerStatsType)) { imagettftext($templateImg, 9, 0, 320, 51, $textColor, FONT_ACHIEVEMENTS, $playerStatsType); } if ($characterCode) { imagettftext($templateImg, 8, 0, 191, 31, $textColor, FONT_STATS_RANK, ' ID: ' . $characterCode); } if ($region) { imagettftext($templateImg, 8, 0, $regionX, 31, $textColor, FONT_STATS_RANK, $locale[$lang]['region'] . ': ' . $region); } imagecopyresampled($playerImgResource, $templateImg, 0, 0, 0, 0, 358, 68, imagesx($templateImg), imagesy($templateImg)); imagecopyresampled($playerImgResource, $portrait, 237, 12, $portraitX, $portraitY, 46, 46, 46, 46); imagecopyresampled($playerImgResource, $league, 292, 31, 0, 0, 26, 28, 26, 28); imagecopyresampled($playerImgResource, $raceTemplateImg, 219, 43, 0, 0, 18, 18, 18, 18); imagepng($playerImgResource, $sigPath); // не забываем освобождать за собой память imagedestroy($playerImgResource); imagedestroy($templateImg); imagedestroy($portrait); imagedestroy($league); imagedestroy($raceTemplateImg); return true; }