diff --git a/pom.xml b/pom.xml index 165b50c..77c3901 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ nl.SBDeveloper ThemeParkPlus - 2.0 + 2.1 jar ThemeParkPlus @@ -33,7 +33,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.2.1 package @@ -51,6 +51,10 @@ org.codemc.worldguardwrapper nl.sbdeveloper.themeparkplus.libs.worldguardwrapper + + org.bstats + nl.sbdeveloper.themeparkplus.libs.bstats + diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/commands/TPPCMD.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/commands/TPPCMD.java index 775cb4c..ac55e0e 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/commands/TPPCMD.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/commands/TPPCMD.java @@ -296,19 +296,19 @@ public class TPPCMD implements CommandExecutor { if (secOn == 0) { if (!LGUtil.zetLampAan(block)) { - sender.sendMessage(ConfigUtil.getMessage("Lamps.ErrorOn")); + sender.sendMessage(ConfigUtil.getMessage("Lamp.ErrorOn")); return true; } - if (ConfigUtil.sendConsole(sender)) sender.sendMessage(ConfigUtil.getMessage("Lamps.TurnedOn")); + if (ConfigUtil.sendConsole(sender)) sender.sendMessage(ConfigUtil.getMessage("Lamp.TurnedOn")); } else { if (!LGUtil.zetLampAan(block)) { - sender.sendMessage(ConfigUtil.getMessage("Lamps.ErrorOn")); + sender.sendMessage(ConfigUtil.getMessage("Lamp.ErrorOn")); return true; } Bukkit.getScheduler().runTaskLater(ThemeParkPlus.getInstance(), () -> LGUtil.zetLampUit(block), secOn * 20); - if (ConfigUtil.sendConsole(sender)) sender.sendMessage(ConfigUtil.getMessage("Lamps.TurnedOnSec", Collections.singletonMap("%sec%", String.valueOf(secOn)))); + if (ConfigUtil.sendConsole(sender)) sender.sendMessage(ConfigUtil.getMessage("Lamp.TurnedOnSec", Collections.singletonMap("%sec%", String.valueOf(secOn)))); } return true; } @@ -321,11 +321,11 @@ public class TPPCMD implements CommandExecutor { Location loc = new Location(bworld, bx, by, bz); if (!LGUtil.zetLampUit(loc.getBlock())) { - sender.sendMessage(ConfigUtil.getMessage("Lamps.ErrorOn")); + sender.sendMessage(ConfigUtil.getMessage("Lamp.ErrorOff")); return true; } - if (ConfigUtil.sendConsole(sender)) sender.sendMessage(ConfigUtil.getMessage("Lamps.TurnedOff")); + if (ConfigUtil.sendConsole(sender)) sender.sendMessage(ConfigUtil.getMessage("Lamp.TurnedOff")); return true; } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java index d2a62e9..30276ed 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/SignListeners.java @@ -59,9 +59,13 @@ public class SignListeners implements Listener { } else if (lines[1].equalsIgnoreCase("Scanner") && !lines[2].isEmpty() && !lines[3].isEmpty()) { e.setLine(0, sLineOne); e.setLine(1, sLineTwo); - } else if (lines[1].equalsIgnoreCase("WaitingRow") && !lines[2].isEmpty() && !lines[3].isEmpty()) { + } else if (lines[1].equalsIgnoreCase("WaitingRow") && !lines[2].isEmpty()) { WaitingRow foundRow = PlusAPI.getRow(lines[2]); if (foundRow == null) { + if (lines[3].isEmpty()) { + p.sendMessage(ConfigUtil.getMessage("General.IncorrectSign")); + return; + } foundRow = new WaitingRow(lines[2], lines[3]); PlusAPI.addRow(foundRow); } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/managers/DBManager.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/managers/DBManager.java index 64aa1a7..b14a69f 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/managers/DBManager.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/managers/DBManager.java @@ -7,6 +7,7 @@ import nl.sbdeveloper.themeparkplus.api.objects.Gate; import nl.sbdeveloper.themeparkplus.api.objects.WaitingRow; import nl.sbdeveloper.themeparkplus.sbutils.LocationSerializer; import nl.sbdeveloper.themeparkplus.sbutils.SQLiteDB; +import nl.sbdeveloper.themeparkplus.util.License; import nl.sbdeveloper.themeparkplus.util.LocationGsonAdapter; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; @@ -76,6 +77,8 @@ public class DBManager { } public void save() { + if (License.isValid() == null || !License.isValid()) return; + for (Map.Entry entry : PlusAPI.getGates().entrySet()) { Gson gson = getGson(); byte[] blob = gson.toJson(entry.getValue()).getBytes(); diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java index f185406..11dc583 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java @@ -1,6 +1,5 @@ package nl.sbdeveloper.themeparkplus.sbutils; -import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.bukkit.Bukkit; @@ -22,7 +21,7 @@ import java.util.function.BiConsumer; * Update class for SBDevelopment * @author Stijn [SBDeveloper] * @since 05-03-2020 - * @version 1.2 + * @version 1.4 * * © Stijn Bannink - All rights reserved. */ @@ -37,10 +36,10 @@ public class UpdateManager { private static final String RESOURCE_DOWNLOAD = "http://api.spiget.org/v2/resources/%s/download"; private Plugin plugin; - private double currentVersion; + private Version currentVersion; private int resourceID; private CheckType type; - private BiConsumer versionResponse; + private BiConsumer versionResponse; private BiConsumer downloadResponse; /** @@ -52,7 +51,7 @@ public class UpdateManager { */ public UpdateManager(@NotNull Plugin plugin, int resourceID, CheckType type) { this.plugin = plugin; - this.currentVersion = Double.parseDouble(plugin.getDescription().getVersion()); + this.currentVersion = new Version(plugin.getDescription().getVersion()); this.resourceID = resourceID; this.type = type; } @@ -62,7 +61,7 @@ public class UpdateManager { * @param versionResponse The response * @return The updatemanager */ - public UpdateManager handleResponse(BiConsumer versionResponse) { + public UpdateManager handleResponse(BiConsumer versionResponse) { this.versionResponse = versionResponse; return this; } @@ -104,13 +103,10 @@ public class UpdateManager { } in.close(); - JsonParser parser = new JsonParser(); - if (type == CheckType.SPIGOT) { - JsonArray array = parser.parse(response.toString()).getAsJsonArray(); - - version = array.get(0).getAsJsonObject().get("name").getAsString(); + version = response.toString(); } else if (type == CheckType.SBDPLUGINS) { + JsonParser parser = new JsonParser(); JsonObject object = parser.parse(response.toString()).getAsJsonObject(); version = object.get("data").getAsJsonObject().get("version").getAsString(); @@ -118,11 +114,11 @@ public class UpdateManager { if (version == null) return; - boolean latestVersion = Double.parseDouble(version) >= this.currentVersion; + Version onlineVersion = new Version(version); - double versionDouble = Double.parseDouble(version); + boolean latestVersion = this.currentVersion.compareTo(onlineVersion) < 0; - Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(latestVersion ? VersionResponse.LATEST : VersionResponse.FOUND_NEW, latestVersion ? this.currentVersion : versionDouble)); + Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(latestVersion ? VersionResponse.LATEST : VersionResponse.FOUND_NEW, latestVersion ? this.currentVersion : onlineVersion)); } catch (IOException | NullPointerException e) { e.printStackTrace(); Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(VersionResponse.UNAVAILABLE, null)); @@ -202,4 +198,45 @@ public class UpdateManager { DONE, ERROR, UNAVAILABLE } + public static class Version implements Comparable { + + private String version; + + public final String get() { + return this.version; + } + + public Version(String version) { + if(version == null) + throw new IllegalArgumentException("Version can not be null"); + if(!version.matches("[0-9]+(\\.[0-9]+)*")) + throw new IllegalArgumentException("Invalid version format"); + this.version = version; + } + + @Override + public int compareTo(@NotNull Version that) { + String[] thisParts = this.get().split("\\."); + String[] thatParts = that.get().split("\\."); + + int length = Math.max(thisParts.length, thatParts.length); + for (int i = 0; i < length; i++) { + int thisPart = i < thisParts.length ? Integer.parseInt(thisParts[i]) : 0; + int thatPart = i < thatParts.length ? Integer.parseInt(thatParts[i]) : 0; + if(thisPart < thatPart) + return -1; + if(thisPart > thatPart) + return 1; + } + return 0; + } + + @Override + public boolean equals(Object that) { + if (this == that) return true; + if (that == null) return false; + if (this.getClass() != that.getClass()) return false; + return this.compareTo((UpdateManager.Version) that) == 0; + } + } } \ No newline at end of file diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java index 9e91ec6..9eb8d9b 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -58,6 +59,7 @@ public class LGUtil { } return false; } + if (!isAan(lampBlock)) { final Block neighbor = getNeighbor(lampBlock); if (neighbor != null) { @@ -97,8 +99,9 @@ public class LGUtil { } return false; } + if (isAan(lampBlock)) { - lampBlock.setType(Objects.requireNonNull(Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[0]))); + lampBlock.setType(Objects.requireNonNull(Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[1]))); return true; } return false; @@ -250,15 +253,18 @@ public class LGUtil { } private static boolean isAan(Block lamp) { - return ((nieuweVersie) && (Objects.requireNonNull(getAsString(getBlockData(lamp))).contains("lit=true"))) || ((!nieuweVersie) && (lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[1]))); + if (nieuweVersie) { + return getAsString(getBlockData(lamp)).contains("lit=true"); + } else { + return lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[0]); + } } private static boolean isLamp(Block lamp) { if (nieuweVersie) { return lamp.getType() == XMaterial.REDSTONE_LAMP.parseMaterial(); } else { - return lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[1]) - || lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[0]); + return Arrays.asList(XMaterial.REDSTONE_LAMP.getLegacy()).contains(lamp.getType().name()); } } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/License.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/License.java index e3260cc..188c7fc 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/License.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/License.java @@ -3,7 +3,13 @@ package nl.sbdeveloper.themeparkplus.util; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; @@ -14,28 +20,29 @@ import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.Objects; /** * License class for SBDevelopment * - * v1.3 - Changed in 03-03-2020 + * v1.6 - Changed on 06-08-2020 * * @author Stijn [SBDeveloper] * @since 23-12-2019 */ -public class License { +public class License implements Listener { /* - This file is part of ActionFoto. + This file is part of ThemeParkRidecountAddon. Copyright (c) 2018-2020 SBDevelopment - All Rights Reserved Unauthorized copying of this file, via any medium is strictly prohibited Proprietary and confidential Written by Stijn Bannink , January 2020 */ - private Plugin plugin; - private String license; - private String prefix; + private JavaPlugin plugin; // The plugin instance + private String license; // The license code + private String prefix; // The correct prefix for this plugin + @Nullable private String invalidReason; // The reason the license is invalid, if null it's not invalid! + @Nullable private static Boolean valid; // If true, it's valid, if false, it's not valid, if null it's not checked! /** * Construct a new license @@ -43,176 +50,158 @@ public class License { * @param prefix The prefix, like TPP or AF * @param license The license from the config */ - public License(Plugin plugin, String prefix, String license) { + public License(JavaPlugin plugin, String prefix, String license) { this.prefix = prefix; this.plugin = plugin; this.license = license; - startTimer(); + Bukkit.getPluginManager().registerEvents(this, plugin); + + validateLicense(); } - private void startTimer() { - Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { - if (!validateLicense()) { - Bukkit.getLogger().severe("[" + prefix + "] License is incorrect!"); - } - }, 0, 20 * 60 * 60); + @EventHandler + public void onJoin(PlayerJoinEvent e) { + if (this.invalidReason == null) return; + + Player p = e.getPlayer(); + if (p.isOp() || p.hasPermission("sbd.licensemessages")) { + Bukkit.getScheduler().runTaskLater(this.plugin, () -> p.sendMessage(ChatColor.GOLD + "[" + ChatColor.RED + this.plugin.getName() + ChatColor.GOLD + "] " + ChatColor.RED + "The license is incorrect! Reason: " + ChatColor.GOLD + this.invalidReason), 3 * 20L /* 3 sec */); + } } /** * Check a license * - * @return true/false */ - private boolean validateLicense() { + private void validateLicense() { + //STEP 1: Check prefix + if (!this.license.split("-")[0].contains(this.prefix)) { + disable("You used the wrong license for this product."); + return; + } + + //STEP 2: Send license request String url = "https://sbdplugins.nl/wp-json/lmfwc/v2/licenses/" + this.license; - - @Nullable JsonObject res; + @Nullable JsonObject response; try { - res = sendGETRequestJSON(url); + response = sendGETRequestJSON(url); } catch (IOException e) { - disable("GET_request_error"); - return false; + disable("Couldn't send the request."); + return; } - if (res == null) { - disable("GET_request_error_2"); - return false; + if (response == null) { + disable("Couldn't send the request."); + return; } - JsonObject dat = res.get("data").getAsJsonObject(); + JsonObject dataObject = response.get("data").getAsJsonObject(); - int stat = dat.get("status").getAsInt(); - if (stat == 404) { - disable("status_404_error"); - return false; - } - - if (dat.get("licenseKey").isJsonNull()) { - disable("license_null_error"); - return false; - } - - if (!dat.get("licenseKey").getAsString().split("-")[0].contains(prefix)) { - disable("prefix_error"); - return false; - } - - switch(dat.get("status").getAsString()) { + //STEP 3: Check status + switch(dataObject.get("status").getAsString()) { case "2": - //activate? + //Delivered -> Try to activate (double check timesActivated) break; case "3": - //it's good + //Activated! break; default: - disable("status_error"); - return false; + disable("Your license has a wrong status."); + return; } - //Not activated? Activate it! - if (dat.get("timesActivated").isJsonNull() || dat.get("timesActivated").getAsString().equalsIgnoreCase("0")) { - return activate(); + //STEP 4: Check times activated, and if not activated, activate. + if (dataObject.get("timesActivated").isJsonNull() || dataObject.get("timesActivated").getAsString().equalsIgnoreCase("0")) { + activate(); + return; } - if (dat.get("expiresAt").isJsonNull()) { - disable("null_error"); - return false; + //STEP 5: Check expire date + if (dataObject.get("expiresAt").isJsonNull()) { + disable("Your license has no expire date."); + return; } SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date; try { - date = format.parse(dat.get("expiresAt").getAsString()); + date = format.parse(dataObject.get("expiresAt").getAsString()); } catch (ParseException e) { e.printStackTrace(); - disable("null_error"); - return false; + disable("Your license has a wrong expire date."); + return; } - if (!(Objects.requireNonNull(date).after(new Date()))) { - disable("expired_error"); - return false; + if (date == null) { + disable("Your license has a wrong expire date."); + return; } - if (!dat.get("ipcheck").getAsBoolean()) { - disable("ip_error"); - return false; + if (!(date.after(new Date()))) { + disable("Your license has expired."); + return; } - if (dat.get("port").isJsonNull()) { - disable("null_error"); - return false; + //STEP 6: Check IP and port. + if (!dataObject.get("ipcheck").getAsBoolean()) { + disable("Your license has been used with another IP. Update it in our Discord."); + return; } - try { - int por = dat.get("port").getAsInt(); - if (por != Bukkit.getServer().getPort()) { - disable("port_error"); - return false; - } - } catch(NumberFormatException e) { - disable("null_error"); - return false; + if (dataObject.get("port").isJsonNull()) { + disable("Your license has no port."); + return; } - return true; + String por = dataObject.get("port").getAsString(); + if (!checkPortValue(Bukkit.getServer().getPort(), por)) { + disable("Your license has been used with another Port. Update it in our Discord."); + return; + } + + valid = true; } /** - * Activate the license (private) + * Activate the license * - * @return true/false */ - private boolean activate() { + private void activate() { + //STEP 1: Send license activate request String url = "https://sbdplugins.nl/wp-json/lmfwc/v2/licenses/activate/" + this.license + "?port=" + Bukkit.getServer().getPort(); - - @Nullable JsonObject res; + @Nullable JsonObject response; try { - res = sendGETRequestJSON(url); + response = sendGETRequestJSON(url); } catch (IOException e) { - e.printStackTrace(); - disable("GET_request_error"); - return false; + disable("Couldn't send the activate request."); + return; } - if (res == null) { - disable("GET_request_error_2"); - return false; + if (response == null) { + disable("Couldn't send the activate request."); + return; } - JsonObject dat = res.get("data").getAsJsonObject(); + JsonObject dataObject = response.get("data").getAsJsonObject(); - int stat = dat.get("status").getAsInt(); - if (stat == 404) { - disable("status_404_error"); - return false; - } - - if (dat.get("licenseKey").isJsonNull()) { - disable("license_null_error"); - return false; - } - - if (!dat.get("licenseKey").getAsString().split("-")[0].contains(prefix)) { - disable("prefix_error"); - return false; - } - - switch(dat.get("status").getAsString()) { + //STEP 2: Check status + switch(dataObject.get("status").getAsString()) { case "2": - //activate? + //Delivered -> STILL NOT ACTIVATED?! -> Double check break; case "3": - //it's good + //Activated! break; default: - disable("status_error"); - return false; + disable("Your license has a wrong status."); + return; } - //Still not activated? Something is wrong... - return !dat.get("timesActivated").isJsonNull() && !dat.get("timesActivated").getAsString().equalsIgnoreCase("0"); + //STEP 3: Check times activated, and if still not activated, disable. + if (dataObject.get("timesActivated").isJsonNull() || dataObject.get("timesActivated").getAsString().equalsIgnoreCase("0")) { + disable("Couldn't activate the license."); + } } /** @@ -221,10 +210,15 @@ public class License { * @param reason The disabling reason */ private void disable(String reason) { - Bukkit.getScheduler().runTask(plugin, () -> { - Bukkit.getLogger().severe("[" + plugin.getName() + "] " + "Stopping plugin because licensing system check failed."); - Bukkit.getLogger().severe("[" + plugin.getName() + "] " + "Reason: " + reason); - Bukkit.getPluginManager().disablePlugin(plugin); + this.invalidReason = reason; + + Bukkit.getScheduler().runTask(this.plugin, () -> { + valid = false; + + Bukkit.getLogger().severe("[" + this.plugin.getName() + "] Stopping plugin because licensing system check failed."); + Bukkit.getLogger().severe("[" + this.plugin.getName() + "] Reason: " + reason); + Bukkit.getLogger().severe("[" + this.plugin.getName() + "] Contact the developer if you believe something is wrong on their side."); + Bukkit.getPluginManager().disablePlugin(this.plugin); }); } @@ -261,4 +255,51 @@ public class License { return parser.parse(response.toString()).getAsJsonObject(); } + private boolean checkPortValue(int input, @NotNull String dataValue) { + //STEP 1: Check wildcard + if (dataValue.equals("*")) return true; + + //STEP 2: Check if equals + try { + int dataVal = Integer.parseInt(dataValue); + + return input == dataVal; + } catch (NumberFormatException ignored) {} + + //STEP 3: Check if range + if (dataValue.contains("-")) { + String[] dataSplit = dataValue.split("-"); + + //STEP 3.1: Check if min or max is wildcard + if (dataSplit[0].equals("*") && !dataSplit[1].equals("*")) { + int max = Integer.parseInt(dataSplit[1]); + return input <= max; + } else if (dataSplit[1].equals("*") && !dataSplit[0].equals("*")) { + int min = Integer.parseInt(dataSplit[0]); + return min <= input; + } else { + try { + int min = Integer.parseInt(dataSplit[0]); + int max = Integer.parseInt(dataSplit[1]); + + return (min <= input) && (input <= max); + } catch (NumberFormatException ex) { + return false; + } + } + } + + //Else, invalid value + return false; + } + + /** + * Check if the license is valid + * + * @return true -> VALID, false -> INVALID, null -> UNCHECKED + */ + @Nullable + public static Boolean isValid() { + return valid; + } } \ No newline at end of file