false, 'error' => 'Invalid request']); exit; } $room = get_room($roomId); if (!$room) { echo json_encode(['success' => false, 'error' => 'Room not found']); exit; } $sessionPlayer = get_session_player($roomId); if (!$sessionPlayer) { echo json_encode(['success' => false, 'error' => 'Player not in room']); exit; } $state = $room['state']; $players = $state['players'] ?? []; $playerIndex = null; foreach ($players as $index => $player) { if ($player['token'] === $sessionPlayer['token']) { $playerIndex = $index; break; } } if ($playerIndex === null) { echo json_encode(['success' => false, 'error' => 'Player not found']); exit; } if ($action === 'start') { if (!empty($players[$playerIndex]['is_host']) && $room['status'] === 'waiting') { $room['status'] = 'playing'; $state['started_at'] = now_ms(); $room['state'] = $state; $room = update_room_tick($room); save_room_state($roomId, $room['state'], $room['status']); echo json_encode([ 'success' => true, 'status' => 'playing', 'room' => [ 'id' => $room['id'], 'name' => $room['name'], 'status' => $room['status'], 'max_players' => (int) $room['max_players'] ], 'state' => $room['state'], 'server_time' => now_ms() ]); exit; } echo json_encode(['success' => false, 'error' => 'Not allowed']); exit; } if ($room['status'] !== 'playing') { echo json_encode(['success' => false, 'error' => 'Match not active']); exit; } if ($action === 'move') { $dir = $input['dir'] ?? ''; $moves = [ 'up' => [0, -1], 'down' => [0, 1], 'left' => [-1, 0], 'right' => [1, 0], ]; if (!isset($moves[$dir])) { echo json_encode(['success' => false, 'error' => 'Invalid direction']); exit; } $player = $players[$playerIndex]; if (!$player['alive']) { echo json_encode(['success' => false, 'error' => 'Player eliminated']); exit; } $nx = $player['x'] + $moves[$dir][0]; $ny = $player['y'] + $moves[$dir][1]; $tile = $state['map']['tiles'][$ny][$nx] ?? 1; $bombs = $state['bombs'] ?? []; $bombBlocked = false; foreach ($bombs as $bomb) { if ($bomb['x'] === $nx && $bomb['y'] === $ny) { $bombBlocked = true; break; } } if ($tile === 0 && !$bombBlocked) { $player['x'] = $nx; $player['y'] = $ny; if (!empty($state['powerups'])) { foreach ($state['powerups'] as $idx => $powerup) { if ($powerup['x'] === $nx && $powerup['y'] === $ny) { apply_powerup($player, $powerup['type']); unset($state['powerups'][$idx]); } } $state['powerups'] = array_values($state['powerups']); } $players[$playerIndex] = $player; } } if ($action === 'bomb') { $player = $players[$playerIndex]; if (!$player['alive']) { echo json_encode(['success' => false, 'error' => 'Player eliminated']); exit; } $bombs = $state['bombs'] ?? []; $owned = array_filter($bombs, fn($b) => $b['owner'] === $player['token']); $hasBomb = false; foreach ($bombs as $bomb) { if ($bomb['x'] === $player['x'] && $bomb['y'] === $player['y']) { $hasBomb = true; break; } } if (count($owned) < $player['bombs'] && !$hasBomb) { $bombs[] = [ 'x' => $player['x'], 'y' => $player['y'], 'owner' => $player['token'], 'placed_at' => now_ms(), 'blast' => $player['blast'] ]; $state['bombs'] = $bombs; } } $state['players'] = $players; $room['state'] = $state; $room = update_room_tick($room); save_room_state($roomId, $room['state'], $room['status']); echo json_encode([ 'success' => true, 'room' => [ 'id' => $room['id'], 'name' => $room['name'], 'status' => $room['status'], 'max_players' => (int) $room['max_players'] ], 'state' => $room['state'], 'server_time' => now_ms() ]);