With DataBaseREdis
This commit is contained in:
277
public/game.js
277
public/game.js
@ -189,6 +189,10 @@
|
||||
socket = io(url, { transports: ['websocket', 'polling'], reconnection: false });
|
||||
socket.on('connect', () => {
|
||||
clearError();
|
||||
// Отправляем имя пользователя на сервер, если авторизованы
|
||||
if (currentUser && currentUser.username) {
|
||||
socket.emit('setUsername', currentUser.username);
|
||||
}
|
||||
});
|
||||
socket.on('connect_error', (e) => {
|
||||
const errorMsg = e.message || 'Не удалось подключиться к серверу';
|
||||
@ -2830,8 +2834,281 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Авторизация
|
||||
let currentUser = null;
|
||||
|
||||
async function checkAuth() {
|
||||
try {
|
||||
const response = await fetch('/api/user', { credentials: 'include' });
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
currentUser = data.user;
|
||||
updateUserUI();
|
||||
return true;
|
||||
} else {
|
||||
// Не авторизован, но не показываем модальное окно автоматически
|
||||
// Пользователь может продолжить без авторизации
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка проверки авторизации:', error);
|
||||
// Не показываем модальное окно при ошибке, пользователь может продолжить
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function updateUserUI() {
|
||||
const userInfo = $('user-info');
|
||||
const userName = $('user-name');
|
||||
if (currentUser && userInfo && userName) {
|
||||
userInfo.style.display = 'flex';
|
||||
userName.textContent = currentUser.username;
|
||||
if (currentUser.gamesPlayed !== undefined) {
|
||||
userName.textContent += ` (${currentUser.gamesWon || 0}/${currentUser.gamesPlayed || 0})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showAuthModal() {
|
||||
const authOverlay = $('auth-overlay');
|
||||
if (authOverlay) {
|
||||
authOverlay.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function hideAuthModal() {
|
||||
const authOverlay = $('auth-overlay');
|
||||
if (authOverlay) {
|
||||
authOverlay.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function initAuth() {
|
||||
// Переключение между вкладками авторизации
|
||||
$all('.auth-tab').forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
$all('.auth-tab').forEach(t => t.classList.remove('active'));
|
||||
$all('.auth-panel').forEach(p => p.classList.add('hidden'));
|
||||
tab.classList.add('active');
|
||||
const panelId = 'auth-' + tab.dataset.authTab + '-panel';
|
||||
const panel = $(panelId);
|
||||
if (panel) {
|
||||
panel.classList.remove('hidden');
|
||||
panel.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Форма входа
|
||||
const loginForm = $('login-form');
|
||||
if (loginForm) {
|
||||
loginForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const username = $('login-username')?.value.trim();
|
||||
const password = $('login-password')?.value;
|
||||
const errorEl = $('login-error');
|
||||
|
||||
if (!username || !password) {
|
||||
if (errorEl) {
|
||||
errorEl.textContent = 'Заполните все поля';
|
||||
errorEl.classList.remove('hidden');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ username, password })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok && data.success) {
|
||||
currentUser = data.user;
|
||||
updateUserUI();
|
||||
hideAuthModal();
|
||||
if (errorEl) errorEl.classList.add('hidden');
|
||||
} else {
|
||||
if (errorEl) {
|
||||
errorEl.textContent = data.error || 'Ошибка входа';
|
||||
errorEl.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка входа:', error);
|
||||
if (errorEl) {
|
||||
errorEl.textContent = 'Ошибка соединения с сервером';
|
||||
errorEl.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Форма регистрации
|
||||
const registerForm = $('register-form');
|
||||
if (registerForm) {
|
||||
registerForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const username = $('register-username')?.value.trim();
|
||||
const password = $('register-password')?.value;
|
||||
const email = $('register-email')?.value.trim();
|
||||
const errorEl = $('register-error');
|
||||
|
||||
if (!username || !password) {
|
||||
if (errorEl) {
|
||||
errorEl.textContent = 'Заполните обязательные поля';
|
||||
errorEl.classList.remove('hidden');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/register', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ username, password, email })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok && data.success) {
|
||||
currentUser = data.user;
|
||||
updateUserUI();
|
||||
hideAuthModal();
|
||||
if (errorEl) errorEl.classList.add('hidden');
|
||||
// Отправляем имя пользователя на сервер через socket
|
||||
if (socket && socket.connected && currentUser.username) {
|
||||
socket.emit('setUsername', currentUser.username);
|
||||
}
|
||||
} else {
|
||||
if (errorEl) {
|
||||
errorEl.textContent = data.error || 'Ошибка регистрации';
|
||||
errorEl.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка регистрации:', error);
|
||||
if (errorEl) {
|
||||
errorEl.textContent = 'Ошибка соединения с сервером';
|
||||
errorEl.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Кнопка закрытия авторизации
|
||||
const authClose = $('auth-close');
|
||||
if (authClose) {
|
||||
authClose.addEventListener('click', () => {
|
||||
hideAuthModal();
|
||||
});
|
||||
}
|
||||
|
||||
// Кнопка выхода
|
||||
const btnLogout = $('btn-logout');
|
||||
if (btnLogout) {
|
||||
btnLogout.addEventListener('click', async () => {
|
||||
try {
|
||||
await fetch('/api/logout', { method: 'POST', credentials: 'include' });
|
||||
currentUser = null;
|
||||
const userInfo = $('user-info');
|
||||
if (userInfo) userInfo.style.display = 'none';
|
||||
showAuthModal();
|
||||
} catch (error) {
|
||||
console.error('Ошибка выхода:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Leaderboard
|
||||
const btnLeaderboard = $('btn-leaderboard');
|
||||
if (btnLeaderboard) {
|
||||
btnLeaderboard.addEventListener('click', async () => {
|
||||
const overlay = $('leaderboard-overlay');
|
||||
const content = $('leaderboard-content');
|
||||
if (overlay) overlay.classList.remove('hidden');
|
||||
if (content) content.innerHTML = '<p class="hint" style="text-align: center; padding: 2rem;">Загрузка...</p>';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/leaderboard', { credentials: 'include' });
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok && data.leaderboard) {
|
||||
if (data.leaderboard.length === 0) {
|
||||
content.innerHTML = '<p class="hint" style="text-align: center; padding: 2rem;">Рейтинг пуст</p>';
|
||||
} else {
|
||||
content.innerHTML = `
|
||||
<table class="leaderboard-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rank">#</th>
|
||||
<th class="username">Игрок</th>
|
||||
<th class="stats">Игр</th>
|
||||
<th class="stats">Побед</th>
|
||||
<th class="stats">% Побед</th>
|
||||
<th class="stats">Урон</th>
|
||||
<th class="stats">Хил</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${data.leaderboard.map((player, idx) => `
|
||||
<tr>
|
||||
<td class="rank">${idx + 1}</td>
|
||||
<td class="username">${escapeHtml(player.username)}</td>
|
||||
<td class="stats">${player.gamesPlayed}</td>
|
||||
<td class="stats">${player.gamesWon}</td>
|
||||
<td class="stats">${player.winRate}%</td>
|
||||
<td class="stats">${player.totalDamage}</td>
|
||||
<td class="stats">${player.totalHealing}</td>
|
||||
</tr>
|
||||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
} else {
|
||||
content.innerHTML = '<p class="hint" style="text-align: center; padding: 2rem; color: var(--red);">Ошибка загрузки рейтинга</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка загрузки leaderboard:', error);
|
||||
if (content) {
|
||||
content.innerHTML = '<p class="hint" style="text-align: center; padding: 2rem; color: var(--red);">Ошибка соединения</p>';
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof lucide !== 'undefined') {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
lucide.createIcons();
|
||||
} catch (e) {
|
||||
console.warn('Error updating Lucide icons:', e);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const leaderboardClose = $('leaderboard-close');
|
||||
if (leaderboardClose) {
|
||||
leaderboardClose.addEventListener('click', () => {
|
||||
const overlay = $('leaderboard-overlay');
|
||||
if (overlay) overlay.classList.add('hidden');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
initLobby();
|
||||
initAuth();
|
||||
// Проверяем авторизацию, но не блокируем доступ
|
||||
checkAuth().catch(() => {
|
||||
// Если авторизация не удалась, просто показываем модальное окно
|
||||
// Пользователь может продолжить без авторизации
|
||||
});
|
||||
showScreen('lobby');
|
||||
socket = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user