mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-01 14:07:54 +01:00
commit
fefe7e0824
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.djrapitops</groupId>
|
||||
<artifactId>Plan</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.3</version>
|
||||
<packaging>jar</packaging>
|
||||
<repositories>
|
||||
<repository>
|
||||
@ -70,7 +70,7 @@
|
||||
<dependency>
|
||||
<groupId>com.djrapitops</groupId>
|
||||
<artifactId>PlanPluginBridge</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- Testing -->
|
||||
|
@ -10,7 +10,7 @@ import com.djrapitops.plugin.settings.ColorScheme;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.api.exceptions.DatabaseInitException;
|
||||
import main.java.com.djrapitops.plan.command.commands.ReloadCommand;
|
||||
import main.java.com.djrapitops.plan.command.PlanBungeeCommand;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.database.databases.MySQLDB;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
@ -27,7 +27,7 @@ import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -66,10 +66,10 @@ public class PlanBungee extends BungeePlugin<PlanBungee> implements IPlan {
|
||||
Log.info(Locale.get(Msg.ENABLE_DB_INIT).toString());
|
||||
initDatabase();
|
||||
|
||||
registerCommand(new ReloadCommand(this));
|
||||
registerCommand(new PlanBungeeCommand(this));
|
||||
|
||||
String ip = variableHolder.getIp();
|
||||
if ("0.0.0.0" .equals(ip)) {
|
||||
if ("0.0.0.0".equals(ip)) {
|
||||
Log.error("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server.");
|
||||
Log.info("Player Analytics partially enabled (Use /planbungee to reload config)");
|
||||
return;
|
||||
@ -98,6 +98,12 @@ public class PlanBungee extends BungeePlugin<PlanBungee> implements IPlan {
|
||||
}).runTaskAsynchronously();
|
||||
getRunnableFactory().createNew("Player Count task", new TPSCountTimer(this))
|
||||
.runTaskTimerAsynchronously(1000, TimeAmount.SECOND.ticks());
|
||||
getRunnableFactory().createNew("NetworkPageContentUpdateTask", new AbsRunnable("NetworkPageContentUpdateTask") {
|
||||
@Override
|
||||
public void run() {
|
||||
infoManager.updateNetworkPageContent();
|
||||
}
|
||||
}).runTaskTimerAsynchronously(1500, TimeAmount.MINUTE.ticks());
|
||||
|
||||
// getProxy().registerChannel("Plan");
|
||||
// registerListener(new BungeePluginChannelListener(this));
|
||||
@ -122,10 +128,20 @@ public class PlanBungee extends BungeePlugin<PlanBungee> implements IPlan {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (processingQueue != null) {
|
||||
List<Processor> processors = processingQueue.stopAndReturnLeftovers();
|
||||
Log.info("Processing unprocessed processors. (" + processors.size() + ")");
|
||||
for (Processor processor : processors) {
|
||||
processor.process();
|
||||
try {
|
||||
processingQueue.stop();
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
/*ignored*/
|
||||
}
|
||||
}
|
||||
if (webServer != null) {
|
||||
webServer.stop();
|
||||
}
|
||||
if (db != null) {
|
||||
try {
|
||||
db.close();
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
Log.info(Locale.get(Msg.DISABLED).toString());
|
||||
|
@ -26,6 +26,7 @@ public enum Settings {
|
||||
WRITE_NEW_LOCALE("Plugin.WriteNewLocaleFileOnStart"),
|
||||
DEV_MODE("Plugin.Dev"),
|
||||
USE_SERVER_TIME("Customization.UseServerTime"),
|
||||
DISPLAY_SESSIONS_AS_TABLE("Customization.Display.SessionsAsTable"),
|
||||
|
||||
// Integer
|
||||
WEBSERVER_PORT("WebServer.Port"),
|
||||
|
@ -27,14 +27,14 @@ import java.util.UUID;
|
||||
* @author Rsl1122
|
||||
* @see PluginData
|
||||
* @see AnalysisType
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class API {
|
||||
|
||||
private final Plan plugin;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
* Creates a new API instance - not supposed to be called outside {@code Plan.onEnable}.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
@ -78,7 +78,7 @@ public class API {
|
||||
* {@code <a href="Link">PlayerName</a>}
|
||||
*
|
||||
* @param name Name of the player
|
||||
* @return ./player/PlayerName
|
||||
* @return {@code ../player/PlayerName}
|
||||
*/
|
||||
public String getPlayerInspectPageLink(String name) {
|
||||
String link = "../player/" + name;
|
||||
@ -86,7 +86,7 @@ public class API {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Players's Inspect page is cached to pagecache.
|
||||
* Check if Players's Inspect page is cached to PageCache.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return true/false
|
||||
@ -97,12 +97,21 @@ public class API {
|
||||
return isPlayerHtmlCached(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Players's Inspect page is cached to PageCache of the providing WebServer.
|
||||
* <p>
|
||||
* Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's PageCache.
|
||||
* Only Bukkit: Checks PageCache for page.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean isPlayerHtmlCached(UUID uuid) {
|
||||
return plugin.getInfoManager().isCached(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache Players's Inspect page to the PageCache of the WebServer.
|
||||
* Cache Players's Inspect page to the PageCache of the providing WebServer.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @deprecated use {@code cachePlayerHtml}
|
||||
@ -113,9 +122,13 @@ public class API {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache Players's Inspect page to the PageCache of the WebServer.
|
||||
* Cache Players's Inspect page to the PageCache of the providing WebServer.
|
||||
* <p>
|
||||
* Using BungeeCord: Will send a {@code PostHtmlWebAPI} request after calculating the inspect page.
|
||||
* Only Bukkit: Calculates inspect page and places it in the PageCache.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @deprecated use {@code cachePlayerHtml}
|
||||
*/
|
||||
public void cachePlayerHtml(UUID uuid) {
|
||||
plugin.getInfoManager().cachePlayer(uuid);
|
||||
@ -124,7 +137,7 @@ public class API {
|
||||
/**
|
||||
* Used to get the full Html of the Inspect page as a string.
|
||||
* <p>
|
||||
* Check if the data is cached to InspectCache before calling this.
|
||||
* Re-calculates the inspect html on this server.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return player.html with all placeholders replaced.
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main.java.com.djrapitops.plan.api.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when something goes wrong with creating tables with Table#createTable.
|
||||
* Thrown when something goes wrong with creating tables with {@code Table#createTable}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main.java.com.djrapitops.plan.api.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when something goes wrong in the database, generic exception.
|
||||
* Thrown when something goes wrong with the Database, generic exception.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main.java.com.djrapitops.plan.api.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when something goes wrong with Database#init.
|
||||
* Thrown when something goes wrong with {@code Database#init}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main.java.com.djrapitops.plan.api.exceptions;
|
||||
|
||||
/**
|
||||
* Exception thrown when Html page parsing fails.
|
||||
* Exception thrown when PageParser encounters an Exception.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main.java.com.djrapitops.plan.api.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when WebAPI fails to connect.
|
||||
* Thrown when WebAPI fails to connect to an address.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main.java.com.djrapitops.plan.api.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when web api post request fails.
|
||||
* Thrown when WebAPI POST-request fails, general Exception.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
|
@ -0,0 +1,50 @@
|
||||
package main.java.com.djrapitops.plan.command;
|
||||
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.TreeCommand;
|
||||
import com.djrapitops.plugin.command.defaultcmds.StatusCommand;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.PlanBungee;
|
||||
import main.java.com.djrapitops.plan.command.commands.*;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
|
||||
/**
|
||||
* TreeCommand for the /plan command, and all subcommands.
|
||||
* <p>
|
||||
* Uses the Abstract Plugin Framework for easier command management.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class PlanBungeeCommand extends TreeCommand<PlanBungee> {
|
||||
|
||||
/**
|
||||
* CommandExecutor class Constructor.
|
||||
* <p>
|
||||
* Initializes Subcommands
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanBungeeCommand(PlanBungee plugin) {
|
||||
super(plugin, "planbungee", CommandType.CONSOLE, "", "", "planbungee");
|
||||
super.setDefaultCommand("help");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] addHelp() {
|
||||
return Locale.get(Msg.CMD_HELP_PLAN).toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommands() {
|
||||
commands.add(new ReloadCommand(plugin));
|
||||
commands.add(new StatusCommand<>(plugin, Permissions.MANAGE.getPermission()));
|
||||
commands.add(new ListCommand());
|
||||
RegisterCommand registerCommand = new RegisterCommand(plugin);
|
||||
commands.add(registerCommand);
|
||||
commands.add(new WebUserCommand(plugin, registerCommand));
|
||||
commands.add(new NetworkCommand(plugin));
|
||||
commands.add(new ListServersCommand(plugin));
|
||||
}
|
||||
}
|
@ -5,9 +5,9 @@ import com.djrapitops.plugin.command.CommandUtils;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
import com.djrapitops.plugin.command.SubCommand;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
|
||||
/**
|
||||
* Command used to display link to the player list webpage.
|
||||
@ -43,7 +43,7 @@ public class ListCommand extends SubCommand {
|
||||
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).parse());
|
||||
|
||||
// Link
|
||||
String url = Plan.getInstance().getInfoManager().getLinkTo("/players");
|
||||
String url = MiscUtils.getIPlan().getInfoManager().getLinkTo("/players/");
|
||||
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
|
||||
boolean console = !CommandUtils.isPlayer(sender);
|
||||
if (console) {
|
||||
|
@ -6,7 +6,6 @@ import com.djrapitops.plugin.command.SubCommand;
|
||||
import com.djrapitops.plugin.settings.ColorScheme;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
@ -29,11 +28,11 @@ public class ListServersCommand extends SubCommand {
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public ListServersCommand(Plan plugin) {
|
||||
public ListServersCommand(IPlan plugin) {
|
||||
super("servers, serverlist, listservers, sl",
|
||||
CommandType.CONSOLE,
|
||||
Permissions.MANAGE.getPermission(),
|
||||
Locale.get(Msg.CMD_USG_RELOAD).toString());
|
||||
"List servers in the network");
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import com.djrapitops.plugin.command.CommandUtils;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
import com.djrapitops.plugin.command.SubCommand;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
|
||||
@ -19,22 +19,21 @@ import main.java.com.djrapitops.plan.locale.Msg;
|
||||
*/
|
||||
public class NetworkCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final IPlan plugin;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*/
|
||||
public NetworkCommand(Plan plugin) {
|
||||
super("network, n, netw", CommandType.CONSOLE, Permissions.ANALYZE.getPermission(), Locale.get(Msg.CMD_USG_LIST).toString(), "");
|
||||
public NetworkCommand(IPlan plugin) {
|
||||
super("network, n, netw",
|
||||
CommandType.CONSOLE,
|
||||
Permissions.ANALYZE.getPermission(),
|
||||
"Get the link to the network page");
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(ISender sender, String commandLabel, String[] args) {
|
||||
if (plugin.getInfoManager().isUsingAnotherWebServer()) {
|
||||
sender.sendMessage("§cNot using Bungee WebServer!");
|
||||
return true;
|
||||
}
|
||||
sendNetworkMsg(sender);
|
||||
return true;
|
||||
}
|
||||
@ -43,7 +42,7 @@ public class NetworkCommand extends SubCommand {
|
||||
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).parse());
|
||||
|
||||
// Link
|
||||
String url = Plan.getInstance().getInfoManager().getLinkTo("/network");
|
||||
String url = plugin.getInfoManager().getLinkTo("/network/");
|
||||
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
|
||||
boolean console = !CommandUtils.isPlayer(sender);
|
||||
if (console) {
|
||||
|
@ -5,17 +5,16 @@ import com.djrapitops.plugin.command.CommandUtils;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
import com.djrapitops.plugin.command.SubCommand;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import com.djrapitops.plugin.utilities.Compatibility;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.data.WebUser;
|
||||
import main.java.com.djrapitops.plan.database.tables.SecurityTable;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
import main.java.com.djrapitops.plan.utilities.Check;
|
||||
import main.java.com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.Logger;
|
||||
|
||||
/**
|
||||
* Command for registering web users.
|
||||
@ -31,16 +30,18 @@ import org.apache.logging.log4j.core.Logger;
|
||||
*/
|
||||
public class RegisterCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final IPlan plugin;
|
||||
|
||||
public RegisterCommand(Plan plugin) {
|
||||
public RegisterCommand(IPlan plugin) {
|
||||
super("register",
|
||||
CommandType.CONSOLE_WITH_ARGUMENTS,
|
||||
"", // No Permission Requirement
|
||||
Locale.get(Msg.CMD_USG_WEB_REGISTER).toString(),
|
||||
"<password> [name] [access lvl]");
|
||||
this.plugin = plugin;
|
||||
setupFilter();
|
||||
if (Compatibility.isBukkitAvailable()) {
|
||||
setupFilter();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -140,7 +141,6 @@ public class RegisterCommand extends SubCommand {
|
||||
* Setups the command console output filter
|
||||
*/
|
||||
private void setupFilter() {
|
||||
Logger logger = (Logger) LogManager.getRootLogger();
|
||||
logger.addFilter(new RegisterCommandFilter());
|
||||
new RegisterCommandFilter().registerFilter();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package main.java.com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.apache.logging.log4j.core.Logger;
|
||||
@ -20,6 +21,11 @@ public class RegisterCommandFilter extends AbstractFilter {
|
||||
|
||||
private final Set<String> censoredCommands = ImmutableSet.of("/plan web register", "/plan webuser register", "/plan register");
|
||||
|
||||
public void registerFilter() {
|
||||
Logger logger = (Logger) LogManager.getRootLogger();
|
||||
logger.addFilter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result filter(LogEvent event) {
|
||||
if (event == null) {
|
||||
|
@ -4,8 +4,6 @@ import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
import com.djrapitops.plugin.command.SubCommand;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.PlanBungee;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
@ -25,7 +23,7 @@ public class ReloadCommand extends SubCommand {
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public ReloadCommand(Plan plugin) {
|
||||
public ReloadCommand(IPlan plugin) {
|
||||
super("reload",
|
||||
CommandType.CONSOLE,
|
||||
Permissions.MANAGE.getPermission(),
|
||||
@ -34,15 +32,6 @@ public class ReloadCommand extends SubCommand {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public ReloadCommand(PlanBungee plugin) {
|
||||
super("planbungee",
|
||||
CommandType.CONSOLE,
|
||||
Permissions.MANAGE.getPermission(),
|
||||
Locale.get(Msg.CMD_USG_RELOAD).toString());
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(ISender sender, String commandLabel, String[] args) {
|
||||
plugin.restart();
|
||||
|
@ -3,7 +3,7 @@ package main.java.com.djrapitops.plan.command.commands;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.TreeCommand;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.command.commands.webuser.WebCheckCommand;
|
||||
import main.java.com.djrapitops.plan.command.commands.webuser.WebDeleteCommand;
|
||||
import main.java.com.djrapitops.plan.command.commands.webuser.WebLevelCommand;
|
||||
@ -17,9 +17,9 @@ import main.java.com.djrapitops.plan.locale.Msg;
|
||||
* @author Rsl1122
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public class WebUserCommand extends TreeCommand<Plan> {
|
||||
public class WebUserCommand extends TreeCommand<IPlan> {
|
||||
|
||||
public WebUserCommand(Plan plugin, RegisterCommand register) {
|
||||
public WebUserCommand(IPlan plugin, RegisterCommand register) {
|
||||
super(plugin, "webuser, web",
|
||||
CommandType.CONSOLE,
|
||||
Permissions.MANAGE_WEB.getPerm(),
|
||||
|
@ -55,6 +55,10 @@ public class ManageSetupCommand extends SubCommand {
|
||||
return true;
|
||||
}
|
||||
String address = args[0].toLowerCase();
|
||||
if (!address.startsWith("http")) {
|
||||
sender.sendMessage("§cMake sure you're using the full address (Starts with http:// or https://) - Check Bungee enable log for the full address.");
|
||||
return true;
|
||||
}
|
||||
if (address.endsWith("/")) {
|
||||
address = address.substring(0, address.length() - 1);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.djrapitops.plugin.command.SubCommand;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.data.WebUser;
|
||||
import main.java.com.djrapitops.plan.database.tables.SecurityTable;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
@ -22,9 +22,9 @@ import org.bukkit.ChatColor;
|
||||
*/
|
||||
public class WebCheckCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final IPlan plugin;
|
||||
|
||||
public WebCheckCommand(Plan plugin) {
|
||||
public WebCheckCommand(IPlan plugin) {
|
||||
super("check",
|
||||
CommandType.CONSOLE_WITH_ARGUMENTS,
|
||||
Permissions.MANAGE_WEB.getPerm(),
|
||||
|
@ -6,7 +6,7 @@ import com.djrapitops.plugin.command.SubCommand;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.database.tables.SecurityTable;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
@ -21,9 +21,9 @@ import net.md_5.bungee.api.ChatColor;
|
||||
*/
|
||||
public class WebDeleteCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final IPlan plugin;
|
||||
|
||||
public WebDeleteCommand(Plan plugin) {
|
||||
public WebDeleteCommand(IPlan plugin) {
|
||||
super("delete, remove",
|
||||
CommandType.CONSOLE_WITH_ARGUMENTS,
|
||||
Permissions.MANAGE_WEB.getPerm(),
|
||||
|
@ -5,7 +5,7 @@ import com.djrapitops.plugin.command.ISender;
|
||||
import com.djrapitops.plugin.command.SubCommand;
|
||||
import com.djrapitops.plugin.settings.ColorScheme;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
|
||||
@ -17,9 +17,9 @@ import main.java.com.djrapitops.plan.locale.Msg;
|
||||
*/
|
||||
public class WebLevelCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final IPlan plugin;
|
||||
|
||||
public WebLevelCommand(Plan plugin) {
|
||||
public WebLevelCommand(IPlan plugin) {
|
||||
super("level",
|
||||
CommandType.CONSOLE,
|
||||
Permissions.MANAGE_WEB.getPerm(),
|
||||
|
@ -7,7 +7,7 @@ import com.djrapitops.plugin.settings.ColorScheme;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.IPlan;
|
||||
import main.java.com.djrapitops.plan.data.WebUser;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
@ -23,9 +23,9 @@ import java.util.List;
|
||||
*/
|
||||
public class WebListUsersCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final IPlan plugin;
|
||||
|
||||
public WebListUsersCommand(Plan plugin) {
|
||||
public WebListUsersCommand(IPlan plugin) {
|
||||
super("list", CommandType.CONSOLE, Permissions.MANAGE_WEB.getPerm(), "List registered web users & permission levels.");
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package main.java.com.djrapitops.plan.data;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.data.analysis.*;
|
||||
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
@ -38,7 +37,6 @@ public class AnalysisData extends RawData {
|
||||
private final TPSPart tpsPart;
|
||||
private final WorldPart worldPart;
|
||||
private long refreshDate;
|
||||
private String planVersion;
|
||||
private String pluginsTabLayout;
|
||||
private Map<String, Serializable> additionalDataReplaceMap;
|
||||
private String playersTable;
|
||||
@ -97,26 +95,10 @@ public class AnalysisData extends RawData {
|
||||
worldPart);
|
||||
}
|
||||
|
||||
public String getPlanVersion() {
|
||||
return planVersion;
|
||||
}
|
||||
|
||||
public void setPlanVersion(String planVersion) {
|
||||
this.planVersion = planVersion;
|
||||
}
|
||||
|
||||
public String getPluginsTabLayout() {
|
||||
return pluginsTabLayout;
|
||||
}
|
||||
|
||||
public void setPluginsTabLayout(String pluginsTabLayout) {
|
||||
this.pluginsTabLayout = pluginsTabLayout;
|
||||
}
|
||||
|
||||
public Map<String, Serializable> getAdditionalDataReplaceMap() {
|
||||
return additionalDataReplaceMap;
|
||||
}
|
||||
|
||||
public void setAdditionalDataReplaceMap(Map<String, Serializable> additionalDataReplaceMap) {
|
||||
this.additionalDataReplaceMap = additionalDataReplaceMap;
|
||||
}
|
||||
@ -127,12 +109,15 @@ public class AnalysisData extends RawData {
|
||||
|
||||
@Override
|
||||
protected void analyse() {
|
||||
Verify.nullCheck(playersTable);
|
||||
Verify.nullCheck(pluginsTabLayout);
|
||||
Verify.nullCheck(planVersion);
|
||||
if (playersTable == null) {
|
||||
playersTable = "";
|
||||
}
|
||||
if (pluginsTabLayout == null) {
|
||||
pluginsTabLayout = "";
|
||||
}
|
||||
|
||||
addValue("tableBodyPlayerList", playersTable);
|
||||
addValue("version", planVersion);
|
||||
addValue("version", MiscUtils.getIPlan().getVersion());
|
||||
|
||||
final List<RawData> parts = getAllParts();
|
||||
parts.forEach(part -> {
|
||||
@ -157,8 +142,4 @@ public class AnalysisData extends RawData {
|
||||
public long getRefreshDate() {
|
||||
return refreshDate;
|
||||
}
|
||||
|
||||
public void setRefreshDate(long refreshDate) {
|
||||
this.refreshDate = refreshDate;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public class UserInfo {
|
||||
this.registered = registered;
|
||||
this.opped = opped;
|
||||
this.banned = banned;
|
||||
lastSeen = 0L;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
|
@ -5,6 +5,7 @@ import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.data.Session;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
||||
|
||||
import java.util.*;
|
||||
@ -61,7 +62,10 @@ public class JoinInfoPart extends RawData {
|
||||
}
|
||||
|
||||
private void sessionTables() {
|
||||
String[] tables = SessionsTableCreator.createTables(this);
|
||||
String[] tables = SessionsTableCreator.createTable(this);
|
||||
String[] sessionContent = SessionTabStructureCreator.creteStructure(this);
|
||||
addValue("contentSessions", sessionContent[0]);
|
||||
addValue("sessionTabGraphViewFunctions", sessionContent[1]);
|
||||
addValue("tableBodySessions", tables[0]);
|
||||
addValue("tableBodyRecentLogins", tables[1]);
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ public abstract class SQLDB extends Database {
|
||||
|
||||
if (newDatabase) {
|
||||
Log.info("New Database created.");
|
||||
setVersion(11);
|
||||
setVersion(12);
|
||||
}
|
||||
|
||||
int version = getVersion();
|
||||
@ -131,6 +131,11 @@ public abstract class SQLDB extends Database {
|
||||
serverTable.alterTableV11();
|
||||
setVersion(11);
|
||||
}
|
||||
if (version < 12) {
|
||||
actionsTable.alterTableV12();
|
||||
ipsTable.alterTableV12();
|
||||
setVersion(12);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DatabaseInitException("Failed to set-up Database", e);
|
||||
}
|
||||
|
@ -68,12 +68,18 @@ public class ActionsTable extends UserIDTable {
|
||||
.column(columnServerID, Sql.INT).notNull()
|
||||
.column(columnDate, Sql.LONG).notNull()
|
||||
.column(columnActionID, Sql.INT).notNull()
|
||||
.column(columnAdditionalInfo, Sql.varchar(100))
|
||||
.column(columnAdditionalInfo, Sql.varchar(300))
|
||||
.foreignKey(columnUserID, usersTable.toString(), usersTable.getColumnID())
|
||||
.foreignKey(columnServerID, serverTable.toString(), serverTable.getColumnID())
|
||||
.toString());
|
||||
}
|
||||
|
||||
public void alterTableV12() throws SQLException {
|
||||
if (usingMySQL) {
|
||||
executeUnsafe("ALTER TABLE " + tableName + " MODIFY " + columnAdditionalInfo + " VARCHAR(300)");
|
||||
}
|
||||
}
|
||||
|
||||
public void insertAction(UUID uuid, Action action) throws SQLException {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
|
@ -43,13 +43,19 @@ public class IPsTable extends UserIDTable {
|
||||
public void createTable() throws DBCreateTableException {
|
||||
createTable(TableSqlParser.createTable(tableName)
|
||||
.column(columnUserID, Sql.INT).notNull()
|
||||
.column(columnIP, Sql.varchar(20)).notNull()
|
||||
.column(columnIP, Sql.varchar(39)).notNull()
|
||||
.column(columnGeolocation, Sql.varchar(50)).notNull()
|
||||
.foreignKey(columnUserID, usersTable.getTableName(), usersTable.getColumnID())
|
||||
.toString()
|
||||
);
|
||||
}
|
||||
|
||||
public void alterTableV12() throws SQLException {
|
||||
if (usingMySQL) {
|
||||
executeUnsafe("ALTER TABLE " + tableName + " MODIFY " + columnIP + " VARCHAR(39) NOT NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user.
|
||||
* @return Users's Login Geolocations.
|
||||
|
@ -130,7 +130,7 @@ public class BukkitInformationManager extends InformationManager {
|
||||
HookHandler hookHandler = plugin.getHookHandler();
|
||||
List<PluginData> plugins = hookHandler.getAdditionalDataSources();
|
||||
Map<String, Serializable> replaceMap = hookHandler.getAdditionalInspectReplaceRules(uuid);
|
||||
String contents = HtmlStructure.createInspectPageTabContent(serverName, plugins, replaceMap);
|
||||
String contents = HtmlStructure.createInspectPluginsTabContent(serverName, plugins, replaceMap);
|
||||
cacheInspectPluginsTab(uuid, contents);
|
||||
}
|
||||
}
|
||||
|
@ -15,16 +15,14 @@ import main.java.com.djrapitops.plan.systems.info.parsing.NetworkPageParser;
|
||||
import main.java.com.djrapitops.plan.systems.info.server.BungeeServerInfoManager;
|
||||
import main.java.com.djrapitops.plan.systems.info.server.ServerInfo;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.PageCache;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.response.InspectPageResponse;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.response.InternalErrorResponse;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.response.NotFoundResponse;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.response.Response;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.response.*;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.WebAPIManager;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.bukkit.AnalysisReadyWebAPI;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.bukkit.AnalyzeWebAPI;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.bukkit.InspectWebAPI;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.bukkit.IsOnlineWebAPI;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.bungee.RequestPluginsTabWebAPI;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@ -158,7 +156,14 @@ public class BungeeInformationManager extends InformationManager {
|
||||
*/
|
||||
private ServerInfo getInspectRequestProcessorServer(UUID uuid) {
|
||||
if (bukkitServers.isEmpty()) {
|
||||
throw new IllegalStateException("No Bukkit Servers.");
|
||||
try {
|
||||
refreshBukkitServerMap();
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
if (bukkitServers.isEmpty()) {
|
||||
throw new IllegalStateException("No Bukkit Servers.");
|
||||
}
|
||||
}
|
||||
|
||||
Collection<ServerInfo> onlineServers = serverInfoManager.getOnlineBukkitServers();
|
||||
@ -319,6 +324,7 @@ public class BungeeInformationManager extends InformationManager {
|
||||
|
||||
public void cacheNetworkPageContent(UUID serverUUID, String html) {
|
||||
networkPageContent.put(serverUUID, html);
|
||||
updateNetworkPageContent();
|
||||
}
|
||||
|
||||
public void removeNetworkPageContent(UUID serverUUID) {
|
||||
@ -348,9 +354,7 @@ public class BungeeInformationManager extends InformationManager {
|
||||
|
||||
@Override
|
||||
public void updateNetworkPageContent() {
|
||||
Collection<ServerInfo> online = serverInfoManager.getOnlineBukkitServers();
|
||||
online.stream().map(ServerInfo::getUuid)
|
||||
.forEach(this::removeNetworkPageContent);
|
||||
PageCache.cachePage("analysisPage:" + MiscUtils.getIPlan().getServerUuid(), () -> new AnalysisPageResponse(this));
|
||||
}
|
||||
|
||||
public void sendConfigSettings() {
|
||||
|
@ -13,6 +13,8 @@ import main.java.com.djrapitops.plan.data.Action;
|
||||
import main.java.com.djrapitops.plan.data.PlayerKill;
|
||||
import main.java.com.djrapitops.plan.data.Session;
|
||||
import main.java.com.djrapitops.plan.data.UserInfo;
|
||||
import main.java.com.djrapitops.plan.data.time.GMTimes;
|
||||
import main.java.com.djrapitops.plan.data.time.WorldTimes;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.database.tables.SessionsTable;
|
||||
import main.java.com.djrapitops.plan.database.tables.UsersTable;
|
||||
@ -98,10 +100,10 @@ public class InspectPageParser extends PageParser {
|
||||
Map<String, List<Session>> sessions = sessionsTable.getSessions(uuid);
|
||||
List<Session> allSessions = sessions.values().stream()
|
||||
.flatMap(Collection::stream)
|
||||
.sorted(new SessionStartComparator())
|
||||
.sorted(new SessionStartComparator()) // Sorted Newest first.
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String[] sessionsTabContent = HtmlStructure.createSessionsTabContent(sessions, allSessions);
|
||||
String[] sessionsTabContent = HtmlStructure.createSessionsTabContentInspectPage(sessions, allSessions, uuid);
|
||||
addValue("contentSessions", sessionsTabContent[0]);
|
||||
addValue("sessionTabGraphViewFunctions", sessionsTabContent[1]);
|
||||
addValue("contentServerOverview", HtmlStructure.createServerOverviewColumn(sessions));
|
||||
@ -154,7 +156,18 @@ public class InspectPageParser extends PageParser {
|
||||
addValue("playtimeTotal", FormatUtils.formatTimeAmount(playTime));
|
||||
|
||||
String punchCardData = PunchCardGraphCreator.createDataSeries(allSessions);
|
||||
String[] worldPieData = WorldPieCreator.createSeriesData(db.getWorldTimesTable().getWorldTimesOfUser(uuid));
|
||||
WorldTimes worldTimes = db.getWorldTimesTable().getWorldTimesOfUser(uuid);
|
||||
|
||||
// Add 0 time for worlds not present.
|
||||
Set<String> nonZeroWorlds = worldTimes.getWorldTimes().keySet();
|
||||
for (String world : db.getWorldTable().getWorlds()) {
|
||||
if (nonZeroWorlds.contains(world)) {
|
||||
continue;
|
||||
}
|
||||
worldTimes.setGMTimesForWorld(world, new GMTimes());
|
||||
}
|
||||
|
||||
String[] worldPieData = WorldPieCreator.createSeriesData(worldTimes);
|
||||
|
||||
addValue("worldPieSeries", worldPieData[0]);
|
||||
addValue("gmSeries", worldPieData[1]);
|
||||
|
@ -48,7 +48,6 @@ public class NetworkPageParser extends PageParser {
|
||||
addValue("playersOnlineSeries", PlayerActivityGraphCreator.buildSeriesDataString(networkOnlineData));
|
||||
addValue("playersGraphColor", Colors.PLAYERS_ONLINE.getColor());
|
||||
addValue("playersOnline", plugin.getProxy().getOnlineCount());
|
||||
addValue("playersMax", plugin.getProxy().getConfig().getPlayerLimit());
|
||||
|
||||
addValue("playersTotal", db.getUsersTable().getPlayerCount());
|
||||
|
||||
|
@ -97,7 +97,7 @@ public class BukkitServerInfoManager {
|
||||
}
|
||||
|
||||
private UUID generateNewUUID(ServerVariableHolder variableHolder) {
|
||||
String seed = variableHolder.getName() + variableHolder.getIp() + variableHolder.getPort() + variableHolder.getVersion() + variableHolder.getImplVersion();
|
||||
String seed = plugin.getServer().getServerId() + variableHolder.getName() + variableHolder.getIp() + variableHolder.getPort() + variableHolder.getVersion() + variableHolder.getImplVersion();
|
||||
return UUID.nameUUIDFromBytes(seed.getBytes());
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,9 @@ public class BungeeServerInfoManager {
|
||||
}
|
||||
|
||||
public void serverConnected(UUID serverUUID) {
|
||||
if (plugin.getServerUuid().equals(serverUUID)) {
|
||||
return;
|
||||
}
|
||||
Log.info("Received a connection from a Bukkit server..");
|
||||
if (onlineServers.contains(serverUUID)) {
|
||||
sendConfigSettings(serverUUID);
|
||||
|
@ -34,9 +34,7 @@ public class NewNickActionProcessor extends PlayerProcessor {
|
||||
public void process() {
|
||||
UUID uuid = getUUID();
|
||||
|
||||
String n = HtmlUtils.swapColorsToSpan(displayName);
|
||||
|
||||
String info = HtmlUtils.removeXSS(n);
|
||||
String info = HtmlUtils.removeXSS(displayName);
|
||||
|
||||
Action action = new Action(MiscUtils.getTime(), Actions.NEW_NICKNAME, info);
|
||||
|
||||
|
@ -49,12 +49,12 @@ public class RegisterProcessor extends PlayerProcessor {
|
||||
if (!usersTable.isRegistered(uuid)) {
|
||||
usersTable.registerUser(uuid, registered, name);
|
||||
}
|
||||
if (db.getActionsTable().getActions(uuid).size() > 0) {
|
||||
return;
|
||||
}
|
||||
if (!userInfoTable.isRegistered(uuid)) {
|
||||
userInfoTable.registerUserInfo(uuid, registered);
|
||||
}
|
||||
if (db.getActionsTable().getActions(uuid).size() > 0) {
|
||||
return;
|
||||
}
|
||||
plugin.getDataCache().markFirstSession(uuid);
|
||||
db.getActionsTable().insertAction(uuid, new Action(time, Actions.FIRST_SESSION, "Online: " + playersOnline + " Players"));
|
||||
} catch (SQLException e) {
|
||||
|
@ -13,6 +13,7 @@ import main.java.com.djrapitops.plan.api.exceptions.WebAPIException;
|
||||
import main.java.com.djrapitops.plan.systems.info.BukkitInformationManager;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.response.Response;
|
||||
import main.java.com.djrapitops.plan.systems.webserver.webapi.WebAPI;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@ -53,6 +54,7 @@ public class PingWebAPI extends WebAPI {
|
||||
|
||||
public void sendRequest(String address, String accessCode) throws WebAPIException {
|
||||
addVariable("accessKey", accessCode);
|
||||
addVariable("version", MiscUtils.getIPlan().getVersion());
|
||||
sendRequest(address);
|
||||
}
|
||||
}
|
@ -119,6 +119,11 @@ public class FormatUtils {
|
||||
}
|
||||
if (minutes != 0) {
|
||||
String m = Settings.FORMAT_MINUTES.toString().replace("%minutes%", String.valueOf(minutes));
|
||||
if (hours == 0 && m.contains("%hours%")) {
|
||||
m = m.replace("%hours%", Settings.FORMAT_MINUTES.toString().replace("%zero%", "0") + "0");
|
||||
} else {
|
||||
m = m.replace("%hours", "");
|
||||
}
|
||||
if (m.contains("%zero%") && String.valueOf(minutes).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
@ -126,6 +131,11 @@ public class FormatUtils {
|
||||
}
|
||||
if (seconds != 0) {
|
||||
String s = Settings.FORMAT_SECONDS.toString().replace("%seconds%", String.valueOf(seconds));
|
||||
if (minutes == 0 && s.contains("%minutes%")) {
|
||||
s = s.replace("%minutes%", Settings.FORMAT_MINUTES.toString().replace("%hours", "").replace("%zero%", "0") + 0);
|
||||
} else {
|
||||
s = s.replace("%minutes%", "");
|
||||
}
|
||||
if (s.contains("%zero%") && String.valueOf(seconds).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import main.java.com.djrapitops.plan.data.additional.AnalysisType;
|
||||
import main.java.com.djrapitops.plan.data.additional.HookHandler;
|
||||
import main.java.com.djrapitops.plan.data.additional.PluginData;
|
||||
import main.java.com.djrapitops.plan.data.analysis.*;
|
||||
import main.java.com.djrapitops.plan.data.time.GMTimes;
|
||||
import main.java.com.djrapitops.plan.data.time.WorldTimes;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.database.tables.TPSTable;
|
||||
@ -110,7 +111,6 @@ public class Analysis {
|
||||
AnalysisData analysisData = new AnalysisData();
|
||||
List<PluginData> thirdPartyPlugins = plugin.getHookHandler().getAdditionalDataSources();
|
||||
analysisData.setPluginsTabLayout(HtmlStructure.createAnalysisPluginsTabLayout(thirdPartyPlugins));
|
||||
analysisData.setPlanVersion(plugin.getVersion());
|
||||
|
||||
Benchmark.stop("Analysis", "Create Empty dataset");
|
||||
fillDataset(analysisData, db);
|
||||
@ -261,17 +261,12 @@ public class Analysis {
|
||||
}
|
||||
}
|
||||
|
||||
Map<UUID, UserInfo> mappedUserInfo = new HashMap<>();
|
||||
userInfo.forEach(u -> mappedUserInfo.put(u.getUuid(), u));
|
||||
|
||||
Map<UUID, Long> lastSeen = db.getSessionsTable().getLastSeenForAllPlayers();
|
||||
for (Map.Entry<UUID, Long> entry : lastSeen.entrySet()) {
|
||||
UserInfo user = mappedUserInfo.get(entry.getKey());
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
user.setLastSeen(entry.getValue());
|
||||
for (UserInfo info : userInfo) {
|
||||
Long userLastSeen = lastSeen.getOrDefault(info.getUuid(), 0L);
|
||||
info.setLastSeen(userLastSeen);
|
||||
}
|
||||
|
||||
userInfo.sort(new UserInfoLastPlayedComparator());
|
||||
|
||||
activity.setRecentPlayersUUIDs(userInfo.stream().map(UserInfo::getUuid).collect(Collectors.toList()));
|
||||
@ -279,7 +274,7 @@ public class Analysis {
|
||||
|
||||
playerCount.addPlayers(userInfo.stream().map(UserInfo::getUuid).collect(Collectors.toSet()));
|
||||
|
||||
Map<UUID, Long> registered = mappedUserInfo.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getRegistered()));
|
||||
Map<UUID, Long> registered = userInfo.stream().collect(Collectors.toMap(UserInfo::getUuid, UserInfo::getRegistered));
|
||||
joinInfo.addRegistered(registered);
|
||||
activity.addBans(userInfo.stream().filter(UserInfo::isBanned).map(UserInfo::getUuid).collect(Collectors.toSet()));
|
||||
|
||||
@ -292,15 +287,25 @@ public class Analysis {
|
||||
joinInfo.addSessions(sessions);
|
||||
}
|
||||
|
||||
Map<UUID, List<String>> geolocations = db.getIpsTable().getAllGeolocations();
|
||||
geolocPart.addGeoLocations(geolocations);
|
||||
|
||||
analysisData.setPlayersTable(PlayersTableCreator.createTable(userInfo, joinInfo, geolocPart));
|
||||
|
||||
Map<UUID, List<PlayerKill>> playerKills = db.getKillsTable().getPlayerKills();
|
||||
killPart.addKills(playerKills);
|
||||
|
||||
Map<UUID, List<String>> geolocations = db.getIpsTable().getAllGeolocations();
|
||||
geolocPart.addGeoLocations(geolocations);
|
||||
|
||||
WorldTimes worldTimes = db.getWorldTimesTable().getWorldTimesOfServer();
|
||||
|
||||
// Add 0 time for worlds not present.
|
||||
Set<String> nonZeroWorlds = worldTimes.getWorldTimes().keySet();
|
||||
for (String world : db.getWorldTable().getWorlds()) {
|
||||
if (nonZeroWorlds.contains(world)) {
|
||||
continue;
|
||||
}
|
||||
worldTimes.setGMTimesForWorld(world, new GMTimes());
|
||||
}
|
||||
|
||||
worldPart.setWorldTimes(worldTimes);
|
||||
|
||||
playtime.setTotalPlaytime(db.getSessionsTable().getPlaytimeOfServer());
|
||||
|
@ -1,6 +1,5 @@
|
||||
package main.java.com.djrapitops.plan.utilities.html;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -34,13 +33,27 @@ public enum Html {
|
||||
BUTTON("<a class=\"button\" href=\"${0}\">${1}</a>"),
|
||||
BUTTON_CLASS("class=\"button\""),
|
||||
LINK("<a class=\"link\" href=\"${0}\">${1}</a>"),
|
||||
LINK_TOOLTIP("<a title=\"${2}\" class=\"link\" href=\"${0}\">${1}</a>"),
|
||||
LINK_EXTERNAL("<a class=\"link\" target=\"_blank\" href=\"${0}\">${1}</a>"),
|
||||
LINK_CLASS("class=\"link\""),
|
||||
IMG("<img src=\"${0}\">"),
|
||||
//
|
||||
PARAGRAPH("<p>${0}</p>"),
|
||||
HEADER("<h1>${0}</h1>"),
|
||||
HEADER_2("<h2>${0}</h2>"),
|
||||
//
|
||||
DIV_W_CLASS("<div class=\"${0}\">${1}</div>"),
|
||||
DIV_W_CLASS_STYLE("<div class=\"${0}\" style=\"${1}\">${2}</div>"),
|
||||
//
|
||||
ROW(DIV_W_CLASS.parse("row", "${0}")),
|
||||
//
|
||||
TABLE_END("</tbody></table>"),
|
||||
TABLE_START_2("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th></tr></thead><tbody>"),
|
||||
TABLE_START_3("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th></tr></thead><tbody>"),
|
||||
TABLE_START_4("<table class=\"sortable table\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th><th>${3}</th></tr></thead><tbody>"),
|
||||
TABLE_SESSIONS(DIV_W_CLASS_STYLE.parse("box-footer scrollbar", "padding: 2px;",
|
||||
TABLE_START_4.parse("Player", "Started", "Length", "World - Time") + "${0}" + TABLE_END.parse())
|
||||
),
|
||||
TABLE_SESSIONS_START(TABLE_START_3.parse("Session Started", "Session Ended", "Session Length")),
|
||||
TABLE_KILLS_START(TABLE_START_3.parse(FONT_AWESOME_ICON.parse("clock-o") + " Time", "Killed", "With")),
|
||||
TABLE_FACTIONS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("flag") + " Faction", FONT_AWESOME_ICON.parse("bolt") + " Power", FONT_AWESOME_ICON.parse("map-o") + " Land", FONT_AWESOME_ICON.parse("user") + " Leader")),
|
||||
@ -50,8 +63,7 @@ public enum Html {
|
||||
TABLELINE_4("<tr><td><b>${0}</b></td><td>${1}</td><td>${2}</td><td>${3}</td></tr>"),
|
||||
TABLELINE_PLAYERS("<tr><td>${0}</td><td>${1}</td><td sorttable_customkey=\"${2}\">${3}</td><td>${4}</td><td sorttable_customkey=\"${5}\">${6}</td>" + "<td sorttable_customkey=\"${7}\">${8}</td><td>${9}</td></tr>"),
|
||||
TABLELINE_3_CUSTOMKEY("<tr><td sorttable_customkey=\"${0}\">${1}</td><td sorttable_customkey=\"${2}\">${3}</td><td sorttable_customkey=\"${4}\">${5}</td></tr>"),
|
||||
TABLELINE_3_CUSTOMKEY_1("<tr><td sorttable_customkey=\"${0}\">${1}</td><td>${2}</td><td>${3}</td></tr>"),
|
||||
TABLE_END("</tbody></table>");
|
||||
TABLELINE_3_CUSTOMKEY_1("<tr><td sorttable_customkey=\"${0}\">${1}</td><td>${2}</td><td>${3}</td></tr>");
|
||||
|
||||
private final String html;
|
||||
|
||||
|
@ -12,8 +12,8 @@ import main.java.com.djrapitops.plan.data.additional.PluginData;
|
||||
import main.java.com.djrapitops.plan.systems.info.BukkitInformationManager;
|
||||
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.tables.KillsTableCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
@ -92,114 +92,33 @@ public class HtmlStructure {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String[] createSessionsTabContent(Map<String, List<Session>> sessions, List<Session> allSessions) throws FileNotFoundException {
|
||||
Map<Integer, String> serverNameIDRelationMap = new HashMap<>();
|
||||
|
||||
if (Verify.isEmpty(allSessions)) {
|
||||
return new String[]{"<div class=\"session column\">" +
|
||||
"<div class=\"session-header\">" +
|
||||
"<div class=\"session-col\" style=\"width: 200%;\">" +
|
||||
"<h3>No Sessions</h3>" +
|
||||
"</div></div></div>", ""};
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<Session>> entry : sessions.entrySet()) {
|
||||
String serverName = entry.getKey();
|
||||
List<Session> serverSessions = entry.getValue();
|
||||
for (Session session : serverSessions) {
|
||||
serverNameIDRelationMap.put(session.getSessionID(), serverName);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder html = new StringBuilder();
|
||||
StringBuilder viewScript = new StringBuilder();
|
||||
int i = 0;
|
||||
for (Session session : allSessions) {
|
||||
if (i >= 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
String sessionStart = FormatUtils.formatTimeStampYear(session.getSessionStart());
|
||||
String sessionLength = FormatUtils.formatTimeAmount(session.getLength());
|
||||
String sessionEnd = FormatUtils.formatTimeStampYear(session.getSessionEnd());
|
||||
|
||||
String dotSeparated = separateWithDots(sessionStart, sessionLength);
|
||||
|
||||
// Session-column starts & header.
|
||||
html.append("<div class=\"session column\">")
|
||||
.append("<div class=\"session-header\">")
|
||||
.append("<div class=\"session-col\" style=\"width: 200%;\">")
|
||||
.append("<h3><i style=\"color:#777\" class=\"fa fa-chevron-down\" aria-hidden=\"true\"></i> ").append(dotSeparated).append("</h3>")
|
||||
.append("</div>")
|
||||
.append("</div>");
|
||||
|
||||
String serverName = serverNameIDRelationMap.get(session.getSessionID());
|
||||
|
||||
// Left side of Session box
|
||||
html.append("<div class=\"session-content\">")
|
||||
.append("<div class=\"row\">") //
|
||||
.append("<div class=\"session-col\" style=\"padding: 0px;\">");
|
||||
|
||||
// Left side header
|
||||
html.append("<div class=\"box-header\" style=\"margin: 0px;\">")
|
||||
.append("<h2><i class=\"fa fa-calendar\" aria-hidden=\"true\"></i> ")
|
||||
.append(sessionStart)
|
||||
.append("</h2>")
|
||||
.append("</div>");
|
||||
|
||||
// Left side content
|
||||
html.append("<div class=\"box\" style=\"margin: 0px;\">")
|
||||
.append("<p>Session Length: ").append(sessionLength).append("<br>")
|
||||
.append("Session Ended: ").append(sessionEnd).append("<br>")
|
||||
.append("Server: ").append(serverName).append("<br><br>")
|
||||
.append("Mob Kills: ").append(session.getMobKills()).append("<br>")
|
||||
.append("Deaths: ").append(session.getDeaths()).append("</p>");
|
||||
|
||||
html.append(KillsTableCreator.createTable(session.getPlayerKills()))
|
||||
.append("</div>"); // Left Side content ends
|
||||
|
||||
// Left side ends & Right side starts
|
||||
html.append("</div>")
|
||||
.append("<div class=\"session-col\">");
|
||||
|
||||
String id = "worldPie" + session.getSessionStart() + i;
|
||||
|
||||
html.append("<div id=\"").append(id).append("\" style=\"width: 100%; height: 400px;\"></div>");
|
||||
|
||||
String[] worldData = WorldPieCreator.createSeriesData(session.getWorldTimes());
|
||||
|
||||
html.append("<script>")
|
||||
.append("var ").append(id).append("series = {name:'World Playtime',colors: worldPieColors,colorByPoint:true,data:").append(worldData[0]).append("};")
|
||||
.append("var ").append(id).append("gmseries = ").append(worldData[1]).append(";")
|
||||
.append("</script>");
|
||||
|
||||
viewScript.append("worldPie(")
|
||||
.append(id).append(", ")
|
||||
.append(id).append("series, ")
|
||||
.append(id).append("gmseries")
|
||||
.append(");");
|
||||
|
||||
// Session-col, Row, Session-Content, Session-column ends.
|
||||
html.append("</div>")
|
||||
.append("</div>")
|
||||
.append("</div>")
|
||||
.append("</div>");
|
||||
|
||||
i++;
|
||||
}
|
||||
return new String[]{html.toString(), viewScript.toString()};
|
||||
public static String[] createSessionsTabContentInspectPage(Map<String, List<Session>> sessions, List<Session> allSessions, UUID uuid) throws FileNotFoundException {
|
||||
Map<UUID, Map<String, List<Session>>> map = new HashMap<>();
|
||||
map.put(uuid, sessions);
|
||||
return SessionTabStructureCreator.creteStructure(map, allSessions, false);
|
||||
}
|
||||
|
||||
public static String createInspectPageTabContent(String serverName, List<PluginData> plugins, Map<String, Serializable> replaceMap) {
|
||||
private static String[] getSessionsAsTable(Map<String, List<Session>> sessions, List<Session> allSessions, UUID uuid) {
|
||||
Map<Integer, UUID> uuidByID = new HashMap<>();
|
||||
for (List<Session> sessionList : sessions.values()) {
|
||||
for (Session session : sessionList) {
|
||||
uuidByID.put(session.getSessionID(), uuid);
|
||||
}
|
||||
}
|
||||
|
||||
return new String[]{Html.TABLE_SESSIONS.parse(SessionsTableCreator.createTable(uuidByID, allSessions)[0]), ""};
|
||||
}
|
||||
|
||||
public static String createInspectPluginsTabContent(String serverName, List<PluginData> plugins, Map<String, Serializable> replaceMap) {
|
||||
if (plugins.isEmpty()) {
|
||||
return "<div class=\"plugins-server\">" +
|
||||
"<div class=\"plugins-header\">" +
|
||||
"<div class=\"row\">" +
|
||||
"<div class=\"column\">" +
|
||||
"<div class=\"box-header\">" +
|
||||
"<h2><i class=\"fa fa-server\" aria-hidden=\"true\"></i> " + serverName +
|
||||
"</h2><p>No Compatible Plugins</p>" +
|
||||
"</div></div></div></div></div>";
|
||||
String icon = Html.FONT_AWESOME_ICON.parse("server");
|
||||
// TODO Move plain text to Locale
|
||||
String headerText = Html.HEADER_2.parse(icon + " " + serverName) + Html.PARAGRAPH.parse("No Compatible Plugins");
|
||||
return Html.DIV_W_CLASS.parse("plugins-server",
|
||||
Html.DIV_W_CLASS.parse("plugins-header",
|
||||
Html.ROW.parse(Html.DIV_W_CLASS.parse("box-header", headerText))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, List<String>> placeholders = getPlaceholdersInspect(plugins);
|
||||
@ -213,7 +132,7 @@ public class HtmlStructure {
|
||||
.append("<div class=\"box-header\">")
|
||||
.append("<h2><i style=\"padding: 8px;\" class=\"fa fa-chevron-down\" aria-hidden=\"true\"></i> ")
|
||||
.append(serverName)
|
||||
.append(" <i class=\"fa fa-server\" aria-hidden=\"true\"></i></h2>")
|
||||
.append("</h2>")
|
||||
.append("</div>")
|
||||
.append("</div>")
|
||||
.append("</div>")
|
||||
@ -385,6 +304,7 @@ public class HtmlStructure {
|
||||
int i = 0;
|
||||
StringBuilder b = new StringBuilder();
|
||||
List<String> values = new ArrayList<>(networkPageContents.values());
|
||||
Collections.sort(values);
|
||||
int size = values.size();
|
||||
int extra = size % 3;
|
||||
for (int j = 0; j < extra; j++) {
|
||||
|
@ -3,6 +3,9 @@ package main.java.com.djrapitops.plan.utilities.html.graphs;
|
||||
import main.java.com.djrapitops.plan.data.time.GMTimes;
|
||||
import main.java.com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -25,11 +28,13 @@ public class WorldPieCreator {
|
||||
Map<String, Long> playtimePerWorld = worldTimes.getWorldTimes().entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getTotal()));
|
||||
|
||||
List<String> worlds = new ArrayList<>(playtimePerWorld.keySet());
|
||||
Collections.sort(worlds);
|
||||
|
||||
int size = playtimePerWorld.size();
|
||||
for (Map.Entry<String, Long> world : playtimePerWorld.entrySet()) {
|
||||
String worldName = world.getKey();
|
||||
for (String worldName : worlds) {
|
||||
seriesBuilder.append("{name:'").append(worldName)
|
||||
.append("',y:").append(world.getValue())
|
||||
.append("',y:").append(playtimePerWorld.getOrDefault(worldName, 0L))
|
||||
.append(",drilldown: '").append(worldName).append("'");
|
||||
|
||||
seriesBuilder.append("}");
|
||||
|
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package main.java.com.djrapitops.plan.utilities.html.structure;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.Settings;
|
||||
import main.java.com.djrapitops.plan.data.Session;
|
||||
import main.java.com.djrapitops.plan.data.analysis.JoinInfoPart;
|
||||
import main.java.com.djrapitops.plan.data.time.GMTimes;
|
||||
import main.java.com.djrapitops.plan.data.time.WorldTimes;
|
||||
import main.java.com.djrapitops.plan.utilities.FormatUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.Html;
|
||||
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.tables.KillsTableCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* //TODO Class Javadoc Comment
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class SessionTabStructureCreator {
|
||||
|
||||
public static String[] creteStructure(Map<UUID, Map<String, List<Session>>> sessions, List<Session> allSessions, boolean appendName) {
|
||||
|
||||
Map<Integer, UUID> uuidsByID = generateIDtoUUIDMap(sessions);
|
||||
|
||||
if (Settings.DISPLAY_SESSIONS_AS_TABLE.isTrue()) {
|
||||
return new String[]{Html.TABLE_SESSIONS.parse(SessionsTableCreator.createTable(uuidsByID, allSessions)[0]), ""};
|
||||
}
|
||||
|
||||
if (Verify.isEmpty(allSessions)) {
|
||||
return new String[]{"<div class=\"session column\">" +
|
||||
"<div class=\"session-header\">" +
|
||||
"<div class=\"session-col\" style=\"width: 200%;\">" +
|
||||
"<h3>No Sessions</h3>" +
|
||||
"</div></div></div>", ""};
|
||||
}
|
||||
|
||||
Map<Integer, String> serverNameIDMap = generateIDtoServerNameMap(sessions);
|
||||
|
||||
StringBuilder html = new StringBuilder();
|
||||
StringBuilder viewScript = new StringBuilder();
|
||||
int i = 0;
|
||||
for (Session session : allSessions) {
|
||||
if (i >= 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
int sessionID = session.getSessionID();
|
||||
UUID uuid = uuidsByID.get(sessionID);
|
||||
String serverName = serverNameIDMap.get(sessionID);
|
||||
|
||||
String sessionStart = FormatUtils.formatTimeStampYear(session.getSessionStart());
|
||||
String sessionLength = FormatUtils.formatTimeAmount(session.getLength());
|
||||
String sessionEnd = FormatUtils.formatTimeStampYear(session.getSessionEnd());
|
||||
|
||||
String name = Plan.getInstance().getDataCache().getName(uuid);
|
||||
String link = Html.LINK.parse(Plan.getPlanAPI().getPlayerInspectPageLink(name), name);
|
||||
String dotSeparated = appendName ?
|
||||
HtmlStructure.separateWithDots(link, sessionStart, sessionLength) :
|
||||
HtmlStructure.separateWithDots(sessionStart, sessionLength);
|
||||
|
||||
// Session-column starts & header.
|
||||
html.append("<div class=\"session column\">")
|
||||
.append("<div title=\"Session ID: ").append(sessionID).append("\" class=\"session-header\">")
|
||||
.append("<div class=\"session-col\" style=\"width: 200%;\">")
|
||||
.append("<h3><i style=\"color:#777\" class=\"fa fa-chevron-down\" aria-hidden=\"true\"></i> ").append(dotSeparated).append("</h3>")
|
||||
.append("</div>")
|
||||
.append("</div>");
|
||||
|
||||
|
||||
// Left side of Session box
|
||||
html.append("<div class=\"session-content\">")
|
||||
.append("<div class=\"row\">") //
|
||||
.append("<div class=\"session-col\" style=\"padding: 0px;\">");
|
||||
|
||||
// Left side header
|
||||
html.append("<div class=\"box-header\" style=\"margin: 0px;\">")
|
||||
.append("<h2><i class=\"fa fa-calendar\" aria-hidden=\"true\"></i> ")
|
||||
.append(sessionStart)
|
||||
.append("</h2>")
|
||||
.append("</div>");
|
||||
|
||||
// Left side content
|
||||
html.append("<div class=\"box\" style=\"margin: 0px;\">")
|
||||
.append("<p>Session Length: ").append(sessionLength).append("<br>")
|
||||
.append("Session Ended: ").append(sessionEnd).append("<br>")
|
||||
.append("Server: ").append(serverName).append("<br><br>")
|
||||
.append("Mob Kills: ").append(session.getMobKills()).append("<br>")
|
||||
.append("Deaths: ").append(session.getDeaths()).append("</p>");
|
||||
|
||||
html.append(KillsTableCreator.createTable(session.getPlayerKills()))
|
||||
.append("</div>"); // Left Side content ends
|
||||
|
||||
// Left side ends & Right side starts
|
||||
html.append("</div>")
|
||||
.append("<div class=\"session-col\">");
|
||||
|
||||
String id = "worldPie" + session.getSessionStart() + i;
|
||||
|
||||
html.append("<div id=\"").append(id).append("\" style=\"width: 100%; height: 400px;\"></div>");
|
||||
|
||||
WorldTimes worldTimes = session.getWorldTimes();
|
||||
|
||||
try {
|
||||
// Add 0 time for worlds not present.
|
||||
Set<String> nonZeroWorlds = worldTimes.getWorldTimes().keySet();
|
||||
for (String world : MiscUtils.getIPlan().getDB().getWorldTable().getWorlds()) {
|
||||
if (nonZeroWorlds.contains(world)) {
|
||||
continue;
|
||||
}
|
||||
worldTimes.setGMTimesForWorld(world, new GMTimes());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.toLog("SessionTabStructureCreator", e);
|
||||
}
|
||||
|
||||
String[] worldData = WorldPieCreator.createSeriesData(worldTimes);
|
||||
|
||||
html.append("<script>")
|
||||
.append("var ").append(id).append("series = {name:'World Playtime',colors: worldPieColors,colorByPoint:true,data:").append(worldData[0]).append("};")
|
||||
.append("var ").append(id).append("gmseries = ").append(worldData[1]).append(";")
|
||||
.append("</script>");
|
||||
|
||||
viewScript.append("worldPie(")
|
||||
.append(id).append(", ")
|
||||
.append(id).append("series, ")
|
||||
.append(id).append("gmseries")
|
||||
.append(");");
|
||||
|
||||
// Session-col, Row, Session-Content, Session-column ends.
|
||||
html.append("</div>")
|
||||
.append("</div>")
|
||||
.append("</div>")
|
||||
.append("</div>");
|
||||
|
||||
i++;
|
||||
}
|
||||
return new String[]{html.toString(), viewScript.toString()};
|
||||
}
|
||||
|
||||
private static Map<Integer, String> generateIDtoServerNameMap(Map<UUID, Map<String, List<Session>>> sessions) {
|
||||
Map<Integer, String> serverNameIDRelationMap = new HashMap<>();
|
||||
for (Map<String, List<Session>> map : sessions.values()) {
|
||||
for (Map.Entry<String, List<Session>> entry : map.entrySet()) {
|
||||
String serverName = entry.getKey();
|
||||
List<Session> serverSessions = entry.getValue();
|
||||
for (Session session : serverSessions) {
|
||||
serverNameIDRelationMap.put(session.getSessionID(), serverName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return serverNameIDRelationMap;
|
||||
}
|
||||
|
||||
private static Map<Integer, UUID> generateIDtoUUIDMap(Map<UUID, Map<String, List<Session>>> sessions) {
|
||||
Map<Integer, UUID> uuidsByID = new HashMap<>();
|
||||
for (Map.Entry<UUID, Map<String, List<Session>>> entry : sessions.entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
for (List<Session> sessionList : entry.getValue().values()) {
|
||||
for (Session session : sessionList) {
|
||||
uuidsByID.put(session.getSessionID(), uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return uuidsByID;
|
||||
}
|
||||
|
||||
public static String[] creteStructure(JoinInfoPart joinInfoPart) {
|
||||
Map<UUID, Map<String, List<Session>>> map = new HashMap<>();
|
||||
Map<UUID, List<Session>> sessions = joinInfoPart.getSessions();
|
||||
for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) {
|
||||
Map<String, List<Session>> serverSpecificMap = new HashMap<>();
|
||||
serverSpecificMap.put("This server", entry.getValue());
|
||||
map.put(entry.getKey(), serverSpecificMap);
|
||||
}
|
||||
|
||||
List<Session> allSessions = sessions.values().stream()
|
||||
.flatMap(Collection::stream)
|
||||
.sorted(new SessionStartComparator())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return creteStructure(map, allSessions, true);
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import java.util.*;
|
||||
*/
|
||||
public class SessionsTableCreator {
|
||||
|
||||
public static String[] createTables(JoinInfoPart joinInfoPart) {
|
||||
public static String[] createTable(JoinInfoPart joinInfoPart) {
|
||||
Map<Integer, UUID> uuidByID = new HashMap<>();
|
||||
for (Map.Entry<UUID, List<Session>> entry : joinInfoPart.getSessions().entrySet()) {
|
||||
List<Session> sessions = entry.getValue();
|
||||
@ -34,6 +34,10 @@ public class SessionsTableCreator {
|
||||
}
|
||||
|
||||
List<Session> allSessions = joinInfoPart.getAllSessions();
|
||||
return createTable(uuidByID, allSessions);
|
||||
}
|
||||
|
||||
public static String[] createTable(Map<Integer, UUID> uuidByID, List<Session> allSessions) {
|
||||
if (allSessions.isEmpty()) {
|
||||
return new String[]{Html.TABLELINE_4.parse("<b>No Sessions</b>", "", "", ""),
|
||||
Html.TABLELINE_2.parse("<b>No Sessions</b>", "")};
|
||||
@ -73,8 +77,9 @@ public class SessionsTableCreator {
|
||||
String world = getLongestWorldPlayed(session);
|
||||
|
||||
String inspectUrl = Plan.getPlanAPI().getPlayerInspectPageLink(name);
|
||||
String toolTip = "Session ID: " + (session.isFetchedFromDB() ? session.getSessionID() : "Not Saved.");
|
||||
sessionTableBuilder.append(Html.TABLELINE_4.parse(
|
||||
Html.LINK.parse(inspectUrl, name),
|
||||
Html.LINK_TOOLTIP.parse(inspectUrl, name, toolTip),
|
||||
start,
|
||||
length,
|
||||
world
|
||||
|
@ -1,4 +1,4 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: main.java.com.djrapitops.plan.PlanBungee
|
||||
version: 4.0.2
|
||||
version: 4.0.3
|
@ -52,6 +52,8 @@ Data:
|
||||
|
||||
Customization:
|
||||
UseServerTime: true
|
||||
Display:
|
||||
SessionsAsTable: false
|
||||
Formatting:
|
||||
DecimalPoints: '#.##'
|
||||
TimeAmount:
|
||||
|
@ -41,7 +41,7 @@
|
||||
<h2><i class="fa fa-info-circle"></i> Information</h2>
|
||||
</div>
|
||||
<div class="box" style="height: 75%;">
|
||||
<p>${playersOnline}/${playersMax} Players Online</p>
|
||||
<p>${playersOnline} Players Online</p>
|
||||
<p>${playersTotal} Total Players</p>
|
||||
<p>${playersNewDay} New Players Today<br>${playersNewWeek} New Players This Week</p>
|
||||
</div>
|
||||
|
@ -14,6 +14,10 @@
|
||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var worldPieColors = [${worldPieColors}];
|
||||
var gmPieColors = [${gmPieColors}];
|
||||
</script>
|
||||
<header>
|
||||
<div>
|
||||
<div class="right fa-stack fa-lg" style="padding: 23px; margin:8px">
|
||||
@ -183,21 +187,7 @@
|
||||
<div class="box-header">
|
||||
<h2><i class="fa fa-calendar"></i> 50 Most Recent Sessions</h2>
|
||||
</div>
|
||||
<div class="box-footer scrollbar" style="padding: 2px;">
|
||||
<table class="sortable table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Player</th>
|
||||
<th>Started</th>
|
||||
<th>Length</th>
|
||||
<th>World - Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${tableBodySessions}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
${contentSessions}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -358,6 +348,7 @@
|
||||
<script src="./js/performanceGraph.js"></script>
|
||||
<script src="./js/worldMap.js"></script>
|
||||
<script src="./js/worldPie.js"></script>
|
||||
<script src="./js/sessionTabExpand.js"></script>
|
||||
<script>
|
||||
Highcharts.setOptions({
|
||||
lang: {noData: "No Data to Display"},
|
||||
@ -449,8 +440,6 @@
|
||||
y: ${banned}
|
||||
}]
|
||||
};
|
||||
var worldPieColors = [${worldPieColors}];
|
||||
var gmPieColors = [${gmPieColors}];
|
||||
var worldSeries = {
|
||||
name: 'World Playtime',
|
||||
colorByPoint: true,
|
||||
@ -473,7 +462,14 @@
|
||||
</script>
|
||||
<script>
|
||||
$( function() {
|
||||
$( "#tabs" ).tabs();
|
||||
var resourceTab = window.sessionStorage.getItem("AnalysisResourceTab");
|
||||
if (resourceTab == null) {
|
||||
resourceTab = 1;
|
||||
}
|
||||
$( "#tabs" ).tabs({active: resourceTab});
|
||||
$( "#tabs" ).on("tabsactivate", function(event, ui) {
|
||||
window.sessionStorage.setItem("AnalysisResourceTab", $( "#tabs" ).tabs( "option", "active" ));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
@ -502,6 +498,7 @@
|
||||
worldChart('worldGraph', entitySeries, chunkSeries, playersOnlineSeries);
|
||||
worldMap('choropleth', '#EEFFEE', '#267f00', mapSeries);
|
||||
punchCard('punchcard', punchcardSeries);
|
||||
${sessionTabGraphViewFunctions}
|
||||
/*countUpTimer();*/
|
||||
|
||||
function openFunc(i) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: main.java.com.djrapitops.plan.Plan
|
||||
version: 4.0.2
|
||||
version: 4.0.3
|
||||
softdepend:
|
||||
- OnTime
|
||||
- EssentialsX
|
||||
|
@ -437,6 +437,11 @@ public class DatabaseTest {
|
||||
assertNull(sessions.get(worlds.get(1)));
|
||||
|
||||
assertEquals(session, savedSessions.get(0));
|
||||
|
||||
Map<UUID, Long> lastSeen = sessionsTable.getLastSeenForAllPlayers();
|
||||
assertTrue(lastSeen.containsKey(uuid));
|
||||
assertFalse(lastSeen.containsKey(uuid2));
|
||||
assertEquals(22345L, (long) lastSeen.get(uuid));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,9 +67,10 @@ public class ComparatorTest {
|
||||
longValues.sort(Long::compare);
|
||||
|
||||
Collections.reverse(longValues);
|
||||
System.out.println(longValues);
|
||||
userInfo.sort(new UserInfoLastPlayedComparator());
|
||||
List<Long> afterSort = userInfo.stream().map(UserInfo::getLastSeen).collect(Collectors.toList());
|
||||
|
||||
System.out.println(afterSort);
|
||||
assertEquals(longValues, afterSort);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import test.java.utils.MockUtils;
|
||||
import test.java.utils.RandomData;
|
||||
import test.java.utils.TestInit;
|
||||
|
||||
@ -47,7 +48,7 @@ public class HtmlStructureTest {
|
||||
@Test
|
||||
public void createSessionsTabContent() throws Exception {
|
||||
List<Session> allSessions = sessions.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||
String[] sessionsTab = HtmlStructure.createSessionsTabContent(sessions, allSessions);
|
||||
String[] sessionsTab = HtmlStructure.createSessionsTabContentInspectPage(sessions, allSessions, MockUtils.getPlayerUUID());
|
||||
|
||||
int opened = StringUtils.countMatches(sessionsTab[0], "<div");
|
||||
int closed = StringUtils.countMatches(sessionsTab[0], "</div");
|
||||
|
Binary file not shown.
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.djrapitops</groupId>
|
||||
<artifactId>PlanPluginBridge</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.3</version>
|
||||
<packaging>jar</packaging>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
@ -13,6 +13,8 @@ import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook;
|
||||
import com.djrapitops.pluginbridge.plan.towny.TownyHook;
|
||||
import com.djrapitops.pluginbridge.plan.vault.VaultHook;
|
||||
import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionHook;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Settings;
|
||||
import main.java.com.djrapitops.plan.data.additional.HookHandler;
|
||||
|
||||
/**
|
||||
@ -56,7 +58,10 @@ public class Bridge {
|
||||
for (Hook hook : hooks) {
|
||||
try {
|
||||
hook.hook();
|
||||
} catch (Exception | NoClassDefFoundError ignore) {
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
if (Settings.DEV_MODE.isTrue()) {
|
||||
Log.toLog("PluginBridge", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ public abstract class Hook {
|
||||
|
||||
protected HookHandler hookHandler;
|
||||
|
||||
private Hook() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
* <p>
|
||||
@ -45,8 +49,9 @@ public abstract class Hook {
|
||||
/**
|
||||
* Constructor to set enabled to false.
|
||||
*/
|
||||
public Hook() {
|
||||
public Hook(HookHandler hookHandler) {
|
||||
enabled = false;
|
||||
this.hookHandler = hookHandler;
|
||||
}
|
||||
|
||||
protected void addPluginDataSource(PluginData pluginData) {
|
||||
|
@ -25,7 +25,7 @@ public class LiteBansHook extends Hook {
|
||||
*/
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public LiteBansHook(HookHandler hookH) {
|
||||
super();
|
||||
super(hookH);
|
||||
try {
|
||||
Database.get();
|
||||
enabled = true;
|
||||
|
Loading…
Reference in New Issue
Block a user