Actual asset renders are working!!!!

This commit is contained in:
Graphictoria 2022-08-21 23:58:44 -04:00
parent 80ba7876c5
commit 6d7b781470
10 changed files with 206 additions and 27 deletions

View File

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
@ -14,50 +15,93 @@ use App\Models\RenderTracker;
class ThumbnailController extends Controller
{
public function renderAsset(Request $request)
private function assetValidationRules()
{
$validator = Validator::make($request->all(), [
return [
'id' => [
'required',
Rule::exists('App\Models\Asset', 'id')->where(function($query) {
return $query->where('moderated', false);
return $query->where('moderated', false)
->where('approved', true);
})
],
'type' => 'regex:/(3D|2D)/i'
]);
];
}
private function userValidationRules()
{
// TODO: Fail validation if user is moderated.
return [
'id' => [
'required',
Rule::exists('App\Models\User', 'id')
],
'position' => ['sometimes', 'regex:/(Full|Bust)/i'],
'type' => 'regex:/(3D|2D)/i'
];
}
private function handleRender(Request $request, string $renderType)
{
$validator = Validator::make($request->all(), $this->{strtolower($renderType) . 'ValidationRules'}());
if($validator->fails())
return ValidationHelper::generateValidatorError($validator);
$valid = $validator->valid();
$asset = Asset::where('id', $valid['id'])->first();
$model = ('App\\Models\\' . $renderType)::where('id', $valid['id'])->first();
if($renderType == 'User') {
if($valid['position'] == null)
$valid['position'] = 'Full';
$valid['position'] = strtolower($valid['position']);
} elseif($renderType == 'Asset') {
// TODO: XlXi: Turn this into a switch case and fill in the rest of the unrenderables.
// Things like HTML assets should just have a generic "default" image.
if($model->assetTypeId == 1)
$model = Asset::where('id', $model->parentAsset)->first();
}
$valid['type'] = strtolower($valid['type']);
if($asset->thumbnail2DHash && $valid['type'] == '2d')
return response(['status' => 'success', 'data' => route('content', $asset->thumbnail2DHash)]);
if($model->thumbnail2DHash && $valid['type'] == '2d')
return response(['status' => 'success', 'data' => route('content', $model->thumbnail2DHash)]);
if($asset->thumbnail3DHash && $valid['type'] == '3d')
return response(['status' => 'success', 'data' => route('content', $asset->thumbnail3DHash)]);
if($model->thumbnail3DHash && $valid['type'] == '3d')
return response(['status' => 'success', 'data' => route('content', $model->thumbnail3DHash)]);
$tracker = RenderTracker::where('type', sprintf('asset%s', $valid['type']))
->where('target', $valid['id']);
$trackerType = sprintf('%s%s', strtolower($renderType), $valid['type']);
$tracker = RenderTracker::where('type', $trackerType)
->where('target', $valid['id'])
->where('created_at', '>', Carbon::now()->subMinute());
if(!$tracker->exists()) {
$tracker = new RenderTracker;
$tracker->type = sprintf('asset%s', $valid['type']);
$tracker->target = $valid['id'];
$tracker->save();
$tracker = RenderTracker::create([
'type' => $trackerType,
'target' => $valid['id']
]);
ArbiterRender::dispatch($tracker, $valid['type'] == '3d', $asset->typeString(), $asset->id);
ArbiterRender::dispatch(
$tracker,
$valid['type'] == '3d',
($renderType == 'User' ? $valid['position'] : $model->typeString()),
$model->id
);
}
return response(['status' => 'loading']);
}
public function renderAsset(Request $request)
{
return $this->handleRender($request, 'Asset');
}
public function renderUser()
{
//
return handleRender($request, 'User');
}
public function tryAsset()

View File

@ -0,0 +1,98 @@
<?php
namespace App\Http\Controllers\Web;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Helpers\GridHelper;
use App\Helpers\ValidationHelper;
use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Models\AssetVersion;
class ClientController extends Controller
{
function assetRegularValidator()
{
return [
'id' => [
'required',
Rule::exists('App\Models\Asset', 'id')->where(function($query) {
return $query->where('moderated', false)
->where('approved', true);
})
],
'version' => [
'sometimes',
'numeric'
]
];
}
function assetVersionValidator()
{
return [
'assetversionid' => [
'required',
Rule::exists('App\Models\AssetVersion', 'id')
]
];
}
function asset(Request $request)
{
// TODO: XlXi: userAssetId (owned asset)
$reqData = array_change_key_case($request->all());
$validatorRuleSet = 'assetRegularValidator';
if(array_key_exists('assetversionid', $reqData))
$validatorRuleSet = 'assetVersionValidator';
elseif(array_key_exists('userassetid', $reqData))
return response('todo');
$validator = Validator::make($reqData, $this->{$validatorRuleSet}());
if($validator->fails())
return ValidationHelper::generateValidatorError($validator);
$valid = $validator->valid();
$asset = null;
if(array_key_exists('assetversionid', $reqData)) {
$assetVersion = AssetVersion::where('id', $valid['assetversionid'])->first();
$asset = $assetVersion->asset;
$valid['version'] = $assetVersion->localVersion;
} else {
$asset = Asset::where('id', $valid['id'])->first();
if(!array_key_exists('version', $valid))
$valid['version'] = 0;
}
if($asset == null) {
$validator->errors()->add('version', 'Unknown asset version.');
return ValidationHelper::generateValidatorError($validator);
}
if(
!($asset->onSale || (Auth::check() && Auth::user()->id == $asset->creatorId)) // not on sale and not the creator
&&
!GridHelper::hasAllAccess() // not grid
) {
$validator->errors()->add('id', 'You do not have access to this asset.');
return ValidationHelper::generateValidatorError($validator);
}
$contentHash = $asset->getContent($valid['version']);
if(!$contentHash) {
$validator->errors()->add('version', 'Unknown asset version.');
return ValidationHelper::generateValidatorError($validator);
}
return redirect(route('content', $contentHash));
}
}

View File

@ -81,12 +81,13 @@ class ArbiterRender implements ShouldQueue
*/
public function handle()
{
// TODO: XlXi: User avatar/closeup render support.
$arguments = [
url(sprintf('/asset?id=%d', $this->assetId)), // TODO: XlXi: Move url() to route once the route actually exists.
($this->is3D ? 'OBJ' : 'PNG'),
840, // Width
840, // Height
url('/')
url('/') . '/'
];
switch($this->type) {
case 'Head':
@ -118,7 +119,10 @@ class ArbiterRender implements ShouldQueue
));
if(is_soap_fault($result))
{
$this->tracker->delete();
$this->fail(sprintf('SOAP Fault: (faultcode: %s, faultstring: %s)', $result->faultcode, $result->faultstring));
}
$result = $result->OpenJobExResult->LuaValue[0]->value;

View File

@ -9,6 +9,16 @@ class RenderTracker extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'type',
'target'
];
public function targetObj()
{
if($this->type == 'user2d' || $this->type == 'user3d')

View File

@ -2,9 +2,10 @@
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;
class Asset extends Model
{
@ -135,6 +136,11 @@ class Asset extends Model
return $this->belongsTo(User::class, 'creatorId');
}
public function parentAsset()
{
return $this->belongsTo(User::class, 'parentAssetId');
}
public function typeString()
{
return $this->assetTypes[$this->assetTypeId];
@ -147,7 +153,18 @@ class Asset extends Model
public function getThumbnail()
{
return 'https://gtoria.local/images/testing/hat.png';
$renderId = $this->id;
// TODO: XlXi: Turn this into a switch case and fill in the rest of the unrenderables.
// Things like HTML assets should just have a generic "default" image.
if($this->assetTypeId == 1) // Image
$renderId = $this->parentAsset->id;
$thumbnail = Http::get(route('thumbnails.v1.asset', ['id' => $renderId, 'type' => '2d']));
if($thumbnail->json('status') == 'loading')
return 'https://gtoria.local/images/busy/asset.png';
return $thumbnail->json('data');
}
public function set2DHash($hash)
@ -189,13 +206,13 @@ class Asset extends Model
// Version 0 is internally considered the latest.
public function getContent($version = 0)
{
if($version === 0)
if($version == 0)
return $this->latestVersion->contentURL;
$assetVersion = AssetVersion::where('parentAsset', $this->id)
->where('localVersion', $version)
->get();
->first();
return ($assetVersion !== null ? $assetVersion->contentURL : null);
return ($assetVersion ? $assetVersion->contentURL : null);
}
}

View File

@ -25,6 +25,9 @@ return new class extends Migration
$table->unsignedBigInteger('tokens')->default(0);
$table->dateTime('next_reward')->useCurrent();
$table->string('thumbnail2DHash')->nullable();
$table->string('thumbnail3DHash')->nullable();
$table->timestamps();
});
}

View File

@ -19,6 +19,7 @@ return new class extends Migration
$table->unsignedBigInteger('creatorId');
$table->string('name');
$table->string('description')->nullable();
$table->unsignedBigInteger('parentAssetId')->nullable()->comment('Used by things like images that were created because of something else.');
$table->boolean('approved')->default(false);
$table->boolean('moderated')->default(false);

View File

@ -19,8 +19,6 @@ return new class extends Migration
$table->unsignedBigInteger('parentAsset');
$table->unsignedBigInteger('localVersion');
// Calculating the subdomain on runtime is too expensive.
// So full URLs are used instead of just the hashes.
$table->string('contentURL');
$table->timestamps();

View File

@ -58,12 +58,12 @@
<div class="pe-4">
<div id="gt-thumbnail"
class="border position-relative graphictoria-asset-thumbnail"
data-asset-thumbnail-2d="{{ asset('images/testing/hat.png') }}"
data-asset-thumbnail-2d="{{ $asset->getThumbnail() }}"
data-asset-thumbnail-3d="{{ route('thumbnails.v1.asset', ['id' => $asset->id]) }}"
data-asset-name="{{ $asset->name }}"
data-asset-id="{{ $asset->id }}"
>
<img src="{{ asset('images/testing/hat.png') }}" alt="{{ $asset->name }}" class="img-fluid" />
<img src="{{ $asset->getThumbnail() }}" alt="{{ $asset->name }}" class="img-fluid" />
</div>
</div>
<div class="flex-fill">

View File

@ -82,4 +82,8 @@ Route::group(['as' => 'auth.', 'namespace' => 'Auth'], function() {
Route::get('/logout', 'AuthenticatedSessionController@destroy')->name('logout');
});
});
Route::group(['as' => 'client.'], function() {
Route::get('/asset', 'ClientController@asset')->name('asset');
});