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);
+ }
+}
\ No newline at end of file
diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java
index 4da7cdffc..ad8af1497 100644
--- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java
+++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java
@@ -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("### DataContainer Cache:
");
-
- content.append("Key | Is Cached | Cache Time
")
- .append("-- | -- | --
");
- Formatter timeStamp = Formatters.yearLongValue();
- Set> dataContainers = CacheSystem.getInstance().getDataContainerCache().getMap().entrySet();
- if (dataContainers.isEmpty()) {
- content.append("Empty");
- }
- for (Map.Entry 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("
");
- } else {
- content.append(keyName).append(" | ").append("Non-caching Supplier").append(" | ").append("-").append("
");
- }
- }
- content.append("
");
- } catch (Exception e) {
- Log.toLog(this.getClass(), e);
- }
- }
-
private String createConfigContent() {
StringBuilder content = new StringBuilder();
appendConfig(content);
diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java
index 6312d31f4..506626182 100644
--- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java
+++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java
@@ -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");
}
diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java
index 00cbc8ee9..b50ebd4e4 100644
--- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java
+++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java
@@ -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;
}
diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java
index 327048f5a..15c2cd6c3 100644
--- a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java
+++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java
@@ -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.");
}
}
diff --git a/Plan/src/main/resources/bungee.yml b/Plan/src/main/resources/bungee.yml
index 3d5049815..365f2b64d 100644
--- a/Plan/src/main/resources/bungee.yml
+++ b/Plan/src/main/resources/bungee.yml
@@ -1,4 +1,4 @@
name: Plan
author: Rsl1122
main: com.djrapitops.plan.PlanBungee
-version: 4.4.3
\ No newline at end of file
+version: 4.4.4
\ No newline at end of file
diff --git a/Plan/src/main/resources/bungeeconfig.yml b/Plan/src/main/resources/bungeeconfig.yml
index 0e4be559d..02d582993 100644
--- a/Plan/src/main/resources/bungeeconfig.yml
+++ b/Plan/src/main/resources/bungeeconfig.yml
@@ -67,6 +67,9 @@ Data:
LogUnknownCommands: false
CombineCommandAliases: true
Geolocations: true
+ Ping:
+ ServerEnableDelaySeconds: 300
+ PlayerLoginDelaySeconds: 30
KeepInactivePlayerDataForDays: 180
# -----------------------------------------------------
Customization:
diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml
index be15fa519..266672566 100644
--- a/Plan/src/main/resources/config.yml
+++ b/Plan/src/main/resources/config.yml
@@ -81,6 +81,9 @@ Data:
LogUnknownCommands: false
CombineCommandAliases: true
Geolocations: true
+ Ping:
+ ServerEnableDelaySeconds: 300
+ PlayerLoginDelaySeconds: 30
KeepInactivePlayerDataForDays: 180
# -----------------------------------------------------
Customization:
diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml
index a13aacbab..8583e4134 100644
--- a/Plan/src/main/resources/plugin.yml
+++ b/Plan/src/main/resources/plugin.yml
@@ -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:
diff --git a/Plan/src/main/resources/web/server.html b/Plan/src/main/resources/web/server.html
index 17a79e9e8..5438fa41a 100644
--- a/Plan/src/main/resources/web/server.html
+++ b/Plan/src/main/resources/web/server.html
@@ -1148,9 +1148,9 @@
-
-
-
+
+
+
diff --git a/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java b/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java
index 50e45a227..7316387ab 100644
--- a/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java
+++ b/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java
@@ -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 result = SessionCache.getCachedSession(uuid);
+ assertTrue(result.isPresent());
+ assertEquals(expected, result.get());
+ }
}
\ No newline at end of file
diff --git a/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java b/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java
new file mode 100644
index 000000000..ba7c40523
--- /dev/null
+++ b/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java
@@ -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> 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 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);
+ }
+}
\ No newline at end of file
diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/analysis/MedianTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/analysis/MedianTest.java
new file mode 100644
index 000000000..50a0a3656
--- /dev/null
+++ b/Plan/src/test/java/com/djrapitops/plan/utilities/analysis/MedianTest.java
@@ -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 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 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 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 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 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 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);
+ }
+
+}
\ No newline at end of file
diff --git a/PlanPluginBridge/pom.xml b/PlanPluginBridge/pom.xml
index e588a00d0..cc4e6edba 100644
--- a/PlanPluginBridge/pom.xml
+++ b/PlanPluginBridge/pom.xml
@@ -129,7 +129,7 @@
com.gmail.nossr50
- mcmmo
+ mcMMO
1.5.07
provided
@@ -161,7 +161,7 @@
net.kaikk.mc
GriefPreventionPlus
- RELEASE
+ 13.3
provided
@@ -230,6 +230,12 @@
6.549
provided
+
+ me.leoko
+ advancedban
+ 2.1.5
+ provided
+
${project.artifactId}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java
index a29c66bea..809783300 100644
--- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java
@@ -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),
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java
index 8abe4ff9b..16f600f53 100644
--- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java
@@ -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;
}
}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java
new file mode 100644
index 000000000..31f4bfae2
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java
@@ -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(" " + getWithIcon("Operator", Icon.called("user").of(Color.RED)), link);
+ inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.RED).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(start));
+ inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.RED).of(Family.REGULAR)), end);
+ inspectContainer.addValue(" " + 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(" " + getWithIcon("Operator", Icon.called("user").of(Color.DEEP_ORANGE)), link);
+ inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.DEEP_ORANGE).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(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);
+ }
+
+ return inspectContainer;
+ }
+
+ @Override
+ public AnalysisContainer getServerData(Collection uuids, AnalysisContainer analysisContainer) {
+ return analysisContainer;
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java
new file mode 100644
index 000000000..b118ce1f4
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java
@@ -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());
+ }
+ }
+}