mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-23 09:37:54 +01:00
Merge remote-tracking branch 'origin/Version-3.4.2-or-3.5.0' into Version-3.4.2-or-3.5.0
# Conflicts: # Plan/src/main/java/com/djrapitops/plan/ui/graphs/PunchCardGraphCreator.java
This commit is contained in:
commit
d4ff5dd899
@ -73,8 +73,8 @@ public enum Phrase {
|
||||
ANALYSIS_FETCH_DATA(ANALYSIS + "Fetching Data.."),
|
||||
ANALYSIS_FAIL_NO_PLAYERS(ANALYSIS + "Analysis failed, no known players."),
|
||||
ANALYSIS_FAIL_NO_DATA(ANALYSIS + "Analysis failed, no data in the database."),
|
||||
ANALYSIS_BEGIN_ANALYSIS(ANALYSIS + "Data Fetched, beginning Analysis of data.."),
|
||||
ANALYSIS_COMPLETE(ANALYSIS + "Analysis Complete."),
|
||||
ANALYSIS_BEGIN_ANALYSIS(ANALYSIS + "Data Fetched (REPLACE0 users, took REPLACE1ms), beginning Analysis of data.."),
|
||||
ANALYSIS_COMPLETE(ANALYSIS + "Analysis Complete. (took REPLACE0ms) REPLACE1"),
|
||||
DATA_CORRUPTION_WARN("Some data might be corrupted: " + REPLACE0),
|
||||
//
|
||||
ERROR_CONSOLE_PLAYER("This point of code should not be accessable on console. Inform author: " + REPLACE0 + " Console: REPLACE1"),
|
||||
@ -113,6 +113,10 @@ public enum Phrase {
|
||||
CMD_MANAGE_HELP_HEADER(CMD_FOOTER + "" + COLOR_MAIN.color() + " Player Analytics - Managment Help"),
|
||||
CMD_MANAGE_STATUS_HEADER(CMD_FOOTER + "" + COLOR_MAIN.color() + " Player Analytics - Database status"),
|
||||
CMD_MANAGE_STATUS_ACTIVE_DB(CMD_BALL + "" + COLOR_MAIN.color() + " Active Database: " + COLOR_SEC.color() + "REPLACE0"),
|
||||
CMD_MANAGE_STATUS_QUEUE_SAVE(CMD_BALL + "" + COLOR_MAIN.color() + " Save Queue Size: " + COLOR_SEC.color() + "REPLACE0/"+Settings.PROCESS_SAVE_LIMIT.getNumber()),
|
||||
CMD_MANAGE_STATUS_QUEUE_GET(CMD_BALL + "" + COLOR_MAIN.color() + " Get Queue Size: " + COLOR_SEC.color() + "REPLACE0/"+Settings.PROCESS_GET_LIMIT.getNumber()),
|
||||
CMD_MANAGE_STATUS_QUEUE_CLEAR(CMD_BALL + "" + COLOR_MAIN.color() + " Clear Queue Size: " + COLOR_SEC.color() + "REPLACE0/"+Settings.PROCESS_CLEAR_LIMIT.getNumber()),
|
||||
CMD_MANAGE_STATUS_QUEUE_PROCESS(CMD_BALL + "" + COLOR_MAIN.color() + " Process Queue Size: " + COLOR_SEC.color() + "REPLACE0/20000"),
|
||||
CMD_CLICK_ME("Click Me"),
|
||||
CMD_LINK(COLOR_SEC.color() + " " + BALL + COLOR_MAIN.color() + " Link: " + COLOR_TER.color()),
|
||||
CMD_PASS_PLANLITE("UNUSED"),
|
||||
|
@ -62,6 +62,7 @@ public class Plan extends JavaPlugin {
|
||||
private HashSet<Database> databases;
|
||||
private WebSocketServer uiServer;
|
||||
private HookHandler hookHandler;
|
||||
private ServerVariableHolder variable;
|
||||
|
||||
private int bootAnalysisTaskID;
|
||||
|
||||
@ -80,7 +81,9 @@ public class Plan extends JavaPlugin {
|
||||
getDataFolder().mkdirs();
|
||||
|
||||
initLocale();
|
||||
|
||||
|
||||
variable = new ServerVariableHolder(this);
|
||||
|
||||
databases = new HashSet<>();
|
||||
databases.add(new MySQLDB(this));
|
||||
databases.add(new SQLiteDB(this));
|
||||
@ -130,6 +133,7 @@ public class Plan extends JavaPlugin {
|
||||
}
|
||||
|
||||
hookHandler = new HookHandler();
|
||||
|
||||
Log.debug("Verboose debug messages are enabled.");
|
||||
Log.info(Phrase.ENABLED + "");
|
||||
}
|
||||
@ -385,6 +389,10 @@ public class Plan extends JavaPlugin {
|
||||
Log.info("Using locale: " + usingLocale);
|
||||
}
|
||||
|
||||
public ServerVariableHolder getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the current instance of Plan.
|
||||
*
|
||||
|
@ -0,0 +1,20 @@
|
||||
package main.java.com.djrapitops.plan;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ServerVariableHolder {
|
||||
|
||||
private int maxPlayers;
|
||||
|
||||
public ServerVariableHolder(Plan plugin) {
|
||||
maxPlayers = plugin.getServer().getMaxPlayers();
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return maxPlayers;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -5,7 +5,6 @@ import main.java.com.djrapitops.plan.Phrase;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.command.CommandType;
|
||||
import main.java.com.djrapitops.plan.command.SubCommand;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@ -31,13 +30,17 @@ public class ManageStatusCommand extends SubCommand {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
||||
ChatColor hColor = Phrase.COLOR_TER.color();
|
||||
String[] messages = new String[]{
|
||||
Phrase.CMD_MANAGE_STATUS_HEADER + "",
|
||||
Phrase.CMD_MANAGE_STATUS_ACTIVE_DB.parse(plugin.getDB().getConfigName()),
|
||||
Phrase.CMD_MANAGE_STATUS_QUEUE_PROCESS.parse("" + plugin.getHandler().getProcessTask().size()),
|
||||
Phrase.CMD_MANAGE_STATUS_QUEUE_SAVE.parse("" + plugin.getHandler().getSaveTask().size()),
|
||||
Phrase.CMD_MANAGE_STATUS_QUEUE_GET.parse("" + plugin.getHandler().getGetTask().size()),
|
||||
Phrase.CMD_MANAGE_STATUS_QUEUE_CLEAR.parse("" + plugin.getHandler().getClearTask().size()),
|
||||
Phrase.CMD_FOOTER + ""
|
||||
};
|
||||
|
||||
sender.sendMessage(Phrase.CMD_MANAGE_STATUS_HEADER + "");
|
||||
|
||||
sender.sendMessage(Phrase.CMD_MANAGE_STATUS_ACTIVE_DB.parse(plugin.getDB().getConfigName()));
|
||||
|
||||
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
|
||||
sender.sendMessage(messages);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,10 @@ public class SessionData {
|
||||
this.sessionEnd = sessionEnd;
|
||||
}
|
||||
|
||||
public SessionData(SessionData s) {
|
||||
this.sessionStart = s.getSessionStart();
|
||||
this.sessionEnd = s.getSessionEnd();
|
||||
}
|
||||
/**
|
||||
* Ends the session with given end point.
|
||||
*
|
||||
|
@ -42,22 +42,24 @@ public class AdvancedAchievementsAchievements extends PluginData {
|
||||
|
||||
@Override
|
||||
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
|
||||
if (MiscUtils.getTime()- lastRefresh > 60000) {
|
||||
if (MiscUtils.getTime() - lastRefresh > 60000) {
|
||||
totalAchievements = aaAPI.getPlayersTotalAchievements();
|
||||
}
|
||||
if (totalAchievements.containsKey(uuid)) {
|
||||
return parseContainer(modifierPrefix,totalAchievements.get(uuid) + "");
|
||||
Integer total = totalAchievements.get(uuid);
|
||||
if (total != null) {
|
||||
return parseContainer(modifierPrefix, total + "");
|
||||
}
|
||||
return parseContainer(modifierPrefix, 0+"");
|
||||
return parseContainer(modifierPrefix, 0 + "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getValue(UUID uuid) {
|
||||
if (MiscUtils.getTime()- lastRefresh > 60000) {
|
||||
if (MiscUtils.getTime() - lastRefresh > 60000) {
|
||||
totalAchievements = aaAPI.getPlayersTotalAchievements();
|
||||
}
|
||||
if (totalAchievements.containsKey(uuid)) {
|
||||
return totalAchievements.get(uuid);
|
||||
Integer total = totalAchievements.get(uuid);
|
||||
if (total != null) {
|
||||
return total;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ public class DataCacheHandler extends LocationCache {
|
||||
|
||||
// Variables
|
||||
private int timesSaved;
|
||||
private int maxPlayers;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
@ -83,7 +82,6 @@ public class DataCacheHandler extends LocationCache {
|
||||
startQueues();
|
||||
|
||||
timesSaved = 0;
|
||||
maxPlayers = plugin.getServer().getMaxPlayers();
|
||||
|
||||
commandUse = new HashMap<>();
|
||||
if (!getCommandUseFromDb()) {
|
||||
@ -253,7 +251,7 @@ public class DataCacheHandler extends LocationCache {
|
||||
saveTask.stop();
|
||||
getTask.stop();
|
||||
clearTask.stop();
|
||||
List<HandlingInfo> toProcess = processTask.stop();
|
||||
List<HandlingInfo> toProcess = processTask.stopAndReturnLeftovers();
|
||||
Benchmark.start("ProcessOnlineHandlingInfo");
|
||||
Log.debug("ToProcess size: " + toProcess.size() + " DataCache size: " + dataCache.keySet().size());
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
@ -337,7 +335,7 @@ public class DataCacheHandler extends LocationCache {
|
||||
*/
|
||||
public void saveCommandUse() {
|
||||
try {
|
||||
db.saveCommandUse(commandUse);
|
||||
db.saveCommandUse(new HashMap<>(commandUse));
|
||||
} catch (SQLException | NullPointerException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
@ -347,15 +345,23 @@ public class DataCacheHandler extends LocationCache {
|
||||
* Refreshes the calculations for all online players with ReloadInfo.
|
||||
*/
|
||||
public void saveHandlerDataToCache() {
|
||||
Bukkit.getServer().getOnlinePlayers().parallelStream().forEach((p) -> {
|
||||
saveHandlerDataToCache(p);
|
||||
Bukkit.getServer().getOnlinePlayers().stream().forEach((p) -> {
|
||||
saveHandlerDataToCache(p, false);
|
||||
});
|
||||
}
|
||||
|
||||
private void saveHandlerDataToCache(Player player) {
|
||||
private void saveHandlerDataToCache(Player player, boolean pool) {
|
||||
long time = MiscUtils.getTime();
|
||||
UUID uuid = player.getUniqueId();
|
||||
addToPool(new ReloadInfo(uuid, time, player.getAddress().getAddress(), player.isBanned(), player.getDisplayName(), player.getGameMode()));
|
||||
ReloadInfo info = new ReloadInfo(uuid, time, player.getAddress().getAddress(), player.isBanned(), player.getDisplayName(), player.getGameMode());
|
||||
if (!pool) {
|
||||
UserData data = dataCache.get(uuid);
|
||||
if (data != null) {
|
||||
info.process(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
addToPool(info);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -474,22 +480,13 @@ public class DataCacheHandler extends LocationCache {
|
||||
newPlayer(player);
|
||||
}
|
||||
startSession(uuid);
|
||||
saveHandlerDataToCache(player);
|
||||
saveHandlerDataToCache(player, true);
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
}).runTaskAsynchronously(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by Analysis for Player activity graphs.
|
||||
*
|
||||
* @return Maximum number of players defined in server.properties.
|
||||
*/
|
||||
public int getMaxPlayers() {
|
||||
return maxPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to handle a command's execution.
|
||||
*
|
||||
@ -501,4 +498,20 @@ public class DataCacheHandler extends LocationCache {
|
||||
}
|
||||
commandUse.put(command, commandUse.get(command) + 1);
|
||||
}
|
||||
|
||||
public DataCacheSaveQueue getSaveTask() {
|
||||
return saveTask;
|
||||
}
|
||||
|
||||
public DataCacheClearQueue getClearTask() {
|
||||
return clearTask;
|
||||
}
|
||||
|
||||
public DataCacheProcessQueue getProcessTask() {
|
||||
return processTask;
|
||||
}
|
||||
|
||||
public DataCacheGetQueue getGetTask() {
|
||||
return getTask;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -13,6 +14,7 @@ import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.ExportUtility;
|
||||
|
||||
/**
|
||||
* This class stores UserData objects used for displaying the Html pages.
|
||||
@ -53,6 +55,11 @@ public class InspectCacheHandler {
|
||||
public void process(UserData data) {
|
||||
cache.put(uuid, new UserData(data));
|
||||
cacheTimes.put(uuid, MiscUtils.getTime());
|
||||
try {
|
||||
ExportUtility.writeInspectHtml(data, ExportUtility.getPlayersFolder(ExportUtility.getFolder()));
|
||||
} catch (IOException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
handler.getUserDataForProcessing(cacher, uuid, false);
|
||||
@ -81,7 +88,7 @@ public class InspectCacheHandler {
|
||||
long time = MiscUtils.getTime();
|
||||
for (UserData uData : userDataForUUIDS) {
|
||||
UUID uuid = uData.getUuid();
|
||||
cache.put(uuid, uData);
|
||||
cache.put(uuid, new UserData(uData));
|
||||
cacheTimes.put(uuid, time);
|
||||
}
|
||||
}
|
||||
|
43
Plan/src/main/java/com/djrapitops/plan/data/cache/queue/Consumer.java
vendored
Normal file
43
Plan/src/main/java/com/djrapitops/plan/data/cache/queue/Consumer.java
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
package main.java.com.djrapitops.plan.data.cache.queue;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* Abstract class representing a queue consumer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class Consumer<T> implements Runnable {
|
||||
|
||||
boolean run;
|
||||
final BlockingQueue<T> queue;
|
||||
|
||||
/**
|
||||
* Constructor, defines queue.
|
||||
*
|
||||
* @param queue Queue to consume from.
|
||||
*/
|
||||
public Consumer(BlockingQueue<T> queue) {
|
||||
this.queue = queue;
|
||||
run = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (run) {
|
||||
consume(queue.take());
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
run = false;
|
||||
}
|
||||
|
||||
abstract void clearVariables();
|
||||
|
||||
abstract void consume(T toConsume);
|
||||
}
|
@ -15,10 +15,7 @@ import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class DataCacheClearQueue {
|
||||
|
||||
private BlockingQueue<UUID> q;
|
||||
private ClearSetup s;
|
||||
public class DataCacheClearQueue extends Queue<UUID>{
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for clearing.
|
||||
@ -26,9 +23,9 @@ public class DataCacheClearQueue {
|
||||
* @param handler current instance of DataCachehandler.
|
||||
*/
|
||||
public DataCacheClearQueue(DataCacheHandler handler) {
|
||||
q = new ArrayBlockingQueue(Settings.PROCESS_CLEAR_LIMIT.getNumber());
|
||||
s = new ClearSetup();
|
||||
s.go(q, handler);
|
||||
super(new ArrayBlockingQueue(Settings.PROCESS_CLEAR_LIMIT.getNumber()));
|
||||
setup = new ClearSetup(queue, handler);
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,7 +35,7 @@ public class DataCacheClearQueue {
|
||||
*/
|
||||
public void scheduleForClear(UUID uuid) {
|
||||
Log.debug(uuid + ": Scheduling for clear");
|
||||
q.add(uuid);
|
||||
queue.add(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,46 +49,23 @@ public class DataCacheClearQueue {
|
||||
}
|
||||
Log.debug("Scheduling for clear: " + uuids);
|
||||
try {
|
||||
q.addAll(uuids);
|
||||
queue.addAll(uuids);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Clear Queue", Settings.PROCESS_CLEAR_LIMIT.getNumber() + ""));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all activity and clears the queue.
|
||||
*/
|
||||
public void stop() {
|
||||
if (s != null) {
|
||||
s.stop();
|
||||
}
|
||||
s = null;
|
||||
q.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class ClearConsumer implements Runnable {
|
||||
class ClearConsumer extends Consumer<UUID> implements Runnable {
|
||||
|
||||
private final BlockingQueue<UUID> queue;
|
||||
private DataCacheHandler handler;
|
||||
private boolean run;
|
||||
|
||||
ClearConsumer(BlockingQueue q, DataCacheHandler handler) {
|
||||
queue = q;
|
||||
super(q);
|
||||
this.handler = handler;
|
||||
run = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (run) {
|
||||
consume(queue.take());
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
void consume(UUID uuid) {
|
||||
if (handler == null) {
|
||||
return;
|
||||
@ -108,24 +82,16 @@ class ClearConsumer implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
run = false;
|
||||
@Override
|
||||
void clearVariables() {
|
||||
if (handler != null) {
|
||||
handler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClearSetup {
|
||||
|
||||
private ClearConsumer one;
|
||||
|
||||
void go(BlockingQueue<UUID> q, DataCacheHandler handler) {
|
||||
one = new ClearConsumer(q, handler);
|
||||
new Thread(one).start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
one.stop();
|
||||
class ClearSetup extends Setup<UUID> {
|
||||
public ClearSetup(BlockingQueue<UUID> q, DataCacheHandler handler) {
|
||||
super(new ClearConsumer(q, handler));
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
@ -21,10 +22,7 @@ import main.java.com.djrapitops.plan.database.Database;
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class DataCacheGetQueue {
|
||||
|
||||
private BlockingQueue<HashMap<UUID, List<DBCallableProcessor>>> q;
|
||||
private GetSetup s;
|
||||
public class DataCacheGetQueue extends Queue<Map<UUID, List<DBCallableProcessor>>> {
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for fetching.
|
||||
@ -32,9 +30,9 @@ public class DataCacheGetQueue {
|
||||
* @param plugin current instance of Plan
|
||||
*/
|
||||
public DataCacheGetQueue(Plan plugin) {
|
||||
q = new ArrayBlockingQueue(Settings.PROCESS_GET_LIMIT.getNumber());
|
||||
s = new GetSetup();
|
||||
s.go(q, plugin.getDB());
|
||||
super(new ArrayBlockingQueue(Settings.PROCESS_GET_LIMIT.getNumber()));
|
||||
setup = new GetSetup(queue, plugin.getDB());
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,52 +45,29 @@ public class DataCacheGetQueue {
|
||||
public void scheduleForGet(UUID uuid, DBCallableProcessor... processors) {
|
||||
Log.debug(uuid + ": Scheduling for get");
|
||||
try {
|
||||
HashMap<UUID, List<DBCallableProcessor>> map = new HashMap<>();
|
||||
Map<UUID, List<DBCallableProcessor>> map = new HashMap<>();
|
||||
if (map.get(uuid) == null) {
|
||||
map.put(uuid, new ArrayList<>());
|
||||
}
|
||||
map.get(uuid).addAll(Arrays.asList(processors));
|
||||
q.add(map);
|
||||
queue.add(map);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Get Queue", Settings.PROCESS_GET_LIMIT.getNumber() + ""));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the activities and clears the queue.
|
||||
*/
|
||||
public void stop() {
|
||||
if (s != null) {
|
||||
s.stop();
|
||||
}
|
||||
s = null;
|
||||
q.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class GetConsumer implements Runnable {
|
||||
class GetConsumer extends Consumer<Map<UUID, List<DBCallableProcessor>>> {
|
||||
|
||||
private final BlockingQueue<HashMap<UUID, List<DBCallableProcessor>>> queue;
|
||||
private Database db;
|
||||
private boolean run;
|
||||
|
||||
GetConsumer(BlockingQueue q, Database db) {
|
||||
queue = q;
|
||||
super(q);
|
||||
this.db = db;
|
||||
run = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (run) {
|
||||
consume(queue.take());
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
void consume(HashMap<UUID, List<DBCallableProcessor>> processors) {
|
||||
void consume(Map<UUID, List<DBCallableProcessor>> processors) {
|
||||
if (db == null) {
|
||||
return;
|
||||
}
|
||||
@ -116,28 +91,17 @@ class GetConsumer implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
run = false;
|
||||
@Override
|
||||
void clearVariables() {
|
||||
if (db != null) {
|
||||
db = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GetSetup {
|
||||
class GetSetup extends Setup<Map<UUID, List<DBCallableProcessor>>> {
|
||||
|
||||
private GetConsumer one;
|
||||
private GetConsumer two;
|
||||
|
||||
void go(BlockingQueue<HashMap<UUID, List<DBCallableProcessor>>> q, Database db) {
|
||||
one = new GetConsumer(q, db);
|
||||
two = new GetConsumer(q, db);
|
||||
new Thread(one).start();
|
||||
new Thread(two).start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
one.stop();
|
||||
two.stop();
|
||||
GetSetup(BlockingQueue<Map<UUID, List<DBCallableProcessor>>> q, Database db) {
|
||||
super(new GetConsumer(q, db), new GetConsumer(q, db));
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,7 @@ import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class DataCacheProcessQueue {
|
||||
|
||||
private BlockingQueue<HandlingInfo> queue;
|
||||
private ProcessSetup setup;
|
||||
public class DataCacheProcessQueue extends Queue<HandlingInfo> {
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for processing.
|
||||
@ -31,9 +28,9 @@ public class DataCacheProcessQueue {
|
||||
* @param handler current instance of DataCachehandler.
|
||||
*/
|
||||
public DataCacheProcessQueue(DataCacheHandler handler) {
|
||||
queue = new ArrayBlockingQueue(20000);
|
||||
setup = new ProcessSetup();
|
||||
setup.go(queue, handler);
|
||||
super(new ArrayBlockingQueue(20000));
|
||||
setup = new ProcessSetup(queue, handler);
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,48 +69,18 @@ public class DataCacheProcessQueue {
|
||||
public boolean containsUUID(UUID uuid) {
|
||||
return new ArrayList<>(queue).stream().map(d -> d.getUuid()).collect(Collectors.toList()).contains(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all activites and clears the queue.
|
||||
*
|
||||
* @return unprocessed HandlingInfo objects.
|
||||
*/
|
||||
public List<HandlingInfo> stop() {
|
||||
try {
|
||||
if (setup != null) {
|
||||
setup.stop();
|
||||
return new ArrayList<>(queue);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
} finally {
|
||||
setup = null;
|
||||
queue.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessConsumer implements Runnable {
|
||||
class ProcessConsumer extends Consumer<HandlingInfo> {
|
||||
|
||||
private final BlockingQueue<HandlingInfo> queue;
|
||||
private DataCacheHandler handler;
|
||||
private boolean run;
|
||||
|
||||
ProcessConsumer(BlockingQueue q, DataCacheHandler h) {
|
||||
super(q);
|
||||
handler = h;
|
||||
queue = q;
|
||||
run = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (run) {
|
||||
consume(queue.take());
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
void consume(HandlingInfo info) {
|
||||
if (handler == null) {
|
||||
return;
|
||||
@ -130,28 +97,16 @@ class ProcessConsumer implements Runnable {
|
||||
handler.getUserDataForProcessing(p, info.getUuid());
|
||||
}
|
||||
|
||||
void stop() {
|
||||
run = false;
|
||||
@Override
|
||||
void clearVariables() {
|
||||
if (handler != null) {
|
||||
handler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessSetup {
|
||||
|
||||
private ProcessConsumer one;
|
||||
private ProcessConsumer two;
|
||||
|
||||
void go(BlockingQueue<HandlingInfo> q, DataCacheHandler h) {
|
||||
one = new ProcessConsumer(q, h);
|
||||
two = new ProcessConsumer(q, h);
|
||||
new Thread(one).start();
|
||||
new Thread(two).start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
one.stop();
|
||||
two.stop();
|
||||
class ProcessSetup extends Setup<HandlingInfo> {
|
||||
ProcessSetup(BlockingQueue<HandlingInfo> q, DataCacheHandler h) {
|
||||
super(new ProcessConsumer(q, h), new ProcessConsumer(q, h));
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,7 @@ import main.java.com.djrapitops.plan.database.Database;
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class DataCacheSaveQueue {
|
||||
|
||||
private BlockingQueue<UserData> q;
|
||||
private SaveSetup s;
|
||||
public class DataCacheSaveQueue extends Queue<UserData>{
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for saving.
|
||||
@ -33,9 +30,9 @@ public class DataCacheSaveQueue {
|
||||
* UserData.clearAfterSave() is true
|
||||
*/
|
||||
public DataCacheSaveQueue(Plan plugin, DataCacheClearQueue clear) {
|
||||
q = new ArrayBlockingQueue(Settings.PROCESS_SAVE_LIMIT.getNumber());
|
||||
s = new SaveSetup();
|
||||
s.go(q, clear, plugin.getDB());
|
||||
super(new ArrayBlockingQueue(Settings.PROCESS_SAVE_LIMIT.getNumber()));
|
||||
setup = new SaveSetup(queue, clear, plugin.getDB());
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +43,7 @@ public class DataCacheSaveQueue {
|
||||
public void scheduleForSave(UserData data) {
|
||||
Log.debug(data.getUuid() + ": Scheduling for save");
|
||||
try {
|
||||
q.add(data);
|
||||
queue.add(data);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber() + ""));
|
||||
}
|
||||
@ -60,7 +57,7 @@ public class DataCacheSaveQueue {
|
||||
public void scheduleForSave(Collection<UserData> data) {
|
||||
Log.debug("Scheduling for save: " + data.stream().map(u -> u.getUuid()).collect(Collectors.toList()));
|
||||
try {
|
||||
q.addAll(data);
|
||||
queue.addAll(data);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber() + ""));
|
||||
}
|
||||
@ -74,7 +71,7 @@ public class DataCacheSaveQueue {
|
||||
public void scheduleNewPlayer(UserData data) {
|
||||
Log.debug(data.getUuid() + ": Scheduling new Player");
|
||||
try {
|
||||
q.add(data);
|
||||
queue.add(data);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber() + ""));
|
||||
}
|
||||
@ -87,45 +84,23 @@ public class DataCacheSaveQueue {
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean containsUUID(UUID uuid) {
|
||||
return new ArrayList<>(q).stream().map(d -> d.getUuid()).collect(Collectors.toList()).contains(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all activites and clears the queue.
|
||||
*/
|
||||
public void stop() {
|
||||
if (s != null) {
|
||||
s.stop();
|
||||
}
|
||||
s = null;
|
||||
q.clear();
|
||||
return new ArrayList<>(queue).stream().map(d -> d.getUuid()).collect(Collectors.toList()).contains(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
class SaveConsumer implements Runnable {
|
||||
class SaveConsumer extends Consumer<UserData> {
|
||||
|
||||
private final BlockingQueue<UserData> queue;
|
||||
private Database db;
|
||||
private DataCacheClearQueue clear;
|
||||
private boolean run;
|
||||
|
||||
SaveConsumer(BlockingQueue q, DataCacheClearQueue clear, Database db) {
|
||||
queue = q;
|
||||
super(q);
|
||||
this.db = db;
|
||||
this.clear = clear;
|
||||
run = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (run) {
|
||||
consume(queue.take());
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
void consume(UserData data) {
|
||||
if (db == null) {
|
||||
return;
|
||||
@ -147,8 +122,8 @@ class SaveConsumer implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
run = false;
|
||||
@Override
|
||||
void clearVariables() {
|
||||
if (db != null) {
|
||||
db = null;
|
||||
}
|
||||
@ -158,20 +133,8 @@ class SaveConsumer implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
class SaveSetup {
|
||||
|
||||
private SaveConsumer one;
|
||||
private SaveConsumer two;
|
||||
|
||||
void go(BlockingQueue<UserData> q, DataCacheClearQueue clear, Database db) {
|
||||
one = new SaveConsumer(q, clear, db);
|
||||
two = new SaveConsumer(q, clear, db);
|
||||
new Thread(one).start();
|
||||
new Thread(two).start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
one.stop();
|
||||
two.stop();
|
||||
class SaveSetup extends Setup<UserData>{
|
||||
SaveSetup(BlockingQueue<UserData> q, DataCacheClearQueue clear, Database db) {
|
||||
super(new SaveConsumer(q, clear, db), new SaveConsumer(q, clear, db));
|
||||
}
|
||||
}
|
||||
|
72
Plan/src/main/java/com/djrapitops/plan/data/cache/queue/Queue.java
vendored
Normal file
72
Plan/src/main/java/com/djrapitops/plan/data/cache/queue/Queue.java
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
package main.java.com.djrapitops.plan.data.cache.queue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a Queue.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @param <T> Object this queue consumes
|
||||
*/
|
||||
public abstract class Queue<T> {
|
||||
|
||||
final BlockingQueue<T> queue;
|
||||
Setup<T> setup;
|
||||
|
||||
/**
|
||||
* Consturctor, defines queue.
|
||||
*
|
||||
* @param queue BlockingQueue to use for this queue.
|
||||
*/
|
||||
public Queue(BlockingQueue<T> queue) {
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a object to the queue, default implementation.
|
||||
*
|
||||
* @param object Object to add.
|
||||
*/
|
||||
public void add(T object) {
|
||||
queue.add(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to stop the queue processing & get the unprocessed objects.
|
||||
*
|
||||
* @return List of unprocessed objects.
|
||||
*/
|
||||
public List<T> stopAndReturnLeftovers() {
|
||||
try {
|
||||
if (setup != null) {
|
||||
setup.stop();
|
||||
return new ArrayList<>(queue);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
} finally {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all activity and clears the queue.
|
||||
*/
|
||||
public void stop() {
|
||||
if (setup != null) {
|
||||
setup.stop();
|
||||
}
|
||||
setup = null;
|
||||
queue.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get how many objects are in the queue.
|
||||
*
|
||||
* @return size of the queue.
|
||||
*/
|
||||
public int size() {
|
||||
return queue.size();
|
||||
}
|
||||
}
|
33
Plan/src/main/java/com/djrapitops/plan/data/cache/queue/Setup.java
vendored
Normal file
33
Plan/src/main/java/com/djrapitops/plan/data/cache/queue/Setup.java
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package main.java.com.djrapitops.plan.data.cache.queue;
|
||||
|
||||
/**
|
||||
* Abstract representation of a queue setup.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @param <T> Object this queue consumes.
|
||||
*/
|
||||
public abstract class Setup<T> {
|
||||
|
||||
private Consumer<T>[] consumers;
|
||||
|
||||
/**
|
||||
* Constructor, defines consumers.
|
||||
*
|
||||
* @param consumers Consumers for the new threads.
|
||||
*/
|
||||
public Setup(Consumer<T>... consumers) {
|
||||
this.consumers = consumers;
|
||||
}
|
||||
|
||||
void go() {
|
||||
for (Consumer<T> consumer : consumers) {
|
||||
new Thread(consumer).start();
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
for (Consumer<T> consumer : consumers) {
|
||||
consumer.stop();
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.Settings;
|
||||
import main.java.com.djrapitops.plan.data.SessionData;
|
||||
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
@ -27,10 +28,9 @@ public class PlayerActivityGraphCreator {
|
||||
*
|
||||
* @param sessionData
|
||||
* @param scale
|
||||
* @param maxPlayers
|
||||
* @return
|
||||
*/
|
||||
public static String[] generateDataArray(List<SessionData> sessionData, long scale, int maxPlayers) {
|
||||
public static String[] generateDataArray(List<SessionData> sessionData, long scale) {
|
||||
Benchmark.start("Generate Player Activity Graph " + sessionData.size() + " " + scale + " |");
|
||||
long now = new Date().toInstant().getEpochSecond() * (long) 1000;
|
||||
long nowMinusScale = now - scale;
|
||||
@ -75,17 +75,12 @@ public class PlayerActivityGraphCreator {
|
||||
for (int i = 0; i < playersOnline.size(); i++) {
|
||||
long value = playersOnline.get(i);
|
||||
if (value - average > 3 * standardDiviation) {
|
||||
playersOnline.set(i, (long) maxPlayers + 10);
|
||||
playersOnline.set(i, (long) Plan.getInstance().getVariable().getMaxPlayers() + 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Benchmark.stop("Player Activity Graph Amount Calculation");
|
||||
playersOnline.add(0L);
|
||||
playersOnline.add(0L);
|
||||
playersOnline.add(0L);
|
||||
playersOnline.add(0L);
|
||||
playersOnline.add((long) maxPlayers);
|
||||
Benchmark.stop("Generate Player Activity Graph " + sessionData.size() + " " + scale + " |");
|
||||
return new String[]{playersOnline.toString(), labels.toString()};
|
||||
}
|
||||
@ -142,7 +137,7 @@ public class PlayerActivityGraphCreator {
|
||||
public static List<List<Long>> filterAndTransformSessions(List<SessionData> sessionData, long nowMinusScale) {
|
||||
List<Long[]> values = sessionData.parallelStream()
|
||||
.filter(session -> (session != null))
|
||||
.filter(session -> session.isValid())
|
||||
.filter(session -> session.isValid() || session.getSessionEnd() == -1)
|
||||
.filter((session) -> (session.getSessionStart() >= nowMinusScale || session.getSessionEnd() >= nowMinusScale))
|
||||
.map(session -> new Long[]{session.getSessionStart(), session.getSessionEnd()})
|
||||
.collect(Collectors.toList());
|
||||
@ -150,7 +145,10 @@ public class PlayerActivityGraphCreator {
|
||||
List<Long> sessionEnds = new ArrayList<>();
|
||||
for (Long[] startAndEnd : values) {
|
||||
sessionStarts.add(getSecond(startAndEnd[0]));
|
||||
sessionEnds.add(getSecond(startAndEnd[1]));
|
||||
Long end = startAndEnd[1];
|
||||
if (end != -1) {
|
||||
sessionEnds.add(getSecond(end));
|
||||
}
|
||||
}
|
||||
List<List<Long>> r = new ArrayList<>();
|
||||
r.add(sessionStarts);
|
||||
|
@ -40,10 +40,6 @@ public class PunchCardGraphCreator {
|
||||
private static StringBuilder buildString(int[][] scaled) {
|
||||
StringBuilder arrayBuilder = new StringBuilder();
|
||||
arrayBuilder.append("[");
|
||||
arrayBuilder.append("{").append("x:").append(-1).append(", y:").append(-1).append(", r:").append(1).append("}");
|
||||
arrayBuilder.append(",");
|
||||
arrayBuilder.append("{").append("x:").append(25).append(", y:").append(7).append(", r:").append(1).append("}");
|
||||
arrayBuilder.append(",");
|
||||
for (int i = 0; i < 7; i++) {
|
||||
for (int j = 0; j < 24; j++) {
|
||||
int value = scaled[i][j];
|
||||
@ -160,7 +156,7 @@ public class PunchCardGraphCreator {
|
||||
scaled[i][j] = value;
|
||||
}
|
||||
}
|
||||
Log.debug("Biggest value: " + big);
|
||||
Log.debug("Punchcard Biggest value: " + big);
|
||||
return scaled;
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,9 @@ public class SessionLengthDistributionGraphCreator {
|
||||
*/
|
||||
public static String[] generateDataArray(Collection<Long> lengths) {
|
||||
Map<Long, Integer> values = getValues(lengths);
|
||||
Map<Long, Integer> scaled = scale(values);
|
||||
StringBuilder arrayBuilder = buildString(scaled);
|
||||
StringBuilder labelBuilder = buildLabels(scaled);
|
||||
// Map<Long, Integer> scaled = scale(values);
|
||||
StringBuilder arrayBuilder = buildString(values);
|
||||
StringBuilder labelBuilder = buildLabels(values);
|
||||
return new String[]{arrayBuilder.toString(), labelBuilder.toString()};
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,7 @@ public class PlaceholderUtils {
|
||||
replaceMap.put("#" + defaultCols[i], "#" + colors[i]);
|
||||
}
|
||||
}
|
||||
replaceMap.put("%graphmaxplayers%", plugin.getVariable().getMaxPlayers()+"");
|
||||
replaceMap.put("%refreshlong%", data.getRefreshDate()+"");
|
||||
replaceMap.put("%servername%", Settings.SERVER_NAME.toString());
|
||||
Benchmark.stop("Replace Placeholders Anaysis");
|
||||
@ -205,7 +206,8 @@ public class PlaceholderUtils {
|
||||
Plan plugin = Plan.getInstance();
|
||||
replaceMap.put("%version%", plugin.getDescription().getVersion());
|
||||
replaceMap.put("%planlite%", "");
|
||||
String[] playersDataArray = PlayerActivityGraphCreator.generateDataArray(data.getSessions(), (long) 604800 * 1000, 2);
|
||||
String[] playersDataArray = PlayerActivityGraphCreator.generateDataArray(data.getSessions(), (long) 604800 * 1000);
|
||||
replaceMap.put("%graphmaxplayers%", 2+"");
|
||||
replaceMap.put("%dataweek%", playersDataArray[0]);
|
||||
replaceMap.put("%labelsweek%", playersDataArray[1]);
|
||||
replaceMap.put("%playersgraphcolor%", Settings.HCOLOR_ACT_ONL + "");
|
||||
|
@ -20,6 +20,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.cache.AnalysisCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.ui.Html;
|
||||
@ -99,7 +100,7 @@ public class Analysis {
|
||||
Log.info(Phrase.ANALYSIS_FAIL_NO_DATA + "");
|
||||
return false;
|
||||
}
|
||||
Benchmark.stop("Analysis Fetch Phase");
|
||||
;
|
||||
return analyzeData(rawData, analysisCache);
|
||||
}
|
||||
|
||||
@ -115,11 +116,21 @@ public class Analysis {
|
||||
List<UUID> uuids = rawData.stream().map(d -> d.getUuid()).collect(Collectors.toList());
|
||||
Benchmark.stop("Analysis UUID transform");
|
||||
Benchmark.start("Analysis Create Empty dataset");
|
||||
Map<String, Integer> commandUse = plugin.getHandler().getCommandUse();
|
||||
DataCacheHandler handler = plugin.getHandler();
|
||||
Map<UUID, SessionData> activeSessions = handler.getActiveSessions();
|
||||
long now = MiscUtils.getTime();
|
||||
rawData.stream().forEach((data) -> {
|
||||
SessionData session = activeSessions.get(data.getUuid());
|
||||
List<SessionData> sessions = data.getSessions();
|
||||
if (session != null && !sessions.contains(session)) {
|
||||
sessions.add(session);
|
||||
}
|
||||
});
|
||||
Map<String, Integer> commandUse = handler.getCommandUse();
|
||||
|
||||
AnalysisData analysisData = new AnalysisData();
|
||||
Benchmark.stop("Analysis Create Empty dataset");
|
||||
log(Phrase.ANALYSIS_BEGIN_ANALYSIS + "");
|
||||
log(Phrase.ANALYSIS_BEGIN_ANALYSIS.parse(rawData.size() + "", Benchmark.stop("Analysis Fetch Phase") + ""));
|
||||
String playersTable = SortablePlayersTableCreator.createSortablePlayersTable(rawData);
|
||||
analysisData.setSortablePlayersTable(playersTable);
|
||||
|
||||
@ -150,14 +161,13 @@ public class Analysis {
|
||||
analysisData.setAdditionalDataReplaceMap(analyzeAdditionalPluginData(uuids));
|
||||
|
||||
analysisCache.cache(analysisData);
|
||||
Benchmark.stop("Analysis");
|
||||
long time = Benchmark.stop("Analysis");
|
||||
if (Settings.ANALYSIS_LOG_FINISHED.isTrue()) {
|
||||
Log.info(Phrase.ANALYSIS_COMPLETE + "");
|
||||
}
|
||||
// LocationAnalysis.performAnalysis(analysisData, plugin.getDB());
|
||||
if (Settings.ANALYSIS_EXPORT.isTrue()) {
|
||||
ExportUtility.export(plugin, analysisData, rawData);
|
||||
Log.info(Phrase.ANALYSIS_COMPLETE.parse(time + "", HtmlUtils.getServerAnalysisUrl()));
|
||||
}
|
||||
// LocationAnalysis.performAnalysis(analysisData, plugin.getDB());
|
||||
ExportUtility.export(plugin, analysisData, rawData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -291,7 +301,6 @@ public class Analysis {
|
||||
long scaleDay = 86400 * 1000;
|
||||
long scaleWeek = 604800 * 1000;
|
||||
long scaleMonth = (long) 2592000 * (long) 1000;
|
||||
int maxPlayers = plugin.getHandler().getMaxPlayers();
|
||||
|
||||
data.setNewPlayersDay(AnalysisUtils.getNewPlayers(registered, scaleDay, now));
|
||||
data.setNewPlayersWeek(AnalysisUtils.getNewPlayers(registered, scaleWeek, now));
|
||||
@ -303,22 +312,22 @@ public class Analysis {
|
||||
data.setAvgUniqJoinsWeek(AnalysisUtils.getUniqueJoinsPerDay(sortedSData, scaleWeek));
|
||||
data.setAvgUniqJoinsMonth(AnalysisUtils.getUniqueJoinsPerDay(sortedSData, scaleMonth));
|
||||
Benchmark.stop("Analysis Unique/day");
|
||||
|
||||
|
||||
Benchmark.start("Analysis Unique");
|
||||
data.setUniqueJoinsDay(AnalysisUtils.getUniqueJoins(sortedSData, scaleDay));
|
||||
data.setUniqueJoinsWeek(AnalysisUtils.getUniqueJoins(sortedSData, scaleWeek));
|
||||
data.setUniqueJoinsMonth(AnalysisUtils.getUniqueJoins(sortedSData, scaleMonth));
|
||||
Benchmark.stop("Analysis Unique");
|
||||
|
||||
|
||||
List<SessionData> sessions = sData.stream()
|
||||
.filter(session -> (session != null))
|
||||
.filter(session -> session.isValid())
|
||||
.filter((session) -> (session.getSessionStart() >= now - scaleMonth || session.getSessionEnd() >= now - scaleMonth))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String[] dayArray = PlayerActivityGraphCreator.generateDataArray(sessions, scaleDay, maxPlayers);
|
||||
String[] weekArray = PlayerActivityGraphCreator.generateDataArray(sessions, scaleWeek, maxPlayers);
|
||||
String[] monthArray = PlayerActivityGraphCreator.generateDataArray(sessions, scaleMonth, maxPlayers);
|
||||
String[] dayArray = PlayerActivityGraphCreator.generateDataArray(sessions, scaleDay);
|
||||
String[] weekArray = PlayerActivityGraphCreator.generateDataArray(sessions, scaleWeek);
|
||||
String[] monthArray = PlayerActivityGraphCreator.generateDataArray(sessions, scaleMonth);
|
||||
|
||||
data.setPlayersDataArray(new String[]{dayArray[0], dayArray[1], weekArray[0], weekArray[1], monthArray[0], monthArray[1]});
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import main.java.com.djrapitops.plan.utilities.PlaceholderUtils;
|
||||
*/
|
||||
public class ExportUtility {
|
||||
|
||||
private static File getFolder() throws IOException {
|
||||
public static File getFolder() throws IOException {
|
||||
String path = Settings.ANALYSIS_EXPORT_PATH.toString();
|
||||
if (path.contains(":")) {
|
||||
File folder = new File(path);
|
||||
@ -46,12 +46,14 @@ public class ExportUtility {
|
||||
}
|
||||
|
||||
public static void export(Plan plugin, AnalysisData analysisData, List<UserData> rawData) {
|
||||
if (!Settings.ANALYSIS_EXPORT.isTrue()) {
|
||||
return;
|
||||
}
|
||||
Benchmark.start("Exporting Html pages");
|
||||
try {
|
||||
File folder = getFolder();
|
||||
writeAnalysisHtml(analysisData, folder);
|
||||
File playersFolder = new File(folder, "player");
|
||||
playersFolder.mkdirs();
|
||||
File playersFolder = getPlayersFolder(folder);
|
||||
for (UserData userData : rawData) {
|
||||
writeInspectHtml(userData, playersFolder);
|
||||
}
|
||||
@ -62,7 +64,16 @@ public class ExportUtility {
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeInspectHtml(UserData userData, File playersFolder) throws FileNotFoundException, IOException {
|
||||
public static File getPlayersFolder(File folder) {
|
||||
File playersFolder = new File(folder, "player");
|
||||
playersFolder.mkdirs();
|
||||
return playersFolder;
|
||||
}
|
||||
|
||||
public static void writeInspectHtml(UserData userData, File playersFolder) throws FileNotFoundException, IOException {
|
||||
if (!Settings.ANALYSIS_EXPORT.isTrue()) {
|
||||
return;
|
||||
}
|
||||
String inspectHtml = HtmlUtils.replacePlaceholders(HtmlUtils.getHtmlStringFromResource("player.html"),
|
||||
PlaceholderUtils.getInspectReplaceRules(userData));
|
||||
File playerFolder = new File(playersFolder, userData.getName());
|
||||
@ -74,7 +85,10 @@ public class ExportUtility {
|
||||
Files.write(inspectHtmlFile.toPath(), Arrays.asList(inspectHtml));
|
||||
}
|
||||
|
||||
private static void writeAnalysisHtml(AnalysisData analysisData, File folder) throws FileNotFoundException, IOException {
|
||||
public static void writeAnalysisHtml(AnalysisData analysisData, File folder) throws FileNotFoundException, IOException {
|
||||
if (!Settings.ANALYSIS_EXPORT.isTrue()) {
|
||||
return;
|
||||
}
|
||||
String analysisHtml = HtmlUtils.replacePlaceholders(HtmlUtils.getHtmlStringFromResource("analysis.html"),
|
||||
PlaceholderUtils.getAnalysisReplaceRules(analysisData))
|
||||
.replace(HtmlUtils.getInspectUrl(""), "./player/");
|
||||
|
@ -630,6 +630,7 @@ header p {
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="sessiondistribution" width="1000" height="600" style="width: 95%;"></canvas>
|
||||
<p>If the graph contains more sessions than login times, likely cause is use of /reload (Restarts sessions).</p>
|
||||
</div>
|
||||
</div>
|
||||
<!--<div class="columns">
|
||||
@ -1028,6 +1029,12 @@ function countUpTimer() {
|
||||
data: dataday,
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
suggestedMax: %graphmaxplayers%
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
display: false
|
||||
}]
|
||||
@ -1039,6 +1046,12 @@ function countUpTimer() {
|
||||
data: dataday,
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
suggestedMax: %graphmaxplayers%
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
display: false
|
||||
}]
|
||||
@ -1050,6 +1063,12 @@ function countUpTimer() {
|
||||
data: dataweek,
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
suggestedMax: %graphmaxplayers%
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
display: false
|
||||
}]
|
||||
@ -1061,6 +1080,12 @@ function countUpTimer() {
|
||||
data: datamonth,
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
suggestedMax: %graphmaxplayers%
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
display: false
|
||||
}]
|
||||
@ -1130,14 +1155,18 @@ function countUpTimer() {
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return hour(value);
|
||||
}
|
||||
},
|
||||
suggestedMax: 25,
|
||||
suggestedMin: -1
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return day(value);
|
||||
}
|
||||
},
|
||||
suggestedMax: 7,
|
||||
suggestedMin: -1
|
||||
}
|
||||
}]
|
||||
}
|
||||
@ -1178,7 +1207,7 @@ function countUpTimer() {
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItems, data) {
|
||||
return tooltipItems.xLabel+'utes: '+tooltipItems.yLabel+'%';
|
||||
return tooltipItems.xLabel+'utes: '+tooltipItems.yLabel+' sessions';
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1186,7 +1215,7 @@ function countUpTimer() {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return value+'%';
|
||||
return value+'';
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
@ -18,9 +18,9 @@ Settings:
|
||||
DestinationFolder: 'Analysis Results'
|
||||
Cache:
|
||||
Processing:
|
||||
GetLimit: 2000
|
||||
SaveLimit: 1000
|
||||
ClearLimit: 1000
|
||||
GetLimit: 5000
|
||||
SaveLimit: 2500
|
||||
ClearLimit: 2500
|
||||
AnalysisCache:
|
||||
RefreshAnalysisCacheOnEnable: true
|
||||
RefreshEveryXMinutes: -1
|
||||
|
@ -539,7 +539,8 @@ table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sor
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="sessiondistribution" width="1000" height="600" style="width: 95%;"></canvas>
|
||||
</div>
|
||||
<p>If the graph contains more sessions than login times, likely cause is use of /reload (Restarts sessions).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab" style="display: block;">
|
||||
@ -730,6 +731,12 @@ function countUpTimer() {
|
||||
data: dataweek,
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
suggestedMax: %graphmaxplayers%
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
display: false
|
||||
}]
|
||||
@ -795,14 +802,18 @@ function countUpTimer() {
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return hour(value);
|
||||
}
|
||||
},
|
||||
suggestedMax: 25,
|
||||
suggestedMin: -1
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return day(value);
|
||||
}
|
||||
},
|
||||
suggestedMax: 7,
|
||||
suggestedMin: -1
|
||||
}
|
||||
}]
|
||||
}
|
||||
@ -841,7 +852,7 @@ function countUpTimer() {
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItems, data) {
|
||||
return tooltipItems.xLabel+'utes: '+tooltipItems.yLabel+'%';
|
||||
return tooltipItems.xLabel+'utes: '+tooltipItems.yLabel+' sessions';
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -849,7 +860,7 @@ function countUpTimer() {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return value+'%';
|
||||
return value+'';
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: main.java.com.djrapitops.plan.Plan
|
||||
version: 3.4.0
|
||||
version: 3.4.1
|
||||
|
||||
softdepend:
|
||||
- OnTime
|
||||
|
@ -303,14 +303,6 @@ public class DataCacheHandlerTest {
|
||||
public void testHandleReload() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testGetMaxPlayers() {
|
||||
assertEquals(20, handler.getMaxPlayers());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -104,7 +104,7 @@ public class DataCacheProcessQueueTest {
|
||||
}
|
||||
});
|
||||
Thread.sleep(1000);
|
||||
assertTrue(q.stop().isEmpty());
|
||||
assertTrue(q.stopAndReturnLeftovers().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ public class DataCacheProcessQueueTest {
|
||||
l.add(h);
|
||||
q.addToPool(l);
|
||||
Thread.sleep(1000);
|
||||
assertTrue(q.stop().isEmpty());
|
||||
assertTrue(q.stopAndReturnLeftovers().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ public class PlayerActivityGraphCreatorTest {
|
||||
public void testGenerateDataArray() {
|
||||
List<SessionData> sessionData = createRandomSessionDataList();
|
||||
long scale = 2592000L * 1000L;
|
||||
String result = PlayerActivityGraphCreator.generateDataArray(sessionData, scale, 20)[1];
|
||||
String result = PlayerActivityGraphCreator.generateDataArray(sessionData, scale)[1];
|
||||
assertTrue("0", 0 < result.length());
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ The plugin uses two .html files: `analysis.html` and `player.html`
|
||||
If the `/plugins/Plan/` folder contains either of the files, they will be used instead of the ones found inside the .jar.
|
||||
This means you can copy the html files from the jar to the folder and edit them.
|
||||
|
||||
Page version: **3.2.0**
|
||||
Page version: **3.4.0**
|
||||
|
||||
## Placeholders
|
||||
The plugin uses placeholders to place the values into the html. Here I will go through each placeholder.
|
||||
|
Loading…
Reference in New Issue
Block a user