With DataBaseREdis

This commit is contained in:
2026-01-28 00:49:37 +03:00
parent 4b01c2d4de
commit af62de5569
10 changed files with 1309 additions and 24 deletions

View File

@ -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;
}