diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java
index 9671bbe49..bf952f6ed 100644
--- a/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java
+++ b/Plan/src/main/java/com/djrapitops/plan/ui/tables/SortablePlayersTableCreator.java
@@ -27,48 +27,31 @@ public class SortablePlayersTableCreator {
Benchmark.start("Create Players table " + data.size());
StringBuilder html = new StringBuilder();
long now = MiscUtils.getTime();
- boolean showImages = Settings.PLAYERLIST_SHOW_IMAGES.isTrue() && data.size() < 3000;
- if (data.size() < 3000) {
- for (UserData uData : data) {
- try {
- String banOunknownOactiveOinactive = uData.isBanned() ? Html.GRAPH_BANNED.parse()
- : uData.getLoginTimes() == 1 ? Html.GRAPH_UNKNOWN.parse()
- : AnalysisUtils.isActive(now, uData.getLastPlayed(), uData.getPlayTime(), uData.getLoginTimes()) ? Html.GRAPH_ACTIVE.parse()
- : Html.GRAPH_INACTIVE.parse();
- String img = showImages ? Html.MINOTAR_SMALL_IMG.parse(uData.getName()) : "";
- html.append(Html.TABLELINE_PLAYERS.parse(
- img + Html.LINK.parse(HtmlUtils.getInspectUrl(uData.getName()), uData.getName()),
- banOunknownOactiveOinactive,
- uData.getPlayTime() + "", FormatUtils.formatTimeAmount(uData.getPlayTime()),
- uData.getLoginTimes() + "",
- uData.getRegistered() + "", FormatUtils.formatTimeStampYear(uData.getRegistered()),
- uData.getLastPlayed() + "", FormatUtils.formatTimeStamp(uData.getLastPlayed()),
- uData.getDemData().getGeoLocation()
- ));
- } catch (NullPointerException e) {
- }
+ boolean showImages = Settings.PLAYERLIST_SHOW_IMAGES.isTrue();
+ int i = 0;
+ Collections.sort(data, new UserDataLastPlayedComparator());
+ for (UserData uData : data) {
+ if (i >= 1500) {
+ break;
}
- } else {
- Collections.sort(data, new UserDataLastPlayedComparator());
- int i = 0;
- for (UserData uData : data) {
- if (i >= 3000) {
- break;
- }
- try {
- html.append(Html.TABLELINE_PLAYERS.parse(
- Html.LINK.parse(HtmlUtils.getInspectUrl(uData.getName()), uData.getName()),
- "",
- "",
- "",
- uData.getRegistered() + "", FormatUtils.formatTimeStampYear(uData.getRegistered()),
- uData.getLastPlayed() + "", FormatUtils.formatTimeStamp(uData.getLastPlayed()),
- uData.getDemData().getGeoLocation()
- ));
- } catch (NullPointerException e) {
- }
- i++;
+ try {
+ String banOunknownOactiveOinactive = uData.isBanned() ? Html.GRAPH_BANNED.parse()
+ : uData.getLoginTimes() == 1 ? Html.GRAPH_UNKNOWN.parse()
+ : AnalysisUtils.isActive(now, uData.getLastPlayed(), uData.getPlayTime(), uData.getLoginTimes()) ? Html.GRAPH_ACTIVE.parse()
+ : Html.GRAPH_INACTIVE.parse();
+ String img = showImages ? Html.MINOTAR_SMALL_IMG.parse(uData.getName()) : "";
+ html.append(Html.TABLELINE_PLAYERS.parse(
+ img + Html.LINK.parse(HtmlUtils.getInspectUrl(uData.getName()), uData.getName()),
+ banOunknownOactiveOinactive,
+ uData.getPlayTime() + "", FormatUtils.formatTimeAmount(uData.getPlayTime()),
+ uData.getLoginTimes() + "",
+ uData.getRegistered() + "", FormatUtils.formatTimeStampYear(uData.getRegistered()),
+ uData.getLastPlayed() + "", FormatUtils.formatTimeStamp(uData.getLastPlayed()),
+ uData.getDemData().getGeoLocation()
+ ));
+ } catch (NullPointerException e) {
}
+ i++;
}
Benchmark.stop("Create Players table " + data.size());
return html.toString();
diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml
index b714dfd6c..816070e02 100644
--- a/Plan/src/main/resources/plugin.yml
+++ b/Plan/src/main/resources/plugin.yml
@@ -14,6 +14,9 @@ softdepend:
- Jobs
- ASkyBlock
- GriefPrevention
+- LiteBans
+- SuperbVote
+- ViaVersion
commands:
plan:
diff --git a/PlanPluginBridge/pom.xml b/PlanPluginBridge/pom.xml
index 3bcec5f71..21b5fc741 100644
--- a/PlanPluginBridge/pom.xml
+++ b/PlanPluginBridge/pom.xml
@@ -14,6 +14,10 @@
jitpack.io
https://jitpack.io
+
+ viaversion-repo
+ https://repo.viaversion.com
+
@@ -89,11 +93,28 @@
provided
- com.github.TechFortress
- GriefPrevention
- 16.7.1
+ com.github.TechFortress
+ GriefPrevention
+ 16.7.1
provided
-
+
+
+ litebans
+ api
+ 0.2
+ provided
+
+
+ io.minimum
+ minecraft.superbvote
+ 0.3.4
+ provided
+
+
+ us.myles
+ viaversion
+ 1.1.1
+
UTF-8
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 fbc4804da..b1d7d6dfa 100644
--- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java
@@ -1,19 +1,18 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
package com.djrapitops.pluginbridge.plan;
import com.djrapitops.pluginbridge.plan.advancedachievements.AdvancedAchievementsHook;
import com.djrapitops.pluginbridge.plan.askyblock.ASkyBlockHook;
import com.djrapitops.pluginbridge.plan.essentials.EssentialsHook;
import com.djrapitops.pluginbridge.plan.factions.FactionsHook;
+import com.djrapitops.pluginbridge.plan.griefprevention.GriefPreventionHook;
import com.djrapitops.pluginbridge.plan.jobs.JobsHook;
+import com.djrapitops.pluginbridge.plan.litebans.LiteBansHook;
import com.djrapitops.pluginbridge.plan.mcmmo.McmmoHook;
import com.djrapitops.pluginbridge.plan.ontime.OnTimeHook;
+import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook;
import com.djrapitops.pluginbridge.plan.towny.TownyHook;
import com.djrapitops.pluginbridge.plan.vault.VaultHook;
+import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionHook;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
/**
@@ -59,5 +58,21 @@ public class Bridge {
ASkyBlockHook askyblockHook = new ASkyBlockHook(handler);
} catch (NoClassDefFoundError e) {
}
+ try {
+ GriefPreventionHook griefPrevHook = new GriefPreventionHook(handler);
+ } catch (NoClassDefFoundError e) {
+ }
+ try {
+ LiteBansHook hook = new LiteBansHook(handler);
+ } catch (NoClassDefFoundError e) {
+ }
+ try {
+ SuperbVoteHook hook = new SuperbVoteHook(handler);
+ } catch (NoClassDefFoundError e) {
+ }
+ try {
+ ViaVersionHook hook = new ViaVersionHook(handler);
+ } catch (NoClassDefFoundError e) {
+ }
}
}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionClaimTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionClaimTable.java
index 3a144b3c5..db157df0d 100644
--- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionClaimTable.java
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/griefprevention/GriefPreventionClaimTable.java
@@ -27,7 +27,7 @@ public class GriefPreventionClaimTable extends PluginData {
this.dataStore = dataStore;
String location = Html.FONT_AWESOME_ICON.parse("map-marker") + " Location";
String size = Html.FONT_AWESOME_ICON.parse("map-o") + " Area";
- super.setPrefix(Html.TABLE_START_3.parse(location, size));
+ super.setPrefix(Html.TABLE_START_2.parse(location, size));
super.setSuffix(Html.TABLE_END.parse());
}
@@ -48,7 +48,7 @@ public class GriefPreventionClaimTable extends PluginData {
.forEach(claim -> {
String location = FormattingUtils.formatLocation(claim.getGreaterBoundaryCorner());
String area = claim.getArea() + "";
- html.append(Html.TABLELINE_3.parse(location, area));
+ html.append(Html.TABLELINE_2.parse(location, area));
});
return html.toString();
}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/BanObject.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/BanObject.java
new file mode 100644
index 000000000..82ca2394b
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/BanObject.java
@@ -0,0 +1,38 @@
+package com.djrapitops.pluginbridge.plan.litebans;
+
+import java.util.UUID;
+
+/**
+ * Class representing LiteBans database data about a ban.
+ *
+ * @author Rsl1122
+ */
+public class BanObject {
+ private final UUID uuid;
+ private final String reason;
+ private final String bannedBy;
+ private final long expires;
+
+ public BanObject(UUID uuid, String reason, String bannedBy, long expires) {
+ this.uuid = uuid;
+ this.reason = reason;
+ this.bannedBy = bannedBy;
+ this.expires = expires;
+ }
+
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public String getBannedBy() {
+ return bannedBy;
+ }
+
+ public long getExpiry() {
+ return expires;
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansBansTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansBansTable.java
new file mode 100644
index 000000000..f65a3ae87
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansBansTable.java
@@ -0,0 +1,81 @@
+package com.djrapitops.pluginbridge.plan.litebans;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.Plan;
+import main.java.com.djrapitops.plan.data.UserData;
+import main.java.com.djrapitops.plan.data.additional.AnalysisType;
+import main.java.com.djrapitops.plan.data.additional.PluginData;
+import main.java.com.djrapitops.plan.ui.Html;
+import main.java.com.djrapitops.plan.utilities.FormatUtils;
+import main.java.com.djrapitops.plan.utilities.HtmlUtils;
+
+/**
+ * PluginData class for LiteBans-plugin.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class LiteBansBansTable extends PluginData {
+
+ private final LiteBansDatabaseQueries db;
+
+ /**
+ * Class Constructor, sets the parameters of the PluginData object.
+ *
+ * @param database Database class for queries
+ */
+ public LiteBansBansTable(LiteBansDatabaseQueries database) {
+ super("LiteBans", "bantable", AnalysisType.HTML);
+ db = database;
+ String banned = Html.FONT_AWESOME_ICON.parse("ban") + " Banned";
+ String by = Html.FONT_AWESOME_ICON.parse("gavel") + " Banned By";
+ String reason = Html.FONT_AWESOME_ICON.parse("balance-scale") + " Reason";
+ String date = Html.FONT_AWESOME_ICON.parse("calendar-times-o") + " Expires";
+ super.setPrefix(Html.TABLELINE_4.parse(banned, by, reason, date));
+ super.setSuffix(Html.TABLE_END.parse());
+ }
+
+ @Override
+ public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
+ return parseContainer("", getTableLines());
+ }
+
+ @Override
+ public Serializable getValue(UUID uuid) {
+ return -1;
+ }
+
+ private String getTableLines() {
+ StringBuilder html = new StringBuilder();
+ try {
+ List bans = db.getBans();
+ Map users = Plan.getPlanAPI().getInspectCachedUserDataMap();
+ for (BanObject ban : bans) {
+ UUID uuid = ban.getUuid();
+ UserData userData = users.get(uuid);
+ if (userData == null) {
+ continue;
+ }
+ String name = userData.getName();
+ String tableLine = "REPLACE0 | REPLACE1 | REPLACE2 | REPLACE4 |
";
+ long expiry = ban.getExpiry();
+ String expires = expiry <= 0 ? "Never" : FormatUtils.formatTimeStampSecond(expiry);
+ html.append(tableLine
+ .replace("REPLACE0", Html.LINK.parse(HtmlUtils.getInspectUrl(name), name))
+ .replace("REPLACE1", Html.LINK.parse(HtmlUtils.getInspectUrl(ban.getBannedBy()), ban.getBannedBy()))
+ .replace("REPLACE2", ban.getReason())
+ .replace("REPLACE3", expiry <= 0 ? "0" : expiry + "")
+ .replace("REPLACE4", expires
+ )
+ );
+ }
+ } catch (SQLException ex) {
+ html.append(Html.TABLELINE_4.parse(ex.toString(), "", "", ""));
+ }
+ return html.toString();
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansDatabaseQueries.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansDatabaseQueries.java
new file mode 100644
index 000000000..565c78090
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansDatabaseQueries.java
@@ -0,0 +1,76 @@
+package com.djrapitops.pluginbridge.plan.litebans;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import litebans.api.Database;
+import main.java.com.djrapitops.plan.database.tables.Table;
+
+/**
+ * Class responsible for making queries to LiteBans database.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class LiteBansDatabaseQueries extends Table{
+ private final Database database;
+
+ public LiteBansDatabaseQueries() {
+ super("litebans", null, false);
+ database = Database.get();
+ }
+
+ public List getBans() throws SQLException {
+ PreparedStatement statement = null;
+ ResultSet set = null;
+ try {
+ statement = database.prepareStatement("SELECT uuid, reason, banned_by_name, until FROM litebans_bans");
+ set = statement.executeQuery();
+ List bans = new ArrayList<>();
+ while (set.next()) {
+ String uuidS = set.getString("uuid");
+ UUID uuid = UUID.fromString(uuidS);
+ String reason = set.getString("reason");
+ String bannedBy = set.getString("banned_by_name");
+ long time = set.getLong("until");
+ bans.add(new BanObject(uuid, reason, bannedBy, time));
+ }
+ return bans;
+ } finally {
+ close(set);
+ close(statement);
+ }
+ }
+
+ public List getBans(UUID playerUUID) throws SQLException {
+ PreparedStatement statement = null;
+ ResultSet set = null;
+ try {
+ statement = database.prepareStatement("SELECT uuid, reason, banned_by_name, until FROM litebans_bans WHERE uuid=?");
+ statement.setString(1, playerUUID.toString());
+ set = statement.executeQuery();
+ List bans = new ArrayList<>();
+ while (set.next()) {
+ String uuidS = set.getString("uuid");
+ UUID uuid = UUID.fromString(uuidS);
+ String reason = set.getString("reason");
+ String bannedBy = set.getString("banned_by_name");
+ long time = set.getLong("until");
+ bans.add(new BanObject(uuid, reason, bannedBy, time));
+ }
+ return bans;
+ } finally {
+ close(set);
+ close(statement);
+ }
+ }
+
+ @Override
+ @Deprecated
+ public boolean createTable() {
+ return false;
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansHook.java
new file mode 100644
index 000000000..92b5a9aaf
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansHook.java
@@ -0,0 +1,40 @@
+package com.djrapitops.pluginbridge.plan.litebans;
+
+import com.djrapitops.pluginbridge.plan.Hook;
+import litebans.api.Database;
+import main.java.com.djrapitops.plan.api.API;
+import main.java.com.djrapitops.plan.data.additional.HookHandler;
+
+/**
+ * A Class responsible for hooking to LiteBans and registering data
+ * sources.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class LiteBansHook extends Hook {
+
+ /**
+ * Hooks the plugin and registers it's PluginData objects.
+ *
+ * API#addPluginDataSource uses the same method from HookHandler.
+ *
+ * @param hookH HookHandler instance for registering the data sources.
+ * @see API
+ * @throws NoClassDefFoundError when the plugin class can not be found.
+ */
+ public LiteBansHook(HookHandler hookH) throws NoClassDefFoundError {
+ super();
+ try {
+ Database.get();
+ enabled = true;
+ } catch (Throwable e) {
+ enabled = false;
+ }
+ if (enabled) {
+ LiteBansDatabaseQueries db = new LiteBansDatabaseQueries();
+ hookH.addPluginDataSource(new LiteBansBansTable(db));
+ hookH.addPluginDataSource(new LiteBansInspectBansTable(db));
+ }
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansInspectBansTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansInspectBansTable.java
new file mode 100644
index 000000000..07858ea81
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansInspectBansTable.java
@@ -0,0 +1,70 @@
+package com.djrapitops.pluginbridge.plan.litebans;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.data.additional.PluginData;
+import main.java.com.djrapitops.plan.ui.Html;
+import main.java.com.djrapitops.plan.utilities.FormatUtils;
+import main.java.com.djrapitops.plan.utilities.HtmlUtils;
+
+/**
+ * PluginData class for LiteBans-plugin.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class LiteBansInspectBansTable extends PluginData {
+
+ private final LiteBansDatabaseQueries db;
+
+ /**
+ * Class Constructor, sets the parameters of the PluginData object.
+ *
+ * @param database Database class for queries
+ */
+ public LiteBansInspectBansTable(LiteBansDatabaseQueries database) {
+ super("LiteBans", "inspect_banned");
+ db = database;
+ String by = Html.FONT_AWESOME_ICON.parse("gavel") + " Banned By";
+ String reason = Html.FONT_AWESOME_ICON.parse("balance-scale") + " Reason";
+ String date = Html.FONT_AWESOME_ICON.parse("calendar-times-o") + " Expires";
+ super.setPrefix(Html.TABLELINE_3.parse(date, by, reason));
+ super.setSuffix(Html.TABLE_END.parse());
+ }
+
+ @Override
+ public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
+ return parseContainer("", getTableLines(uuid));
+ }
+
+ @Override
+ public Serializable getValue(UUID uuid) {
+ return -1;
+ }
+
+ private String getTableLines(UUID uuid) {
+ StringBuilder html = new StringBuilder();
+ try {
+ List bans = db.getBans(uuid);
+ if (bans.isEmpty()) {
+ html.append(Html.TABLELINE_3.parse("Not LiteBanned", "", ""));
+ } else {
+ for (BanObject ban : bans) {
+ long expiry = ban.getExpiry();
+ String expires = expiry <= 0 ? "Never" : FormatUtils.formatTimeStampSecond(expiry);
+ html.append(Html.TABLELINE_3_CUSTOMKEY_1.parse(
+ expiry <= 0 ? "0" : expiry + "",
+ expires,
+ Html.LINK.parse(HtmlUtils.getInspectUrl(ban.getBannedBy()), ban.getBannedBy()),
+ ban.getReason())
+ );
+ }
+ }
+ } catch (SQLException ex) {
+ html.append(Html.TABLELINE_3.parse(ex.toString(), "", ""));
+ }
+ return html.toString();
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/ontime/OntimeReferMonth.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/ontime/OntimeReferMonth.java
index bcc0be02b..82b1a07c1 100644
--- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/ontime/OntimeReferMonth.java
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/ontime/OntimeReferMonth.java
@@ -1,16 +1,12 @@
package com.djrapitops.pluginbridge.plan.ontime;
-import com.djrapitops.pluginbridge.plan.FakeOfflinePlayer;
import java.io.Serializable;
-import java.util.Arrays;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
-import static org.bukkit.Bukkit.getOfflinePlayer;
-import org.bukkit.OfflinePlayer;
/**
* PluginData class for Ontime-plugin.
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteHook.java
new file mode 100644
index 000000000..e18333330
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteHook.java
@@ -0,0 +1,35 @@
+package com.djrapitops.pluginbridge.plan.superbvote;
+
+import com.djrapitops.pluginbridge.plan.Hook;
+import io.minimum.minecraft.superbvote.SuperbVote;
+import io.minimum.minecraft.superbvote.storage.VoteStorage;
+import main.java.com.djrapitops.plan.api.API;
+import main.java.com.djrapitops.plan.data.additional.HookHandler;
+import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
+
+/**
+ * A Class responsible for hooking to SuperbVote and registering data
+ * sources.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class SuperbVoteHook extends Hook {
+
+ /**
+ * Hooks the plugin and registers it's PluginData objects.
+ *
+ * API#addPluginDataSource uses the same method from HookHandler.
+ *
+ * @param hookH HookHandler instance for registering the data sources.
+ * @see API
+ * @throws NoClassDefFoundError when the plugin class can not be found.
+ */
+ public SuperbVoteHook(HookHandler hookH) throws NoClassDefFoundError {
+ super("io.minimum.minecraft.superbvote.SuperbVote");
+ if (enabled) {
+ VoteStorage store = getPlugin(SuperbVote.class).getVoteStorage();
+ hookH.addPluginDataSource(null);
+ }
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteVotes.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteVotes.java
new file mode 100644
index 000000000..7770494a2
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteVotes.java
@@ -0,0 +1,42 @@
+package com.djrapitops.pluginbridge.plan.superbvote;
+
+import io.minimum.minecraft.superbvote.storage.VoteStorage;
+import java.io.Serializable;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.data.additional.AnalysisType;
+import main.java.com.djrapitops.plan.data.additional.PluginData;
+
+/**
+ * PluginData class for GriefPrevention-plugin.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class SuperbVoteVotes extends PluginData {
+
+ private final VoteStorage store;
+
+ /**
+ * Class Constructor, sets the parameters of the PluginData object.
+ *
+ * @param store VoteStorage of SuperbVote
+ */
+ public SuperbVoteVotes(VoteStorage store) {
+ super("SuperbVote", "votes", new AnalysisType[]{AnalysisType.INT_TOTAL, AnalysisType.INT_AVG});
+ this.store = store;
+ super.setAnalysisOnly(false);
+ super.setIcon("check");
+ super.setPrefix("Votes: ");
+ }
+
+ @Override
+ public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
+ int votes = store.getVotes(uuid);
+ return parseContainer(modifierPrefix, votes+"");
+ }
+
+ @Override
+ public Serializable getValue(UUID uuid) {
+ return store.getVotes(uuid);
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteVotesTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteVotesTable.java
new file mode 100644
index 000000000..6fd5a01f9
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/superbvote/SuperbVoteVotesTable.java
@@ -0,0 +1,59 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.djrapitops.pluginbridge.plan.superbvote;
+
+import io.minimum.minecraft.superbvote.storage.VoteStorage;
+import java.io.Serializable;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.Plan;
+import main.java.com.djrapitops.plan.data.additional.AnalysisType;
+import main.java.com.djrapitops.plan.data.additional.PluginData;
+import main.java.com.djrapitops.plan.ui.Html;
+import main.java.com.djrapitops.plan.utilities.FormatUtils;
+import main.java.com.djrapitops.plan.utilities.HtmlUtils;
+
+/**
+ * PluginData class for Vault-plugin.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class SuperbVoteVotesTable extends PluginData {
+
+ private final VoteStorage store;
+
+ public SuperbVoteVotesTable(VoteStorage store) {
+ super("SuperbVote", "votetable", AnalysisType.HTML);
+ this.store = store;
+ String user = Html.FONT_AWESOME_ICON.parse("user") + " Player";
+ String votes = Html.FONT_AWESOME_ICON.parse("check") + " Votes";
+ super.setPrefix(Html.TABLE_START_2.parse(user, votes));
+ super.setSuffix(Html.TABLE_END.parse());
+ }
+
+ @Override
+ public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
+ String tableLines = getTableLines();
+ return parseContainer("", tableLines);
+ }
+
+ @Override
+ public Serializable getValue(UUID uuid) {
+ return -1;
+ }
+
+ private String getTableLines() {
+ StringBuilder html = new StringBuilder();
+ Plan.getPlanAPI().getInspectCachedUserData().stream()
+ .forEach(data -> {
+ String link = Html.LINK.parse(HtmlUtils.getInspectUrl(data.getName()), data.getName());
+ String bal = FormatUtils.cutDecimals(store.getVotes(data.getUuid()));
+ html.append(Html.TABLELINE_2.parse(link, bal));
+ });
+ return html.toString();
+ }
+
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/vault/EconomyBalance.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/vault/EconomyBalance.java
index df5c031b8..258f48cf4 100644
--- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/vault/EconomyBalance.java
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/vault/EconomyBalance.java
@@ -3,7 +3,6 @@ package com.djrapitops.pluginbridge.plan.vault;
import com.djrapitops.pluginbridge.plan.FakeOfflinePlayer;
import java.io.Serializable;
import java.util.UUID;
-import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/PlayerVersionListener.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/PlayerVersionListener.java
new file mode 100644
index 000000000..2a5f4537b
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/PlayerVersionListener.java
@@ -0,0 +1,56 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.djrapitops.pluginbridge.plan.viaversion;
+
+import java.sql.SQLException;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.Log;
+import main.java.com.djrapitops.plan.Plan;
+import main.java.com.djrapitops.plan.data.UserData;
+import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
+import main.java.com.djrapitops.plan.data.handling.info.InfoType;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import us.myles.ViaVersion.api.ViaAPI;
+
+/**
+ * Class responsible for listening join events for Version protocol.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class PlayerVersionListener implements Listener {
+
+ private final Plan plan;
+ private final ViaAPI viaAPI;
+ private final ProtocolTable table;
+
+ public PlayerVersionListener(Plan plan, ViaAPI viaAPI, ProtocolTable dbTable) {
+ this.plan = plan;
+ this.viaAPI = viaAPI;
+ this.table = dbTable;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void onPlayerLogin(PlayerJoinEvent event) {
+ UUID uuid = event.getPlayer().getUniqueId();
+ int playerVersion = viaAPI.getPlayerVersion(uuid);
+ HandlingInfo i = new HandlingInfo(uuid, InfoType.OTHER, 0) {
+ @Override
+ public boolean process(UserData uData) {
+ try {
+ table.saveProtocolVersion(uData.getUuid(), playerVersion);
+ } catch (SQLException ex) {
+ Log.toLog(this.getClass().getName(), ex);
+ }
+ return true;
+ }
+ };
+ plan.getHandler().addToPool(i);
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/Protocol.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/Protocol.java
new file mode 100644
index 000000000..e69866abf
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/Protocol.java
@@ -0,0 +1,47 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.djrapitops.pluginbridge.plan.viaversion;
+
+/**
+ * Contains static method for formatting protocol version into readable form.
+ *
+ * @author Rsl1122
+ */
+public class Protocol {
+
+ /**
+ * http://wiki.vg/Protocol_version_numbers
+ *
+ * @param protocolVersion ProtocolVersion
+ * @return Minecraft Version (estimate)
+ */
+ public static String getMCVersion(int protocolVersion) {
+ switch (protocolVersion) {
+ case 335:
+ return "1.12";
+ case 316:
+ return "1.11.2";
+ case 315:
+ return "1.11";
+ case 210:
+ return "1.10.2";
+ case 110:
+ return "1.9.4";
+ case 109:
+ return "1.9.2";
+ case 107:
+ return "1.9";
+ case 47:
+ return "1.8.9";
+ case 5:
+ return "1.7.10";
+ case 4:
+ return "1.7.5";
+ default:
+ return "Unknown ProtocolVersion: " + protocolVersion;
+ }
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ProtocolTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ProtocolTable.java
new file mode 100644
index 000000000..3a22f6aa7
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ProtocolTable.java
@@ -0,0 +1,138 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.djrapitops.pluginbridge.plan.viaversion;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.Log;
+import main.java.com.djrapitops.plan.database.databases.SQLDB;
+import main.java.com.djrapitops.plan.database.tables.Table;
+
+/**
+ * Class responsible for version protocol information in Plan database.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class ProtocolTable extends Table {
+
+ private final String columnUUID;
+ private final String columnProtocolVersion;
+
+ public ProtocolTable(SQLDB db) {
+ super("plan_viaversion_protocol", db, db.supportsModification());
+ columnUUID = "uuid";
+ columnProtocolVersion = "protocol_version";
+ }
+
+ @Override
+ public boolean createTable() {
+ try {
+ execute("CREATE TABLE IF NOT EXISTS " + tableName + " ("
+ + columnUUID + " varchar(36) NOT NULL UNIQUE, "
+ + columnProtocolVersion + " integer NOT NULL"
+ + ")"
+ );
+ return true;
+ } catch (SQLException ex) {
+ Log.toLog(this.getClass().getName(), ex);
+ return false;
+ }
+ }
+
+ public void saveProtocolVersion(UUID uuid, int version) throws SQLException {
+ if (exists(uuid)) {
+ updateProtocolVersion(uuid, version);
+ } else {
+ insertProtocolVerison(uuid, version);
+ }
+ }
+
+ public int getProtocolVersion(UUID uuid) throws SQLException {
+ PreparedStatement statement = null;
+ ResultSet set = null;
+ try {
+ statement = prepareStatement("SELECT " + columnProtocolVersion + " FROM " + tableName + " WHERE " + columnUUID + "=?");
+ statement.setString(1, uuid.toString());
+ set = statement.executeQuery();
+ if (set.next()) {
+ return set.getInt(columnProtocolVersion);
+ } else {
+ return -1;
+ }
+ } finally {
+ close(set);
+ close(statement);
+ }
+ }
+
+ public Map getProtocolVersions() throws SQLException {
+ PreparedStatement statement = null;
+ ResultSet set = null;
+ try {
+ statement = prepareStatement("SELECT * FROM " + tableName);
+ set = statement.executeQuery();
+ Map versions = new HashMap<>();
+ while (set.next()) {
+ String uuidS = set.getString(columnUUID);
+ UUID uuid = UUID.fromString(uuidS);
+ versions.put(uuid, set.getInt(columnProtocolVersion));
+ }
+ return versions;
+ } finally {
+ close(set);
+ close(statement);
+ }
+ }
+
+ private boolean exists(UUID uuid) throws SQLException {
+ PreparedStatement statement = null;
+ ResultSet set = null;
+ try {
+ statement = prepareStatement("SELECT " + columnUUID + " FROM " + tableName + " WHERE " + columnUUID + "=?");
+ statement.setString(1, uuid.toString());
+ set = statement.executeQuery();
+ return set.next();
+ } finally {
+ close(set);
+ close(statement);
+ }
+ }
+
+ private void updateProtocolVersion(UUID uuid, int version) throws SQLException {
+ PreparedStatement statement = null;
+ try {
+ statement = prepareStatement("UPDATE " + tableName + " SET "
+ + columnProtocolVersion + "=? "
+ + " WHERE (" + columnUUID + "=?)");
+ statement.setInt(1, version);
+ statement.setString(2, uuid.toString());
+ statement.execute();
+ } finally {
+ close(statement);
+ }
+ }
+
+ private void insertProtocolVerison(UUID uuid, int version) throws SQLException {
+ PreparedStatement statement = null;
+ try {
+ statement = prepareStatement(
+ "INSERT INTO " + tableName + " ("
+ + columnUUID + ", "
+ + columnProtocolVersion
+ + ") VALUES (?, ?)");
+ statement.setString(1, uuid.toString());
+ statement.setInt(2, version);
+ statement.execute();
+ } finally {
+ close(statement);
+ }
+ }
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionHook.java
new file mode 100644
index 000000000..b01a1c446
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionHook.java
@@ -0,0 +1,42 @@
+package com.djrapitops.pluginbridge.plan.viaversion;
+
+import com.djrapitops.pluginbridge.plan.Hook;
+import main.java.com.djrapitops.plan.Plan;
+import main.java.com.djrapitops.plan.data.additional.HookHandler;
+import main.java.com.djrapitops.plan.api.API;
+import main.java.com.djrapitops.plan.database.databases.SQLDB;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.ViaAPI;
+
+/**
+ * A Class responsible for hooking to ViaVersion and registering data sources.
+ *
+ * @author Rsl1122
+ * @since 3.1.0
+ */
+public class ViaVersionHook extends Hook {
+
+ /**
+ * Hooks the plugin and registers it's PluginData objects.
+ *
+ * API#addPluginDataSource uses the same method from HookHandler.
+ *
+ * @param hookH HookHandler instance for registering the data sources.
+ * @see API
+ * @throws NoClassDefFoundError when the plugin class can not be found.
+ */
+ public ViaVersionHook(HookHandler hookH) throws NoClassDefFoundError {
+ super("us.myles.ViaVersion.ViaVersionPlugin");
+ if (!enabled) {
+ return;
+ }
+ Plan plan = Plan.getInstance();
+ ViaAPI api = Via.getAPI();
+ ProtocolTable table = new ProtocolTable((SQLDB) plan.getDB());
+ table.createTable();
+ PlayerVersionListener l = new PlayerVersionListener(plan, api, table);
+ plan.registerListener(l);
+ hookH.addPluginDataSource(new ViaVersionVersionTable(table));
+ hookH.addPluginDataSource(new ViaVersionVersion(table));
+ }
+}
\ No newline at end of file
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionVersion.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionVersion.java
new file mode 100644
index 000000000..706691cd1
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionVersion.java
@@ -0,0 +1,67 @@
+package com.djrapitops.pluginbridge.plan.viaversion;
+
+import com.djrapitops.pluginbridge.plan.vault.*;
+import com.djrapitops.pluginbridge.plan.FakeOfflinePlayer;
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import main.java.com.djrapitops.plan.Log;
+import main.java.com.djrapitops.plan.Plan;
+import main.java.com.djrapitops.plan.data.UserData;
+import main.java.com.djrapitops.plan.data.additional.AnalysisType;
+import main.java.com.djrapitops.plan.data.additional.PluginData;
+import main.java.com.djrapitops.plan.utilities.FormatUtils;
+import net.milkbowl.vault.economy.Economy;
+import static org.bukkit.Bukkit.getOfflinePlayer;
+import org.bukkit.OfflinePlayer;
+
+/**
+ * PluginData class for Vault-plugin.
+ *
+ * Registered to the plugin by VaultHook
+ *
+ * Gives Total Balance Double as value.
+ *
+ * @author Rsl1122
+ * @since 3.1.0
+ * @see VaultHook
+ */
+public class ViaVersionVersion extends PluginData {
+
+ private final ProtocolTable table;
+
+ /**
+ * Class Constructor, sets the parameters of the PluginData object.
+ *
+ * @param table ProtocolTable where protocol versions are stored.
+ */
+ public ViaVersionVersion(ProtocolTable table) {
+ super("ViaVersion", "version");
+ this.table = table;
+ super.setAnalysisOnly(false);
+ super.setIcon("signal");
+ super.setPrefix("Last Join Version: ");
+ }
+
+ @Override
+ public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
+ try {
+ int protocolVersion = table.getProtocolVersion(uuid);
+ if (protocolVersion == -1) {
+ parseContainer(modifierPrefix, "Not Yet Known");
+ }
+ return parseContainer(modifierPrefix, Protocol.getMCVersion(protocolVersion));
+ } catch (SQLException ex) {
+ Log.toLog(this.getClass().getName(), ex);
+ return parseContainer(modifierPrefix, ex.toString());
+ }
+ }
+
+ @Override
+ public Serializable getValue(UUID uuid) {
+ return -1;
+ }
+
+}
diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionVersionTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionVersionTable.java
new file mode 100644
index 000000000..dced87544
--- /dev/null
+++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/viaversion/ViaVersionVersionTable.java
@@ -0,0 +1,75 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.djrapitops.pluginbridge.plan.viaversion;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import main.java.com.djrapitops.plan.data.additional.AnalysisType;
+import main.java.com.djrapitops.plan.data.additional.PluginData;
+import main.java.com.djrapitops.plan.ui.Html;
+
+/**
+ * PluginData class for Vault-plugin.
+ *
+ * @author Rsl1122
+ * @since 3.5.0
+ */
+public class ViaVersionVersionTable extends PluginData {
+
+ private final ProtocolTable table;
+
+ public ViaVersionVersionTable(ProtocolTable table) {
+ super("ViaVersion", "versiontable", AnalysisType.HTML);
+ this.table = table;
+ String version = Html.FONT_AWESOME_ICON.parse("signal") + " Version";
+ String members = Html.FONT_AWESOME_ICON.parse("users") + " Users";
+ super.setPrefix(Html.TABLE_START_2.parse(version, members));
+ super.setSuffix(Html.TABLE_END.parse());
+ }
+
+ @Override
+ public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
+ String tableLines = getTableLines();
+ return parseContainer("", tableLines);
+ }
+
+ @Override
+ public Serializable getValue(UUID uuid) {
+ return -1;
+ }
+
+ private String getTableLines() {
+ StringBuilder html = new StringBuilder();
+
+ Map usersPerVersion = getUsersPerVersion(html);
+ usersPerVersion.entrySet().stream().map(e -> Html.TABLELINE_2.parse(e.getKey(), e.getValue() + "")).forEach(string -> {
+ html.append(string);
+ });
+ return html.toString();
+ }
+
+ private Map getUsersPerVersion(StringBuilder html) {
+ Map usersPerVersion = new HashMap<>();
+ try {
+ Map versions = table.getProtocolVersions();
+ for (int protocolVersion : versions.values()) {
+ String mcVer = Protocol.getMCVersion(protocolVersion);
+ if (!usersPerVersion.containsKey(mcVer)) {
+ usersPerVersion.put(mcVer, 0);
+ }
+ usersPerVersion.replace(mcVer, usersPerVersion.get(mcVer) + 1);
+ }
+ } catch (SQLException ex) {
+ html.append(Html.TABLELINE_2.parse(ex.toString(), ""));
+ return new HashMap<>();
+ }
+ return usersPerVersion;
+ }
+
+}