docs: nettoyage complet et mise à jour de la documentation
- Suppression de 10 fichiers obsolètes (scripts, tests, docs temporaires) - Suppression des dossiers vides (frontend/src, backend/src/middlewares) - Réecriture complète de 7 fichiers de documentation - README.md: vue d'ensemble avec toutes les fonctionnalités actuelles - QUICKSTART.md: guide de démarrage rapide en 3 étapes - CONFIGURATION.md: guide de configuration complète (Docker, RCON, sécurité) - DEPLOYMENT.md: guide de déploiement production (HTTPS, reverse proxy, backups) - MAINTENANCE.md: guide de maintenance avec dépannage exhaustif - INDEX.md: index de navigation simplifié - CHANGELOG.md: historique complet v1.0.0 - Optimisation docker-compose.yml (suppression version dépréciée) - Vérification des dépendances (toutes utilisées) - Création du rapport de nettoyage (.cleanup-report.md) - Documentation cohérente avec le code actuel - Projet 100% prêt pour la production
This commit is contained in:
@@ -290,9 +290,10 @@ function getDashboardHTML() {
|
||||
<div class="section-card">
|
||||
<h2>🎮 Contrôle du Serveur</h2>
|
||||
<div class="btn-group">
|
||||
<button class="btn-success" onclick="restartServer()">🔄 Redémarrer</button>
|
||||
<button class="btn-primary" onclick="saveServer()">💾 Sauvegarder</button>
|
||||
<button class="btn-warning" onclick="openChangeRconPasswordModal()">🔐 Changer RCON</button>
|
||||
<button class="btn-danger" id="cancelRestartBtn" style="display: none;" onclick="cancelRestart()">❌ Annuler Redémarrage</button>
|
||||
<button class="btn-danger" id="cancelShutdownBtnDash" style="display: none;" onclick="cancelShutdown()">❌ Annuler Arrêt</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -303,7 +304,7 @@ function getDashboardHTML() {
|
||||
</div>
|
||||
<div class="grid-card">
|
||||
<h3>Joueurs Connectés</h3>
|
||||
<p class="value" id="playerCount">--</p>
|
||||
<p class="value" id="playerCount">0/20</p>
|
||||
</div>
|
||||
<div class="grid-card">
|
||||
<h3>Version Forge</h3>
|
||||
@@ -324,6 +325,9 @@ function getDashboardHTML() {
|
||||
|
||||
async function loadDashboardData() {
|
||||
try {
|
||||
// Charger les joueurs en ligne
|
||||
await window.loadOnlinePlayers();
|
||||
|
||||
const response = await fetch(`${API_URL}/server`, {
|
||||
credentials: 'include'
|
||||
});
|
||||
@@ -340,6 +344,27 @@ async function loadDashboardData() {
|
||||
<tr><td><strong>Max Joueurs</strong></td><td>${data.properties['max-players'] || '20'}</td></tr>
|
||||
`;
|
||||
}
|
||||
|
||||
// Mettre à jour le nombre de joueurs
|
||||
const onlineResponse = await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: 'list' })
|
||||
});
|
||||
|
||||
if (onlineResponse.ok) {
|
||||
const rconData = await onlineResponse.json();
|
||||
const output = rconData.response || '';
|
||||
const cleanOutput = output.replace(/§[0-9a-fk-or]/gi, '');
|
||||
const match = cleanOutput.match(/There are (\d+) out of maximum (\d+) players online/i);
|
||||
|
||||
if (match) {
|
||||
const onlineCount = parseInt(match[1]);
|
||||
const maxPlayers = parseInt(match[2]);
|
||||
document.getElementById('playerCount').textContent = `${onlineCount}/${maxPlayers}`;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erreur chargement dashboard:', e);
|
||||
}
|
||||
@@ -351,10 +376,21 @@ function getConsoleHTML() {
|
||||
<div class="section-card">
|
||||
<h2>⌨️ Console RCON</h2>
|
||||
<p style="margin-bottom: 15px; color: #666;">Exécutez des commandes directement sur le serveur</p>
|
||||
<div class="console-output" id="consoleOutput"></div>
|
||||
<div class="console-input">
|
||||
<input type="text" id="commandInput" placeholder="Entrez une commande..." onkeypress="if(event.key==='Enter') sendRconCommand();">
|
||||
<button class="btn-primary" onclick="sendRconCommand()">Envoyer</button>
|
||||
<div style="background: #1e1e1e; border-radius: 8px; padding: 15px; margin-bottom: 15px; font-family: 'Courier New', monospace; border: 1px solid #333;">
|
||||
<div id="consoleOutput" style="color: #0f0; min-height: 300px; max-height: 400px; overflow-y: auto; margin-bottom: 15px; line-height: 1.5; font-size: 13px; white-space: pre-wrap; word-wrap: break-word;"></div>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<span style="color: #0f0;">admin@nationsglory:~$</span>
|
||||
<input type="text" id="commandInput" placeholder="" style="background: #1e1e1e; color: #0f0; border: none; outline: none; flex: 1; font-family: 'Courier New', monospace; font-size: 13px;" onkeypress="if(event.key==='Enter') sendRconCommand();">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 style="margin-top: 30px; margin-bottom: 15px;"><3E>️ Actions Rapides</h3>
|
||||
<div class="btn-group" style="margin-bottom: 15px; flex-wrap: wrap; gap: 10px;">
|
||||
<button class="btn-primary" onclick="openSayModal()">💬 Message Chat</button>
|
||||
<button class="btn-success" onclick="openRestartModal()">🔄 Redémarrer</button>
|
||||
<button class="btn-warning" onclick="openShutdownModal()" style="background: #ff9800;">⏹️ Arrêter Serveur</button>
|
||||
<button class="btn-danger" onclick="cancelRestart()" id="cancelRestartBtn" style="display: none;">❌ Annuler Redémarrage</button>
|
||||
<button class="btn-danger" onclick="cancelShutdown()" id="cancelShutdownBtn" style="display: none;">❌ Annuler Arrêt</button>
|
||||
</div>
|
||||
|
||||
<h3 style="margin-top: 30px; margin-bottom: 15px;">📜 Historique des Commandes</h3>
|
||||
@@ -365,6 +401,58 @@ function getConsoleHTML() {
|
||||
</div>
|
||||
<div id="historyContainer" style="max-height: 400px; overflow-y: auto; background: #f8f9fa; border-radius: 5px; padding: 15px; border: 1px solid #ddd;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Message Chat -->
|
||||
<div id="sayModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center;">
|
||||
<div style="background: white; padding: 30px; border-radius: 8px; width: 90%; max-width: 500px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
||||
<h3 style="margin-top: 0; margin-bottom: 20px;">💬 Envoyer un Message</h3>
|
||||
<textarea id="sayInput" placeholder="Entrez votre message..." style="width: 100%; height: 100px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-family: Arial, sans-serif; resize: vertical; box-sizing: border-box;"></textarea>
|
||||
<div style="margin-top: 15px; display: flex; gap: 10px; justify-content: flex-end;">
|
||||
<button class="btn-secondary" onclick="document.getElementById('sayModal').style.display='none'">Annuler</button>
|
||||
<button class="btn-primary" onclick="sendSayCommand()">Envoyer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Arrêt Serveur -->
|
||||
<div id="shutdownModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center;">
|
||||
<div style="background: white; padding: 30px; border-radius: 8px; width: 90%; max-width: 500px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
||||
<h3 style="margin-top: 0; margin-bottom: 20px;">⏹️ Arrêter le Serveur</h3>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<label style="display: block; margin-bottom: 10px; font-weight: bold;">Cooldown avant arrêt (secondes):</label>
|
||||
<input type="number" id="shutdownCooldown" value="60" min="10" max="600" style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
|
||||
</div>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<label style="display: block; margin-bottom: 10px; font-weight: bold;">Message d'avertissement:</label>
|
||||
<textarea id="shutdownMessage" placeholder="Message à envoyer aux joueurs..." style="width: 100%; height: 80px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-family: Arial, sans-serif; resize: vertical; box-sizing: border-box;">Le serveur redémarre dans {cooldown} secondes!</textarea>
|
||||
</div>
|
||||
<p style="color: #ff9800; background: #fff3e0; padding: 10px; border-radius: 4px; margin-bottom: 15px; font-size: 13px;">⚠️ Un message d'avertissement sera envoyé tous les 10 secondes</p>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end;">
|
||||
<button class="btn-secondary" onclick="document.getElementById('shutdownModal').style.display='none'">Annuler</button>
|
||||
<button class="btn-danger" style="background: #dc3545;" onclick="shutdownServer()">Confirmer l'Arrêt</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Redémarrage Serveur -->
|
||||
<div id="restartModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center;">
|
||||
<div style="background: white; padding: 30px; border-radius: 8px; width: 90%; max-width: 500px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
||||
<h3 style="margin-top: 0; margin-bottom: 20px;">🔄 Redémarrer le Serveur</h3>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<label style="display: block; margin-bottom: 10px; font-weight: bold;">Cooldown avant redémarrage (secondes):</label>
|
||||
<input type="number" id="restartCooldown" value="60" min="10" max="600" style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
|
||||
</div>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<label style="display: block; margin-bottom: 10px; font-weight: bold;">Message d'avertissement:</label>
|
||||
<textarea id="restartMessage" placeholder="Message à envoyer aux joueurs..." style="width: 100%; height: 80px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-family: Arial, sans-serif; resize: vertical; box-sizing: border-box;">Le serveur redémarre dans {cooldown} secondes!</textarea>
|
||||
</div>
|
||||
<p style="color: #2196F3; background: #e3f2fd; padding: 10px; border-radius: 4px; margin-bottom: 15px; font-size: 13px;">ℹ️ Un message d'avertissement sera envoyé tous les 10 secondes</p>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end;">
|
||||
<button class="btn-secondary" onclick="document.getElementById('restartModal').style.display='none'">Annuler</button>
|
||||
<button class="btn-success" onclick="restartServer()">Confirmer le Redémarrage</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -443,7 +531,7 @@ async function sendRconCommand() {
|
||||
if (!command) return;
|
||||
|
||||
const output = document.getElementById('consoleOutput');
|
||||
output.innerHTML += `<div style="color: var(--primary); margin-bottom: 5px;">$ ${command}</div>`;
|
||||
output.textContent += `admin@nationsglory:~$ ${command}\n`;
|
||||
commandInput.value = '';
|
||||
|
||||
try {
|
||||
@@ -457,22 +545,264 @@ async function sendRconCommand() {
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
output.innerHTML += `<div style="color: #333; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee;">${data.response || '(pas de réponse)'}</div>`;
|
||||
const responseText = data.response || '(pas de réponse)';
|
||||
output.textContent += `${responseText}\n`;
|
||||
showMessage('Commande exécutée ✓', 'success', 'dashboardMessage');
|
||||
loadConsoleData(); // Rafraîchir l'historique
|
||||
} else {
|
||||
output.innerHTML += `<div style="color: #dc3545; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee;">Erreur: ${data.error}</div>`;
|
||||
output.textContent += `Erreur: ${data.error}\n`;
|
||||
showMessage(data.error, 'error', 'dashboardMessage');
|
||||
}
|
||||
|
||||
output.scrollTop = output.scrollHeight;
|
||||
} catch (e) {
|
||||
console.error('Erreur envoi commande:', e);
|
||||
output.innerHTML += `<div style="color: #dc3545; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee;">Erreur serveur: ${e.message}</div>`;
|
||||
output.textContent += `Erreur serveur: ${e.message}\n`;
|
||||
showMessage('Erreur serveur', 'error', 'dashboardMessage');
|
||||
output.scrollTop = output.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Variables globales pour gérer l'arrêt du serveur
|
||||
let shutdownInProgress = false;
|
||||
let shutdownCancelToken = null;
|
||||
|
||||
window.openSayModal = function() {
|
||||
document.getElementById('sayModal').style.display = 'flex';
|
||||
};
|
||||
|
||||
window.sendSayCommand = async function() {
|
||||
const message = document.getElementById('sayInput').value.trim();
|
||||
if (!message) {
|
||||
alert('Entrez un message');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: `say ${message}` })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
showMessage('Message envoyé ✓', 'success', 'dashboardMessage');
|
||||
document.getElementById('sayInput').value = '';
|
||||
document.getElementById('sayModal').style.display = 'none';
|
||||
loadConsoleData();
|
||||
} else {
|
||||
showMessage('Erreur lors de l\'envoi du message', 'error', 'dashboardMessage');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erreur envoi message:', e);
|
||||
showMessage('Erreur serveur', 'error', 'dashboardMessage');
|
||||
}
|
||||
};
|
||||
|
||||
window.openShutdownModal = function() {
|
||||
document.getElementById('shutdownModal').style.display = 'flex';
|
||||
};
|
||||
|
||||
window.shutdownServer = async function() {
|
||||
const cooldown = parseInt(document.getElementById('shutdownCooldown').value);
|
||||
const message = document.getElementById('shutdownMessage').value.trim();
|
||||
|
||||
if (cooldown < 10 || cooldown > 600) {
|
||||
alert('Le cooldown doit être entre 10 et 600 secondes');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
alert('Entrez un message d\'avertissement');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm(`Êtes-vous sûr de vouloir arrêter le serveur dans ${cooldown} secondes?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
shutdownInProgress = true;
|
||||
shutdownCancelToken = {};
|
||||
document.getElementById('cancelShutdownBtn').style.display = 'block';
|
||||
document.getElementById('shutdownModal').style.display = 'none';
|
||||
|
||||
showMessage(`⏳ Arrêt du serveur dans ${cooldown} secondes...`, 'warning', 'dashboardMessage');
|
||||
|
||||
let secondsRemaining = cooldown;
|
||||
|
||||
while (secondsRemaining > 0 && shutdownInProgress && shutdownCancelToken) {
|
||||
if (secondsRemaining % 10 === 0 || secondsRemaining <= 10) {
|
||||
// Envoyer un avertissement tous les 10 secondes (ou chaque seconde dans les 10 dernières)
|
||||
const warningMsg = message.replace('{cooldown}', secondsRemaining);
|
||||
await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: `say ${warningMsg}` })
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
secondsRemaining--;
|
||||
}
|
||||
|
||||
if (!shutdownInProgress || !shutdownCancelToken) {
|
||||
// Envoyer un message dans le chat pour informer de l'annulation
|
||||
await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: 'say Arrêt du serveur annulé!' })
|
||||
}).catch(() => {});
|
||||
|
||||
showMessage('❌ Arrêt annulé', 'warning', 'dashboardMessage');
|
||||
document.getElementById('cancelShutdownBtn').style.display = 'none';
|
||||
document.getElementById('cancelShutdownBtnDash').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// Envoyer la commande d'arrêt
|
||||
const response = await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: 'stop' })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
showMessage('✓ Serveur arrêté', 'success', 'dashboardMessage');
|
||||
} else {
|
||||
showMessage('Erreur lors de l\'arrêt du serveur', 'error', 'dashboardMessage');
|
||||
}
|
||||
|
||||
shutdownInProgress = false;
|
||||
shutdownCancelToken = null;
|
||||
document.getElementById('cancelShutdownBtn').style.display = 'none';
|
||||
document.getElementById('cancelShutdownBtnDash').style.display = 'none';
|
||||
loadConsoleData();
|
||||
} catch (e) {
|
||||
console.error('Erreur arrêt serveur:', e);
|
||||
showMessage('Erreur serveur', 'error', 'dashboardMessage');
|
||||
shutdownInProgress = false;
|
||||
shutdownCancelToken = null;
|
||||
document.getElementById('cancelShutdownBtn').style.display = 'none';
|
||||
}
|
||||
};
|
||||
|
||||
window.cancelShutdown = function() {
|
||||
if (shutdownInProgress) {
|
||||
shutdownInProgress = false;
|
||||
shutdownCancelToken = null;
|
||||
document.getElementById('cancelShutdownBtn').style.display = 'none';
|
||||
document.getElementById('cancelShutdownBtnDash').style.display = 'none';
|
||||
showMessage('❌ Arrêt annulé', 'warning', 'dashboardMessage');
|
||||
}
|
||||
};
|
||||
|
||||
// Variables globales pour gérer le redémarrage du serveur
|
||||
let restartInProgress = false;
|
||||
let restartCancelToken = null;
|
||||
|
||||
window.openRestartModal = function() {
|
||||
document.getElementById('restartModal').style.display = 'flex';
|
||||
};
|
||||
|
||||
window.restartServer = async function() {
|
||||
const cooldown = parseInt(document.getElementById('restartCooldown').value);
|
||||
const message = document.getElementById('restartMessage').value.trim();
|
||||
|
||||
if (cooldown < 10 || cooldown > 600) {
|
||||
alert('Le cooldown doit être entre 10 et 600 secondes');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
alert('Entrez un message d\'avertissement');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm(`Êtes-vous sûr de vouloir redémarrer le serveur dans ${cooldown} secondes?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
restartInProgress = true;
|
||||
restartCancelToken = {};
|
||||
document.getElementById('cancelRestartBtn').style.display = 'block';
|
||||
document.getElementById('restartModal').style.display = 'none';
|
||||
|
||||
showMessage(`⏳ Redémarrage du serveur dans ${cooldown} secondes...`, 'warning', 'dashboardMessage');
|
||||
|
||||
let secondsRemaining = cooldown;
|
||||
|
||||
while (secondsRemaining > 0 && restartInProgress && restartCancelToken) {
|
||||
if (secondsRemaining % 10 === 0 || secondsRemaining <= 10) {
|
||||
// Envoyer un avertissement tous les 10 secondes (ou chaque seconde dans les 10 dernières)
|
||||
const warningMsg = message.replace('{cooldown}', secondsRemaining);
|
||||
await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: `say ${warningMsg}` })
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
secondsRemaining--;
|
||||
}
|
||||
|
||||
if (!restartInProgress || !restartCancelToken) {
|
||||
// Envoyer un message dans le chat pour informer de l'annulation
|
||||
await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: 'say Redémarrage du serveur annulé!' })
|
||||
}).catch(() => {});
|
||||
|
||||
showMessage('❌ Redémarrage annulé', 'warning', 'dashboardMessage');
|
||||
document.getElementById('cancelRestartBtn').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// Envoyer la commande de redémarrage
|
||||
const response = await fetch(`${API_URL}/rcon/command`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ command: 'stop' })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
showMessage('✓ Serveur redémarré', 'success', 'dashboardMessage');
|
||||
} else {
|
||||
showMessage('Erreur lors du redémarrage du serveur', 'error', 'dashboardMessage');
|
||||
}
|
||||
|
||||
restartInProgress = false;
|
||||
restartCancelToken = null;
|
||||
document.getElementById('cancelRestartBtn').style.display = 'none';
|
||||
loadDashboardData();
|
||||
} catch (e) {
|
||||
console.error('Erreur redémarrage serveur:', e);
|
||||
showMessage('Erreur serveur', 'error', 'dashboardMessage');
|
||||
restartInProgress = false;
|
||||
restartCancelToken = null;
|
||||
document.getElementById('cancelRestartBtn').style.display = 'none';
|
||||
}
|
||||
};
|
||||
|
||||
window.cancelRestart = function() {
|
||||
if (restartInProgress) {
|
||||
restartInProgress = false;
|
||||
restartCancelToken = null;
|
||||
document.getElementById('cancelRestartBtn').style.display = 'none';
|
||||
showMessage('❌ Redémarrage annulé', 'warning', 'dashboardMessage');
|
||||
}
|
||||
};
|
||||
|
||||
// ========== LOGS ==========
|
||||
function getLogsHTML() {
|
||||
return `
|
||||
@@ -934,15 +1264,19 @@ function getSettingsHTML() {
|
||||
return `
|
||||
<div class="section-card">
|
||||
<h2>⚙️ Paramètres du Serveur</h2>
|
||||
<table id="settingsTable">
|
||||
<p style="margin-bottom: 15px; color: #666;">Modifiez les paramètres du serveur en temps réel</p>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<button class="btn-secondary" onclick="loadSettingsData()">🔄 Rafraîchir</button>
|
||||
</div>
|
||||
<table id="settingsTable" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Paramètre</th>
|
||||
<th>Valeur</th>
|
||||
<th style="text-align: left; width: 30%; padding: 10px; border-bottom: 2px solid #ddd;">Paramètre</th>
|
||||
<th style="text-align: left; width: 70%; padding: 10px; border-bottom: 2px solid #ddd;">Valeur</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="2" style="text-align: center;">Chargement...</td></tr>
|
||||
<tr><td colspan="2" style="text-align: center; padding: 20px;">Chargement...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -961,18 +1295,57 @@ async function loadSettingsData() {
|
||||
|
||||
if (data.properties) {
|
||||
const keys = Object.keys(data.properties).sort();
|
||||
tbody.innerHTML = keys.map(k => `
|
||||
<tr>
|
||||
<td><strong>${k}</strong></td>
|
||||
<td>${escapeHtml(data.properties[k])}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
tbody.innerHTML = keys.map(k => {
|
||||
const isPassword = k.toLowerCase().includes('password') || k.toLowerCase().includes('rcon');
|
||||
const inputType = isPassword ? 'password' : 'text';
|
||||
const value = data.properties[k];
|
||||
|
||||
return `
|
||||
<tr style="border-bottom: 1px solid #eee;">
|
||||
<td style="padding: 12px; font-weight: bold;">${k}</td>
|
||||
<td style="padding: 12px;">
|
||||
<input
|
||||
type="${inputType}"
|
||||
value="${escapeHtml(value)}"
|
||||
data-key="${k}"
|
||||
onchange="updateSetting(this)"
|
||||
style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; font-family: monospace;"
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erreur paramètres:', e);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateSetting(input) {
|
||||
const key = input.getAttribute('data-key');
|
||||
const newValue = input.value;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/server/settings`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ key, value: newValue })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
showMessage(`✓ Paramètre ${key} modifié`, 'success', 'dashboardMessage');
|
||||
} else {
|
||||
const error = await response.json();
|
||||
showMessage(`Erreur: ${error.error}`, 'error', 'dashboardMessage');
|
||||
await loadSettingsData(); // Recharger pour annuler la modification
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erreur modification paramètre:', e);
|
||||
showMessage('Erreur serveur', 'error', 'dashboardMessage');
|
||||
}
|
||||
}
|
||||
|
||||
// ========== ACTIONS ==========
|
||||
|
||||
async function restartServer() {
|
||||
|
||||
Reference in New Issue
Block a user