mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-04-24 18:40:34 +08:00
Merge pull request #207 from Fuzzlemann/master
PR for 3.6.0 (Fuzzlemann) (6)
This commit is contained in:
commit
f9af3eee03
Plan/src
main
java/com/djrapitops/plan
Plan.java
data
cache
handling/info
listeners
database/tables
ui
utilities/analysis
resources
test/java/main/java/com/djrapitops/plan/data/handling/info
@ -32,6 +32,7 @@ import main.java.com.djrapitops.plan.data.additional.HookHandler;
|
||||
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.data.cache.PageCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.listeners.*;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.database.databases.MySQLDB;
|
||||
@ -223,25 +224,32 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
*/
|
||||
@Override
|
||||
public void onDisable() {
|
||||
//Clears the page cache
|
||||
PageCacheHandler.clearCache();
|
||||
|
||||
// Stop the UI Server
|
||||
if (uiServer != null) {
|
||||
uiServer.stop();
|
||||
}
|
||||
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
|
||||
if (Verify.notNull(handler, db)) {
|
||||
Benchmark.start("Disable: DataCache Save");
|
||||
// Saves the DataCache to the database without Bukkit's Schedulers.
|
||||
Log.info(Phrase.CACHE_SAVE + "");
|
||||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
Log.info(Phrase.CACHE_SAVE.toString());
|
||||
|
||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
scheduler.execute(() -> {
|
||||
handler.saveCacheOnDisable();
|
||||
taskStatus().cancelAllKnownTasks();
|
||||
Benchmark.stop("Disable: DataCache Save");
|
||||
});
|
||||
scheduler.shutdown(); // Schedules the save to shutdown after it has ran the execute method.
|
||||
|
||||
scheduler.shutdown(); // Schedules the save to shutdown after it has ran the execute method.
|
||||
}
|
||||
Log.info(Phrase.DISABLED + "");
|
||||
|
||||
Log.info(Phrase.DISABLED.toString());
|
||||
}
|
||||
|
||||
private void registerListeners() {
|
||||
|
@ -176,12 +176,7 @@ public class DataCacheHandler extends SessionCache {
|
||||
UserData uData = dataCache.get(uuid);
|
||||
if (uData == null) {
|
||||
if (cache) {
|
||||
DBCallableProcessor cacher = new DBCallableProcessor() {
|
||||
@Override
|
||||
public void process(UserData data) {
|
||||
cache(data);
|
||||
}
|
||||
};
|
||||
DBCallableProcessor cacher = this::cache;
|
||||
getTask.scheduleForGet(uuid, cacher, processor);
|
||||
} else {
|
||||
getTask.scheduleForGet(uuid, processor);
|
||||
|
@ -4,6 +4,7 @@ import main.java.com.djrapitops.plan.Log;
|
||||
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.ui.webserver.response.InspectPageResponse;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.ExportUtility;
|
||||
|
||||
@ -48,6 +49,7 @@ public class InspectCacheHandler {
|
||||
public void process(UserData data) {
|
||||
cache.put(uuid, new UserData(data));
|
||||
cacheTimes.put(uuid, MiscUtils.getTime());
|
||||
PageCacheHandler.cachePage("inspectPage: " + uuid.toString(), () -> new InspectPageResponse(Plan.getInstance().getUiServer().getDataReqHandler(), uuid));
|
||||
try {
|
||||
ExportUtility.writeInspectHtml(data, ExportUtility.getPlayersFolder(ExportUtility.getFolder()));
|
||||
} catch (IOException ex) {
|
||||
|
75
Plan/src/main/java/com/djrapitops/plan/data/cache/PageCacheHandler.java
vendored
Normal file
75
Plan/src/main/java/com/djrapitops/plan/data/cache/PageCacheHandler.java
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
package main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import main.java.com.djrapitops.plan.ui.webserver.response.Response;
|
||||
|
||||
/**
|
||||
* This class contains the page cache.
|
||||
* <p>
|
||||
* It caches all Responses with their matching identifiers.
|
||||
* This reduces CPU cycles and the time to wait for loading the pages.
|
||||
* This is especially useful in situations where multiple clients are accessing the server.
|
||||
* <p>
|
||||
* This cache uses the Google Guava {@link Cache}.
|
||||
*
|
||||
* @author Fuzzlemann
|
||||
*/
|
||||
public class PageCacheHandler {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private PageCacheHandler() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
private static final Cache<String, Response> pageCache = CacheBuilder.newBuilder()
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Loads the page from the page cache.
|
||||
* <p>
|
||||
* If the {@link Response} isn't cached, {@link PageLoader#createResponse()} in the {@code loader}
|
||||
* is called to create the Response.
|
||||
* <p>
|
||||
* If the Response is created, it's automatically cached.
|
||||
*
|
||||
* @param identifier The identifier of the page
|
||||
* @param loader The {@link PageLoader} (How should it load the page if it's not cached)
|
||||
* @return The Response that was cached or created by the {@link PageLoader loader}
|
||||
*/
|
||||
public static Response loadPage(String identifier, PageLoader loader) {
|
||||
Response response = pageCache.asMap().get(identifier);
|
||||
|
||||
if (response != null) {
|
||||
return response;
|
||||
}
|
||||
|
||||
response = loader.createResponse();
|
||||
|
||||
pageCache.put(identifier, response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the page into the page cache.
|
||||
* <p>
|
||||
* If the cache already inherits that {@code identifier}, it's renewed.
|
||||
*
|
||||
* @param identifier The identifier of the page
|
||||
* @param loader The {@link PageLoader} (How it should load the page)
|
||||
*/
|
||||
public static void cachePage(String identifier, PageLoader loader) {
|
||||
Response response = loader.createResponse();
|
||||
pageCache.put(identifier, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cache from all its contents.
|
||||
*/
|
||||
public static void clearCache() {
|
||||
pageCache.asMap().clear();
|
||||
}
|
||||
}
|
14
Plan/src/main/java/com/djrapitops/plan/data/cache/PageLoader.java
vendored
Normal file
14
Plan/src/main/java/com/djrapitops/plan/data/cache/PageLoader.java
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
package main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import main.java.com.djrapitops.plan.ui.webserver.response.Response;
|
||||
|
||||
/**
|
||||
* This interface is used for providing the method to load the page.
|
||||
*
|
||||
* @author Fuzzlemann
|
||||
*/
|
||||
public interface PageLoader {
|
||||
|
||||
Response createResponse();
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.data.cache.queue;
|
||||
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
|
||||
@ -89,12 +88,9 @@ class ProcessConsumer extends Consumer<HandlingInfo> {
|
||||
return;
|
||||
}
|
||||
Log.debug(info.getUuid() + ": Processing type: " + info.getType().name());
|
||||
DBCallableProcessor p = new DBCallableProcessor() {
|
||||
@Override
|
||||
public void process(UserData data) {
|
||||
if (!info.process(data)) {
|
||||
Log.error("Attempted to process data for wrong uuid: W:" + data.getUuid() + " | R:" + info.getUuid() + " Type:" + info.getType().name());
|
||||
}
|
||||
DBCallableProcessor p = data -> {
|
||||
if (!info.process(data)) {
|
||||
Log.error("Attempted to process data for wrong uuid: W:" + data.getUuid() + " | R:" + info.getUuid() + " Type:" + info.getType().name());
|
||||
}
|
||||
};
|
||||
handler.getUserDataForProcessing(p, info.getUuid());
|
||||
|
@ -14,19 +14,16 @@ import java.util.UUID;
|
||||
public class ChatInfo extends HandlingInfo {
|
||||
|
||||
private final String nickname;
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @param nickname Nickname of the player.
|
||||
* @param message Message the player sent.
|
||||
*/
|
||||
public ChatInfo(UUID uuid, String nickname, String message) {
|
||||
public ChatInfo(UUID uuid, String nickname) {
|
||||
super(uuid, InfoType.CHAT, 0L);
|
||||
this.nickname = nickname;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,7 +37,8 @@ public class PlanChatListener implements Listener {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player p = event.getPlayer();
|
||||
handler.addToPool(new ChatInfo(p.getUniqueId(), p.getDisplayName(), event.getMessage()));
|
||||
handler.addToPool(new ChatInfo(p.getUniqueId(), p.getDisplayName()));
|
||||
}
|
||||
}
|
||||
|
@ -93,14 +93,14 @@ public class CommandUseTable extends Table {
|
||||
Map<String, Integer> updateData = new HashMap<>(data);
|
||||
updateData.keySet().removeAll(newData.keySet());
|
||||
|
||||
for (String cmd : saved.keySet()) {
|
||||
for (Map.Entry<String, Integer> entrySet : saved.entrySet()) {
|
||||
String cmd = entrySet.getKey();
|
||||
// IMPORTANT - not using saved as value
|
||||
Integer toSave = updateData.get(cmd);
|
||||
|
||||
if (toSave == null || toSave > saved.get(cmd)) {
|
||||
continue;
|
||||
if (toSave != null && toSave <= entrySet.getValue()) {
|
||||
updateData.remove(cmd);
|
||||
}
|
||||
updateData.remove(cmd);
|
||||
}
|
||||
|
||||
updateCommands(updateData);
|
||||
|
@ -199,6 +199,7 @@ public class NicknamesTable extends Table {
|
||||
lastNicks.put(id, nickname);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, String> entry : lastNicks.entrySet()) {
|
||||
Integer id = entry.getKey();
|
||||
String lastNick = entry.getValue();
|
||||
@ -208,8 +209,7 @@ public class NicknamesTable extends Table {
|
||||
// Moves the last known nickname to the end of the List.
|
||||
// This is due to the way nicknames are added to UserData,
|
||||
// Nicknames are stored as a Set and last Nickname is a separate String.
|
||||
list.remove(lastNick);
|
||||
list.add(lastNick);
|
||||
list.set(list.size() - 1, lastNick);
|
||||
}
|
||||
|
||||
return nicks;
|
||||
|
@ -72,8 +72,7 @@ public class DataRequestHandler {
|
||||
}
|
||||
return HtmlUtils.replacePlaceholders(
|
||||
HtmlUtils.getStringFromResource("analysis.html"),
|
||||
PlaceholderUtils.getAnalysisReplaceRules(analysisCache.getData())
|
||||
);
|
||||
PlaceholderUtils.getAnalysisReplaceRules(analysisCache.getData()));
|
||||
} catch (FileNotFoundException ex) {
|
||||
return "<h1>404 analysis.html was not found</h1>";
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ public class PunchCardGraphCreator {
|
||||
}
|
||||
}
|
||||
|
||||
double size = array.length * array[0].length;
|
||||
int size = array.length * array[0].length;
|
||||
double sum = sum(valueMinusAvg);
|
||||
return Math.sqrt(sum / size);
|
||||
}
|
||||
|
@ -5,15 +5,11 @@
|
||||
*/
|
||||
package main.java.com.djrapitops.plan.ui.html.graphs;
|
||||
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.DouglasPeuckerAlgorithm;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.Point;
|
||||
import main.java.com.djrapitops.plan.utilities.comparators.PointComparator;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.ReduceGapTriangles;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Abstract scatter graph creator used by other graph creators.
|
||||
@ -42,26 +38,7 @@ public class ScatterGraphCreator {
|
||||
}
|
||||
|
||||
if (reduceGapTriangles) {
|
||||
Point lastPoint = null;
|
||||
|
||||
Set<Point> toAdd = new HashSet<>();
|
||||
for (Point point : points) {
|
||||
if (Verify.notNull(point, lastPoint)) {
|
||||
long date = (long) point.getX();
|
||||
long lastDate = (long) lastPoint.getX();
|
||||
double y = point.getY();
|
||||
double lastY = lastPoint.getY();
|
||||
if (Double.compare(y, lastY) != 0 && Math.abs(lastY - y) > 0.5) {
|
||||
if (lastDate < date - TimeAmount.MINUTE.ms() * 10L) {
|
||||
toAdd.add(new Point(lastDate + 1, lastY));
|
||||
toAdd.add(new Point(date - 1, lastY));
|
||||
}
|
||||
}
|
||||
}
|
||||
lastPoint = point;
|
||||
}
|
||||
points.addAll(toAdd);
|
||||
points.sort(new PointComparator());
|
||||
points = ReduceGapTriangles.reduce(points);
|
||||
}
|
||||
|
||||
int size = points.size();
|
||||
|
@ -5,15 +5,11 @@
|
||||
*/
|
||||
package main.java.com.djrapitops.plan.ui.html.graphs;
|
||||
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.DouglasPeuckerAlgorithm;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.Point;
|
||||
import main.java.com.djrapitops.plan.utilities.comparators.PointComparator;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.ReduceGapTriangles;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Abstract scatter graph creator used by other graph creators.
|
||||
@ -42,26 +38,7 @@ public class SeriesCreator {
|
||||
}
|
||||
|
||||
if (reduceGapTriangles) {
|
||||
Point lastPoint = null;
|
||||
|
||||
Set<Point> toAdd = new HashSet<>();
|
||||
for (Point point : points) {
|
||||
if (Verify.notNull(point, lastPoint)) {
|
||||
long date = (long) point.getX();
|
||||
long lastDate = (long) lastPoint.getX();
|
||||
double y = point.getY();
|
||||
double lastY = lastPoint.getY();
|
||||
if (Double.compare(y, lastY) != 0 && Math.abs(lastY - y) > 0.5) {
|
||||
if (lastDate < date - TimeAmount.MINUTE.ms() * 10L) {
|
||||
toAdd.add(new Point(lastDate + 1, lastY));
|
||||
toAdd.add(new Point(date - 1, lastY));
|
||||
}
|
||||
}
|
||||
}
|
||||
lastPoint = point;
|
||||
}
|
||||
points.addAll(toAdd);
|
||||
points.sort(new PointComparator());
|
||||
points = ReduceGapTriangles.reduce(points);
|
||||
}
|
||||
|
||||
int size = points.size();
|
||||
@ -74,6 +51,7 @@ public class SeriesCreator {
|
||||
arrayBuilder.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
arrayBuilder.append("]");
|
||||
return arrayBuilder.toString();
|
||||
}
|
||||
|
@ -22,13 +22,14 @@ public class TPSGraphCreator {
|
||||
}
|
||||
|
||||
public static String buildSeriesDataString(List<TPS> tpsData) {
|
||||
long now = MiscUtils.getTime();
|
||||
List<Point> points = tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getTps()))
|
||||
.collect(Collectors.toList());
|
||||
return ScatterGraphCreator.scatterGraph(points, true);
|
||||
|
||||
}public static String buildScatterDataStringTPS(List<TPS> tpsData, long scale) {
|
||||
}
|
||||
|
||||
public static String buildScatterDataStringTPS(List<TPS> tpsData, long scale) {
|
||||
long now = MiscUtils.getTime();
|
||||
List<Point> points = tpsData.stream()
|
||||
.filter(tps -> tps.getDate() >= now - scale)
|
||||
|
@ -7,6 +7,7 @@ import main.java.com.djrapitops.plan.Phrase;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.Settings;
|
||||
import main.java.com.djrapitops.plan.data.WebUser;
|
||||
import main.java.com.djrapitops.plan.data.cache.PageCacheHandler;
|
||||
import main.java.com.djrapitops.plan.database.tables.SecurityTable;
|
||||
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
|
||||
import main.java.com.djrapitops.plan.ui.webserver.response.*;
|
||||
@ -224,11 +225,11 @@ public class WebServer {
|
||||
|
||||
private Response getResponse(String target, WebUser user) {
|
||||
if ("/favicon.ico".equals(target)) {
|
||||
return new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico");
|
||||
return PageCacheHandler.loadPage("Redirect: favicon", () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"));
|
||||
}
|
||||
if (usingHttps) {
|
||||
if (user == null) {
|
||||
return new PromptAuthorizationResponse();
|
||||
return PageCacheHandler.loadPage("promptAuthorization", PromptAuthorizationResponse::new);
|
||||
}
|
||||
|
||||
int permLevel = user.getPermLevel(); // Lower number has higher clearance.
|
||||
@ -245,7 +246,7 @@ public class WebServer {
|
||||
String page = args[1];
|
||||
switch (page) {
|
||||
case "players":
|
||||
return new PlayersPageResponse(plugin);
|
||||
return PageCacheHandler.loadPage("players", () -> new PlayersPageResponse(plugin));
|
||||
case "player":
|
||||
return playerResponse(args);
|
||||
case "server":
|
||||
@ -255,15 +256,17 @@ public class WebServer {
|
||||
}
|
||||
}
|
||||
|
||||
private ForbiddenResponse forbiddenResponse(int permLevel, int required) {
|
||||
ForbiddenResponse response403 = new ForbiddenResponse();
|
||||
String content = "<h1>403 Forbidden - Access Denied</h1>"
|
||||
+ "<p>Unauthorized User.<br>"
|
||||
+ "Make sure your user has the correct access level.<br>"
|
||||
+ "This page requires permission level of " + String.valueOf(required) + ",<br>"
|
||||
+ "This user has permission level of " + String.valueOf(permLevel) + "</p>";
|
||||
response403.setContent(content);
|
||||
return response403;
|
||||
private Response forbiddenResponse(int permLevel, int required) {
|
||||
return PageCacheHandler.loadPage("forbidden", () -> {
|
||||
ForbiddenResponse response403 = new ForbiddenResponse();
|
||||
String content = "<h1>403 Forbidden - Access Denied</h1>"
|
||||
+ "<p>Unauthorized User.<br>"
|
||||
+ "Make sure your user has the correct access level.<br>"
|
||||
+ "This page requires permission level of " + String.valueOf(required) + ",<br>"
|
||||
+ "This user has permission level of " + String.valueOf(permLevel) + "</p>";
|
||||
response403.setContent(content);
|
||||
return response403;
|
||||
});
|
||||
}
|
||||
|
||||
private Response rootPageResponse(WebUser user) {
|
||||
@ -274,7 +277,7 @@ public class WebServer {
|
||||
case 0:
|
||||
return serverResponse();
|
||||
case 1:
|
||||
return new PlayersPageResponse(plugin);
|
||||
return PageCacheHandler.loadPage("players", () -> new PlayersPageResponse(plugin));
|
||||
case 2:
|
||||
return playerResponse(new String[]{"", "", user.getName()});
|
||||
default:
|
||||
@ -284,34 +287,45 @@ public class WebServer {
|
||||
|
||||
private Response serverResponse() {
|
||||
if (!dataReqHandler.checkIfAnalysisIsCached()) {
|
||||
return new NotFoundResponse("Analysis Data was not cached.<br>Use /plan analyze to cache the Data.");
|
||||
String error = "Analysis Data was not cached.<br>Use /plan analyze to cache the Data.";
|
||||
PageCacheHandler.loadPage("notFound: " + error, () -> new NotFoundResponse(error));
|
||||
}
|
||||
return new AnalysisPageResponse(dataReqHandler);
|
||||
|
||||
return PageCacheHandler.loadPage("analysisPage", () -> new AnalysisPageResponse(dataReqHandler));
|
||||
}
|
||||
|
||||
private Response playerResponse(String[] args) {
|
||||
if (args.length < 3) {
|
||||
return new NotFoundResponse();
|
||||
return PageCacheHandler.loadPage("notFound", NotFoundResponse::new);
|
||||
}
|
||||
|
||||
String playerName = args[2].trim();
|
||||
UUID uuid = UUIDUtility.getUUIDOf(playerName);
|
||||
|
||||
if (uuid == null) {
|
||||
return new NotFoundResponse("Player has no UUID");
|
||||
String error = "Player has no UUID";
|
||||
return PageCacheHandler.loadPage("notFound: " + error, () -> new NotFoundResponse(error));
|
||||
}
|
||||
|
||||
if (!dataReqHandler.checkIfCached(uuid)) {
|
||||
return new NotFoundResponse("Player's data was not cached.<br>Use /plan inspect " + playerName + " to cache the Data.");
|
||||
String error = "Player's data was not cached.<br>Use /plan inspect " + playerName + " to cache the Data.";
|
||||
return PageCacheHandler.loadPage("notFound: " + error, () -> new NotFoundResponse(error));
|
||||
}
|
||||
return new InspectPageResponse(dataReqHandler, uuid);
|
||||
|
||||
return PageCacheHandler.loadPage("inspectPage: " + uuid.toString(), () -> new InspectPageResponse(dataReqHandler, uuid));
|
||||
}
|
||||
|
||||
private Response notFoundResponse() {
|
||||
NotFoundResponse response404 = new NotFoundResponse();
|
||||
String content = "<h1>404 Not Found</h1>"
|
||||
String error = "<h1>404 Not Found</h1>"
|
||||
+ "<p>Make sure you're accessing a link given by a command, Examples:</p>"
|
||||
+ "<p>" + getProtocol() + HtmlUtils.getInspectUrl("<player>") + " or<br>"
|
||||
+ getProtocol() + HtmlUtils.getServerAnalysisUrl() + "</p>";
|
||||
response404.setContent(content);
|
||||
return response404;
|
||||
|
||||
return PageCacheHandler.loadPage("notFound: " + error, () -> {
|
||||
Response response404 = new NotFoundResponse();
|
||||
response404.setContent(error);
|
||||
return response404;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,13 +371,11 @@ public class WebServer {
|
||||
if (t.length < 3) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
final String wantedUser = t[2].toLowerCase().trim();
|
||||
final String theUser = user.trim().toLowerCase();
|
||||
if (wantedUser.equals(theUser)) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return wantedUser.equals(theUser) ? 2 : 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,10 +36,6 @@ public abstract class Response {
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
if (header == null) {
|
||||
return 500;
|
||||
} else {
|
||||
return Integer.parseInt(header.split(" ")[1]);
|
||||
}
|
||||
return header == null ? 500 : Integer.parseInt(header.split(" ")[1]);
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,11 @@ import main.java.com.djrapitops.plan.data.analysis.*;
|
||||
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.data.cache.PageCacheHandler;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.ui.html.tables.PlayersTableCreator;
|
||||
import main.java.com.djrapitops.plan.ui.webserver.response.AnalysisPageResponse;
|
||||
import main.java.com.djrapitops.plan.ui.webserver.response.PlayersPageResponse;
|
||||
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
@ -47,7 +50,7 @@ public class Analysis {
|
||||
* Analyzes the data of all offline players on the server.
|
||||
* <p>
|
||||
* First retrieves all offline players and checks those that are in the
|
||||
* database. Then Runs a new Analysis Task Asynchronously. Saves AnalysisData
|
||||
* database. Then runs a new Analysis Task asynchronously. Saves AnalysisData
|
||||
* to the provided Cache. Saves all UserData to InspectCache for 15 minutes.
|
||||
*
|
||||
* @param analysisCache Cache that the data is saved to.
|
||||
@ -56,6 +59,7 @@ public class Analysis {
|
||||
if (isAnalysisBeingRun()) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.processStatus().startExecution("Analysis");
|
||||
log(Phrase.ANALYSIS_START.toString());
|
||||
// Async task for Analysis
|
||||
@ -79,8 +83,9 @@ public class Analysis {
|
||||
* @return Whether or not analysis was successful.
|
||||
*/
|
||||
public boolean analyze(AnalysisCacheHandler analysisCache, Database db) {
|
||||
log(Phrase.ANALYSIS_FETCH_DATA + "");
|
||||
log(Phrase.ANALYSIS_FETCH_DATA.toString());
|
||||
Benchmark.start("Analysis: Fetch Phase");
|
||||
|
||||
plugin.processStatus().setStatus("Analysis", "Analysis Fetch Phase");
|
||||
try {
|
||||
inspectCache.cacheAllUserData(db);
|
||||
@ -88,18 +93,22 @@ public class Analysis {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
Log.error(Phrase.ERROR_ANALYSIS_FETCH_FAIL.toString());
|
||||
}
|
||||
|
||||
List<UserData> rawData = inspectCache.getCachedUserData();
|
||||
if (rawData.isEmpty()) {
|
||||
Log.info(Phrase.ANALYSIS_FAIL_NO_DATA.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
List<TPS> tpsData = new ArrayList<>();
|
||||
|
||||
try {
|
||||
tpsData = db.getTpsTable().getTPSData();
|
||||
Log.debug("TPS Data Size: " + tpsData.size());
|
||||
} catch (Exception ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
|
||||
return analyzeData(rawData, tpsData, analysisCache);
|
||||
}
|
||||
|
||||
@ -150,7 +159,10 @@ public class Analysis {
|
||||
if (Settings.ANALYSIS_LOG_FINISHED.isTrue()) {
|
||||
Log.info(Phrase.ANALYSIS_COMPLETE.parse(String.valueOf(time), HtmlUtils.getServerAnalysisUrlWithProtocol()));
|
||||
}
|
||||
|
||||
ExportUtility.export(plugin, analysisData, rawData);
|
||||
PageCacheHandler.cachePage("analysisPage", () -> new AnalysisPageResponse(plugin.getUiServer().getDataReqHandler()));
|
||||
PageCacheHandler.cachePage("players", () -> new PlayersPageResponse(plugin));
|
||||
} catch (Exception e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
plugin.processStatus().setStatus("Analysis", "Error: " + e);
|
||||
|
@ -24,9 +24,11 @@ public class DouglasPeuckerAlgorithm {
|
||||
if (points.isEmpty()) {
|
||||
return points;
|
||||
}
|
||||
|
||||
if (Double.compare(epsilon, -1) == 0) {
|
||||
epsilon = 0.002;
|
||||
}
|
||||
|
||||
int size = points.size();
|
||||
final int lastIndex = size - 1;
|
||||
final Point start = points.get(0);
|
||||
|
@ -186,11 +186,6 @@ public class MathUtils {
|
||||
* @return The rounded number
|
||||
*/
|
||||
public static double round(double number) {
|
||||
String formattedNumber = decimalFormat.format(number);
|
||||
if (formattedNumber.length() > 4) {
|
||||
formattedNumber = formattedNumber.substring(0, 3); //Fix for unknown reasons for not-rounding
|
||||
}
|
||||
|
||||
return Double.valueOf(formattedNumber);
|
||||
return Double.valueOf(decimalFormat.format(number));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
package main.java.com.djrapitops.plan.utilities.analysis;
|
||||
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.utilities.comparators.PointComparator;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by Fuzzlemann on 30.07.2017.
|
||||
*/
|
||||
public class ReduceGapTriangles {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private ReduceGapTriangles() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static List<Point> reduce(List<Point> points) {
|
||||
Point lastPoint = null;
|
||||
|
||||
Set<Point> toAdd = new HashSet<>();
|
||||
for (Point point : points) {
|
||||
if (!Verify.notNull(point, lastPoint)) {
|
||||
lastPoint = point;
|
||||
continue;
|
||||
}
|
||||
|
||||
long date = (long) point.getX();
|
||||
long lastDate = (long) lastPoint.getX();
|
||||
double y = point.getY();
|
||||
double lastY = lastPoint.getY();
|
||||
|
||||
if (Double.compare(y, lastY) != 0
|
||||
&& Math.abs(lastY - y) > 0.5
|
||||
&& lastDate < date - TimeAmount.MINUTE.ms() * 10L) {
|
||||
toAdd.add(new Point(lastDate + 1, lastY));
|
||||
toAdd.add(new Point(date - 1, lastY));
|
||||
}
|
||||
|
||||
lastPoint = point;
|
||||
}
|
||||
|
||||
points.addAll(toAdd);
|
||||
points.sort(new PointComparator());
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
@ -1152,13 +1152,13 @@
|
||||
var dm = Math.floor(seconds / 60);
|
||||
seconds -= (dm * 60);
|
||||
seconds = Math.floor(seconds);
|
||||
if (dd != 0) {
|
||||
if (dd !== 0) {
|
||||
out += dd.toString() + "d ";
|
||||
}
|
||||
if (dh != 0) {
|
||||
if (dh !== 0) {
|
||||
out += dh.toString() + "h ";
|
||||
}
|
||||
if (dm != 0) {
|
||||
if (dm !== 0) {
|
||||
out += dm.toString() + "m ";
|
||||
}
|
||||
out += seconds.toString() + "s ";
|
||||
|
@ -32,7 +32,7 @@ public class ChatInfoTest {
|
||||
public void testProcessNick() {
|
||||
UserData data = MockUtils.mockUser();
|
||||
String expected = "TestNicknameChatInfo";
|
||||
ChatInfo i = new ChatInfo(data.getUuid(), expected, "im 18 male");
|
||||
ChatInfo i = new ChatInfo(data.getUuid(), expected);
|
||||
assertTrue("Didn't succeed", i.process(data));
|
||||
assertTrue("Didn't add nickname", data.getNicknames().contains(expected));
|
||||
}
|
||||
@ -44,7 +44,7 @@ public class ChatInfoTest {
|
||||
public void testProcessWrongUUID() {
|
||||
UserData data = MockUtils.mockUser();
|
||||
String expected = "TestNicknameChatInfo";
|
||||
ChatInfo i = new ChatInfo(null, expected, "im 18 male");
|
||||
ChatInfo i = new ChatInfo(null, expected);
|
||||
assertTrue("Succeeded.", !i.process(data));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user