finish
This commit is contained in:
parent
7aa6a2a8fb
commit
5d72bc1ab4
@ -15,6 +15,9 @@ let connectionTimestamp = null;
|
|||||||
let reconnectDelayMs = 5000;
|
let reconnectDelayMs = 5000;
|
||||||
const RECONNECT_DELAY_MAX_MS = 5 * 60 * 1000; // 5 min
|
const RECONNECT_DELAY_MAX_MS = 5 * 60 * 1000; // 5 min
|
||||||
|
|
||||||
|
// Suivi des joueurs connectés (fallback si la console n’affiche pas les déconnexions)
|
||||||
|
const connectedPlayers = new Map(); // steamId -> { name, playerId, lastSeen }
|
||||||
|
|
||||||
const parseLogMessage = (log) => {
|
const parseLogMessage = (log) => {
|
||||||
// Format réel de log Palworld:
|
// Format réel de log Palworld:
|
||||||
// [2025-12-09 13:28:23] [CHAT] <LouisMazin> !link X2NMAY
|
// [2025-12-09 13:28:23] [CHAT] <LouisMazin> !link X2NMAY
|
||||||
@ -135,12 +138,87 @@ const getWebSocketCredentials = async (pterodactylToken, serverId) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper: récupérer la liste actuelle des joueurs via l’API Palworld
|
||||||
|
const fetchCurrentPlayers = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
method: 'get',
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
url: 'http://play.louismazin.ovh:8212/v1/api/players',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Basic ${process.env.PALWORLD_API_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const players = response.data.players || {};
|
||||||
|
const list = [];
|
||||||
|
for (const [, player] of Object.entries(players)) {
|
||||||
|
list.push({
|
||||||
|
steamId: player.userId,
|
||||||
|
playerId: player.playerId,
|
||||||
|
name: player.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
} catch (error) {
|
||||||
|
// API inaccessible quand le serveur est down
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mettre à jour le set des joueurs et détecter les départs silencieux
|
||||||
|
const pollPlayersAndDetectDisconnects = async (serverState = null) => {
|
||||||
|
const list = await fetchCurrentPlayers();
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
// Marquer présents
|
||||||
|
for (const p of list) {
|
||||||
|
connectedPlayers.set(p.steamId, { name: p.name, playerId: p.playerId, lastSeen: now });
|
||||||
|
}
|
||||||
|
// Détecter ceux qui ont disparu depuis le dernier poll
|
||||||
|
for (const [steamId, info] of connectedPlayers) {
|
||||||
|
const stillHere = list.find(x => x.steamId === steamId);
|
||||||
|
if (!stillHere) {
|
||||||
|
try {
|
||||||
|
const result = await updateLastConnection(steamId);
|
||||||
|
if (result.changes > 0) {
|
||||||
|
console.log(`✅ Départ silencieux détecté: ${info.name} (${steamId}) -> lastConnection mis à jour`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`❌ Erreur update lastConnection pour ${steamId}:`, e.message);
|
||||||
|
}
|
||||||
|
connectedPlayers.delete(steamId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Pas de liste (serveur inaccessible) ou vide:
|
||||||
|
// Si le serveur est arrêté/stopping/offline, considérer tous comme déconnectés
|
||||||
|
if (serverState && ['offline', 'stopping', 'stopped'].includes(serverState)) {
|
||||||
|
for (const [steamId, info] of connectedPlayers) {
|
||||||
|
try {
|
||||||
|
const result = await updateLastConnection(steamId);
|
||||||
|
if (result.changes > 0) {
|
||||||
|
console.log(`✅ Serveur ${serverState}: déconnexion implicite de ${info.name} (${steamId})`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`❌ Erreur update lastConnection pour ${steamId}:`, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connectedPlayers.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const checkAndManageWebSocket = async () => {
|
const checkAndManageWebSocket = async () => {
|
||||||
const { hasActiveLinkCodes, cleanExpiredCodes } = require('./database.js');
|
const { cleanExpiredCodes } = require('./database.js');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await cleanExpiredCodes();
|
await cleanExpiredCodes();
|
||||||
|
|
||||||
|
// Fallback polling toutes les 20s
|
||||||
|
await pollPlayersAndDetectDisconnects();
|
||||||
|
|
||||||
// Le WebSocket doit toujours être connecté maintenant (pour les déconnexions)
|
// Le WebSocket doit toujours être connecté maintenant (pour les déconnexions)
|
||||||
if (!ws && !isConnecting) {
|
if (!ws && !isConnecting) {
|
||||||
console.log('🔌 Connexion au WebSocket pour surveillance...');
|
console.log('🔌 Connexion au WebSocket pour surveillance...');
|
||||||
@ -263,7 +341,13 @@ const connectWebSocket = async (pterodactylToken, serverId) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message.event === 'status') {
|
if (message.event === 'status') {
|
||||||
console.log('📊 Statut du serveur:', message.args[0]);
|
const state = message.args[0];
|
||||||
|
console.log('📊 Statut du serveur:', state);
|
||||||
|
|
||||||
|
// Si le serveur s’arrête/offline, forcer la mise à jour des joueurs connectés (déconnexions implicites)
|
||||||
|
if (['offline', 'stopping', 'stopped'].includes(state)) {
|
||||||
|
await pollPlayersAndDetectDisconnects(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -335,9 +419,9 @@ const startConsoleMonitoring = (discordClient, pterodactylToken) => {
|
|||||||
// Vérifier immédiatement
|
// Vérifier immédiatement
|
||||||
checkAndManageWebSocket();
|
checkAndManageWebSocket();
|
||||||
|
|
||||||
// Vérifier toutes les 30 secondes (nettoyage codes et reconnect si besoin)
|
// Vérifier toutes les 20 secondes (nettoyage codes et reconnect si besoin)
|
||||||
if (checkInterval) clearInterval(checkInterval);
|
if (checkInterval) clearInterval(checkInterval);
|
||||||
checkInterval = setInterval(checkAndManageWebSocket, 30000);
|
checkInterval = setInterval(checkAndManageWebSocket, 20000); // 20s pour détecter vite les départs silencieux
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopConsoleMonitoring = () => {
|
const stopConsoleMonitoring = () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user