mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-01 00:10:12 +01:00
commit
0d3eb77d90
@ -306,10 +306,6 @@
|
|||||||
<artifactId>guice</artifactId>
|
<artifactId>guice</artifactId>
|
||||||
<groupId>com.google.inject</groupId>
|
<groupId>com.google.inject</groupId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
|
||||||
<artifactId>caffeine</artifactId>
|
|
||||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
14
Plan/pom.xml
14
Plan/pom.xml
@ -122,6 +122,13 @@
|
|||||||
<version>2.9.0</version>
|
<version>2.9.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Cache with invalidation -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
<version>2.6.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Metrics -->
|
<!-- Metrics -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bstats</groupId>
|
<groupId>org.bstats</groupId>
|
||||||
@ -139,6 +146,13 @@
|
|||||||
<version>1.2</version>
|
<version>1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- HTML Compression -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlecode.htmlcompressor</groupId>
|
||||||
|
<artifactId>htmlcompressor</artifactId>
|
||||||
|
<version>1.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Mockito (Test Dependency) -->
|
<!-- Mockito (Test Dependency) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
|
@ -25,7 +25,7 @@ import org.spongepowered.api.plugin.Plugin;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@Plugin(id = "plan", name = "Plan", version = "4.4.5", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"})
|
@Plugin(id = "plan", name = "Plan", version = "4.4.6", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"})
|
||||||
public class PlanSponge extends SpongePlugin implements PlanPlugin {
|
public class PlanSponge extends SpongePlugin implements PlanPlugin {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
package com.djrapitops.plan.data.element;
|
package com.djrapitops.plan.data.element;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@ -25,18 +27,18 @@ import java.util.TreeMap;
|
|||||||
*/
|
*/
|
||||||
public class InspectContainer {
|
public class InspectContainer {
|
||||||
|
|
||||||
protected TreeMap<String, String> values;
|
protected List<String> values;
|
||||||
protected TreeMap<String, String> html;
|
protected TreeMap<String, String> html;
|
||||||
protected TreeMap<String, TableContainer> tables;
|
protected TreeMap<String, TableContainer> tables;
|
||||||
|
|
||||||
public InspectContainer() {
|
public InspectContainer() {
|
||||||
values = new TreeMap<>();
|
values = new ArrayList<>();
|
||||||
html = new TreeMap<>();
|
html = new TreeMap<>();
|
||||||
tables = new TreeMap<>();
|
tables = new TreeMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void addValue(String label, Serializable value) {
|
public final void addValue(String label, Serializable value) {
|
||||||
values.put(label, value.toString());
|
values.add(label + ": " + value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void addHtml(String key, String html) {
|
public final void addHtml(String key, String html) {
|
||||||
@ -52,8 +54,8 @@ public class InspectContainer {
|
|||||||
|
|
||||||
if (!values.isEmpty()) {
|
if (!values.isEmpty()) {
|
||||||
parsed.append("<div class=\"body\">");
|
parsed.append("<div class=\"body\">");
|
||||||
for (Map.Entry<String, String> entry : values.entrySet()) {
|
for (String value : values) {
|
||||||
parsed.append("<p>").append(entry.getKey()).append(": ").append(entry.getValue()).append("</p>");
|
parsed.append("<p>").append(value).append("</p>");
|
||||||
}
|
}
|
||||||
parsed.append("</div>");
|
parsed.append("</div>");
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,9 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addAnalysisSuppliers() {
|
private void addAnalysisSuppliers() {
|
||||||
putSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> SessionsMutator.forContainer(serverContainer));
|
putCachingSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> SessionsMutator.forContainer(serverContainer));
|
||||||
putSupplier(AnalysisKeys.TPS_MUTATOR, () -> TPSMutator.forContainer(serverContainer));
|
putCachingSupplier(AnalysisKeys.TPS_MUTATOR, () -> TPSMutator.forContainer(serverContainer));
|
||||||
putSupplier(AnalysisKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(serverContainer));
|
putCachingSupplier(AnalysisKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(serverContainer));
|
||||||
|
|
||||||
addConstants();
|
addConstants();
|
||||||
addPlayerSuppliers();
|
addPlayerSuppliers();
|
||||||
@ -101,7 +101,7 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addServerProperties() {
|
private void addServerProperties() {
|
||||||
putSupplier(AnalysisKeys.SERVER_NAME, () ->
|
putCachingSupplier(AnalysisKeys.SERVER_NAME, () ->
|
||||||
getUnsafe(serverNames).getOrDefault(serverContainer.getUnsafe(ServerKeys.SERVER_UUID), "Plan")
|
getUnsafe(serverNames).getOrDefault(serverContainer.getUnsafe(ServerKeys.SERVER_UUID), "Plan")
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addPlayerSuppliers() {
|
private void addPlayerSuppliers() {
|
||||||
putSupplier(AnalysisKeys.PLAYER_NAMES, () -> serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())
|
putCachingSupplier(AnalysisKeys.PLAYER_NAMES, () -> serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())
|
||||||
.stream().collect(Collectors.toMap(
|
.stream().collect(Collectors.toMap(
|
||||||
p -> p.getUnsafe(PlayerKeys.UUID), p -> p.getValue(PlayerKeys.NAME).orElse("?"))
|
p -> p.getUnsafe(PlayerKeys.UUID), p -> p.getValue(PlayerKeys.NAME).orElse("?"))
|
||||||
)
|
)
|
||||||
@ -169,22 +169,22 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY");
|
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY");
|
||||||
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK");
|
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK");
|
||||||
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH");
|
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH");
|
||||||
putSupplier(newDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(newDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(newWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(newWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(newMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(newMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(uniqueDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(uniqueDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||||
.filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(uniqueWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(uniqueWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||||
.filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(uniqueMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(uniqueMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||||
.filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
|
|
||||||
Key<Integer> retentionDay = new Key<>(Integer.class, "RETENTION_DAY");
|
Key<Integer> retentionDay = new Key<>(Integer.class, "RETENTION_DAY");
|
||||||
// compareAndFindThoseLikelyToBeRetained can throw exception.
|
// compareAndFindThoseLikelyToBeRetained can throw exception.
|
||||||
putSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained(
|
putCachingSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained(
|
||||||
getUnsafe(newDay).all(), getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
getUnsafe(newDay).all(), getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
||||||
getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER)
|
getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER)
|
||||||
).count()
|
).count()
|
||||||
@ -224,13 +224,13 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK, () ->
|
putCachingSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK, () ->
|
||||||
getUnsafe(newWeek).filterRetained(
|
getUnsafe(newWeek).filterRetained(
|
||||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO),
|
getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO),
|
||||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME)
|
getUnsafe(AnalysisKeys.ANALYSIS_TIME)
|
||||||
).count()
|
).count()
|
||||||
);
|
);
|
||||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH, () ->
|
putCachingSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH, () ->
|
||||||
getUnsafe(newMonth).filterRetained(
|
getUnsafe(newMonth).filterRetained(
|
||||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
||||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME)
|
getUnsafe(AnalysisKeys.ANALYSIS_TIME)
|
||||||
@ -260,8 +260,8 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
|
|
||||||
private void addSessionSuppliers() {
|
private void addSessionSuppliers() {
|
||||||
Key<SessionAccordion> sessionAccordion = new Key<>(SessionAccordion.class, "SESSION_ACCORDION");
|
Key<SessionAccordion> sessionAccordion = new Key<>(SessionAccordion.class, "SESSION_ACCORDION");
|
||||||
putSupplier(serverNames, () -> Database.getActive().fetch().getServerNames());
|
putCachingSupplier(serverNames, () -> Database.getActive().fetch().getServerNames());
|
||||||
putSupplier(sessionAccordion, () -> SessionAccordion.forServer(
|
putCachingSupplier(sessionAccordion, () -> SessionAccordion.forServer(
|
||||||
getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(),
|
getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(),
|
||||||
getSupplier(serverNames),
|
getSupplier(serverNames),
|
||||||
() -> getUnsafe(AnalysisKeys.PLAYER_NAMES)
|
() -> getUnsafe(AnalysisKeys.PLAYER_NAMES)
|
||||||
@ -301,13 +301,13 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
Key<SessionsMutator> sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY");
|
Key<SessionsMutator> sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY");
|
||||||
Key<SessionsMutator> sessionsWeek = new Key<>(SessionsMutator.class, "SESSIONS_WEEK");
|
Key<SessionsMutator> sessionsWeek = new Key<>(SessionsMutator.class, "SESSIONS_WEEK");
|
||||||
Key<SessionsMutator> sessionsMonth = new Key<>(SessionsMutator.class, "SESSIONS_MONTH");
|
Key<SessionsMutator> sessionsMonth = new Key<>(SessionsMutator.class, "SESSIONS_MONTH");
|
||||||
putSupplier(sessionsDay, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
putCachingSupplier(sessionsDay, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(sessionsWeek, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
putCachingSupplier(sessionsWeek, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(sessionsMonth, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
putCachingSupplier(sessionsMonth, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
|
|
||||||
private void addGraphSuppliers() {
|
private void addGraphSuppliers() {
|
||||||
Key<WorldPie> worldPie = new Key<>(WorldPie.class, "WORLD_PIE");
|
Key<WorldPie> worldPie = new Key<>(WorldPie.class, "WORLD_PIE");
|
||||||
putSupplier(worldPie, () -> new WorldPie(serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>()))));
|
putCachingSupplier(worldPie, () -> new WorldPie(serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>()))));
|
||||||
putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries());
|
putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries());
|
||||||
putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown());
|
putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown());
|
||||||
putSupplier(AnalysisKeys.PLAYERS_ONLINE_SERIES, () ->
|
putSupplier(AnalysisKeys.PLAYERS_ONLINE_SERIES, () ->
|
||||||
@ -335,12 +335,12 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
new WorldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).getGeolocations()).toHighChartsSeries()
|
new WorldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).getGeolocations()).toHighChartsSeries()
|
||||||
);
|
);
|
||||||
Key<GeolocationBarGraph> geolocationBarChart = new Key<>(GeolocationBarGraph.class, "GEOLOCATION_BAR_CHART");
|
Key<GeolocationBarGraph> geolocationBarChart = new Key<>(GeolocationBarGraph.class, "GEOLOCATION_BAR_CHART");
|
||||||
putSupplier(geolocationBarChart, () -> new GeolocationBarGraph(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)));
|
putCachingSupplier(geolocationBarChart, () -> new GeolocationBarGraph(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)));
|
||||||
putSupplier(AnalysisKeys.COUNTRY_CATEGORIES, () -> getUnsafe(geolocationBarChart).toHighChartsCategories());
|
putSupplier(AnalysisKeys.COUNTRY_CATEGORIES, () -> getUnsafe(geolocationBarChart).toHighChartsCategories());
|
||||||
putSupplier(AnalysisKeys.COUNTRY_SERIES, () -> getUnsafe(geolocationBarChart).toHighChartsSeries());
|
putSupplier(AnalysisKeys.COUNTRY_SERIES, () -> getUnsafe(geolocationBarChart).toHighChartsSeries());
|
||||||
|
|
||||||
Key<PingGraph> pingGraph = new Key<>(PingGraph.class, "PING_GRAPH");
|
Key<PingGraph> pingGraph = new Key<>(PingGraph.class, "PING_GRAPH");
|
||||||
putSupplier(pingGraph, () -> new PingGraph(
|
putCachingSupplier(pingGraph, () -> new PingGraph(
|
||||||
PingMutator.forContainer(serverContainer).mutateToByMinutePings().all()
|
PingMutator.forContainer(serverContainer).mutateToByMinutePings().all()
|
||||||
));
|
));
|
||||||
putSupplier(AnalysisKeys.AVG_PING_SERIES, () -> getUnsafe(pingGraph).toAvgSeries());
|
putSupplier(AnalysisKeys.AVG_PING_SERIES, () -> getUnsafe(pingGraph).toAvgSeries());
|
||||||
@ -353,9 +353,9 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY)
|
getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY)
|
||||||
).toCalendarSeries());
|
).toCalendarSeries());
|
||||||
|
|
||||||
putSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME)));
|
putCachingSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME)));
|
||||||
Key<ActivityStackGraph> activityStackGraph = new Key<>(ActivityStackGraph.class, "ACTIVITY_STACK_GRAPH");
|
Key<ActivityStackGraph> activityStackGraph = new Key<>(ActivityStackGraph.class, "ACTIVITY_STACK_GRAPH");
|
||||||
putSupplier(activityStackGraph, () -> new ActivityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA)));
|
putCachingSupplier(activityStackGraph, () -> new ActivityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA)));
|
||||||
putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels());
|
putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels());
|
||||||
putSupplier(AnalysisKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries());
|
putSupplier(AnalysisKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries());
|
||||||
putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () ->
|
putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () ->
|
||||||
@ -376,17 +376,17 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
Key<TPSMutator> tpsWeek = new Key<>(TPSMutator.class, "TPS_WEEK");
|
Key<TPSMutator> tpsWeek = new Key<>(TPSMutator.class, "TPS_WEEK");
|
||||||
Key<TPSMutator> tpsDay = new Key<>(TPSMutator.class, "TPS_DAY");
|
Key<TPSMutator> tpsDay = new Key<>(TPSMutator.class, "TPS_DAY");
|
||||||
|
|
||||||
putSupplier(tpsMonth, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
putCachingSupplier(tpsMonth, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
||||||
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(tpsWeek, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
putCachingSupplier(tpsWeek, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
||||||
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(tpsDay, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
putCachingSupplier(tpsDay, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
||||||
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||||
);
|
);
|
||||||
|
|
||||||
putSupplier(AnalysisKeys.PLAYERS_ONLINE_RESOLVER, () -> new PlayersOnlineResolver(getUnsafe(AnalysisKeys.TPS_MUTATOR)));
|
putCachingSupplier(AnalysisKeys.PLAYERS_ONLINE_RESOLVER, () -> new PlayersOnlineResolver(getUnsafe(AnalysisKeys.TPS_MUTATOR)));
|
||||||
|
|
||||||
putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount());
|
putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount());
|
||||||
putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS());
|
putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS());
|
||||||
@ -416,7 +416,7 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
|
|
||||||
private void addServerHealth() {
|
private void addServerHealth() {
|
||||||
Key<HealthInformation> healthInformation = new Key<>(HealthInformation.class, "HEALTH_INFORMATION");
|
Key<HealthInformation> healthInformation = new Key<>(HealthInformation.class, "HEALTH_INFORMATION");
|
||||||
putSupplier(healthInformation, () -> new HealthInformation(this));
|
putCachingSupplier(healthInformation, () -> new HealthInformation(this));
|
||||||
putSupplier(AnalysisKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
putSupplier(AnalysisKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
||||||
putSupplier(AnalysisKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
putSupplier(AnalysisKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
||||||
}
|
}
|
||||||
@ -424,13 +424,13 @@ public class AnalysisContainer extends DataContainer {
|
|||||||
private void addPluginSuppliers() {
|
private void addPluginSuppliers() {
|
||||||
// TODO Refactor into a system that supports running the analysis on Bungee
|
// TODO Refactor into a system that supports running the analysis on Bungee
|
||||||
Key<String[]> navAndTabs = new Key<>(new Type<String[]>() {}, "NAV_AND_TABS");
|
Key<String[]> navAndTabs = new Key<>(new Type<String[]>() {}, "NAV_AND_TABS");
|
||||||
putSupplier(navAndTabs, () ->
|
putCachingSupplier(navAndTabs, () ->
|
||||||
AnalysisPluginsTabContentCreator.createContent(
|
AnalysisPluginsTabContentCreator.createContent(
|
||||||
getUnsafe(AnalysisKeys.PLAYERS_MUTATOR),
|
getUnsafe(AnalysisKeys.PLAYERS_MUTATOR),
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
putSupplier(AnalysisKeys.BAN_DATA, () -> new ServerBanDataReader().readBanDataForContainer(this));
|
putCachingSupplier(AnalysisKeys.BAN_DATA, () -> new ServerBanDataReader().readBanDataForContainer(this));
|
||||||
putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(navAndTabs)[0]);
|
putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(navAndTabs)[0]);
|
||||||
putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(navAndTabs)[1]);
|
putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(navAndTabs)[1]);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,13 @@ public class DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> void putSupplier(Key<T> key, Supplier<T> supplier) {
|
public <T> void putSupplier(Key<T> key, Supplier<T> supplier) {
|
||||||
|
if (supplier == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map.put(key, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void putCachingSupplier(Key<T> key, Supplier<T> supplier) {
|
||||||
if (supplier == null) {
|
if (supplier == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class NetworkContainer extends DataContainer {
|
|||||||
this.bungeeContainer = bungeeContainer;
|
this.bungeeContainer = bungeeContainer;
|
||||||
serverContainers = new HashMap<>();
|
serverContainers = new HashMap<>();
|
||||||
|
|
||||||
putSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer));
|
putCachingSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer));
|
||||||
|
|
||||||
addConstants();
|
addConstants();
|
||||||
addPlayerInformation();
|
addPlayerInformation();
|
||||||
@ -55,9 +55,9 @@ public class NetworkContainer extends DataContainer {
|
|||||||
|
|
||||||
private void addNetworkHealth() {
|
private void addNetworkHealth() {
|
||||||
Key<NetworkHealthInformation> healthInformation = new Key<>(NetworkHealthInformation.class, "HEALTH_INFORMATION");
|
Key<NetworkHealthInformation> healthInformation = new Key<>(NetworkHealthInformation.class, "HEALTH_INFORMATION");
|
||||||
putSupplier(healthInformation, () -> new NetworkHealthInformation(this));
|
putCachingSupplier(healthInformation, () -> new NetworkHealthInformation(this));
|
||||||
putSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
putCachingSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
||||||
putSupplier(NetworkKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
putCachingSupplier(NetworkKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putAnalysisContainer(AnalysisContainer analysisContainer) {
|
public void putAnalysisContainer(AnalysisContainer analysisContainer) {
|
||||||
@ -90,7 +90,7 @@ public class NetworkContainer extends DataContainer {
|
|||||||
putRawData(NetworkKeys.VERSION, PlanPlugin.getInstance().getVersion());
|
putRawData(NetworkKeys.VERSION, PlanPlugin.getInstance().getVersion());
|
||||||
putSupplier(NetworkKeys.TIME_ZONE, MiscUtils::getTimeZoneOffsetHours);
|
putSupplier(NetworkKeys.TIME_ZONE, MiscUtils::getTimeZoneOffsetHours);
|
||||||
|
|
||||||
putSupplier(NetworkKeys.NETWORK_NAME, () ->
|
putCachingSupplier(NetworkKeys.NETWORK_NAME, () ->
|
||||||
Check.isBungeeAvailable() ?
|
Check.isBungeeAvailable() ?
|
||||||
Settings.BUNGEE_NETWORK_NAME.toString() :
|
Settings.BUNGEE_NETWORK_NAME.toString() :
|
||||||
bungeeContainer.getValue(ServerKeys.NAME).orElse("Plan")
|
bungeeContainer.getValue(ServerKeys.NAME).orElse("Plan")
|
||||||
@ -146,22 +146,22 @@ public class NetworkContainer extends DataContainer {
|
|||||||
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY");
|
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY");
|
||||||
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK");
|
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK");
|
||||||
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH");
|
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH");
|
||||||
putSupplier(newDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(newDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||||
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(newWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(newWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||||
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(newMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(newMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||||
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(uniqueDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(uniqueDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||||
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(uniqueWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(uniqueWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||||
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||||
);
|
);
|
||||||
putSupplier(uniqueMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
putCachingSupplier(uniqueMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||||
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -57,20 +57,13 @@ public class TimeAmountFormatter implements Formatter<Long> {
|
|||||||
return formattedTime;
|
return formattedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendSeconds(StringBuilder builder, long seconds, long minutes, long hours, String fHours, String fMinutes, String fSeconds) {
|
private void appendHours(StringBuilder builder, long hours, String fHours) {
|
||||||
if (seconds != 0) {
|
if (hours != 0) {
|
||||||
String s = fSeconds.replace(SECONDS_PH, String.valueOf(seconds));
|
String h = fHours.replace(HOURS_PH, String.valueOf(hours));
|
||||||
if (minutes == 0 && s.contains(MINUTES_PH)) {
|
if (h.contains(ZERO_PH) && String.valueOf(hours).length() == 1) {
|
||||||
if (hours == 0 && fMinutes.contains(HOURS_PH)) {
|
|
||||||
builder.append(fHours.replace(ZERO_PH, "0").replace(HOURS_PH, "0"));
|
|
||||||
}
|
|
||||||
builder.append(fMinutes.replace(HOURS_PH, "").replace(ZERO_PH, "0").replace(MINUTES_PH, "0"));
|
|
||||||
}
|
|
||||||
s = s.replace(MINUTES_PH, "");
|
|
||||||
if (s.contains(ZERO_PH) && String.valueOf(seconds).length() == 1) {
|
|
||||||
builder.append('0');
|
builder.append('0');
|
||||||
}
|
}
|
||||||
builder.append(s);
|
builder.append(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,13 +82,20 @@ public class TimeAmountFormatter implements Formatter<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendHours(StringBuilder builder, long hours, String fHours) {
|
private void appendSeconds(StringBuilder builder, long seconds, long minutes, long hours, String fHours, String fMinutes, String fSeconds) {
|
||||||
if (hours != 0) {
|
if (seconds != 0 || fSeconds.contains(ZERO_PH)) {
|
||||||
String h = fHours.replace(HOURS_PH, String.valueOf(hours));
|
String s = fSeconds.replace(SECONDS_PH, String.valueOf(seconds));
|
||||||
if (h.contains(ZERO_PH) && String.valueOf(hours).length() == 1) {
|
if (minutes == 0 && s.contains(MINUTES_PH)) {
|
||||||
|
if (hours == 0 && fMinutes.contains(HOURS_PH)) {
|
||||||
|
builder.append(fHours.replace(ZERO_PH, "0").replace(HOURS_PH, "0"));
|
||||||
|
}
|
||||||
|
builder.append(fMinutes.replace(HOURS_PH, "").replace(ZERO_PH, "0").replace(MINUTES_PH, "0"));
|
||||||
|
}
|
||||||
|
s = s.replace(MINUTES_PH, "");
|
||||||
|
if (s.contains(ZERO_PH) && String.valueOf(seconds).length() == 1) {
|
||||||
builder.append('0');
|
builder.append('0');
|
||||||
}
|
}
|
||||||
builder.append(h);
|
builder.append(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,4 +65,14 @@ public class AFKTracker {
|
|||||||
lastMovement.remove(uuid);
|
lastMovement.remove(uuid);
|
||||||
usedAFKCommand.remove(uuid);
|
usedAFKCommand.remove(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAfk(UUID uuid) {
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Long lastMoved = lastMovement.get(uuid);
|
||||||
|
if (lastMoved == null || lastMoved == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return time - lastMoved > afkThresholdMs;
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,6 +16,7 @@ import com.maxmind.geoip2.record.Country;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
@ -147,8 +148,12 @@ public class GeolocationCache implements SubSystem {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
URL downloadSite = new URL("http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz");
|
URL downloadSite = new URL("http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz");
|
||||||
try (ReadableByteChannel rbc = Channels.newChannel(new GZIPInputStream(downloadSite.openStream()));
|
try (
|
||||||
FileOutputStream fos = new FileOutputStream(getInstance().geolocationDB.getAbsoluteFile())) {
|
InputStream in = downloadSite.openStream();
|
||||||
|
GZIPInputStream gzipIn = new GZIPInputStream(in);
|
||||||
|
ReadableByteChannel rbc = Channels.newChannel(gzipIn);
|
||||||
|
FileOutputStream fos = new FileOutputStream(getInstance().geolocationDB.getAbsoluteFile())
|
||||||
|
) {
|
||||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
|
|||||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||||
import com.djrapitops.plan.system.info.server.Server;
|
import com.djrapitops.plan.system.info.server.Server;
|
||||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||||
import com.djrapitops.plugin.api.TimeAmount;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class SQLFetchOps extends SQLOps implements FetchOperations {
|
public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
@Override
|
@Override
|
||||||
public NetworkContainer getNetworkContainer() {
|
public NetworkContainer getNetworkContainer() {
|
||||||
NetworkContainer networkContainer = new NetworkContainer(getBungeeServerContainer());
|
NetworkContainer networkContainer = new NetworkContainer(getBungeeServerContainer());
|
||||||
networkContainer.putSupplier(NetworkKeys.BUKKIT_SERVERS, () -> getBukkitServers().values());
|
networkContainer.putCachingSupplier(NetworkKeys.BUKKIT_SERVERS, () -> getBukkitServers().values());
|
||||||
return networkContainer;
|
return networkContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +38,8 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ServerContainer container = getServerContainer(bungeeInfo.get().getUuid());
|
ServerContainer container = getServerContainer(bungeeInfo.get().getUuid());
|
||||||
container.putSupplier(ServerKeys.PLAYERS, this::getAllPlayerContainers);
|
container.putCachingSupplier(ServerKeys.PLAYERS, this::getAllPlayerContainers);
|
||||||
container.putSupplier(ServerKeys.TPS, tpsTable::getNetworkOnlineData);
|
container.putCachingSupplier(ServerKeys.TPS, tpsTable::getNetworkOnlineData);
|
||||||
container.putSupplier(ServerKeys.WORLD_TIMES, null); // Additional Session information not supported
|
container.putSupplier(ServerKeys.WORLD_TIMES, null); // Additional Session information not supported
|
||||||
container.putSupplier(ServerKeys.PLAYER_KILLS, null);
|
container.putSupplier(ServerKeys.PLAYER_KILLS, null);
|
||||||
container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, null);
|
container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, null);
|
||||||
@ -58,12 +58,12 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
|
|
||||||
container.putRawData(ServerKeys.SERVER_UUID, serverUUID);
|
container.putRawData(ServerKeys.SERVER_UUID, serverUUID);
|
||||||
container.putRawData(ServerKeys.NAME, serverInfo.get().getName());
|
container.putRawData(ServerKeys.NAME, serverInfo.get().getName());
|
||||||
container.putSupplier(ServerKeys.PLAYERS, () -> getPlayerContainers(serverUUID));
|
container.putCachingSupplier(ServerKeys.PLAYERS, () -> getPlayerContainers(serverUUID));
|
||||||
container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getUnsafe(ServerKeys.PLAYERS).size());
|
container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getUnsafe(ServerKeys.PLAYERS).size());
|
||||||
|
|
||||||
container.putSupplier(ServerKeys.TPS, () -> tpsTable.getTPSData(serverUUID));
|
container.putCachingSupplier(ServerKeys.TPS, () -> tpsTable.getTPSData(serverUUID));
|
||||||
container.putSupplier(ServerKeys.PING, () -> PlayersMutator.forContainer(container).pings());
|
container.putCachingSupplier(ServerKeys.PING, () -> PlayersMutator.forContainer(container).pings());
|
||||||
container.putSupplier(ServerKeys.ALL_TIME_PEAK_PLAYERS, () -> {
|
container.putCachingSupplier(ServerKeys.ALL_TIME_PEAK_PLAYERS, () -> {
|
||||||
Optional<TPS> allTimePeak = tpsTable.getAllTimePeak(serverUUID);
|
Optional<TPS> allTimePeak = tpsTable.getAllTimePeak(serverUUID);
|
||||||
if (allTimePeak.isPresent()) {
|
if (allTimePeak.isPresent()) {
|
||||||
TPS peak = allTimePeak.get();
|
TPS peak = allTimePeak.get();
|
||||||
@ -71,8 +71,8 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
container.putSupplier(ServerKeys.RECENT_PEAK_PLAYERS, () -> {
|
container.putCachingSupplier(ServerKeys.RECENT_PEAK_PLAYERS, () -> {
|
||||||
long twoDaysAgo = System.currentTimeMillis() - (TimeAmount.DAY.ms() * 2L);
|
long twoDaysAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(2);
|
||||||
Optional<TPS> lastPeak = tpsTable.getPeakPlayerCount(serverUUID, twoDaysAgo);
|
Optional<TPS> lastPeak = tpsTable.getPeakPlayerCount(serverUUID, twoDaysAgo);
|
||||||
if (lastPeak.isPresent()) {
|
if (lastPeak.isPresent()) {
|
||||||
TPS peak = lastPeak.get();
|
TPS peak = lastPeak.get();
|
||||||
@ -81,22 +81,22 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
container.putSupplier(ServerKeys.COMMAND_USAGE, () -> commandUseTable.getCommandUse(serverUUID));
|
container.putCachingSupplier(ServerKeys.COMMAND_USAGE, () -> commandUseTable.getCommandUse(serverUUID));
|
||||||
container.putSupplier(ServerKeys.WORLD_TIMES, () -> worldTimesTable.getWorldTimesOfServer(serverUUID));
|
container.putCachingSupplier(ServerKeys.WORLD_TIMES, () -> worldTimesTable.getWorldTimesOfServer(serverUUID));
|
||||||
|
|
||||||
// Calculating getters
|
// Calculating getters
|
||||||
container.putSupplier(ServerKeys.OPERATORS, () -> PlayersMutator.forContainer(container).operators());
|
container.putCachingSupplier(ServerKeys.OPERATORS, () -> PlayersMutator.forContainer(container).operators());
|
||||||
container.putSupplier(ServerKeys.SESSIONS, () -> {
|
container.putCachingSupplier(ServerKeys.SESSIONS, () -> {
|
||||||
List<Session> sessions = PlayersMutator.forContainer(container).getSessions();
|
List<Session> sessions = PlayersMutator.forContainer(container).getSessions();
|
||||||
if (serverUUID.equals(ServerInfo.getServerUUID())) {
|
if (serverUUID.equals(ServerInfo.getServerUUID())) {
|
||||||
sessions.addAll(SessionCache.getActiveSessions().values());
|
sessions.addAll(SessionCache.getActiveSessions().values());
|
||||||
}
|
}
|
||||||
return sessions;
|
return sessions;
|
||||||
});
|
});
|
||||||
container.putSupplier(ServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
container.putCachingSupplier(ServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
||||||
container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(ServerKeys.PLAYER_KILLS).size());
|
container.putCachingSupplier(ServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(ServerKeys.PLAYER_KILLS).size());
|
||||||
container.putSupplier(ServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
container.putCachingSupplier(ServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||||
container.putSupplier(ServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
container.putCachingSupplier(ServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
@ -129,13 +129,13 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
|
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
|
||||||
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
|
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
|
||||||
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
|
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
|
||||||
container.putSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
||||||
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
|
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
|
||||||
|
|
||||||
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
|
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
|
||||||
container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator());
|
container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator());
|
||||||
|
|
||||||
container.putSupplier(PlayerKeys.SESSIONS, () -> {
|
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
|
||||||
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
|
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
|
||||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
||||||
return playerSessions;
|
return playerSessions;
|
||||||
@ -143,7 +143,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Calculating getters
|
// Calculating getters
|
||||||
container.putSupplier(PlayerKeys.WORLD_TIMES, () -> {
|
container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () -> {
|
||||||
WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
|
WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
|
||||||
container.getValue(PlayerKeys.ACTIVE_SESSION)
|
container.getValue(PlayerKeys.ACTIVE_SESSION)
|
||||||
.ifPresent(session -> worldTimes.add(
|
.ifPresent(session -> worldTimes.add(
|
||||||
@ -187,10 +187,10 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
|
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
|
||||||
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
|
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
|
||||||
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
|
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
|
||||||
container.putSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
||||||
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
|
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
|
||||||
|
|
||||||
container.putSupplier(PlayerKeys.SESSIONS, () -> {
|
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
|
||||||
List<Session> playerSessions = PerServerMutator.forContainer(container).flatMapSessions();
|
List<Session> playerSessions = PerServerMutator.forContainer(container).flatMapSessions();
|
||||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
||||||
return playerSessions;
|
return playerSessions;
|
||||||
@ -285,21 +285,21 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
container.putRawData(PlayerKeys.UUID, uuid);
|
container.putRawData(PlayerKeys.UUID, uuid);
|
||||||
|
|
||||||
container.putAll(usersTable.getUserInformation(uuid));
|
container.putAll(usersTable.getUserInformation(uuid));
|
||||||
container.putSupplier(PlayerKeys.GEO_INFO, () -> geoInfoTable.getGeoInfo(uuid));
|
container.putCachingSupplier(PlayerKeys.GEO_INFO, () -> geoInfoTable.getGeoInfo(uuid));
|
||||||
container.putSupplier(PlayerKeys.PING, () -> pingTable.getPing(uuid));
|
container.putCachingSupplier(PlayerKeys.PING, () -> pingTable.getPing(uuid));
|
||||||
container.putSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
||||||
container.putSupplier(PlayerKeys.PER_SERVER, () -> getPerServerData(uuid));
|
container.putCachingSupplier(PlayerKeys.PER_SERVER, () -> getPerServerData(uuid));
|
||||||
|
|
||||||
container.putSupplier(PlayerKeys.BANNED, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isBanned());
|
container.putSupplier(PlayerKeys.BANNED, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isBanned());
|
||||||
container.putSupplier(PlayerKeys.OPERATOR, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isOperator());
|
container.putSupplier(PlayerKeys.OPERATOR, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isOperator());
|
||||||
|
|
||||||
container.putSupplier(PlayerKeys.SESSIONS, () -> {
|
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
|
||||||
List<Session> sessions = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapSessions();
|
List<Session> sessions = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapSessions();
|
||||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(sessions::add);
|
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(sessions::add);
|
||||||
return sessions;
|
return sessions;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
container.putSupplier(PlayerKeys.WORLD_TIMES, () ->
|
container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () ->
|
||||||
{
|
{
|
||||||
WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
|
WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
|
||||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(session -> worldTimes.add(
|
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(session -> worldTimes.add(
|
||||||
|
@ -4,6 +4,7 @@ import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
|||||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement;
|
import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement;
|
||||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement;
|
import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement;
|
||||||
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
|
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -29,13 +30,16 @@ public abstract class Patch {
|
|||||||
|
|
||||||
public boolean hasTable(String tableName) {
|
public boolean hasTable(String tableName) {
|
||||||
String sql = usingMySQL ?
|
String sql = usingMySQL ?
|
||||||
"SELECT * FROM information_schema.TABLES WHERE table_name=? LIMIT 1" :
|
"SELECT * FROM information_schema.TABLES WHERE table_name=? AND TABLE_SCHEMA=? LIMIT 1" :
|
||||||
"SELECT tbl_name FROM sqlite_master WHERE tbl_name=?";
|
"SELECT tbl_name FROM sqlite_master WHERE tbl_name=?";
|
||||||
|
|
||||||
return query(new QueryStatement<Boolean>(sql) {
|
return query(new QueryStatement<Boolean>(sql) {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
statement.setString(1, tableName);
|
statement.setString(1, tableName);
|
||||||
|
if (usingMySQL) {
|
||||||
|
statement.setString(2, Settings.DB_DATABASE.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,11 +52,12 @@ public abstract class Patch {
|
|||||||
protected boolean hasColumn(String tableName, String columnName) {
|
protected boolean hasColumn(String tableName, String columnName) {
|
||||||
return usingMySQL ?
|
return usingMySQL ?
|
||||||
query(new QueryStatement<Boolean>("SELECT * FROM information_schema.COLUMNS" +
|
query(new QueryStatement<Boolean>("SELECT * FROM information_schema.COLUMNS" +
|
||||||
" WHERE TABLE_NAME=? AND COLUMN_NAME=?") {
|
" WHERE TABLE_NAME=? AND COLUMN_NAME=? AND TABLE_SCHEMA=?") {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
statement.setString(1, tableName);
|
statement.setString(1, tableName);
|
||||||
statement.setString(2, columnName);
|
statement.setString(2, columnName);
|
||||||
|
statement.setString(3, Settings.DB_DATABASE.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,7 +10,7 @@ public class VersionTableRemovalPatch extends Patch {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBeenApplied() {
|
public boolean hasBeenApplied() {
|
||||||
return hasTable("plan_version");
|
return !hasTable("plan_version");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -151,9 +151,12 @@ public class TPSTable extends Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) {
|
public Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) {
|
||||||
|
String subStatement = "SELECT MAX(" + Col.PLAYERS_ONLINE + ") FROM " + tableName +
|
||||||
|
" WHERE " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID +
|
||||||
|
" AND " + Col.DATE + ">= ?";
|
||||||
String sql = Select.all(tableName)
|
String sql = Select.all(tableName)
|
||||||
.where(Col.SERVER_ID + "=" + serverTable.statementSelectServerID)
|
.where(Col.SERVER_ID + "=" + serverTable.statementSelectServerID)
|
||||||
.and(Col.PLAYERS_ONLINE + "= (SELECT MAX(" + Col.PLAYERS_ONLINE + ") FROM " + tableName + ")")
|
.and(Col.PLAYERS_ONLINE + "= (" + subStatement + ")")
|
||||||
.and(Col.DATE + ">= ?")
|
.and(Col.DATE + ">= ?")
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
@ -161,13 +164,14 @@ public class TPSTable extends Table {
|
|||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
statement.setString(1, serverUUID.toString());
|
statement.setString(1, serverUUID.toString());
|
||||||
statement.setLong(2, afterDate);
|
statement.setString(2, serverUUID.toString());
|
||||||
|
statement.setLong(3, afterDate);
|
||||||
|
statement.setLong(4, afterDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<TPS> processResults(ResultSet set) throws SQLException {
|
public Optional<TPS> processResults(ResultSet set) throws SQLException {
|
||||||
if (set.next()) {
|
if (set.next()) {
|
||||||
|
|
||||||
TPS tps = TPSBuilder.get()
|
TPS tps = TPSBuilder.get()
|
||||||
.date(set.getLong(Col.DATE.get()))
|
.date(set.getLong(Col.DATE.get()))
|
||||||
.tps(set.getDouble(Col.TPS.get()))
|
.tps(set.getDouble(Col.TPS.get()))
|
||||||
|
@ -41,7 +41,10 @@ public class AFKListener implements Listener {
|
|||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
|
||||||
boolean ignored = ignorePermissionInfo.getOrDefault(uuid, player.hasPermission(Permissions.IGNORE_AFK.getPermission()));
|
Boolean ignored = ignorePermissionInfo.get(uuid);
|
||||||
|
if (ignored == null) {
|
||||||
|
ignored = player.hasPermission(Permissions.IGNORE_AFK.getPermission());
|
||||||
|
}
|
||||||
if (ignored) {
|
if (ignored) {
|
||||||
AFK_TRACKER.hasIgnorePermission(uuid);
|
AFK_TRACKER.hasIgnorePermission(uuid);
|
||||||
ignorePermissionInfo.put(uuid, true);
|
ignorePermissionInfo.put(uuid, true);
|
||||||
|
@ -63,6 +63,10 @@ public class PlayerOnlineListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UUID uuid = event.getPlayer().getUniqueId();
|
UUID uuid = event.getPlayer().getUniqueId();
|
||||||
|
if (AFKListener.AFK_TRACKER.isAfk(uuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Processing.submit(new KickProcessor(uuid));
|
Processing.submit(new KickProcessor(uuid));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.toLog(this.getClass(), e);
|
Log.toLog(this.getClass(), e);
|
||||||
|
@ -2,6 +2,7 @@ package com.djrapitops.plan.system.listeners.sponge;
|
|||||||
|
|
||||||
import com.djrapitops.plan.data.container.Session;
|
import com.djrapitops.plan.data.container.Session;
|
||||||
import com.djrapitops.plan.system.cache.SessionCache;
|
import com.djrapitops.plan.system.cache.SessionCache;
|
||||||
|
import com.djrapitops.plan.system.listeners.bukkit.AFKListener;
|
||||||
import com.djrapitops.plan.system.processing.Processing;
|
import com.djrapitops.plan.system.processing.Processing;
|
||||||
import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor;
|
import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor;
|
||||||
import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor;
|
import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor;
|
||||||
@ -52,6 +53,9 @@ public class SpongePlayerListener {
|
|||||||
public void onKick(KickPlayerEvent event) {
|
public void onKick(KickPlayerEvent event) {
|
||||||
try {
|
try {
|
||||||
UUID uuid = event.getTargetEntity().getUniqueId();
|
UUID uuid = event.getTargetEntity().getUniqueId();
|
||||||
|
if (AFKListener.AFK_TRACKER.isAfk(uuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Processing.submit(new KickProcessor(uuid));
|
Processing.submit(new KickProcessor(uuid));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.toLog(this.getClass(), e);
|
Log.toLog(this.getClass(), e);
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
package com.djrapitops.plan.system.locale;
|
package com.djrapitops.plan.system.locale;
|
||||||
|
|
||||||
import com.djrapitops.plan.PlanPlugin;
|
import com.djrapitops.plan.PlanPlugin;
|
||||||
import com.djrapitops.plan.system.locale.lang.Lang;
|
import com.djrapitops.plan.system.locale.lang.*;
|
||||||
import com.djrapitops.plan.system.settings.Settings;
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,10 +73,22 @@ public class Locale extends HashMap<Lang, Message> {
|
|||||||
|
|
||||||
String replaced = from;
|
String replaced = from;
|
||||||
|
|
||||||
// Longest first so that entries that contain each other don't partially replace.
|
Lang[][] langs = new Lang[][]{
|
||||||
List<Entry<Lang, Message>> entries = entrySet().stream().sorted(
|
NetworkPageLang.values(),
|
||||||
(one, two) -> Integer.compare(two.getKey().getIdentifier().length(), one.getKey().getIdentifier().length())
|
PlayerPageLang.values(),
|
||||||
).collect(Collectors.toList());
|
ServerPageLang.values(),
|
||||||
|
CommonHtmlLang.values()
|
||||||
|
};
|
||||||
|
|
||||||
|
List<Entry<Lang, Message>> entries = Arrays.stream(langs)
|
||||||
|
.flatMap(Arrays::stream)
|
||||||
|
.collect(Collectors.toMap(Function.identity(), this::get))
|
||||||
|
.entrySet().stream()
|
||||||
|
// Longest first so that entries that contain each other don't partially replace.
|
||||||
|
.sorted((one, two) -> Integer.compare(
|
||||||
|
two.getKey().getIdentifier().length(),
|
||||||
|
one.getKey().getIdentifier().length()
|
||||||
|
)).collect(Collectors.toList());
|
||||||
|
|
||||||
for (Entry<Lang, Message> entry : entries) {
|
for (Entry<Lang, Message> entry : entries) {
|
||||||
String defaultValue = entry.getKey().getDefault();
|
String defaultValue = entry.getKey().getDefault();
|
||||||
|
@ -9,6 +9,7 @@ import com.djrapitops.plan.system.locale.lang.PluginLang;
|
|||||||
import com.djrapitops.plugin.StaticHolder;
|
import com.djrapitops.plugin.StaticHolder;
|
||||||
import com.djrapitops.plugin.api.utility.log.Log;
|
import com.djrapitops.plugin.api.utility.log.Log;
|
||||||
import com.djrapitops.plugin.utilities.Verify;
|
import com.djrapitops.plugin.utilities.Verify;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
@ -23,8 +24,8 @@ public class Processing implements SubSystem {
|
|||||||
|
|
||||||
public Processing(Supplier<Locale> locale) {
|
public Processing(Supplier<Locale> locale) {
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
nonCriticalExecutor = Executors.newFixedThreadPool(6);
|
nonCriticalExecutor = Executors.newFixedThreadPool(6, new ThreadFactoryBuilder().setNameFormat("Plan Non critical-pool-%d").build());
|
||||||
criticalExecutor = Executors.newFixedThreadPool(2);
|
criticalExecutor = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder().setNameFormat("Plan Critical-pool-%d").build());
|
||||||
saveInstance(nonCriticalExecutor);
|
saveInstance(nonCriticalExecutor);
|
||||||
saveInstance(criticalExecutor);
|
saveInstance(criticalExecutor);
|
||||||
saveInstance(this);
|
saveInstance(this);
|
||||||
|
@ -276,4 +276,28 @@ public class UserImportData {
|
|||||||
return new UserImportData(name, uuid, nicknames, registered, op, banned, timesKicked, ips, worldTimes, kills, mobKills, deaths);
|
return new UserImportData(name, uuid, nicknames, registered, op, banned, timesKicked, ips, worldTimes, kills, mobKills, deaths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof UserImportData)) return false;
|
||||||
|
UserImportData that = (UserImportData) o;
|
||||||
|
return registered == that.registered &&
|
||||||
|
op == that.op &&
|
||||||
|
banned == that.banned &&
|
||||||
|
timesKicked == that.timesKicked &&
|
||||||
|
mobKills == that.mobKills &&
|
||||||
|
deaths == that.deaths &&
|
||||||
|
Objects.equals(name, that.name) &&
|
||||||
|
Objects.equals(uuid, that.uuid) &&
|
||||||
|
Objects.equals(nicknames, that.nicknames) &&
|
||||||
|
Objects.equals(ips, that.ips) &&
|
||||||
|
Objects.equals(worldTimes, that.worldTimes) &&
|
||||||
|
Objects.equals(kills, that.kills);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, uuid, nicknames, registered, op, banned, timesKicked, ips, worldTimes, kills, mobKills, deaths);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
package com.djrapitops.plan.system.processing.processors.info;
|
package com.djrapitops.plan.system.processing.processors.info;
|
||||||
|
|
||||||
import com.djrapitops.plan.system.info.InfoSystem;
|
import com.djrapitops.plan.system.webserver.cache.PageId;
|
||||||
import com.djrapitops.plan.system.info.connection.WebExceptionLogger;
|
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
||||||
import com.djrapitops.plugin.api.Check;
|
|
||||||
import com.djrapitops.plugin.api.TimeAmount;
|
|
||||||
import com.djrapitops.plugin.task.AbsRunnable;
|
|
||||||
import com.djrapitops.plugin.task.RunnableFactory;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -19,20 +15,6 @@ public class PlayerPageUpdateProcessor implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!InfoSystem.getInstance().getConnectionSystem().isServerAvailable() || Check.isBungeeAvailable()) {
|
ResponseCache.clearResponse(PageId.PLAYER.of(uuid));
|
||||||
RunnableFactory.createNew("Generate Inspect page: " + uuid, new AbsRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
WebExceptionLogger.logIfOccurs(PlayerPageUpdateProcessor.class,
|
|
||||||
() -> InfoSystem.getInstance().generateAndCachePlayerPage(uuid)
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ public enum Permissions {
|
|||||||
|
|
||||||
HELP("plan.?"),
|
HELP("plan.?"),
|
||||||
|
|
||||||
INSPECT("plan.inspect"),
|
INSPECT("plan.inspect.base"),
|
||||||
QUICK_INSPECT("plan.qinspect"),
|
QUICK_INSPECT("plan.qinspect.base"),
|
||||||
INSPECT_OTHER("plan.inspect.other"),
|
INSPECT_OTHER("plan.inspect.other"),
|
||||||
QUICK_INSPECT_OTHER("plan.qinspect.other"),
|
QUICK_INSPECT_OTHER("plan.qinspect.other"),
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ public enum Permissions {
|
|||||||
/**
|
/**
|
||||||
* Returns the permission node in plugin.yml.
|
* Returns the permission node in plugin.yml.
|
||||||
*
|
*
|
||||||
* @return permission node eg. plan.inspect
|
* @return permission node eg. plan.inspect.base
|
||||||
*/
|
*/
|
||||||
public String getPermission() {
|
public String getPermission() {
|
||||||
return permission;
|
return permission;
|
||||||
@ -45,7 +45,7 @@ public enum Permissions {
|
|||||||
/**
|
/**
|
||||||
* Same as {@link #getPermission()}.
|
* Same as {@link #getPermission()}.
|
||||||
*
|
*
|
||||||
* @return permission node eg. plan.inspect
|
* @return permission node eg. plan.inspect.base
|
||||||
*/
|
*/
|
||||||
public String getPerm() {
|
public String getPerm() {
|
||||||
return getPermission();
|
return getPermission();
|
||||||
|
@ -8,7 +8,7 @@ import com.djrapitops.plan.Plan;
|
|||||||
import com.djrapitops.plan.system.settings.Settings;
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
import com.djrapitops.plan.system.tasks.server.BukkitTPSCountTimer;
|
import com.djrapitops.plan.system.tasks.server.BukkitTPSCountTimer;
|
||||||
import com.djrapitops.plan.system.tasks.server.PaperTPSCountTimer;
|
import com.djrapitops.plan.system.tasks.server.PaperTPSCountTimer;
|
||||||
import com.djrapitops.plan.system.tasks.server.PingCountTimer;
|
import com.djrapitops.plan.system.tasks.server.PingCountTimerBukkit;
|
||||||
import com.djrapitops.plugin.api.Check;
|
import com.djrapitops.plugin.api.Check;
|
||||||
import com.djrapitops.plugin.api.TimeAmount;
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
import com.djrapitops.plugin.task.RunnableFactory;
|
import com.djrapitops.plugin.task.RunnableFactory;
|
||||||
@ -33,11 +33,11 @@ public class BukkitTaskSystem extends ServerTaskSystem {
|
|||||||
public void enable() {
|
public void enable() {
|
||||||
super.enable();
|
super.enable();
|
||||||
try {
|
try {
|
||||||
PingCountTimer pingCountTimer = new PingCountTimer();
|
PingCountTimerBukkit pingCountTimer = new PingCountTimerBukkit();
|
||||||
((Plan) plugin).registerListener(pingCountTimer);
|
((Plan) plugin).registerListener(pingCountTimer);
|
||||||
long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber();
|
long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber();
|
||||||
RunnableFactory.createNew("PingCountTimer", pingCountTimer)
|
RunnableFactory.createNew("PingCountTimer", pingCountTimer)
|
||||||
.runTaskTimer(startDelay, PingCountTimer.PING_INTERVAL);
|
.runTaskTimer(startDelay, PingCountTimerBukkit.PING_INTERVAL);
|
||||||
} catch (ExceptionInInitializerError | NoClassDefFoundError ignore) {
|
} catch (ExceptionInInitializerError | NoClassDefFoundError ignore) {
|
||||||
// Running CraftBukkit
|
// Running CraftBukkit
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@ import com.djrapitops.plan.system.settings.Settings;
|
|||||||
import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer;
|
import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer;
|
||||||
import com.djrapitops.plan.system.tasks.bungee.EnableConnectionTask;
|
import com.djrapitops.plan.system.tasks.bungee.EnableConnectionTask;
|
||||||
import com.djrapitops.plan.system.tasks.server.NetworkPageRefreshTask;
|
import com.djrapitops.plan.system.tasks.server.NetworkPageRefreshTask;
|
||||||
|
import com.djrapitops.plan.system.tasks.server.PingCountTimerBungee;
|
||||||
import com.djrapitops.plan.utilities.file.export.HtmlExport;
|
import com.djrapitops.plan.utilities.file.export.HtmlExport;
|
||||||
import com.djrapitops.plugin.api.TimeAmount;
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import com.djrapitops.plugin.task.RunnableFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TaskSystem responsible for registering tasks for Bungee.
|
* TaskSystem responsible for registering tasks for Bungee.
|
||||||
@ -38,5 +40,10 @@ public class BungeeTaskSystem extends TaskSystem {
|
|||||||
if (Settings.ANALYSIS_EXPORT.isTrue()) {
|
if (Settings.ANALYSIS_EXPORT.isTrue()) {
|
||||||
registerTask(new HtmlExport(plugin)).runTaskAsynchronously();
|
registerTask(new HtmlExport(plugin)).runTaskAsynchronously();
|
||||||
}
|
}
|
||||||
|
PingCountTimerBungee pingCountTimer = new PingCountTimerBungee();
|
||||||
|
plugin.registerListener(pingCountTimer);
|
||||||
|
long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber();
|
||||||
|
RunnableFactory.createNew("PingCountTimer", pingCountTimer)
|
||||||
|
.runTaskTimer(startDelay, PingCountTimerBungee.PING_INTERVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,11 @@ public class LogsFolderCleanTask extends AbsRunnable {
|
|||||||
} catch (NullPointerException ignore) {
|
} catch (NullPointerException ignore) {
|
||||||
/* Ignored - not supposed to occur. */
|
/* Ignored - not supposed to occur. */
|
||||||
} finally {
|
} finally {
|
||||||
cancel();
|
try {
|
||||||
|
cancel();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
/* Ignored, TaskCenter concurrent modification exception, will be fixed later in apf-3.3.0. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,37 @@
|
|||||||
package com.djrapitops.plan.system.tasks;
|
package com.djrapitops.plan.system.tasks;
|
||||||
|
|
||||||
import com.djrapitops.plan.PlanSponge;
|
import com.djrapitops.plan.PlanSponge;
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
import com.djrapitops.plan.system.tasks.server.PingCountTimerSponge;
|
||||||
import com.djrapitops.plan.system.tasks.server.SpongeTPSCountTimer;
|
import com.djrapitops.plan.system.tasks.server.SpongeTPSCountTimer;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import com.djrapitops.plugin.task.RunnableFactory;
|
||||||
import org.spongepowered.api.Sponge;
|
import org.spongepowered.api.Sponge;
|
||||||
import org.spongepowered.api.scheduler.Task;
|
import org.spongepowered.api.scheduler.Task;
|
||||||
|
|
||||||
public class SpongeTaskSystem extends ServerTaskSystem {
|
public class SpongeTaskSystem extends ServerTaskSystem {
|
||||||
|
|
||||||
|
private final PlanSponge planSponge;
|
||||||
|
|
||||||
public SpongeTaskSystem(PlanSponge plugin) {
|
public SpongeTaskSystem(PlanSponge plugin) {
|
||||||
super(plugin, new SpongeTPSCountTimer(plugin));
|
super(plugin, new SpongeTPSCountTimer(plugin));
|
||||||
|
this.planSponge = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
super.enable();
|
||||||
|
PingCountTimerSponge pingCountTimer = new PingCountTimerSponge();
|
||||||
|
planSponge.registerListener(pingCountTimer);
|
||||||
|
long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber();
|
||||||
|
RunnableFactory.createNew("PingCountTimer", pingCountTimer)
|
||||||
|
.runTaskTimer(startDelay, PingCountTimerSponge.PING_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
super.disable();
|
super.disable();
|
||||||
for (Task task : Sponge.getScheduler().getScheduledTasks(plugin)) {
|
for (Task task : Sponge.getScheduler().getScheduledTasks(planSponge)) {
|
||||||
task.cancel();
|
task.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,23 +53,23 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* @author games647
|
* @author games647
|
||||||
*/
|
*/
|
||||||
public class PingCountTimer extends AbsRunnable implements Listener {
|
public class PingCountTimerBukkit extends AbsRunnable implements Listener {
|
||||||
|
|
||||||
//the server is pinging the client every 40 Ticks (2 sec) - so check it then
|
//the server is pinging the client every 40 Ticks (2 sec) - so check it then
|
||||||
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
||||||
public static final int PING_INTERVAL = 2 * 20;
|
public static final int PING_INTERVAL = 2 * 20;
|
||||||
|
|
||||||
private static final boolean pingMethodAvailable;
|
private static final boolean PING_METHOD_AVAILABLE;
|
||||||
|
|
||||||
private static final MethodHandle pingField;
|
private static final MethodHandle PING_FIELD;
|
||||||
private static final MethodHandle getHandleMethod;
|
private static final MethodHandle GET_HANDLE_METHOD;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
pingMethodAvailable = isPingMethodAvailable();
|
PING_METHOD_AVAILABLE = isPingMethodAvailable();
|
||||||
|
|
||||||
MethodHandle localHandle = null;
|
MethodHandle localHandle = null;
|
||||||
MethodHandle localPing = null;
|
MethodHandle localPing = null;
|
||||||
if (!pingMethodAvailable) {
|
if (!PING_METHOD_AVAILABLE) {
|
||||||
Class<?> craftPlayerClass = Reflection.getCraftBukkitClass("entity.CraftPlayer");
|
Class<?> craftPlayerClass = Reflection.getCraftBukkitClass("entity.CraftPlayer");
|
||||||
Class<?> entityPlayer = Reflection.getMinecraftClass("EntityPlayer");
|
Class<?> entityPlayer = Reflection.getMinecraftClass("EntityPlayer");
|
||||||
|
|
||||||
@ -80,12 +80,12 @@ public class PingCountTimer extends AbsRunnable implements Listener {
|
|||||||
|
|
||||||
localPing = lookup.findGetter(entityPlayer, "ping", Integer.TYPE);
|
localPing = lookup.findGetter(entityPlayer, "ping", Integer.TYPE);
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException reflectiveEx) {
|
} catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException reflectiveEx) {
|
||||||
Log.toLog(PingCountTimer.class, reflectiveEx);
|
Log.toLog(PingCountTimerBukkit.class, reflectiveEx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getHandleMethod = localHandle;
|
GET_HANDLE_METHOD = localHandle;
|
||||||
pingField = localPing;
|
PING_FIELD = localPing;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory = new HashMap<>();
|
private final Map<UUID, List<DateObj<Integer>>> playerHistory = new HashMap<>();
|
||||||
@ -133,7 +133,7 @@ public class PingCountTimer extends AbsRunnable implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getPing(Player player) {
|
private int getPing(Player player) {
|
||||||
if (pingMethodAvailable) {
|
if (PING_METHOD_AVAILABLE) {
|
||||||
return player.spigot().getPing();
|
return player.spigot().getPing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +142,8 @@ public class PingCountTimer extends AbsRunnable implements Listener {
|
|||||||
|
|
||||||
private int getReflectionPing(Player player) {
|
private int getReflectionPing(Player player) {
|
||||||
try {
|
try {
|
||||||
Object entityPlayer = getHandleMethod.invoke(player);
|
Object entityPlayer = GET_HANDLE_METHOD.invoke(player);
|
||||||
return (int) pingField.invoke(entityPlayer);
|
return (int) PING_FIELD.invoke(entityPlayer);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return -1;
|
return -1;
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2018
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.djrapitops.plan.system.tasks.server;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.store.objects.DateObj;
|
||||||
|
import com.djrapitops.plan.system.processing.Processing;
|
||||||
|
import com.djrapitops.plan.system.processing.processors.player.PingInsertProcessor;
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import com.djrapitops.plugin.task.AbsRunnable;
|
||||||
|
import com.djrapitops.plugin.task.RunnableFactory;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||||
|
import net.md_5.bungee.api.event.ServerDisconnectEvent;
|
||||||
|
import net.md_5.bungee.api.plugin.Listener;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task that handles player ping calculation on Bungee based servers.
|
||||||
|
*
|
||||||
|
* @author BrainStone
|
||||||
|
*/
|
||||||
|
public class PingCountTimerBungee extends AbsRunnable implements Listener {
|
||||||
|
|
||||||
|
//the server is pinging the client every 40 Ticks (2 sec) - so check it then
|
||||||
|
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
||||||
|
public static final int PING_INTERVAL = 2 * 20;
|
||||||
|
|
||||||
|
private final Map<UUID, List<DateObj<Integer>>> playerHistory = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
List<UUID> loggedOut = new ArrayList<>();
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
playerHistory.forEach((uuid, history) -> {
|
||||||
|
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
|
||||||
|
if (player != null) {
|
||||||
|
int ping = getPing(player);
|
||||||
|
if (ping < -1 || ping > TimeAmount.SECOND.ms() * 8L) {
|
||||||
|
// Don't accept bad values
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
history.add(new DateObj<>(time, ping));
|
||||||
|
if (history.size() >= 30) {
|
||||||
|
Processing.submit(new PingInsertProcessor(uuid, new ArrayList<>(history)));
|
||||||
|
history.clear();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loggedOut.add(uuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loggedOut.forEach(playerHistory::remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayer(ProxiedPlayer player) {
|
||||||
|
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayer(ProxiedPlayer player) {
|
||||||
|
playerHistory.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPing(ProxiedPlayer player) {
|
||||||
|
return player.getPing();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(ServerConnectedEvent joinEvent) {
|
||||||
|
ProxiedPlayer player = joinEvent.getPlayer();
|
||||||
|
RunnableFactory.createNew("Add Player to Ping list", new AbsRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (player.isConnected()) {
|
||||||
|
addPlayer(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerQuit(ServerDisconnectEvent quitEvent) {
|
||||||
|
removePlayer(quitEvent.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
playerHistory.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2018
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.djrapitops.plan.system.tasks.server;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.store.objects.DateObj;
|
||||||
|
import com.djrapitops.plan.system.processing.Processing;
|
||||||
|
import com.djrapitops.plan.system.processing.processors.player.PingInsertProcessor;
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import com.djrapitops.plugin.task.AbsRunnable;
|
||||||
|
import com.djrapitops.plugin.task.RunnableFactory;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
|
import org.spongepowered.api.event.Listener;
|
||||||
|
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task that handles player ping calculation on Sponge based servers.
|
||||||
|
*
|
||||||
|
* @author BrainStone
|
||||||
|
*/
|
||||||
|
public class PingCountTimerSponge extends AbsRunnable {
|
||||||
|
|
||||||
|
//the server is pinging the client every 40 Ticks (2 sec) - so check it then
|
||||||
|
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
||||||
|
public static final int PING_INTERVAL = 2 * 20;
|
||||||
|
|
||||||
|
private final Map<UUID, List<DateObj<Integer>>> playerHistory = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
List<UUID> loggedOut = new ArrayList<>();
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
playerHistory.forEach((uuid, history) -> {
|
||||||
|
Optional<Player> player = Sponge.getServer().getPlayer(uuid);
|
||||||
|
if (player.isPresent()) {
|
||||||
|
int ping = getPing(player.get());
|
||||||
|
if (ping < -1 || ping > TimeAmount.SECOND.ms() * 8L) {
|
||||||
|
// Don't accept bad values
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
history.add(new DateObj<>(time, ping));
|
||||||
|
if (history.size() >= 30) {
|
||||||
|
Processing.submit(new PingInsertProcessor(uuid, new ArrayList<>(history)));
|
||||||
|
history.clear();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loggedOut.add(uuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loggedOut.forEach(playerHistory::remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayer(Player player) {
|
||||||
|
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayer(Player player) {
|
||||||
|
playerHistory.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPing(Player player) {
|
||||||
|
return player.getConnection().getLatency();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Listener
|
||||||
|
public void onPlayerJoin(ClientConnectionEvent.Join joinEvent) {
|
||||||
|
Player player = joinEvent.getTargetEntity();
|
||||||
|
RunnableFactory.createNew("Add Player to Ping list", new AbsRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (player.isOnline()) {
|
||||||
|
addPlayer(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Listener
|
||||||
|
public void onPlayerQuit(ClientConnectionEvent.Disconnect quitEvent) {
|
||||||
|
removePlayer(quitEvent.getTargetEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
playerHistory.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import com.djrapitops.plugin.StaticHolder;
|
|||||||
import com.djrapitops.plugin.api.Check;
|
import com.djrapitops.plugin.api.Check;
|
||||||
import com.djrapitops.plugin.api.utility.log.Log;
|
import com.djrapitops.plugin.api.utility.log.Log;
|
||||||
import com.djrapitops.plugin.utilities.Verify;
|
import com.djrapitops.plugin.utilities.Verify;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.sun.net.httpserver.HttpServer;
|
import com.sun.net.httpserver.HttpServer;
|
||||||
import com.sun.net.httpserver.HttpsConfigurator;
|
import com.sun.net.httpserver.HttpsConfigurator;
|
||||||
import com.sun.net.httpserver.HttpsParameters;
|
import com.sun.net.httpserver.HttpsParameters;
|
||||||
@ -27,9 +28,7 @@ import java.nio.file.Paths;
|
|||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +107,11 @@ public class WebServer implements SubSystem {
|
|||||||
}
|
}
|
||||||
server.createContext("/", requestHandler);
|
server.createContext("/", requestHandler);
|
||||||
|
|
||||||
server.setExecutor(new ThreadPoolExecutor(4, 8, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100)));
|
ExecutorService executor = new ThreadPoolExecutor(
|
||||||
|
4, 8, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100),
|
||||||
|
new ThreadFactoryBuilder().setNameFormat("Plan WebServer Thread-%d").build()
|
||||||
|
);
|
||||||
|
server.setExecutor(executor);
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
enabled = true;
|
enabled = true;
|
||||||
@ -199,12 +202,26 @@ public class WebServer implements SubSystem {
|
|||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
|
shutdown();
|
||||||
Log.info(locale.get().getString(PluginLang.DISABLED_WEB_SERVER));
|
Log.info(locale.get().getString(PluginLang.DISABLED_WEB_SERVER));
|
||||||
server.stop(0);
|
|
||||||
}
|
}
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void shutdown() {
|
||||||
|
server.stop(0);
|
||||||
|
Executor executor = server.getExecutor();
|
||||||
|
if (executor instanceof ExecutorService) {
|
||||||
|
ExecutorService service = (ExecutorService) executor;
|
||||||
|
service.shutdown();
|
||||||
|
try {
|
||||||
|
service.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException timeoutExceededEx) {
|
||||||
|
service.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getProtocol() {
|
public String getProtocol() {
|
||||||
return usingHttps ? "https" : "http";
|
return usingHttps ? "https" : "http";
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package com.djrapitops.plan.system.webserver.cache;
|
package com.djrapitops.plan.system.webserver.cache;
|
||||||
|
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
import com.djrapitops.plan.system.webserver.response.Response;
|
||||||
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,7 +20,9 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
public class ResponseCache {
|
public class ResponseCache {
|
||||||
|
|
||||||
private static final Map<String, Response> cache = new HashMap<>();
|
private static final Cache<String, Response> cache = Caffeine.newBuilder()
|
||||||
|
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used to hide the public constructor
|
* Constructor used to hide the public constructor
|
||||||
@ -41,17 +44,7 @@ public class ResponseCache {
|
|||||||
* @return The Response that was cached or created by the the {@link Response} {@link Supplier}
|
* @return The Response that was cached or created by the the {@link Response} {@link Supplier}
|
||||||
*/
|
*/
|
||||||
public static Response loadResponse(String identifier, Supplier<Response> loader) {
|
public static Response loadResponse(String identifier, Supplier<Response> loader) {
|
||||||
Response response = loadResponse(identifier);
|
return cache.get(identifier, k -> loader.get());
|
||||||
|
|
||||||
if (response != null) {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = loader.get();
|
|
||||||
|
|
||||||
cache.put(identifier, response);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,7 +54,7 @@ public class ResponseCache {
|
|||||||
* @return The Response that was cached or {@code null} if it wasn't
|
* @return The Response that was cached or {@code null} if it wasn't
|
||||||
*/
|
*/
|
||||||
public static Response loadResponse(String identifier) {
|
public static Response loadResponse(String identifier) {
|
||||||
return cache.get(identifier);
|
return cache.getIfPresent(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,21 +77,25 @@ public class ResponseCache {
|
|||||||
* @return true if the page is cached
|
* @return true if the page is cached
|
||||||
*/
|
*/
|
||||||
public static boolean isCached(String identifier) {
|
public static boolean isCached(String identifier) {
|
||||||
return cache.containsKey(identifier);
|
return cache.getIfPresent(identifier) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the cache from all its contents.
|
* Clears the cache from all its contents.
|
||||||
*/
|
*/
|
||||||
public static void clearCache() {
|
public static void clearCache() {
|
||||||
cache.clear();
|
cache.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<String> getCacheKeys() {
|
public static Set<String> getCacheKeys() {
|
||||||
return cache.keySet();
|
return cache.asMap().keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getEstimatedSize() {
|
||||||
|
return cache.estimatedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearResponse(String identifier) {
|
public static void clearResponse(String identifier) {
|
||||||
cache.remove(identifier);
|
cache.invalidate(identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,10 @@ public abstract class Response {
|
|||||||
? getContent()
|
? getContent()
|
||||||
: locale.replaceMatchingLanguage(getContent());
|
: locale.replaceMatchingLanguage(getContent());
|
||||||
|
|
||||||
try (GZIPOutputStream out = new GZIPOutputStream(exchange.getResponseBody());
|
try (
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(sentContent.getBytes(StandardCharsets.UTF_8))) {
|
GZIPOutputStream out = new GZIPOutputStream(exchange.getResponseBody());
|
||||||
|
ByteArrayInputStream bis = new ByteArrayInputStream(sentContent.getBytes(StandardCharsets.UTF_8))
|
||||||
|
) {
|
||||||
byte[] buffer = new byte[2048];
|
byte[] buffer = new byte[2048];
|
||||||
int count;
|
int count;
|
||||||
while ((count = bis.read(buffer)) != -1) {
|
while ((count = bis.read(buffer)) != -1) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
package com.djrapitops.plan.system.webserver.response.errors;
|
package com.djrapitops.plan.system.webserver.response.errors;
|
||||||
|
|
||||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
import com.djrapitops.plan.system.webserver.response.pages.PageResponse;
|
||||||
import com.djrapitops.plan.utilities.MiscUtils;
|
import com.djrapitops.plan.utilities.MiscUtils;
|
||||||
import com.djrapitops.plan.utilities.file.FileUtil;
|
import com.djrapitops.plan.utilities.file.FileUtil;
|
||||||
import com.djrapitops.plugin.api.utility.log.Log;
|
import com.djrapitops.plugin.api.utility.log.Log;
|
||||||
@ -20,7 +20,7 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class ErrorResponse extends Response {
|
public class ErrorResponse extends PageResponse {
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
private String paragraph;
|
private String paragraph;
|
||||||
|
@ -7,7 +7,6 @@ import com.djrapitops.plan.system.info.InfoSystem;
|
|||||||
import com.djrapitops.plan.system.processing.Processing;
|
import com.djrapitops.plan.system.processing.Processing;
|
||||||
import com.djrapitops.plan.system.webserver.cache.PageId;
|
import com.djrapitops.plan.system.webserver.cache.PageId;
|
||||||
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
|
||||||
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
|
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
|
||||||
import com.djrapitops.plan.utilities.html.pages.AnalysisPage;
|
import com.djrapitops.plan.utilities.html.pages.AnalysisPage;
|
||||||
import com.djrapitops.plugin.api.utility.log.Log;
|
import com.djrapitops.plugin.api.utility.log.Log;
|
||||||
@ -18,7 +17,7 @@ import java.util.UUID;
|
|||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class AnalysisPageResponse extends Response {
|
public class AnalysisPageResponse extends PageResponse {
|
||||||
|
|
||||||
public static AnalysisPageResponse refreshNow(UUID serverUUID) {
|
public static AnalysisPageResponse refreshNow(UUID serverUUID) {
|
||||||
Processing.submitNonCritical(() -> {
|
Processing.submitNonCritical(() -> {
|
||||||
|
@ -3,20 +3,20 @@ package com.djrapitops.plan.system.webserver.response.pages;
|
|||||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||||
import com.djrapitops.plan.system.webserver.cache.PageId;
|
import com.djrapitops.plan.system.webserver.cache.PageId;
|
||||||
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
|
||||||
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
|
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
|
||||||
import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent;
|
import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent;
|
||||||
import org.apache.commons.text.StringSubstitutor;
|
import org.apache.commons.text.StringSubstitutor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class InspectPageResponse extends Response {
|
public class InspectPageResponse extends PageResponse {
|
||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
|
|
||||||
@ -49,4 +49,18 @@ public class InspectPageResponse extends Response {
|
|||||||
refreshPage.replacePlaceholders();
|
refreshPage.replacePlaceholders();
|
||||||
return new InspectPageResponse(null, refreshPage.getContent());
|
return new InspectPageResponse(null, refreshPage.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof InspectPageResponse)) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
InspectPageResponse that = (InspectPageResponse) o;
|
||||||
|
return Objects.equals(uuid, that.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package com.djrapitops.plan.system.webserver.response.pages;
|
|||||||
import com.djrapitops.plan.api.exceptions.ParseException;
|
import com.djrapitops.plan.api.exceptions.ParseException;
|
||||||
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
import com.djrapitops.plan.system.database.databases.Database;
|
import com.djrapitops.plan.system.database.databases.Database;
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
|
||||||
import com.djrapitops.plan.utilities.html.pages.NetworkPage;
|
import com.djrapitops.plan.utilities.html.pages.NetworkPage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,7 +10,7 @@ import com.djrapitops.plan.utilities.html.pages.NetworkPage;
|
|||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class NetworkPageResponse extends Response {
|
public class NetworkPageResponse extends PageResponse {
|
||||||
|
|
||||||
public NetworkPageResponse() throws ParseException {
|
public NetworkPageResponse() throws ParseException {
|
||||||
super.setHeader("HTTP/1.1 200 OK");
|
super.setHeader("HTTP/1.1 200 OK");
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.djrapitops.plan.system.webserver.response.pages;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.system.webserver.response.Response;
|
||||||
|
import com.djrapitops.plan.system.webserver.response.ResponseType;
|
||||||
|
import com.googlecode.htmlcompressor.compressor.HtmlCompressor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response for all HTML Page responses.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class PageResponse extends Response {
|
||||||
|
|
||||||
|
public PageResponse(ResponseType type) {
|
||||||
|
super(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContent(String content) {
|
||||||
|
HtmlCompressor compressor = new HtmlCompressor();
|
||||||
|
compressor.setRemoveIntertagSpaces(true);
|
||||||
|
super.setContent(compressor.compress(content));
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package com.djrapitops.plan.system.webserver.response.pages;
|
package com.djrapitops.plan.system.webserver.response.pages;
|
||||||
|
|
||||||
import com.djrapitops.plan.api.exceptions.ParseException;
|
import com.djrapitops.plan.api.exceptions.ParseException;
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
|
||||||
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
|
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
|
||||||
import com.djrapitops.plan.utilities.html.pages.PlayersPage;
|
import com.djrapitops.plan.utilities.html.pages.PlayersPage;
|
||||||
import com.djrapitops.plugin.api.utility.log.Log;
|
import com.djrapitops.plugin.api.utility.log.Log;
|
||||||
@ -10,7 +9,7 @@ import com.djrapitops.plugin.api.utility.log.Log;
|
|||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.2
|
* @since 3.5.2
|
||||||
*/
|
*/
|
||||||
public class PlayersPageResponse extends Response {
|
public class PlayersPageResponse extends PageResponse {
|
||||||
|
|
||||||
public PlayersPageResponse() {
|
public PlayersPageResponse() {
|
||||||
super.setHeader("HTTP/1.1 200 OK");
|
super.setHeader("HTTP/1.1 200 OK");
|
||||||
|
@ -8,7 +8,7 @@ import com.djrapitops.plan.data.element.InspectContainer;
|
|||||||
import com.djrapitops.plan.data.plugin.HookHandler;
|
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||||
import com.djrapitops.plan.data.plugin.PluginData;
|
import com.djrapitops.plan.data.plugin.PluginData;
|
||||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
import com.djrapitops.plan.system.webserver.response.pages.PageResponse;
|
||||||
import com.djrapitops.plan.utilities.comparators.PluginDataNameComparator;
|
import com.djrapitops.plan.utilities.comparators.PluginDataNameComparator;
|
||||||
import com.djrapitops.plan.utilities.html.Html;
|
import com.djrapitops.plan.utilities.html.Html;
|
||||||
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||||
@ -23,7 +23,7 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class InspectPagePluginsContent extends Response {
|
public class InspectPagePluginsContent extends PageResponse {
|
||||||
|
|
||||||
// ServerUUID, {nav, html}
|
// ServerUUID, {nav, html}
|
||||||
private final Map<UUID, String[]> pluginsTab;
|
private final Map<UUID, String[]> pluginsTab;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.system.webserver.response.pages.parts;
|
package com.djrapitops.plan.system.webserver.response.pages.parts;
|
||||||
|
|
||||||
import com.djrapitops.plan.system.webserver.response.Response;
|
import com.djrapitops.plan.system.webserver.response.pages.PageResponse;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class NetworkPageContent extends Response {
|
public class NetworkPageContent extends PageResponse {
|
||||||
|
|
||||||
private final Map<String, String> content;
|
private final Map<String, String> content;
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@ public class AnalysisPluginsTabContentCreator {
|
|||||||
Log.toLog(AnalysisPluginsTabContentCreator.class, e);
|
Log.toLog(AnalysisPluginsTabContentCreator.class, e);
|
||||||
} finally {
|
} finally {
|
||||||
Benchmark.stop("Analysis", "Analysis: Source " + source.getSourcePlugin());
|
Benchmark.stop("Analysis", "Analysis: Source " + source.getSourcePlugin());
|
||||||
|
source.setAnalysisData(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return containers;
|
return containers;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
name: Plan
|
name: Plan
|
||||||
author: Rsl1122
|
author: Rsl1122
|
||||||
main: com.djrapitops.plan.PlanBungee
|
main: com.djrapitops.plan.PlanBungee
|
||||||
version: 4.4.5
|
version: 4.4.6
|
@ -17,10 +17,10 @@ Cmd Header - Players || > §2Spieler
|
|||||||
Cmd Header - Search || > §2${0} Ergebnisse für §f${1}§2:
|
Cmd Header - Search || > §2${0} Ergebnisse für §f${1}§2:
|
||||||
Cmd Header - Servers || > §2Server
|
Cmd Header - Servers || > §2Server
|
||||||
Cmd Header - Web Users || > §2${0} Accounts
|
Cmd Header - Web Users || > §2${0} Accounts
|
||||||
Cmd Info - Bungee Connection || §2Verbuunden mit Bungee: §f${0}
|
Cmd Info - Bungee Connection || §2Verbunden mit Bungee: §f${0}
|
||||||
Cmd Info - Database || §2Genutzte Datenbank: §f${0}
|
Cmd Info - Database || §2Genutzte Datenbank: §f${0}
|
||||||
Cmd Info - Reload Complete || §aReload erfolgreich.
|
Cmd Info - Reload Complete || §aReload erfolgreich.
|
||||||
Cmd Info - Reload Failed || §cBeim Reload ist etwas schief gelaufen, ein Neustart wird empfohlen.
|
Cmd Info - Reload Failed || §cBeim Reload ist etwas schief gelaufen. Es wird empfohlen, den Server neuzustarten.
|
||||||
Cmd Info - Update || §2Update verfügbar: §f${0}
|
Cmd Info - Update || §2Update verfügbar: §f${0}
|
||||||
Cmd Info - Version || §2Version: §f${0}
|
Cmd Info - Version || §2Version: §f${0}
|
||||||
Cmd Notify - No WebUser || Möglicherweise hast du keinen Account. Erstelle einen mit /plan register <password>
|
Cmd Notify - No WebUser || Möglicherweise hast du keinen Account. Erstelle einen mit /plan register <password>
|
||||||
@ -29,58 +29,58 @@ Cmd Qinspect - Activity Index || §2Aktivitätsindex: §f${0
|
|||||||
Cmd Qinspect - Deaths || §2Tode: §f${0}
|
Cmd Qinspect - Deaths || §2Tode: §f${0}
|
||||||
Cmd Qinspect - Geolocation || §2Eingeloggt aus: §f${0}
|
Cmd Qinspect - Geolocation || §2Eingeloggt aus: §f${0}
|
||||||
Cmd Qinspect - Last Seen || §2Zuletzt gesehen: §f${0}
|
Cmd Qinspect - Last Seen || §2Zuletzt gesehen: §f${0}
|
||||||
Cmd Qinspect - Longest Session || §2Längste Sitzung: §f${0}
|
Cmd Qinspect - Longest Session || §2Längste Session: §f${0}
|
||||||
Cmd Qinspect - Mob Kills || §2Getötete Mobs: §f${0}
|
Cmd Qinspect - Mob Kills || §2Getötete Mobs: §f${0}
|
||||||
Cmd Qinspect - Player Kills || §2Getötete Spieler: §f${0}
|
Cmd Qinspect - Player Kills || §2Getötete Spieler: §f${0}
|
||||||
Cmd Qinspect - Playtime || §Spielzeit: §f${0}
|
Cmd Qinspect - Playtime || §Spielzeit: §f${0}
|
||||||
Cmd Qinspect - Registered || §2Registrierung: §f${0}
|
Cmd Qinspect - Registered || §2Registrierung: §f${0}
|
||||||
Cmd Qinspect - Times Kicked || §2Kicks: §f${0}
|
Cmd Qinspect - Times Kicked || §2Kicks: §f${0}
|
||||||
Cmd Setup - Allowed || §aSet-up ist nun erlaubt.
|
Cmd Setup - Allowed || §aSetupmodus wurde aktiviert.
|
||||||
Cmd Setup - Bad Request || §eVerbindung hergestellt, der empfangende Server ist kein Bungee-Server. Nutze stattdessen die Bungee-Adresse.
|
Cmd Setup - Bad Request || §eVerbindung hergestellt. Der empfangende Server ist kein Bungeecordserver. Nutze stattdessen die Bungeecord-Adresse.
|
||||||
Cmd Setup - Disallowed || §cSet-up ist nun nicht mehr erlaubt.
|
Cmd Setup - Disallowed || §cSet-up wurde deaktiviert.
|
||||||
Cmd Setup - Forbidden || §eVerbindung hergestellt, aber der Bungee-Server hat den Set-up-Modus ausgeschaltet - nutze '/planbungee setup' um ihn zu aktivieren.
|
Cmd Setup - Forbidden || §eVerbindung hergestellt aber der Bungeecordserver hat den Setupmodus nicht aktiviert. Nutze '/planbungee setup' um ihn zu aktivieren.
|
||||||
Cmd Setup - Gateway Error || §eVerbindung hergestellt, aber der Bungee-Server konnte sich nicht mit diesem Server verbinden (Wurde der aktuelle Server neugestartet?). Nutze /plan m con & /planbungee con zum debuggen.
|
Cmd Setup - Gateway Error || §eVerbindung hergestellt, aber der Bungeecordserver konnte sich nicht mit diesem Server verbinden (Wurde der aktuelle Server neugestartet?). Nutze /plan m con & /planbungee con zum debuggen.
|
||||||
Cmd Setup - Generic Fail || §eVerbindung fehlgeschlagen: ${0}
|
Cmd Setup - Generic Fail || §eVerbindung fehlgeschlagen: ${0}
|
||||||
Cmd Setup - Internal Error || §eVerbindung hergestellt. ${0}, eventuelle Fehler kannst du dem Error-Log auf der Debugseite des empfangenden Servers einsehen.
|
Cmd Setup - Internal Error || §eVerbindung hergestellt. ${0}, eventuelle Fehler kannst du dem Error-Log auf der Debugseite des empfangenden Servers entnehmen.
|
||||||
Cmd Setup - Success || §aVerbindung erfolgreich, Plan startet eventuell in ein paar Sekunden neu.
|
Cmd Setup - Success || §aVerbindung erfolgreich, Plan startet eventuell in ein paar Sekunden neu.
|
||||||
Cmd Setup - Unauthorized || §eVerbindung erfolgreich, aber der empfangende Server hat diesen Server nicht autorisiert. Auf dem Plan-Discord bekommst du Hilfe.
|
Cmd Setup - Unauthorized || §eVerbindung erfolgreich, aber der empfangende Server hat diesen Server nicht autorisiert. Auf dem Plan-Discord bekommst du Hilfe.
|
||||||
Cmd Setup - Url mistake || §cNutze die gesamte Adresse (Beginnend mit http:// oder https://) - Diese kannst du dem Bungee enable log entnehmen.
|
Cmd Setup - Url mistake || §cNutze die gesamte Adresse (Beginnend mit http:// oder https://) - Diese kannst du dem Bungee enable log entnehmen.
|
||||||
Cmd Setup - WebServer not Enabled || §cWebServer ist auf diesem Server deaktiviert! Dies sollte beim Start aktiviert werden!
|
Cmd Setup - WebServer not Enabled || §cWebServer ist auf diesem Server deaktiviert! Dies sollte beim Start aktiviert werden!
|
||||||
Cmd SUCCESS - Feature disabled || §a'${0}' wurde bist zum nächsten Reload des Plugins deaktiviert.
|
Cmd SUCCESS - Feature disabled || §a'${0}' wurde bis zum nächsten Reload des Plugins deaktiviert.
|
||||||
Cmd SUCCESS - WebUser register || §aNeuer Account (${0}) erfolgreich hinzugefügt!
|
Cmd SUCCESS - WebUser register || §aNeuer Account (${0}) erfolgreich hinzugefügt!
|
||||||
Cmd Update - Cancel Success || §aAbbruch erfolgreich.
|
Cmd Update - Cancel Success || §aErfolgreich abgebrochen.
|
||||||
Cmd Update - Cancelled || §cUpdate abgebrochen.
|
Cmd Update - Cancelled || §cUpdate abgebrochen.
|
||||||
Cmd Update - Change log || Change Log v${0}:
|
Cmd Update - Change log || Change Log v${0}:
|
||||||
Cmd Update - Fail Cacnel || §cAuf einem Server war das Update nicht erfolgreich, breche auf allen anderen Servern die Updates ab...
|
Cmd Update - Fail Cacnel || §cAuf einem Server war das Update nicht erfolgreich. Das Update wird auf allen Servern abgebrochen
|
||||||
Cmd Update - Fail Force Notify || §e${0} wurde nicht geupdated, -force wurde angegeben, fahre mit Updates fort.
|
Cmd Update - Fail Force Notify || §e${0} wurde nicht geupdated, -force wurde angegeben, fahre mit Updates fort.
|
||||||
Cmd Update - Fail Not Online || §cNicht alle Server sind online oder erreichbar, erreichbare Server kannst du mit /plan update -u -force updaten
|
Cmd Update - Fail Not Online || §cNicht alle Server sind online oder erreichbar. Erreichbare Server kannst du mit /plan update -u -force updaten
|
||||||
Cmd Update - Notify Cancel || §aDu kannst das Update auf Servern, die noch nicht neugestartet wurden verwerfen mit: /plan update cancel.
|
Cmd Update - Notify Cancel || §aDu kannst das Update auf Servern, die noch nicht neugestartet wurden, verwerfen mit: /plan update cancel.
|
||||||
Cmd Update - Online Check || Überprüfe, ob alle Server online sind.
|
Cmd Update - Online Check || Überprüfe ob alle Server online sind.
|
||||||
Cmd Update - Scheduled || §aUpdate für ${0} geplant.
|
Cmd Update - Scheduled || §aUpdate für ${0} geplant.
|
||||||
Cmd Update - Url mismatch || §cDie Download-URL beginnt nicht mit ${0} und ist evtl. nicht vertrauenswürdig. Du kannst diese Version manuell hier downloaden (direkter Download):
|
Cmd Update - Url mismatch || §cDie Download-URL beginnt nicht mit ${0} und ist evtl. nicht vertrauenswürdig. Du kannst diese Version manuell hier downloaden (direkter Download):
|
||||||
Cmd Web - Permission Levels || >\§70: Zugriff auf alle Seiten\§71: Zugriff auf '/players' Und alle Spielerseiten\§72: Zugriff auf alle Spielerseiten mit dem gleichen Username wie der Web-Account\§73+: Keine Berechtigung
|
Cmd Web - Permission Levels || >\§70: Zugriff auf alle Seiten\§71: Zugriff auf '/players' Und alle Spielerseiten\§72: Zugriff auf alle Spielerseiten mit dem gleichen Username wie der Web-Account\§73+: Keine Berechtigung
|
||||||
Command Help - /plan analyze || Server-Übersicht
|
Command Help - /plan analyze || Server-Übersicht
|
||||||
Command Help - /plan dev || Entwicklungsmodus-Befehl
|
Command Help - /plan dev || Entwicklungsmodus-Befehl
|
||||||
Command Help - /plan help || Zeigt eine Befehlsliste
|
Command Help - /plan help || Zeigt eine Befehlsliste an
|
||||||
Command Help - /plan info || Zeigt die Version von Plan
|
Command Help - /plan info || Zeigt die Version von Plan an
|
||||||
Command Help - /plan inspect || Zeigt eine Spielerseite
|
Command Help - /plan inspect || Zeigt eine Spielerseite an
|
||||||
Command Help - /plan manage || Verwaltet die Plan-Datenbank
|
Command Help - /plan manage || Verwaltet die Plan-Datenbank
|
||||||
Command Help - /plan manage backup || Erstellt ein Backup der Datenbank
|
Command Help - /plan manage backup || Erstellt ein Backup der Datenbank
|
||||||
Command Help - /plan manage clear || Leer die Datenbank
|
Command Help - /plan manage clear || Datenbank leeren
|
||||||
Command Help - /plan manage con || Debug Server-Bungee Verbindungen
|
Command Help - /plan manage con || Debug Server-Bungee Verbindungen
|
||||||
Command Help - /plan manage disable || Schalte eine Funktion temporär aus
|
Command Help - /plan manage disable || Schalte eine Funktion temporär aus
|
||||||
Command Help - /plan manage hotswap || Ändere die Datenbank schnell
|
Command Help - /plan manage hotswap || Ändere die Datenbank schnell
|
||||||
Command Help - /plan manage import || Importiere Daten
|
Command Help - /plan manage import || Daten importieren
|
||||||
Command Help - /plan manage move || Bewege die Daten zwischen Datenbanken
|
Command Help - /plan manage move || Bewege die Daten zwischen den Datenbanken
|
||||||
Command Help - /plan manage remove || Entferne die Daten eines Spielers
|
Command Help - /plan manage remove || Entferne die Daten eines Spielers
|
||||||
Command Help - /plan manage restore || Spiele ein Backup ein
|
Command Help - /plan manage restore || Spiele ein Backup ein
|
||||||
Command Help - /plan manage setup || Stelle die Server-Bungee-Verbindung her
|
Command Help - /plan manage setup || Stelle die Server-Bungee-Verbindung her
|
||||||
Command Help - /plan network || Netzwerk-Seite
|
Command Help - /plan network || Netzwerk-Seite
|
||||||
Command Help - /plan players || Spieler-Seite
|
Command Help - /plan players || Spieler-Seite
|
||||||
Command Help - /plan qinspect || Zeige Spielerinfo im Spiel
|
Command Help - /plan qinspect || Zeigt die Spielerinfo im Spiel
|
||||||
Command Help - /plan register || Registriere einen Account
|
Command Help - /plan register || Registriere einen Account
|
||||||
Command Help - /plan reload || Starte Plan neu
|
Command Help - /plan reload || Plan neuladen
|
||||||
Command Help - /plan search || Suche nach einem Spieler
|
Command Help - /plan search || Nach einem Spieler suchen
|
||||||
Command Help - /plan servers || Liste die Server in der Datenbank auf
|
Command Help - /plan servers || Liste die Server in der Datenbank auf
|
||||||
Command Help - /plan update || Zeige das Änderungsprotokoll oder update den Server
|
Command Help - /plan update || Zeige das Änderungsprotokoll oder update den Server
|
||||||
Command Help - /plan web check || Infos über einen Account
|
Command Help - /plan web check || Infos über einen Account
|
||||||
@ -92,11 +92,11 @@ Command Help - /planbungee con || Debug Bungee-Server Verbindun
|
|||||||
Command Help - /planbungee disable || Deaktiviert das Plugin temporär
|
Command Help - /planbungee disable || Deaktiviert das Plugin temporär
|
||||||
Command Help - /planbungee setup || Schaltet Setup-Modus an oder aus
|
Command Help - /planbungee setup || Schaltet Setup-Modus an oder aus
|
||||||
Database - Apply Patch || Wende Patch an: ${0}..
|
Database - Apply Patch || Wende Patch an: ${0}..
|
||||||
Database - Patches Applied || Alle Datenbankpatches wurden erfolgreich angewandt.
|
Database - Patches Applied || Alle Datenbankpatches wurden erfolgreich angewendet.
|
||||||
Database - Patches Applied Already || Alle Datenbankpatches wurden bereits angewandt.
|
Database - Patches Applied Already || Alle Datenbankpatches wurden bereits angewendet.
|
||||||
Database MySQL - Launch Options Error || Startoptionen sind falsch, nutze Voreinstellungen (${0})
|
Database MySQL - Launch Options Error || Startoptionen sind falsch, nutze Voreinstellungen (${0})
|
||||||
Database Notify - Clean || Daten von ${0} Spielern gelöscht.
|
Database Notify - Clean || Daten von ${0} Spielern gelöscht.
|
||||||
Database Notify - SQLite No WAL || SQLite WAL auf dieser Serverversion nicht unterstützt, nutze Voreinstellungen. Dies beeinträchtigt möglicherweise die Serverperformance.
|
Database Notify - SQLite No WAL || SQLite WAL wird auf dieser Serverversion nicht unterstützt, nutze Voreinstellungen. Dies beeinträchtigt möglicherweise die Serverperformance.
|
||||||
Disable || Player Analytics ausgeschaltet.
|
Disable || Player Analytics ausgeschaltet.
|
||||||
Disable - Processing || Verarbeite kritische unverarbeitete Aufgaben. (${0})
|
Disable - Processing || Verarbeite kritische unverarbeitete Aufgaben. (${0})
|
||||||
Disable - Processing Complete || Verarbeitung komplett.
|
Disable - Processing Complete || Verarbeitung komplett.
|
||||||
@ -104,15 +104,15 @@ Disable - WebServer || Webserver deaktiviert.
|
|||||||
Enable || Player Analytics angeschaltet.
|
Enable || Player Analytics angeschaltet.
|
||||||
Enable - Database || ${0}-dDatenbankverbindung hergestellt.
|
Enable - Database || ${0}-dDatenbankverbindung hergestellt.
|
||||||
Enable - Notify Address Confirmation || Versichere dich, dass die Adresse auf DIESEN Server verweist: ${0}
|
Enable - Notify Address Confirmation || Versichere dich, dass die Adresse auf DIESEN Server verweist: ${0}
|
||||||
Enable - Notify Empty IP || IP in der server.properties ist leer & AlternativeIP ist nicht in Verwendung. Falsche Links werden verwendet!
|
Enable - Notify Empty IP || IP in der server.properties ist leer & AlternativeIP ist nicht in Verwendung. Es werden falsche Links verwendet!
|
||||||
Enable - Notify Geolocations disabled || Geolocation wird nicht aufgezeichnet (Data.Geolocations: false)
|
Enable - Notify Geolocations disabled || Geolocation wird nicht aufgezeichnet (Data.Geolocations: false)
|
||||||
Enable - Notify Geolocations Internet Required || Plan braucht Internetzugang um die GeoLite2 Geolocation Datenbank runterzuladen.
|
Enable - Notify Geolocations Internet Required || Plan braucht einen Internetzugang um die GeoLite2 Geolocation Datenbank runterzuladen.
|
||||||
Enable - Notify Webserver disabled || WebServer wurde nicht initialisiert. (WebServer.DisableWebServer: true)
|
Enable - Notify Webserver disabled || WebServer wurde nicht geladen. (WebServer.DisableWebServer: true)
|
||||||
Enable - WebServer || Webserver läuft auf PORT ${0} (${1})
|
Enable - WebServer || Webserver läuft auf PORT ${0} (${1})
|
||||||
Enable FAIL - Database || ${0}-Datenbankverbindung fehlgeschlagen: ${1}
|
Enable FAIL - Database || ${0}-Datenbankverbindung fehlgeschlagen: ${1}
|
||||||
Enable FAIL - Database Patch || Datenbank-Patch ist fehlgeschlagen, Plugin wurde deaktiviert. Bitte melde dies.
|
Enable FAIL - Database Patch || Datenbank-Patch ist fehlgeschlagen. Plugin wurde deaktiviert. Wir bitten dich, uns diesen Vorfall mitzuteilen.
|
||||||
Enable FAIL - GeoDB Write || Etwas ist beim Speichern der GeoLite2 Geolocation Datenbank fehlgeschlagen
|
Enable FAIL - GeoDB Write || Etwas ist beim Speichern der GeoLite2 Geolocation Datenbank fehlgeschlagen
|
||||||
Enable FAIL - WebServer (Bungee) || Webserver ist nicht initialisiert!
|
Enable FAIL - WebServer (Bungee) || Webserver ist nicht geladen
|
||||||
Enable FAIL - Wrong Database Type || ${0} ist keine gültige Datenbank
|
Enable FAIL - Wrong Database Type || ${0} ist keine gültige Datenbank
|
||||||
HTML - ACTIVITY_INDEX || Aktivitätsindex
|
HTML - ACTIVITY_INDEX || Aktivitätsindex
|
||||||
HTML - ALL || Gesamt
|
HTML - ALL || Gesamt
|
||||||
@ -166,7 +166,7 @@ HTML - NAV_COMMAND_USAGE || Befehlsverwendung
|
|||||||
HTML - NAV_GEOLOCATIONS || Geolocations
|
HTML - NAV_GEOLOCATIONS || Geolocations
|
||||||
HTML - NAV_INFORMATION || Information
|
HTML - NAV_INFORMATION || Information
|
||||||
HTML - NAV_NETWORK_PLAYERS || Netzwerk Spieler
|
HTML - NAV_NETWORK_PLAYERS || Netzwerk Spieler
|
||||||
HTML - NAV_ONLINE_ACTIVITY || Online Aktivität
|
HTML - NAV_ONLINE_ACTIVITY || Onlineaktivität
|
||||||
HTML - NAV_OVERVIEW || Übersicht
|
HTML - NAV_OVERVIEW || Übersicht
|
||||||
HTML - NAV_PERFORMANCE || Performance
|
HTML - NAV_PERFORMANCE || Performance
|
||||||
HTML - NAV_PLAYERS || Spieler
|
HTML - NAV_PLAYERS || Spieler
|
||||||
@ -205,7 +205,7 @@ HTML - PUNCHCARD || LOCHKARTE
|
|||||||
HTML - RECENT_LOGINS || Letzte LOGINS
|
HTML - RECENT_LOGINS || Letzte LOGINS
|
||||||
HTML - REGISTERED || REGISTRIERT
|
HTML - REGISTERED || REGISTRIERT
|
||||||
HTML - REGISTERED_TEXT || Registriert
|
HTML - REGISTERED_TEXT || Registriert
|
||||||
HTML - REGULAR || REGELMÄSSIG
|
HTML - REGULAR || REGELMÄSSIGE
|
||||||
HTML - SEEN_NICKNAMES || Registrierte Nicknames
|
HTML - SEEN_NICKNAMES || Registrierte Nicknames
|
||||||
HTML - SERVER || Server
|
HTML - SERVER || Server
|
||||||
HTML - SERVER_ANALYSIS || Server Analyse
|
HTML - SERVER_ANALYSIS || Server Analyse
|
||||||
@ -221,8 +221,8 @@ HTML - SESSIONS || Sessions
|
|||||||
HTML - TIME || Zeit
|
HTML - TIME || Zeit
|
||||||
HTML - TIMES_KICKED || Mal gekickt
|
HTML - TIMES_KICKED || Mal gekickt
|
||||||
HTML - TIMES_USED || Mal benutzt
|
HTML - TIMES_USED || Mal benutzt
|
||||||
HTML - TOTAL_ACTIVE_TEXT || Gesamt Aktiv
|
HTML - TOTAL_ACTIVE_TEXT || Gesamte Aktive Spielzeit
|
||||||
HTML - TOTAL_AFK || Gesamt AFK
|
HTML - TOTAL_AFK || Gesamte AFK-Zeit
|
||||||
HTML - TOTAL_PLAYERS || Gesamte Spieler
|
HTML - TOTAL_PLAYERS || Gesamte Spieler
|
||||||
HTML - TOTAL_PLAYTIME || Gesamte Spielzeit
|
HTML - TOTAL_PLAYTIME || Gesamte Spielzeit
|
||||||
HTML - UNIQUE || EINZIGARTIG
|
HTML - UNIQUE || EINZIGARTIG
|
||||||
@ -252,7 +252,7 @@ HTML ERRORS - NOT_FOUND_404 || Nicht gefunden.
|
|||||||
HTML ERRORS - NOT_PLAYED_404 || Der Spieler war nie auf dem Server.
|
HTML ERRORS - NOT_PLAYED_404 || Der Spieler war nie auf dem Server.
|
||||||
HTML ERRORS - PAGE_NOT_FOUND_404 || Diese Seite existiert nicht.
|
HTML ERRORS - PAGE_NOT_FOUND_404 || Diese Seite existiert nicht.
|
||||||
HTML ERRORS - UNAUTHORIZED_401 || Unautorisiert
|
HTML ERRORS - UNAUTHORIZED_401 || Unautorisiert
|
||||||
HTML ERRORS - UNKNOWN_PAGE_404 || Stelle sicher, dass du einen Link benutzt, der von einem Command generiert wurde. Beispielsweise:</p><p>/player/PlayerName<br>/server/ServerName</p>
|
HTML ERRORS - UNKNOWN_PAGE_404 || Stelle sicher, dass du einen Link benutzt, der von einem Befehl generiert wurde. Beispielsweise:</p><p>/player/PlayerName<br>/server/ServerName</p>
|
||||||
HTML ERRORS - UUID_404 || Die UUID des Spielers wurde nicht in der Datenbank gefunden.
|
HTML ERRORS - UUID_404 || Die UUID des Spielers wurde nicht in der Datenbank gefunden.
|
||||||
In Depth Help - /plan ? || > §2Hauptbefehl\ Zugriff auf Unterbefehle und Hilfe\ §2/plan §fListe Unterbefehle\ §2/plan <unterbefehl> ? §fAusführliche Hilfe
|
In Depth Help - /plan ? || > §2Hauptbefehl\ Zugriff auf Unterbefehle und Hilfe\ §2/plan §fListe Unterbefehle\ §2/plan <unterbefehl> ? §fAusführliche Hilfe
|
||||||
In Depth Help - /plan analyze ? || > §2Analysebefehl\ Aktualisiert die Serverseite und stellt einen Zugriffslink bereit.
|
In Depth Help - /plan analyze ? || > §2Analysebefehl\ Aktualisiert die Serverseite und stellt einen Zugriffslink bereit.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: Plan
|
name: Plan
|
||||||
author: Rsl1122
|
author: Rsl1122
|
||||||
main: com.djrapitops.plan.Plan
|
main: com.djrapitops.plan.Plan
|
||||||
version: 4.4.5
|
version: 4.4.6
|
||||||
softdepend:
|
softdepend:
|
||||||
- EssentialsX
|
- EssentialsX
|
||||||
- Towny
|
- Towny
|
||||||
@ -51,13 +51,13 @@ permissions:
|
|||||||
plan.?:
|
plan.?:
|
||||||
description: Help command
|
description: Help command
|
||||||
default: true
|
default: true
|
||||||
plan.inspect:
|
plan.inspect.base:
|
||||||
description: Allows you to check your player data.
|
description: Allows you to check your player data.
|
||||||
default: true
|
default: true
|
||||||
plan.inspect.other:
|
plan.inspect.other:
|
||||||
description: Allows you to check other players' player data.
|
description: Allows you to check other players' player data.
|
||||||
default: op
|
default: op
|
||||||
plan.qinspect:
|
plan.qinspect.base:
|
||||||
description: Allows you to check your player data.
|
description: Allows you to check your player data.
|
||||||
default: op
|
default: op
|
||||||
plan.qinspect.other:
|
plan.qinspect.other:
|
||||||
@ -93,8 +93,8 @@ permissions:
|
|||||||
plan.basic:
|
plan.basic:
|
||||||
children:
|
children:
|
||||||
plan.?: true
|
plan.?: true
|
||||||
plan.inspect: true
|
plan.inspect.base: true
|
||||||
plan.qinspect: true
|
plan.qinspect.base: true
|
||||||
plan.advanced:
|
plan.advanced:
|
||||||
childer:
|
childer:
|
||||||
plan.basic: true
|
plan.basic: true
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.djrapitops.plan.data.store.mutators.formatting;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import utilities.Teardown;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for {@link TimeAmountFormatter} that checks extra zeros config example.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class TimeAmountFormatterDefaultTest {
|
||||||
|
|
||||||
|
private TimeAmountFormatter timeAmountFormatter;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
Settings.FORMAT_YEAR.setTemporaryValue("1 year, ");
|
||||||
|
Settings.FORMAT_YEARS.setTemporaryValue("%years% years, ");
|
||||||
|
Settings.FORMAT_MONTH.setTemporaryValue("1 month, ");
|
||||||
|
Settings.FORMAT_MONTHS.setTemporaryValue("%months% months, ");
|
||||||
|
Settings.FORMAT_DAY.setTemporaryValue("1d ");
|
||||||
|
Settings.FORMAT_DAYS.setTemporaryValue("%days%d ");
|
||||||
|
Settings.FORMAT_HOURS.setTemporaryValue("%hours%h ");
|
||||||
|
Settings.FORMAT_MINUTES.setTemporaryValue("%minutes%m ");
|
||||||
|
Settings.FORMAT_SECONDS.setTemporaryValue("%seconds%s");
|
||||||
|
Settings.FORMAT_ZERO_SECONDS.setTemporaryValue("0s");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
Teardown.resetSettingsTempValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
timeAmountFormatter = new TimeAmountFormatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleOne() {
|
||||||
|
String expected = "1 year, 1 month, 5d 12h 30m 20s";
|
||||||
|
|
||||||
|
long ms = TimeAmount.DAY.ms() * 400L +
|
||||||
|
TimeAmount.HOUR.ms() * 12L +
|
||||||
|
TimeAmount.MINUTE.ms() * 30L +
|
||||||
|
TimeAmount.SECOND.ms() * 20L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleTwo() {
|
||||||
|
String expected = "1 year, 1 month, 5d ";
|
||||||
|
|
||||||
|
long ms = TimeAmount.DAY.ms() * 400L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleThree() {
|
||||||
|
String expected = "12h 20s";
|
||||||
|
|
||||||
|
long ms = TimeAmount.HOUR.ms() * 12L +
|
||||||
|
TimeAmount.SECOND.ms() * 20L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleFour() {
|
||||||
|
String expected = "30m ";
|
||||||
|
|
||||||
|
long ms = TimeAmount.MINUTE.ms() * 30L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleFive() {
|
||||||
|
String expected = "20s";
|
||||||
|
|
||||||
|
long ms = TimeAmount.SECOND.ms() * 20L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleZero() {
|
||||||
|
String expected = "-";
|
||||||
|
|
||||||
|
long ms = 0L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleOneSecond() {
|
||||||
|
String expected = "1s";
|
||||||
|
|
||||||
|
long ms = TimeAmount.SECOND.ms();
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleOneMinute() {
|
||||||
|
String expected = "1m ";
|
||||||
|
|
||||||
|
long ms = TimeAmount.MINUTE.ms();
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.djrapitops.plan.data.store.mutators.formatting;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import utilities.Teardown;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for {@link TimeAmountFormatter} that checks extra zeros config example.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class TimeAmountFormatterExtraZerosTest {
|
||||||
|
|
||||||
|
private TimeAmountFormatter timeAmountFormatter;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
Settings.FORMAT_YEAR.setTemporaryValue("1 year, ");
|
||||||
|
Settings.FORMAT_YEARS.setTemporaryValue("%years% years, ");
|
||||||
|
Settings.FORMAT_MONTH.setTemporaryValue("1 month, ");
|
||||||
|
Settings.FORMAT_MONTHS.setTemporaryValue("%months% months, ");
|
||||||
|
Settings.FORMAT_DAY.setTemporaryValue("1d ");
|
||||||
|
Settings.FORMAT_DAYS.setTemporaryValue("%days%d ");
|
||||||
|
Settings.FORMAT_HOURS.setTemporaryValue("%zero%%hours%:");
|
||||||
|
Settings.FORMAT_MINUTES.setTemporaryValue("%hours%%zero%%minutes%:");
|
||||||
|
Settings.FORMAT_SECONDS.setTemporaryValue("%minutes%%zero%%seconds%");
|
||||||
|
Settings.FORMAT_ZERO_SECONDS.setTemporaryValue("00:00:00");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
Teardown.resetSettingsTempValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
timeAmountFormatter = new TimeAmountFormatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleOne() {
|
||||||
|
String expected = "1 year, 1 month, 5d 12:30:20";
|
||||||
|
|
||||||
|
long ms = TimeAmount.DAY.ms() * 400L +
|
||||||
|
TimeAmount.HOUR.ms() * 12L +
|
||||||
|
TimeAmount.MINUTE.ms() * 30L +
|
||||||
|
TimeAmount.SECOND.ms() * 20L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleTwo() {
|
||||||
|
String expected = "1 year, 1 month, 5d 00:00:00";
|
||||||
|
|
||||||
|
long ms = TimeAmount.DAY.ms() * 400L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleThree() {
|
||||||
|
String expected = "12:00:20";
|
||||||
|
|
||||||
|
long ms = TimeAmount.HOUR.ms() * 12L +
|
||||||
|
TimeAmount.SECOND.ms() * 20L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleFour() {
|
||||||
|
String expected = "00:30:00";
|
||||||
|
|
||||||
|
long ms = TimeAmount.MINUTE.ms() * 30L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleFive() {
|
||||||
|
String expected = "00:00:20";
|
||||||
|
|
||||||
|
long ms = TimeAmount.SECOND.ms() * 20L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleZero() {
|
||||||
|
String expected = "-";
|
||||||
|
|
||||||
|
long ms = 0L;
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleOneSecond() {
|
||||||
|
String expected = "00:00:01";
|
||||||
|
|
||||||
|
long ms = TimeAmount.SECOND.ms();
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exampleOneMinute() {
|
||||||
|
String expected = "00:01:00";
|
||||||
|
|
||||||
|
long ms = TimeAmount.MINUTE.ms();
|
||||||
|
String result = timeAmountFormatter.apply(ms);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.djrapitops.plan.system.listeners.bukkit;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import utilities.Teardown;
|
||||||
|
import utilities.TestConstants;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link AFKListener}
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class AFKListenerTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
Settings.AFK_THRESHOLD_MINUTES.setTemporaryValue(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
Teardown.resetSettingsTempValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAfkPermissionCallCaching() {
|
||||||
|
AFKListener afkListener = new AFKListener();
|
||||||
|
Collection<Boolean> calls = new ArrayList<>();
|
||||||
|
|
||||||
|
Player player = mockPlayer(calls);
|
||||||
|
PlayerMoveEvent event = mockMoveEvent(player);
|
||||||
|
|
||||||
|
afkListener.onMove(event);
|
||||||
|
assertEquals(1, calls.size());
|
||||||
|
afkListener.onMove(event);
|
||||||
|
assertEquals(1, calls.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerMoveEvent mockMoveEvent(Player player) {
|
||||||
|
PlayerMoveEvent event = Mockito.mock(PlayerMoveEvent.class);
|
||||||
|
doReturn(player).when(event).getPlayer();
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Player mockPlayer(Collection<Boolean> calls) {
|
||||||
|
Player player = Mockito.mock(Player.class);
|
||||||
|
doReturn(TestConstants.PLAYER_ONE_UUID).when(player).getUniqueId();
|
||||||
|
doAnswer(perm -> {
|
||||||
|
calls.add(true);
|
||||||
|
return true;
|
||||||
|
}).when(player).hasPermission(Mockito.anyString());
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
@ -53,6 +53,10 @@
|
|||||||
<id>paper-repo</id>
|
<id>paper-repo</id>
|
||||||
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
|
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>sponge-repo</id>
|
||||||
|
<url>https://repo.spongepowered.org/maven</url>
|
||||||
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>vault-repo</id>
|
<id>vault-repo</id>
|
||||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||||
@ -77,6 +81,10 @@
|
|||||||
<id>advanced-achievements-repo</id>
|
<id>advanced-achievements-repo</id>
|
||||||
<url>https://raw.github.com/PyvesB/AdvancedAchievements/mvn-repo/</url>
|
<url>https://raw.github.com/PyvesB/AdvancedAchievements/mvn-repo/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>nucleus-repo</id>
|
||||||
|
<url>http://repo.drnaylor.co.uk/artifactory/list/minecraft</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -108,6 +116,13 @@
|
|||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spongepowered</groupId>
|
||||||
|
<artifactId>spongeapi</artifactId>
|
||||||
|
<version>7.0.0</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<!-- Plugins from repositories -->
|
<!-- Plugins from repositories -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -146,6 +161,12 @@
|
|||||||
<version>1.5.0</version>
|
<version>1.5.0</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.nucleuspowered</groupId>
|
||||||
|
<artifactId>nucleus-api</artifactId>
|
||||||
|
<version>1.6.0-PR1-S7.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Plugins requiring local install -->
|
<!-- Plugins requiring local install -->
|
||||||
|
|
||||||
|
@ -19,8 +19,10 @@ import com.djrapitops.pluginbridge.plan.kingdoms.KingdomsHook;
|
|||||||
import com.djrapitops.pluginbridge.plan.litebans.LiteBansBukkitHook;
|
import com.djrapitops.pluginbridge.plan.litebans.LiteBansBukkitHook;
|
||||||
import com.djrapitops.pluginbridge.plan.litebans.LiteBansBungeeHook;
|
import com.djrapitops.pluginbridge.plan.litebans.LiteBansBungeeHook;
|
||||||
import com.djrapitops.pluginbridge.plan.mcmmo.McmmoHook;
|
import com.djrapitops.pluginbridge.plan.mcmmo.McmmoHook;
|
||||||
|
import com.djrapitops.pluginbridge.plan.nucleus.NucleusHook;
|
||||||
import com.djrapitops.pluginbridge.plan.protocolsupport.ProtocolSupportHook;
|
import com.djrapitops.pluginbridge.plan.protocolsupport.ProtocolSupportHook;
|
||||||
import com.djrapitops.pluginbridge.plan.redprotect.RedProtectHook;
|
import com.djrapitops.pluginbridge.plan.redprotect.RedProtectHook;
|
||||||
|
import com.djrapitops.pluginbridge.plan.sponge.SpongeEconomyHook;
|
||||||
import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook;
|
import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook;
|
||||||
import com.djrapitops.pluginbridge.plan.towny.TownyHook;
|
import com.djrapitops.pluginbridge.plan.towny.TownyHook;
|
||||||
import com.djrapitops.pluginbridge.plan.vault.VaultHook;
|
import com.djrapitops.pluginbridge.plan.vault.VaultHook;
|
||||||
@ -72,7 +74,9 @@ public class Bridge {
|
|||||||
|
|
||||||
private static Hook[] getSpongeHooks(HookHandler h) {
|
private static Hook[] getSpongeHooks(HookHandler h) {
|
||||||
return new Hook[]{
|
return new Hook[]{
|
||||||
new BuyCraftHook(h)
|
new BuyCraftHook(h),
|
||||||
|
new SpongeEconomyHook(h),
|
||||||
|
new NucleusHook(h)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.djrapitops.pluginbridge.plan.nucleus;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.api.PlanAPI;
|
||||||
|
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||||
|
import com.djrapitops.plan.data.element.InspectContainer;
|
||||||
|
import com.djrapitops.plan.data.element.TableContainer;
|
||||||
|
import com.djrapitops.plan.data.plugin.ContainerSize;
|
||||||
|
import com.djrapitops.plan.data.plugin.PluginData;
|
||||||
|
import com.djrapitops.plan.utilities.FormatUtils;
|
||||||
|
import com.djrapitops.plan.utilities.html.Html;
|
||||||
|
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||||
|
import com.djrapitops.plan.utilities.html.icon.Color;
|
||||||
|
import com.djrapitops.plan.utilities.html.icon.Family;
|
||||||
|
import com.djrapitops.plan.utilities.html.icon.Icon;
|
||||||
|
import io.github.nucleuspowered.nucleus.api.NucleusAPI;
|
||||||
|
import io.github.nucleuspowered.nucleus.api.nucleusdata.*;
|
||||||
|
import io.github.nucleuspowered.nucleus.api.service.*;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.*;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import org.spongepowered.api.entity.living.player.User;
|
||||||
|
import org.spongepowered.api.service.user.UserStorageService;
|
||||||
|
import org.spongepowered.api.text.Text;
|
||||||
|
import org.spongepowered.api.text.serializer.TextSerializers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PluginData for Nucleus plugin.
|
||||||
|
*
|
||||||
|
* @author Vankka
|
||||||
|
*/
|
||||||
|
public class NucleusData extends PluginData {
|
||||||
|
private UserStorageService userStorageService = null;
|
||||||
|
|
||||||
|
public NucleusData() {
|
||||||
|
super(ContainerSize.TWO_THIRDS, "Nucleus");
|
||||||
|
setPluginIcon(Icon.called("flask").of(Color.DEEP_ORANGE).build());
|
||||||
|
|
||||||
|
Sponge.getServiceManager().provide(UserStorageService.class).ifPresent(storageService -> userStorageService = storageService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) {
|
||||||
|
User user = getUser(uuid);
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
inspectContainer.addValue("Data unavailable", "Could not get user data");
|
||||||
|
return inspectContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
NucleusAPI.getMuteService().ifPresent(muteService -> addMuteData(user, muteService, inspectContainer));
|
||||||
|
NucleusAPI.getJailService().ifPresent(jailService -> addJailData(user, jailService, inspectContainer));
|
||||||
|
NucleusAPI.getHomeService().ifPresent(homeService -> addHomeData(user, homeService, inspectContainer));
|
||||||
|
NucleusAPI.getNoteService().ifPresent(noteService -> addNoteData(user, noteService, inspectContainer));
|
||||||
|
NucleusAPI.getWarningService().ifPresent(warningService -> addWarningData(user, warningService, inspectContainer));
|
||||||
|
NucleusAPI.getInvulnerabilityService().ifPresent(invulnerabilityService -> addInvulnerabilityData(user, invulnerabilityService, inspectContainer));
|
||||||
|
NucleusAPI.getNicknameService().ifPresent(nicknameService -> addNicknameData(user, nicknameService, inspectContainer));
|
||||||
|
|
||||||
|
return inspectContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnalysisContainer getServerData(Collection<UUID> uuids, AnalysisContainer analysisContainer) {
|
||||||
|
NucleusAPI.getWarpService().ifPresent(warpService -> addWarpData(warpService, analysisContainer));
|
||||||
|
NucleusAPI.getJailService().ifPresent(jailService -> addJailData(jailService, analysisContainer));
|
||||||
|
NucleusAPI.getKitService().ifPresent(kitService -> addKitData(kitService, analysisContainer));
|
||||||
|
|
||||||
|
return analysisContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private User getUser(UUID uuid) {
|
||||||
|
if (Sponge.getServer().getPlayer(uuid).isPresent()) {
|
||||||
|
return Sponge.getServer().getPlayer(uuid).get();
|
||||||
|
} else if (userStorageService != null) {
|
||||||
|
Optional<User> optionalUser = userStorageService.get(uuid);
|
||||||
|
return optionalUser.orElse(null);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatTimeStampYear(Instant instant) {
|
||||||
|
return FormatUtils.formatTimeStampYear(instant.toEpochMilli());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatTimeStampYear(Duration duration) {
|
||||||
|
return FormatUtils.formatTimeStampYear(duration.plusMillis(System.currentTimeMillis()).toMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Player Data
|
||||||
|
*/
|
||||||
|
private void addMuteData(User user, NucleusMuteService muteService, InspectContainer inspectContainer) {
|
||||||
|
boolean muted = muteService.isMuted(user);
|
||||||
|
inspectContainer.addValue(getWithIcon("Muted", Icon.called("bell-slash").of(Color.DEEP_ORANGE)), muted ? "Yes" : "No");
|
||||||
|
|
||||||
|
Optional<MuteInfo> optionalMuteInfo = muteService.getPlayerMuteInfo(user);
|
||||||
|
if (muted && optionalMuteInfo.isPresent()) {
|
||||||
|
MuteInfo muteInfo = optionalMuteInfo.get();
|
||||||
|
|
||||||
|
String reason = HtmlUtils.swapColorsToSpan(muteInfo.getReason());
|
||||||
|
String start = muteInfo.getCreationInstant().map(this::formatTimeStampYear).orElse("Unknown");
|
||||||
|
String end = muteInfo.getRemainingTime().map(this::formatTimeStampYear).orElse("Permanent mute");
|
||||||
|
String link = "Unknown";
|
||||||
|
|
||||||
|
User operatorUser = muteInfo.getMuter().map(this::getUser).orElse(null);
|
||||||
|
if (operatorUser != null) {
|
||||||
|
String operator = operatorUser.getName();
|
||||||
|
link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(operator), operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Operator", Icon.called("user").of(Color.DEEP_ORANGE)), link);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.DEEP_ORANGE).of(Family.REGULAR)), start);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.DEEP_ORANGE).of(Family.REGULAR)), end);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Reason", Icon.called("comment").of(Color.DEEP_ORANGE).of(Family.REGULAR)), reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addJailData(User user, NucleusJailService jailService, InspectContainer inspectContainer) {
|
||||||
|
boolean jailed = jailService.isPlayerJailed(user);
|
||||||
|
inspectContainer.addValue(getWithIcon("Jailed", Icon.called("bars").of(Color.YELLOW).of(Family.SOLID)), jailed ? "Yes" : "No");
|
||||||
|
|
||||||
|
if (jailed && jailService.getPlayerJailData(user).isPresent()) {
|
||||||
|
Inmate inmate = jailService.getPlayerJailData(user).get();
|
||||||
|
|
||||||
|
String reason = inmate.getReason();
|
||||||
|
String start = inmate.getCreationInstant().map(this::formatTimeStampYear).orElse("Unknown");
|
||||||
|
String end = inmate.getRemainingTime().map(this::formatTimeStampYear).orElse("Permanent jail sentence");
|
||||||
|
String link = "Unknown";
|
||||||
|
|
||||||
|
User operatorUser = inmate.getJailer().map(this::getUser).orElse(null);
|
||||||
|
if (operatorUser != null) {
|
||||||
|
String operator = operatorUser.getName();
|
||||||
|
link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(operator), operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Operator", Icon.called("user").of(Color.YELLOW)), link);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.YELLOW).of(Family.REGULAR)), start);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.YELLOW).of(Family.REGULAR)), end);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Reason", Icon.called("comment").of(Color.YELLOW).of(Family.REGULAR)), reason);
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Jail", Icon.called("bars").of(Color.YELLOW).of(Family.SOLID)), inmate.getJailName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHomeData(User user, NucleusHomeService homeService, InspectContainer inspectContainer) {
|
||||||
|
int homeCount = homeService.getHomeCount(user);
|
||||||
|
int maxHomes = homeService.getMaximumHomes(user);
|
||||||
|
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Homes", Icon.called("home").of(Color.GREEN).of(Family.SOLID)), homeCount + "/" + maxHomes);
|
||||||
|
|
||||||
|
List<Home> homes = homeService.getHomes(user);
|
||||||
|
|
||||||
|
if (!homes.isEmpty()) {
|
||||||
|
TableContainer homesTable = new TableContainer(getWithIcon("Home", Icon.called("home").of(Family.SOLID)));
|
||||||
|
homesTable.setColor("light-green");
|
||||||
|
|
||||||
|
for (Home home : homes) {
|
||||||
|
homesTable.addRow(home.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectContainer.addTable("Homes", homesTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNoteData(User user, NucleusNoteService noteService, InspectContainer inspectContainer) {
|
||||||
|
List<Note> notes = noteService.getNotes(user);
|
||||||
|
|
||||||
|
if (!notes.isEmpty()) {
|
||||||
|
TableContainer notesTable = new TableContainer(
|
||||||
|
getWithIcon("Noter", Icon.called("pen").of(Family.SOLID)),
|
||||||
|
getWithIcon("Note", Icon.called("sticky-note").of(Family.REGULAR))
|
||||||
|
);
|
||||||
|
|
||||||
|
notesTable.setColor("light-blue");
|
||||||
|
|
||||||
|
for (Note note : notes) {
|
||||||
|
String noter = "Unknown";
|
||||||
|
|
||||||
|
User noterUser = note.getNoter().map(this::getUser).orElse(null);
|
||||||
|
if (noterUser != null) {
|
||||||
|
noter = noterUser.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
notesTable.addRow(noter, note.getNote());
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectContainer.addTable("Notes", notesTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWarningData(User user, NucleusWarningService warningService, InspectContainer inspectContainer) {
|
||||||
|
List<Warning> warnings = warningService.getWarnings(user);
|
||||||
|
inspectContainer.addValue(getWithIcon("Warning count", Icon.called("flag").of(Color.AMBER)), warnings.size());
|
||||||
|
|
||||||
|
if (!warnings.isEmpty()) {
|
||||||
|
TableContainer warningsTable = new TableContainer(
|
||||||
|
getWithIcon("Warner", Icon.called("exclamation").of(Family.SOLID)),
|
||||||
|
getWithIcon("Reason", Icon.called("sticky-note").of(Family.SOLID))
|
||||||
|
);
|
||||||
|
|
||||||
|
warningsTable.setColor("amber");
|
||||||
|
|
||||||
|
for (Warning warning : warnings) {
|
||||||
|
String warner = "Unknown";
|
||||||
|
|
||||||
|
User warnerUser = warning.getWarner().map(this::getUser).orElse(null);
|
||||||
|
if (warnerUser != null) {
|
||||||
|
warner = warnerUser.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
warningsTable.addRow(warner, warning.getReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectContainer.addTable("Warnings", warningsTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addInvulnerabilityData(User user, NucleusInvulnerabilityService invulnerabilityService, InspectContainer inspectContainer) {
|
||||||
|
boolean invulnerable = invulnerabilityService.isInvulnerable(user);
|
||||||
|
inspectContainer.addValue(getWithIcon("Invulnerable", Icon.called("crosshairs").of(Color.BLUE).of(Family.SOLID)), invulnerable ? "Yes" : "No");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNicknameData(User user, NucleusNicknameService nicknameService, InspectContainer inspectContainer) {
|
||||||
|
Optional<Text> nickname = nicknameService.getNickname(user);
|
||||||
|
|
||||||
|
if (nickname.isPresent()) {
|
||||||
|
String nicknameString = HtmlUtils.swapColorsToSpan(TextSerializers.FORMATTING_CODE.serialize(nickname.get()));
|
||||||
|
inspectContainer.addValue(" " + getWithIcon("Nickname", Icon.called("id-badge").of(Color.GREEN).of(Family.REGULAR)), nicknameString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Server Data
|
||||||
|
*/
|
||||||
|
private void addWarpData(NucleusWarpService warpService, AnalysisContainer analysisContainer) {
|
||||||
|
List<Warp> warps = warpService.getAllWarps();
|
||||||
|
analysisContainer.addValue(getWithIcon("Warp count", Icon.called("map-marker-alt").of(Color.BLUE)), warps.size());
|
||||||
|
|
||||||
|
if (!warps.isEmpty()) {
|
||||||
|
TableContainer warpsTable = new TableContainer(
|
||||||
|
getWithIcon("Name", Icon.called("map-marker-alt").of(Family.SOLID)),
|
||||||
|
getWithIcon("Description", Icon.called("sticky-note").of(Family.REGULAR)),
|
||||||
|
getWithIcon("Category", Icon.called("list").of(Family.SOLID))
|
||||||
|
);
|
||||||
|
|
||||||
|
for (Warp warp : warps) {
|
||||||
|
String description = warp.getDescription().map(desc -> HtmlUtils.swapColorsToSpan(TextSerializers.FORMATTING_CODE.serialize(desc))).orElse("None");
|
||||||
|
String category = warp.getCategory().orElse("None");
|
||||||
|
|
||||||
|
warpsTable.addRow(warp.getName(), description, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
analysisContainer.addTable("Warps", warpsTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addJailData(NucleusJailService jailService, AnalysisContainer analysisContainer) {
|
||||||
|
Map<String, NamedLocation> jails = jailService.getJails();
|
||||||
|
analysisContainer.addValue(getWithIcon("Jail count", Icon.called("bars").of(Family.SOLID).of(Color.TEAL)), jails.size());
|
||||||
|
|
||||||
|
if (!jails.isEmpty()) {
|
||||||
|
TableContainer jailsTable = new TableContainer(getWithIcon("Jail", Icon.called("bars").of(Family.SOLID)));
|
||||||
|
|
||||||
|
for (String jail : jails.keySet()) {
|
||||||
|
jailsTable.addRow(jail);
|
||||||
|
}
|
||||||
|
|
||||||
|
analysisContainer.addTable("Jails", jailsTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addKitData(NucleusKitService kitService, AnalysisContainer analysisContainer) {
|
||||||
|
Set<String> kits = kitService.getKitNames();
|
||||||
|
analysisContainer.addValue(getWithIcon("Kit count", Icon.called("box").of(Family.SOLID)), kits.size());
|
||||||
|
|
||||||
|
if (!kits.isEmpty()) {
|
||||||
|
TableContainer kitsTable = new TableContainer(getWithIcon("Kit", Icon.called("box").of(Family.SOLID)));
|
||||||
|
|
||||||
|
for (String kit : kits) {
|
||||||
|
kitsTable.addRow(kit);
|
||||||
|
}
|
||||||
|
|
||||||
|
analysisContainer.addTable("Kits", kitsTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.djrapitops.pluginbridge.plan.nucleus;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||||
|
import com.djrapitops.pluginbridge.plan.Hook;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for AdvancedBan plugin.
|
||||||
|
*
|
||||||
|
* @author Vankka
|
||||||
|
*/
|
||||||
|
public class NucleusHook extends Hook {
|
||||||
|
public NucleusHook(HookHandler hookHandler) {
|
||||||
|
super("io.github.nucleuspowered.nucleus.NucleusPlugin", hookHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hook() throws NoClassDefFoundError {
|
||||||
|
if (enabled) {
|
||||||
|
addPluginDataSource(new NucleusData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package com.djrapitops.pluginbridge.plan.sponge;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||||
|
import com.djrapitops.plan.data.element.InspectContainer;
|
||||||
|
import com.djrapitops.plan.data.plugin.ContainerSize;
|
||||||
|
import com.djrapitops.plan.data.plugin.PluginData;
|
||||||
|
import com.djrapitops.plan.data.store.keys.AnalysisKeys;
|
||||||
|
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||||
|
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||||
|
import com.djrapitops.plan.system.cache.DataCache;
|
||||||
|
import com.djrapitops.plan.utilities.html.icon.Color;
|
||||||
|
import com.djrapitops.plan.utilities.html.icon.Icon;
|
||||||
|
import org.spongepowered.api.service.economy.Currency;
|
||||||
|
import org.spongepowered.api.service.economy.EconomyService;
|
||||||
|
import org.spongepowered.api.service.economy.account.UniqueAccount;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PluginData for Sponge.
|
||||||
|
*
|
||||||
|
* @author BrainStone
|
||||||
|
*/
|
||||||
|
public class SpongeEconomyData extends PluginData {
|
||||||
|
private static final Color color = Color.AMBER;
|
||||||
|
private static final String nameMoneyIcon = "money-bill-wave";
|
||||||
|
private static final Icon moneyIcon = Icon.called(nameMoneyIcon).build();
|
||||||
|
private static final Icon moneyIconColored = Icon.called(nameMoneyIcon).of(color).build();
|
||||||
|
|
||||||
|
private final EconomyService economyService;
|
||||||
|
|
||||||
|
public SpongeEconomyData(EconomyService economyService) {
|
||||||
|
super(ContainerSize.THIRD, "Sponge Economy");
|
||||||
|
|
||||||
|
this.economyService = economyService;
|
||||||
|
|
||||||
|
setPluginIcon(moneyIconColored);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) {
|
||||||
|
String name = DataCache.getInstance().getName(uuid);
|
||||||
|
|
||||||
|
if (name == null) {
|
||||||
|
return inspectContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<UniqueAccount> uOpt = economyService.getOrCreateAccount(uuid);
|
||||||
|
|
||||||
|
if (!uOpt.isPresent()) {
|
||||||
|
return inspectContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniqueAccount acc = uOpt.get();
|
||||||
|
|
||||||
|
for(Currency currency : economyService.getCurrencies()) {
|
||||||
|
BigDecimal balance = acc.getBalance(currency);
|
||||||
|
inspectContainer.addValue(getWithIcon(currency.getName(), moneyIconColored), currency.format(balance).toPlain());
|
||||||
|
}
|
||||||
|
|
||||||
|
return inspectContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnalysisContainer getServerData(Collection<UUID> uuids, AnalysisContainer analysisContainer) {
|
||||||
|
List<UniqueAccount> players = uuids.stream().map(economyService::getOrCreateAccount)
|
||||||
|
.filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
|
||||||
|
|
||||||
|
for(Currency currency : economyService.getCurrencies()) {
|
||||||
|
addCurrencyToContainer(currency, players, analysisContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return analysisContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCurrencyToContainer(Currency currency, List<UniqueAccount> players, AnalysisContainer analysisContainer) {
|
||||||
|
BigDecimal totalBalance = BigDecimal.ZERO;
|
||||||
|
Map<UUID, String> playerBalances = new HashMap<>();
|
||||||
|
|
||||||
|
for (UniqueAccount player : players) {
|
||||||
|
BigDecimal balance = player.getBalance(currency);
|
||||||
|
|
||||||
|
totalBalance = totalBalance.add(balance);
|
||||||
|
playerBalances.put(player.getUniqueId(), currency.format(balance).toPlain());
|
||||||
|
}
|
||||||
|
|
||||||
|
analysisContainer.addValue(getWithIcon("Total Server Balance " + currency.getName(), moneyIconColored), currency.format(totalBalance).toPlain());
|
||||||
|
analysisContainer.addPlayerTableValues(getWithIcon("Balance " + currency.getName(), moneyIcon), playerBalances);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.djrapitops.pluginbridge.plan.sponge;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.plugin.HookHandler;
|
||||||
|
import com.djrapitops.pluginbridge.plan.Hook;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import org.spongepowered.api.service.economy.EconomyService;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Class responsible for hooking to Sponge and registering 1 data sources
|
||||||
|
*
|
||||||
|
* @author BrainStone
|
||||||
|
* @since 4.4.6
|
||||||
|
*/
|
||||||
|
public class SpongeEconomyHook extends Hook {
|
||||||
|
public SpongeEconomyHook(HookHandler hookHandler) {
|
||||||
|
super("org.spongepowered.api.Sponge", hookHandler);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Optional<EconomyService> serviceOpt = Sponge.getServiceManager().provide(EconomyService.class);
|
||||||
|
enabled = serviceOpt.isPresent();
|
||||||
|
} catch(NoClassDefFoundError e) {
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hook() {
|
||||||
|
if (enabled) {
|
||||||
|
addPluginDataSource(new SpongeEconomyData(Sponge.getServiceManager().provide(EconomyService.class).get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -430,7 +430,7 @@ not permitted.)</div>
|
|||||||
<div class="block">Returns the permission node in plugin.yml.</div>
|
<div class="block">Returns the permission node in plugin.yml.</div>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><span class="returnLabel">Returns:</span></dt>
|
<dt><span class="returnLabel">Returns:</span></dt>
|
||||||
<dd>permission node eg. plan.inspect</dd>
|
<dd>permission node eg. plan.inspect.base</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -444,7 +444,7 @@ not permitted.)</div>
|
|||||||
<div class="block">Same as <a href="../../../../../main/java/com/djrapitops/plan/Permissions.html#getPermission--"><code>getPermission()</code></a>.</div>
|
<div class="block">Same as <a href="../../../../../main/java/com/djrapitops/plan/Permissions.html#getPermission--"><code>getPermission()</code></a>.</div>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><span class="returnLabel">Returns:</span></dt>
|
<dt><span class="returnLabel">Returns:</span></dt>
|
||||||
<dd>permission node eg. plan.inspect</dd>
|
<dd>permission node eg. plan.inspect.base</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
Reference in New Issue
Block a user