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'); } }