2016-07-21 22:01:57 +08:00
|
|
|
<?php
|
|
|
|
|
2016-08-28 10:05:21 +08:00
|
|
|
namespace App\Http\Controllers;
|
2016-07-21 22:01:57 +08:00
|
|
|
|
2016-09-04 15:35:12 +08:00
|
|
|
use App\Models\Player;
|
|
|
|
use App\Models\Texture;
|
2019-12-14 11:10:37 +08:00
|
|
|
use App\Models\User;
|
2020-01-12 09:27:39 +08:00
|
|
|
use Blessing\Minecraft;
|
2019-12-30 23:29:44 +08:00
|
|
|
use Cache;
|
2019-12-14 11:10:37 +08:00
|
|
|
use Carbon\Carbon;
|
2020-01-12 09:27:39 +08:00
|
|
|
use Illuminate\Http\Request;
|
2019-12-31 23:03:37 +08:00
|
|
|
use Image;
|
2019-12-14 11:10:37 +08:00
|
|
|
use Storage;
|
2016-07-21 22:01:57 +08:00
|
|
|
|
2016-09-04 15:35:12 +08:00
|
|
|
class TextureController extends Controller
|
2016-07-21 22:01:57 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$this->middleware('cache.headers:etag;public;max_age='.option('cache_expire_time'))
|
|
|
|
->only([
|
|
|
|
'preview',
|
|
|
|
'raw',
|
|
|
|
'texture',
|
|
|
|
'avatarByPlayer',
|
|
|
|
'avatarByUser',
|
|
|
|
'avatarByTexture',
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
2019-12-30 23:29:44 +08:00
|
|
|
public function json($player)
|
2016-07-21 22:01:57 +08:00
|
|
|
{
|
2019-12-30 23:29:44 +08:00
|
|
|
$player = $this->getPlayerInstance($player);
|
|
|
|
if (option('enable_json_cache')) {
|
|
|
|
$json = Cache::rememberForever('json-'.$player->pid, function () use ($player) {
|
|
|
|
return $player->toJson();
|
|
|
|
});
|
|
|
|
|
|
|
|
return response($json)
|
|
|
|
->header('Content-Type', 'application/json')
|
|
|
|
->setLastModified($player->last_modified);
|
2016-07-21 22:01:57 +08:00
|
|
|
}
|
2016-10-30 11:57:26 +08:00
|
|
|
|
2019-12-30 23:29:44 +08:00
|
|
|
return response()->json($player)->setLastModified($player->last_modified);
|
2016-07-21 22:01:57 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
public function preview(Minecraft $minecraft, Request $request, $tid)
|
2019-03-02 22:58:37 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
$texture = Texture::findOrFail($tid);
|
|
|
|
$hash = $texture->hash;
|
|
|
|
|
|
|
|
$disk = Storage::disk('textures');
|
|
|
|
abort_if($disk->missing($hash), 404);
|
|
|
|
|
|
|
|
$height = (int) $request->query('height', 200);
|
|
|
|
$now = Carbon::now();
|
|
|
|
$response = Cache::remember(
|
|
|
|
'preview-t'.$tid,
|
|
|
|
option('enable_preview_cache') ? $now->addYear() : $now->addMinute(),
|
|
|
|
function () use ($minecraft, $disk, $texture, $hash, $height) {
|
|
|
|
$file = $disk->get($hash);
|
|
|
|
if ($texture->type === 'cape') {
|
|
|
|
$image = $minecraft->renderCape($file, 12);
|
|
|
|
} else {
|
|
|
|
$image = $minecraft->renderSkin($file, 12, $texture->type === 'alex');
|
|
|
|
}
|
|
|
|
|
|
|
|
$lastModified = $disk->lastModified($hash);
|
|
|
|
|
|
|
|
return Image::make($image)
|
|
|
|
->resize(null, $height, function ($constraint) {
|
|
|
|
$constraint->aspectRatio();
|
|
|
|
})
|
|
|
|
->response('png', 100)
|
|
|
|
->setLastModified(Carbon::createFromTimestamp($lastModified));
|
2018-07-22 10:00:30 +08:00
|
|
|
}
|
2020-01-12 09:27:39 +08:00
|
|
|
);
|
2018-07-22 10:00:30 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
return $response;
|
2016-08-28 20:33:35 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
public function raw($tid)
|
2018-07-30 15:13:14 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
abort_unless(option('allow_downloading_texture'), 403);
|
2018-07-30 15:13:14 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
$texture = Texture::findOrFail($tid);
|
2019-12-31 23:03:37 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
return $this->texture($texture->hash);
|
2018-07-30 15:13:14 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
public function texture(string $hash)
|
2018-07-30 15:13:14 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
$disk = Storage::disk('textures');
|
|
|
|
abort_if($disk->missing($hash), 404);
|
2016-08-29 14:25:24 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
$lastModified = Carbon::createFromTimestamp($disk->lastModified($hash));
|
2019-12-31 23:03:37 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
return response($disk->get($hash))
|
|
|
|
->withHeaders([
|
|
|
|
'Content-Type' => 'image/png',
|
|
|
|
'Content-Length' => $disk->size($hash),
|
|
|
|
])
|
|
|
|
->setLastModified($lastModified);
|
2016-08-13 22:14:01 +08:00
|
|
|
}
|
2016-07-21 22:01:57 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
public function avatarByPlayer(Minecraft $minecraft, Request $request, $name)
|
2016-08-13 22:14:01 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
$player = Player::where('name', $name)->firstOrFail();
|
2016-08-29 14:25:24 +08:00
|
|
|
|
2020-01-12 09:57:55 +08:00
|
|
|
return $this->avatar($minecraft, $request, $player->skin);
|
2016-08-13 22:14:01 +08:00
|
|
|
}
|
2016-07-21 22:01:57 +08:00
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
public function avatarByUser(Minecraft $minecraft, Request $request, $uid)
|
2019-03-02 22:58:37 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
$texture = Texture::find(optional(User::find($uid))->avatar);
|
2018-07-22 09:38:42 +08:00
|
|
|
|
2020-01-12 09:57:55 +08:00
|
|
|
return $this->avatar($minecraft, $request, $texture);
|
2016-07-27 18:52:46 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
public function avatarByTexture(Minecraft $minecraft, Request $request, $tid)
|
2016-10-16 18:16:15 +08:00
|
|
|
{
|
2020-01-12 09:27:39 +08:00
|
|
|
$texture = Texture::find($tid);
|
2019-03-16 18:49:51 +08:00
|
|
|
|
2020-01-12 09:57:55 +08:00
|
|
|
return $this->avatar($minecraft, $request, $texture);
|
2019-03-16 17:40:04 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:57:55 +08:00
|
|
|
protected function avatar(Minecraft $minecraft, Request $request, Texture $texture = null)
|
2019-09-10 19:52:17 +08:00
|
|
|
{
|
2020-01-12 09:57:55 +08:00
|
|
|
$size = (int) $request->query('size', 100);
|
|
|
|
$mode = $request->has('3d') ? '3d' : '2d';
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
$disk = Storage::disk('textures');
|
|
|
|
if (is_null($texture) || $disk->missing($texture->hash)) {
|
2020-01-12 09:57:55 +08:00
|
|
|
return Image::make(resource_path("misc/textures/avatar$mode.png"))
|
2020-01-12 09:27:39 +08:00
|
|
|
->resize($size, $size)
|
|
|
|
->response('png', 100);
|
2019-09-10 19:52:17 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
$hash = $texture->hash;
|
|
|
|
$now = Carbon::now();
|
|
|
|
$response = Cache::remember(
|
2020-01-12 09:57:55 +08:00
|
|
|
'avatar-'.$mode.'-t'.$texture->tid.'-s'.$size,
|
2020-01-12 09:27:39 +08:00
|
|
|
option('enable_avatar_cache') ? $now->addYear() : $now->addMinute(),
|
2020-01-12 09:57:55 +08:00
|
|
|
function () use ($minecraft, $disk, $hash, $size, $mode) {
|
|
|
|
$file = $disk->get($hash);
|
|
|
|
if ($mode === '3d') {
|
|
|
|
$image = $minecraft->render3dAvatar($file, 25);
|
|
|
|
} else {
|
|
|
|
$image = $minecraft->render2dAvatar($file, 25);
|
|
|
|
}
|
|
|
|
|
2020-01-12 09:27:39 +08:00
|
|
|
$lastModified = Carbon::createFromTimestamp($disk->lastModified($hash));
|
|
|
|
|
|
|
|
return Image::make($image)
|
|
|
|
->resize($size, $size)
|
|
|
|
->response('png', 100)
|
|
|
|
->setLastModified($lastModified);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
return $response;
|
2019-09-10 19:52:17 +08:00
|
|
|
}
|
|
|
|
|
2019-03-16 17:43:57 +08:00
|
|
|
protected function getPlayerInstance($player_name)
|
2019-03-16 17:40:04 +08:00
|
|
|
{
|
2019-03-16 17:43:57 +08:00
|
|
|
$player = Player::where('name', $player_name)->first();
|
2019-03-31 11:00:07 +08:00
|
|
|
abort_if($player->isBanned(), 403, trans('general.player-banned'));
|
2019-04-19 19:36:36 +08:00
|
|
|
|
2016-10-16 18:16:15 +08:00
|
|
|
return $player;
|
|
|
|
}
|
2016-07-21 22:01:57 +08:00
|
|
|
}
|