LibsDisguises/plugin/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java

351 lines
13 KiB
Java

package me.libraryaddict.disguise.utilities;
import lombok.Getter;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.utilities.plugin.BisectHosting;
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.FileUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
/**
* Created by libraryaddict on 2/06/2017.
*/
public class LibsPremium {
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;
@Getter
private static boolean bisectHosted;
public static PluginInformation getPluginInformation() {
return pluginInformation;
}
public static PluginInformation getPaidInformation() {
return paidInformation;
}
/**
* @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 resourceID, String userID) {
return !userID.contains("__USER__") && resourceID.equals("32453");
}
/**
* Returns true if this plugin is premium
*/
public static Boolean isPremium() {
return true;
}
/**
* 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;
}
if (premiumVersion.startsWith("9.")) {
return false;
}
// 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
String[] currentSplit = currentVersion.split("\\.");
String[] premSplit = premiumVersion.split("\\.");
// Comparing major versions
// Current version must be the same, or lower than premium version
return Integer.parseInt(currentSplit[0]) <= Integer.parseInt(premSplit[0]);
// Snapshot must be of current version
//return premiumVersion.equals(currentVersion);
}
public static PluginInformation getInformation(File file) throws Exception {
try (URLClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()})) {
Class c = cl.loadClass(LibsPremium.class.getName());
// Fetch the plugin.yml from the jar file
YamlConfiguration config = ReflectionManager.getPluginYAMLEx(file);
// No checks for null config as the correct error will be thrown on access
String userId = (String) c.getMethod("getUserID").invoke(null);
String downloadId = (String) c.getMethod("getDownloadID").invoke(null);
String resourceId = (String) c.getMethod("getResourceID").invoke(null);
Boolean premium = isPremium(resourceId, userId);
String pluginBuildDate = "??/??/????";
// If plugin.yml contains a build-date
if (config.contains("build-date")) {
pluginBuildDate = config.getString("build-date");
}
String pluginBuildNumber = "???";
// If plugin.yml contains a jenkins build number
if (config.contains("build-number")) {
pluginBuildNumber = config.getString("build-number");
// If build number is composed of purely numbers, prepend with # for readability
if (pluginBuildNumber.matches("[0-9]+")) {
pluginBuildNumber = "#" + pluginBuildNumber;
}
}
String pluginVersion = config.getString("version");
return new PluginInformation(file.length(), userId, resourceId, downloadId, premium, pluginVersion, pluginBuildNumber, pluginBuildDate);
}
}
private static void doSecondaryCheck(String version) {
File pluginDir = new File("plugins/LibsDisguises/");
if (!pluginDir.exists() && LibsDisguises.getInstance() != null) {
pluginDir = LibsDisguises.getInstance().getDataFolder();
}
File[] files = pluginDir.listFiles();
boolean foundJar = false;
if (files == null) {
return;
}
for (File file : files) {
if (!file.isFile()) {
continue;
}
if (!file.getName().endsWith(".jar")) {
continue;
}
foundJar = true;
PluginInformation plugin;
try {
plugin = getInformation(file);
} catch (ClassNotFoundException | NoClassDefFoundError ex) {
DisguiseUtilities.getLogger().warning(
"Found an unrecognized jar in the LibsDisguises folder (" + file.getName() + ") - It may need replacing with a newer jar from SpigotMC");
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()) {
if (!isValidVersion(version, plugin.getVersion()) || plugin.getUserID() == null || plugin.getDownloadID() == null ||
plugin.getUserID().equals("666666")) {
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;
}
paidInformation = plugin;
thisPluginIsPaidFor = true;
// Found a premium Lib's Disguises jar (v5.2.6, build #40, created 16/02/2019)
DisguiseUtilities.getLogger().info("Found a premium Lib's Disguises jar (" + fileInfo + ")");
DisguiseUtilities.getLogger().info("Registered to: " + getSanitizedUser(plugin.getUserID()));
// >.>
if (plugin.getBuildNumber() == null || !plugin.getBuildNumber().matches("#[0-9]+") ||
Integer.parseInt(plugin.getBuildNumber().substring(1)) < 300) {
file.delete();
continue;
}
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!");
DisguiseUtilities.getLogger()
.warning("Please place the premium jar downloaded from https://www.spigotmc" + ".org/resources/libs-disguises.32453/ " + "in here!");
}
}
if (!isPremium()) {
if (bisectHosted = new BisectHosting().isBisectHosted("LibsDisguises")) {
DisguiseUtilities.getLogger().info("Hosted by BisectHosting! Premium enabled!");
paidInformation = new PluginInformation(0, "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/");
}
}
}
private static String getSanitizedUser(String userID) {
if (userID == null) {
return "N/A";
}
if (!userID.matches("[0-9]+")) {
return String.format("... %s? Am I reading this right?", userID);
}
int total = 0;
for (char c : userID.toCharArray()) {
total += Character.getNumericValue(c);
}
return String.format("%s (%s)", userID, total);
}
public static void check(String version, File file) {
thisPluginIsPaidFor = isPremium();
try {
pluginInformation = getInformation(file);
} catch (Exception e) {
String pluginBuildDate = "??/??/????";
YamlConfiguration config = new YamlConfiguration();
try {
try (InputStream stream = LibsDisguises.getInstance().getResource("plugin.yml")) {
config.loadFromString(new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n")));
}
// If plugin.yml contains a build-date
if (config.contains("build-date")) {
pluginBuildDate = config.getString("build-date");
}
} catch (Exception ex) {
ex.printStackTrace();
}
String buildNo = LibsDisguises.getInstance().getBuildNo();
if (buildNo != null && buildNo.matches("[0-9]+")) {
buildNo = "#" + buildNo;
}
pluginInformation = new PluginInformation(LibsDisguises.getInstance().getFile().length(), getUserID(), getResourceID(), getDownloadID(),
isPremium(getResourceID(), getUserID()), version, buildNo, pluginBuildDate);
}
if (!isPremium() || !LibsDisguises.getInstance().isReleaseBuild()) {
doSecondaryCheck(version);
} else {
DisguiseUtilities.getLogger().info("Registered to: " + getSanitizedUser(getUserID()));
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().replace("#", "")) <
Integer.parseInt(LibsDisguises.getInstance().getBuildNo().replace("#", ""))) {
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 (ClassNotFoundException | NoClassDefFoundError e) {
DisguiseUtilities.getLogger().info("Ew, error about invalid Libs Disguises jar. Deleting " + f.getName());
f.delete();
} catch (Throwable e) {
e.printStackTrace();
}
}
if (!foundBetter) {
File f = LibsDisguises.getInstance().getFile();
FileUtil.copy(f, new File(LibsDisguises.getInstance().getDataFolder(), f.getName()));
DisguiseUtilities.getLogger().info("Copied " + f.getName() + " to the plugin folder! You can use dev builds with premium enabled!");
}
}
if (isPremium()) {
boolean prem = getPaidInformation() == null ? getPluginInformation().isLegit() : getPaidInformation().isLegit();
DisguiseUtilities.getLogger().info("Premium enabled, thank you for supporting Lib's Disguises!" + (!prem ? "!" : ""));
}
}
}