37711-vm/api/multiplayer.php
Flatlogic Bot b3cf9df956 123
2026-01-22 16:53:25 +00:00

199 lines
8.9 KiB
PHP

<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
$action = $_GET['action'] ?? '';
$input = json_decode(file_get_contents('php://input'), true);
try {
$pdo = db();
switch ($action) {
case 'set_nickname':
$nickname = trim($input['nickname'] ?? '');
$session_id = $input['player_id'] ?? '';
if (!$nickname || !$session_id) {
echo json_encode(['success' => false, 'error' => 'Missing data']);
break;
}
$stmt = $pdo->prepare("INSERT INTO players (nickname, session_id, last_seen) VALUES (?, ?, NOW()) ON DUPLICATE KEY UPDATE nickname = ?, last_seen = NOW()");
$stmt->execute([$nickname, $session_id, $nickname]);
echo json_encode(['success' => true]);
break;
case 'heartbeat':
$session_id = $input['player_id'] ?? '';
if ($session_id) {
$stmt = $pdo->prepare("UPDATE players SET last_seen = NOW() WHERE session_id = ?");
$stmt->execute([$session_id]);
}
echo json_encode(['success' => true]);
break;
case 'get_online':
$session_id = $_GET['player_id'] ?? '';
$stmt = $pdo->prepare("SELECT id, nickname, session_id FROM players WHERE last_seen > DATE_SUB(NOW(), INTERVAL 30 SECOND) AND session_id != ? LIMIT 20");
$stmt->execute([$session_id]);
$players = $stmt->fetchAll();
echo json_encode(['success' => true, 'players' => $players]);
break;
case 'invite':
$from_session = $input['from_player_id'] ?? '';
$to_session = $input['to_player_id'] ?? '';
$room_code = strtoupper(substr(md5(uniqid()), 0, 6));
$stmt = $pdo->prepare("SELECT id FROM players WHERE session_id = ?");
$stmt->execute([$from_session]);
$from = $stmt->fetch();
$stmt = $pdo->prepare("SELECT id FROM players WHERE session_id = ?");
$stmt->execute([$to_session]);
$to = $stmt->fetch();
if ($from && $to) {
$stmt = $pdo->prepare("INSERT INTO invitations (from_player_id, to_player_id, room_code) VALUES (?, ?, ?)");
$stmt->execute([$from['id'], $to['id'], $room_code]);
// Pre-create the room
$stmt = $pdo->prepare("INSERT INTO rooms (room_code, player1_id, status) VALUES (?, ?, 'waiting')");
$stmt->execute([$room_code, $from_session]);
echo json_encode(['success' => true, 'room_code' => $room_code]);
} else {
echo json_encode(['success' => false, 'error' => 'Player not found']);
}
break;
case 'check_invites':
$session_id = $_GET['player_id'] ?? '';
$stmt = $pdo->prepare("
SELECT i.id, p.nickname as from_nickname, i.room_code
FROM invitations i
JOIN players p ON i.from_player_id = p.id
JOIN players target ON i.to_player_id = target.id
WHERE target.session_id = ? AND i.status = 'pending' AND i.created_at > DATE_SUB(NOW(), INTERVAL 1 MINUTE)
");
$stmt->execute([$session_id]);
$invites = $stmt->fetchAll();
echo json_encode(['success' => true, 'invites' => $invites]);
break;
case 'respond_invite':
$invite_id = $input['invite_id'] ?? 0;
$status = $input['status'] ?? 'rejected';
$stmt = $pdo->prepare("UPDATE invitations SET status = ? WHERE id = ?");
$stmt->execute([$status, $invite_id]);
echo json_encode(['success' => true]);
break;
case 'create':
$player_id = $input['player_id'] ?? '';
$room_code = $input['room_code'] ?? strtoupper(substr(md5(uniqid()), 0, 6));
$stmt = $pdo->prepare("INSERT INTO rooms (room_code, player1_id, status) VALUES (?, ?, 'waiting') ON DUPLICATE KEY UPDATE player1_id = VALUES(player1_id)");
$stmt->execute([$room_code, $player_id]);
$room_id = $pdo->lastInsertId();
if (!$room_id) {
$stmt = $pdo->prepare("SELECT id FROM rooms WHERE room_code = ?");
$stmt->execute([$room_code]);
$room_id = $stmt->fetchColumn();
}
echo json_encode(['success' => true, 'room_code' => $room_code, 'room_id' => $room_id]);
break;
case 'join':
$player_id = $input['player_id'] ?? '';
$room_code = strtoupper($input['room_code'] ?? '');
$stmt = $pdo->prepare("SELECT id, player1_id, player2_id FROM rooms WHERE room_code = ? AND (status = 'waiting' OR status = 'playing')");
$stmt->execute([$room_code]);
$room = $stmt->fetch();
if ($room) {
if ($room['player1_id'] === $player_id) {
echo json_encode(['success' => true, 'room_id' => $room['id']]);
} else {
$stmt = $pdo->prepare("UPDATE rooms SET player2_id = ?, status = 'playing' WHERE id = ?");
$stmt->execute([$player_id, $room['id']]);
echo json_encode(['success' => true, 'room_id' => $room['id']]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Room not found or full']);
}
break;
case 'update':
$room_id = $input['room_id'] ?? 0;
$player_id = $input['player_id'] ?? '';
$board = json_encode($input['board'] ?? []);
$score = $input['score'] ?? 0;
$is_game_over = $input['is_game_over'] ? 1 : 0;
$stmt = $pdo->prepare("INSERT INTO game_states (room_id, player_id, board, score, is_game_over)
VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE board = VALUES(board), score = VALUES(score), is_game_over = VALUES(is_game_over)");
$stmt->execute([$room_id, $player_id, $board, $score, $is_game_over]);
echo json_encode(['success' => true]);
break;
case 'poll':
$room_id = $_GET['room_id'] ?? 0;
$player_id = $_GET['player_id'] ?? '';
$stmt = $pdo->prepare("SELECT player_id, board, score, is_game_over FROM game_states WHERE room_id = ? AND player_id != ?");
$stmt->execute([$room_id, $player_id]);
$opponent = $stmt->fetch();
$stmt = $pdo->prepare("SELECT pending_debuffs FROM game_states WHERE room_id = ? AND player_id = ?");
$stmt->execute([$room_id, $player_id]);
$self = $stmt->fetch();
$debuffs = [];
if ($self && $self['pending_debuffs']) {
$debuffs = explode(',', $self['pending_debuffs']);
$stmt = $pdo->prepare("UPDATE game_states SET pending_debuffs = NULL WHERE room_id = ? AND player_id = ?");
$stmt->execute([$room_id, $player_id]);
}
$stmt = $pdo->prepare("SELECT status FROM rooms WHERE id = ?");
$stmt->execute([$room_id]);
$room = $stmt->fetch();
echo json_encode([
'success' => true,
'opponent' => $opponent ? [
'board' => json_decode($opponent['board']),
'score' => $opponent['score'],
'is_game_over' => (bool)$opponent['is_game_over']
] : null,
'status' => $room['status'] ?? 'unknown',
'debuffs' => $debuffs
]);
break;
case 'send_debuff':
$room_id = $input['room_id'] ?? 0;
$player_id = $input['player_id'] ?? '';
$debuff = $input['debuff'] ?? '';
$stmt = $pdo->prepare("SELECT player_id FROM game_states WHERE room_id = ? AND player_id != ?");
$stmt->execute([$room_id, $player_id]);
$opponent = $stmt->fetch();
if ($opponent) {
$stmt = $pdo->prepare("UPDATE game_states SET pending_debuffs = IF(pending_debuffs IS NULL, ?, CONCAT(pending_debuffs, ',', ?)) WHERE room_id = ? AND player_id = ?");
$stmt->execute([$debuff, $debuff, $room_id, $opponent['player_id']]);
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => 'Opponent not found']);
}
break;
default:
echo json_encode(['success' => false, 'error' => 'Invalid action']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}