[2.6.0] Added most of PlanLite features, added sortable players table

- Added All hooks except Towny
- Text interface missing.
- Untested
This commit is contained in:
Rsl1122 2017-02-20 15:29:39 +02:00
parent ab03c43204
commit f0daeb91c4
25 changed files with 664 additions and 89 deletions

View File

@ -12,10 +12,11 @@
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- SoftDepended Plugins-->
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>plan.lite</artifactId>
<version>1.6.3</version>
<groupId>com.hm</groupId>
<artifactId>advanced.achievements</artifactId>
<version>4.1.5</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -24,6 +25,31 @@
<version>4.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.earth2me</groupId>
<artifactId>essentials</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.minimum</groupId>
<artifactId>superbvote</artifactId>
<version>0.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>
<artifactId>factions</artifactId>
<version>2.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>
<artifactId>mcore</artifactId>
<version>2.10.0</version>
<scope>provided</scope>
</dependency>
<!-- -->
<dependency>
<groupId>com.googlecode.charts4j</groupId>
<artifactId>charts4j</artifactId>

View File

@ -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
*/
/**
*

View File

@ -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);
}
/**

View File

@ -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;

View File

@ -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
*/

View File

@ -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<SessionData> 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);

View File

@ -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());
}
}

View File

@ -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<String> 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<String, Serializable> getEssentialsData(UUID uuid) {
HashMap<String, Serializable> 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<String> getWarps() {
return (ArrayList<String>) ess.getWarps().getList();
}
}

View File

@ -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<String> getTopFactions() {
List<Faction> topFactions = new ArrayList<>();
topFactions.addAll(FactionColl.get().getAll());
Collections.sort(topFactions, new FactionComparator());
List<String> 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<String, Serializable> getFactionInfo(String factionName) {
HashMap<String, Serializable> 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();
}
}

View File

@ -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<? extends JavaPlugin> 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;
}
}

View File

@ -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;
}
}

View File

@ -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<String, Serializable> getOnTimeData(UUID uuid) {
HashMap<String, Serializable> 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;
}
}

View File

@ -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);
}
}

View File

@ -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");

View File

@ -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<String, DataPoint> getData(String playername) throws Exception {
HashMap<String, DataPoint> 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<String, String> 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<String, DataPoint> getAllData(String playername) throws Exception {
return getData(playername);
}
}

View File

@ -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());

View File

@ -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 "<h1>404 analysis.html was not found</h1>";
}
}
/**
* Returns the players.html as string with replaced placeholders.
*
* @return the html
*/
public String getPlayersHtml() {
try {
if (!analysisCache.isCached()) {
return "<h1>404 Data was not found in cache</h1>";
}
return HtmlUtils.replacePlaceholders(
HtmlUtils.getHtmlStringFromResource("players.html"),
PlaceholderUtils.getPlayersReplaceRules(analysisCache.getData())
);
} catch (FileNotFoundException ex) {
return "<h1>404 players.html was not found</h1>";
}
}
/**
* Checks if the AnalysisData is cached.

View File

@ -36,6 +36,7 @@ public enum Html {
SPAN("" + REPLACE0 + "</span>"),
BUTTON("<a class=\"button\" href=\"" + REPLACE0 + "\">" + REPLACE1 + "</a>"),
BUTTON_CLASS("class=\"button\""),
LINK("<a class=\"link\" href=\"" + REPLACE0 + "\">" + REPLACE1 + "</a>"),
LINK_CLASS("class=\"link\""),
TABLE_START("<table class=\"table\">"),
TABLE_END("</table>"),

View File

@ -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<UserData> data) {
String html = "";
Date now = new Date();
for (UserData uData : data) {
html += "<tr>"
+ "<td>" + Html.LINK.parse(HtmlUtils.getInspectUrl(uData.getName()),uData.getName())+"</td>"
+ "<td>" + AnalysisUtils.isActive(uData.getLastPlayed(), uData.getPlayTime(), uData.getLoginTimes()) + "</td>"
+ "<td>" + FormatUtils.formatTimeAmount(uData.getPlayTime() + "") + "</td>"
+ "<td>" + uData.getLoginTimes() + "</td>"
+ "<td>" + FormatUtils.formatTimeAmountSinceString(uData.getLastPlayed() + "", now) + "</td>"
+ "<td>" + uData.getDemData().getGeoLocation() + "</td>"
+ "</tr>";
}
return html;
}
}

View File

@ -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"
+ "<h1>404 Data was not found in cache</h1>";
output.write(errorMessage.getBytes());
} catch (Exception e) {
e.printStackTrace();
getPlugin(Plan.class).toLog(this.getClass().getName(), e);
}
}

View File

@ -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 {

View File

@ -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<String, Long> map, int limit) {
return SortedTableCreator.createActivePlayersTable(map, limit);
}
static String createSortablePlayersTable(Collection<UserData> data) {
return SortablePlayersTableCreator.createSortablePlayersTable(data);
}
static String createListStringOutOfHashMapLong(HashMap<String, Long> map, int limit) {
List<String[]> sorted = MapComparator.sortByValueLong(map);

View File

@ -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<String, String> getPlayersReplaceRules(AnalysisData data) {
HashMap<String, String> 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;
}
}

View File

@ -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<Faction> {
// 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;
}
}

View File

@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Plan | Inspect %name%</title>
<meta name="description" content="Player inspect window">
<meta name="author" content="Rsl1122">
<link rel="icon" href="https://puu.sh/tK0KL/6aa2ba141b.ico" type="image/x-icon" />
<script src="http://puu.sh/ubCTc/7e611ffe42.js"></script>
<style>
* {
box-sizing: border-box;
}
img {
width: auto;
}
body {
line-height: 140%;
font-family: Verdana, Geneva, sans-serif;
font-style: normal;
}
header, footer {
line-height: 40%;
background-color: #267F00;
color: white;
padding: 10px 15px 5px 15px;
font-family: futura-pt, Futura, Futura-Medium, Verdana, Geneva, sans-serif;
font-style: normal;
}
.column {
float: left;
padding: 15px;
}
.link {
color: green;
text-decoration:none!important;
}
.link:hover {
color: darkgreen;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
.green {
color: #55FF55;
}
.red {
color: #FF5555;
}
table.sortable thead {
background-color: #267F00;
color:white;
font-weight: bold;
cursor: default;
}
.table {
table-layout: fixed;
border-style: solid;
border-width: 1px;
padding: 8px 14px;
width: 100%;
}
</style>
</head>
<body>
<header>
<img style="float: right; padding: 5px" src="http://puu.sh/tJZUb/c2e0ab220f.png" alt="Player Analytics | Players">
<p style="float: right; text-align: right;">Player Analytics v.%version%</p>
<h1>Plan | Players</h1>
<h4>Showing %total% players</h4>
</header>
<div class="clearfix">
<div class="column">
<table class="sortable table">
<thead>
<tr>
<th>Player</th>
<th>Active</th>
<th>Playtime</th>
<th>Login times</th>
<th>Last seen</th>
<th>Geolocation</th>
</tr>
</thead>
<tbody>
%sortabletable%
</tbody>
</table>
</div>
</div>
</body>
</html>