Projet_Web_IceBreaker/assets/js/storage.js
2025-12-21 13:10:23 +01:00

184 lines
5.1 KiB
JavaScript

/*
* Gestion du stockage local - pseudo, scores, préférences
* localStorage + cookies en fallback
*/
const IceBreakerStorage = (function () {
'use strict';
// clés localStorage
const KEYS = {
CAPTAIN_NAME: 'icebreaker_captain',
LEADERBOARD: 'icebreaker_scores',
SETTINGS: 'icebreaker_settings',
PLAY_COUNT: 'icebreaker_plays',
LAST_PLAYED: 'icebreaker_lastplayed'
};
const MAX_SCORES = 10;
// --- Cookies (vieux mais ça marche) ---
function setCookie(name, value, days = 365) {
const expires = new Date(Date.now() + days * 864e5).toUTCString();
document.cookie = `${name}=${encodeURIComponent(JSON.stringify(value))}; expires=${expires}; path=/; SameSite=Lax`;
}
function getCookie(name) {
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) {
try {
return JSON.parse(decodeURIComponent(match[2]));
} catch {
return null;
}
}
return null;
}
function deleteCookie(name) {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
}
// --- Wrapper localStorage (avec fallback cookies au cas où) ---
function saveData(key, data) {
try {
localStorage.setItem(key, JSON.stringify(data));
} catch {
setCookie(key, data);
}
}
function loadData(key, defaultValue = null) {
try {
const data = localStorage.getItem(key);
return data ? JSON.parse(data) : getCookie(key) || defaultValue;
} catch {
return getCookie(key) || defaultValue;
}
}
// --- Fonctions publiques ---
// sauvegarde le nom du capitaine
function saveCaptainName(name) {
if (!name || typeof name !== 'string') return false;
const sanitized = name.trim().slice(0, 30);
saveData(KEYS.CAPTAIN_NAME, sanitized);
return true;
}
// récup le nom
function getCaptainName() {
return loadData(KEYS.CAPTAIN_NAME, null);
}
// le joueur est-il déjà venu ?
function isReturningPlayer() {
return loadData(KEYS.PLAY_COUNT, 0) > 0;
}
// +1 partie jouée
function incrementPlayCount() {
const count = loadData(KEYS.PLAY_COUNT, 0) + 1;
saveData(KEYS.PLAY_COUNT, count);
saveData(KEYS.LAST_PLAYED, Date.now());
return count;
}
// combien de parties ?
function getPlayCount() {
return loadData(KEYS.PLAY_COUNT, 0);
}
// enregistre un score
function saveScore(scoreData) {
const scores = loadData(KEYS.LEADERBOARD, []);
// Calculer le pourcentage de livraison si non fourni
let deliveryRate = scoreData.cargoDeliveryRate;
if (typeof deliveryRate !== 'number') {
const totalDelivered = parseInt(scoreData.totalDelivered) || 0;
const totalPossible = parseInt(scoreData.totalPossible) || 1;
deliveryRate = Math.round((totalDelivered / totalPossible) * 100);
}
const entry = {
score: parseInt(scoreData.score) || 0,
difficulty: parseFloat(scoreData.difficulty) || 1,
cargoDeliveryRate: deliveryRate, // Pourcentage de marchandise livrée
checkpoints: parseInt(scoreData.checkpoints) || 0, // Nombre de checkpoints atteints
captain: getCaptainName() || 'Anonyme',
timestamp: Date.now()
};
scores.push(entry);
// Trier et limiter
scores.sort((a, b) => b.score - a.score);
const trimmed = scores.slice(0, MAX_SCORES);
saveData(KEYS.LEADERBOARD, trimmed);
return entry;
}
// tous les scores
function getLeaderboard() {
return loadData(KEYS.LEADERBOARD, []);
}
// meilleur score
function getBestScore() {
const scores = getLeaderboard();
return scores.length > 0 ? scores[0] : null;
}
// tout effacer (reset)
function clearAllData() {
Object.values(KEYS).forEach(key => {
try {
localStorage.removeItem(key);
} catch { }
deleteCookie(key);
});
}
// --- Audio ---
function saveSettings(settings) {
const current = loadData(KEYS.SETTINGS, {});
const merged = { ...current, ...settings };
saveData(KEYS.SETTINGS, merged);
return merged;
}
function getSettings() {
return loadData(KEYS.SETTINGS, {
masterVolume: 0.8,
sfxVolume: 1.0,
musicVolume: 0.6,
sfxEnabled: true,
musicEnabled: true
});
}
// Exposer l'API
return {
saveCaptainName,
getCaptainName,
isReturningPlayer,
incrementPlayCount,
getPlayCount,
saveScore,
getLeaderboard,
getBestScore,
clearAllData,
saveSettings,
getSettings,
KEYS
};
})();
// Export pour utilisation en modules si nécessaire
if (typeof module !== 'undefined' && module.exports) {
module.exports = IceBreakerStorage;
}