184 lines
5.1 KiB
JavaScript
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;
|
|
}
|