Files
City10/app/Http/Controllers/Web/CityPresenceController.php
marcocosta10000 c299a4ae21 feat(city): implement marketplace, missions, customization and admin dashboard
- Add database migrations for market_listings, missions and character cosmetics
- Create controllers for marketplace, missions, presence and character customization
- Implement admin world dashboard with live platform metrics
- Add feature tests for world functionality
- Include phase 2 design documents and gap analysis
2026-10-17 23:21:23 -03:00

69 lines
2.3 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Character;
use App\Models\City;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
/**
* Lightweight multiplayer presence feed.
*
* Returns the positions and states of characters active in a city so the
* viewer can render other citizens in near-real-time without WebSockets.
*/
class CityPresenceController extends Controller
{
/**
* Snapshot of citizens in the requested (or default) city.
*/
public function __invoke(Request $request): JsonResponse
{
$user = $request->user();
abort_unless($user !== null, 401);
$me = Character::ensureForUser($user);
$slug = $request->query('city');
$city = $me->city;
if (is_string($slug) && $slug !== '') {
$city = City::query()
->where('slug', $slug)
->orWhere('id', ctype_digit($slug) ? (int) $slug : 0)
->first() ?? $city;
}
$cacheKey = 'presence.'.$city->id.'.'.now()->timestamp;
$citizens = Cache::remember($cacheKey, 1, function () use ($city, $me) {
return Character::query()
->where('city_id', $city->id)
->where(function ($q): void {
$q->where('is_online', true)
->orWhere('updated_at', '>=', now()->subMinutes(10));
})
->with('user:id,name')
->get()
->map(fn (Character $c): array => [
'id' => $c->id,
'name' => $c->name,
'type' => $c->user_id === null ? 'child' : 'citizen',
'status' => $c->state,
'position' => [(float) $c->pos_x, (float) $c->pos_y, (float) $c->pos_z],
'is_online' => (bool) $c->is_online,
'is_me' => (int) $c->id === (int) $me->id,
'owner_name' => $c->user?->name,
])
->values()
->all();
});
return response()->json([
'city_id' => $city->id,
'server_time' => now()->toIso8601String(),
'citizens' => $citizens,
])->header('Cache-Control', 'no-store');
}
}