diff --git a/Plan/pom.xml b/Plan/pom.xml index fcf86109f..c58f516cb 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -12,10 +12,11 @@ 1.10.2-R0.1-SNAPSHOT provided + - com.djrapitops - plan.lite - 1.6.3 + com.hm + advanced.achievements + 4.1.5 provided @@ -24,6 +25,31 @@ 4.1.4 provided + + com.earth2me + essentials + 2.0.1 + provided + + + io.minimum + superbvote + 0.3.3 + provided + + + com.massivecraft + factions + 2.10.0 + provided + + + com.massivecraft + mcore + 2.10.0 + provided + + com.googlecode.charts4j charts4j diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index ca997585c..444c9bdd8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -52,14 +52,20 @@ import org.bukkit.scheduler.BukkitTask; /* TODO 2.6.0 Placeholder API -Database cleaning Play session length +- Playtime month +- Playtime week Location Analysis to view meaningful locations on Dynmap (Investigate dynmap api) Integrate PlanLite features to Plan and discontinue PlanLite +- Towny hook +- Text interface Database Cleaning of useless data -Fix any bugs that come up Sortable player table. +- Players page +- Navigation (Security req) Add -n argument for nickname search. +Location saving & getting seperately +Fix any bugs that come up */ /** * diff --git a/Plan/src/main/java/com/djrapitops/plan/api/API.java b/Plan/src/main/java/com/djrapitops/plan/api/API.java index 9ad7fc4cb..2982a8175 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/API.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/API.java @@ -1,6 +1,5 @@ package main.java.com.djrapitops.plan.api; -import com.djrapitops.planlite.UUIDFetcher; import java.util.Date; import java.util.UUID; import main.java.com.djrapitops.plan.Plan; @@ -9,6 +8,7 @@ import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.ui.DataRequestHandler; import main.java.com.djrapitops.plan.ui.webserver.WebSocketServer; import main.java.com.djrapitops.plan.utilities.FormatUtils; +import main.java.com.djrapitops.plan.utilities.UUIDFetcher; /** * @@ -108,10 +108,10 @@ public class API { public String getPlayerHtmlAsString(UUID uuid) { WebSocketServer server = plugin.getUiServer(); if (server != null) { - return server.getDataReqHandler().getDataHtml(uuid); + return server.getDataReqHandler().getInspectHtml(uuid); } DataRequestHandler reqH = new DataRequestHandler(plugin); - return reqH.getDataHtml(uuid); + return reqH.getInspectHtml(uuid); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java index 91f72d1be..8dc181d2c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java @@ -17,7 +17,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; -import static org.bukkit.Bukkit.getOfflinePlayer; /** * @@ -79,7 +78,7 @@ public class InspectCommand extends SubCommand { sender.sendMessage(Phrase.USERNAME_NOT_VALID.toString()); return true; } - OfflinePlayer p = getOfflinePlayer(uuid); + OfflinePlayer p = Bukkit.getOfflinePlayer(uuid); if (!p.hasPlayedBefore()) { sender.sendMessage(Phrase.USERNAME_NOT_SEEN.toString()); return true; diff --git a/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java b/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java index 3b8ef12a9..4591aeab3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java @@ -19,6 +19,7 @@ public class AnalysisData { private String top50CommandsListHtml; private String top20ActivePlayers; private String recentPlayers; + private String sortablePlayersTable; private int newPlayersMonth; private int newPlayersWeek; @@ -38,7 +39,7 @@ public class AnalysisData { private int totalPlayers; private long totalLoginTimes; private int ops; - + private long totalkills; private long totalmobkills; private long totaldeaths; @@ -49,9 +50,26 @@ public class AnalysisData { * All data has to be set with setters to avoid NPE. */ public AnalysisData() { + sortablePlayersTable = "Error: Replace rule was not set"; + gmTimesChartImgHtml = "Error: Replace rule was not set"; + playersChartImgHtmlMonth = "Error: Replace rule was not set"; + playersChartImgHtmlWeek = "Error: Replace rule was not set"; + playersChartImgHtmlDay = "Error: Replace rule was not set"; + activityChartImgHtml = "Error: Replace rule was not set"; + top50CommandsListHtml = "Error: Replace rule was not set"; + top20ActivePlayers = "Error: Replace rule was not set"; + recentPlayers = "Error: Replace rule was not set"; } // Getters and setters v---------------------------------v + public String getSortablePlayersTable() { + return sortablePlayersTable; + } + + public void setSortablePlayersTable(String sortablePlayersTable) { + this.sortablePlayersTable = sortablePlayersTable; + } + /** * @return The Amount of players who have joined only once */ diff --git a/Plan/src/main/java/com/djrapitops/plan/data/UserData.java b/Plan/src/main/java/com/djrapitops/plan/data/UserData.java index 60d7166b0..aac8f3c77 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/UserData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/UserData.java @@ -7,7 +7,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.UUID; -import main.java.com.djrapitops.plan.database.Database; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.OfflinePlayer; @@ -44,8 +43,9 @@ public class UserData { private SessionData currentSession; private List sessions; + private AdditionalData additionalData; - public UserData(Player player, DemographicsData demData, Database db) { + public UserData(Player player, DemographicsData demData) { accessing = 0; uuid = player.getUniqueId(); registered = player.getFirstPlayed(); @@ -71,9 +71,10 @@ public class UserData { sessions = new ArrayList<>(); lastNick = ""; playerKills = new ArrayList<>(); + additionalData = new AdditionalData(); } - public UserData(OfflinePlayer player, DemographicsData demData, Database db) { + public UserData(OfflinePlayer player, DemographicsData demData) { accessing = 0; uuid = player.getUniqueId(); registered = player.getFirstPlayed(); @@ -97,8 +98,13 @@ public class UserData { sessions = new ArrayList<>(); lastNick = ""; playerKills = new ArrayList<>(); + additionalData = new AdditionalData(); } + public AdditionalData getAdditionalData() { + return additionalData; + } + public void addIpAddress(InetAddress ip) { if (!ips.contains(ip)) { ips.add(ip); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/AdvancedAchievementsHook.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/AdvancedAchievementsHook.java new file mode 100644 index 000000000..5e70cfa26 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/AdvancedAchievementsHook.java @@ -0,0 +1,83 @@ +package main.java.com.djrapitops.plan.data.additional; + +import com.hm.achievement.AdvancedAchievements; +import com.hm.achievement.category.MultipleAchievements; +import com.hm.achievement.category.NormalAchievements; +import java.util.UUID; +import main.java.com.djrapitops.plan.Plan; + +/** + * + * @author Rsl1122 + */ +public class AdvancedAchievementsHook extends Hook { + + private final Plan plugin; + private AdvancedAchievements adAc; + private int totalAchievements; + + /** + * Hooks the plugin and calculates Total Achievements. + * + * @param plugin + */ + public AdvancedAchievementsHook(Plan plugin) { + super(AdvancedAchievements.class); + this.plugin = plugin; + if (isEnabled()) { + try { + totalAchievements = calcTotalAchievements(); + } catch (Exception | NoClassDefFoundError e) { + setEnabled(false); + } + } + } + + private int calcTotalAchievements() throws Exception, NoClassDefFoundError { + int total = 0; + for (NormalAchievements category : NormalAchievements.values()) { + String categoryName = category.toString(); + if (adAc.getDisabledCategorySet().contains(categoryName)) { + // Ignore this type. + continue; + } + total += adAc.getPluginConfig().getConfigurationSection(categoryName).getKeys(false).size(); + } + for (MultipleAchievements category : MultipleAchievements.values()) { + String categoryName = category.toString(); + if (adAc.getDisabledCategorySet().contains(categoryName)) { + // Ignore this type. + continue; + } + for (String item : adAc.getPluginConfig().getConfigurationSection(categoryName).getKeys(false)) { + total += adAc.getPluginConfig().getConfigurationSection(categoryName + '.' + item) + .getKeys(false).size(); + } + } + if (!adAc.getDisabledCategorySet().contains("Commands")) { + total += adAc.getPluginConfig().getConfigurationSection("Commands").getKeys(false).size(); + } + return total; + } + + /** + * Returns total number of achievements. isEnabled() should be called before + * calling this method + * + * @return Total Achievements calculated during Initialization + */ + public int getTotalAchievements() { + return totalAchievements; + } + + /** + * Returns achievement number of a player. isEnabled() should be called + * before calling this method + * + * @param uuid UUID of player + * @return Achievement amount of the Player + */ + public int getPlayerAchievements(UUID uuid) { + return adAc.getDb().getPlayerAchievementsAmount(uuid.toString()); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/EssentialsHook.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/EssentialsHook.java new file mode 100644 index 000000000..67dac5a39 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/EssentialsHook.java @@ -0,0 +1,56 @@ +package main.java.com.djrapitops.plan.data.additional; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; +import main.java.com.djrapitops.plan.Plan; + +/** + * + * @author Rsl1122 + */ +public class EssentialsHook extends Hook { + + private final Plan plugin; + private Essentials ess; + private List warps; + + /** + * Hooks to Essentials plugin + * @param plugin + */ + public EssentialsHook(Plan plugin) { + super(Essentials.class); + this.plugin = plugin; + } + + /** + * Grabs information not provided by Player class or Plan from Essentials. + * isEnabled() should be called before this method. + * + * @param uuid UUID of player + * @return HashMap with boolean, int and string values: JAILED boolean, MUTED + * boolean, AFK boolean, GOD boolean, JAILTIMEOUT + */ + public HashMap getEssentialsData(UUID uuid) { + HashMap essData = new HashMap<>(); + User user = ess.getUser(uuid); + essData.put("JAILED", user.isJailed()); + essData.put("MUTED", user.isMuted()); + essData.put("AFK", user.isAfk()); + essData.put("GOD", user.isGodModeEnabled()); + return essData; + } + + /** + * @return + */ + public List getWarps() { + return (ArrayList) ess.getWarps().getList(); + } + +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/FactionsHook.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/FactionsHook.java new file mode 100644 index 000000000..b573ab2b0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/FactionsHook.java @@ -0,0 +1,84 @@ +package main.java.com.djrapitops.plan.data.additional; + +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.entity.Faction; +import com.massivecraft.factions.entity.FactionColl; +import com.massivecraft.factions.entity.MPlayer; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import main.java.com.djrapitops.plan.Plan; +import main.java.com.djrapitops.plan.utilities.comparators.FactionComparator; + +/** + * + * @author Rsl1122 + */ +public class FactionsHook extends Hook { + + private final Plan plugin; + + /** + * Hooks to Factions plugin + * + * @param plugin + */ + public FactionsHook(Plan plugin) { + super(Factions.class); + this.plugin = plugin; + } + + /** + * @return List of Faction names sorted by power + */ + public List getTopFactions() { + List topFactions = new ArrayList<>(); + topFactions.addAll(FactionColl.get().getAll()); + Collections.sort(topFactions, new FactionComparator()); + List factionNames = topFactions.stream() + .map(faction -> faction.getName()) + .collect(Collectors.toList()); + return factionNames; + } + + /** + * Grab basic info about Faction. isEnabled() should be called before this + * method. + * + * @param factionName Name of the faction. + * @return HashMap containing boolean, number & string: LEADER String, POWER + * double, LAND int + */ + public HashMap getFactionInfo(String factionName) { + HashMap info = new HashMap<>(); + Faction faction = FactionColl.get().getByName(factionName); + info.put("LEADER", faction.getLeader().getNameAndSomething("", "")); + info.put("POWER", faction.getPower()); + info.put("LAND", faction.getPower()); + return info; + } + + /** + * Grab power of player. isEnabled() should be called before this + * method. + * @param uuid UUID of player + * @return Faction power of player + */ + public double getPower(UUID uuid) { + return MPlayer.get(uuid).getPower(); + } + + /** + * Grab Max power of player. isEnabled() should be called before this + * method. + * @param uuid UUID of player + * @return Faction Max power of player + */ + public double getMaxPower(UUID uuid) { + return MPlayer.get(uuid).getPowerMax(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/Hook.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/Hook.java new file mode 100644 index 000000000..aeb15b1c4 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/Hook.java @@ -0,0 +1,37 @@ +package main.java.com.djrapitops.plan.data.additional; + +import org.bukkit.plugin.java.JavaPlugin; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; + +/** + * + * @author Rsl1122 + */ +public abstract class Hook { + + private boolean enabled; + + /** + * + * @param plugin + */ + public Hook(Class plugin) { + JavaPlugin hookedPlugin = getPlugin(plugin); + try { + enabled = hookedPlugin.isEnabled(); + } catch (Exception | NoClassDefFoundError e) { + enabled = false; + } + } + + /** + * @return Whether or not the plugin was successfully hooked. + */ + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/HookHandler.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/HookHandler.java new file mode 100644 index 000000000..9f0ce3c7a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/HookHandler.java @@ -0,0 +1,49 @@ +package main.java.com.djrapitops.plan.data.additional; + +import main.java.com.djrapitops.plan.Plan; + +/** + * + * @author Rsl1122 + */ +public class HookHandler { + private Plan plan; + private AdvancedAchievementsHook advancedAchievementsHook; + private EssentialsHook essentialsHook; + private SuperbVoteHook superbVoteHook; + private FactionsHook factionsHook; + + public HookHandler(Plan plan) { + this.plan = plan; + hook(); + } + + public void reloadHooks() { + hook(); + } + + private void hook() { + advancedAchievementsHook = new AdvancedAchievementsHook(plan); + essentialsHook = new EssentialsHook(plan); + superbVoteHook = new SuperbVoteHook(plan); + factionsHook = new FactionsHook(plan); + } + + public AdvancedAchievementsHook getAdvancedAchievementsHook() { + return advancedAchievementsHook; + } + + public EssentialsHook getEssentialsHook() { + return essentialsHook; + } + + public SuperbVoteHook getSuperbVoteHook() { + return superbVoteHook; + } + + public FactionsHook getFactionsHook() { + return factionsHook; + } + + +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/OnTimeHook.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/OnTimeHook.java new file mode 100644 index 000000000..b7d77f6e0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/OnTimeHook.java @@ -0,0 +1,43 @@ +package main.java.com.djrapitops.plan.data.additional; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.UUID; +import main.java.com.djrapitops.plan.Plan; +import me.edge209.OnTime.OnTime; +import me.edge209.OnTime.OnTimeAPI; +import org.bukkit.Bukkit; + +/** + * + * @author Rsl1122 + */ +public class OnTimeHook extends Hook { + + private final Plan plugin; + private OnTimeAPI ontimeAPI; + + /** + * Hooks to OnTime plugin + * @param plugin + */ + public OnTimeHook(Plan plugin) { + super(OnTime.class); + this.plugin = plugin; + } + + /** + * Grabs information not provided by Player class or Plan from OnTime. + * isEnabled() should be called before this method. + * + * @param uuid UUID of player + * @return HashMap with boolean, int and string values: VOTES int, REFERRALS int + */ + public HashMap getOnTimeData(UUID uuid) { + HashMap ontimeData = new HashMap<>(); + String name = Bukkit.getOfflinePlayer(uuid).getName(); + ontimeData.put("VOTES", OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALVOTE)); + ontimeData.put("REFERRALS", OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALREFER)); + return ontimeData; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/SuperbVoteHook.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/SuperbVoteHook.java new file mode 100644 index 000000000..83d621172 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/SuperbVoteHook.java @@ -0,0 +1,38 @@ +package main.java.com.djrapitops.plan.data.additional; + +import io.minimum.minecraft.superbvote.SuperbVote; +import io.minimum.minecraft.superbvote.storage.VoteStorage; +import java.util.UUID; +import main.java.com.djrapitops.plan.Plan; + +/** + * + * @author Rsl1122 + */ +public class SuperbVoteHook extends Hook { + + private final Plan plugin; + private VoteStorage votes; + + /** + * Hooks to SuperbVote plugin + * + * @param plugin + */ + public SuperbVoteHook(Plan plugin) { + super(SuperbVote.class); + this.plugin = plugin; + } + + /** + * Grabs votes from SuperbVote. + * isEnabled() should be called before this + * method. + * + * @param uuid UUID of player + * @return Amount of votes + */ + public int getVotes(UUID uuid) { + return votes.getVotes(uuid); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/handlers/NewPlayerCreator.java b/Plan/src/main/java/com/djrapitops/plan/data/handlers/NewPlayerCreator.java index e275af60f..fe0da2f81 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/handlers/NewPlayerCreator.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/handlers/NewPlayerCreator.java @@ -50,7 +50,7 @@ public class NewPlayerCreator { } public void createNewPlayer(OfflinePlayer player, GameMode gm) { - UserData data = new UserData(player, new DemographicsData(), db); + UserData data = new UserData(player, new DemographicsData()); data.setLastGamemode(gm); data.setLastPlayed(new Date().getTime()); long zero = Long.parseLong("0"); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/handlers/PlanLiteDataPushHook.java b/Plan/src/main/java/com/djrapitops/plan/data/handlers/PlanLiteDataPushHook.java deleted file mode 100644 index 536f04d58..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/data/handlers/PlanLiteDataPushHook.java +++ /dev/null @@ -1,66 +0,0 @@ -package main.java.com.djrapitops.plan.data.handlers; - -import com.djrapitops.planlite.UUIDFetcher; -import com.djrapitops.planlite.api.DataPoint; -import com.djrapitops.planlite.api.DataType; -import com.djrapitops.planlite.api.Hook; -import java.util.HashMap; -import java.util.UUID; -import main.java.com.djrapitops.plan.Plan; -import main.java.com.djrapitops.plan.data.UserData; -import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler; -import main.java.com.djrapitops.plan.utilities.PlaceholderUtils; - -/** - * - * @author Rsl1122 - */ -public class PlanLiteDataPushHook implements Hook { - - private final Plan plugin; - - public PlanLiteDataPushHook(Plan plugin) { - this.plugin = plugin; - } - - /** - * Used to send data to PlanLite if it's use as UI is enabled. - * - * @param playername - * @return - * @throws Exception - */ - @Override - public HashMap getData(String playername) throws Exception { - HashMap data = new HashMap<>(); - try { - UUID uuid = UUIDFetcher.getUUIDOf(playername); - if (uuid != null) { - InspectCacheHandler inspectCache = plugin.getInspectCache(); - inspectCache.cache(uuid); - UserData uData = inspectCache.getFromCache(uuid); - HashMap userData = PlaceholderUtils.getInspectReplaceRules(uData); - for (String key : userData.keySet()) { - if (key.equals("%planlite%") || key.equals("%gmpiechart%")) { - continue; - } - data.put("PLA-" + key.toUpperCase().substring(1, key.length() - 1), new DataPoint(userData.get(key), DataType.OTHER)); - } - } - } catch (Exception e) { - } - return data; - } - - /** - * Used to send data to PlanLite if it's use as UI is enabled. - * - * @param playername - * @return - * @throws Exception - */ - @Override - public HashMap getAllData(String playername) throws Exception { - return getData(playername); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java index 0c29f33ff..bc55b07ba 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java @@ -238,6 +238,7 @@ public abstract class SQLDB extends Database { query("CREATE TABLE IF NOT EXISTS " + nicknamesName + " (" + nicknamesColumnUserID + " integer NOT NULL, " + nicknamesColumnNick + " varchar(30) NOT NULL, " + + nicknamesColumnCurrent + " boolean NOT NULL DEFAULT (0), " + "FOREIGN KEY(" + nicknamesColumnUserID + ") REFERENCES " + userName + "(" + userColumnID + ")" + ")" ); @@ -523,7 +524,7 @@ public abstract class SQLDB extends Database { worlds.put(w.getName(), w); } // Get the data - UserData data = new UserData(getOfflinePlayer(uuid), new DemographicsData(), this); + UserData data = new UserData(getOfflinePlayer(uuid), new DemographicsData()); PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + userName + " WHERE UPPER(" + userColumnUUID + ") LIKE UPPER(?)"); statement.setString(1, uuid.toString()); diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java b/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java index 2fae569e8..806c3a48c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java @@ -47,7 +47,7 @@ public class DataRequestHandler { * placeholders with * @return The html */ - public String getDataHtml(UUID uuid) { + public String getInspectHtml(UUID uuid) { try { UserData data = inspectCache.getFromCache(uuid); if (data == null) { @@ -80,6 +80,25 @@ public class DataRequestHandler { return "

404 analysis.html was not found

"; } } + + /** + * Returns the players.html as string with replaced placeholders. + * + * @return the html + */ + public String getPlayersHtml() { + try { + if (!analysisCache.isCached()) { + return "

404 Data was not found in cache

"; + } + return HtmlUtils.replacePlaceholders( + HtmlUtils.getHtmlStringFromResource("players.html"), + PlaceholderUtils.getPlayersReplaceRules(analysisCache.getData()) + ); + } catch (FileNotFoundException ex) { + return "

404 players.html was not found

"; + } + } /** * Checks if the AnalysisData is cached. diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/Html.java b/Plan/src/main/java/com/djrapitops/plan/ui/Html.java index e5abdf671..567d9644e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/Html.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/Html.java @@ -36,6 +36,7 @@ public enum Html { SPAN("" + REPLACE0 + ""), BUTTON("" + REPLACE1 + ""), BUTTON_CLASS("class=\"button\""), + LINK("" + REPLACE1 + ""), LINK_CLASS("class=\"link\""), TABLE_START(""), TABLE_END("
"), diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java new file mode 100644 index 000000000..75c75723c --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java @@ -0,0 +1,32 @@ +package main.java.com.djrapitops.plan.ui.tables; + +import java.util.Collection; +import java.util.Date; +import main.java.com.djrapitops.plan.data.UserData; +import main.java.com.djrapitops.plan.ui.Html; +import main.java.com.djrapitops.plan.utilities.AnalysisUtils; +import main.java.com.djrapitops.plan.utilities.FormatUtils; +import main.java.com.djrapitops.plan.utilities.HtmlUtils; + +/** + * + * @author Rsl1122 + */ +public class SortablePlayersTableCreator { + + public static String createSortablePlayersTable(Collection data) { + String html = ""; + Date now = new Date(); + for (UserData uData : data) { + html += "" + + "" + Html.LINK.parse(HtmlUtils.getInspectUrl(uData.getName()),uData.getName())+"" + + "" + AnalysisUtils.isActive(uData.getLastPlayed(), uData.getPlayTime(), uData.getLoginTimes()) + "" + + "" + FormatUtils.formatTimeAmount(uData.getPlayTime() + "") + "" + + "" + uData.getLoginTimes() + "" + + "" + FormatUtils.formatTimeAmountSinceString(uData.getLastPlayed() + "", now) + "" + + "" + uData.getDemData().getGeoLocation() + "" + + ""; + } + return html; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java index eedf36f06..8ded296e5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java @@ -3,9 +3,11 @@ package main.java.com.djrapitops.plan.ui.webserver; import java.io.IOException; import java.io.OutputStream; import java.util.UUID; +import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.Settings; import main.java.com.djrapitops.plan.ui.DataRequestHandler; import main.java.com.djrapitops.plan.utilities.UUIDFetcher; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; /** * @@ -78,14 +80,14 @@ public class Response { } if (requestHandler.checkIfCached(uuid)) { try { - String dataHtml = requestHandler.getDataHtml(uuid); + String dataHtml = requestHandler.getInspectHtml(uuid); String htmlDef = "HTTP/1.1 OK\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "Content-Length: " + dataHtml.length() + "\r\n" + "\r\n"; output.write((htmlDef + dataHtml).getBytes()); } catch (NullPointerException e) { - e.printStackTrace(); + getPlugin(Plan.class).toLog(this.getClass().getName(), e); String errorMessage = "HTTP/1.1 404 Error\r\n" + "Content-Type: text/html;\r\n" + "Content-Length: 30\r\n" @@ -106,6 +108,16 @@ public class Response { output.write((htmlDef + analysisHtml).getBytes()); return; } + } else if (command.equals("players")) { + if (requestHandler.checkIfAnalysisIsCached()) { + String playersHtml = requestHandler.getPlayersHtml(); + String htmlDef = "HTTP/1.1 OK\r\n" + + "Content-Type: text/html; charset=utf-8\r\n" + + "Content-Length: " + playersHtml.length() + "\r\n" + + "\r\n"; + output.write((htmlDef + playersHtml).getBytes()); + return; + } } String errorMessage = "HTTP/1.1 404 UserData not Found\r\n" + "Content-Type: text/html\r\n" @@ -113,9 +125,8 @@ public class Response { + "\r\n" + "

404 Data was not found in cache

"; output.write(errorMessage.getBytes()); - } catch (Exception e) { - e.printStackTrace(); + getPlugin(Plan.class).toLog(this.getClass().getName(), e); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java index bdfb16f41..9ae6d78f3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java @@ -87,7 +87,7 @@ public class Analysis { sorted.setCommandUse(plugin.getHandler().getCommandUse()); log(Phrase.ANALYSIS_BEGIN_ANALYSIS + ""); AnalysisData analysisData = new AnalysisData(); - + analysisData.setSortablePlayersTable(AnalysisUtils.createSortablePlayersTable(rawData)); // Fill Dataset with userdata. rawData.parallelStream().forEach((uData) -> { try { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java index 82dd7f2d1..3a2b452e1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java @@ -1,16 +1,19 @@ package main.java.com.djrapitops.plan.utilities; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import main.java.com.djrapitops.plan.Settings; import main.java.com.djrapitops.plan.data.SessionData; +import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.ui.Html; import main.java.com.djrapitops.plan.ui.graphs.ActivityPieChartCreator; import main.java.com.djrapitops.plan.ui.graphs.GMTimesPieChartCreator; import main.java.com.djrapitops.plan.ui.graphs.PlayerActivityGraphCreator; +import main.java.com.djrapitops.plan.ui.tables.SortablePlayersTableCreator; import main.java.com.djrapitops.plan.ui.tables.SortedTableCreator; import main.java.com.djrapitops.plan.utilities.comparators.MapComparator; import org.bukkit.GameMode; @@ -51,7 +54,7 @@ public class AnalysisUtils { return Html.IMG.parse(url); } - static boolean isActive(long lastPlayed, long playTime, int loginTimes) { + public static boolean isActive(long lastPlayed, long playTime, int loginTimes) { int timeToActive = Settings.ANALYSIS_MINUTES_FOR_ACTIVE.getNumber(); if (timeToActive < 0) { timeToActive = 0; @@ -87,6 +90,10 @@ public class AnalysisUtils { static String createActivePlayersTable(HashMap map, int limit) { return SortedTableCreator.createActivePlayersTable(map, limit); } + + static String createSortablePlayersTable(Collection data) { + return SortablePlayersTableCreator.createSortablePlayersTable(data); + } static String createListStringOutOfHashMapLong(HashMap map, int limit) { List sorted = MapComparator.sortByValueLong(map); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java index 864c8647f..e086fb023 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java @@ -120,4 +120,13 @@ public class PlaceholderUtils { replaceMap.put("%inaccuratedatawarning%", (new Date().getTime() - data.getRegistered() < 180000) ? Html.WARN_INACCURATE.parse() : ""); return replaceMap; } + + public static HashMap getPlayersReplaceRules(AnalysisData data) { + HashMap replaceMap = new HashMap<>(); + Plan plugin = getPlugin(Plan.class); + replaceMap.put("%version%", plugin.getDescription().getVersion()); + replaceMap.put("%total%", "" + data.getTotal()); + replaceMap.put("%sortabletable%", data.getSortablePlayersTable()); + return replaceMap; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/comparators/FactionComparator.java b/Plan/src/main/java/com/djrapitops/plan/utilities/comparators/FactionComparator.java new file mode 100644 index 000000000..990adbdb0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/comparators/FactionComparator.java @@ -0,0 +1,21 @@ +package main.java.com.djrapitops.plan.utilities.comparators; + +import com.massivecraft.factions.entity.Faction; +import java.util.Comparator; + +/** + * + * @author Rsl1122 + */ +public class FactionComparator implements Comparator { + + // This method should only be used if FactionsHook.isEnabled() returns true. + // Note: this comparator imposes orderings that are inconsistent with equals. + @Override + public int compare(Faction fac1, Faction fac2) { + if (fac1.getPower() > fac2.getPower()) { + return 1; + } + return -1; + } +} diff --git a/Plan/src/main/resources/players.html b/Plan/src/main/resources/players.html new file mode 100644 index 000000000..0bbf788c7 --- /dev/null +++ b/Plan/src/main/resources/players.html @@ -0,0 +1,95 @@ + + + + + Plan | Inspect %name% + + + + + + + + +
+ Player Analytics | Players +

Player Analytics v.%version%

+

Plan | Players

+

Showing %total% players

+
+
+
+ + + + + + + + + + + + + %sortabletable% + +
PlayerActivePlaytimeLogin timesLast seenGeolocation
+
+
+ + \ No newline at end of file