License system

This commit is contained in:
ceze88 2023-01-02 13:39:54 +01:00
parent bd187c7512
commit 10aac8c10f
3 changed files with 226 additions and 1 deletions

View File

@ -8,6 +8,8 @@ import com.songoda.core.core.PluginInfo;
import com.songoda.core.core.PluginInfoModule;
import com.songoda.core.core.SongodaCoreCommand;
import com.songoda.core.core.SongodaCoreDiagCommand;
import com.songoda.core.core.SongodaCoreIPCommand;
import com.songoda.core.core.SongodaCoreSetAPIKeyCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -24,13 +26,20 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -67,6 +76,7 @@ public class SongodaCore {
private CommandManager commandManager;
private EventListener loginListener;
private ShadedEventListener shadingListener;
private static String apiKey;
public static boolean hasShading() {
// sneaky hack to check the package name since maven tries to re-shade all references to the package string
@ -172,7 +182,7 @@ public class SongodaCore {
private void init() {
shadingListener = new ShadedEventListener();
commandManager.registerCommandDynamically(new SongodaCoreCommand())
.addSubCommand(new SongodaCoreDiagCommand());
.addSubCommands(new SongodaCoreDiagCommand(), new SongodaCoreIPCommand(), new SongodaCoreSetAPIKeyCommand());
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
@ -188,6 +198,82 @@ public class SongodaCore {
20 * 60 * 2));
}
private boolean checkAPIKey() {
String currentDir = System.getProperty("user.dir");
File tokenFile = new File(currentDir).getParentFile().toPath().resolve(".songoda-marketplace.key").toFile();
if (!tokenFile.exists()) {
return false;
}
try (BufferedReader reader = new BufferedReader(new FileReader(tokenFile))) {
String token = reader.readLine();
if (token == null || token.isEmpty()) {
return false;
}
token = token;
return true;
} catch (IOException ex) {
return false;
}
}
public static void setAPIKey(String token) {
token = token;
//Save token to file
String currentDir = System.getProperty("user.dir");
File tokenFile = new File(currentDir).getParentFile().toPath().resolve(".songoda-marketplace.key").toFile();
try (BufferedWriter writer = new BufferedWriter(new FileWriter(tokenFile))) {
writer.write(token);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public String getAPIKey() {
return apiKey;
}
public static boolean hasAPIKey() {
return apiKey != null;
}
private boolean checkPluginAccess(int id, String name) {
//No need to check Ultimate series since they are all free
if (name.toLowerCase().startsWith("ultimate")) {
return true;
}
if (!hasAPIKey()) {
return false;
}
try {
URL url = new URL("https://marketplace.songoda.com/api/v2/products/license/validate");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setDoOutput(true);
String jsonInputString = "{\"product_id\":" + id + ",\"license\":\"" + apiKey + "\"}";
try(OutputStream os = con.getOutputStream()) {
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
try(BufferedReader br = new BufferedReader(
new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
return response.toString().contains("true");
}
} catch (Exception e) {
logger.log(Level.WARNING, "Error checking plugin access for " + name);
}
return true;
}
/**
* Used to yield this core to a newer core
*/
@ -210,6 +296,15 @@ public class SongodaCore {
private ArrayList<BukkitTask> tasks = new ArrayList<>();
private void register(JavaPlugin plugin, int pluginID, String icon, String libraryVersion) {
if(!checkPluginAccess(pluginID, plugin.getName())) {
plugin.getServer().getPluginManager().disablePlugin(plugin);
if (hasAPIKey()) {
logger.log(Level.WARNING, "You do not have access to " + plugin.getName() + " on this server. Please check your license key.");
} else {
logger.log(Level.WARNING, "You do not have access to " + plugin.getName() + " on this server. Please set your license key.");
}
return;
}
logger.info(getPrefix() + "Hooked " + plugin.getName() + ".");
PluginInfo info = new PluginInfo(plugin, pluginID, icon, libraryVersion);

View File

@ -0,0 +1,75 @@
package com.songoda.core.core;
import com.songoda.core.commands.AbstractCommand;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.bukkit.command.CommandSender;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class SongodaCoreIPCommand extends AbstractCommand {
public SongodaCoreIPCommand() {
super(CommandType.CONSOLE_OK, "myip");
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
try {
HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://marketplace.songoda.com/api/v2/products/license/ip");
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
try (InputStream inputStream = entity.getContent()) {
//Read json and get ip key value
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String ip = (String) json.get("ip");
sender.sendMessage("");
sender.sendMessage("IP Information");
sender.sendMessage("");
sender.sendMessage("Public IP: " + ip);
sender.sendMessage("");
return ReturnType.SUCCESS;
} catch (Exception ignored) {}
}
} catch (Exception ignored) {}
sender.sendMessage("Error: Could not get IP information.");
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}
@Override
public String getPermissionNode() {
return "songoda.admin";
}
@Override
public String getSyntax() {
return "/songoda myip";
}
@Override
public String getDescription() {
return "Displays your public IP address.";
}
}

View File

@ -0,0 +1,55 @@
package com.songoda.core.core;
import com.songoda.core.SongodaCore;
import com.songoda.core.commands.AbstractCommand;
import org.bukkit.command.CommandSender;
import java.util.List;
import java.util.UUID;
public class SongodaCoreSetAPIKeyCommand extends AbstractCommand {
public SongodaCoreSetAPIKeyCommand() {
super(CommandType.CONSOLE_OK, "key");
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
if (args.length == 0) {
sender.sendMessage("Please provide an API key.");
return ReturnType.FAILURE;
}
String key = args[0];
//Let's check if the key is in the correct format
UUID uuid = UUID.fromString(key);
if (uuid.version() != 4) {
sender.sendMessage("The API key you provided is not in the correct format.");
return ReturnType.FAILURE;
}
SongodaCore.setAPIKey(key);
sender.sendMessage("API key set.");
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}
@Override
public String getPermissionNode() {
return "songodacore.admin";
}
@Override
public String getSyntax() {
return "/songodacore key <key>";
}
@Override
public String getDescription() {
return "Sets the stored API key.";
}
}