login fix, lobby fix
This commit is contained in:
55
app.py
55
app.py
@@ -833,6 +833,44 @@ def reset_room(room_code):
|
||||
return jsonify({'success': True})
|
||||
|
||||
|
||||
@app.route('/api/room/<room_code>/players')
|
||||
@login_required
|
||||
def get_room_players(room_code):
|
||||
"""Получение списка игроков комнаты без перезагрузки страницы"""
|
||||
room = GameRoom.query.filter_by(code=room_code).first_or_404()
|
||||
|
||||
# Проверяем, состоит ли пользователь в комнате
|
||||
current_player = GamePlayer.query.filter_by(
|
||||
user_id=current_user.id,
|
||||
room_id=room.id
|
||||
).first()
|
||||
|
||||
if not current_player:
|
||||
return jsonify({'error': 'Вы не в этой комнате'}), 403
|
||||
|
||||
# Получаем всех игроков
|
||||
players = GamePlayer.query.filter_by(room_id=room.id).all()
|
||||
|
||||
players_data = []
|
||||
for player in players:
|
||||
user = User.query.get(player.user_id)
|
||||
players_data.append({
|
||||
'user_id': player.user_id,
|
||||
'username': user.username if user else 'Игрок',
|
||||
'is_admin': player.is_admin,
|
||||
'is_ready': player.is_ready,
|
||||
'capital': player.capital,
|
||||
'ability_name': get_ability_name(player.ability),
|
||||
'ability_description': get_ability_description(player.ability)
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'players': players_data,
|
||||
'room_status': room.status
|
||||
})
|
||||
|
||||
|
||||
@app.route('/room/<room_code>/delete', methods=['POST'])
|
||||
@login_required
|
||||
def delete_room(room_code):
|
||||
@@ -952,15 +990,28 @@ def handle_connect():
|
||||
@socketio.on('join_room')
|
||||
def handle_join_room(data):
|
||||
room_code = data.get('room')
|
||||
if room_code:
|
||||
if room_code and current_user.is_authenticated:
|
||||
join_room(room_code)
|
||||
logger.info(f'User {current_user.username} joined room {room_code}')
|
||||
|
||||
# Проверяем, было ли уже уведомление о входе
|
||||
session_key = f'has_notified_join_{room_code}'
|
||||
if not session.get(session_key):
|
||||
# Отправляем уведомление другим игрокам
|
||||
emit('player_joined', {
|
||||
'user_id': current_user.id,
|
||||
'username': current_user.username,
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
'timestamp': datetime.utcnow().isoformat(),
|
||||
'is_reconnect': False
|
||||
}, room=room_code, include_self=False)
|
||||
|
||||
# Отмечаем в сессии, что уведомление отправлено
|
||||
session[session_key] = True
|
||||
else:
|
||||
# Это реконнект, отправляем тихое обновление
|
||||
emit('player_reconnected', {
|
||||
'user_id': current_user.id,
|
||||
'username': current_user.username
|
||||
}, room=room_code, include_self=False)
|
||||
|
||||
|
||||
|
||||
@@ -423,11 +423,20 @@
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Глобальные переменные
|
||||
// Не объявляем socket заново, он уже объявлен в base.html
|
||||
// let socket = io(); // УБРАТЬ эту строку!
|
||||
let roomCode = '{{ room.code }}';
|
||||
let currentPlayerId = '{{ current_player.id }}';
|
||||
let isAdmin = {{ 'true' if current_player.is_admin else 'false' }};
|
||||
let lastNotificationTime = 0; // Для ограничения частоты уведомлений
|
||||
window.roomStatus = '{{ room.status }}'; // Добавьте эту строку
|
||||
|
||||
// Функция форматирования валюты
|
||||
function formatCurrency(amount) {
|
||||
return new Intl.NumberFormat('ru-RU', {
|
||||
style: 'currency',
|
||||
currency: 'RUB',
|
||||
minimumFractionDigits: 0
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
// Инициализация при загрузке
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@@ -493,11 +502,39 @@ if (typeof socket !== 'undefined') {
|
||||
});
|
||||
|
||||
socket.on('player_joined', function(data) {
|
||||
console.log('Player joined:', data.username);
|
||||
console.log('Player joined:', data.username, data);
|
||||
|
||||
// Проверяем, не текущий ли это пользователь
|
||||
if (data.user_id && data.user_id == currentPlayerId) {
|
||||
console.log('Это текущий пользователь, игнорируем');
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, не было ли уже уведомления
|
||||
if (window.lastJoinNotification === data.user_id + '_' + new Date().toISOString().slice(0, 10)) {
|
||||
console.log('Уведомление уже показывалось сегодня');
|
||||
return;
|
||||
}
|
||||
|
||||
// Показываем уведомление
|
||||
showNotification(`🎮 ${data.username} присоединился к комнате`);
|
||||
|
||||
// Обновляем список игроков без перезагрузки
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1000);
|
||||
updatePlayerList();
|
||||
}, 500);
|
||||
|
||||
// Запоминаем, что показали уведомление
|
||||
window.lastJoinNotification = data.user_id + '_' + new Date().toISOString().slice(0, 10);
|
||||
});
|
||||
|
||||
socket.on('player_reconnected', function(data) {
|
||||
console.log('Player reconnected:', data.username);
|
||||
// Не показываем уведомление для реконнекта
|
||||
// Просто обновляем список
|
||||
setTimeout(() => {
|
||||
updatePlayerList();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
socket.on('player_left', function(data) {
|
||||
@@ -897,7 +934,20 @@ function updateRoomStatus() {
|
||||
}
|
||||
|
||||
function showNotification(message, type = 'info') {
|
||||
// Ограничиваем частоту уведомлений (не чаще 1 раза в 3 секунды)
|
||||
const now = Date.now();
|
||||
if (now - lastNotificationTime < 3000) {
|
||||
console.log('Notification throttled');
|
||||
return;
|
||||
}
|
||||
lastNotificationTime = now;
|
||||
|
||||
// Скрываем предыдущие уведомления
|
||||
const oldNotifications = document.querySelectorAll('.custom-notification');
|
||||
oldNotifications.forEach(n => n.remove());
|
||||
|
||||
const notification = document.createElement('div');
|
||||
notification.className = 'custom-notification';
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
top: 80px;
|
||||
@@ -911,6 +961,7 @@ function showNotification(message, type = 'info') {
|
||||
animation: slideInRight 0.3s ease;
|
||||
max-width: 300px;
|
||||
word-break: break-word;
|
||||
transition: opacity 0.3s;
|
||||
`;
|
||||
|
||||
if (type === 'success') notification.style.borderLeftColor = 'var(--success-color)';
|
||||
@@ -920,8 +971,9 @@ function showNotification(message, type = 'info') {
|
||||
notification.textContent = message;
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Автоматическое скрытие через 3 секунды
|
||||
setTimeout(() => {
|
||||
notification.style.animation = 'slideOutRight 0.3s ease';
|
||||
notification.style.opacity = '0';
|
||||
setTimeout(() => notification.remove(), 300);
|
||||
}, 3000);
|
||||
}
|
||||
@@ -958,6 +1010,105 @@ if (chatMessages) {
|
||||
if (chatInput) chatInput.focus();
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
if (typeof socket !== 'undefined' && socket.connected && roomCode) {
|
||||
socket.emit('leave_room', { room: roomCode });
|
||||
}
|
||||
});
|
||||
|
||||
// Обработка видимости страницы (если переключились на другую вкладку)
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (document.hidden) {
|
||||
console.log('Page is now hidden');
|
||||
} else {
|
||||
console.log('Page is now visible');
|
||||
// При возвращении на страницу проверяем статус
|
||||
updateRoomStatus();
|
||||
}
|
||||
});
|
||||
|
||||
// Функция обновления списка игроков без перезагрузки страницы
|
||||
function updatePlayerList() {
|
||||
console.log('Updating player list...');
|
||||
|
||||
fetch(`/api/room/${roomCode}/players`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success && data.players) {
|
||||
updatePlayerListUI(data.players);
|
||||
updateReadyStatus();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error updating player list:', error);
|
||||
// В случае ошибки делаем мягкую перезагрузку через 2 секунды
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
// Функция обновления UI списка игроков
|
||||
function updatePlayerListUI(players) {
|
||||
const playerList = document.getElementById('player-list');
|
||||
if (!playerList) return;
|
||||
|
||||
playerList.innerHTML = '';
|
||||
|
||||
players.forEach(player => {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'player-item';
|
||||
|
||||
li.innerHTML = `
|
||||
<div class="player-info">
|
||||
<div class="player-avatar" style="background-color: ${player.is_admin ? '#ff9800' : 'var(--primary-color)'};">
|
||||
${player.username ? player.username[0].toUpperCase() : '?'}
|
||||
</div>
|
||||
<div>
|
||||
<div style="display: flex; align-items: center; gap: 5px;">
|
||||
<strong>${player.username || 'Игрок'}</strong>
|
||||
${player.is_admin ? '<span style="background-color: #fff3e0; color: #ef6c00; padding: 2px 6px; border-radius: 10px; font-size: 0.75rem;">Админ</span>' : ''}
|
||||
${player.user_id == currentPlayerId ? '<span style="background-color: #e3f2fd; color: #1976d2; padding: 2px 6px; border-radius: 10px; font-size: 0.75rem;">Вы</span>' : ''}
|
||||
</div>
|
||||
<div class="player-capital">
|
||||
${formatCurrency(player.capital)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
${window.roomStatus === 'waiting' ? `
|
||||
<div class="player-ready ${player.is_ready ? 'ready' : 'not-ready'}">
|
||||
${player.is_ready ? '✅ Готов' : '⏳ Ожидание'}
|
||||
</div>
|
||||
` : ''}
|
||||
<div class="player-ability" title="${player.ability_description}">
|
||||
${player.ability_name}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
playerList.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
// Обработка дисконнекта WebSocket
|
||||
socket.on('disconnect', function(reason) {
|
||||
console.log('WebSocket disconnected:', reason);
|
||||
|
||||
if (reason === 'io server disconnect') {
|
||||
// Сервер намеренно отключил
|
||||
showNotification('🔌 Соединение с сервером потеряно. Переподключаемся...', 'warning');
|
||||
}
|
||||
});
|
||||
|
||||
// Периодическая проверка подключения
|
||||
setInterval(() => {
|
||||
if (socket && !socket.connected) {
|
||||
console.log('Socket not connected, attempting to reconnect...');
|
||||
socket.connect();
|
||||
}
|
||||
}, 5000);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block title %}Вход - Капитал & Рынок{% endblock %}
|
||||
|
||||
{% block screen_content %}
|
||||
{% block content %}
|
||||
<div class="header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Капитал & Рынок" class="logo">
|
||||
|
||||
Reference in New Issue
Block a user