305 lines
No EOL
10 KiB
Java
305 lines
No EOL
10 KiB
Java
package nl.sbdeveloper.themeparkplus.util;
|
|
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonParser;
|
|
import org.bukkit.Bukkit;
|
|
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;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
import java.text.ParseException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
|
|
/**
|
|
* License class for SBDevelopment
|
|
*
|
|
* v1.6 - Changed on 06-08-2020
|
|
*
|
|
* @author Stijn [SBDeveloper]
|
|
* @since 23-12-2019
|
|
*/
|
|
public class License implements Listener {
|
|
/*
|
|
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 <stijnbannink23@gmail.com>, January 2020
|
|
*/
|
|
|
|
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
|
|
* @param plugin The Main class [Javaplugin]
|
|
* @param prefix The prefix, like TPP or AF
|
|
* @param license The license from the config
|
|
*/
|
|
public License(JavaPlugin plugin, String prefix, String license) {
|
|
this.prefix = prefix;
|
|
this.plugin = plugin;
|
|
this.license = license;
|
|
|
|
Bukkit.getPluginManager().registerEvents(this, plugin);
|
|
|
|
validateLicense();
|
|
}
|
|
|
|
@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
|
|
*
|
|
*/
|
|
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 response;
|
|
try {
|
|
response = sendGETRequestJSON(url);
|
|
} catch (IOException e) {
|
|
disable("Couldn't send the request.");
|
|
return;
|
|
}
|
|
|
|
if (response == null) {
|
|
disable("Couldn't send the request.");
|
|
return;
|
|
}
|
|
|
|
JsonObject dataObject = response.get("data").getAsJsonObject();
|
|
|
|
//STEP 3: Check status
|
|
switch(dataObject.get("status").getAsString()) {
|
|
case "2":
|
|
//Delivered -> Try to activate (double check timesActivated)
|
|
break;
|
|
case "3":
|
|
//Activated!
|
|
break;
|
|
default:
|
|
disable("Your license has a wrong status.");
|
|
return;
|
|
}
|
|
|
|
//STEP 4: Check times activated, and if not activated, activate.
|
|
if (dataObject.get("timesActivated").isJsonNull() || dataObject.get("timesActivated").getAsString().equalsIgnoreCase("0")) {
|
|
activate();
|
|
return;
|
|
}
|
|
|
|
//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(dataObject.get("expiresAt").getAsString());
|
|
} catch (ParseException e) {
|
|
e.printStackTrace();
|
|
disable("Your license has a wrong expire date.");
|
|
return;
|
|
}
|
|
|
|
if (date == null) {
|
|
disable("Your license has a wrong expire date.");
|
|
return;
|
|
}
|
|
|
|
if (!(date.after(new Date()))) {
|
|
disable("Your license has expired.");
|
|
return;
|
|
}
|
|
|
|
//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;
|
|
}
|
|
|
|
if (dataObject.get("port").isJsonNull()) {
|
|
disable("Your license has no port.");
|
|
return;
|
|
}
|
|
|
|
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 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 response;
|
|
try {
|
|
response = sendGETRequestJSON(url);
|
|
} catch (IOException e) {
|
|
disable("Couldn't send the activate request.");
|
|
return;
|
|
}
|
|
|
|
if (response == null) {
|
|
disable("Couldn't send the activate request.");
|
|
return;
|
|
}
|
|
|
|
JsonObject dataObject = response.get("data").getAsJsonObject();
|
|
|
|
//STEP 2: Check status
|
|
switch(dataObject.get("status").getAsString()) {
|
|
case "2":
|
|
//Delivered -> STILL NOT ACTIVATED?! -> Double check
|
|
break;
|
|
case "3":
|
|
//Activated!
|
|
break;
|
|
default:
|
|
disable("Your license has a wrong status.");
|
|
return;
|
|
}
|
|
|
|
//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.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable the plugin (private)
|
|
*
|
|
* @param reason The disabling reason
|
|
*/
|
|
private void disable(String reason) {
|
|
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);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Send an GET request with JSONObject response
|
|
*
|
|
* @param uri The URL
|
|
*
|
|
* @return The JSONObject
|
|
* @throws IOException URL errors
|
|
*/
|
|
@Nullable
|
|
private JsonObject sendGETRequestJSON(String uri) throws IOException {
|
|
URL url = new URL(uri);
|
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
|
con.setRequestMethod("GET");
|
|
con.setRequestProperty("User-Agent", "Mozilla/5.0");
|
|
String authStringEnc = "Y2tfMGEzNWEzMWE2NzExNmM3NDg2MGEwYTJhNjUxNGVjZjM4NTBmM2JmMDpjc185NmYxZGNlYjI4MWRkZDExOTBjMzQ3ZjJjYzMwMGNjZTIzYWNhODI1";
|
|
con.setRequestProperty("Authorization", "Basic " + authStringEnc);
|
|
int code = con.getResponseCode();
|
|
if (code == 404) {
|
|
disable("404_error");
|
|
return null;
|
|
}
|
|
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
|
String inputLine;
|
|
StringBuilder response = new StringBuilder();
|
|
while ((inputLine = in.readLine()) != null) {
|
|
response.append(inputLine);
|
|
}
|
|
in.close();
|
|
|
|
JsonParser parser = new JsonParser();
|
|
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;
|
|
}
|
|
} |