39001-vm/api/room_action.php
2026-03-05 10:39:31 +00:00

167 lines
4.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';
header('Content-Type: application/json');
ensure_rooms_schema();
$input = $_POST;
$roomId = (int) ($input['room_id'] ?? 0);
$action = $input['action'] ?? '';
if ($roomId <= 0 || $action === '') {
echo json_encode(['success' => 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()
]);