Merge pull request #698 from Rsl1122/cleaning

PR for 4.4.4
This commit is contained in:
Rsl1122 2018-08-23 19:29:46 +03:00 committed by GitHub
commit e34f2f773f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 567 additions and 225 deletions

View File

@ -112,7 +112,7 @@
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
</dependency>
<!-- Geo IP -->

View File

@ -14,6 +14,7 @@ import com.djrapitops.plugin.api.utility.log.DebugLog;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.settings.ColorScheme;
import com.google.inject.Inject;
import org.bstats.sponge.Metrics;
import org.slf4j.Logger;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
@ -24,9 +25,12 @@ import org.spongepowered.api.plugin.Plugin;
import java.io.File;
import java.io.InputStream;
@Plugin(id = "plan", name = "Plan", version = "4.4.3", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"})
@Plugin(id = "plan", name = "Plan", version = "4.4.4", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"})
public class PlanSponge extends SpongePlugin implements PlanPlugin {
@Inject
private Metrics metrics;
@Inject
private Logger logger;
@ -58,7 +62,7 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin {
locale = system.getLocaleSystem().getLocale();
system.enable();
new BStatsSponge().registerMetrics();
new BStatsSponge(metrics).registerMetrics();
Log.info(locale.getString(PluginLang.ENABLED));
} catch (AbstractMethodError e) {

View File

@ -4,6 +4,7 @@ import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.command.commands.*;
import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand;
import com.djrapitops.plan.command.commands.manage.ManageRawDataCommand;
import com.djrapitops.plan.command.commands.manage.ManageUninstalledCommand;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.locale.lang.DeepHelpLang;
import com.djrapitops.plan.system.settings.Permissions;
@ -44,6 +45,7 @@ public class PlanBungeeCommand extends TreeCmdNode {
new ManageConDebugCommand(plugin),
new ManageRawDataCommand(plugin),
new BungeeSetupToggleCommand(plugin),
new ManageUninstalledCommand(plugin),
new ReloadCommand(plugin),
new DisableCommand(plugin),
new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()),

View File

@ -154,11 +154,11 @@ public class Session extends DataContainer implements DateHolder {
}
public void setWorldTimes(WorldTimes worldTimes) {
putRawData(SessionKeys.WORLD_TIMES, worldTimes);
this.worldTimes = worldTimes;
}
public void setPlayerKills(List<PlayerKill> playerKills) {
putRawData(SessionKeys.PLAYER_KILLS, playerKills);
this.playerKills = playerKills;
}
public boolean isFetchedFromDB() {
@ -182,14 +182,8 @@ public class Session extends DataContainer implements DateHolder {
getValue(SessionKeys.END).orElse(-1L).equals(session.getValue(SessionKeys.END).orElse(-1L)) &&
mobKills == session.mobKills &&
deaths == session.deaths &&
Objects.equals(
getValue(SessionKeys.WORLD_TIMES).orElse(null),
session.getValue(SessionKeys.WORLD_TIMES).orElse(null)
) &&
Objects.equals(
getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()),
session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>())
);
Objects.equals(playerKills, session.playerKills) &&
Objects.equals(worldTimes, session.worldTimes);
}
@Override
@ -205,7 +199,7 @@ public class Session extends DataContainer implements DateHolder {
return worldTimes;
}
private List<PlayerKill> getPlayerKills() {
public List<PlayerKill> getPlayerKills() {
return playerKills;
}
@ -231,7 +225,6 @@ public class Session extends DataContainer implements DateHolder {
}
Map<String, Long> playtimePerAlias = worldTimes.getPlaytimePerAlias();
long total = worldTimes.getTotal();
long longest = 0;
String theWorld = "-";
@ -244,8 +237,25 @@ public class Session extends DataContainer implements DateHolder {
}
}
long total = worldTimes.getTotal();
// Prevent arithmetic error if 0
if (total <= 0) {
total = -1;
}
double quotient = longest * 1.0 / total;
return theWorld + " (" + Formatters.percentage().apply(quotient) + ")";
}
@Override
public String toString() {
return "Session{" +
"sessionStart=" + sessionStart +
", worldTimes=" + worldTimes +
", playerKills=" + playerKills +
", mobKills=" + mobKills +
", deaths=" + deaths +
", afkTime=" + afkTime +
'}';
}
}

View File

@ -52,7 +52,7 @@ public class PingMutator {
int max = -1;
for (Ping ping : pings) {
Integer value = ping.getMax();
if (value < 0 || 8000 < value) {
if (value <= 0 || 4000 < value) {
continue;
}
if (value > max) {
@ -67,7 +67,7 @@ public class PingMutator {
int min = -1;
for (Ping ping : pings) {
Integer value = ping.getMin();
if (value < 0 || 8000 < value) {
if (value <= 0 || 4000 < value) {
continue;
}
if (value < min || min == -1) {
@ -80,7 +80,7 @@ public class PingMutator {
public double average() {
return pings.stream().mapToDouble(Ping::getAverage)
.filter(value -> value >= 0 && value <= 8000)
.filter(value -> value > 0 && value <= 4000)
.average().orElse(-1);
}
}

View File

@ -7,6 +7,7 @@ import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.keys.CommonKeys;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.utilities.analysis.Median;
import java.util.*;
import java.util.function.Predicate;
@ -142,13 +143,8 @@ public class SessionsMutator {
}
public long toMedianSessionLength() {
List<Long> sessionLengths = sessions.stream().map(Session::getLength)
.sorted()
.collect(Collectors.toList());
if (sessionLengths.isEmpty()) {
return 0;
}
return sessionLengths.get(sessionLengths.size() / 2);
List<Long> sessionLengths = sessions.stream().map(Session::getLength).collect(Collectors.toList());
return (long) Median.forLong(sessionLengths).calculate();
}
public int toAverageUniqueJoinsPerDay() {
@ -200,5 +196,4 @@ public class SessionsMutator {
return toPlayerDeathList().size();
}
}

View File

@ -170,8 +170,11 @@ public class WorldTimes {
}
public Map<String, Long> getPlaytimePerAlias() {
Map<String, Long> playtimePerWorld = getWorldTimes() // WorldTimes Map<String, GMTimes>
.entrySet().stream()
if (times.isEmpty()) {
return new HashMap<>();
}
Map<String, Long> playtimePerWorld = times.entrySet().stream() // WorldTimes Map<String, GMTimes>
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().getTotal() // GMTimes.getTotal

View File

@ -7,9 +7,6 @@ package com.djrapitops.plan.system.cache;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
/**
@ -21,7 +18,6 @@ public class CacheSystem implements SubSystem {
private final DataCache dataCache;
private final GeolocationCache geolocationCache;
private final DataContainerCache dataContainerCache;
public CacheSystem(PlanSystem system) {
this(new DataCache(system), system);
@ -30,7 +26,6 @@ public class CacheSystem implements SubSystem {
protected CacheSystem(DataCache dataCache, PlanSystem system) {
this.dataCache = dataCache;
geolocationCache = new GeolocationCache(() -> system.getLocaleSystem().getLocale());
dataContainerCache = new DataContainerCache();
}
public static CacheSystem getInstance() {
@ -43,19 +38,11 @@ public class CacheSystem implements SubSystem {
public void enable() throws EnableException {
dataCache.enable();
geolocationCache.enable();
RunnableFactory.createNew("DataContainer cache clean task", new AbsRunnable() {
@Override
public void run() {
dataContainerCache.clear();
}
}).runTaskTimerAsynchronously(TimeAmount.MINUTE.ticks(), TimeAmount.MINUTE.ms());
}
@Override
public void disable() {
geolocationCache.clearCache();
dataContainerCache.clear();
}
public DataCache getDataCache() {
@ -66,7 +53,4 @@ public class CacheSystem implements SubSystem {
return geolocationCache;
}
public DataContainerCache getDataContainerCache() {
return dataContainerCache;
}
}

View File

@ -1,67 +0,0 @@
package com.djrapitops.plan.system.cache;
import com.djrapitops.plan.data.store.Key;
import com.djrapitops.plan.data.store.containers.AnalysisContainer;
import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.UUID;
import java.util.function.Supplier;
/**
* Cache to aid Bungee in case SQL is causing cpu thread starvation, leading to mysql connection drops.
*
* @author Rsl1122
*/
public class DataContainerCache extends DataContainer {
public DataContainerCache() {
super(TimeAmount.SECOND.ms() * 10L);
}
public PlayerContainer getPlayerContainer(UUID uuid) {
return getAndCacheSupplier(Keys.playerContainer(uuid), Suppliers.playerContainer(uuid));
}
public AnalysisContainer getAnalysisContainer(UUID serverUUID) {
return getAndCacheSupplier(Keys.analysisContainer(serverUUID), Suppliers.analysisContainer(serverUUID));
}
private <T> T getAndCacheSupplier(Key<T> key, Supplier<T> ifNotPresent) {
if (!supports(key)) {
putSupplier(key, ifNotPresent);
}
return getUnsafe(key);
}
private static class Keys {
static Key<AnalysisContainer> analysisContainer(UUID serverUUID) {
return new Key<>(AnalysisContainer.class, "ANALYSIS_CONTAINER:" + serverUUID);
}
static Key<PlayerContainer> playerContainer(UUID uuid) {
return new Key<>(PlayerContainer.class, "PLAYER_CONTAINER:" + uuid);
}
private Keys() {
// Static utility class
}
}
private static class Suppliers {
static Supplier<AnalysisContainer> analysisContainer(UUID serverUUID) {
return () -> new AnalysisContainer(Database.getActive().fetch().getServerContainer(serverUUID));
}
static Supplier<PlayerContainer> playerContainer(UUID uuid) {
return () -> Database.getActive().fetch().getPlayerContainer(uuid);
}
private Suppliers() {
// Static utility class
}
}
}

View File

@ -0,0 +1,56 @@
package com.djrapitops.plan.system.database.databases.sql;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.system.database.databases.sql.patches.Patch;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.locale.lang.PluginLang;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.task.AbsRunnable;
import java.util.function.Supplier;
/**
* Task that is in charge on patching the database when the database enables.
*
* @author Rsl1122
*/
public class PatchTask extends AbsRunnable {
private final Patch[] patches;
private final Supplier<Locale> locale;
public PatchTask(Patch[] patches, Supplier<Locale> locale) {
this.patches = patches;
this.locale = locale;
}
@Override
public void run() {
try {
boolean didApply = applyPatches();
Log.info(locale.get().getString(
didApply ? PluginLang.DB_APPLIED_PATCHES : PluginLang.DB_APPLIED_PATCHES_ALREADY
));
} catch (Exception e) {
Log.error("----------------------------------------------------");
Log.error(locale.get().getString(PluginLang.ENABLE_FAIL_DB_PATCH));
Log.error("----------------------------------------------------");
Log.toLog(this.getClass(), e);
PlanPlugin.getInstance().onDisable();
}
}
private boolean applyPatches() {
boolean didApply = false;
for (Patch patch : patches) {
if (!patch.hasBeenApplied()) {
String patchName = patch.getClass().getSimpleName();
Log.info(locale.get().getString(PluginLang.DB_APPLY_PATCH, patchName));
patch.apply();
didApply = true;
}
}
return didApply;
}
}

View File

@ -1,6 +1,5 @@
package com.djrapitops.plan.system.database.databases.sql;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.database.DBInitException;
import com.djrapitops.plan.api.exceptions.database.DBOpException;
import com.djrapitops.plan.system.database.databases.Database;
@ -157,31 +156,12 @@ public abstract class SQLDB extends Database {
new VersionTableRemovalPatch(this)
};
RunnableFactory.createNew("Database Patch", new AbsRunnable() {
@Override
public void run() {
try {
boolean applied = false;
for (Patch patch : patches) {
if (!patch.hasBeenApplied()) {
String patchName = patch.getClass().getSimpleName();
Log.info(locale.get().getString(PluginLang.DB_APPLY_PATCH, patchName));
patch.apply();
applied = true;
}
}
Log.info(locale.get().getString(
applied ? PluginLang.DB_APPLIED_PATCHES : PluginLang.DB_APPLIED_PATCHES_ALREADY
));
} catch (Exception e) {
Log.error("----------------------------------------------------");
Log.error(locale.get().getString(PluginLang.ENABLE_FAIL_DB_PATCH));
Log.error("----------------------------------------------------");
Log.toLog(this.getClass(), e);
PlanPlugin.getInstance().onDisable();
}
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5L);
try {
RunnableFactory.createNew("Database Patch", new PatchTask(patches, locale))
.runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5L);
} catch (Exception ignore) {
// Task failed to register because plugin is being disabled
}
} catch (DBOpException e) {
throw new DBInitException("Failed to set-up Database", e);
}

View File

@ -9,9 +9,11 @@ import com.djrapitops.plan.data.store.mutators.PlayersMutator;
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.*;
@ -84,7 +86,13 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
// Calculating getters
container.putSupplier(ServerKeys.OPERATORS, () -> PlayersMutator.forContainer(container).operators());
container.putSupplier(ServerKeys.SESSIONS, () -> PlayersMutator.forContainer(container).getSessions());
container.putSupplier(ServerKeys.SESSIONS, () -> {
List<Session> sessions = PlayersMutator.forContainer(container).getSessions();
if (serverUUID.equals(ServerInfo.getServerUUID())) {
sessions.addAll(SessionCache.getActiveSessions().values());
}
return sessions;
});
container.putSupplier(ServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(ServerKeys.PLAYER_KILLS).size());
container.putSupplier(ServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());

View File

@ -117,7 +117,7 @@ public class KillsTable extends UserIDTable {
UUID victim = UUID.fromString(uuidS);
long date = set.getLong(Col.DATE.get());
String weapon = set.getString(Col.WEAPON.get());
session.getUnsafe(SessionKeys.PLAYER_KILLS).add(new PlayerKill(victim, weapon, date));
session.getPlayerKills().add(new PlayerKill(victim, weapon, date));
}
return null;
}
@ -286,7 +286,7 @@ public class KillsTable extends UserIDTable {
for (Session session : sessions) {
int sessionID = session.getUnsafe(SessionKeys.DB_ID);
// Every kill
for (PlayerKill kill : session.getUnsafe(SessionKeys.PLAYER_KILLS)) {
for (PlayerKill kill : session.getPlayerKills()) {
UUID victim = kill.getVictim();
long date = kill.getDate();
String weapon = kill.getWeapon();

View File

@ -113,7 +113,7 @@ public class SessionsTable extends UserIDTable {
}
db.getWorldTimesTable().saveWorldTimes(uuid, sessionID, session.getUnsafe(SessionKeys.WORLD_TIMES));
db.getKillsTable().savePlayerKills(uuid, sessionID, session.getUnsafe(SessionKeys.PLAYER_KILLS));
db.getKillsTable().savePlayerKills(uuid, sessionID, session.getPlayerKills());
}
/**

View File

@ -144,6 +144,7 @@ public class ConnectionOut {
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
post.setHeader("charset", "UTF-8");
post.setHeader("Connection", "close");
byte[] toSend = parameters.getBytes();
post.setEntity(new ByteArrayEntity(toSend));

View File

@ -9,7 +9,7 @@ import com.djrapitops.plan.api.exceptions.connection.InternalErrorException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.api.exceptions.database.DBOpException;
import com.djrapitops.plan.data.store.containers.AnalysisContainer;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
@ -79,7 +79,7 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem
try {
runningAnalysis = true;
UUID serverUUID = ServerInfo.getServerUUID();
AnalysisContainer analysisContainer = CacheSystem.getInstance().getDataContainerCache().getAnalysisContainer(serverUUID);
AnalysisContainer analysisContainer = new AnalysisContainer(Database.getActive().fetch().getServerContainer(serverUUID));
return new AnalysisPage(analysisContainer).toHtml();
} catch (DBOpException e) {
if (!e.getCause().getMessage().contains("Connection is closed")) {

View File

@ -12,6 +12,8 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
@ -27,14 +29,24 @@ public class AFKListener implements Listener {
// Static so that /reload does not cause afk tracking to fail.
public static final AFKTracker AFK_TRACKER = new AFKTracker();
private final Map<UUID, Boolean> ignorePermissionInfo;
public AFKListener() {
ignorePermissionInfo = new HashMap<>();
}
private void event(PlayerEvent event) {
try {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
long time = System.currentTimeMillis();
if (player.hasPermission(Permissions.IGNORE_AFK.getPermission())) {
boolean ignored = ignorePermissionInfo.getOrDefault(uuid, player.hasPermission(Permissions.IGNORE_AFK.getPermission()));
if (ignored) {
AFK_TRACKER.hasIgnorePermission(uuid);
ignorePermissionInfo.put(uuid, true);
} else {
ignorePermissionInfo.put(uuid, false);
}
AFK_TRACKER.performedAction(uuid, time);

View File

@ -15,8 +15,8 @@ import com.djrapitops.plan.system.webserver.cache.PageId;
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
import com.djrapitops.plugin.api.utility.log.Log;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.event.ServerDisconnectEvent;
import net.md_5.bungee.api.event.ServerSwitchEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
@ -53,7 +53,7 @@ public class PlayerOnlineListener implements Listener {
}
@EventHandler
public void onLogout(ServerDisconnectEvent event) {
public void onLogout(PlayerDisconnectEvent event) {
try {
ProxiedPlayer player = event.getPlayer();
UUID uuid = player.getUniqueId();

View File

@ -32,7 +32,7 @@ public class PlayerPageUpdateProcessor implements Runnable {
cancel();
}
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 20);
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5);
}
}
}

View File

@ -9,10 +9,12 @@ import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plan.utilities.analysis.Median;
import java.util.List;
import java.util.OptionalInt;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Processes 60s values of a Ping list.
@ -37,30 +39,35 @@ public class PingInsertProcessor implements CriticalRunnable {
long lastDate = history.get(history.size() - 1).getDate();
OptionalInt max = history.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i >= 0)
.filter(i -> i > 0 && i < 4000)
.max();
if (!max.isPresent()) {
return;
}
int minValue = history.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i >= 0)
.min().orElse(-1);
int minValue = getMinValue(history);
double avgValue = history.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i >= 0)
.average().orElse(-1);
int meanValue = getMeanValue(history);
int maxValue = max.getAsInt();
Ping ping = new Ping(lastDate, ServerInfo.getServerUUID(),
minValue,
maxValue,
avgValue);
meanValue);
Database.getActive().save().ping(uuid, ping);
}
int getMinValue(List<DateObj<Integer>> history) {
return history.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i > 0 && i < 4000)
.min().orElse(-1);
}
int getMeanValue(List<DateObj<Integer>> history) {
return (int) Median.forInt(history.stream().map(DateObj::getValue).collect(Collectors.toList())).calculate();
}
}

View File

@ -52,6 +52,8 @@ public enum Settings {
AFK_THRESHOLD_MINUTES("Data.AFKThresholdMinutes"),
KEEP_LOGS_DAYS("Plugin.KeepLogsForXDays"),
KEEP_INACTIVE_PLAYERS_DAYS("Data.KeepInactivePlayerDataForDays"),
PING_SERVER_ENABLE_DELAY("Data.Ping.ServerEnableDelaySeconds"),
PING_PLAYER_LOGIN_DELAY("Data.Ping.PlayerLoginDelaySeconds"),
// String
DEBUG("Plugin.Debug"),

View File

@ -174,7 +174,9 @@ public class NetworkSettings {
AFK_THRESHOLD_MINUTES,
DATA_GEOLOCATIONS,
KEEP_LOGS_DAYS,
KEEP_INACTIVE_PLAYERS_DAYS
KEEP_INACTIVE_PLAYERS_DAYS,
PING_SERVER_ENABLE_DELAY,
PING_PLAYER_LOGIN_DELAY
};
Log.debug("NetworkSettings: Adding Config Values..");
for (Settings setting : sameStrings) {

View File

@ -5,10 +5,12 @@
package com.djrapitops.plan.system.tasks;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.tasks.server.BukkitTPSCountTimer;
import com.djrapitops.plan.system.tasks.server.PaperTPSCountTimer;
import com.djrapitops.plan.system.tasks.server.PingCountTimer;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.RunnableFactory;
import org.bukkit.Bukkit;
@ -33,8 +35,9 @@ public class BukkitTaskSystem extends ServerTaskSystem {
try {
PingCountTimer pingCountTimer = new PingCountTimer();
((Plan) plugin).registerListener(pingCountTimer);
long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber();
RunnableFactory.createNew("PingCountTimer", pingCountTimer)
.runTaskTimer(20L, PingCountTimer.PING_INTERVAL);
.runTaskTimer(startDelay, PingCountTimer.PING_INTERVAL);
} catch (ExceptionInInitializerError | NoClassDefFoundError ignore) {
// Running CraftBukkit
}

View File

@ -26,6 +26,7 @@ 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.plan.utilities.java.Reflection;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log;
@ -160,7 +161,7 @@ public class PingCountTimer extends AbsRunnable implements Listener {
addPlayer(player);
}
}
}).runTaskLater(TimeAmount.SECOND.ticks() * 10L);
}).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber());
}
@EventHandler

View File

@ -1,6 +1,6 @@
package com.djrapitops.plan.system.webserver.response.pages;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.database.databases.Database;
import java.util.UUID;
@ -12,6 +12,6 @@ import java.util.UUID;
public class RawPlayerDataResponse extends RawDataResponse {
public RawPlayerDataResponse(UUID uuid) {
super(CacheSystem.getInstance().getDataContainerCache().getPlayerContainer(uuid));
super(Database.getActive().fetch().getPlayerContainer(uuid));
}
}

View File

@ -1,6 +1,6 @@
package com.djrapitops.plan.system.webserver.response.pages;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.database.databases.Database;
import java.util.UUID;
@ -12,6 +12,6 @@ import java.util.UUID;
public class RawServerDataResponse extends RawDataResponse {
public RawServerDataResponse(UUID serverUUID) {
super(CacheSystem.getInstance().getDataContainerCache().getAnalysisContainer(serverUUID).getServerContainer());
super(Database.getActive().fetch().getServerContainer(serverUUID));
}
}

View File

@ -0,0 +1,58 @@
package com.djrapitops.plan.utilities.analysis;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* Math utility for calculating the median from Integer values.
*
* @author Rsl1122
*/
public class Median {
private final List<Long> values;
private int size;
private Median(Collection<Integer> values, int b) {
this(values.stream().map(i -> (long) i).collect(Collectors.toList()));
}
private Median(List<Long> values) {
this.values = values;
Collections.sort(values);
size = values.size();
}
public static Median forInt(Collection<Integer> integers) {
return new Median(integers, 0);
}
public static Median forLong(List<Long> longs) {
return new Median(longs);
}
public double calculate() {
if (values.isEmpty()) {
return -1;
}
if (size % 2 == 0) {
return calculateEven();
} else {
return calculateOdd();
}
}
private double calculateEven() {
int half = size / 2;
double x1 = values.get(half);
double x2 = values.get(half - 1);
return (x1 + x2) / 2;
}
private double calculateOdd() {
int half = size / 2;
return (double) values.get(half);
}
}

View File

@ -2,13 +2,10 @@ package com.djrapitops.plan.utilities.html.pages;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.CachingSupplier;
import com.djrapitops.plan.data.store.Key;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.connection.ConnectionLog;
@ -32,7 +29,6 @@ import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.nio.charset.Charset;
import java.util.*;
import java.util.function.Supplier;
/**
* Html parsing for the Debug page.
@ -68,7 +64,6 @@ public class DebugPage implements Page {
StringBuilder content = new StringBuilder();
appendResponseCache(content);
appendSessionCache(content);
appendDataContainerCache(content);
return content.toString();
}
@ -110,36 +105,6 @@ public class DebugPage implements Page {
}
}
private void appendDataContainerCache(StringBuilder content) {
try {
content.append("<pre>### DataContainer Cache:<br><br>");
content.append("Key | Is Cached | Cache Time <br>")
.append("-- | -- | -- <br>");
Formatter<Long> timeStamp = Formatters.yearLongValue();
Set<Map.Entry<Key, Supplier>> dataContainers = CacheSystem.getInstance().getDataContainerCache().getMap().entrySet();
if (dataContainers.isEmpty()) {
content.append("Empty");
}
for (Map.Entry<Key, Supplier> entry : dataContainers) {
String keyName = entry.getKey().getKeyName();
Supplier supplier = entry.getValue();
if (supplier instanceof CachingSupplier) {
CachingSupplier cachingSupplier = (CachingSupplier) supplier;
boolean isCached = cachingSupplier.isCached();
String cacheText = isCached ? "Yes" : "No";
String cacheTime = isCached ? timeStamp.apply(cachingSupplier.getCacheTime()) : "-";
content.append(keyName).append(" | ").append(cacheText).append(" | ").append(cacheTime).append("<br>");
} else {
content.append(keyName).append(" | ").append("Non-caching Supplier").append(" | ").append("-").append("<br>");
}
}
content.append("</pre>");
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private String createConfigContent() {
StringBuilder content = new StringBuilder();
appendConfig(content);

View File

@ -14,7 +14,6 @@ import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.ServerInfo;
@ -60,7 +59,7 @@ public class InspectPage implements Page {
}
Benchmark.start("Inspect Parse, Fetch");
Database db = Database.getActive();
PlayerContainer container = CacheSystem.getInstance().getDataContainerCache().getPlayerContainer(uuid);
PlayerContainer container = Database.getActive().fetch().getPlayerContainer(uuid);
if (!container.getValue(PlayerKeys.REGISTERED).isPresent()) {
throw new IllegalStateException("Player is not registered");
}

View File

@ -160,7 +160,7 @@ public class SessionAccordion extends AbstractAccordion {
sessions.sort(new DateHolderRecentComparator());
int i = 0;
for (Session session : sessions) {
for (Session session : new ArrayList<>(sessions)) {
if (i >= maxSessions) {
break;
}

View File

@ -5,18 +5,22 @@ import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plugin.api.utility.log.Log;
import org.bstats.sponge.Metrics;
import javax.inject.Inject;
import java.io.Serializable;
public class BStatsSponge {
@Inject
private Metrics metrics;
private final Metrics metrics;
public BStatsSponge(Metrics metrics) {
this.metrics = metrics;
}
public void registerMetrics() {
Log.logDebug("Enable", "Enabling bStats Metrics.");
if (metrics != null) {
registerConfigSettingGraphs();
} else {
Log.debug("Metrics not injected properly.");
}
}

View File

@ -1,4 +1,4 @@
name: Plan
author: Rsl1122
main: com.djrapitops.plan.PlanBungee
version: 4.4.3
version: 4.4.4

View File

@ -67,6 +67,9 @@ Data:
LogUnknownCommands: false
CombineCommandAliases: true
Geolocations: true
Ping:
ServerEnableDelaySeconds: 300
PlayerLoginDelaySeconds: 30
KeepInactivePlayerDataForDays: 180
# -----------------------------------------------------
Customization:

View File

@ -81,6 +81,9 @@ Data:
LogUnknownCommands: false
CombineCommandAliases: true
Geolocations: true
Ping:
ServerEnableDelaySeconds: 300
PlayerLoginDelaySeconds: 30
KeepInactivePlayerDataForDays: 180
# -----------------------------------------------------
Customization:

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: com.djrapitops.plan.Plan
version: 4.4.3
version: 4.4.4
softdepend:
- EssentialsX
- Towny
@ -19,6 +19,7 @@ softdepend:
- ProtocolSupport
- Kingdoms
- RedProtect
- AdvancedBan
commands:
plan:

View File

@ -1148,9 +1148,9 @@
<script src="js/admin.js"></script>
<!-- FullCalendar -->
<link rel='stylesheet' href='../plugins/fullcalendar/fullcalendar.min.css'/>
<script src='../plugins/momentjs/moment.js'></script>
<script src='../plugins/fullcalendar/fullcalendar.min.js'></script>
<link rel='stylesheet' href='plugins/fullcalendar/fullcalendar.min.css'/>
<script src='plugins/momentjs/moment.js'></script>
<script src='plugins/fullcalendar/fullcalendar.min.js'></script>
<!-- Plan Charts -->
<script src="js/charts/playerGraph.js"></script>

View File

@ -1,10 +1,7 @@
package com.djrapitops.plan.system.cache;
import com.djrapitops.plan.data.container.Session;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import utilities.TestConstants;
import utilities.mocks.SystemMockUtil;
@ -36,6 +33,11 @@ public class SessionCacheTest {
sessionCache.cacheSession(uuid, session);
}
@After
public void tearDown() {
SessionCache.clear();
}
@Test
public void testAtomity() {
SessionCache reloaded = new SessionCache(null);
@ -43,4 +45,16 @@ public class SessionCacheTest {
assertTrue(cachedSession.isPresent());
assertEquals(session, cachedSession.get());
}
@Test
public void testBungeeReCaching() {
SessionCache cache = new BungeeDataCache(null);
cache.cacheSession(uuid, session);
Session expected = new Session(uuid, 0, "", "");
cache.cacheSession(uuid, expected);
Optional<Session> result = SessionCache.getCachedSession(uuid);
assertTrue(result.isPresent());
assertEquals(expected, result.get());
}
}

View File

@ -0,0 +1,66 @@
package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.utilities.analysis.Median;
import com.djrapitops.plugin.api.TimeAmount;
import org.junit.Before;
import org.junit.Test;
import utilities.RandomData;
import utilities.TestConstants;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
/**
* Test for {@link PingInsertProcessor}.
*
* @author Rsl1122
*/
public class PingInsertProcessorTest {
private List<DateObj<Integer>> testPing;
@Before
public void setUp() {
testPing = new ArrayList<>();
for (int i = 0; i < TimeAmount.MINUTE.ms(); i += TimeAmount.SECOND.ms() * 2L) {
testPing.add(new DateObj<>(i, RandomData.randomInt(1, 4000)));
}
}
@Test
public void testMedian() {
List<Integer> collect = testPing.stream().map(DateObj::getValue).sorted().collect(Collectors.toList());
System.out.println(collect);
int expected = (int) Median.forInt(collect).calculate();
int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, new ArrayList<>()).getMeanValue(testPing);
System.out.println(result);
assertEquals(expected, result);
}
@Test
public void testMedianSingleEntry() {
int expected = 50;
int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, new ArrayList<>()).getMeanValue(
Collections.singletonList(new DateObj<>(0, expected))
);
assertEquals(expected, result);
}
@Test
public void testMedianEmpty() {
int expected = -1;
int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, new ArrayList<>()).getMeanValue(
Collections.emptyList()
);
assertEquals(expected, result);
}
}

View File

@ -0,0 +1,90 @@
package com.djrapitops.plan.utilities.analysis;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* Tests for {@link Median}.
*
* @author Rsl1122
*/
public class MedianTest {
@Test
public void simpleOdd() {
List<Integer> testValues = Arrays.asList(1, 3, 3, 6, 7, 8, 9);
Collections.shuffle(testValues);
double expected = 6;
double result = Median.forInt(testValues).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void simpleEven() {
List<Integer> testValues = Arrays.asList(1, 2, 3, 4, 5, 6, 8, 9);
Collections.shuffle(testValues);
double expected = 4.5;
double result = Median.forInt(testValues).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void empty() {
double expected = -1;
double result = Median.forInt(Collections.emptyList()).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void singleValue() {
double expected = 50;
double result = Median.forInt(Collections.singletonList((int) expected)).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void twoValues() {
List<Integer> testValues = Arrays.asList(1, 2);
double expected = 1.5;
double result = Median.forInt(testValues).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void overflowOdd() {
List<Integer> testValues = Arrays.asList(Integer.MIN_VALUE, 2, Integer.MAX_VALUE);
double expected = 2;
double result = Median.forInt(testValues).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void overflowEven() {
List<Integer> testValues = Arrays.asList(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
double expected = -0.5;
double result = Median.forInt(testValues).calculate();
assertEquals(expected, result, 0.01);
}
@Test
public void overflowEven2() {
List<Integer> testValues = Arrays.asList(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
double expected = Integer.MAX_VALUE;
double result = Median.forInt(testValues).calculate();
assertEquals(expected, result, 0.01);
}
}

View File

@ -129,7 +129,7 @@
</dependency>
<dependency>
<groupId>com.gmail.nossr50</groupId>
<artifactId>mcmmo</artifactId>
<artifactId>mcMMO</artifactId>
<version>1.5.07</version>
<scope>provided</scope>
</dependency>
@ -161,7 +161,7 @@
<dependency>
<groupId>net.kaikk.mc</groupId>
<artifactId>GriefPreventionPlus</artifactId>
<version>RELEASE</version>
<version>13.3</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -230,6 +230,12 @@
<version>6.549</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.leoko</groupId>
<artifactId>advancedban</artifactId>
<version>2.1.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>

View File

@ -6,6 +6,7 @@ import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.pluginbridge.plan.aac.AdvancedAntiCheatHook;
import com.djrapitops.pluginbridge.plan.advancedachievements.AdvancedAchievementsHook;
import com.djrapitops.pluginbridge.plan.advancedban.AdvancedBanHook;
import com.djrapitops.pluginbridge.plan.askyblock.ASkyBlockHook;
import com.djrapitops.pluginbridge.plan.banmanager.BanManagerHook;
import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook;
@ -64,13 +65,16 @@ public class Bridge {
}
private static Hook[] getBungeeHooks(HookHandler h) {
return new Hook[0];
return new Hook[]{
new AdvancedBanHook(h)
};
}
private static Hook[] getBukkitHooks(HookHandler h) {
return new Hook[]{
new AdvancedAntiCheatHook(h),
new AdvancedAchievementsHook(h),
new AdvancedBanHook(h),
new ASkyBlockHook(h),
new BanManagerHook(h),
new BuyCraftHook(h),

View File

@ -2,9 +2,6 @@ package com.djrapitops.pluginbridge.plan;
import com.djrapitops.plan.data.plugin.HookHandler;
import com.djrapitops.plan.data.plugin.PluginData;
import org.bukkit.plugin.java.JavaPlugin;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
* Abstract class for easy hooking of plugins.
@ -35,11 +32,9 @@ public abstract class Hook {
public Hook(String plugin, HookHandler hookHandler) {
this.hookHandler = hookHandler;
try {
Class<?> givenClass = Class.forName(plugin);
Class<? extends JavaPlugin> pluginClass = (Class<? extends JavaPlugin>) givenClass;
JavaPlugin hookedPlugin = getPlugin(pluginClass);
enabled = hookedPlugin.isEnabled();
} catch (NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError | Exception e) {
Class.forName(plugin);
enabled = true;
} catch (Exception e) {
enabled = false;
}
}

View File

@ -0,0 +1,105 @@
/*
* 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.advancedban;
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.plugin.ContainerSize;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.data.store.keys.AnalysisKeys;
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 com.djrapitops.plan.utilities.html.icon.Icons;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.Collection;
import java.util.HashMap;
import java.util.UUID;
import me.leoko.advancedban.manager.PunishmentManager;
import me.leoko.advancedban.manager.UUIDManager;
import me.leoko.advancedban.utils.Punishment;
import me.leoko.advancedban.utils.PunishmentType;
/**
* PluginData for AdvancedBan plugin.
*
* @author Vankka
*/
public class AdvancedBanData extends PluginData {
public AdvancedBanData() {
super(ContainerSize.THIRD, "AdvancedBan");
setPluginIcon(Icons.BANNED);
}
@Override
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) {
String abUuid = uuid.toString().replace("-", "");
if (uuid.version() == 3) { // Cracked / Offline UUID
return inspectContainer;
}
Punishment ban = PunishmentManager.get().getBan(abUuid);
Punishment mute = PunishmentManager.get().getMute(abUuid);
long warnings = PunishmentManager.get().getWarns(abUuid).stream().filter(warning -> !warning.isExpired()).count();
inspectContainer.addValue(getWithIcon("Banned", Icons.BANNED), ban != null ? "Yes" : "No");
inspectContainer.addValue(getWithIcon("Muted", Icon.called("bell-slash").of(Color.DEEP_ORANGE)), mute != null ? "Yes" : "No");
inspectContainer.addValue(getWithIcon("Warnings", Icon.called("flag").of(Color.YELLOW)), warnings);
if (ban != null) {
String operator = ban.getOperator();
String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(operator), operator);
String reason = HtmlUtils.swapColorsToSpan(ban.getReason());
long start = ban.getStart();
String end = FormatUtils.formatTimeStampYear(ban.getEnd());
if (ban.getType() == PunishmentType.BAN || ban.getType() == PunishmentType.IP_BAN) { // Permanent
end = "Permanent ban";
}
if (operator.equals("CONSOLE")) {
link = "CONSOLE";
}
inspectContainer.addValue("&nbsp;" + getWithIcon("Operator", Icon.called("user").of(Color.RED)), link);
inspectContainer.addValue("&nbsp;" + getWithIcon("Date", Icon.called("calendar").of(Color.RED).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(start));
inspectContainer.addValue("&nbsp;" + getWithIcon("Ends", Icon.called("calendar-check").of(Color.RED).of(Family.REGULAR)), end);
inspectContainer.addValue("&nbsp;" + getWithIcon("Reason", Icon.called("comment").of(Color.RED).of(Family.REGULAR)), reason);
}
if (mute != null) {
String operator = mute.getOperator();
String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(operator), operator);
String reason = HtmlUtils.swapColorsToSpan(mute.getReason());
long start = mute.getStart();
String end = FormatUtils.formatTimeStampYear(mute.getEnd());
if (mute.getType() == PunishmentType.MUTE) { // Permanent
end = "Permanent mute";
}
if (operator.equals("CONSOLE")) {
link = "CONSOLE";
}
inspectContainer.addValue("&nbsp;" + getWithIcon("Operator", Icon.called("user").of(Color.DEEP_ORANGE)), link);
inspectContainer.addValue("&nbsp;" + getWithIcon("Date", Icon.called("calendar").of(Color.DEEP_ORANGE).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(start));
inspectContainer.addValue("&nbsp;" + getWithIcon("Ends", Icon.called("calendar-check").of(Color.DEEP_ORANGE).of(Family.REGULAR)), end);
inspectContainer.addValue("&nbsp;" + getWithIcon("Reason", Icon.called("comment").of(Color.DEEP_ORANGE).of(Family.REGULAR)), reason);
}
return inspectContainer;
}
@Override
public AnalysisContainer getServerData(Collection<UUID> uuids, AnalysisContainer analysisContainer) {
return analysisContainer;
}
}

View File

@ -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.advancedban;
import com.djrapitops.pluginbridge.plan.Hook;
import com.djrapitops.plan.data.plugin.HookHandler;
/**
* Hook for AdvancedBan plugin.
*
* @author Vankka
*/
public class AdvancedBanHook extends Hook {
public AdvancedBanHook(HookHandler hookHandler) {
super("me.leoko.advancedban.Universal", hookHandler);
}
@Override
public void hook() throws NoClassDefFoundError {
if (enabled) {
addPluginDataSource(new AdvancedBanData());
}
}
}