Adding support for displaying competitive format stats in the server info
This commit is contained in:
@@ -1,21 +1,17 @@
|
||||
package com.gempukku.lotro.async.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.gempukku.lotro.async.HttpProcessingException;
|
||||
import com.gempukku.lotro.async.ResponseWriter;
|
||||
import com.gempukku.lotro.common.JSONDefs;
|
||||
import com.gempukku.lotro.game.GameHistoryService;
|
||||
import com.gempukku.lotro.game.GameHistoryStatistics;
|
||||
import com.gempukku.lotro.game.Player;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
@@ -56,32 +52,14 @@ public class ServerStatsRequestHandler extends LotroServerRequestHandler impleme
|
||||
}
|
||||
long duration = to.getTime() - from;
|
||||
|
||||
int activePlayers = _gameHistoryService.getActivePlayersCount(from, duration);
|
||||
int gamesCount = _gameHistoryService.getGamesPlayedCount(from, duration);
|
||||
var stats = new JSONDefs.PlayHistoryStats();
|
||||
stats.ActivePlayers = _gameHistoryService.getActivePlayersCount(from, duration);
|
||||
stats.GamesCount = _gameHistoryService.getGamesPlayedCount(from, duration);
|
||||
stats.StartDate = format.format(new Date(from));
|
||||
stats.EndDate = format.format(new Date(from + duration - 1));
|
||||
stats.Stats = _gameHistoryService.getGameHistoryStatistics(from, duration);
|
||||
|
||||
GameHistoryStatistics gameHistoryStatistics = _gameHistoryService.getGameHistoryStatistics(from, duration);
|
||||
|
||||
DecimalFormat percFormat = new DecimalFormat("#0.0%");
|
||||
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document doc = documentBuilder.newDocument();
|
||||
Element stats = doc.createElement("stats");
|
||||
stats.setAttribute("activePlayers", String.valueOf(activePlayers));
|
||||
stats.setAttribute("gamesCount", String.valueOf(gamesCount));
|
||||
stats.setAttribute("start", format.format(new Date(from)));
|
||||
stats.setAttribute("end", format.format(new Date(from + duration - 1)));
|
||||
for (GameHistoryStatistics.FormatStat formatStat : gameHistoryStatistics.getFormatStats()) {
|
||||
Element formatStatElem = doc.createElement("formatStat");
|
||||
formatStatElem.setAttribute("format", formatStat.getFormat());
|
||||
formatStatElem.setAttribute("count", String.valueOf(formatStat.getCount()));
|
||||
formatStatElem.setAttribute("perc", percFormat.format(formatStat.getPercentage()));
|
||||
stats.appendChild(formatStatElem);
|
||||
}
|
||||
|
||||
doc.appendChild(stats);
|
||||
|
||||
responseWriter.writeXmlResponse(doc);
|
||||
responseWriter.writeJsonResponse(JSON.toJSONString(stats));
|
||||
} catch (ParseException exp) {
|
||||
logHttpError(_log, 400, request.uri(), exp);
|
||||
throw new HttpProcessingException(400);
|
||||
|
||||
@@ -35,7 +35,36 @@
|
||||
</span>
|
||||
<input class='getStats' type='button' value='Display Stats'>
|
||||
</div>
|
||||
<div id="stats"></div>
|
||||
<div id="stats">
|
||||
<div class='period'>Stats for <span id="startDateSpan"></span> - <span id="endDateSpan"></span> </div>
|
||||
<div class='activePlayers'>Active players: <span id="activePlayersStat"></span></div>
|
||||
<div class='gamesCount'>All games count: <span id="gamesCountStat"></span></div>
|
||||
<table class='tables' id="competitiveStatsTable">
|
||||
<caption>Competitive Games by Format</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Format name</th>
|
||||
<th># of games</th>
|
||||
<th>% of competitive</th>
|
||||
<th>% of total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<br>
|
||||
<table class='tables' id="casualStatsTable">
|
||||
<caption>Casual Games by Format</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Format name</th>
|
||||
<th># of games</th>
|
||||
<th>% of casual</th>
|
||||
<th>% of total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="about" >
|
||||
|
||||
@@ -79,7 +79,7 @@ var GempLotrCommunication = Class.extend({
|
||||
participantId:getUrlParam("participantId") },
|
||||
success:this.deliveryCheck(callback),
|
||||
error:this.errorCheck(errorMap),
|
||||
dataType:"xml"
|
||||
dataType:"json"
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -35,38 +35,66 @@ var StatsUI = Class.extend({
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
getPercentage:function (num1, num2) {
|
||||
return Number(num1 / num2).toLocaleString(undefined, {style: 'percent', minimumFractionDigits:2});
|
||||
},
|
||||
|
||||
loadedStats:function (xml) {
|
||||
loadedStats:function (json) {
|
||||
var that = this;
|
||||
log(xml);
|
||||
var root = xml.documentElement;
|
||||
if (root.tagName == 'stats') {
|
||||
$("#stats").html("");
|
||||
log(json);
|
||||
|
||||
var getPercentage = (num1, num2) => Number(num1 / num2).toLocaleString(undefined, {style: 'percent', minimumFractionDigits:2});
|
||||
|
||||
var stats = root;
|
||||
$("#startDateSpan").html(json["StartDate"]);
|
||||
$("#endDateSpan").html(json["EndDate"]);
|
||||
$("#activePlayersStat").html(json["ActivePlayers"]);
|
||||
$("#gamesCountStat").html(json["GamesCount"]);
|
||||
|
||||
var activePlayers = stats.getAttribute("activePlayers");
|
||||
var gamesCount = stats.getAttribute("gamesCount");
|
||||
var start = stats.getAttribute("start");
|
||||
var end = stats.getAttribute("end");
|
||||
|
||||
$("#stats").append("<div class='period'>Stats for " + start + " - " + end + "</div>");
|
||||
$("#stats").append("<div class='activePlayers'>Active players: " + activePlayers + "</div>");
|
||||
$("#stats").append("<div class='gamesCount'>All games count: " + gamesCount + "</div>");
|
||||
|
||||
var formatStats = stats.getElementsByTagName("formatStat");
|
||||
if (formatStats.length > 0) {
|
||||
$("#stats").append("<div class='tableHeader'>Casual games per format</div>");
|
||||
|
||||
var table = $("<table class='tables'></table>");
|
||||
table.append("<tr><th>Format name</th><th># of games</th><th>% of casual</th></tr>");
|
||||
for (var i = 0; i < formatStats.length; i++) {
|
||||
var formatStat = formatStats[i];
|
||||
table.append("<tr><td>" + formatStat.getAttribute("format") + "</td><td>" + formatStat.getAttribute("count") + "</td><td>" + formatStat.getAttribute("perc") + "</td></tr>");
|
||||
var formatStats = json["Stats"];
|
||||
if (formatStats.length > 0) {
|
||||
|
||||
var casualStats = $("#casualStatsTable");
|
||||
var compStats = $("#competitiveStatsTable");
|
||||
$("#casualStatsTable > tbody").empty();
|
||||
$("#competitiveStatsTable > tbody").empty();
|
||||
|
||||
var casuals = 0;
|
||||
var comps = 0;
|
||||
var total = 0;
|
||||
|
||||
json["Stats"].forEach(item => {
|
||||
if(item.Casual) {
|
||||
casuals += item.Count;
|
||||
}
|
||||
else {
|
||||
comps += item.Count;
|
||||
}
|
||||
total += item.Count;
|
||||
});
|
||||
|
||||
json["Stats"].forEach(item => {
|
||||
|
||||
var test = getPercentage(item.Count, total);
|
||||
|
||||
if(item.Casual) {
|
||||
casualStats.append("<tr>"
|
||||
+ "<td>" + item.Format + "</td>"
|
||||
+ "<td>" + item.Count + "</td>"
|
||||
+ "<td>" + getPercentage(item.Count, casuals) + "</td>"
|
||||
+ "<td>" + getPercentage(item.Count, total) + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
else {
|
||||
compStats.append("<tr>"
|
||||
+ "<td>" + item.Format + "</td>"
|
||||
+ "<td>" + item.Count + "</td>"
|
||||
+ "<td>" + getPercentage(item.Count, comps) + "</td>"
|
||||
+ "<td>" + getPercentage(item.Count, total) + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
});
|
||||
|
||||
$("#stats").append(table);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -65,4 +65,10 @@ public class DBDefs {
|
||||
public int id;
|
||||
public String name;
|
||||
}
|
||||
|
||||
public static class FormatStats {
|
||||
public String Format;
|
||||
public int Count;
|
||||
public boolean Casual;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,4 +73,12 @@ public class JSONDefs {
|
||||
public Map<String, String> ErrataIDs;
|
||||
}
|
||||
|
||||
public static class PlayHistoryStats {
|
||||
public List<DBDefs.FormatStats> Stats;
|
||||
public int ActivePlayers;
|
||||
public int GamesCount;
|
||||
public String StartDate;
|
||||
public String EndDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -174,6 +174,34 @@ public class DbGameHistoryDAO implements GameHistoryDAO {
|
||||
}
|
||||
}
|
||||
|
||||
public List<DBDefs.FormatStats> GetAllGameFormatData(long from, long duration) {
|
||||
try {
|
||||
Sql2o db = new Sql2o(_dbAccess.getDataSource());
|
||||
|
||||
try (org.sql2o.Connection conn = db.open()) {
|
||||
String sql = """
|
||||
SELECT
|
||||
COUNT(*) AS Count
|
||||
,format_name AS Format
|
||||
,CASE WHEN tournament IS NULL OR tournament LIKE 'Casual %' THEN 1 ELSE 0 END AS Casual
|
||||
FROM game_history
|
||||
WHERE end_date >= :from
|
||||
AND end_date < :to
|
||||
GROUP BY format_name, CASE WHEN tournament IS NULL OR tournament LIKE 'Casual %' THEN 1 ELSE 0 END
|
||||
""";
|
||||
List<DBDefs.FormatStats> result = conn.createQuery(sql)
|
||||
.addParameter("from", from)
|
||||
.addParameter("to", from + duration)
|
||||
.executeAndFetch(DBDefs.FormatStats.class);
|
||||
|
||||
return result;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Unable to retrieve format stats", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<PlayerStatistic> getCasualPlayerStatistics(Player player) {
|
||||
try {
|
||||
try (Connection connection = _dbAccess.getDataSource().getConnection()) {
|
||||
|
||||
@@ -22,6 +22,8 @@ public interface GameHistoryDAO {
|
||||
|
||||
public Map<String, Integer> getCasualGamesPlayedPerFormat(long from, long duration);
|
||||
|
||||
public List<DBDefs.FormatStats> GetAllGameFormatData(long from, long duration);
|
||||
|
||||
public List<PlayerStatistic> getCasualPlayerStatistics(Player player);
|
||||
|
||||
public List<PlayerStatistic> getCompetitivePlayerStatistics(Player player);
|
||||
|
||||
@@ -56,10 +56,8 @@ public class GameHistoryService {
|
||||
return _gameHistoryDAO.getGamesPlayedCount(from, duration);
|
||||
}
|
||||
|
||||
public GameHistoryStatistics getGameHistoryStatistics(long from, long duration) {
|
||||
GameHistoryStatistics stats = new GameHistoryStatistics(from, duration);
|
||||
stats.init(_gameHistoryDAO);
|
||||
return stats;
|
||||
public List<DBDefs.FormatStats> getGameHistoryStatistics(long from, long duration) {
|
||||
return _gameHistoryDAO.GetAllGameFormatData(from, duration);
|
||||
}
|
||||
|
||||
public List<PlayerStatistic> getCasualPlayerStatistics(Player player) {
|
||||
|
||||
Reference in New Issue
Block a user