diff --git a/composer.json b/composer.json index fd1ea70..f42e753 100644 --- a/composer.json +++ b/composer.json @@ -53,6 +53,7 @@ "knplabs/github-api": "^2.9", "lcobucci/jwt": "^3.2", "linfo/linfo": "^4.0", + "meyfa/php-svg": "^0.9.0", "nelexa/zip": "^3.1", "php-http/guzzle6-adapter": "^1.1", "statickidz/php-google-translate-free": "^1.0" diff --git a/composer.lock b/composer.lock index e979967..ca78531 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "1e3d4a77d4437524ea4f86a7b6a37a2d", + "content-hash": "b10a281952b669fb32d8c184b7a118d7", "packages": [], "packages-dev": [ { @@ -489,6 +489,51 @@ ], "time": "2018-04-05T06:29:11+00:00" }, + { + "name": "meyfa/php-svg", + "version": "v0.9.0", + "source": { + "type": "git", + "url": "https://github.com/meyfa/php-svg.git", + "reference": "1680eca33c0e107439969650904ab08ecfe83603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/meyfa/php-svg/zipball/1680eca33c0e107439969650904ab08ecfe83603", + "reference": "1680eca33c0e107439969650904ab08ecfe83603", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "meyfa/phpunit-assert-gd": "^1.1", + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "SVG\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabian Meyer", + "homepage": "http://meyfa.net" + } + ], + "description": "Read, edit, write, and render SVG files with PHP", + "homepage": "https://github.com/meyfa/php-svg", + "keywords": [ + "svg" + ], + "time": "2018-07-25T10:30:00+00:00" + }, { "name": "nelexa/zip", "version": "3.1.5", diff --git a/module/help/osu.php b/module/help/osu.php index a4ef4a8..eb73ec1 100644 --- a/module/help/osu.php +++ b/module/help/osu.php @@ -5,7 +5,7 @@ $msg=<< \ No newline at end of file diff --git a/module/osu/Exo2-Italic.ttf b/module/osu/Exo2-Italic.ttf index 383e3b0..90c23b1 100644 Binary files a/module/osu/Exo2-Italic.ttf and b/module/osu/Exo2-Italic.ttf differ diff --git a/module/osu/bind.php b/module/osu/bind.php index 8adbf45..45b5088 100644 --- a/module/osu/bind.php +++ b/module/osu/bind.php @@ -1,14 +1,13 @@ username; +$userRealname = get_user($osu_api_key, $username)['username']; setOsuID($Event['user_id'], $userRealname); diff --git a/module/osu/bp.php b/module/osu/bp.php index e732a66..b0e113a 100644 --- a/module/osu/bp.php +++ b/module/osu/bp.php @@ -1,8 +1,10 @@ 'imagick')); - -$withMeText = false; - -do{ - $arg = nextArg(); - switch($arg){ - case '-withMe': - $withMeText = true; - break; - case '-osu': - case '-std': - $mode = 'osu'; - break; - case '-taiko': - $mode = 'taiko'; - break; - case '-ctb': - case '-fruit': - case '-fruits': - $mode = 'fruits'; - break; - case '-mania': - $mode = 'mania'; - break; - case '-user': - $osuid = nextArg(); - break; - default: - - } -}while($arg !== NULL); - -$osuid = $osuid??getOsuID($Event['user_id']); - -if($osuid == ''){ - throw new \Exception('未绑定 osu!'); -} - -$osuid = OsuUsernameEscape($osuid); - -$web = file_get_contents('https://osu.ppy.sh/users/'.$osuid.'/'.$mode); - -$target = ''); - -$userJson = substr($web, $start+strlen($target), $end-strlen($target)); - -$user = json_decode($userJson); - -//初始化绘图环境 -$here = __DIR__.'/'; -$exo2 = $here.'Exo2-Regular.ttf'; -$exo2_italic = $here.'Exo2-Italic.ttf'; -$exo2_bold = $here.'Exo2-Bold.ttf'; -$yahei = $here.'Yahei.ttf'; -$white = '#ffffff'; -$mode = $mode??$user->playmode; -$badges = $user->badges; -$badge = $badges[rand(0, count($badges)-1)]; -$flag = file_exists($here."flags/{$user->country->code}.png")?($here."flags/{$user->country->code}.png"):($here.'flags/__.png'); -$stats_key = imageFont($yahei, 12, $white); -$statics = $user->statistics; -try{ - $avatar = Image::make('https://a.ppy.sh/'.$user->id); -}catch(\Exception $e){ - $avatar = Image::make($here.'avatar-guest.png'); -} -$playtime = [ - 'hours' => sprintf('%d', $statics->play_time/3600), - 'minutes' => sprintf('%d', ($statics->play_time%3600)/60), - 'seconds' => sprintf('%d', $statics->play_time%60), -]; -$stat = [ - 'Ranked 谱面总分' => number_format($statics->ranked_score), - '准确率' => sprintf('%.2f%%', $statics->hit_accuracy), - '游戏次数' => number_format($statics->play_count), - '总分' => number_format($statics->total_score), - '总命中次数' => number_format($statics->total_hits), - '最大连击' => number_format($statics->maximum_combo), - '回放被观看次数' => number_format($statics->replays_watched_by_others), -]; -$grade = [ - 'XH' => $statics->grade_counts->ssh, - 'X' => $statics->grade_counts->ss, - 'SH' => $statics->grade_counts->sh, - 'S' => $statics->grade_counts->s, - 'A' => $statics->grade_counts->a, -]; -//开始绘图 -$img = Image::make($user->cover_url); -$img->resize(1000, 350) - ->insert(Image::canvas(1000, 350)->fill([0, 0, 0, 0.5])) //背景暗化50% - ->insert($avatar->resize(110, 110), 'top-left', 40, 220) //插入头像 - ->text($user->username, 170, 256, imageFont($exo2_italic, 24, $white, 'left', 'top')) //插入用户名 - ->text($user->title, 170, 285, imageFont($exo2_italic, 15, $white, 'left', 'top')) //插入title - ; -if($badge!=NULL)$img->insert(Image::make($badge->image_url), 'top-left', 40, 168); //插入狗牌 -if($user->is_supporter){ - $img->insert(Image::make($here.'heart.png')->resize(28, 28), 'top-left', 170, 223) //插入支持者标志 - ->insert(Image::make($here."modes/{$mode}.png")->resize(28, 28), 'top-left', 210, 223) //插入模式标志 - ; -}else{ - $img->insert(Image::make($here."modes/{$mode}.png")->resize(28, 28), 'top-left', 170, 223); //插入模式标志 -} -$img->insert(Image::make($flag)->resize(30, 20), 'top-left', 170, 310) //插入国旗 - ->insert(Image::canvas(280, 323)->fill([0, 0, 0, 0.3]), 'top-left', 670, 27) //绘制右侧暗化 - ->text('游戏时间', 690, 50, $stats_key) - ->text("{$playtime['hours']}小时 {$playtime['minutes']}分钟 {$playtime['seconds']}秒", 690, 72, imageFont($yahei, 18, '#ffcc22')) - ->insert(Image::make($here.'levelbadge.png')->resize(50, 50), 'top-left', 880, 30) - ->text($statics->level->current, 905, 45, imageFont($exo2_bold, 18, $white, 'center', 'middle')) -; -$yIndex = 120; -foreach($stat as $key => $value){ - $img->text($key, 690, $yIndex, $stats_key); - $img->text($value, 930, $yIndex, imageFont($exo2_bold, 16, $white, 'right')); - $yIndex+=20; -} -$img->text(sprintf('%.2f', $statics->pp), 690, 280, imageFont($exo2_bold, 40, $white)); -$img->text('PP', 740, 300, imageFont($exo2_bold, 20, $white)); -$img->text('#'.number_format($statics->rank->global), 930, 280, imageFont($exo2_bold, 20, $white, 'right')); -$img->text($user->country->code.' '.'#'.number_format($statics->rank->country), 930, 300, imageFont($exo2_bold, 20, $white, 'right')); -$xIndex = 675; -foreach($grade as $key => $value){ - $img->insert(Image::make($here."{$key}.png")->resize(50, 50), 'top-left', $xIndex, 300); - $img->text($value, $xIndex+20, 350, imageFont($exo2_bold, 16, $white, 'center', 'buttom')); - $xIndex+=55; -} -$img->save('../storage/cache/'.$Event['message_id']); - -$msg = sendImg(getCache($Event['message_id'])); -if($withMeText)$msg.="\n".preg_replace('/\n+/', "\n", str_replace('
', "\n", htmlspecialchars_decode(strip_tags($user->page->html, '
')))); - -$Queue[]= sendBack($msg); - - -?> \ No newline at end of file +loadModule('osu.profile'); diff --git a/module/osu/mp/blue.png b/module/osu/mp/blue.png new file mode 100644 index 0000000..4a60d86 Binary files /dev/null and b/module/osu/mp/blue.png differ diff --git a/module/osu/mp/head-to-head.svg b/module/osu/mp/head-to-head.svg new file mode 100644 index 0000000..7083fb1 --- /dev/null +++ b/module/osu/mp/head-to-head.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/module/osu/mp/jump.php b/module/osu/mp/jump.php new file mode 100644 index 0000000..0803c42 --- /dev/null +++ b/module/osu/mp/jump.php @@ -0,0 +1,35 @@ +latest_event_id; + +$historyJson = file_get_contents("https://osu.ppy.sh/community/matches/{$matchID}/history?before={$latestEventID}&limit={$limit}"); +$history = json_decode($historyJson); +$events = $history->events; +$users = getEventUsers($history->users); + +decCredit($User_id, count($events)); + +$count = 0; +foreach($events as $event){ + $Queue[]= sendBack(parseEvent($event, $users)); + $count++; + if($event->detail->type == 'other' && $event->game->end_time == NULL){addCredit($User_id, count($events)-$count+1);break;} + setData("osu/mp/{$User_id}", "{$matchID} {$event->id}"); + if($event->detail->type == 'match-disbanded'){ + unlink("../storage/data/osu/mp/{$User_id}"); + } +} + +$Queue[]= sendBack('你的余额为 '.getCredit($User_id)); + +?> diff --git a/module/osu/mp/none.png b/module/osu/mp/none.png new file mode 100644 index 0000000..b5d9e94 Binary files /dev/null and b/module/osu/mp/none.png differ diff --git a/module/osu/mp/red.png b/module/osu/mp/red.png new file mode 100644 index 0000000..1990c0e Binary files /dev/null and b/module/osu/mp/red.png differ diff --git a/module/osu/mp/refresh.php b/module/osu/mp/refresh.php new file mode 100644 index 0000000..acbf060 --- /dev/null +++ b/module/osu/mp/refresh.php @@ -0,0 +1,33 @@ +events; +$users = getEventUsers($history->users); + +decCredit($User_id, count($events)); + +$count = 0; +foreach($events as $event){ + $Queue[]= sendBack(parseEvent($event, $users)); + $count++; + if($event->detail->type == 'other' && $event->game->end_time == NULL){addCredit($User_id, count($events)-$count+1);break;} + setData("osu/mp/{$User_id}", "{$matchID} {$event->id}"); + if($event->detail->type == 'match-disbanded'){ + unlink("../storage/data/osu/mp/{$User_id}"); + } +} + +$Queue[]= sendBack('你的余额为 '.getCredit($User_id)); + +?> diff --git a/module/osu/mp/start.php b/module/osu/mp/start.php new file mode 100644 index 0000000..c834c9a --- /dev/null +++ b/module/osu/mp/start.php @@ -0,0 +1,25 @@ +users); + +$firstEvent = $history->events[0]; +$eventTime = convertTimestamp($firstEvent->timestamp)->format('Y-m-d H:i:s'); +$Queue[]= sendBack("开始监听 mp_{$matchID}\n房间由 {$users[$firstEvent->user_id]->username} 创建于 {$eventTime}"); +$Queue[]= sendBack('你的余额为 '.getCredit($User_id)); + +setData("osu/mp/{$User_id}", "{$matchID} {$firstEvent->id}"); + +?> diff --git a/module/osu/mp/stop.php b/module/osu/mp/stop.php new file mode 100644 index 0000000..af1fcb1 --- /dev/null +++ b/module/osu/mp/stop.php @@ -0,0 +1,5 @@ + diff --git a/module/osu/mp/tag-coop.svg b/module/osu/mp/tag-coop.svg new file mode 100644 index 0000000..7e49535 --- /dev/null +++ b/module/osu/mp/tag-coop.svg @@ -0,0 +1,17 @@ + + + + + + + diff --git a/module/osu/mp/tag-team-vs.svg b/module/osu/mp/tag-team-vs.svg new file mode 100644 index 0000000..fad74d5 --- /dev/null +++ b/module/osu/mp/tag-team-vs.svg @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/module/osu/mp/team-vs.svg b/module/osu/mp/team-vs.svg new file mode 100644 index 0000000..d311ada --- /dev/null +++ b/module/osu/mp/team-vs.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/module/osu/mp/tools.php b/module/osu/mp/tools.php new file mode 100644 index 0000000..102ea3b --- /dev/null +++ b/module/osu/mp/tools.php @@ -0,0 +1,172 @@ +setTimezone(new DateTimeZone('Asia/Shanghai')); +} + +function getEventUsers($eventUsers){ + foreach($eventUsers as $user){ + $users[$user->id] = $user; + } + return $users; +} + +function parseEvent($event, $users){ + $time = '['.convertTimestamp($event->timestamp)->format('Y-m-d H:i:s').']'; + switch($event->detail->type){ + case 'match-created': + return ''; //start时已经播报过了 + case 'player-joined': + return $time." {$users[$event->user_id]->username} 加入了房间"; + case 'host-changed': + return $time." {$users[$event->user_id]->username} 成为房主"; + case 'player-kicked': + return $time." {$users[$event->user_id]->username} 被踢出房间"; + case 'player-left': + return $time." {$users[$event->user_id]->username} 离开了房间"; + case 'match-disbanded': + return $time.' 房间被关闭'; + case 'other': + global $Event; + $img = drawMatchEvent($event, $users); + $img->save('../storage/cache/'.$Event['message_id']); + return sendImg(getCache($Event['message_id'])); + default: + return ''; + } +} + +function drawMatchEvent($event, $users){ + $game = $event->game; + $beatmap = $game->beatmap; + $scores = $game->scores; + $here = __DIR__.'/'; + $outside = $here.'../'; + $exo2 = $outside.'Exo2-Regular.ttf'; + $exo2_italic = $outside.'Exo2-Italic.ttf'; + $exo2_bold = $outside.'Exo2-Bold.ttf'; + $yahei = $outside.'Yahei.ttf'; + $white = '#ffffff'; + $startTime = convertTimestamp($game->start_time)->format('H:i'); + $endTime = convertTimestamp($game->end_time)->format('H:i'); + $teamTypeImg = Image::make(SVG::fromFile($here.$game->team_type.'.svg')->toRasterImage(40, 40)); + try{ + $img = Image::make($beatmap->beatmapset->covers->cover)->fit(960, 150); //slimcover不一定能获取到,所以使用cover + }catch(\Exception $e){ + $img = Image::canvas(960, 150, '#888888'); + } + //TODO 添加MOD图标 + $img->insert(Image::canvas(960, 150)->fill([0, 0, 0, 0.5])) //暗化50% + ->insert($teamTypeImg, 'top-left', 910, 100) + ->text($beatmap->beatmapset->title."[{$beatmap->version}]", 10, 120, imageFont($exo2_italic, 20, $white)) + ->text($beatmap->beatmapset->artist, 10, 140, imageFont($exo2_italic, 14, $white)); + if($scores==[]){ + $img->text("{$startTime} - (match in progress) {$game->mode} {$game->scoring_type}", 10, 20, imageFont($exo2_italic, 14, $white)); + return $img; + } + $img->text("{$startTime} - {$endTime} {$game->mode} {$game->scoring_type}", 10, 20, imageFont($exo2_italic, 14, $white)); + + $eventResult = Image::canvas(960, 155 + 79*count($scores), 'rgb(238, 238, 238)') + ->insert($img); + $xIndex = 10; + $yIndex = 155; + + switch($game->team_type){ + case 'head-to-head': + usort($scores, function($scoreA, $scoreB){ + return $scoreB->score - $scoreA->score; + });break; + case 'team-vs': + foreach($scores as $score){ + if($score->multiplayer->team == 'red')$redScore += $score->score; + if($score->multiplayer->team == 'blue')$blueScore += $score->score; + } + usort($scores, function($scoreA, $scoreB) use ($redScore, $blueScore){ + if($scoreA->multiplayer->team == 'red' && $scoreB->multiplayer->team == 'blue'){ + if($redScore > $blueScore)return -1; + else return 1; + }else if($scoreA->multiplayer->team == $scoreB->multiplayer->team){ + return $scoreB->score - $scoreA->score; + }else{ + if($redScore > $blueScore)return 1; + else return -1; + } + });break; + case 'tag-coop': + case 'tag-team-vs': + default: //TODO 完成tag的排序方案 + } + + foreach($scores as $score){ + $eventResult->insert(drawPlayerMatchScore($score, $users[$score->user_id], $game->mode), 'top-left', $xIndex, $yIndex); + $yIndex+=79; + } + + return $eventResult; +} + +function drawPlayerMatchScore($score, $user, $mode){ + $here = __DIR__.'/'; + $outside = $here.'../'; + $exo2_italic = $outside.'Exo2-Italic.ttf'; + $exo2_bold = $outside.'Exo2-Bold.ttf'; + $yahei = $outside.'Yahei.ttf'; + $white = '#ffffff'; + $blue = '#2299bb'; + $purple = '#6644cc'; + $pink = '#bb1177'; + $gray = '#555555'; + $light_gray = '#999999'; + $label_small = imageFont($exo2_italic, 10, $gray, 'right'); + $label_large = imageFont($exo2_italic, 12, $light_gray, 'right'); + $number_medium = imageFont($exo2_italic, 14, $purple); + $img = Image::canvas(940, 74, $white); + $team = Image::make($here.$score->multiplayer->team.'.png')->resize(40, 74); + $flag = Image::make($outside."flags/{$user->country_code}.png")->resize(30, 20); + + //TODO 添加MOD图标 + $img->insert($team) + ->text($user->username, 45, 28, imageFont($exo2_italic, 18, $blue)) + ->insert($flag, 'top-left', 45, 37) + ->text('Combo', 500, 35, $label_small) + ->text(number_format($score->max_combo), 540, 35, $number_medium) + ->text('Accuracy', 655, 35, $label_small) + ->text(sprintf('%.2f%%', $score->accuracy*100), 710, 35, $number_medium) + ->text(number_format($score->score), 790, 35, imageFont($exo2_italic, 25, $pink, 'right')) + ->text('miss', 875, 65, $label_large) + ->text(number_format($score->statistics->count_miss), 905, 65, $number_medium) + ->text('50', 830, 65, $label_large) + ->text(number_format($score->statistics->count_50), 850, 65, $number_medium) + ->text('100', 775, 65, $label_large) + ->text(number_format($score->statistics->count_100), 800, 65, $number_medium) + ; + + if(!$score->multiplayer->pass){ + $img->text('FAILED', 215, 28, imageFont($exo2_bold, 15, '#ed1221')); + } + + switch($mode){ + case 'mania': + $img + ->text('200', 710, 65, $label_large) + ->text(number_format($score->statistics->count_katu), 733, 65, $number_medium) + ->text('300', 640, 65, $label_large) + ->text(number_format($score->statistics->count_300), 665, 65, $number_medium) + ->text('MAX', 570, 65, $label_large) + ->text(number_format($score->statistics->count_geki), 598, 65, $number_medium) + ; + break; + default: + $img + ->text('300', 710, 65, $label_large) + ->text(number_format($score->statistics->count_300), 733, 65, $number_medium) + ; + } + + return $img; +} + +?> diff --git a/module/osu/profile.php b/module/osu/profile.php new file mode 100644 index 0000000..e50aa03 --- /dev/null +++ b/module/osu/profile.php @@ -0,0 +1,155 @@ + 'imagick')); + +$withMeText = false; +$qq = $User_id; + +do{ + $arg = nextArg(); + switch($arg){ + case '-withMe': + $withMeText = true; + break; + case '-osu': + case '-std': + $mode = 'osu'; + break; + case '-taiko': + $mode = 'taiko'; + break; + case '-ctb': + case '-fruit': + case '-fruits': + $mode = 'fruits'; + break; + case '-mania': + $mode = 'mania'; + break; + case '-user': + $temp = nextArg(); + if(parseQQ($temp)!==NULL){ + $qq = parseQQ($temp); + $osuid = getOsuID($qq); + if($osuid=='')leave('指定的用户未绑定 osu!'); + }else{ + $osuid = $temp; + } + break; + default: + + } +}while($arg !== NULL); + +$osuid = $osuid??getOsuID($qq); + +if($osuid == ''){ + throw new \Exception('未绑定 osu!'); +} + +$osuid = OsuUsernameEscape($osuid); + +$web = file_get_contents('https://osu.ppy.sh/users/'.$osuid.'/'.$mode); + +$target = ''); + +$userJson = substr($web, $start+strlen($target), $end-strlen($target)); + +$user = json_decode($userJson); + +//初始化绘图环境 +$here = __DIR__.'/'; +$exo2 = $here.'Exo2-Regular.ttf'; +$exo2_italic = $here.'Exo2-Italic.ttf'; +$exo2_bold = $here.'Exo2-Bold.ttf'; +$yahei = $here.'Yahei.ttf'; +$white = '#ffffff'; +$mode = $mode??$user->playmode; +$badges = $user->badges; +$badge = $badges[rand(0, count($badges)-1)]; +$flag = file_exists($here."flags/{$user->country->code}.png")?($here."flags/{$user->country->code}.png"):($here.'flags/__.png'); +$stats_key = imageFont($yahei, 12, $white); +$statics = $user->statistics; +try{ + $avatar = Image::make('https://a.ppy.sh/'.$user->id); +}catch(\Exception $e){ + $avatar = Image::make($here.'avatar-guest.png'); +} +$playtime = [ + 'hours' => sprintf('%d', $statics->play_time/3600), + 'minutes' => sprintf('%d', ($statics->play_time%3600)/60), + 'seconds' => sprintf('%d', $statics->play_time%60), +]; +$stat = [ + 'Ranked 谱面总分' => number_format($statics->ranked_score), + '准确率' => sprintf('%.2f%%', $statics->hit_accuracy), + '游戏次数' => number_format($statics->play_count), + '总分' => number_format($statics->total_score), + '总命中次数' => number_format($statics->total_hits), + '最大连击' => number_format($statics->maximum_combo), + '回放被观看次数' => number_format($statics->replays_watched_by_others), +]; +$grade = [ + 'XH' => $statics->grade_counts->ssh, + 'X' => $statics->grade_counts->ss, + 'SH' => $statics->grade_counts->sh, + 'S' => $statics->grade_counts->s, + 'A' => $statics->grade_counts->a, +]; +//开始绘图 +$img = Image::make($user->cover_url); +$img->resize(1000, 350) + ->insert(Image::canvas(1000, 350)->fill([0, 0, 0, 0.5])) //背景暗化50% + ->insert($avatar->resize(110, 110), 'top-left', 40, 220) //插入头像 + ->text($user->username, 170, 256, imageFont($exo2_italic, 24, $white, 'left', 'top')) //插入用户名 + ->text($user->title, 170, 285, imageFont($exo2_italic, 15, $white, 'left', 'top')) //插入title + ; +if($badge!=NULL)$img->insert(Image::make($badge->image_url), 'top-left', 40, 168); //插入狗牌 +if($user->is_supporter){ + $img->insert(Image::make($here.'heart.png')->resize(28, 28), 'top-left', 170, 223) //插入支持者标志 + ->insert(Image::make($here."modes/{$mode}.png")->resize(28, 28), 'top-left', 210, 223) //插入模式标志 + ; +}else{ + $img->insert(Image::make($here."modes/{$mode}.png")->resize(28, 28), 'top-left', 170, 223); //插入模式标志 +} +$img->insert(Image::make($flag)->resize(30, 20), 'top-left', 170, 310) //插入国旗 + ->insert(Image::canvas(280, 323)->fill([0, 0, 0, 0.3]), 'top-left', 670, 27) //绘制右侧暗化 + ->text('游戏时间', 690, 50, $stats_key) + ->text("{$playtime['hours']}小时 {$playtime['minutes']}分钟 {$playtime['seconds']}秒", 690, 72, imageFont($yahei, 18, '#ffcc22')) + ->insert(Image::make($here.'levelbadge.png')->resize(50, 50), 'top-left', 880, 30) + ->text($statics->level->current, 905, 45, imageFont($exo2_bold, 18, $white, 'center', 'middle')) +; +$yIndex = 120; +foreach($stat as $key => $value){ + $img->text($key, 690, $yIndex, $stats_key); + $img->text($value, 930, $yIndex, imageFont($exo2_bold, 16, $white, 'right')); + $yIndex+=20; +} +$img->text(sprintf('%.2f', $statics->pp), 690, 280, imageFont($exo2_bold, 40, $white)); +$img->text('PP', 740, 300, imageFont($exo2_bold, 20, $white)); +$img->text('#'.number_format($statics->rank->global), 930, 280, imageFont($exo2_bold, 20, $white, 'right')); +$img->text($user->country->code.' '.'#'.number_format($statics->rank->country), 930, 300, imageFont($exo2_bold, 20, $white, 'right')); +$xIndex = 675; +foreach($grade as $key => $value){ + $img->insert(Image::make($here."{$key}.png")->resize(50, 50), 'top-left', $xIndex, 300); + $img->text($value, $xIndex+20, 350, imageFont($exo2_bold, 16, $white, 'center', 'buttom')); + $xIndex+=55; +} +$img->save('../storage/cache/'.$Event['message_id']); + +$msg = sendImg(getCache($Event['message_id'])); +if($withMeText)$msg.="\n".preg_replace('/\n+/', "\n", str_replace('
', "\n", htmlspecialchars_decode(strip_tags($user->page->html, '
')))); + +$Queue[]= sendBack($msg); + + +?> \ No newline at end of file diff --git a/module/osu/recent.php b/module/osu/recent.php index 7f316a5..94d6ff2 100644 --- a/module/osu/recent.php +++ b/module/osu/recent.php @@ -1,13 +1,22 @@ \ No newline at end of file +?> diff --git a/public/tools/convert.php b/public/tools/convert.php index deafdc7..8cdc25f 100644 --- a/public/tools/convert.php +++ b/public/tools/convert.php @@ -1,8 +1,8 @@