bc/public/js/gameSetup.js

256 lines
12 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// /public/js/gameSetup.js
// ПРИМЕРНЫЕ РЕАЛИЗАЦИИ ВСПОМОГАТЕЛЬНЫХ ФУНКЦИЙ (лучше передавать из main.js)
/*
function parseJwtPayloadForValidation(token) {
try {
if (typeof token !== 'string') return null;
const base64Url = token.split('.')[1];
if (!base64Url) return null;
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
} catch (e) {
return null;
}
}
function isTokenValid(token) {
if (!token) {
return false;
}
const decodedToken = parseJwtPayloadForValidation(token);
if (!decodedToken || !decodedToken.exp) {
localStorage.removeItem('jwtToken');
return false;
}
const currentTimeInSeconds = Math.floor(Date.now() / 1000);
if (decodedToken.exp < currentTimeInSeconds) {
localStorage.removeItem('jwtToken');
return false;
}
return true;
}
*/
// Конец примерных реализаций
export function initGameSetup(dependencies) {
const { socket, clientState, ui, utils } = dependencies; // Предполагаем, что utils.isTokenValid передается
const {
createAIGameButton, createPvPGameButton, joinPvPGameButton,
findRandomPvPGameButton, gameIdInput, availableGamesDiv, pvpCharacterRadios
} = ui.elements;
// Получаем функцию isTokenValid либо из utils, либо используем локальную, если она определена выше
const checkTokenValidity = utils?.isTokenValid || window.isTokenValidFunction; // window.isTokenValidFunction - если вы определили ее глобально/локально
if (typeof checkTokenValidity !== 'function') {
console.error("[GameSetup.js] CRITICAL: isTokenValid function is not available. Auth checks will fail.");
// Можно добавить фоллбэк или аварийное поведение
}
// --- Вспомогательные функции ---
function getSelectedCharacterKey() {
let selectedKey = 'elena'; // Значение по умолчанию
if (pvpCharacterRadios) {
pvpCharacterRadios.forEach(radio => {
if (radio.checked) {
selectedKey = radio.value;
}
});
}
return selectedKey;
}
function updateAvailableGamesList(games) {
if (!availableGamesDiv) return;
availableGamesDiv.innerHTML = '<h3>Доступные PvP игры:</h3>';
if (games && games.length > 0) {
const ul = document.createElement('ul');
games.forEach(game => {
if (game && game.id) {
const li = document.createElement('li');
li.textContent = `ID: ${game.id.substring(0, 8)}... - ${game.status || 'Ожидает игрока'}`;
const joinBtn = document.createElement('button');
joinBtn.textContent = 'Присоединиться';
joinBtn.dataset.gameId = game.id;
if (clientState.isLoggedIn && clientState.myUserId && game.ownerIdentifier === clientState.myUserId) {
joinBtn.disabled = true;
joinBtn.title = "Вы не можете присоединиться к своей же ожидающей игре.";
} else {
joinBtn.disabled = false;
}
joinBtn.addEventListener('click', (e) => {
// --- ПРОВЕРКА ТОКЕНА ПЕРЕД ДЕЙСТВИЕМ ---
if (typeof checkTokenValidity === 'function' && (!clientState.isLoggedIn || !checkTokenValidity(localStorage.getItem('jwtToken')))) {
if (typeof ui.redirectToLogin === 'function') {
ui.redirectToLogin('Для присоединения к игре необходимо войти или обновить сессию.');
} else {
alert('Для присоединения к игре необходимо войти или обновить сессию.');
window.location.href = '/'; // Фоллбэк
}
return;
}
// --- КОНЕЦ ПРОВЕРКИ ТОКЕНА ---
if (e.target.disabled) return;
ui.disableSetupButtons();
socket.emit('joinGame', { gameId: e.target.dataset.gameId });
ui.setGameStatusMessage(`Присоединение к игре ${e.target.dataset.gameId.substring(0, 8)}...`);
});
li.appendChild(joinBtn);
ul.appendChild(li);
}
});
availableGamesDiv.appendChild(ul);
} else {
availableGamesDiv.innerHTML += '<p>Нет доступных игр. Создайте свою!</p>';
}
ui.enableSetupButtons();
}
// --- Обработчики событий DOM ---
if (createAIGameButton) {
createAIGameButton.addEventListener('click', () => {
// --- ПРОВЕРКА ТОКЕНА ПЕРЕД ДЕЙСТВИЕМ ---
if (typeof checkTokenValidity === 'function' && (!clientState.isLoggedIn || !checkTokenValidity(localStorage.getItem('jwtToken')))) {
if (typeof ui.redirectToLogin === 'function') {
ui.redirectToLogin('Для создания игры необходимо войти или обновить сессию.');
} else {
alert('Для создания игры необходимо войти или обновить сессию.');
window.location.href = '/'; // Фоллбэк
}
return;
}
// --- КОНЕЦ ПРОВЕРКИ ТОКЕНА ---
ui.disableSetupButtons();
socket.emit('createGame', { mode: 'ai', characterKey: 'elena' }); // Персонаж для AI может быть фиксированным
ui.setGameStatusMessage("Создание игры против AI...");
});
}
if (createPvPGameButton) {
createPvPGameButton.addEventListener('click', () => {
// --- ПРОВЕРКА ТОКЕНА ПЕРЕД ДЕЙСТВИЕМ ---
if (typeof checkTokenValidity === 'function' && (!clientState.isLoggedIn || !checkTokenValidity(localStorage.getItem('jwtToken')))) {
if (typeof ui.redirectToLogin === 'function') {
ui.redirectToLogin('Для создания PvP игры необходимо войти или обновить сессию.');
} else {
alert('Для создания PvP игры необходимо войти или обновить сессию.');
window.location.href = '/'; // Фоллбэк
}
return;
}
// --- КОНЕЦ ПРОВЕРКИ ТОКЕНА ---
ui.disableSetupButtons();
const characterKey = getSelectedCharacterKey();
socket.emit('createGame', { mode: 'pvp', characterKey: characterKey });
ui.setGameStatusMessage("Создание PvP игры...");
});
}
if (joinPvPGameButton) {
joinPvPGameButton.addEventListener('click', () => {
// --- ПРОВЕРКА ТОКЕНА ПЕРЕД ДЕЙСТВИЕМ ---
if (typeof checkTokenValidity === 'function' && (!clientState.isLoggedIn || !checkTokenValidity(localStorage.getItem('jwtToken')))) {
if (typeof ui.redirectToLogin === 'function') {
ui.redirectToLogin('Для присоединения к игре необходимо войти или обновить сессию.');
} else {
alert('Для присоединения к игре необходимо войти или обновить сессию.');
window.location.href = '/'; // Фоллбэк
}
return;
}
// --- КОНЕЦ ПРОВЕРКИ ТОКЕНА ---
const gameId = gameIdInput ? gameIdInput.value.trim() : '';
if (gameId) {
ui.disableSetupButtons();
socket.emit('joinGame', { gameId: gameId });
ui.setGameStatusMessage(`Присоединение к игре ${gameId}...`);
} else {
ui.setGameStatusMessage("Введите ID игры, чтобы присоединиться.", true);
}
});
}
if (findRandomPvPGameButton) {
findRandomPvPGameButton.addEventListener('click', () => {
// --- ПРОВЕРКА ТОКЕНА ПЕРЕД ДЕЙСТВИЕМ ---
if (typeof checkTokenValidity === 'function' && (!clientState.isLoggedIn || !checkTokenValidity(localStorage.getItem('jwtToken')))) {
if (typeof ui.redirectToLogin === 'function') {
ui.redirectToLogin('Для поиска игры необходимо войти или обновить сессию.');
} else {
alert('Для поиска игры необходимо войти или обновить сессию.');
window.location.href = '/'; // Фоллбэк
}
return;
}
// --- КОНЕЦ ПРОВЕРКИ ТОКЕНА ---
ui.disableSetupButtons();
const characterKey = getSelectedCharacterKey();
socket.emit('findRandomGame', { characterKey: characterKey });
ui.setGameStatusMessage("Поиск случайной PvP игры...");
});
}
// --- Обработчики событий Socket.IO ---
socket.on('gameCreated', (data) => {
if (!clientState.isLoggedIn) return;
console.log('[GameSetup] Game created by this client:', data);
clientState.currentGameId = data.gameId;
clientState.myPlayerId = data.yourPlayerId;
ui.updateGlobalWindowVariablesForUI();
});
socket.on('availablePvPGamesList', (games) => {
// Проверяем, залогинен ли пользователь, ПЕРЕД обновлением списка.
// Если пользователь разлогинился, а список пришел, его не нужно показывать на экране логина.
if (!clientState.isLoggedIn) {
if (availableGamesDiv) availableGamesDiv.innerHTML = ''; // Очищаем, если пользователь не залогинен
return;
}
updateAvailableGamesList(games);
});
socket.on('noPendingGamesFound', (data) => {
if (!clientState.isLoggedIn) return;
ui.setGameStatusMessage(data.message || "Свободных игр не найдено. Создана новая для вас. Ожидание оппонента...");
updateAvailableGamesList([]);
if (data.gameId) clientState.currentGameId = data.gameId;
if (data.yourPlayerId) clientState.myPlayerId = data.yourPlayerId;
ui.updateGlobalWindowVariablesForUI();
clientState.isInGame = false;
ui.disableSetupButtons();
if (window.gameUI?.updateTurnTimerDisplay) {
window.gameUI.updateTurnTimerDisplay(null, false, 'pvp');
}
});
socket.on('waitingForOpponent', () => {
if (!clientState.isLoggedIn) return;
ui.setGameStatusMessage("Ожидание присоединения оппонента...");
ui.disableSetupButtons();
if (window.gameUI?.updateTurnTimerDisplay) {
window.gameUI.updateTurnTimerDisplay(null, false, 'pvp');
}
});
}