2017-06-02 15:51:03 +02:00
|
|
|
package me.libraryaddict.disguise.utilities;
|
|
|
|
|
2020-03-08 21:00:58 +01:00
|
|
|
import lombok.Getter;
|
2019-05-18 08:54:51 +02:00
|
|
|
import me.libraryaddict.disguise.LibsDisguises;
|
2020-03-07 09:07:19 +01:00
|
|
|
import me.libraryaddict.disguise.utilities.plugin.BisectHosting;
|
2019-06-29 03:38:20 +02:00
|
|
|
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
|
2019-01-03 03:13:03 +01:00
|
|
|
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
2019-06-29 03:38:20 +02:00
|
|
|
import org.bukkit.configuration.InvalidConfigurationException;
|
2018-10-23 23:11:37 +02:00
|
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
2020-04-15 15:09:20 +02:00
|
|
|
import org.bukkit.util.FileUtil;
|
2018-10-23 23:11:37 +02:00
|
|
|
|
2020-02-13 07:47:02 +01:00
|
|
|
import java.io.*;
|
2017-06-02 15:51:03 +02:00
|
|
|
import java.net.URL;
|
|
|
|
import java.net.URLClassLoader;
|
2020-02-13 07:47:02 +01:00
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import java.util.stream.Collectors;
|
2017-06-02 15:51:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by libraryaddict on 2/06/2017.
|
|
|
|
*/
|
2017-06-08 17:09:28 +02:00
|
|
|
public class LibsPremium {
|
2019-06-29 03:38:20 +02:00
|
|
|
private static Boolean thisPluginIsPaidFor;
|
|
|
|
/**
|
|
|
|
* Information of the actively running plugin
|
|
|
|
*/
|
|
|
|
private static PluginInformation pluginInformation;
|
|
|
|
/**
|
|
|
|
* Information of the plugin used to activate premium, if exists
|
|
|
|
*/
|
|
|
|
private static PluginInformation paidInformation;
|
2020-03-08 21:00:58 +01:00
|
|
|
@Getter
|
|
|
|
private static boolean bisectHosted;
|
2019-02-16 04:57:07 +01:00
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
public static PluginInformation getPluginInformation() {
|
|
|
|
return pluginInformation;
|
2019-02-16 04:57:07 +01:00
|
|
|
}
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
public static PluginInformation getPaidInformation() {
|
|
|
|
return paidInformation;
|
|
|
|
}
|
2017-06-02 15:51:03 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
/**
|
|
|
|
* @return Account ID if downloaded through SpigotMC
|
|
|
|
*/
|
|
|
|
public static String getUserID() {
|
|
|
|
return "%%__USER__%%";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Resource ID if downloaded through SpigotMC
|
|
|
|
*/
|
|
|
|
public static String getResourceID() {
|
|
|
|
return "%%__RESOURCE__%%";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Download ID if downloaded through SpigotMC
|
|
|
|
*/
|
|
|
|
public static String getDownloadID() {
|
|
|
|
return "%%__NONCE__%%";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param userID
|
|
|
|
* @return true if userID does not contain __USER__
|
|
|
|
*/
|
|
|
|
private static Boolean isPremium(String userID) {
|
2020-04-13 16:27:34 +02:00
|
|
|
return !userID.contains("__USER__") && !getResourceID().equals("81");
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Boolean isAPIPlugin() {
|
|
|
|
return !isPremium() && getResourceID().equals("81");
|
2019-02-16 04:57:07 +01:00
|
|
|
}
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
/**
|
|
|
|
* Returns true if this plugin is premium
|
|
|
|
*/
|
2017-06-02 15:51:03 +02:00
|
|
|
public static Boolean isPremium() {
|
2019-06-29 03:38:20 +02:00
|
|
|
return thisPluginIsPaidFor == null ? isPremium(getUserID()) : thisPluginIsPaidFor;
|
2017-06-02 15:51:03 +02:00
|
|
|
}
|
|
|
|
|
2019-03-05 05:51:06 +01:00
|
|
|
/**
|
|
|
|
* Checks if the premiumVersion can work on the current version
|
|
|
|
*/
|
|
|
|
private static boolean isValidVersion(String currentVersion, String premiumVersion) {
|
|
|
|
currentVersion = currentVersion.replaceAll("(v)|(-SNAPSHOT)", "");
|
|
|
|
|
|
|
|
// Premium version must be using an accepted versioning system
|
|
|
|
if (!premiumVersion.matches("[0-9]+(\\.[0-9]+)+")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-04-13 16:27:34 +02:00
|
|
|
if (premiumVersion.startsWith("9.")) {
|
2020-04-05 04:41:12 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-05 05:51:06 +01:00
|
|
|
// If current version is not a number version, then the premium version cannot be checked
|
|
|
|
if (!currentVersion.matches("[0-9]+(\\.[0-9]+)+")) {
|
|
|
|
// Return true as the rest of the version check cannot be used
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Split by decimal points
|
2019-03-07 02:39:10 +01:00
|
|
|
String[] currentSplit = currentVersion.split("\\.");
|
|
|
|
String[] premSplit = premiumVersion.split("\\.");
|
2019-03-05 05:51:06 +01:00
|
|
|
|
|
|
|
// Comparing major versions
|
|
|
|
// Current version must be the same, or lower than premium version
|
2019-12-19 08:54:38 +01:00
|
|
|
return Integer.parseInt(currentSplit[0]) <= Integer.parseInt(premSplit[0]);
|
2019-11-03 06:07:12 +01:00
|
|
|
|
|
|
|
// Snapshot must be of current version
|
2019-11-25 13:57:36 +01:00
|
|
|
//return premiumVersion.equals(currentVersion);
|
2019-03-05 05:51:06 +01:00
|
|
|
}
|
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
private static PluginInformation getInformation(File file) throws Exception {
|
|
|
|
try (URLClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()})) {
|
|
|
|
Class c = cl.loadClass(LibsPremium.class.getName());
|
2017-06-02 15:51:03 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
boolean oldJarFile = true;
|
2017-06-08 17:06:58 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
try {
|
|
|
|
// Error thrown if method doesn't exist
|
|
|
|
c.getMethod("getUserID");
|
|
|
|
// Method exists, is not older file
|
|
|
|
oldJarFile = false;
|
|
|
|
}
|
|
|
|
catch (Exception ignored) {
|
|
|
|
}
|
2017-06-08 17:06:58 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
// Fetch the plugin.yml from the jar file
|
|
|
|
YamlConfiguration config = ReflectionManager.getPluginYaml(cl);
|
|
|
|
// No checks for null config as the correct error will be thrown on access
|
2017-06-02 15:51:03 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
Boolean premium;
|
|
|
|
String userId = null;
|
2019-06-29 03:38:20 +02:00
|
|
|
String downloadId = null;
|
|
|
|
String resourceId = null;
|
2017-06-02 15:51:03 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
if (oldJarFile) {
|
|
|
|
premium = (Boolean) c.getMethod("isPremium").invoke(null);
|
|
|
|
} else {
|
|
|
|
userId = (String) c.getMethod("getUserID").invoke(null);
|
2019-06-29 03:38:20 +02:00
|
|
|
resourceId = (String) c.getMethod("getResourceID").invoke(null);
|
|
|
|
downloadId = (String) c.getMethod("getDownloadID").invoke(null);
|
2019-02-16 04:57:07 +01:00
|
|
|
premium = isPremium(userId);
|
|
|
|
}
|
2017-06-02 15:51:03 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
String pluginBuildDate = "??/??/????";
|
2018-10-23 23:11:37 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
// If plugin.yml contains a build-date
|
|
|
|
if (config.contains("build-date")) {
|
|
|
|
pluginBuildDate = config.getString("build-date");
|
|
|
|
}
|
2018-10-23 23:11:37 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
String pluginBuildNumber = "???";
|
2017-06-02 15:51:03 +02:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
// If plugin.yml contains a jenkins build number
|
|
|
|
if (config.contains("build-number")) {
|
|
|
|
pluginBuildNumber = config.getString("build-number");
|
2018-02-15 22:51:15 +01:00
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
// If build number is composed of purely numbers, prepend with # for readability
|
|
|
|
if (pluginBuildNumber.matches("[0-9]+")) {
|
|
|
|
pluginBuildNumber = "#" + pluginBuildNumber;
|
2017-06-02 15:51:03 +02:00
|
|
|
}
|
|
|
|
}
|
2019-02-16 04:57:07 +01:00
|
|
|
|
|
|
|
String pluginVersion = config.getString("version");
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
return new PluginInformation(userId, resourceId, downloadId, premium, pluginVersion, pluginBuildNumber,
|
|
|
|
pluginBuildDate);
|
2019-02-16 04:57:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-05 05:51:06 +01:00
|
|
|
private static void doSecondaryCheck(String version) {
|
2019-02-16 04:57:07 +01:00
|
|
|
File[] files = new File("plugins/LibsDisguises/").listFiles();
|
2019-12-21 22:46:37 +01:00
|
|
|
boolean foundJar = false;
|
2019-02-16 04:57:07 +01:00
|
|
|
|
|
|
|
if (files == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (File file : files) {
|
|
|
|
if (!file.isFile())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!file.getName().endsWith(".jar"))
|
|
|
|
continue;
|
|
|
|
|
2019-12-21 22:46:37 +01:00
|
|
|
foundJar = true;
|
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
PluginInformation plugin;
|
|
|
|
|
|
|
|
try {
|
|
|
|
plugin = getInformation(file);
|
|
|
|
}
|
|
|
|
catch (ClassNotFoundException ex) {
|
|
|
|
DisguiseUtilities.getLogger()
|
|
|
|
.warning("Found an unrecognized jar in the LibsDisguises folder (" + file.getName() + ")");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
catch (Exception ex) {
|
|
|
|
DisguiseUtilities.getLogger().warning("Error while trying to handle the file " + file.getName());
|
|
|
|
ex.printStackTrace();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format into a string
|
|
|
|
// v5.2.6, build #40, created 16/02/2019
|
|
|
|
String fileInfo = String.format("v%s, build %s, created %s", plugin.getVersion(), plugin.getBuildNumber(),
|
|
|
|
plugin.getBuildDate());
|
|
|
|
|
|
|
|
if (plugin.isPremium()) {
|
2019-06-29 03:38:20 +02:00
|
|
|
if (!isValidVersion(version, plugin.getVersion()) || plugin.getUserID() == null ||
|
2019-12-19 08:54:38 +01:00
|
|
|
plugin.getDownloadID() == null || plugin.getUserID().equals("666666")) {
|
2019-03-05 05:51:06 +01:00
|
|
|
DisguiseUtilities.getLogger().warning(
|
|
|
|
"You have an old Lib's Disguises jar (" + file.getName() + " " + fileInfo +
|
|
|
|
") in the LibsDisguises folder! For security purposes, please replace this with a" +
|
|
|
|
" new " +
|
|
|
|
"version from SpigotMC - https://www.spigotmc.org/resources/libs-disguises.32453/");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
paidInformation = plugin;
|
|
|
|
|
2019-02-16 04:57:07 +01:00
|
|
|
thisPluginIsPaidFor = true;
|
|
|
|
// Found a premium Lib's Disguises jar (v5.2.6, build #40, created 16/02/2019)
|
2019-03-05 05:51:06 +01:00
|
|
|
DisguiseUtilities.getLogger().info("Found a premium Lib's Disguises jar (" + fileInfo + ")");
|
|
|
|
DisguiseUtilities.getLogger().info("Registered to: " + getSanitizedUser(plugin.getUserID()));
|
2019-02-16 04:57:07 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
// You have a non-premium Lib's Disguises jar (LibsDisguises.jar v5.2.6, build #40, created
|
|
|
|
// 16/02/2019) in the LibsDisguises folder!
|
|
|
|
DisguiseUtilities.getLogger().warning(
|
|
|
|
"You have a non-premium Lib's Disguises jar (" + file.getName() + " " + fileInfo +
|
|
|
|
") in the LibsDisguises folder!");
|
2019-12-21 22:46:37 +01:00
|
|
|
DisguiseUtilities.getLogger().warning(
|
|
|
|
"Please place the premium jar downloaded from https://www.spigotmc" +
|
|
|
|
".org/resources/libs-disguises.32453/ " + "in here!");
|
2019-02-16 04:57:07 +01:00
|
|
|
}
|
|
|
|
}
|
2019-12-21 22:46:37 +01:00
|
|
|
|
|
|
|
if (!foundJar) {
|
2020-03-08 21:00:58 +01:00
|
|
|
if (bisectHosted = new BisectHosting().isBisectHosted("LibsDisguises")) {
|
2020-03-07 15:32:58 +01:00
|
|
|
DisguiseUtilities.getLogger().info("Hosted by BisectHosting! Premium enabled!");
|
2020-03-07 09:07:19 +01:00
|
|
|
|
|
|
|
paidInformation = new PluginInformation("0", "32453", "0", true, "0", "#0", "0");
|
|
|
|
|
|
|
|
thisPluginIsPaidFor = true;
|
|
|
|
} else {
|
|
|
|
DisguiseUtilities.getLogger().warning(
|
|
|
|
"If you own the plugin, place the premium jar downloaded from https://www.spigotmc" +
|
|
|
|
".org/resources/libs-disguises.32453/ in plugins/LibsDisguises/");
|
|
|
|
}
|
2019-12-21 22:46:37 +01:00
|
|
|
}
|
2019-02-16 04:57:07 +01:00
|
|
|
}
|
|
|
|
|
2019-03-05 05:51:06 +01:00
|
|
|
private static String getSanitizedUser(String userID) {
|
2019-03-05 14:32:30 +01:00
|
|
|
if (userID == null) {
|
|
|
|
return "N/A";
|
|
|
|
}
|
|
|
|
|
2019-03-05 05:51:06 +01:00
|
|
|
if (!userID.matches("[0-9]+")) {
|
|
|
|
return String.format("... %s? Am I reading this right?", userID);
|
|
|
|
}
|
|
|
|
|
2019-05-18 08:54:51 +02:00
|
|
|
int total = 0;
|
|
|
|
|
|
|
|
for (char c : userID.toCharArray()) {
|
|
|
|
total += Character.getNumericValue(c);
|
|
|
|
}
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
return String.format("%s (%s)", userID, total);
|
2019-03-05 05:51:06 +01:00
|
|
|
}
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
public static void check(String version, File file) {
|
2019-02-16 04:57:07 +01:00
|
|
|
thisPluginIsPaidFor = isPremium();
|
|
|
|
|
2019-06-29 03:38:20 +02:00
|
|
|
try {
|
|
|
|
pluginInformation = getInformation(file);
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
String pluginBuildDate = "??/??/????";
|
|
|
|
|
|
|
|
YamlConfiguration config = new YamlConfiguration();
|
|
|
|
|
|
|
|
try {
|
2020-02-13 07:47:02 +01:00
|
|
|
try (InputStream stream = LibsDisguises.getInstance().getResource("plugin.yml")) {
|
|
|
|
config.loadFromString(
|
|
|
|
new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines()
|
|
|
|
.collect(Collectors.joining("\n")));
|
|
|
|
}
|
2019-06-29 03:38:20 +02:00
|
|
|
|
|
|
|
// If plugin.yml contains a build-date
|
|
|
|
if (config.contains("build-date")) {
|
|
|
|
pluginBuildDate = config.getString("build-date");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (InvalidConfigurationException | IOException ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
|
|
|
|
String buildNo = LibsDisguises.getInstance().getBuildNo();
|
|
|
|
|
|
|
|
if (buildNo != null && buildNo.matches("[0-9]+")) {
|
|
|
|
buildNo = "#" + buildNo;
|
|
|
|
}
|
|
|
|
|
|
|
|
pluginInformation = new PluginInformation(getUserID(), getResourceID(), getDownloadID(),
|
|
|
|
isPremium(getUserID()), version, buildNo, pluginBuildDate);
|
|
|
|
}
|
|
|
|
|
2019-05-18 08:54:51 +02:00
|
|
|
if (!isPremium() || !LibsDisguises.getInstance().isReleaseBuild()) {
|
2019-03-05 05:51:06 +01:00
|
|
|
doSecondaryCheck(version);
|
|
|
|
} else {
|
|
|
|
DisguiseUtilities.getLogger().info("Registered to: " + getSanitizedUser(getUserID()));
|
2020-04-15 15:09:20 +02:00
|
|
|
|
|
|
|
boolean foundBetter = false;
|
|
|
|
|
|
|
|
// Lets not do any sanity checks since it won't affect legit users
|
|
|
|
for (File f : LibsDisguises.getInstance().getDataFolder().listFiles()) {
|
|
|
|
if (f.isDirectory() || !f.getName().endsWith(".jar")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
PluginInformation info = getInformation(f);
|
|
|
|
|
|
|
|
if (info.getBuildNumber() == null || !info.getBuildNumber().matches("[0-9]+")) {
|
|
|
|
f.delete();
|
|
|
|
DisguiseUtilities.getLogger().info("Ew, I don't recognize " + f.getName());
|
|
|
|
continue;
|
|
|
|
} else if (Integer.parseInt(info.getBuildNumber()) <
|
|
|
|
Integer.parseInt(LibsDisguises.getInstance().getBuildNo())) {
|
|
|
|
f.delete();
|
|
|
|
DisguiseUtilities.getLogger().info("Ew, " + f.getName() + " is so old");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!info.isLegit()) {
|
|
|
|
f.delete();
|
|
|
|
DisguiseUtilities.getLogger().info("Ew, I saw something nasty in " + f.getName());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
foundBetter = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!foundBetter) {
|
|
|
|
File f = new File(
|
|
|
|
LibsDisguises.getInstance().getClass().getProtectionDomain().getCodeSource().getLocation()
|
|
|
|
.getFile());
|
|
|
|
|
|
|
|
FileUtil.copy(f, new File(LibsDisguises.getInstance().getDataFolder(), f.getName()));
|
|
|
|
|
|
|
|
DisguiseUtilities.getLogger().info("Copied " + f.getName() +
|
|
|
|
" to the plugin folder! This is incase you want to use dev builds.");
|
|
|
|
}
|
2019-02-16 04:57:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isPremium()) {
|
2019-06-29 03:38:20 +02:00
|
|
|
boolean prem =
|
|
|
|
getPaidInformation() == null ? getPluginInformation().isLegit() : getPaidInformation().isLegit();
|
|
|
|
|
|
|
|
DisguiseUtilities.getLogger()
|
|
|
|
.info("Premium enabled, thank you for supporting Lib's Disguises!" + (!prem ? "!" : ""));
|
2017-06-02 15:51:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|