package net.shadewind.racetrack.server;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.shadewind.racetrack.Score;
/**
* Manages high scores.
*
* @author shadewind
*/
public class HighscoreManager {
private static final Logger logger = Logger
.getLogger("net.shadewind.racetrack.server.HighscoreManager");
private static final int LIST_SIZE = 10;
private final Path path;
private final List<Score> scores = new ArrayList<Score>();
/**
* Creates a <code>HighscoreManager</code> that stores high scores in the
* specified file.
*
* @param path The path to the high score file.
*/
public HighscoreManager(Path path)
{
this.path = path;
}
/**
* Loads the high scores from the file replacing the current ones.
*/
public synchronized void load()
{
try {
List<String> lines = Files.readAllLines(path,
StandardCharsets.UTF_8);
scores.clear();
for (String line : lines) {
Score score = Score.parse(line);
if (score != null)
scores.add(score);
}
} catch (NoSuchFileException e) {
logger.info("High score file doesn't exist, starting from scratch.");
} catch (IOException e) {
logger.log(Level.WARNING,
"Unable to load high scores from score file.", e);
}
}
/**
* Adds scores.
*
* @param scores The scores to add.
*/
public synchronized void addScores(Collection<Score> scores)
{
this.scores.addAll(scores);
save();
}
/**
* Returns highs cores filtered by map name and collision setting and sorted
* by number of steps.
*
* @param mapName The name of the map.
* @param collisionsEnabled Whether collisions were enabled.
*/
public synchronized List<Score> getScores(String mapName, boolean collisionsEnabled)
{
List<Score> selected = new ArrayList<Score>();
for (Score score : scores) {
if (score.getMapName().equals(mapName) && (score.isCollisionsEnabled() == collisionsEnabled))
selected.add(score);
}
Collections.sort(selected);
if (selected.size() > LIST_SIZE)
return selected.subList(0, LIST_SIZE);
else
return selected;
}
private synchronized void save()
{
List<String> scoreStrings = new ArrayList<String>();
for (Score score : scores)
scoreStrings.add(score.toString());
try {
Files.write(path, scoreStrings, StandardCharsets.UTF_8);
} catch (IOException e) {
logger.log(Level.WARNING, "Unable to save scores to score file.", e);
}
}
}