diff --git a/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java b/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java index 113a38a60..84fb8b63a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java @@ -22,6 +22,10 @@ public class AnalysisData { private String top20ActivePlayers; private String recentPlayers; + private int newPlayersMonth; + private int newPlayersWeek; + private int newPlayersDay; + private double gm0Perc; private double gm1Perc; private double gm2Perc; @@ -42,7 +46,7 @@ public class AnalysisData { /** * Class constructor. - * + * * All data has to be set with setters to avoid NPE. */ public AnalysisData() { @@ -71,7 +75,8 @@ public class AnalysisData { } /** - * @param planLiteEnabled true if PlanLite was enabled at the time of Analysis + * @param planLiteEnabled true if PlanLite was enabled at the time of + * Analysis */ public void setPlanLiteEnabled(boolean planLiteEnabled) { this.planLiteEnabled = planLiteEnabled; @@ -79,8 +84,9 @@ public class AnalysisData { /** * Retrieve the PlanLiteAnalyzedData. - * + * * null if planLiteEnabled = false + * * @return Seperate object used to save PlanLiteData */ public PlanLiteAnalyzedData getPlanLiteData() { @@ -89,6 +95,7 @@ public class AnalysisData { /** * Set the PlanLiteAnalyzedData. + * * @param planLiteData Seperate object used to save PlanLiteData */ public void setPlanLiteData(PlanLiteAnalyzedData planLiteData) { @@ -167,9 +174,9 @@ public class AnalysisData { /** * Retrieve the amount of active players. - * + * * Activity is determined by AnalysisUtils.isActive() - * + * * @return Amount of active players */ public int getActive() { @@ -178,9 +185,9 @@ public class AnalysisData { /** * Set the amount of active players. - * + * * Activity is determined by AnalysisUtils.isActive() - * + * * @param active Amount of active players */ public void setActive(int active) { @@ -250,7 +257,7 @@ public class AnalysisData { return gm2Perc; } - /** + /** * @param gm2Perc Percentage of Gamemode usage time as a whole */ public void setGm2Perc(double gm2Perc) { @@ -412,7 +419,28 @@ public class AnalysisData { public void setRecentPlayers(String recentPlayers) { this.recentPlayers = recentPlayers; } - - + public int getNewPlayersMonth() { + return newPlayersMonth; + } + + public void setNewPlayersMonth(int newPlayersMonth) { + this.newPlayersMonth = newPlayersMonth; + } + + public int getNewPlayersWeek() { + return newPlayersWeek; + } + + public void setNewPlayersWeek(int newPlayersWeek) { + this.newPlayersWeek = newPlayersWeek; + } + + public int getNewPlayersDay() { + return newPlayersDay; + } + + public void setNewPlayersDay(int newPlayersDay) { + this.newPlayersDay = newPlayersDay; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java index b8ad2e3db..549da05b4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java @@ -778,17 +778,23 @@ public abstract class SQLDB extends Database { + locationColumnWorld + ") VALUES (?, ?, ?, ?)"); boolean commitRequired = false; - for (Location location : locations) { - saveStatement.setInt(1, userId); - saveStatement.setInt(2, (int) location.getBlockX()); - saveStatement.setInt(3, (int) location.getBlockZ()); - saveStatement.setString(4, location.getWorld().getName()); - saveStatement.addBatch(); - commitRequired = true; - } - saveStatement.executeBatch(); - if (commitRequired) { - connection.commit(); + if (!locations.isEmpty()) { + for (Location location : locations) { + saveStatement.setInt(1, userId); + saveStatement.setInt(2, (int) location.getBlockX()); + saveStatement.setInt(3, (int) location.getBlockZ()); + World world = location.getWorld(); + if (world == null) { + continue; + } + saveStatement.setString(4, world.getName()); + saveStatement.addBatch(); + commitRequired = true; + } + saveStatement.executeBatch(); + if (commitRequired) { + connection.commit(); + } } saveStatement.close(); diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/graphs/PlayerActivityGraphCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/graphs/PlayerActivityGraphCreator.java index e08ec70e4..0281801d5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/graphs/PlayerActivityGraphCreator.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/graphs/PlayerActivityGraphCreator.java @@ -35,7 +35,6 @@ public class PlayerActivityGraphCreator { List xListDate = new ArrayList<>(); List pYList = new ArrayList<>(); - List nYList = new ArrayList<>(); List xDateAxisLabels = new ArrayList<>(); List xDateAxisLabelsLocations = new ArrayList<>(); @@ -46,30 +45,23 @@ public class PlayerActivityGraphCreator { long nowMinusScale = now - scale; int lastPValue = 0; - int lastNValue = 0; int lastSavedPValue = -1; - int lastSavedNValue = -1; long lastSaveI = 0; for (long i = nowMinusScale; i <= now; i += 1000) { if (rawServerData.containsKey(i)) { ServerData serverData = rawServerData.get(i); lastPValue = serverData.getPlayersOnline(); - lastNValue = serverData.getNewPlayers(); } Double scaledDateValue = ((i - nowMinusScale) * 1.0 / scale) * 100; Double scaledPlayerValue = (lastPValue * 1.0 / maxPlayers) * 100; - Double scaledNewPValue = (lastNValue * 1.0 / maxPlayers) * 100; - if (lastSavedPValue != lastPValue || lastSavedNValue != lastNValue || i - lastSaveI > (scale / (long) 50)) { + if (lastSavedPValue != lastPValue || i - lastSaveI > (scale / (long) 50)) { lastSaveI = i; xListDate.add(scaledDateValue); pYList.add((lastSavedPValue * 1.0 / maxPlayers) * 100); - nYList.add((lastSavedNValue * 1.0 / maxPlayers) * 100); lastSavedPValue = lastPValue; - lastSavedNValue = lastNValue; xListDate.add(scaledDateValue); pYList.add(scaledPlayerValue); - nYList.add(scaledNewPValue); } } @@ -90,11 +82,9 @@ public class PlayerActivityGraphCreator { AxisLabels xAxisLabels = AxisLabelsFactory.newAxisLabels(xDateAxisLabels, xDateAxisLabelsLocations); Data xData = Data.newData(xListDate); Data pYData = Data.newData(pYList); - Data nYData = Data.newData(nYList); - XYLine playerLine = Plots.newXYLine(xData, pYData, Color.newColor(Phrase.HCOLOR_ACT_ONL + ""), "Online Players"); - XYLine newPlayerLine = Plots.newXYLine(xData, nYData, Color.newColor(Phrase.HCOLOR_ACT_NEW + ""), "New Players"); - LineChart chart = GCharts.newLineChart(playerLine, newPlayerLine); + XYLine playerLine = Plots.newXYLine(xData, pYData, Color.newColor(Phrase.HCOLOR_ACT_ONL + ""), "Players Online"); + LineChart chart = GCharts.newLineChart(playerLine); chart.addXAxisLabels(xAxisLabels); chart.addTopAxisLabels(AxisLabelsFactory.newAxisLabels("Players", 1)); chart.addYAxisLabels(AxisLabelsFactory.newAxisLabels(yAxisLabels)); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java index 0fec1c241..412181edd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java @@ -9,6 +9,7 @@ import com.djrapitops.plan.data.UserData; import com.djrapitops.plan.data.cache.AnalysisCacheHandler; import com.djrapitops.plan.data.cache.InspectCacheHandler; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -66,8 +67,8 @@ public class Analysis { plugin.log(Phrase.ANALYSIS_FAIL_NO_PLAYERS + ""); return; } - - List uuids = fetchPlayersInDB(offlinePlayers); + + List uuids = fetchPlayersInDB(offlinePlayers); if (uuids.isEmpty()) { plugin.log(Phrase.ANALYSIS_FAIL_NO_DATA + ""); return; @@ -186,7 +187,7 @@ public class Analysis { // Save Dataset to AnalysisData data.setTop20ActivePlayers(AnalysisUtils.createActivePlayersTable(playtimes, 20)); data.setRecentPlayers(AnalysisUtils.createListStringOutOfHashMapLong(latestLogins, 20)); - + addPlanLiteToData(planLiteEnabled, plData, factionMap, townMap, totalVotes, totalMoney, data); data.setTotalPlayTime(totalPlaytime); @@ -194,9 +195,9 @@ public class Analysis { data.setTotalLoginTimes(totalLoginTimes); createActivityVisalization(totalBanned, active, inactive, joinleaver, data); - + data.setOps(ops); - + analyzeAverageAge(ages, data); createGamemodeUsageVisualization(gmZero, gmOne, gmTwo, gmThree, data); createCommandUseTable(data); @@ -292,12 +293,60 @@ public class Analysis { long scaleMonth = (long) 2592000 * (long) 1000; String playerActivityHtmlMonth = AnalysisUtils.createPlayerActivityGraph(rawServerData, scaleMonth); data.setPlayersChartImgHtmlMonth(playerActivityHtmlMonth); + data.setNewPlayersMonth(getHighestNPValueForScale(scaleMonth)); long scaleWeek = 604800 * 1000; String playerActivityHtmlWeek = AnalysisUtils.createPlayerActivityGraph(rawServerData, scaleWeek); data.setPlayersChartImgHtmlWeek(playerActivityHtmlWeek); + data.setNewPlayersWeek(getHighestNPValueForScale(scaleWeek)); long scaleDay = 86400 * 1000; String playerActivityHtmlDay = AnalysisUtils.createPlayerActivityGraph(rawServerData, scaleDay); data.setPlayersChartImgHtmlDay(playerActivityHtmlDay); + data.setNewPlayersDay(getHighestNPValueForScale(scaleDay)); + } + + private int getHighestNPValueForScale(long scale) { + List> sDataForEachDay = sortServerDatasByDay(scale); + int NPTotalInsideScaleTimeFrame = 0; + NPTotalInsideScaleTimeFrame = sDataForEachDay.parallelStream() + .map((serverDataList) -> { + int highestNPValue = 0; + for (ServerData serverData : serverDataList) { + int newPlayers = serverData.getNewPlayers(); + if (newPlayers > highestNPValue) { + highestNPValue = newPlayers; + } + } + return highestNPValue; + }).map((highestNPValue) -> highestNPValue) + .reduce(NPTotalInsideScaleTimeFrame, Integer::sum); + return NPTotalInsideScaleTimeFrame; + } + + private List> sortServerDatasByDay(long scale) { + List> sDataForEachDay = new ArrayList<>(); + Date lastStartOfDay = null; + List keys = new ArrayList<>(); + keys.addAll(rawServerData.keySet()); + Collections.sort(keys); + for (long date : keys) { + Date startOfDate = MiscUtils.getStartOfDate(new Date(date)); + if (lastStartOfDay == null) { + sDataForEachDay.add(new ArrayList<>()); + lastStartOfDay = startOfDate; + } + // If data is older than one month, ignore + if (new Date().getTime() - startOfDate.getTime() > scale) { + continue; + } + if (startOfDate.getTime() != lastStartOfDay.getTime()) { + sDataForEachDay.add(new ArrayList<>()); + } + int lastIndex = sDataForEachDay.size() - 1; + ServerData serverData = rawServerData.get(date); + sDataForEachDay.get(lastIndex).add(serverData); + lastStartOfDay = startOfDate; + } + return sDataForEachDay; } }).runTaskAsynchronously(plugin); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java index bc0b61117..e157166c2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java @@ -142,6 +142,9 @@ public class AnalysisUtils { replaceMap.put("%playerchartmonth%", data.getPlayersChartImgHtmlMonth()); replaceMap.put("%playerchartweek%", data.getPlayersChartImgHtmlWeek()); replaceMap.put("%playerchartday%", data.getPlayersChartImgHtmlDay()); + replaceMap.put("%npday%", data.getNewPlayersDay()+""); + replaceMap.put("%npweek%", data.getNewPlayersWeek()+""); + replaceMap.put("%npmonth%", data.getNewPlayersMonth()+""); replaceMap.put("%top50commands%", data.getTop50CommandsListHtml()); replaceMap.put("%avgage%", (data.getAverageAge() != -1) ? "" + data.getAverageAge() : Phrase.DEM_UNKNOWN + ""); replaceMap.put("%avgplaytime%", FormatUtils.formatTimeAmount("" + data.getAveragePlayTime())); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java index bb9e3e698..c5ddcf683 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java @@ -108,8 +108,13 @@ public class MiscUtils { } public static boolean isOnSameDay(Date first, Date second) { - Date startOfFirst = new Date(first.getTime() - (first.getTime() % 86400000)); - Date startOfSecond = new Date(second.getTime() - (second.getTime() % 86400000)); + Date startOfFirst = getStartOfDate(first); + Date startOfSecond = getStartOfDate(second); return (startOfFirst != startOfSecond); } + + public static Date getStartOfDate(Date date) { + Date startOfDate = new Date(date.getTime() - (date.getTime() % 86400000)); + return startOfDate; + } } diff --git a/Plan/src/main/resources/analysis.html b/Plan/src/main/resources/analysis.html index f857f5acf..a4f80d8ab 100644 --- a/Plan/src/main/resources/analysis.html +++ b/Plan/src/main/resources/analysis.html @@ -95,11 +95,11 @@
-

Player Activity - Last 24h

+

Player Activity | Last 24h - New Players: %npday%

%playerchartday% -

Player Activity - Last 7 days

+

Player Activity | Last 7 days - New Players: %npweek%

%playerchartweek% -

Player Activity - Last 30 days

+

Player Activity | Last 30 days - New Players: %npmonth%

%playerchartmonth%

Most recent logins: %recentlogins%

diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml index 144ec33ed..e3643e75a 100644 --- a/Plan/src/main/resources/plugin.yml +++ b/Plan/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.Plan -version: 2.4.0 +version: 2.4.1 commands: plan: