163 lines
7.0 KiB
PHP
163 lines
7.0 KiB
PHP
<?php
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/session_bootstrap.php';
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/user_avatar.php';
|
|
require_once __DIR__ . '/../../../api/matches/ping-pong/1v1/internal/env.php';
|
|
if (!isset($_SESSION['logged_in']) || !$_SESSION['logged_in']) {
|
|
header('Location: /login/index.php');
|
|
exit();
|
|
}
|
|
|
|
if (!og_session_has_valid_username()) {
|
|
header('Location: /account/profile/?error=' . urlencode('Aby wejść do trybu 1v1 musisz mieć ustawiony poprawny username.') . '&username_required=1&focus=username');
|
|
exit();
|
|
}
|
|
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/account_suspension.php';
|
|
try {
|
|
$pdo = og_session_get_pdo();
|
|
if ($pdo instanceof PDO) {
|
|
$suspension = og_is_current_user_suspended($pdo);
|
|
if (!empty($suspension['is_suspended'])) {
|
|
header('Location: /disciplines/ping-pong/?blocked=suspended');
|
|
exit();
|
|
}
|
|
}
|
|
} catch (Throwable $e) {
|
|
// Fail open: nie blokuj strony przy problemie z odczytem stanu.
|
|
}
|
|
|
|
// Configure WS URL from env if present (recommended behind reverse proxy).
|
|
$wsUrl = og_env('PINGPONG_1V1_WS_URL');
|
|
if (!$wsUrl) {
|
|
$wsUrl = og_env('PUBLIC_WS_URL');
|
|
}
|
|
if (!$wsUrl) {
|
|
// Fallback for local dev: ws://host:8088
|
|
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
|
$wsUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')
|
|
? ('wss://' . $host . '/ping-pong-1v1')
|
|
: ('ws://' . $host . ':8088');
|
|
}
|
|
|
|
$currentUserAvatarUrl = null;
|
|
try {
|
|
$pdoAvatar = og_session_get_pdo();
|
|
if ($pdoAvatar instanceof PDO) {
|
|
$avatarFile = og_get_user_avatar_file($pdoAvatar, (int)($_SESSION['user_id'] ?? 0));
|
|
$currentUserAvatarUrl = og_avatar_file_to_url($avatarFile);
|
|
}
|
|
} catch (Throwable $e) {
|
|
$currentUserAvatarUrl = null;
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Ping-Pong 1v1 Online</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta charset="utf-8">
|
|
<link rel="stylesheet" href="/css/header.css" type="text/css" media="all"/>
|
|
<link rel="stylesheet" href="/css/footer.css" type="text/css" media="all"/>
|
|
<link href="/css/style.css" rel="stylesheet" type="text/css" media="all"/>
|
|
<link href="//fonts.googleapis.com/css?family=Lato:400,500,600,700,800,900" rel="stylesheet">
|
|
<link rel="stylesheet" href="/disciplines/ping-pong/1v1/css/online.css">
|
|
<script>
|
|
window.PP1V1_WS_URL = <?php echo json_encode($wsUrl, JSON_UNESCAPED_SLASHES); ?>;
|
|
window.PP1V1_PLAYER_SUMMARY_URL = '/api/matches/ping-pong/1v1/player-summary.php';
|
|
window.PP1V1_CURRENT_USER = <?php echo json_encode([
|
|
'userId' => (int) ($_SESSION['user_id'] ?? 0),
|
|
'username' => (string) ($_SESSION['username'] ?? ''),
|
|
'role' => (string) ($_SESSION['role'] ?? 'user'),
|
|
'email' => (string) ($_SESSION['email'] ?? ''),
|
|
'avatarUrl' => $currentUserAvatarUrl,
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="wrap">
|
|
<section class="player-navbar" id="playerRibbon">
|
|
<div class="player-navbar-main">
|
|
<div class="player-ribbon-identity">
|
|
<div class="player-avatar" id="playerAvatar"><?php echo htmlspecialchars(strtoupper(substr((string) ($_SESSION['username'] ?? 'G'), 0, 1)), ENT_QUOTES, 'UTF-8'); ?></div>
|
|
<div class="player-ribbon-copy">
|
|
<div class="player-kicker">Ping-Pong 1v1 Online</div>
|
|
<div class="player-name-row">
|
|
<div class="player-name" id="playerName"><?php echo htmlspecialchars((string) ($_SESSION['username'] ?? 'Gracz'), ENT_QUOTES, 'UTF-8'); ?></div>
|
|
<?php $r = (string) ($_SESSION['role'] ?? 'user'); ?>
|
|
<div class="player-role" id="playerRole"><?php echo htmlspecialchars($r === 'user' ? 'Player' : strtoupper($r), ENT_QUOTES, 'UTF-8'); ?></div>
|
|
<div class="player-conn-status" id="playerConnStatus" hidden></div>
|
|
</div>
|
|
<div class="player-meta" id="playerMeta">Ładowanie profilu konta…</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="player-navbar-stats" id="playerHighlights"></div>
|
|
</section>
|
|
|
|
<div id="hud">
|
|
<div class="hud-left">
|
|
<div class="badge badge-self" id="badge">Ty: —</div>
|
|
</div>
|
|
<div class="hud-center">
|
|
<div class="badge" id="score">0:0</div>
|
|
<div class="badge" id="status">—</div>
|
|
</div>
|
|
<div class="hud-right btnrow">
|
|
<button class="btn" id="btnFind">Szukaj meczu</button>
|
|
<button class="btn secondary" id="btnLeave">Wyjście</button>
|
|
</div>
|
|
</div>
|
|
<div class="arena-shell">
|
|
<div class="arena-decor" aria-hidden="true">
|
|
<span class="arena-decor-item item-1">🌑</span>
|
|
<span class="arena-decor-item item-2">🕶️</span>
|
|
<span class="arena-decor-item item-3">🖤</span>
|
|
<span class="arena-decor-item item-4">🎮</span>
|
|
<span class="arena-decor-item item-5">♠️</span>
|
|
<span class="arena-decor-item item-6">🌘</span>
|
|
<span class="arena-decor-item item-7">🎱</span>
|
|
<span class="arena-decor-item item-8">🕹️</span>
|
|
</div>
|
|
<canvas id="canvas"></canvas>
|
|
</div>
|
|
<section class="opponent-footer" id="opponentFooter">
|
|
<div class="opponent-footer-main">
|
|
<div class="opponent-avatar" id="opponentAvatar">?</div>
|
|
<div class="opponent-footer-copy">
|
|
<div class="opponent-footer-kicker">Przeciwnik</div>
|
|
<div class="opponent-footer-name-row">
|
|
<div class="opponent-footer-name" id="opponentFooterName">—</div>
|
|
<div class="opponent-footer-state" id="opponentFooterState">—</div>
|
|
</div>
|
|
<div class="opponent-footer-meta" id="opponentFooterMeta">Pola uzupełnią się po dobraniu przeciwnika.</div>
|
|
</div>
|
|
</div>
|
|
<div class="opponent-footer-stats" id="opponentFooterStats"></div>
|
|
</section>
|
|
</div>
|
|
|
|
<div id="overlay">
|
|
<div class="panel">
|
|
<div class="overlay-badge" id="overlayBadge" hidden></div>
|
|
<div class="overlay-stage" id="overlayStage" hidden></div>
|
|
<div class="h1" id="overlayTitle">—</div>
|
|
<div class="overlay-hero" id="overlayHero" hidden>
|
|
<div class="overlay-hero-number" id="overlayHeroNumber">10</div>
|
|
<div class="overlay-hero-label" id="overlayHeroLabel">sekund do startu</div>
|
|
</div>
|
|
<div class="overlay-progress" id="overlayProgress" hidden>
|
|
<div class="overlay-progress-bar" id="overlayProgressBar"></div>
|
|
</div>
|
|
<div class="p" id="overlayText">—</div>
|
|
<div class="overlay-grid" id="overlayGrid" hidden></div>
|
|
<div class="btnrow" id="overlayButtons"></div>
|
|
<div class="small" id="overlayHint" style="margin-top:10px; opacity:.75;">
|
|
Sterowanie: W/S lub strzałki lub myszka.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/disciplines/ping-pong/1v1/js/online.js"></script>
|
|
</body>
|
|
</html>
|