Bugfixes, Format fixes, Some Javadocs.

Following bugs have been fixed:
- Changed command links to say "Click me"
- Concurrent modification exception: Cachehandler 83, Cachehandler 208
- GMTimes on analysis page still shows 0 but graph works
- Page has to be refreshed multiple times to view (Faulty response)
- Data not saved to db on login
- Command usages upside down
- New Players set to 0 too easily (Wrong data was fetched)

Known bugs:
- Graph is wrong way around
- Graph is written to points with no data present
- (Player activity graph data might not be properly saved)
-> Graph uses players from a single point and draws a line
- Demographics data is not saved properly/detected

Other:
- (MySQL not tested)
- PlanLite features
This commit is contained in:
Rsl1122 2017-01-14 21:18:39 +02:00
parent f9df236c59
commit 3ab14a6dd5
43 changed files with 365 additions and 250 deletions

View File

@ -1,82 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.djrapitops</groupId>
<artifactId>Plan</artifactId>
<version>2.0.0</version>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<defaultGoal>clean package install</defaultGoal>
<resources>
<resource>
<targetPath>.</targetPath>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>*.yml</include>
<include>*.html</include>
</includes>
</resource>
</resources>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<includes>
<include>org.jfree:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.jfree</pattern>
<shadedPattern>com.djrapitops.plan.jfree</shadedPattern>
</relocation>
</relocations>
<minimizeJar>false</minimizeJar>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>plan.lite</artifactId>
<version>1.6.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<modelVersion>4.0.0</modelVersion>
<groupId>com.djrapitops</groupId>
<artifactId>Plan</artifactId>
<version>2.0.0</version>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<defaultGoal>clean package install</defaultGoal>
<resources>
<resource>
<targetPath>.</targetPath>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>*.yml</include>
<include>*.html</include>
</includes>
</resource>
</resources>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<includes>
<include>org.jfree:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.jfree</pattern>
<shadedPattern>com.djrapitops.plan.jfree</shadedPattern>
</relocation>
</relocations>
<minimizeJar>false</minimizeJar>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>plan.lite</artifactId>
<version>1.6.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>

View File

@ -71,7 +71,7 @@
</descriptorRefs>
</configuration>
</plugin>
<!-- <plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>

View File

@ -10,19 +10,19 @@ public enum Phrase {
DATABASE_TYPE_DOES_NOT_EXIST("That database type doesn't exist."),
DATABASE_FAILURE_DISABLE("Database initialization has failed, disabling Plan."),
PLANLITE_REG_HOOK("Registered additional hook, passed on to PlanLite: "),
USERNAME_NOT_VALID(ChatColor.RED+"This Player doesn't exist."),
USERNAME_NOT_SEEN(ChatColor.RED+"This Player has not played on this server."),
USERNAME_NOT_KNOWN(ChatColor.RED+"Player not found from the database."),
USERNAME_NOT_VALID(ChatColor.RED + "This Player doesn't exist."),
USERNAME_NOT_SEEN(ChatColor.RED + "This Player has not played on this server."),
USERNAME_NOT_KNOWN(ChatColor.RED + "Player not found from the database."),
COLOR_MAIN(ChatColor.DARK_GREEN),
COLOR_SEC(ChatColor.GRAY),
COLOR_TER(ChatColor.WHITE),
ARROWS_RIGHT("»"),
BALL(""),
ERROR_PLANLITE("PlanLite not found, if you're have plugins using PlanAPI v1.6.0 download PlanLite."),
ERROR_NO_USERNAME("INSPECT-GETNAME\nNo username given, returned empty username.\n"),
COMMAND_SENDER_NOT_PLAYER(ChatColor.RED + "[Plan] This command can be only used as a player."),
COMMAND_REQUIRES_ARGUMENTS(ChatColor.RED + "[Plan] Command requires arguments."),
COMMAND_REQUIRES_ARGUMENTS_ONE(ChatColor.RED + "[Plan] Command requires one argument."),
ERROR_NO_USERNAME("INSPECT-GETNAME\nNo username given, returned empty username.\n"),
COMMAND_SENDER_NOT_PLAYER(ChatColor.RED + "[Plan] This command can be only used as a player."),
COMMAND_REQUIRES_ARGUMENTS(ChatColor.RED + "[Plan] Command requires arguments."),
COMMAND_REQUIRES_ARGUMENTS_ONE(ChatColor.RED + "[Plan] Command requires one argument."),
COMMAND_NO_PERMISSION(ChatColor.RED + "[Plan] You do not have the required permmission.");
private final String text;

View File

@ -11,7 +11,7 @@ import com.djrapitops.plan.database.databases.SQLiteDB;
import com.djrapitops.plan.data.cache.DataCacheHandler;
import com.djrapitops.plan.data.cache.InspectCacheHandler;
import com.djrapitops.plan.data.listeners.*;
import com.djrapitops.plan.ui.WebSocketServer;
import main.java.com.djrapitops.plan.ui.webserver.WebSocketServer;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
@ -92,7 +92,7 @@ public class Plan extends JavaPlugin {
uiServer.initServer();
log("Player Analytics Enabled.");
if (getConfig().getBoolean("Settings.Cache.AnalysisCache.RefreshAnalysisCacheOnEnable")) {
log("Analysis | Boot analysis in 30 seconds..");
(new BukkitRunnable() {

View File

@ -19,9 +19,9 @@ public class PlanLiteHook {
/**
* Class Constructor.
*
*
* Attempts to hook to PlanLite, if not present logs error.
*
*
* @param plugin
*/
public PlanLiteHook(Plan plugin) {
@ -33,7 +33,7 @@ public class PlanLiteHook {
}
planLiteApi = planLite.getAPI();
} catch (Exception e) {
}
}
@ -63,7 +63,7 @@ public class PlanLiteHook {
public boolean getVisibleOnTime() {
return planLiteApi.getVisibleOnTime();
}
@Deprecated
public boolean getVisibleFactions() {
return planLiteApi.getVisibleFactions();

View File

@ -1,8 +1,8 @@
package com.djrapitops.plan.api;
/**
* Old API Part.
*
* @author Rsl1122
* @deprecated Moved to PlanLite plugin
*/

View File

@ -1,4 +1,3 @@
package com.djrapitops.plan.api;
public enum Gender {

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
/**
* Old API Part
*
* @author Rsl1122
* @deprecated
*/
@ -11,7 +12,7 @@ import java.util.HashMap;
public interface Hook {
/**
*
*
* @param player
* @return
* @throws Exception

View File

@ -1,7 +1,6 @@
package com.djrapitops.plan.command;
public enum CommandType
{
public enum CommandType {
CONSOLE,
PLAYER,
CONSOLE_WITH_ARGUMENTS

View File

@ -22,7 +22,7 @@ public abstract class SubCommand {
public String getArguments() {
return arguments;
}
public String getFirstName() {
return name.split(",")[0];
}

View File

@ -5,7 +5,6 @@ import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.CommandType;
import com.djrapitops.plan.command.SubCommand;
import com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import com.djrapitops.plan.utilities.FormatUtils;
import java.util.Date;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -15,23 +14,44 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
/**
*
* @author Rsl1122
*/
public class AnalyzeCommand extends SubCommand {
private Plan plugin;
private AnalysisCacheHandler analysisCache;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public AnalyzeCommand(Plan plugin) {
super("analyze", "plan.analyze", "View the Server Analysis", CommandType.CONSOLE, "");
this.plugin = plugin;
analysisCache = plugin.getAnalysisCache();
}
/**
* Subcommand analyze.
*
* Updates AnalysisCache if last refresh was over 60 seconds ago and sends
* player the link that views cache.
*
* @param sender
* @param cmd
* @param commandLabel
* @param args
* @return true in all cases.
*/
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
Date refresh = new Date();
if (!analysisCache.isCached()) {
analysisCache.updateCache();
} else if (new Date().getTime() - analysisCache.getData().getRefreshDate() > 60 * 5) {
} else if (new Date().getTime() - analysisCache.getData().getRefreshDate() > 60) {
analysisCache.updateCache();
}
ChatColor oColor = Phrase.COLOR_MAIN.color();
@ -60,7 +80,7 @@ public class AnalyzeCommand extends SubCommand {
Player player = (Player) sender;
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw " + player.getName() + " [\"\",{\"text\":\" Analysis Results\",\"underlined\":true,"
"tellraw " + player.getName() + " [\"\",{\"text\":\"Click Me\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + url + "\"}}]");
}
// Footer

View File

@ -46,7 +46,7 @@ public class HelpCommand extends SubCommand {
continue;
}
sender.sendMessage(tColor + " " + Phrase.BALL.toString() + oColor
sender.sendMessage(tColor + " " + Phrase.BALL.toString() + oColor
+ " /plan " + command.getFirstName() + command.getArguments() + tColor + " - " + command.getUsage());
}
// Footer

View File

@ -24,11 +24,11 @@ public class InfoCommand extends SubCommand {
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
String[] messages = {
hColor + Phrase.ARROWS_RIGHT.toString()+oColor+"Player Analytics - Info",
tColor + " " + Phrase.BALL.toString() +oColor+"Version: "+tColor+plugin.getDescription().getVersion(),
tColor + " " + Phrase.BALL.toString() +tColor+MiscUtils.checkVersion(),
hColor + Phrase.ARROWS_RIGHT.toString() + oColor + "Player Analytics - Info",
tColor + " " + Phrase.BALL.toString() + oColor + "Version: " + tColor + plugin.getDescription().getVersion(),
tColor + " " + Phrase.BALL.toString() + tColor + MiscUtils.checkVersion(),
hColor + Phrase.ARROWS_RIGHT.toString()
};
sender.sendMessage(messages);

View File

@ -10,7 +10,6 @@ import java.util.Date;
import com.djrapitops.plan.data.cache.InspectCacheHandler;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.MiscUtils;
import static com.google.common.base.Predicates.instanceOf;
import java.util.UUID;
import org.bukkit.Bukkit;
@ -23,11 +22,20 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
/**
*
* @author Rsl1122
*/
public class InspectCommand extends SubCommand {
private Plan plugin;
private InspectCacheHandler inspectCache;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public InspectCommand(Plan plugin) {
super("inspect", "plan.inspect", "Inspect Player's Data", CommandType.CONSOLE_WITH_ARGUMENTS, "<player>");
@ -35,6 +43,19 @@ public class InspectCommand extends SubCommand {
inspectCache = plugin.getInspectCache();
}
/**
* Subcommand inspect.
*
* Adds player's data from DataCache/DB to the InspectCache for amount of
* time specified in the config, and clears the data from Cache with a timer
* task.
*
* @param sender
* @param cmd
* @param commandLabel
* @param args Player's name or nothing - if empty sender's name is used.
* @return true in all cases.
*/
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
String playerName = MiscUtils.getPlayerDisplayname(args, sender);
@ -69,7 +90,11 @@ public class InspectCommand extends SubCommand {
final boolean useAlternativeIP = config.getBoolean("Settings.WebServer.ShowAlternativeServerIP");
final int port = config.getInt("Settings.WebServer.Port");
final String alternativeIP = config.getString("Settings.WebServer.AlternativeIP").replaceAll("%port%", "" + port);
final int available = config.getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
int configValue = config.getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
if (configValue <= 0) {
configValue = 4;
}
final int available = configValue;
(new BukkitRunnable() {
@Override
public void run() {
@ -90,7 +115,7 @@ public class InspectCommand extends SubCommand {
Player player = (Player) sender;
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw " + player.getName() + " [\"\",{\"text\":\" Inspect Results\",\"underlined\":true,"
"tellraw " + player.getName() + " [\"\",{\"text\":\"Click Me\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + url + "\"}}]");
}

View File

@ -23,8 +23,8 @@ public class ReloadCommand extends SubCommand {
plugin.reloadConfig();
plugin.getHandler().saveCachedData();
plugin.hookPlanLite();
sender.sendMessage(ChatColor.GREEN+"[Plan] Reload complete.");
sender.sendMessage(ChatColor.GREEN + "[Plan] Reload complete.");
return true;
}

View File

@ -18,17 +18,38 @@ import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
/**
*
* @author Rsl1122
*/
public class SearchCommand extends SubCommand {
private final Plan plugin;
private InspectCacheHandler inspectCache;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public SearchCommand(Plan plugin) {
super("search", "plan.search", "Search for player", CommandType.CONSOLE_WITH_ARGUMENTS, "<Part of Playername");
this.plugin = plugin;
inspectCache = plugin.getInspectCache();
}
/**
* Subcommand search.
*
* Searches database for matching playernames and caches matching PlayerData
* to InspectCache. Shows all links to matching players data.
*
* @param sender
* @param cmd
* @param commandLabel
* @param args Part of a Players name
* @return true in all cases.
*/
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (args.length != 1) {
@ -53,7 +74,11 @@ public class SearchCommand extends SubCommand {
final boolean useAlternativeIP = config.getBoolean("Settings.WebServer.ShowAlternativeServerIP");
final int port = config.getInt("Settings.WebServer.Port");
final String alternativeIP = config.getString("Settings.WebServer.AlternativeIP").replaceAll("%port%", "" + port);
final int available = config.getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
int configValue = config.getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
if (configValue <= 0) {
configValue = 4;
}
final int available = configValue;
// Header
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics - Search results for: " + args[0]);
@ -79,8 +104,8 @@ public class SearchCommand extends SubCommand {
Player player = (Player) sender;
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "+player.getName()+ " [\"\",{\"text\":\" Search Result\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\""+url+"\"}}]");
"tellraw " + player.getName() + " [\"\",{\"text\":\"Click Me\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + url + "\"}}]");
}
}
}

View File

@ -36,7 +36,6 @@ public class AnalysisData {
}
// Getters and setters v---------------------------------v
public String getPlayersChartImgHtmlMonth() {
return playersChartImgHtmlMonth;
}
@ -59,8 +58,8 @@ public class AnalysisData {
public void setPlayersChartImgHtmlDay(String playersChartImgHtmlDay) {
this.playersChartImgHtmlDay = playersChartImgHtmlDay;
}
}
public String getTop50CommandsListHtml() {
return top50CommandsListHtml;
}
@ -68,7 +67,7 @@ public class AnalysisData {
public void setTop50CommandsListHtml(String top50CommandsListHtml) {
this.top50CommandsListHtml = top50CommandsListHtml;
}
public int getBanned() {
return banned;
}
@ -133,8 +132,6 @@ public class AnalysisData {
this.gm3Perc = gm3Perc;
}
public int getTotalPlayers() {
return totalPlayers;
}
@ -167,7 +164,6 @@ public class AnalysisData {
return gmTimesChartImgHtml;
}
public String getActivityChartImgHtml() {
return activityChartImgHtml;
}
@ -196,7 +192,6 @@ public class AnalysisData {
this.gmTimesChartImgHtml = gmTimesChartImgHtml;
}
public void setActivityChartImgHtml(String activityChartImgHtml) {
this.activityChartImgHtml = activityChartImgHtml;
}

View File

@ -1,9 +1,9 @@
package com.djrapitops.plan.data;
import com.djrapitops.plan.api.Gender;
public class DemographicsData {
private int age;
private Gender gender;
private String geoLocation;
@ -13,13 +13,12 @@ public class DemographicsData {
this.gender = gender;
this.geoLocation = geoLocation;
}
public DemographicsData() {
this(-1, Gender.UNKNOWN, "Not_known");
}
// Getters
public int getAge() {
return age;
}
@ -31,9 +30,8 @@ public class DemographicsData {
public String getGeoLocation() {
return geoLocation;
}
// Setters
// Setters
public void setAge(int age) {
this.age = age;
}
@ -45,6 +43,5 @@ public class DemographicsData {
public void setGeoLocation(String geoLocation) {
this.geoLocation = geoLocation;
}
}

View File

@ -1,10 +1,10 @@
package com.djrapitops.plan.data;
import java.util.HashMap;
import org.bukkit.Bukkit;
public class ServerData {
private final HashMap<String, Integer> commandUsage;
private int playersOnline;
private int newPlayers;
@ -14,7 +14,7 @@ public class ServerData {
this.playersOnline = Bukkit.getServer().getOnlinePlayers().size();
this.newPlayers = newPlayers;
}
public void playerJoined(boolean newPlayer) {
updatePlayerCount();
if (newPlayer) {
@ -25,16 +25,16 @@ public class ServerData {
public void updatePlayerCount() {
playersOnline = Bukkit.getServer().getOnlinePlayers().size();
}
public void playerLeft() {
updatePlayerCount();
}
public void commandRegistered(String command) {
if (!commandUsage.containsKey(command)) {
commandUsage.put(command, 0);
}
commandUsage.put(command, commandUsage.get(command)+1);
commandUsage.put(command, commandUsage.get(command) + 1);
}
public HashMap<String, Integer> getCommandUsage() {
@ -47,5 +47,5 @@ public class ServerData {
public int getNewPlayers() {
return newPlayers;
}
}
}

View File

@ -35,7 +35,7 @@ public class UserData {
private boolean isOp;
private boolean isBanned;
private DemographicsData demData;
private String name;
public UserData(Player player, DemographicsData demData, Database db) {
@ -106,7 +106,7 @@ public class UserData {
if (!locations.isEmpty()) {
location = locations.get(locations.size() - 1);
}
*/
*/
}
public void addNickname(String nick) {
@ -147,7 +147,7 @@ public class UserData {
public UUID getUuid() {
return uuid;
}
@Deprecated
public Location getLocation() {
return location;

View File

@ -1,4 +1,3 @@
package com.djrapitops.plan.data.cache;
import com.djrapitops.plan.Plan;
@ -10,6 +9,7 @@ import com.djrapitops.plan.utilities.Analysis;
* @author Rsl1122
*/
public class AnalysisCacheHandler {
private Plan plugin;
private AnalysisData cache;
private Analysis analysis;
@ -18,16 +18,16 @@ public class AnalysisCacheHandler {
this.plugin = plugin;
analysis = new Analysis(plugin);
}
public void updateCache() {
cache = null;
analysis.analyze(this);
}
public void cache(AnalysisData data) {
cache = data;
}
public AnalysisData getData() {
return cache;
}

View File

@ -5,10 +5,10 @@ import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.data.*;
import com.djrapitops.plan.data.handlers.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import static org.bukkit.Bukkit.getPlayer;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import static org.bukkit.Bukkit.getPlayer;
@ -205,8 +205,9 @@ public class DataCacheHandler {
*/
public void clearCache() {
Set<UUID> uuidSet = dataCache.keySet();
for (UUID uuid : uuidSet) {
clearFromCache(uuid);
Iterator<UUID> uuidIterator = uuidSet.iterator();
while (uuidIterator.hasNext()) {
clearFromCache(uuidIterator.next());
}
}

View File

@ -73,8 +73,7 @@ public class ActivityHandler {
/**
* Updates UserData about activity related things on Logout.
*
* Saves PlayTime, Set's LastPlayed
* value to long matching current Date
* Saves PlayTime, Set's LastPlayed value to long matching current Date
*
* @param event QuitEvent from Listener
* @param data UserData matching the Player

View File

@ -16,6 +16,7 @@ public class BasicInfoHandler {
/**
* Class Constructor
*
* @param plugin Current instance of Plan
* @param h Current instance of DataCacheHandler
*/
@ -25,6 +26,7 @@ public class BasicInfoHandler {
/**
* Adds new nicknames and IPs to UserData
*
* @param event JoinEvent to get the Player
* @param data UserData matching the Player
*/
@ -36,6 +38,7 @@ public class BasicInfoHandler {
/**
* Adds new nicknames and IPs to UserData in case of /reload
*
* @param player A player that is online when /reload is run
* @param data UserData matching the Player
*/

View File

@ -20,6 +20,7 @@ public class LocationHandler {
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
* @param h Current instance of DataCacheHandler
*/
@ -29,6 +30,7 @@ public class LocationHandler {
/**
* Adds location to the UserData if it is not being saved.
*
* @param uuid UUID of the matching Player
* @param loc Location from the MoveEvent listener.
*/
@ -43,6 +45,7 @@ public class LocationHandler {
/**
* Adds multiple locaitons to the UserData.
*
* @param uuid UUID of the matching Player
* @param locs The Locations that are added.
*/
@ -52,8 +55,9 @@ public class LocationHandler {
/**
* Handles QuitEvent by updating BedLocation.
*
*
* Uses OfflinePlayer to prevent null bedlocation.
*
* @param event QuitEvent from Listener.
* @param data UserData matching Player.
*/

View File

@ -1,15 +1,15 @@
package com.djrapitops.plan.data.handlers;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanLiteHook;
public class PlanLiteHandler {
private Plan plugin;
private PlanLiteHook hook;
public PlanLiteHandler(Plan plugin) {
this.plugin = plugin;
hook = plugin.getPlanLiteHook();
}
}
}

View File

@ -1,27 +1,27 @@
package com.djrapitops.plan.data.handlers;
import com.djrapitops.plan.data.ServerData;
public class ServerDataHandler {
private ServerData serverData;
public ServerDataHandler(ServerData serverData) {
this.serverData = serverData;
}
public void handleLogin(boolean newPlayer) {
serverData.playerJoined(newPlayer);
}
public void handleLogout() {
serverData.playerLeft();
}
public void handleKick() {
handleLogout();
}
public void handleCommand(String command) {
serverData.commandRegistered(command);
}

View File

@ -22,7 +22,7 @@ public class PlanChatListener implements Listener {
/**
* Class Constructor.
*
*
* @param plugin Current instance of Plan
*/
public PlanChatListener(Plan plugin) {
@ -33,6 +33,7 @@ public class PlanChatListener implements Listener {
/**
* ChatEvent listener.
*
* @param event Fired Event
*/
@EventHandler(priority = EventPriority.MONITOR)
@ -41,9 +42,8 @@ public class PlanChatListener implements Listener {
return;
}
Player p = event.getPlayer();
UserData data = handler.getCurrentData(p.getUniqueId());
UserData data = handler.getCurrentData(p.getUniqueId());
data.addNickname(p.getDisplayName());
demographicsHandler.handleChatEvent(event, data);
}
}

View File

@ -28,8 +28,7 @@ public class PlanGamemodeChangeListener implements Listener {
return;
}
Player p = event.getPlayer();
UserData data = handler.getCurrentData(p.getUniqueId());
UserData data = handler.getCurrentData(p.getUniqueId());
gmTimesH.handleChangeEvent(event, data);
}
}

View File

@ -12,6 +12,8 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
import org.bukkit.scheduler.BukkitRunnable;
/**
*
@ -19,6 +21,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
*/
public class PlanPlayerListener implements Listener {
private final Plan plugin;
private final DataCacheHandler handler;
private final ActivityHandler activityH;
private final BasicInfoHandler basicInfoH;
@ -37,6 +40,7 @@ public class PlanPlayerListener implements Listener {
* @param plugin Current instance of Plan
*/
public PlanPlayerListener(Plan plugin) {
this.plugin = plugin;
handler = plugin.getHandler();
activityH = handler.getActivityHandler();
basicInfoH = handler.getBasicInfoHandler();
@ -69,7 +73,12 @@ public class PlanPlayerListener implements Listener {
basicInfoH.handleLogin(event, data);
gmTimesH.handleLogin(event, data);
demographicH.handleLogin(event, data);
handler.saveCachedData(uuid);
(new BukkitRunnable() {
@Override
public void run() {
handler.saveCachedData(uuid);
}
}).runTaskLater(plugin, 15 * 20);
}
/**

View File

@ -22,6 +22,7 @@ public class PlanPlayerMoveListener implements Listener {
/**
* Class Consturctor.
*
* @param plugin Current instance of Plan
*/
public PlanPlayerMoveListener(Plan plugin) {
@ -32,9 +33,9 @@ public class PlanPlayerMoveListener implements Listener {
/**
* MoveEventListener.
*
*
* Adds location to UserData if the player has moved a block.
*
*
* @param event Event that is fired
*/
@EventHandler(priority = EventPriority.MONITOR)
@ -44,8 +45,8 @@ public class PlanPlayerMoveListener implements Listener {
}
Player p = event.getPlayer();
Location from = event.getFrom();
Location to = event.getTo();
if (from.getBlockX() == to.getBlockX() && from.getBlockZ()== to.getBlockZ()) {
Location to = event.getTo();
if (from.getBlockX() == to.getBlockX() && from.getBlockZ() == to.getBlockZ()) {
return;
}
Location savedLocation = to.getBlock().getLocation();

View File

@ -21,7 +21,7 @@ public abstract class Database {
}
public abstract UserData getUserData(UUID uuid);
public abstract void saveUserData(UUID uuid, UserData data);
public abstract boolean wasSeenBefore(UUID uuid);

View File

@ -144,7 +144,6 @@ public abstract class SQLDB extends Database {
public boolean init() {
super.init();
return checkConnection();
}
public boolean checkConnection() {
@ -230,10 +229,8 @@ public abstract class SQLDB extends Database {
}
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
@ -344,7 +341,7 @@ public abstract class SQLDB extends Database {
set.close();
statement.close();
String userId = "" + getUserId(uuid.toString());
/* Locations Removed from Build 2.0.0 for performance reasons.
statement = connection.prepareStatement("SELECT * FROM " + locationName + " WHERE UPPER(" + locationColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
@ -420,7 +417,7 @@ public abstract class SQLDB extends Database {
HashMap<Long, ServerData> rawServerData = new HashMap<>();
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + serverdataName
+ " ORDER BY " + serverdataColumnDate + " ASC");
+ " ORDER BY " + serverdataColumnDate + " DESC");
ResultSet set = statement.executeQuery();
while (set.next()) {
@ -443,7 +440,7 @@ public abstract class SQLDB extends Database {
Date startOfToday = new Date(now.getTime() - (now.getTime() % 86400000));
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + serverdataName
+ " ORDER BY " + serverdataColumnDate + " ASC LIMIT 1");
+ " ORDER BY " + serverdataColumnDate + " DESC LIMIT 1");
ResultSet set = statement.executeQuery();
while (set.next()) {

View File

@ -1,4 +1,3 @@
package com.djrapitops.plan.ui;
import com.djrapitops.plan.Plan;
@ -15,6 +14,7 @@ import java.util.UUID;
* @author Rsl1122
*/
public class DataRequestHandler {
private Plan plugin;
private InspectCacheHandler inspectCache;
private AnalysisCacheHandler analysisCache;
@ -41,11 +41,11 @@ public class DataRequestHandler {
html += line + "\r\n";
}
HashMap<String, String> replaceMap = AnalysisUtils.getInspectReplaceRules(data);
for (String key : replaceMap.keySet()) {
html = html.replaceAll(key, replaceMap.get(key));
}
return html;
}
@ -60,11 +60,11 @@ public class DataRequestHandler {
html += line + "\r\n";
}
HashMap<String, String> replaceMap = AnalysisUtils.getAnalysisReplaceRules(analysisCache.getData());
for (String key : replaceMap.keySet()) {
html = html.replaceAll(key, replaceMap.get(key));
}
return html;
}

View File

@ -11,6 +11,14 @@ import com.googlecode.charts4j.Slice;
*/
public class ActivityPieChartCreator {
/**
* Creates a image link to Activity Chart.
*
* @param totalBanned Number of Banned Players
* @param active Number of Active Players
* @param inactive Number of Inactive Players
* @return Url to Image link.
*/
public static String createChart(int totalBanned, int active, int inactive) {
int total = totalBanned + active + inactive;
@ -35,5 +43,4 @@ public class ActivityPieChartCreator {
String refURL = refChart.toURLString();
return refURL;
}
}

View File

@ -13,6 +13,15 @@ import org.bukkit.GameMode;
*/
public class GMTimesPieChartCreator {
/**
* Creates a link to New image of the Gamemode usage chart without total.
*
* Calculated total is not required.
*
* @param gmTimes Map with all 4 Gamemodes and responding times spent in
* them
* @return Url of charts4j image link.
*/
public static String createChart(HashMap<GameMode, Long> gmTimes) {
long total = gmTimes.get(GameMode.SURVIVAL) + gmTimes.get(GameMode.CREATIVE)
+ gmTimes.get(GameMode.ADVENTURE) + gmTimes.get(GameMode.SPECTATOR);
@ -20,6 +29,14 @@ public class GMTimesPieChartCreator {
return createChart(gmTimes, total);
}
/**
* Creates a link to New image of the Gamemode usage chart.
*
* @param gmTimes Map with all 4 Gamemodes and responding times spent in
* them
* @param total Time spent in all 4 gamemodes.
* @return Url of charts4j image link.
*/
public static String createChart(HashMap<GameMode, Long> gmTimes, long total) {
long gmZero = gmTimes.get(GameMode.SURVIVAL);
long gmOne = gmTimes.get(GameMode.CREATIVE);

View File

@ -47,7 +47,7 @@ public class PlayerActivityGraphCreator {
Double scaledPlayerValue = (serverData.getPlayersOnline() * 1.0 / maxPlayers) * 100;
Double scaledNewPValue = (serverData.getNewPlayers() * 1.0 / maxPlayers) * 100;
xListDate.add(scaledDateValue);
pYList.add(scaledPlayerValue);
nYList.add(scaledNewPValue);
}

View File

@ -17,11 +17,22 @@ public class Response {
private DataRequestHandler requestHandler;
/**
* Class Constructor.
*
* @param output Website outputstream to write the response to.
* @param h Current Instance of DataRequestHandler
*/
public Response(OutputStream output, DataRequestHandler h) {
this.output = output;
requestHandler = h;
}
/**
* Wrties the HTML to the Outputstream according to the requested page.
*
* @throws IOException
*/
public void sendStaticResource() throws IOException {
try {
if (request == null) {
@ -55,18 +66,18 @@ public class Response {
}
if (requestHandler.checkIfCached(uuid)) {
String dataHtml = requestHandler.getDataHtml(uuid);
String htmlDef = "HTTP/1.1 Inspect\r\n"
String htmlDef = "HTTP/1.1 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: " + dataHtml.length() + "\r\n"
+ "\r\n";
output.write((htmlDef+dataHtml).getBytes());
output.write((htmlDef + dataHtml).getBytes());
return;
}
}
} else if (command.equals("server")) {
if (requestHandler.checkIfAnalysisIsCached()) {
String analysisHtml = requestHandler.getAnalysisHtml();
String htmlDef = "HTTP/1.1 Analysis\r\n"
String htmlDef = "HTTP/1.1 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: " + analysisHtml.length() + "\r\n"
+ "\r\n";
@ -86,6 +97,11 @@ public class Response {
}
}
/**
* Sets the HTML Request to get response for.
*
* @param request Request.
*/
public void setRequest(Request request) {
this.request = request;
}

View File

@ -1,8 +1,9 @@
package com.djrapitops.plan.ui;
package main.java.com.djrapitops.plan.ui.webserver;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import com.djrapitops.plan.data.cache.InspectCacheHandler;
import com.djrapitops.plan.ui.DataRequestHandler;
import com.djrapitops.plan.ui.webserver.Request;
import com.djrapitops.plan.ui.webserver.Response;
import java.io.IOException;
@ -30,6 +31,13 @@ public class WebSocketServer {
private boolean shutdown;
/**
* Class Constructor.
*
* Initializes DataRequestHandler
*
* @param plugin Current instance of Plan
*/
public WebSocketServer(Plan plugin) {
this.plugin = plugin;
this.inspectHandler = plugin.getInspectCache();
@ -38,6 +46,9 @@ public class WebSocketServer {
dataReqHandler = new DataRequestHandler(plugin);
}
/**
* Starts up the Webserver in a Asyncronous thread.
*/
public void initServer() {
//Server is already enabled stop code
if (ENABLED) {
@ -78,12 +89,15 @@ public class WebSocketServer {
ENABLED = true;
plugin.log("Webserver running on PORT "+server.getLocalPort());
plugin.log("Webserver running on PORT " + server.getLocalPort());
} catch (Exception e) {
ENABLED = false;
}
}
/**
* Shuts down the server - Async thread is closed with shutdown boolean.
*/
public void stop() {
plugin.log("Shutting down Webserver..");
shutdown = true;

View File

@ -5,6 +5,7 @@ import com.djrapitops.plan.data.AnalysisData;
import com.djrapitops.plan.data.ServerData;
import com.djrapitops.plan.data.UserData;
import com.djrapitops.plan.ui.graphs.GMTimesPieChartCreator;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -74,10 +75,10 @@ public class AnalysisUtils {
HashMap<String, String> replaceMap = new HashMap<>();
replaceMap.put("%activitypiechart%", data.getActivityChartImgHtml());
replaceMap.put("%gmpiechart%", data.getGmTimesChartImgHtml());
replaceMap.put("%gm0%", (int) data.getGm0Perc() * 100 + "%");
replaceMap.put("%gm1%", (int) data.getGm1Perc() * 100 + "%");
replaceMap.put("%gm2%", (int) data.getGm2Perc() * 100 + "%");
replaceMap.put("%gm3%", (int) data.getGm3Perc() * 100 + "%");
replaceMap.put("%gm0%", (int) (data.getGm0Perc() * 100) + "%");
replaceMap.put("%gm1%", (int) (data.getGm1Perc() * 100) + "%");
replaceMap.put("%gm2%", (int) (data.getGm2Perc() * 100) + "%");
replaceMap.put("%gm3%", (int) (data.getGm3Perc() * 100) + "%");
replaceMap.put("%active%", "" + data.getActive());
replaceMap.put("%banned%", "" + data.getBanned());
replaceMap.put("%inactive%", "" + data.getInactive());
@ -121,6 +122,7 @@ public class AnalysisUtils {
html = "<p>Error Calcuclating Command usages</p>";
return html;
}
Collections.reverse(sorted);
int i = 1;
for (String[] values : sorted) {
if (i >= 50) {

View File

@ -1,4 +1,3 @@
package com.djrapitops.plan.utilities;
import java.util.ArrayList;
@ -121,7 +120,7 @@ public class FormatUtils {
}
public static String formatLocation(Location loc) {
return "x "+loc.getBlockX()+" z " + loc.getBlockZ() +" in "+loc.getWorld();
return "x " + loc.getBlockX() + " z " + loc.getBlockZ() + " in " + loc.getWorld();
}
}

View File

@ -34,100 +34,87 @@ import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.Callable;
public class UUIDFetcher implements Callable<Map<String, UUID>>
{
public class UUIDFetcher implements Callable<Map<String, UUID>> {
private static final double PROFILES_PER_REQUEST = 100;
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
private final JSONParser jsonParser = new JSONParser();
private final List<String> names;
private final boolean rateLimiting;
public UUIDFetcher( List<String> names, boolean rateLimiting )
{
this.names = ImmutableList.copyOf( names );
public UUIDFetcher(List<String> names, boolean rateLimiting) {
this.names = ImmutableList.copyOf(names);
this.rateLimiting = rateLimiting;
}
public UUIDFetcher( List<String> names )
{
this( names, true );
public UUIDFetcher(List<String> names) {
this(names, true);
}
public Map<String, UUID> call() throws Exception
{
public Map<String, UUID> call() throws Exception {
Map<String, UUID> uuidMap = new HashMap<String, UUID>();
int requests = ( int ) Math.ceil( names.size() / PROFILES_PER_REQUEST );
int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST);
for( int i = 0; i < requests; i++ )
{
for (int i = 0; i < requests; i++) {
HttpURLConnection connection = createConnection();
String body = JSONArray.toJSONString( names.subList( i * 100, Math.min( ( i + 1 ) * 100, names.size() ) ) );
writeBody( connection, body );
JSONArray array = ( JSONArray ) jsonParser.parse( new InputStreamReader( connection.getInputStream() ) );
for( Object profile : array )
{
JSONObject jsonProfile = ( JSONObject ) profile;
String id = ( String ) jsonProfile.get( "id" );
String name = ( String ) jsonProfile.get( "name" );
UUID uuid = UUIDFetcher.getUUID( id );
uuidMap.put( name, uuid );
String body = JSONArray.toJSONString(names.subList(i * 100, Math.min((i + 1) * 100, names.size())));
writeBody(connection, body);
JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream()));
for (Object profile : array) {
JSONObject jsonProfile = (JSONObject) profile;
String id = (String) jsonProfile.get("id");
String name = (String) jsonProfile.get("name");
UUID uuid = UUIDFetcher.getUUID(id);
uuidMap.put(name, uuid);
}
if( rateLimiting && i != requests - 1 )
{
Thread.sleep( 100L );
if (rateLimiting && i != requests - 1) {
Thread.sleep(100L);
}
}
return uuidMap;
}
private static void writeBody( HttpURLConnection connection, String body ) throws Exception
{
private static void writeBody(HttpURLConnection connection, String body) throws Exception {
OutputStream stream = connection.getOutputStream();
stream.write( body.getBytes() );
stream.write(body.getBytes());
stream.flush();
stream.close();
}
private static HttpURLConnection createConnection() throws Exception
{
URL url = new URL( PROFILE_URL );
HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
connection.setRequestMethod( "POST" );
connection.setRequestProperty( "Content-Type", "application/json" );
connection.setUseCaches( false );
connection.setDoInput( true );
connection.setDoOutput( true );
private static HttpURLConnection createConnection() throws Exception {
URL url = new URL(PROFILE_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
return connection;
}
private static UUID getUUID( String id )
{
return UUID.fromString( id.substring( 0, 8 ) + "-" + id.substring( 8, 12 ) + "-" + id.substring( 12, 16 ) + "-" + id.substring( 16, 20 ) + "-" + id.substring( 20, 32 ) );
private static UUID getUUID(String id) {
return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32));
}
public static byte[] toBytes( UUID uuid )
{
ByteBuffer byteBuffer = ByteBuffer.wrap( new byte[16] );
byteBuffer.putLong( uuid.getMostSignificantBits() );
byteBuffer.putLong( uuid.getLeastSignificantBits() );
public static byte[] toBytes(UUID uuid) {
ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
byteBuffer.putLong(uuid.getMostSignificantBits());
byteBuffer.putLong(uuid.getLeastSignificantBits());
return byteBuffer.array();
}
public static UUID fromBytes( byte[] array )
{
if( array.length != 16 )
{
throw new IllegalArgumentException( "Illegal byte array length: " + array.length );
public static UUID fromBytes(byte[] array) {
if (array.length != 16) {
throw new IllegalArgumentException("Illegal byte array length: " + array.length);
}
ByteBuffer byteBuffer = ByteBuffer.wrap( array );
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
long mostSignificant = byteBuffer.getLong();
long leastSignificant = byteBuffer.getLong();
return new UUID( mostSignificant, leastSignificant );
return new UUID(mostSignificant, leastSignificant);
}
public static UUID getUUIDOf( String name ) throws Exception
{
return new UUIDFetcher( Arrays.asList( name ) ).call().get( name );
public static UUID getUUIDOf(String name) throws Exception {
return new UUIDFetcher(Arrays.asList(name)).call().get(name);
}
}
}

View File

@ -10,11 +10,10 @@ public class MapComparator {
public static List<String[]> sortByValue(HashMap<String, Integer> hashMap) {
List<String[]> sortedList = new ArrayList<>();
hashMap.keySet().stream().forEach((key) -> {
sortedList.add(new String[]{""+hashMap.get(key), key});
sortedList.add(new String[]{"" + hashMap.get(key), key});
});
Collections.sort(sortedList, (String[] strings, String[] otherStrings) -> strings[0].compareTo(otherStrings[0]));
return sortedList;
}
}