Adding statistics methods and also, fixing watchable/cancellable games.
This commit is contained in:
@@ -7,9 +7,7 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class GameHistoryDAO {
|
public class GameHistoryDAO {
|
||||||
private DbAccess _dbAccess;
|
private DbAccess _dbAccess;
|
||||||
@@ -181,6 +179,61 @@ public class GameHistoryDAO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getOldestGameHistoryEntry() {
|
||||||
|
try {
|
||||||
|
Connection connection = _dbAccess.getDataSource().getConnection();
|
||||||
|
try {
|
||||||
|
PreparedStatement statement = connection.prepareStatement("select min(end_date) from game_history where (tournament is null or tournament = 'Casual')");
|
||||||
|
try {
|
||||||
|
ResultSet rs = statement.executeQuery();
|
||||||
|
try {
|
||||||
|
if (rs.next())
|
||||||
|
return rs.getLong(1);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
} finally {
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
} catch (SQLException exp) {
|
||||||
|
throw new RuntimeException("Unable to get count of games played", exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getCasualGamesPlayedPerFormat(long from, long duration) {
|
||||||
|
try {
|
||||||
|
Connection connection = _dbAccess.getDataSource().getConnection();
|
||||||
|
try {
|
||||||
|
PreparedStatement statement = connection.prepareStatement("select count(*), format_name from game_history where (tournament is null or tournament = 'Casual') and end_date>=? and end_date<? group by format_name");
|
||||||
|
try {
|
||||||
|
statement.setLong(1, from);
|
||||||
|
statement.setLong(2, from + duration);
|
||||||
|
ResultSet rs = statement.executeQuery();
|
||||||
|
Map<String, Integer> result = new HashMap<String, Integer>();
|
||||||
|
try {
|
||||||
|
while (rs.next()) {
|
||||||
|
result.put(rs.getString(2), rs.getInt(1));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
} catch (SQLException exp) {
|
||||||
|
throw new RuntimeException("Unable to get count of games played", exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
// select deck_name, format_name, sum(win), sum(lose) from
|
// select deck_name, format_name, sum(win), sum(lose) from
|
||||||
// (select winner_deck_name as deck_name, format_name, 1 as win, 0 as lose from game_history where winner='hsiale' union all select loser_deck_name as deck_name, format_name, 0 as win, 1 as lose from game_history where loser='hsiale') as u
|
// (select winner_deck_name as deck_name, format_name, 1 as win, 0 as lose from game_history where winner='hsiale' union all select loser_deck_name as deck_name, format_name, 0 as win, 1 as lose from game_history where loser='hsiale') as u
|
||||||
|
|||||||
@@ -69,4 +69,14 @@ public class GameHistoryService {
|
|||||||
_gamesPlayedCountCachedTimes.put(ms, minute);
|
_gamesPlayedCountCachedTimes.put(ms, minute);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getOldestGameHistoryEntry() {
|
||||||
|
return _gameHistoryDAO.getOldestGameHistoryEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameHistoryStatistics getGameHistoryStatistics(long from, long duration) {
|
||||||
|
GameHistoryStatistics stats = new GameHistoryStatistics(from, duration);
|
||||||
|
stats.init(_gameHistoryDAO);
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package com.gempukku.lotro.game;
|
||||||
|
|
||||||
|
import com.gempukku.lotro.db.GameHistoryDAO;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class GameHistoryStatistics {
|
||||||
|
private List<FormatStat> _formatStats;
|
||||||
|
private long _start;
|
||||||
|
private long _duration;
|
||||||
|
|
||||||
|
public GameHistoryStatistics(long start, long duration) {
|
||||||
|
_start = start;
|
||||||
|
_duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(GameHistoryDAO gameHistoryDao) {
|
||||||
|
Map<String, Integer> countsPerFormat = gameHistoryDao.getCasualGamesPlayedPerFormat(_start, _duration);
|
||||||
|
Map<String, Integer> result = new HashMap<String, Integer>();
|
||||||
|
for (Map.Entry<String, Integer> formatCount : countsPerFormat.entrySet()) {
|
||||||
|
String format = formatCount.getKey();
|
||||||
|
if (!isIgnorable(format)) {
|
||||||
|
incrementResult(result, getMainFormat(format), formatCount.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
for (Integer integer : result.values())
|
||||||
|
sum += integer;
|
||||||
|
|
||||||
|
List<FormatStat> stats = new ArrayList<FormatStat>();
|
||||||
|
for (Map.Entry<String, Integer> formatCount : result.entrySet())
|
||||||
|
stats.add(new FormatStat(formatCount.getKey(), formatCount.getValue(), 1f * formatCount.getValue() / sum));
|
||||||
|
|
||||||
|
Collections.sort(stats, new Comparator<FormatStat>() {
|
||||||
|
@Override
|
||||||
|
public int compare(FormatStat o1, FormatStat o2) {
|
||||||
|
return o2.getCount() - o1.getCount();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_formatStats = stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void incrementResult(Map<String, Integer> result, String format, int value) {
|
||||||
|
Integer previous = result.get(format);
|
||||||
|
if (previous == null)
|
||||||
|
previous = 0;
|
||||||
|
result.put(format, previous + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMainFormat(String format) {
|
||||||
|
if (format.equals("Community Fellowship block"))
|
||||||
|
return "Fellowship block";
|
||||||
|
if (format.equals("Community Two Towers block"))
|
||||||
|
return "Towers block";
|
||||||
|
if (format.equals("Community War of the Ring block"))
|
||||||
|
return "War of the Ring block";
|
||||||
|
if (format.equals("Two Towers block"))
|
||||||
|
return "Towers block";
|
||||||
|
if (format.equals("Towers Standard"))
|
||||||
|
return "Towers standard";
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isIgnorable(String format) {
|
||||||
|
if (format.startsWith("Fellowship block - "))
|
||||||
|
return true;
|
||||||
|
if (format.equals("Format for testing"))
|
||||||
|
return true;
|
||||||
|
if (format.equals("Sealed FotR League (Dec 2011)"))
|
||||||
|
return true;
|
||||||
|
if (format.startsWith("Test league"))
|
||||||
|
return true;
|
||||||
|
if (format.startsWith("Towers block - "))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FormatStat> getFormatStats() {
|
||||||
|
return Collections.unmodifiableList(_formatStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStart() {
|
||||||
|
return _start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDuration() {
|
||||||
|
return _duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FormatStat {
|
||||||
|
private String _format;
|
||||||
|
private int _count;
|
||||||
|
private float _percentage;
|
||||||
|
|
||||||
|
public FormatStat(String format, int count, float percentage) {
|
||||||
|
_format = format;
|
||||||
|
_count = count;
|
||||||
|
_percentage = percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return _count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormat() {
|
||||||
|
return _format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPercentage() {
|
||||||
|
return _percentage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.gempukku.lotro.game;
|
||||||
|
|
||||||
|
import com.gempukku.lotro.db.DbAccess;
|
||||||
|
import com.gempukku.lotro.db.GameHistoryDAO;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GetStatsConsole {
|
||||||
|
private static final SimpleDateFormat monthFormat = new SimpleDateFormat("MMM yyyy");
|
||||||
|
private static final DecimalFormat percFormat = new DecimalFormat("#0.0%");
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
DbAccess dbAccess = new DbAccess();
|
||||||
|
GameHistoryDAO gameHistoryDAO = new GameHistoryDAO(dbAccess);
|
||||||
|
GameHistoryService gameHistoryService = new GameHistoryService(gameHistoryDAO);
|
||||||
|
long startTime = gameHistoryService.getOldestGameHistoryEntry();
|
||||||
|
|
||||||
|
createMonthlyStats(startTime, gameHistoryService);
|
||||||
|
// createWeeklyStats(startTime, gameHistoryService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createMonthlyStats(long startTime, GameHistoryService gameHistoryService) {
|
||||||
|
Date startOfMonth = new Date(startTime);
|
||||||
|
startOfMonth.setDate(1);
|
||||||
|
startOfMonth.setHours(0);
|
||||||
|
startOfMonth.setMinutes(0);
|
||||||
|
startOfMonth.setSeconds(0);
|
||||||
|
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
System.out.println("Monthly statistics:");
|
||||||
|
startOfMonth.setTime(startOfMonth.getTime() / 1000L * 1000L);
|
||||||
|
long periodStart = startOfMonth.getTime();
|
||||||
|
while (periodStart < currentTime) {
|
||||||
|
startOfMonth.setMonth(startOfMonth.getMonth() + 1);
|
||||||
|
long periodEnd = startOfMonth.getTime();
|
||||||
|
|
||||||
|
System.out.println(monthFormat.format(new Date(periodStart)) + ":");
|
||||||
|
GameHistoryStatistics historyStatistics = gameHistoryService.getGameHistoryStatistics(periodStart, periodEnd - periodStart);
|
||||||
|
List<GameHistoryStatistics.FormatStat> stats = historyStatistics.getFormatStats();
|
||||||
|
for (GameHistoryStatistics.FormatStat stat : stats) {
|
||||||
|
System.out.println(stat.getFormat() + ": " + stat.getCount() + " (" + percFormat.format(stat.getPercentage()) + ")");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
periodStart = periodEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -122,13 +122,13 @@ public class LotroServer extends AbstractServer {
|
|||||||
return "Game" + gameId;
|
return "Game" + gameId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized String createNewGame(LotroFormat lotroFormat, String tournament, final LotroGameParticipant[] participants, boolean competetive) {
|
public synchronized String createNewGame(LotroFormat lotroFormat, String tournamentName, final LotroGameParticipant[] participants, boolean competetive, boolean tournament) {
|
||||||
if (participants.length < 2)
|
if (participants.length < 2)
|
||||||
throw new IllegalArgumentException("There has to be at least two players");
|
throw new IllegalArgumentException("There has to be at least two players");
|
||||||
final String gameId = String.valueOf(_nextGameId);
|
final String gameId = String.valueOf(_nextGameId);
|
||||||
|
|
||||||
boolean noSpectators = competetive;
|
boolean noSpectators = tournament;
|
||||||
boolean cancellable = !competetive;
|
boolean cancellable = !tournament;
|
||||||
|
|
||||||
if (noSpectators) {
|
if (noSpectators) {
|
||||||
Set<String> allowedUsers = new HashSet<String>();
|
Set<String> allowedUsers = new HashSet<String>();
|
||||||
@@ -169,7 +169,7 @@ public class LotroServer extends AbstractServer {
|
|||||||
|
|
||||||
lotroGameMediator.sendMessageToPlayers("Players in the game are: " + players.toString());
|
lotroGameMediator.sendMessageToPlayers("Players in the game are: " + players.toString());
|
||||||
|
|
||||||
final GameRecorder.GameRecordingInProgress gameRecordingInProgress = _gameRecorder.recordGame(lotroGameMediator, lotroFormat.getName(), tournament, deckNames);
|
final GameRecorder.GameRecordingInProgress gameRecordingInProgress = _gameRecorder.recordGame(lotroGameMediator, lotroFormat.getName(), tournamentName, deckNames);
|
||||||
lotroGameMediator.addGameResultListener(
|
lotroGameMediator.addGameResultListener(
|
||||||
new GameResultListener() {
|
new GameResultListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -390,12 +390,12 @@ public class HallServer extends AbstractServer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
createGame(tableId, participants, listener, awaitingTable.getLotroFormat(), getTournamentName(awaitingTable), league != null);
|
createGame(tableId, participants, listener, awaitingTable.getLotroFormat(), getTournamentName(awaitingTable), league != null, false);
|
||||||
_awaitingTables.remove(tableId);
|
_awaitingTables.remove(tableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createGame(String tableId, LotroGameParticipant[] participants, GameResultListener listener, LotroFormat lotroFormat, String tournamentName, boolean competetive) {
|
private void createGame(String tableId, LotroGameParticipant[] participants, GameResultListener listener, LotroFormat lotroFormat, String tournamentName, boolean competetive, boolean tournament) {
|
||||||
String gameId = _lotroServer.createNewGame(lotroFormat, tournamentName, participants, competetive);
|
String gameId = _lotroServer.createNewGame(lotroFormat, tournamentName, participants, competetive, tournament);
|
||||||
LotroGameMediator lotroGameMediator = _lotroServer.getGameById(gameId);
|
LotroGameMediator lotroGameMediator = _lotroServer.getGameById(gameId);
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
lotroGameMediator.addGameResultListener(listener);
|
lotroGameMediator.addGameResultListener(listener);
|
||||||
@@ -533,7 +533,7 @@ public class HallServer extends AbstractServer {
|
|||||||
public void gameCancelled() {
|
public void gameCancelled() {
|
||||||
createGameInternal(participants);
|
createGameInternal(participants);
|
||||||
}
|
}
|
||||||
}, _formatLibrary.getFormat(_tournament.getFormat()), _tournament.getTournamentName(), true);
|
}, _formatLibrary.getFormat(_tournament.getFormat()), _tournament.getTournamentName(), true, true);
|
||||||
} finally {
|
} finally {
|
||||||
_hallDataAccessLock.writeLock().unlock();
|
_hallDataAccessLock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user