Merge branch '4.0.0-BungeeCord-Support' of https://github.com/Rsl1122/Plan-PlayerAnalytics

This commit is contained in:
Fuzzlemann 2017-08-25 12:21:44 +02:00
commit 43784f92d3
51 changed files with 602 additions and 746 deletions

View File

@ -44,13 +44,7 @@ import main.java.com.djrapitops.plan.systems.processing.Processor;
import main.java.com.djrapitops.plan.systems.queue.ProcessingQueue;
import main.java.com.djrapitops.plan.systems.tasks.PeriodicDBCommitTask;
import main.java.com.djrapitops.plan.systems.tasks.TPSCountTimer;
import main.java.com.djrapitops.plan.systems.webapi.WebAPIManager;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.AnalyticsWebAPI;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.AnalyzeWebAPI;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.ConfigureWebAPI;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.InspectWebAPI;
import main.java.com.djrapitops.plan.systems.webserver.WebServer;
import main.java.com.djrapitops.plan.ui.webserver.api.bukkit.InspectionWebAPI;
import main.java.com.djrapitops.plan.utilities.Benchmark;
import main.java.com.djrapitops.plan.utilities.Check;
import org.apache.logging.log4j.LogManager;
@ -79,7 +73,7 @@ public class Plan extends BukkitPlugin<Plan> {
private Database db;
private Set<Database> databases;
private WebServer uiServer;
private WebServer webServer;
private InformationManager infoManager;
private ServerInfoManager serverInfoManager;
@ -160,16 +154,16 @@ public class Plan extends BukkitPlugin<Plan> {
Benchmark.stop("Enable", "Init Database");
Benchmark.start("WebServer Initialization");
uiServer = new WebServer(this);
registerWebAPIs(); // TODO Move to WebServer class
uiServer.initServer();
webServer = new WebServer(this);
webServer.initServer();
if (!uiServer.isEnabled()) {
if (!webServer.isEnabled()) {
Log.error("WebServer was not successfully initialized.");
}
serverInfoManager = new ServerInfoManager(this);
infoManager = new InformationManager(this);
webServer.setInfoManager(infoManager);
registerListeners();
registerTasks();
@ -272,8 +266,8 @@ public class Plan extends BukkitPlugin<Plan> {
PageCache.clearCache();
// Stop the UI Server
if (uiServer != null) {
uiServer.stop();
if (webServer != null) {
webServer.stop();
}
getServer().getScheduler().cancelTasks(this);
@ -302,14 +296,6 @@ public class Plan extends BukkitPlugin<Plan> {
Benchmark.stop("Enable", "Register Listeners");
}
private void registerWebAPIs() {
WebAPIManager.registerNewAPI("analytics", new AnalyticsWebAPI());
WebAPIManager.registerNewAPI("analyze", new AnalyzeWebAPI());
WebAPIManager.registerNewAPI("configure", new ConfigureWebAPI());
WebAPIManager.registerNewAPI("inspection", new InspectionWebAPI());
WebAPIManager.registerNewAPI("inspect", new InspectWebAPI());
}
/**
* Initializes the database according to settings in the config.
* <p>
@ -371,8 +357,8 @@ public class Plan extends BukkitPlugin<Plan> {
*
* @return the Webserver
*/
public WebServer getUiServer() {
return uiServer;
public WebServer getWebServer() {
return webServer;
}
/**

View File

@ -76,24 +76,6 @@ public enum Settings {
THEME_GRAPH_RAM("Theme.Graphs.RAM"),
THEME_GRAPH_CHUNKS("Theme.Graphs.Chunks"),
THEME_GRAPH_ENTITIES("Theme.Graphs.Entities"),
//
@Deprecated HCOLOR_MAIN("Customization.Colors.HTML.UI.Main"),
@Deprecated HCOLOR_MAIN_DARK("Customization.Colors.HTML.UI.MainDark"),
@Deprecated HCOLOR_SEC("Customization.Colors.HTML.UI.Secondary"),
@Deprecated HCOLOR_TER("Customization.Colors.HTML.UI.Tertiary"),
@Deprecated HCOLOR_TER_DARK("Customization.Colors.HTML.UI.TertiaryDark"),
@Deprecated HCOLOR_TPS_HIGH("Customization.Colors.HTML.TPSGraph.TPSHighCol"),
@Deprecated HCOLOR_TPS_MED("Customization.Colors.HTML.TPSGraph.TPSMediumCol"),
@Deprecated HCOLOR_TPS_LOW("Customization.Colors.HTML.TPSGraph.TPSLowCol"),
@Deprecated HCOLOR_ACT_ONL("Customization.Colors.HTML.ActivityGraph.OnlinePlayers"),
@Deprecated HCOLOR_ACTP_ACT("Customization.Colors.HTML.ActivityPie.Active"),
@Deprecated HCOLOR_ACTP_BAN("Customization.Colors.HTML.ActivityPie.Banned"),
@Deprecated HCOLOR_ACTP_INA("Customization.Colors.HTML.ActivityPie.Inactive"),
@Deprecated HCOLOR_ACTP_JON("Customization.Colors.HTML.ActivityPie.JoinedOnce"),
@Deprecated HCOLOR_GMP_0("Customization.Colors.HTML.GamemodePie.Survival"),
@Deprecated HCOLOR_GMP_1("Customization.Colors.HTML.GamemodePie.Creative"),
@Deprecated HCOLOR_GMP_2("Customization.Colors.HTML.GamemodePie.Adventure"),
@Deprecated HCOLOR_GMP_3("Customization.Colors.HTML.GamemodePie.Spectator"),
// StringList
HIDE_FACTIONS("Plugins.Factions.HideFactions"),
HIDE_TOWNS("Plugins.Towny.HideTowns");

View File

@ -46,7 +46,7 @@ public class PlanCommand extends TreeCommand<Plan> {
commands.add(new ManageCommand(plugin));
commands.add(new StatusCommand<>(plugin, Permissions.MANAGE.getPermission()));
if (plugin.getUiServer().isEnabled()) {
if (plugin.getWebServer().isEnabled()) {
commands.add(new ListCommand());
RegisterCommand registerCommand = new RegisterCommand(plugin);
commands.add(registerCommand);

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.CommandUtils;
import com.djrapitops.plugin.command.ISender;
@ -11,9 +12,16 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.ConditionUtils;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.systems.info.InformationManager;
import main.java.com.djrapitops.plan.utilities.Check;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import org.bukkit.ChatColor;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
/**
* This subcommand is used to run the analysis and access the /server link.
*
@ -23,6 +31,7 @@ import org.bukkit.ChatColor;
public class AnalyzeCommand extends SubCommand {
private final Plan plugin;
private final InformationManager infoManager;
/**
* Subcommand Constructor.
@ -35,6 +44,7 @@ public class AnalyzeCommand extends SubCommand {
Permissions.ANALYZE.getPermission(),
Locale.get(Msg.CMD_USG_ANALYZE).parse());
this.plugin = plugin;
infoManager = plugin.getInfoManager();
}
@Override
@ -48,14 +58,17 @@ public class AnalyzeCommand extends SubCommand {
return true;
}
// TODO Check if analysis is enabled.
// if (!Check.isTrue(analysisCache.isAnalysisEnabled(), Locale.get(Msg.CMD_INFO_ANALYSIS_TEMP_DISABLE).toString(), sender)
// && !analysisCache.isCached()) {
// return true;
// }
Optional<Long> analysisRefreshDate = infoManager.getAnalysisRefreshDate();
boolean forcedRefresh = args.length >= 1 && "-r".equals(args[0]);
boolean refresh = !analysisRefreshDate.isPresent()
|| analysisRefreshDate.get() < MiscUtils.getTime() - TimeAmount.MINUTE.ms()
|| forcedRefresh;
if (refresh) {
updateCache(sender, refresh);
}
sender.sendMessage(Locale.get(Msg.CMD_INFO_FETCH_DATA).toString());
if (plugin.getUiServer().isAuthRequired() && CommandUtils.isPlayer(sender)) {
if (plugin.getWebServer().isAuthRequired() && CommandUtils.isPlayer(sender)) {
plugin.getRunnableFactory().createNew(new AbsRunnable("WebUser exist check task") {
@Override
public void run() {
@ -72,21 +85,37 @@ public class AnalyzeCommand extends SubCommand {
}
}).runTaskAsynchronously();
}
updateCache(sender);
return true;
}
private void updateCache(ISender sender) {
private void updateCache(ISender sender, boolean refresh) {
// TODO
// if (!analysisCache.isCached() || MiscUtils.getTime() - analysisCache.getData().getRefreshDate() > TimeAmount.MINUTE.ms()) {
// int bootAnID = plugin.getBootAnalysisTaskID();
// if (bootAnID != -1) {
// plugin.getServer().getScheduler().cancelTask(bootAnID);
// }
// analysisCache.addNotification(sender);
// analysisCache.updateCache();
// } else {
// analysisCache.sendAnalysisMessage(sender);
// }
if (refresh) {
int bootAnID = plugin.getBootAnalysisTaskID();
if (bootAnID != -1) {
plugin.getServer().getScheduler().cancelTask(bootAnID);
}
infoManager.addAnalysisNotification(sender);
infoManager.refreshAnalysis();
} else {
sendAnalysisMessage(Collections.singletonList(sender));
}
}
public static void sendAnalysisMessage(Collection<ISender> senders) {
for (ISender sender : senders) {
sender.sendMessage(Locale.get(Msg.CMD_HEADER_ANALYZE).toString());
// Link
String url = HtmlUtils.getServerAnalysisUrlWithProtocol();
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
}
}
}

View File

@ -81,7 +81,7 @@ public class InspectCommand extends SubCommand {
return;
}
sender.sendMessage(Locale.get(Msg.CMD_INFO_FETCH_DATA).toString());
if (CommandUtils.isPlayer(sender) && plugin.getUiServer().isAuthRequired()) {
if (CommandUtils.isPlayer(sender) && plugin.getWebServer().isAuthRequired()) {
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
if (!senderHasWebUser) {
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");

View File

@ -30,7 +30,6 @@ public class AnalysisData extends RawData {
private final ActivityPart activityPart;
private final CommandUsagePart commandUsagePart;
private final GamemodePart gamemodePart;
private final GeolocationPart geolocationPart;
private final JoinInfoPart joinInfoPart;
private final KillPart killPart;
@ -51,7 +50,6 @@ public class AnalysisData extends RawData {
playerCountPart = new PlayerCountPart();
playtimePart = new PlaytimePart();
killPart = new KillPart();
gamemodePart = new GamemodePart();
tpsPart = new TPSPart(tpsData);
activityPart = new ActivityPart(joinInfoPart, tpsPart);
worldPart = new WorldPart();
@ -65,10 +63,6 @@ public class AnalysisData extends RawData {
return commandUsagePart;
}
public GamemodePart getGamemodePart() {
return gamemodePart;
}
public GeolocationPart getGeolocationPart() {
return geolocationPart;
}
@ -98,9 +92,9 @@ public class AnalysisData extends RawData {
}
public List<RawData> getAllParts() {
return Arrays.asList(activityPart, commandUsagePart, gamemodePart,
geolocationPart, joinInfoPart, killPart,
playerCountPart, playtimePart, tpsPart, worldPart);
return Arrays.asList(activityPart, commandUsagePart, geolocationPart,
joinInfoPart, killPart, playerCountPart, playtimePart, tpsPart,
worldPart);
}
public String getPlanVersion() {

View File

@ -26,7 +26,7 @@ import java.util.List;
*/
public class Session {
private Long sessionID;
private Integer sessionID;
private WorldTimes worldTimes;
private final long sessionStart;
private long sessionEnd;
@ -54,7 +54,7 @@ public class Session {
* @param sessionStart Epoch millisecond the session was started.
* @param sessionEnd Epoch millisecond the session ended.
*/
public Session(long id, long sessionStart, long sessionEnd, int mobKills, int deaths) {
public Session(int id, long sessionStart, long sessionEnd, int mobKills, int deaths) {
this.sessionID = id;
this.sessionStart = sessionStart;
this.sessionEnd = sessionEnd;
@ -195,11 +195,11 @@ public class Session {
* @return ID if present.
* @throws NullPointerException if Session was not fetched from DB. Check using {@code isFetchedFromDB}
*/
public long getSessionID() {
public int getSessionID() {
return sessionID;
}
public void setSessionID(long sessionID) {
public void setSessionID(int sessionID) {
this.sessionID = sessionID;
}
}

View File

@ -107,6 +107,10 @@ public class ActivityPart extends RawData {
addValue("banned", counts[3]);
}
public void addBans(Collection<UUID> uuids) {
bans.addAll(uuids);
}
public void addBan(UUID uuid) {
Verify.nullCheck(uuid);
bans.add(uuid);

View File

@ -1,113 +0,0 @@
package main.java.com.djrapitops.plan.data.analysis;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
/**
* Part responsible for all Gamemode usage related analysis.
* <p>
* Gamemode Piechart, Percentages and Totals.
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: gmtotal, gm0col-gm3col, gmcolors, gmlabels,
* gm0-gm3, gmdata, gm0total-gm3total
*
* @author Rsl1122
* @since 3.5.2
*/
@Deprecated
public class GamemodePart extends RawData {
private long survivalTime;
private long creativeTime;
private long adventureTime;
private long spectatorTime;
public GamemodePart() {
survivalTime = 0;
creativeTime = 0;
adventureTime = 0;
spectatorTime = 0;
}
@Override
public void analyse() {
gamemodePiechart();
}
private void gamemodePiechart() {
long totalTime = survivalTime + creativeTime + adventureTime + spectatorTime;
String gmColors = HtmlUtils.separateWithQuotes(
"#555", "#555", "#555", "#555" // TODO Write Colors (enum) variables for GameMode colors.
);
addValue("gmColors", gmColors);
}
/**
* Adds time to a gamemode.
*
* @param gm Name of Gamemode
* @param amount milliseconds to add
* @throws IllegalArgumentException if gm is null
*/
public void addTo(String gm, long amount) {
Verify.nullCheck(gm);
switch (gm) {
case "SURVIVAL":
addToSurvival(amount);
break;
case "CREATIVE":
addToCreative(amount);
break;
case "ADVENTURE":
addToAdventure(amount);
break;
case "SPECTATOR":
addToSpectator(amount);
break;
default:
break;
}
}
public void addToSurvival(long amount) {
if (amount > 0) {
survivalTime += amount;
}
}
public void addToCreative(long amount) {
if (amount > 0) {
creativeTime += amount;
}
}
public void addToAdventure(long amount) {
if (amount > 0) {
adventureTime += amount;
}
}
public void addToSpectator(long amount) {
if (amount > 0) {
spectatorTime += amount;
}
}
public long getSurvivalTime() {
return survivalTime;
}
public long getCreativeTime() {
return creativeTime;
}
public long getAdventureTime() {
return adventureTime;
}
public long getSpectatorTime() {
return spectatorTime;
}
}

View File

@ -3,7 +3,11 @@ package main.java.com.djrapitops.plan.data.analysis;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldMapCreator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Part responsible for all Geolocation related analysis.
@ -18,12 +22,14 @@ import java.util.Map;
*/
public class GeolocationPart extends RawData {
private final Map<UUID, String> mostCommonGeolocations;
private final Map<String, String> geoCodes;
private final Map<String, Integer> geoCodeCounts;
public GeolocationPart() {
geoCodes = new HashMap<>();
geoCodeCounts = new HashMap<>();
mostCommonGeolocations = new HashMap<>();
String[] countries = new String[]{"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas, The", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cabo Verde", "Cambodia", "Cameroon", "Canada", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Colombia", "Comoros", "Congo, Democratic Republic of the", "Congo, Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", "Curacao", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Islas Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "Gabon", "Gambia, The", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea-Bissau", "Guinea", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, North", "Korea, South", "Kosovo", "Kuwait", "Kyrgyzstan", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia, Federated States of", "Moldova", "Monaco", "Mongolia", "Montenegro", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "New Caledonia", "New Zealand", "Nicaragua", "Nigeria", "Niger", "Niue", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Puerto Rico", "Qatar", "Romania", "Russia", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Sint Maarten", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Sudan", "Spain", "Sri Lanka", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Vietnam", "Virgin Islands", "West Bank", "Yemen", "Zambia", "Zimbabwe"};
String[] codes = new String[]{"AFG", "ALB", "DZA", "ASM", "AND", "AGO", "AIA", "ATG", "ARG", "ARM", "ABW", "AUS", "AUT", "AZE", "BHM", "BHR", "BGD", "BRB", "BLR", "BEL", "BLZ", "BEN", "BMU", "BTN", "BOL", "BIH", "BWA", "BRA", "VGB", "BRN", "BGR", "BFA", "MMR", "BDI", "CPV", "KHM", "CMR", "CAN", "CYM", "CAF", "TCD", "CHL", "CHN", "COL", "COM", "COD", "COG", "COK", "CRI", "CIV", "HRV", "CUB", "CUW", "CYP", "CZE", "DNK", "DJI", "DMA", "DOM", "ECU", "EGY", "SLV", "GNQ", "ERI", "EST", "ETH", "FLK", "FRO", "FJI", "FIN", "FRA", "PYF", "GAB", "GMB", "GEO", "DEU", "GHA", "GIB", "GRC", "GRL", "GRD", "GUM", "GTM", "GGY", "GNB", "GIN", "GUY", "HTI", "HND", "HKG", "HUN", "ISL", "IND", "IDN", "IRN", "IRQ", "IRL", "IMN", "ISR", "ITA", "JAM", "JPN", "JEY", "JOR", "KAZ", "KEN", "KIR", "KOR", "PRK", "KSV", "KWT", "KGZ", "LAO", "LVA", "LBN", "LSO", "LBR", "LBY", "LIE", "LTU", "LUX", "MAC", "MKD", "MDG", "MWI", "MYS", "MDV", "MLI", "MLT", "MHL", "MRT", "MUS", "MEX", "FSM", "MDA", "MCO", "MNG", "MNE", "MAR", "MOZ", "NAM", "NPL", "NLD", "NCL", "NZL", "NIC", "NGA", "NER", "NIU", "MNP", "NOR", "OMN", "PAK", "PLW", "PAN", "PNG", "PRY", "PER", "PHL", "POL", "PRT", "PRI", "QAT", "ROU", "RUS", "RWA", "KNA", "LCA", "MAF", "SPM", "VCT", "WSM", "SMR", "STP", "SAU", "SEN", "SRB", "SYC", "SLE", "SGP", "SXM", "SVK", "SVN", "SLB", "SOM", "ZAF", "SSD", "ESP", "LKA", "SDN", "SUR", "SWZ", "SWE", "CHE", "SYR", "TWN", "TJK", "TZA", "THA", "TLS", "TGO", "TON", "TTO", "TUN", "TUR", "TKM", "TUV", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VUT", "VEN", "VNM", "VGB", "WBG", "YEM", "ZMB", "ZWE"};
@ -47,4 +53,31 @@ public class GeolocationPart extends RawData {
geoCodeCounts.computeIfPresent(countryCode, (computedCountry, amount) -> amount + 1);
}
}
public void addGeoLocations(Map<UUID, List<String>> geolocations) {
for (Map.Entry<UUID, List<String>> entry : geolocations.entrySet()) {
String mostCommon = getMostCommon(entry.getValue());
mostCommonGeolocations.put(entry.getKey(), mostCommon);
addGeolocation(mostCommon);
}
}
private String getMostCommon(List<String> geoLocs) {
Map<String, Long> occurrences =
geoLocs.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
String mostCommon = "Not Known";
long count = -1;
for (Map.Entry<String, Long> entry : occurrences.entrySet()) {
Long value = entry.getValue();
if (value > count) {
mostCommon = entry.getKey();
count = value;
}
}
return mostCommon;
}
public Map<UUID, String> getMostCommonGeoLocations() {
return mostCommonGeolocations;
}
}

View File

@ -31,18 +31,21 @@ import java.util.stream.Collectors;
* ${playersNewAverageWeek} - (Number)
* ${playersNewAverageMonth} - (Number)
* //TODO ${tableBodySessions}, ${sessionCount}, ${lastPeakTime}, ${playersLastPeak}, ${bestPeakTime}, ${playersBestPeak}
*
* @author Rsl1122
* @since 3.5.2
*/
public class JoinInfoPart extends RawData {
private final Map<UUID, Session> activeSessions;
private final Map<UUID, List<Session>> sessions;
private final List<Long> registered;
private final Map<UUID, Long> registered;
private long loginTimes;
public JoinInfoPart() {
activeSessions = new HashMap<>();
sessions = new HashMap<>();
registered = new ArrayList<>();
registered = new HashMap<>();
loginTimes = 0;
}
@ -77,18 +80,19 @@ public class JoinInfoPart extends RawData {
private void newPlayers() {
long now = MiscUtils.getTime();
long newDay = AnalysisUtils.getNewPlayers(registered, TimeAmount.DAY.ms(), now);
long newWeek = AnalysisUtils.getNewPlayers(registered, TimeAmount.WEEK.ms(), now);
long newMonth = AnalysisUtils.getNewPlayers(registered, TimeAmount.MONTH.ms(), now);
List<Long> registeredList = getRegisteredList();
long newDay = AnalysisUtils.getNewPlayers(registeredList, TimeAmount.DAY.ms(), now);
long newWeek = AnalysisUtils.getNewPlayers(registeredList, TimeAmount.WEEK.ms(), now);
long newMonth = AnalysisUtils.getNewPlayers(registeredList, TimeAmount.MONTH.ms(), now);
addValue("playersNewDay", newDay);
addValue("playersNewWeek", newWeek);
addValue("playersNewMonth", newMonth);
long newPerDay = AnalysisUtils.getNewUsersPerDay(registered, -1);
long newPerDayDay = AnalysisUtils.getNewUsersPerDay(registered, TimeAmount.DAY.ms());
long newPerDayWeek = AnalysisUtils.getNewUsersPerDay(registered, TimeAmount.WEEK.ms());
long newPerDayMonth = AnalysisUtils.getNewUsersPerDay(registered, TimeAmount.MONTH.ms());
long newPerDay = AnalysisUtils.getNewUsersPerDay(registeredList, -1);
long newPerDayDay = AnalysisUtils.getNewUsersPerDay(registeredList, TimeAmount.DAY.ms());
long newPerDayWeek = AnalysisUtils.getNewUsersPerDay(registeredList, TimeAmount.WEEK.ms());
long newPerDayMonth = AnalysisUtils.getNewUsersPerDay(registeredList, TimeAmount.MONTH.ms());
addValue("playersNewAverage", newPerDay);
addValue("playersNewAverageDay", newPerDayDay);
@ -116,17 +120,34 @@ public class JoinInfoPart extends RawData {
return MiscUtils.flatMap(sessions.values());
}
public void addRegistered(long registerDate) {
registered.add(registerDate);
public void addRegistered(UUID uuid, long registerDate) {
registered.put(uuid, registerDate);
}
public List<Long> getRegistered() {
public void addRegistered(Map<UUID, Long> registerDates) {
registered.putAll(registerDates);
}
public Map<UUID, Long> getRegistered() {
return registered;
}
public List<Long> getRegisteredList() {
return new ArrayList<>(registered.values());
}
public void addSessions(Map<UUID, List<Session>> sessions) {
Verify.nullCheck(sessions);
this.sessions.putAll(sessions);
}
public void addSessions(UUID uuid, List<Session> sessions) {
Verify.nullCheck(uuid);
Verify.nullCheck(sessions);
this.sessions.put(uuid, sessions.stream().distinct().collect(Collectors.toList()));
}
public void addActiveSessions(Map<UUID, Session> activeSessions) {
this.activeSessions.putAll(activeSessions);
}
}

View File

@ -1,14 +1,5 @@
package main.java.com.djrapitops.plan.data.analysis;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.data.PlayerKill;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Part responsible for all Death related analysis.
* <p>
@ -24,12 +15,12 @@ import java.util.UUID;
*/
public class KillPart extends RawData {
private final Map<UUID, List<PlayerKill>> playerKills;
private long playerKills;
private long mobKills;
private long deaths;
public KillPart() {
playerKills = new HashMap<>();
playerKills = 0;
mobKills = 0;
deaths = 0;
}
@ -38,20 +29,17 @@ public class KillPart extends RawData {
public void analyse() {
addValue("deathCount", deaths);
addValue("mobKillCount", mobKills);
int playerKillAmount = getAllPlayerKills().size();
addValue("killCount", playerKillAmount);
addValue("killCount", playerKills);
}
/**
* Adds kills to the dataset.
*
* @param uuid Player whose kills are being added
* @param kills all kills of a player
* @param amount amount of kills
* @throws IllegalArgumentException if kills is null
*/
public void addKills(UUID uuid, List<PlayerKill> kills) {
Verify.nullCheck(kills);
playerKills.put(uuid, kills);
public void addKills(long amount) {
playerKills += amount;
}
public void addMobKills(long amount) {
@ -62,14 +50,10 @@ public class KillPart extends RawData {
deaths += amount;
}
public Map<UUID, List<PlayerKill>> getPlayerKills() {
public long getPlayerKills() {
return playerKills;
}
public List<PlayerKill> getAllPlayerKills() {
return MiscUtils.flatMap(playerKills.values());
}
public long getMobKills() {
return mobKills;
}

View File

@ -44,6 +44,11 @@ public class PlayerCountPart extends RawData {
this.uuids.addAll(uuids);
}
public void addOPs(Collection<UUID> uuids) {
Verify.nullCheck(uuids);
this.ops.addAll(uuids);
}
public void addOP(UUID uuid) {
Verify.nullCheck(uuid);
ops.add(uuid);

View File

@ -16,6 +16,9 @@ import main.java.com.djrapitops.plan.utilities.FormatUtils;
public class PlaytimePart extends RawData {
private long totalPlaytime;
private long playtime30d;
private long playtime7d;
private long playtime24h;
public PlaytimePart() {
totalPlaytime = 0;
@ -24,9 +27,28 @@ public class PlaytimePart extends RawData {
@Override
public void analyse() {
addValue("playtimeTotal", FormatUtils.formatTimeAmount(totalPlaytime));
addValue("playtimeMonth", FormatUtils.formatTimeAmount(playtime30d));
addValue("playtimeWeek", FormatUtils.formatTimeAmount(playtime7d));
addValue("playtimeDay", FormatUtils.formatTimeAmount(playtime24h));
}
public void addToPlaytime(long amount) {
totalPlaytime += amount;
}
public void setTotalPlaytime(long totalPlaytime) {
this.totalPlaytime = totalPlaytime;
}
public void setPlaytime30d(long playtime30d) {
this.playtime30d = playtime30d;
}
public void setPlaytime7d(long playtime7d) {
this.playtime7d = playtime7d;
}
public void setPlaytime24h(long playtime24h) {
this.playtime24h = playtime24h;
}
}

View File

@ -1,9 +1,10 @@
package main.java.com.djrapitops.plan.data.analysis;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import java.util.HashMap;
import java.util.Map;
/**
* Part responsible for all World Playtime related analysis.
@ -21,21 +22,23 @@ import java.util.Map;
*/
public class WorldPart extends RawData {
private final Map<String, Long> worldTimes;
private WorldTimes worldTimes;
public WorldPart() {
worldTimes = new HashMap<>();
worldTimes = new WorldTimes(new HashMap<>());
}
@Override
protected void analyse() {
// TODO WorldTimes t = new WorldTimes(worldTimes);
// addValue("worldTotal", FormatUtils.formatTimeAmount(t.getTotal()));
addValue("worldTotal", FormatUtils.formatTimeAmount(worldTimes.getTotal()));
addValue("worldSeries", WorldPieCreator.createSeriesData(worldTimes));
}
public void addToWorld(String worldName, long playTime) {
Long value = worldTimes.getOrDefault(worldName, 0L);
worldTimes.put(worldName, value + playTime);
public void setWorldTimes(WorldTimes worldTimes) {
this.worldTimes = worldTimes;
}
public WorldTimes getWorldTimes() {
return worldTimes;
}
}

View File

@ -1,132 +0,0 @@
package main.java.com.djrapitops.plan.data.cache;
import com.djrapitops.plugin.command.CommandUtils;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.utilities.player.IPlayer;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.utilities.analysis.Analysis;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
/**
* This class is used to store the most recent AnalysisData object and to run
* Analysis.
*
* @author Rsl1122
* @since 2.0.0
*/
@Deprecated
public class AnalysisCacheHandler {
private final Plan plugin;
private final Analysis analysis;
private AnalysisData cache;
private boolean analysisEnabled;
private final Set<UUID> notifyWhenCached;
/**
* Class Constructor.
* <p>
* Initializes Analysis
*
* @param plugin Current instance of Plan
*/
public AnalysisCacheHandler(Plan plugin) {
this.plugin = plugin;
analysis = new Analysis(plugin);
analysisEnabled = true;
notifyWhenCached = new HashSet<>();
}
/**
* Runs analysis, cache method is called after analysis is complete.
*/
public void updateCache() {
analysis.runAnalysis(this);
}
/**
* Saves the new analysis data to cache.
*
* @param data AnalysisData generated by Analysis.analyze
*/
public void cache(AnalysisData data) {
cache = data;
for (UUID uuid : notifyWhenCached) {
Optional<IPlayer> player = plugin.fetch().getPlayer(uuid);
player.ifPresent(this::sendAnalysisMessage);
}
notifyWhenCached.clear();
}
public void sendAnalysisMessage(ISender sender) {
sender.sendMessage(Locale.get(Msg.CMD_HEADER_ANALYZE).toString());
// Link
String url = HtmlUtils.getServerAnalysisUrlWithProtocol();
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
}
/**
* Returns the cached AnalysisData.
*
* @return null if not cached
*/
public AnalysisData getData() {
return cache;
}
/**
* Check if the AnalysisData has been cached.
*
* @return true if there is data in the cache.
*/
public boolean isCached() {
return cache != null;
}
/**
* @return if currently an analysis is being run
*/
public boolean isAnalysisBeingRun() {
return analysis.isAnalysisBeingRun();
}
public boolean isAnalysisEnabled() {
return analysisEnabled;
}
public void disableAnalysisTemporarily() {
analysisEnabled = false;
analysis.setTaskId(-2);
}
public void enableAnalysis() {
analysis.setTaskId(-1);
analysisEnabled = true;
}
public void addNotification(ISender sender) {
if (CommandUtils.isPlayer(sender)) {
notifyWhenCached.add(((Player) sender.getSender()).getUniqueId());
}
}
}

View File

@ -1,26 +0,0 @@
package main.java.com.djrapitops.plan.data.cache;
import main.java.com.djrapitops.plan.data.UserInfo;
/**
* This interface can be extended with anything as the process method and
* given to the Database.
* <p>
* The process method will be called with the UserInfo object fetched from the
* database.
*
* @author Rsl1122
* @since 2.6.0
*/
@Deprecated
public interface DBCallableProcessor {
/**
* Method used to do multiple things to UserInfo objects such as Caching,
* changing properties etc.
*
* @param data UserInfo object given to the DBCallableProcessor by the
* method it was given as parameter to.
*/
void process(UserInfo data);
}

View File

@ -41,7 +41,7 @@ public class MySQLDB extends SQLDB {
dataSource.setPassword(password);
dataSource.setInitialSize(1);
dataSource.setMaxTotal(120);
dataSource.setMaxTotal(8);
}
/**

View File

@ -71,12 +71,12 @@ public class TableSqlParser extends SqlParser {
return this;
}
public TableSqlParser primaryKeyIDColumn(boolean mySQL, String column, String type) {
public TableSqlParser primaryKeyIDColumn(boolean mySQL, String column) {
if (columns > 0) {
append(", ");
}
append(column).addSpace();
append(type).addSpace();
append(Sql.INT).addSpace();
append((mySQL) ? "NOT NULL AUTO_INCREMENT" : "PRIMARY KEY");
columns++;
return this;

View File

@ -13,7 +13,7 @@ import org.apache.commons.lang3.text.WordUtils;
*/
public enum Actions {
UNKNOWN(-1),
REGISTERED(1),
FIRST_SESSION(1),
FIRST_LOGOUT(2),
CHANGED_NAME(3),
KILLED(-2), // Not stored in ActionsTable.

View File

@ -43,7 +43,7 @@ public class CommandUseTable extends Table {
public boolean createTable() {
ServerTable serverTable = db.getServerTable();
return createTable(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, columnCommandId, Sql.INT)
.primaryKeyIDColumn(usingMySQL, columnCommandId)
.column(columnCommand, Sql.varchar(20)).notNull()
.column(columnTimesUsed, Sql.INT).notNull()
.column(columnServerID, Sql.INT).notNull()

View File

@ -8,10 +8,7 @@ import main.java.com.djrapitops.plan.database.sql.TableSqlParser;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
/**
* @author Rsl1122
@ -67,6 +64,7 @@ public class IPsTable extends UserIDTable {
statement = prepareStatement(Select.from(tableName, column)
.where(columnUserID + "=" + usersTable.statementSelectID)
.toString());
statement.setFetchSize(50);
statement.setString(1, uuid.toString());
set = statement.executeQuery();
while (set.next()) {
@ -128,4 +126,35 @@ public class IPsTable extends UserIDTable {
close(set, statement);
}
}
public Map<UUID, List<String>> getAllGeolocations() throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
Map<UUID, List<String>> geoLocations = new HashMap<>();
String usersIDColumn = usersTable + "." + usersTable.getColumnID();
String usersUUIDColumn = usersTable + "." + usersTable.getColumnUUID() + " as uuid";
statement = prepareStatement("SELECT " +
columnGeolocation + ", " +
usersUUIDColumn +
" FROM " + tableName +
" JOIN " + usersTable + " on " + usersIDColumn + "=" + columnUserID
);
statement.setFetchSize(5000);
set = statement.executeQuery();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString("uuid"));
List<String> userGeoLocs = geoLocations.getOrDefault(uuid, new ArrayList<>());
userGeoLocs.add(set.getString(columnGeolocation));
geoLocations.put(uuid, userGeoLocs);
}
return geoLocations;
} finally {
endTransaction(statement);
close(set, statement);
}
}
}

View File

@ -47,7 +47,7 @@ public class KillsTable extends UserIDTable {
.column(columnVictimUserID, Sql.INT).notNull()
.column(columnWeapon, Sql.varchar(30)).notNull()
.column(columnDate, Sql.LONG).notNull()
.column(columnSessionID, Sql.LONG).notNull()
.column(columnSessionID, Sql.INT).notNull()
.foreignKey(columnKillerUserID, usersTable.getTableName(), usersTable.getColumnID())
.foreignKey(columnVictimUserID, usersTable.getTableName(), usersTable.getColumnID())
.foreignKey(columnSessionID, sessionsTable.getTableName(), sessionsTable.getColumnID())
@ -76,7 +76,7 @@ public class KillsTable extends UserIDTable {
}
}
public void savePlayerKills(UUID uuid, long sessionID, List<PlayerKill> playerKills) throws SQLException {
public void savePlayerKills(UUID uuid, int sessionID, List<PlayerKill> playerKills) throws SQLException {
if (Verify.isEmpty(playerKills)) {
return;
}
@ -98,7 +98,7 @@ public class KillsTable extends UserIDTable {
String weapon = kill.getWeapon();
statement.setString(1, uuid.toString());
statement.setString(2, victim.toString());
statement.setLong(3, sessionID);
statement.setInt(3, sessionID);
statement.setLong(4, date);
statement.setString(5, weapon);
statement.addBatch();
@ -111,7 +111,7 @@ public class KillsTable extends UserIDTable {
}
}
public void addKillsToSessions(UUID uuid, Map<Long, Session> sessions) throws SQLException {
public void addKillsToSessions(UUID uuid, Map<Integer, Session> sessions) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
@ -131,7 +131,7 @@ public class KillsTable extends UserIDTable {
commit(statement.getConnection());
while (set.next()) {
long sessionID = set.getLong(columnSessionID);
int sessionID = set.getInt(columnSessionID);
Session session = sessions.get(sessionID);
if (session == null) {
continue;

View File

@ -49,7 +49,7 @@ public class ServerTable extends Table {
@Override
public boolean createTable() {
return createTable(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, columnServerID, Sql.INT)
.primaryKeyIDColumn(usingMySQL, columnServerID)
.column(columnServerUUID, Sql.varchar(36)).notNull().unique()
.column(columnServerName, Sql.varchar(100))
.column(columnWebserverAddress, Sql.varchar(100))

View File

@ -45,7 +45,7 @@ public class SessionsTable extends UserIDTable {
@Override
public boolean createTable() {
return createTable(TableSqlParser.createTable(this.tableName)
.primaryKeyIDColumn(usingMySQL, columnID, Sql.LONG)
.primaryKeyIDColumn(usingMySQL, columnID)
.column(columnUserID, Sql.INT).notNull()
.column(columnServerID, Sql.INT).notNull()
.column(columnSessionStart, Sql.LONG).notNull()
@ -70,7 +70,7 @@ public class SessionsTable extends UserIDTable {
*/
public void saveSession(UUID uuid, Session session) throws SQLException {
saveSessionInformation(uuid, session);
long sessionID = getSessionID(uuid, session);
int sessionID = getSessionID(uuid, session);
if (sessionID == -1) {
throw new IllegalStateException("Session was not Saved!");
}
@ -124,7 +124,7 @@ public class SessionsTable extends UserIDTable {
* @param session session inserted.
* @return ID of the inserted session or -1 if session has not been inserted.
*/
private long getSessionID(UUID uuid, Session session) throws SQLException {
private int getSessionID(UUID uuid, Session session) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
@ -137,9 +137,9 @@ public class SessionsTable extends UserIDTable {
statement.setLong(3, session.getSessionEnd());
set = statement.executeQuery();
if (set.next()) {
return set.getLong(columnID);
return set.getInt(columnID);
}
return -1L;
return -1;
} finally {
endTransaction(statement);
close(set, statement);
@ -168,7 +168,7 @@ public class SessionsTable extends UserIDTable {
statement.setString(1, uuid.toString());
set = statement.executeQuery();
while (set.next()) {
long id = set.getLong(columnID);
int id = set.getInt(columnID);
long start = set.getLong(columnSessionStart);
long end = set.getLong(columnSessionEnd);
String serverName = serverNames.get(set.getInt(columnServerID));
@ -192,7 +192,7 @@ public class SessionsTable extends UserIDTable {
public Map<String, List<Session>> getSessions(UUID uuid) throws SQLException {
Map<String, List<Session>> sessions = getSessionInformation(uuid);
Map<Long, Session> allSessions = sessions.values().stream().flatMap(Collection::stream).collect(Collectors.toMap(Session::getSessionID, Function.identity()));
Map<Integer, Session> allSessions = sessions.values().stream().flatMap(Collection::stream).collect(Collectors.toMap(Session::getSessionID, Function.identity()));
db.getKillsTable().addKillsToSessions(uuid, allSessions);
db.getWorldTimesTable().addWorldTimesToSessions(uuid, allSessions);
@ -313,6 +313,16 @@ public class SessionsTable extends UserIDTable {
}
}
/**
* Used to get the Total Playtime of THIS Server.
*
* @return Milliseconds played on the server. 0 if server not found.
* @throws SQLException
*/
public long getPlaytimeOfServer() throws SQLException {
return getPlaytimeOfServer(Plan.getServerUUID());
}
/**
* Used to get the Total Playtime of a Server.
*
@ -324,6 +334,17 @@ public class SessionsTable extends UserIDTable {
return getPlaytimeOfServer(serverUUID, 0L);
}
/**
* Used to get Playtime after a date of THIS Server.
*
* @param afterDate Epoch ms (Playtime after this date is calculated)
* @return Milliseconds played after given epoch ms on the server. 0 if server not found.
* @throws SQLException
*/
public long getPlaytimeOfServer(long afterDate) throws SQLException {
return getPlaytimeOfServer(Plan.getServerUUID(), afterDate);
}
/**
* Used to get Playtime after a date of a Server.
*
@ -425,4 +446,52 @@ public class SessionsTable extends UserIDTable {
public String getColumnID() {
return columnID;
}
public Map<UUID, List<Session>> getSessionInfoOfServer() throws SQLException {
return getSessionInfoOfServer(Plan.getServerUUID());
}
public Map<UUID, List<Session>> getSessionInfoOfServer(UUID serverUUID) throws SQLException {
Optional<Integer> id = serverTable.getServerID(serverUUID);
if (!id.isPresent()) {
return new HashMap<>();
}
int serverID = id.get();
Map<UUID, List<Session>> sessionsByUser = new HashMap<>();
PreparedStatement statement = null;
ResultSet set = null;
try {
String usersIDColumn = usersTable + "." + usersTable.getColumnID();
String usersUUIDColumn = usersTable + "." + usersTable.getColumnUUID() + " as uuid";
statement = prepareStatement("SELECT " +
columnSessionStart + ", " +
columnSessionEnd + ", " +
columnDeaths + ", " +
columnMobKills + ", " +
usersUUIDColumn +
" FROM " + tableName +
" JOIN " + usersTable + " on " + usersIDColumn + "=" + columnUserID +
" WHERE " + columnServerID + "=" + serverTable.statementSelectServerID
);
statement.setFetchSize(5000);
statement.setString(1, serverUUID.toString());
set = statement.executeQuery();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString("uuid"));
long start = set.getLong(columnSessionStart);
long end = set.getLong(columnSessionEnd);
int deaths = set.getInt(columnDeaths);
int mobKills = set.getInt(columnMobKills);
List<Session> sessions = sessionsByUser.getOrDefault(uuid, new ArrayList<>());
sessions.add(new Session(serverID, start, end, deaths, mobKills));
sessionsByUser.put(uuid, sessions);
}
return sessionsByUser;
} finally {
endTransaction(statement);
close(set, statement);
}
}
}

View File

@ -37,7 +37,7 @@ public class UsersTable extends UserIDTable {
@Override
public boolean createTable() {
return createTable(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, columnID, Sql.INT)
.primaryKeyIDColumn(usingMySQL, columnID)
.column(columnUUID, Sql.varchar(36)).notNull().unique()
.column(columnRegistered, Sql.LONG).notNull()
.column(columnName, Sql.varchar(16)).notNull()

View File

@ -42,7 +42,7 @@ public class WorldTable extends Table {
@Override
public boolean createTable() {
return createTable(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, columnWorldId, Sql.INT)
.primaryKeyIDColumn(usingMySQL, columnWorldId)
.column(columnWorldName, Sql.varchar(100)).notNull()
.primaryKey(usingMySQL, columnWorldId)
.toString()

View File

@ -1,6 +1,7 @@
package main.java.com.djrapitops.plan.database.tables;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.data.time.GMTimes;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
@ -51,7 +52,7 @@ public class WorldTimesTable extends UserIDTable {
return createTable(TableSqlParser.createTable(tableName)
.column(columnUserID, Sql.INT).notNull()
.column(columnWorldId, Sql.INT).notNull()
.column(columnSessionID, Sql.LONG).notNull()
.column(columnSessionID, Sql.INT).notNull()
.column(columnSurvival, Sql.LONG).notNull().defaultValue("0")
.column(columnCreative, Sql.LONG).notNull().defaultValue("0")
.column(columnAdventure, Sql.LONG).notNull().defaultValue("0")
@ -63,7 +64,7 @@ public class WorldTimesTable extends UserIDTable {
);
}
public void saveWorldTimes(UUID uuid, long sessionID, WorldTimes worldTimes) throws SQLException {
public void saveWorldTimes(UUID uuid, int sessionID, WorldTimes worldTimes) throws SQLException {
Map<String, GMTimes> worldTimesMap = worldTimes.getWorldTimes();
if (Verify.isEmpty(worldTimesMap)) {
return;
@ -92,7 +93,7 @@ public class WorldTimesTable extends UserIDTable {
GMTimes gmTimes = entry.getValue();
statement.setString(1, uuid.toString());
statement.setString(2, worldName);
statement.setLong(3, sessionID);
statement.setInt(3, sessionID);
String[] gms = GMTimes.getGMKeyArray();
statement.setLong(4, gmTimes.getTime(gms[0]));
@ -109,7 +110,7 @@ public class WorldTimesTable extends UserIDTable {
}
}
public void addWorldTimesToSessions(UUID uuid, Map<Long, Session> sessions) throws SQLException {
public void addWorldTimesToSessions(UUID uuid, Map<Integer, Session> sessions) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
@ -131,7 +132,7 @@ public class WorldTimesTable extends UserIDTable {
String[] gms = GMTimes.getGMKeyArray();
while (set.next()) {
long sessionID = set.getLong(columnSessionID);
int sessionID = set.getInt(columnSessionID);
Session session = sessions.get(sessionID);
if (session == null) {
@ -154,4 +155,51 @@ public class WorldTimesTable extends UserIDTable {
close(set, statement);
}
}
public WorldTimes getWorldTimesOfServer() throws SQLException {
return getWorldTimesOfServer(Plan.getServerUUID());
}
public WorldTimes getWorldTimesOfServer(UUID serverUUID) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
String worldIDColumn = worldTable + "." + worldTable.getColumnID();
String worldNameColumn = worldTable + "." + worldTable.getColumnWorldName() + " as world_name";
String sessionIDColumn = sessionsTable + "." + sessionsTable.getColumnID();
String sessionServerIDColumn = sessionsTable + ".server_id";
statement = prepareStatement("SELECT " +
"SUM(" + columnSurvival + ") as survival, " +
"SUM(" + columnCreative + ") as creative, " +
"SUM(" + columnAdventure + ") as adventure, " +
"SUM(" + columnSpectator + ") as spectator, " +
worldNameColumn +
" FROM " + tableName +
" JOIN " + worldTable + " on " + worldIDColumn + "=" + columnWorldId +
" JOIN " + sessionsTable + " on " + sessionIDColumn + "=" + columnSessionID +
" WHERE " + sessionServerIDColumn + "=" + db.getServerTable().statementSelectServerID
);
statement.setString(1, serverUUID.toString());
set = statement.executeQuery();
String[] gms = GMTimes.getGMKeyArray();
WorldTimes worldTimes = new WorldTimes(new HashMap<>());
while (set.next()) {
String worldName = set.getString("world_name");
Map<String, Long> gmMap = new HashMap<>();
gmMap.put(gms[0], set.getLong("survival"));
gmMap.put(gms[1], set.getLong("creative"));
gmMap.put(gms[2], set.getLong("adventure"));
gmMap.put(gms[3], set.getLong("spectator"));
GMTimes gmTimes = new GMTimes(gmMap);
worldTimes.setGMTimesForWorld(worldName, gmTimes);
}
return worldTimes;
} finally {
endTransaction(statement);
close(set, statement);
}
}
}

View File

@ -5,18 +5,23 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.database.Database;
import java.sql.SQLException;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* This Class contains the Cache.
* <p>
* It is used to store command use, active sessions and Unsaved TPS objects
* objects in memory.
* <p>
* Its methods can be used to access all the data it stores and to clear them.
* Contains:
* <ul>
* <li>PlayerName cache, used for reducing database calls on chat events</li>
* <li>DisplayName cache, used for reducing database calls on chat events</li>
* <li>FirstSession MessageCount Map, used for tracking first session & message count on that session.</li>
* </ul>
*
* @author Rsl1122
* @since 2.0.0
* @since 4.0.0
*/
public class DataCache extends SessionCache {
@ -25,13 +30,10 @@ public class DataCache extends SessionCache {
private final Map<UUID, String> playerNames;
private final Map<UUID, String> displayNames;
private final Set<UUID> playersWithFirstSession;
private static final Map<UUID, Integer> firstSessionInformation = new HashMap<>();
/**
* Class Constructor.
* <p>
* Gets the Database from the plugin. Starts the queues. Registers
* Asynchronous Periodic Save Task
*
* @param plugin Current instance of Plan
*/
@ -41,25 +43,47 @@ public class DataCache extends SessionCache {
playerNames = new HashMap<>();
displayNames = new HashMap<>();
playersWithFirstSession = new HashSet<>();
}
/**
* Used to update PlayerName and DisplayName caches.
*
* @param uuid UUID of the player.
* @param playerName Name of the player.
* @param displayName DisplayName of the player.
*/
public void updateNames(UUID uuid, String playerName, String displayName) {
playerNames.put(uuid, playerName);
displayNames.put(uuid, displayName);
}
/**
* Used to get the player name in the cache.
*
* @param uuid UUID of the player.
* @return name or null if not cached.
*/
public String getName(UUID uuid) {
return playerNames.get(uuid);
}
/**
* Used to get the player display name in the cache.
*
* If not cached, one from the database will be cached.
*
* @param uuid UUID of the player.
* @return latest displayName or null if none are saved.
*/
public String getDisplayName(UUID uuid) {
String cached = displayNames.get(uuid);
if (cached == null) {
List<String> nicknames = null;
try {
nicknames = db.getNicknamesTable().getNicknames(uuid);
return nicknames.get(nicknames.size() - 1);
if (!nicknames.isEmpty()) {
return nicknames.get(nicknames.size() - 1);
}
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
}
@ -67,15 +91,35 @@ public class DataCache extends SessionCache {
return cached;
}
public void addFirstLeaveCheck(UUID uuid) {
playersWithFirstSession.add(uuid);
/**
* Used for marking first Session Actions to be saved.
*
* @param uuid UUID of the new player.
*/
public void markFirstSession(UUID uuid) {
firstSessionInformation.put(uuid, 0);
}
/**
*
* @param uuid
* @return
*/
public boolean isFirstSession(UUID uuid) {
return playersWithFirstSession.contains(uuid);
return firstSessionInformation.containsKey(uuid);
}
public void clearFromFirstLeaveCheck(UUID uuid) {
playersWithFirstSession.remove(uuid);
public void endFirstSessionActionTracking(UUID uuid) {
firstSessionInformation.remove(uuid);
}
public void firstSessionMessageSent(UUID uuid) {
Integer msgCount = firstSessionInformation.getOrDefault(uuid, 0);
msgCount++;
firstSessionInformation.put(uuid, msgCount);
}
public int getFirstSessionMsgCount(UUID uuid) {
return firstSessionInformation.getOrDefault(uuid, 0);
}
}

View File

@ -66,7 +66,6 @@ public class SessionCache {
*
* @return key:value UUID:Session
*/
@Deprecated
public Map<UUID, Session> getActiveSessions() {
return activeSessions;
}

View File

@ -4,15 +4,20 @@
*/
package main.java.com.djrapitops.plan.systems.info;
import com.djrapitops.plugin.command.ISender;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.commands.AnalyzeCommand;
import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.systems.cache.DataCache;
import main.java.com.djrapitops.plan.systems.cache.SessionCache;
import main.java.com.djrapitops.plan.systems.info.parsing.UrlParser;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.analysis.Analysis;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
/**
@ -30,7 +35,10 @@ public class InformationManager {
private boolean usingBungeeWebServer;
private String webServerAddress;
private final Set<ISender> analysisNotification;
private final Analysis analysis;
private AnalysisData analysisData;
private String analysisPluginsTab;
private Long refreshDate;
public InformationManager(Plan plugin) {
@ -41,6 +49,8 @@ public class InformationManager {
.ifPresent(address -> webServerAddress = address);
dataCache = new DataCache(plugin);
analysis = new Analysis(plugin);
analysisNotification = new HashSet<>();
if (webServerAddress != null) {
attemptBungeeConnection();
@ -65,7 +75,7 @@ public class InformationManager {
}
public void refreshAnalysis() {
plugin.addToProcessQueue(); // TODO Analysis, PluginData
analysis.runAnalysis(this);
}
public DataCache getDataCache() {
@ -99,6 +109,13 @@ public class InformationManager {
public void cacheAnalysisdata(AnalysisData analysisData) {
this.analysisData = analysisData;
refreshDate = MiscUtils.getTime();
// TODO Web Caching
AnalyzeCommand.sendAnalysisMessage(analysisNotification);
analysisNotification.clear();
}
public void addAnalysisNotification(ISender sender) {
analysisNotification.add(sender);
}
public AnalysisData getAnalysisData() {

View File

@ -67,7 +67,7 @@ public class ServerInfoManager {
return;
}
String name = Settings.SERVER_NAME.toString();
String webAddress = plugin.getUiServer().getAccessAddress();
String webAddress = plugin.getWebServer().getAccessAddress();
if ("plan".equalsIgnoreCase(name)) {
name = "Server" + serverID.get();
}
@ -81,7 +81,7 @@ public class ServerInfoManager {
}
private void registerServer(UUID serverUUID) throws SQLException, IOException {
String webAddress = plugin.getUiServer().getAccessAddress();
String webAddress = plugin.getWebServer().getAccessAddress();
String name = Settings.SERVER_NAME.toString();
serverInfo = new ServerInfo(-1, serverUUID, name, webAddress);
serverTable.saveCurrentServerInfo(serverInfo);

View File

@ -47,6 +47,11 @@ public class PlanChatListener implements Listener {
String name = p.getName();
String displayName = p.getDisplayName();
DataCache dataCache = plugin.getDataCache();
if (dataCache.isFirstSession(uuid)) {
dataCache.firstSessionMessageSent(uuid);
}
plugin.addToProcessQueue(new NameProcessor(uuid, name, displayName));
}
}

View File

@ -96,7 +96,7 @@ public class PlanPlayerListener implements Listener {
cache.cacheSession(uuid, Session.start(time, world, gm));
plugin.addToProcessQueue(
new RegisterProcessor(uuid, player.getFirstPlayed(), playerName, playersOnline),
new RegisterProcessor(uuid, player.getFirstPlayed(), time, playerName, playersOnline),
new IPUpdateProcessor(uuid, ip),
new NameProcessor(uuid, playerName, displayName),
new DBCommitProcessor(plugin.getDB())
@ -122,7 +122,7 @@ public class PlanPlayerListener implements Listener {
new EndSessionProcessor(uuid, time)
);
int messagesSent = 0; // TODO messages Sent on first session
int messagesSent = plugin.getDataCache().getFirstSessionMsgCount(uuid);
if (cache.isFirstSession(uuid)) {
plugin.addToProcessQueue(new FirstLeaveProcessor(uuid, time, messagesSent));

View File

@ -36,7 +36,7 @@ public class FirstLeaveProcessor extends PlayerProcessor {
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
} finally {
plugin.getDataCache().clearFromFirstLeaveCheck(uuid);
plugin.getDataCache().endFirstSessionActionTracking(uuid);
}
}
}

View File

@ -20,12 +20,14 @@ import java.util.UUID;
*/
public class RegisterProcessor extends PlayerProcessor {
private final long registered;
private final long time;
private final int playersOnline;
private final String name;
public RegisterProcessor(UUID uuid, long time, String name, int playersOnline) {
public RegisterProcessor(UUID uuid, long registered, long time, String name, int playersOnline) {
super(uuid);
this.registered = registered;
this.time = time;
this.playersOnline = playersOnline;
this.name = name;
@ -39,10 +41,10 @@ public class RegisterProcessor extends PlayerProcessor {
if (db.wasSeenBefore(uuid)) {
return;
}
plugin.getDataCache().addFirstLeaveCheck(uuid);
plugin.getDataCache().markFirstSession(uuid);
try {
db.getUserInfoTable().registerUserInfo(uuid, time);
db.getActionsTable().insertAction(uuid, new Action(time, Actions.REGISTERED, "Online: " + playersOnline + " Players"));
db.getUserInfoTable().registerUserInfo(uuid, registered);
db.getActionsTable().insertAction(uuid, new Action(time, Actions.FIRST_SESSION, "Online: " + playersOnline + " Players"));
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
}

View File

@ -10,12 +10,16 @@ import main.java.com.djrapitops.plan.database.tables.SecurityTable;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.systems.cache.PageCache;
import main.java.com.djrapitops.plan.systems.info.InformationManager;
import main.java.com.djrapitops.plan.systems.webapi.WebAPI;
import main.java.com.djrapitops.plan.systems.webapi.WebAPIManager;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.AnalyticsWebAPI;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.AnalyzeWebAPI;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.ConfigureWebAPI;
import main.java.com.djrapitops.plan.systems.webapi.bukkit.InspectWebAPI;
import main.java.com.djrapitops.plan.systems.webserver.response.*;
import main.java.com.djrapitops.plan.systems.webserver.response.api.BadRequestResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.api.JsonResponse;
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
import main.java.com.djrapitops.plan.utilities.Benchmark;
import main.java.com.djrapitops.plan.utilities.PassEncryptUtil;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
@ -44,7 +48,8 @@ import java.util.zip.GZIPOutputStream;
public class WebServer {
private final Plan plugin;
private final DataRequestHandler dataReqHandler;
private InformationManager infoManager;
private final int port;
private boolean enabled = false;
private HttpServer server;
@ -53,15 +58,25 @@ public class WebServer {
/**
* Class Constructor.
* <p>
* Initializes DataRequestHandler
*
* @param plugin Current instance of Plan
*/
public WebServer(Plan plugin) {
this.plugin = plugin;
this.port = Settings.WEBSERVER_PORT.getNumber();
dataReqHandler = new DataRequestHandler(plugin);
registerWebAPIs();
}
public void setInfoManager(InformationManager infoManager) {
this.infoManager = infoManager;
}
private void registerWebAPIs() {
WebAPIManager.registerNewAPI("analytics", new AnalyticsWebAPI());
WebAPIManager.registerNewAPI("analyze", new AnalyzeWebAPI());
WebAPIManager.registerNewAPI("configure", new ConfigureWebAPI());
WebAPIManager.registerNewAPI("inspect", new InspectWebAPI());
}
/**
@ -445,12 +460,12 @@ public class WebServer {
}
private Response serverResponse() {
if (!dataReqHandler.checkIfAnalysisIsCached()) {
if (!infoManager.isAnalysisCached()) {
String error = "Analysis Data was not cached.<br>Use /plan analyze to cache the Data.";
PageCache.loadPage("notFound: " + error, () -> new NotFoundResponse(error));
}
return PageCache.loadPage("analysisPage", () -> new AnalysisPageResponse(dataReqHandler));
return PageCache.loadPage("analysisPage", () -> new AnalysisPageResponse(infoManager));
}
private Response playerResponse(String[] args) {
@ -466,12 +481,12 @@ public class WebServer {
return PageCache.loadPage("notFound: " + error, () -> new NotFoundResponse(error));
}
if (!dataReqHandler.checkIfCached(uuid)) {
if (!infoManager.isCached(uuid)) {
String error = "Player's data was not cached.<br>Use /plan inspect " + playerName + " to cache the Data.";
return PageCache.loadPage("notFound: " + error, () -> new NotFoundResponse(error));
}
return PageCache.loadPage("inspectPage: " + uuid, () -> new InspectPageResponse(dataReqHandler, uuid));
return PageCache.loadPage("inspectPage: " + uuid, () -> new InspectPageResponse(infoManager, uuid));
}
private Response notFoundResponse() {
@ -504,15 +519,6 @@ public class WebServer {
}
}
/**
* Used to get the handler for Html content requests.
*
* @return DataRequestHandler used by the WebServer.
*/
public DataRequestHandler getDataReqHandler() {
return dataReqHandler;
}
private int getRequiredPermLevel(String target, String user) {
String[] t = target.split("/");
if (t.length < 2) {

View File

@ -1,7 +1,7 @@
package main.java.com.djrapitops.plan.systems.webserver.response;
import main.java.com.djrapitops.plan.systems.info.InformationManager;
import main.java.com.djrapitops.plan.systems.webserver.theme.Theme;
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
/**
* @author Rsl1122
@ -9,8 +9,8 @@ import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
*/
public class AnalysisPageResponse extends Response {
public AnalysisPageResponse(DataRequestHandler h) {
public AnalysisPageResponse(InformationManager informationManager) {
super.setHeader("HTTP/1.1 200 OK");
super.setContent(Theme.replaceColors(h.getServerHtml()));
super.setContent(Theme.replaceColors(informationManager.getAnalysisHtml()));
}
}

View File

@ -1,7 +1,7 @@
package main.java.com.djrapitops.plan.systems.webserver.response;
import main.java.com.djrapitops.plan.systems.info.InformationManager;
import main.java.com.djrapitops.plan.systems.webserver.theme.Theme;
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
import java.util.UUID;
@ -11,8 +11,8 @@ import java.util.UUID;
*/
public class InspectPageResponse extends Response {
public InspectPageResponse(DataRequestHandler h, UUID uuid) {
public InspectPageResponse(InformationManager infoManager, UUID uuid) {
super.setHeader("HTTP/1.1 200 OK");
super.setContent(Theme.replaceColors(h.getInspectHtml(uuid)));
super.setContent(Theme.replaceColors(infoManager.getPlayerHtml(uuid)));
}
}

View File

@ -1,68 +0,0 @@
package main.java.com.djrapitops.plan.ui.html;
import main.java.com.djrapitops.plan.Plan;
import java.util.UUID;
/**
* @author Rsl1122
*/
@Deprecated //TODO Make an utility class for parsing files to give to the page cache.
public class DataRequestHandler {
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
@Deprecated
public DataRequestHandler(Plan plugin) {
}
/**
* Checks if the Players data is in the inspect cache.
*
* @param uuid UUID of Player
* @return true if cached.
*/
@Deprecated
public boolean checkIfCached(UUID uuid) {
// TODO Check from PageCache
return false;
}
/**
* Returns the player.html as string with replaced placeholders.
*
* @param uuid UUID of player, whose UserInfo is used to replace
* placeholders with
* @return The html
*/
@Deprecated
public String getInspectHtml(UUID uuid) {
// TODO Get from PageCache
return "";
}
/**
* Returns the server.html as string with replaced placeholders.
*
* @return the html
*/
@Deprecated
public String getServerHtml() {
// TODO Get from PageCache
return "";
}
/**
* Checks if the AnalysisData is cached.
*
* @return true if cached.
*/
@Deprecated
public boolean checkIfAnalysisIsCached() {
// TODO Check from PageCache
return false;
}
}

View File

@ -1,45 +0,0 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package main.java.com.djrapitops.plan.ui.webserver.api.bukkit;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.systems.webapi.WebAPI;
import main.java.com.djrapitops.plan.systems.webserver.response.Response;
import main.java.com.djrapitops.plan.systems.webserver.response.api.BadRequestResponse;
import java.util.Map;
/**
* @author Fuzzlemann
*/
@Deprecated // UserData objects should not be sent between servers.
public class InspectionWebAPI implements WebAPI {
@Override
public Response onResponse(Plan plan, Map<String, String> variables) {
// String playerString = variables.get("player");
//
// if (playerString == null) {
// String error = "Player String not included";
// return PageCache.loadPage(error, () -> new BadRequestResponse(error));
// }
//
// UUID uuid = UUIDUtility.getUUIDOf(playerString);
//
// if (uuid == null) {
// String error = "UUID not found";
// return PageCache.loadPage(error, () -> new BadRequestResponse(error));
// }
//
// UserInfo userInfo = plan.getInspectCache().getFromCache(uuid);
//
// if (userInfo == null) {
// String error = "User not cached";
// return PageCache.loadPage(error, () -> new BadRequestResponse(error));
// }
//
// return PageCache.loadPage("inspectionJson: " + uuid, () -> new JsonResponse(plan.getInspectCache().getFromCache(uuid)));
return new BadRequestResponse("Not implemented");
}
}

View File

@ -1,53 +0,0 @@
package main.java.com.djrapitops.plan.utilities;
import com.djrapitops.plugin.utilities.player.Gamemode;
import com.djrapitops.plugin.utilities.player.IOfflinePlayer;
import com.djrapitops.plugin.utilities.player.IPlayer;
import main.java.com.djrapitops.plan.data.UserInfo;
/**
* @author Rsl1122
* @deprecated Will be removed once it's sure that it's unnecessary
*/
@Deprecated // TODO Remove once sure that this is unnecessary.
public class NewPlayerCreator {
/**
* Constructor used to hide the public constructor
*/
private NewPlayerCreator() {
throw new IllegalStateException("Utility class");
}
/**
* Creates a new instance of UserInfo with default values.
*
* @param player Player the UserInfo is created for.
* @return a new UserInfo object
*/
public static UserInfo createNewPlayer(IPlayer player) {
return createNewPlayer(player, player.getGamemode());
}
/**
* Creates a new instance of UserInfo with default values.
*
* @param player OfflinePlayer the UserInfo is created for.
* @return a new UserInfo object
*/
public static UserInfo createNewOfflinePlayer(IOfflinePlayer player) {
return createNewPlayer(player, Gamemode.SURVIVAL);
}
/**
* Creates a new instance of UserInfo with default values.
*
* @param player Player the UserInfo is created for.
* @param gm Gamemode set as the starting Gamemode
* @return a new UserInfo object
*/
public static UserInfo createNewPlayer(IOfflinePlayer player, Gamemode gm) {
return null;
}
}

View File

@ -1,21 +1,25 @@
package main.java.com.djrapitops.plan.utilities.analysis;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.data.UserInfo;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.data.analysis.*;
import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.systems.cache.DataCache;
import main.java.com.djrapitops.plan.systems.cache.PageCache;
import main.java.com.djrapitops.plan.systems.info.InformationManager;
import main.java.com.djrapitops.plan.systems.webserver.response.AnalysisPageResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.PlayersPageResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.api.JsonResponse;
@ -24,6 +28,7 @@ import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
@ -46,14 +51,10 @@ public class Analysis {
/**
* Analyzes the data of all offline players on the server.
* <p>
* First retrieves all offline players and checks those that are in the
* database. Then runs a new Analysis Task asynchronously. Saves AnalysisData
* to the provided Cache. Saves all UserInfo to InspectCache for 15 minutes.
*
* @param analysisCache Cache that the data is saved to.
* @param infoManager InformationManager of the plugin.
*/
public void runAnalysis(AnalysisCacheHandler analysisCache) {
public void runAnalysis(InformationManager infoManager) {
if (isAnalysisBeingRun()) {
return;
}
@ -65,7 +66,7 @@ public class Analysis {
@Override
public void run() {
taskId = this.getTaskId();
analyze(analysisCache, plugin.getDB());
analyze(infoManager, plugin.getDB());
taskId = -1;
this.cancel();
}
@ -75,12 +76,12 @@ public class Analysis {
/**
* Caches analyzed data of db to the provided cache analysisCache.
*
* @param analysisCache Cache that will contain AnalysisData result of this
* method.
* @param db Database which data will be analyzed.
* @param infoManager InformationManager of the plugin.
* method.
* @param db Database which data will be analyzed.
* @return Whether or not analysis was successful.
*/
public boolean analyze(AnalysisCacheHandler analysisCache, Database db) {
public boolean analyze(InformationManager infoManager, Database db) {
log(Locale.get(Msg.ANALYSIS_FETCH).toString());
Benchmark.start("Fetch Phase");
Log.debug("Database", "Analysis Fetch");
@ -95,15 +96,15 @@ public class Analysis {
Log.toLog(this.getClass().getName(), ex);
}
return analyzeData(tpsData, analysisCache);
return analyzeData(tpsData, infoManager, db);
}
/**
* @param tpsData
* @param analysisCache
* @param infoManager InformationManager of the plugin.
* @return
*/
public boolean analyzeData(List<TPS> tpsData, AnalysisCacheHandler analysisCache) {
public boolean analyzeData(List<TPS> tpsData, InformationManager infoManager, Database db) {
try {
// rawData.sort(new UserDataLastPlayedComparator());
// List<UUID> uuids = rawData.stream().map(UserInfo::getUuid).collect(Collectors.toList());
@ -134,7 +135,7 @@ public class Analysis {
// String playersTable = PlayersTableCreator.createSortablePlayersTable(rawData);
// analysisData.setPlayersTable(playersTable);
fillDataset(analysisData);
fillDataset(analysisData, db);
// Analyze
analysisData.analyseData();
Benchmark.stop("Analysis", "Analysis Phase");
@ -143,7 +144,7 @@ public class Analysis {
Log.debug("Analysis", "Analyzing additional data sources (3rd party)");
// TODO analysisData.setAdditionalDataReplaceMap(analyzeAdditionalPluginData(uuids));
analysisCache.cache(analysisData);
infoManager.cacheAnalysisdata(analysisData);
long time = Benchmark.stop("Analysis", "Analysis");
Log.logDebug("Analysis", time);
@ -151,7 +152,7 @@ public class Analysis {
Log.info(Locale.get(Msg.ANALYSIS_FINISHED).parse(String.valueOf(time), HtmlUtils.getServerAnalysisUrlWithProtocol()));
PageCache.removeIf(identifier -> identifier.startsWith("inspectPage: ") || identifier.startsWith("inspectionJson: "));
PageCache.cachePage("analysisPage", () -> new AnalysisPageResponse(plugin.getUiServer().getDataReqHandler()));
PageCache.cachePage("analysisPage", () -> new AnalysisPageResponse(plugin.getInfoManager()));
PageCache.cachePage("analysisJson", () -> new JsonResponse(analysisData));
PageCache.cachePage("players", () -> new PlayersPageResponse(plugin));
@ -239,61 +240,64 @@ public class Analysis {
taskId = id;
}
private void fillDataset(AnalysisData analysisData) {
private void fillDataset(AnalysisData analysisData, Database db) {
ActivityPart activity = analysisData.getActivityPart();
GamemodePart gmPart = analysisData.getGamemodePart();
GeolocationPart geolocPart = analysisData.getGeolocationPart();
JoinInfoPart joinInfo = analysisData.getJoinInfoPart();
KillPart killPart = analysisData.getKillPart();
PlayerCountPart playerCount = analysisData.getPlayerCountPart();
PlaytimePart playtime = analysisData.getPlaytimePart();
WorldPart worldPart = analysisData.getWorldPart();
long now = MiscUtils.getTime();
Benchmark.start("Fill Dataset");
List<PluginData> banSources = plugin.getHookHandler().getAdditionalDataSources()
.stream().filter(PluginData::isBanData).collect(Collectors.toList());
// rawData.forEach(uData -> {
// TODO Map<String, Long> worldTimes = uData.getWorldTimes().getTimes();
Benchmark.start("Fetch Phase");
try {
List<UserInfo> userInfo = db.getUserInfoTable().getAllUserInfo();
playerCount.addPlayers(userInfo.stream().map(UserInfo::getUuid).collect(Collectors.toSet()));
// TODO playtime.addToPlaytime(playTime);
// joinInfo.addToLoginTimes(uData.getLoginTimes());
// joinInfo.addRegistered(uData.getRegistered());
Map<UUID, Long> registered = userInfo.stream().collect(Collectors.toMap(UserInfo::getUuid, UserInfo::getRegistered));
joinInfo.addRegistered(registered);
activity.addBans(userInfo.stream().filter(UserInfo::isBanned).map(UserInfo::getUuid).collect(Collectors.toSet()));
//TODO geolocPart.addGeolocation(uData.getGeolocation());
playerCount.addOPs(userInfo.stream().filter(UserInfo::isOpped).map(UserInfo::getUuid).collect(Collectors.toSet()));
// final UUID uuid = uData.getUuid();
// if (uData.isOp()) {
// playerCount.addOP(uuid);
// }
Map<UUID, Session> activeSessions = plugin.getDataCache().getActiveSessions();
Map<UUID, List<Session>> sessions = db.getSessionsTable().getSessionInfoOfServer();
joinInfo.addActiveSessions(activeSessions);
joinInfo.addSessions(sessions);
// boolean banned = uData.isBanned();
// if (!banned) {
// banned = banSources.stream()
// .anyMatch(banData -> {
// Serializable value = banData.getValue(uuid);
// if (value instanceof Boolean) {
// return (Boolean) value;
// }
// return false;
// });
// }
//
// if (banned) {
// activity.addBan(uuid);
// } else if (uData.getLoginTimes() == 1) {
// activity.addJoinedOnce(uuid);
// TODO } else if (AnalysisUtils.isActive(now, uData.getLastPlayed(), playTime, uData.getSessionCount())) {
// activity.addActive(uuid);
// } else {
// activity.addInActive(uuid);
// }
//TODO List<PlayerKill> playerKills = uData.getPlayerKills();
Map<UUID, List<String>> geolocations = db.getIpsTable().getAllGeolocations();
geolocPart.addGeoLocations(geolocations);
// List<Session> sessions = uData.getSessions();
// joinInfo.addSessions(uuid, sessions);
// });
Benchmark.stop("Analysis", "Fill Dataset");
WorldTimes worldTimes = db.getWorldTimesTable().getWorldTimesOfServer();
worldPart.setWorldTimes(worldTimes);
playtime.setTotalPlaytime(db.getSessionsTable().getPlaytimeOfServer());
playtime.setPlaytime30d(db.getSessionsTable().getPlaytimeOfServer(now - TimeAmount.MONTH.ms()));
playtime.setPlaytime7d(db.getSessionsTable().getPlaytimeOfServer(now - TimeAmount.WEEK.ms()));
playtime.setPlaytime24h(db.getSessionsTable().getPlaytimeOfServer(now - TimeAmount.DAY.ms()));
List<PluginData> banSources = plugin.getHookHandler().getAdditionalDataSources()
.stream().filter(PluginData::isBanData).collect(Collectors.toList());
for (UUID uuid : playerCount.getUuids()) {
boolean banned = banSources.stream().anyMatch(pluginData -> {
try {
Serializable value = pluginData.getValue(uuid);
return value instanceof Boolean
&& (boolean) value;
} catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
Log.toLog(pluginData.getSourcePlugin() + pluginData.getPlaceholder("") + " (Cause) ", e);
return false;
}
});
if (banned) {
activity.addBan(uuid);
}
}
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
}
Benchmark.stop("Analysis", "Fetch Phase");
}
}

View File

@ -198,7 +198,7 @@ public class DumpUtils {
* @param plan The Plan instance
*/
private static void addConfigurationDetails(DumpLog log, Plan plan) {
boolean usingHTTPS = plan.getUiServer().isUsingHTTPS();
boolean usingHTTPS = plan.getWebServer().isUsingHTTPS();
boolean analysisExport = Settings.ANALYSIS_EXPORT.isTrue();
boolean usingAlternativeServerIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();

View File

@ -30,7 +30,6 @@ public enum Html {
COLOR_F("<span class=\"white\">"),
//
FONT_AWESOME_ICON("<i class=\"fa fa-${0}\" aria-hidden=\"true\"></i>"),
@Deprecated MINOTAR_SMALL_IMG("<img style=\"float: left; padding: 2px 2px 0px 2px\" alt=\"${0}\" src=\"https://minotar.net/avatar/${0}/19\">"),
SPAN("${0}</span>"),
BUTTON("<a class=\"button\" href=\"${0}\">${1}</a>"),
BUTTON_CLASS("class=\"button\""),
@ -38,11 +37,6 @@ public enum Html {
LINK_EXTERNAL("<a class=\"link\" target=\"_blank\" href=\"${0}\">${1}</a>"),
LINK_CLASS("class=\"link\""),
IMG("<img src=\"${0}\">"),
@Deprecated COLUMNS_DIV_WRAPPER("<div class=\"columns\">${0}</div>"),
@Deprecated COLUMN_DIV_WRAPPER("<div class=\"about box column\">${0}</div>"),
@Deprecated HEADER("<div class=\"headerbox\" style=\"width: 95%;\"><div class=\"header-icon\"><div class=\"header-label\"><i class=\"fa fa-cube\" aria-hidden=\"true\"></i><span class=\"header-text\"> ${0}</span></div></div></div>"),
@Deprecated PLUGIN_DATA_WRAPPER("<div class=\"plugin-data\">${0}</div>"),
@Deprecated PLUGIN_CONTAINER_START("<div class=\"plugin-container\">"),
//
TABLE_START_2("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th></tr></thead><tbody>"),
TABLE_START_3("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th></tr></thead><tbody>"),
@ -57,8 +51,7 @@ public enum Html {
TABLELINE_PLAYERS("<tr><td>${0}</td><td>${1}</td><td sorttable_customkey=\"${2}\">${3}</td><td>${4}</td><td sorttable_customkey=\"${5}\">${6}</td>" + "<td sorttable_customkey=\"${7}\">${8}</td><td>${9}</td></tr>"),
TABLELINE_3_CUSTOMKEY("<tr><td sorttable_customkey=\"${0}\">${1}</td><td sorttable_customkey=\"${2}\">${3}</td><td sorttable_customkey=\"${4}\">${5}</td></tr>"),
TABLELINE_3_CUSTOMKEY_1("<tr><td sorttable_customkey=\"${0}\">${1}</td><td>${2}</td><td>${3}</td></tr>"),
@Deprecated ERROR_TABLE_2(TABLELINE_2.parse("No data", "No data")),
TABLE_END("</tbody></table>"); // KILLDATA_NONE("No Kills"),
TABLE_END("</tbody></table>");
private final String html;

View File

@ -0,0 +1,13 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package main.java.com.djrapitops.plan.utilities.html;
/**
* Class for parsing layout components of the websites.
*
* @author Rsl1122
*/
public class HtmlStructure {
}

View File

@ -2,8 +2,6 @@ package main.java.com.djrapitops.plan.utilities.html;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.systems.webserver.WebServer;
import main.java.com.djrapitops.plan.utilities.file.FileUtil;
import org.apache.commons.lang.text.StrSubstitutor;
@ -79,7 +77,7 @@ public class HtmlUtils {
}
public static String getProtocol() {
WebServer uiServer = Plan.getInstance().getUiServer();
WebServer uiServer = Plan.getInstance().getWebServer();
return uiServer.isEnabled() ? uiServer.getProtocol() : Settings.EXTERNAL_WEBSERVER_LINK_PROTOCOL.toString();
}
@ -120,7 +118,7 @@ public class HtmlUtils {
* @param placeholders
* @return
*/
// TODO REWRITE
@Deprecated // TODO Move to HtmlStructure
public static String getPluginsTabLayout(List<String> pluginNames, Map<String, List<String>> placeholders) {
boolean sizeIsEvenNumber = pluginNames.size() % 2 == 0;
StringBuilder html = new StringBuilder();
@ -129,33 +127,34 @@ public class HtmlUtils {
for (int i = 0; i < evenSize; i++) {
String name = pluginNames.get(i);
if (i % 2 == 0) {
temp = Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)));
// temp = Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)));
} else {
html.append(Html.COLUMNS_DIV_WRAPPER.parse(temp + Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)))));
// html.append(Html.COLUMNS_DIV_WRAPPER.parse(temp + Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)))));
}
}
if (!sizeIsEvenNumber) {
int lastIndex = pluginNames.size() - 1;
String name = pluginNames.get(lastIndex);
html.append(Html.COLUMNS_DIV_WRAPPER.parse(Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name))) + Html.COLUMN_DIV_WRAPPER.parse("")));
// html.append(Html.COLUMNS_DIV_WRAPPER.parse(Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name))) + Html.COLUMN_DIV_WRAPPER.parse("")));
}
String returnValue = html.toString();
if (returnValue.isEmpty()) {
return Html.COLUMNS_DIV_WRAPPER.parse(
Html.COLUMN_DIV_WRAPPER.parse(
Html.PLUGIN_DATA_WRAPPER.parse(
Locale.get(Msg.HTML_NO_PLUGINS).toString()
)
)
);
// return Html.COLUMNS_DIV_WRAPPER.parse(
// Html.COLUMN_DIV_WRAPPER.parse(
// Html.PLUGIN_DATA_WRAPPER.parse(
// Locale.get(Msg.HTML_NO_PLUGINS).toString()
// )
// )
// );
}
return returnValue;
}
@Deprecated // TODO Move to HtmlStructure
private static String getContent(String name, List<String> placeholders) {
StringBuilder html = new StringBuilder();
html.append(Html.HEADER.parse(name));
html.append(Html.PLUGIN_CONTAINER_START.parse());
// html.append(Html.HEADER.parse(name));
// html.append(Html.PLUGIN_CONTAINER_START.parse());
placeholders.forEach(html::append);
html.append("</div>");
return html.toString();

View File

@ -1,6 +1,6 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
import java.util.Map;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
public class WorldPieCreator {
@ -8,25 +8,27 @@ public class WorldPieCreator {
throw new IllegalStateException("Utility Class");
}
public static String createSeriesData(Map<String, Long> worldTimes) {
StringBuilder arrayBuilder = new StringBuilder("[");
int i = 0;
int size = worldTimes.size();
for (Map.Entry<String, Long> world : worldTimes.entrySet()) {
arrayBuilder.append("{name:'").append(world.getKey())
.append("',y:").append(world.getValue());
if (i == 1) {
arrayBuilder.append(", sliced: true, selected: true");
}
arrayBuilder.append("}");
if (i < size - 1) {
arrayBuilder.append(",");
}
i++;
}
arrayBuilder.append("]");
return arrayBuilder.toString();
public static String createSeriesData(WorldTimes worldTimes) {
// TODO Rewrite WorldPie
// StringBuilder arrayBuilder = new StringBuilder("[");
// int i = 0;
// int size = worldTimes.size();
// for (Map.Entry<String, Long> world : worldTimes.entrySet()) {
// arrayBuilder.append("{name:'").append(world.getKey())
// .append("',y:").append(world.getValue());
//
// if (i == 1) {
// arrayBuilder.append(", sliced: true, selected: true");
// }
//
// arrayBuilder.append("}");
// if (i < size - 1) {
// arrayBuilder.append(",");
// }
// i++;
// }
// arrayBuilder.append("]");
// return arrayBuilder.toString();
return "[]";
}
}

View File

@ -33,7 +33,7 @@ public class BStats {
addStringSettingPie("server_type", serverType);
addStringSettingPie("database_type", databaseType);
addStringSettingPie("web_protocol", plugin.getUiServer().getProtocol().toUpperCase());
addStringSettingPie("web_protocol", plugin.getWebServer().getProtocol().toUpperCase());
}
private void addEnabledDisabledPie(String id, boolean setting) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -216,8 +216,8 @@ public class DatabaseTest {
saveUserOne();
ActionsTable actionsTable = db.getActionsTable();
Action save = new Action(234567890L, Actions.REGISTERED, "Additional Info");
Action expected = new Action(234567890L, Actions.REGISTERED, "Additional Info", 1);
Action save = new Action(234567890L, Actions.FIRST_SESSION, "Additional Info");
Action expected = new Action(234567890L, Actions.FIRST_SESSION, "Additional Info", 1);
actionsTable.insertAction(uuid, save);
@ -508,7 +508,7 @@ public class DatabaseTest {
sessionsTable.saveSession(uuid, session);
nicknamesTable.saveUserName(uuid, "TestNick");
ipsTable.saveIP(uuid, "1.2.3.4", "TestLoc");
actionsTable.insertAction(uuid, new Action(1324L, Actions.REGISTERED, "Add"));
actionsTable.insertAction(uuid, new Action(1324L, Actions.FIRST_SESSION, "Add"));
assertTrue(usersTable.isRegistered(uuid));
@ -545,7 +545,7 @@ public class DatabaseTest {
sessionsTable.saveSession(uuid, session);
nicknamesTable.saveUserName(uuid, "TestNick");
ipsTable.saveIP(uuid, "1.2.3.4", "TestLoc");
actionsTable.insertAction(uuid, new Action(1324L, Actions.REGISTERED, "Add"));
actionsTable.insertAction(uuid, new Action(1324L, Actions.FIRST_SESSION, "Add"));
assertTrue(usersTable.isRegistered(uuid));