100 lines
2.6 KiB
PHP
100 lines
2.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
@ini_set('display_errors', '1');
|
|
@error_reporting(E_ALL);
|
|
@date_default_timezone_set('UTC');
|
|
|
|
session_start();
|
|
require_once __DIR__ . '/../includes/rooms.php';
|
|
|
|
ensure_rooms_schema();
|
|
|
|
$roomId = (int) ($_GET['room_id'] ?? 0);
|
|
if ($roomId <= 0) {
|
|
http_response_code(400);
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['success' => false, 'error' => 'Missing room id']);
|
|
exit;
|
|
}
|
|
|
|
$sessionPlayer = get_session_player($roomId);
|
|
$playerToken = $sessionPlayer['token'] ?? null;
|
|
session_write_close();
|
|
|
|
header('Content-Type: text/event-stream');
|
|
header('Cache-Control: no-cache, no-store, must-revalidate');
|
|
header('Pragma: no-cache');
|
|
header('Expires: 0');
|
|
header('X-Accel-Buffering: no');
|
|
|
|
@ini_set('zlib.output_compression', '0');
|
|
@ini_set('output_buffering', '0');
|
|
while (ob_get_level() > 0) {
|
|
@ob_end_flush();
|
|
}
|
|
ob_implicit_flush(true);
|
|
set_time_limit(0);
|
|
ignore_user_abort(true);
|
|
|
|
$startedAt = time();
|
|
$lastHash = '';
|
|
|
|
while (!connection_aborted()) {
|
|
$room = get_room($roomId);
|
|
if (!$room) {
|
|
echo "event: room_closed\n";
|
|
echo 'data: {"success":false,"error":"Room not found"}' . "\n\n";
|
|
flush();
|
|
break;
|
|
}
|
|
|
|
$state = $room['state'] ?? [];
|
|
$hasDynamicObjects = !empty($state['bombs']) || !empty($state['explosions']);
|
|
if ($room['status'] === 'playing' || $hasDynamicObjects) {
|
|
$room = update_room_tick($room);
|
|
save_room_state((int) $room['id'], $room['state'], (string) $room['status']);
|
|
}
|
|
|
|
$payload = [
|
|
'success' => true,
|
|
'room' => [
|
|
'id' => (int) $room['id'],
|
|
'name' => $room['name'],
|
|
'status' => $room['status'],
|
|
'max_players' => (int) $room['max_players'],
|
|
],
|
|
'state' => $room['state'],
|
|
'player_token' => $playerToken,
|
|
'server_time' => now_ms(),
|
|
];
|
|
|
|
$json = json_encode($payload, JSON_UNESCAPED_UNICODE);
|
|
if ($json === false) {
|
|
break;
|
|
}
|
|
|
|
$stateForHash = $payload['state'];
|
|
unset($stateForHash['last_tick']);
|
|
$hash = sha1(json_encode([
|
|
'room' => $payload['room'],
|
|
'state' => $stateForHash,
|
|
'player_token' => $payload['player_token'],
|
|
], JSON_UNESCAPED_UNICODE) ?: $json);
|
|
if ($hash !== $lastHash) {
|
|
$lastHash = $hash;
|
|
echo "event: state\n";
|
|
echo 'data: ' . $json . "\n\n";
|
|
flush();
|
|
} else {
|
|
echo "event: ping\n";
|
|
echo 'data: {"ts":' . now_ms() . "}\n\n";
|
|
flush();
|
|
}
|
|
|
|
usleep(($room['status'] === 'playing') ? 120000 : 350000);
|
|
|
|
if ((time() - $startedAt) >= 25) {
|
|
break;
|
|
}
|
|
}
|