New ServerID system finished, filteraction has a string formatting bug.
This commit is contained in:
@@ -2,9 +2,6 @@ package io.github.thetrouper.sentinel;
|
||||
|
||||
import club.minnced.discord.webhook.WebhookClient;
|
||||
import club.minnced.discord.webhook.WebhookClientBuilder;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbed;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbedBuilder;
|
||||
import club.minnced.discord.webhook.send.WebhookMessageBuilder;
|
||||
import io.github.itzispyder.pdk.PDK;
|
||||
import io.github.itzispyder.pdk.utils.misc.JsonSerializable;
|
||||
import io.github.thetrouper.sentinel.auth.Auth;
|
||||
@@ -21,7 +18,6 @@ import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public final class Sentinel extends JavaPlugin {
|
||||
@@ -46,6 +42,9 @@ public final class Sentinel extends JavaPlugin {
|
||||
|
||||
public static final Logger log = Bukkit.getLogger();
|
||||
public static boolean usesDynamicIP;
|
||||
public static String serverID;
|
||||
public static String license;
|
||||
public static String IP;
|
||||
public static WebhookClient webclient;
|
||||
|
||||
/**
|
||||
@@ -65,9 +64,9 @@ public final class Sentinel extends JavaPlugin {
|
||||
log.info("Language Status: (" + language.get("if-you-see-this-lang-is-broken") + ")");
|
||||
|
||||
log.info("Initializing Server ID...");
|
||||
String serverID = Authenticator.getServerID();
|
||||
serverID = Authenticator.getServerID();
|
||||
|
||||
String license = mainConfig.plugin.license;
|
||||
license = mainConfig.plugin.license;
|
||||
|
||||
log.info("Pre-load finished!\n]====---- Requesting Authentication ----====[ \n- License Key: " + license + " \n- Server ID: " + serverID);
|
||||
log.info("Auth Requested...");
|
||||
@@ -76,7 +75,7 @@ public final class Sentinel extends JavaPlugin {
|
||||
try {
|
||||
authStatus = Authenticator.authorize(license, serverID);
|
||||
authstatus = Auth.authorize(license, serverID);
|
||||
|
||||
IP = Authenticator.getPublicIPAddress();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.info("WTFFFF ARE YOU DOING MAN??????");
|
||||
@@ -89,17 +88,15 @@ public final class Sentinel extends JavaPlugin {
|
||||
}
|
||||
case "MINEHUT" -> {
|
||||
usesDynamicIP = true;
|
||||
String minehutStatus = Telemetry.loadTelemetryHook(serverID, license);
|
||||
switch (minehutStatus) {
|
||||
case "SUCCESS" -> {
|
||||
authstatus = authstatus.replaceAll("ur a skid lmao","get out of here kiddo");
|
||||
log.info("Dynamic IP auth Success! " + authstatus);
|
||||
startup();
|
||||
}
|
||||
case "FAILURE" -> {
|
||||
log.info("Dynamic IP Failure. Webhook Error possible? Please contact obvWolf to fix this.");
|
||||
manager.disablePlugin(this);
|
||||
}
|
||||
Telemetry.initTelemetryHook();
|
||||
boolean minehutStatus = Telemetry.sendStartupLog();
|
||||
if (minehutStatus) {
|
||||
authstatus = authstatus.replaceAll("ur a skid lmao", "get out of here kiddo");
|
||||
log.info("Dynamic IP auth Success! " + authstatus);
|
||||
startup();
|
||||
} else {
|
||||
log.info("Dynamic IP Failure. Webhook Error possible? Please contact obvWolf to fix this.");
|
||||
manager.disablePlugin(this);
|
||||
}
|
||||
}
|
||||
case "INVALID-ID" -> {
|
||||
@@ -214,7 +211,7 @@ public final class Sentinel extends JavaPlugin {
|
||||
// Plugin shutdown logic
|
||||
log.info("Sentinel has disabled! (" + getDescription().getVersion() + ") Your server is now no longer protected!");
|
||||
if (usesDynamicIP) {
|
||||
Telemetry.sendShutdownLog(Authenticator.getServerID(), mainConfig.plugin.license);
|
||||
Telemetry.sendShutdownLog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ final
|
||||
String
|
||||
ENCRYPTION_KEY
|
||||
=
|
||||
"If I am reading this and I am not a verified developer for Sentinel AntiNuke, I solely swear that my attempts to de-obfuscate this plugin are purely for virus investigation, and have malicious intentions such as cracking, leaking, or ratting this plugin.";
|
||||
"If I am reading this and I am not a verified developer for Sentinel AntiNuke, I solely swear that my attempts to de-obfuscate this plugin are purely for rat checking, and have malicious intentions such as cracking, leaking, or ratting this plugin.";
|
||||
private
|
||||
static
|
||||
final
|
||||
|
||||
@@ -7,12 +7,18 @@ import io.github.itzispyder.pdk.commands.Permission;
|
||||
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.server.functions.ProfanityFilter;
|
||||
import io.github.thetrouper.sentinel.server.functions.Telemetry;
|
||||
import io.github.thetrouper.sentinel.server.util.CipherUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.Text;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.HashSet;
|
||||
@CommandRegistry(value = "sentinel",permission = @Permission("sentinel.debug"))
|
||||
public class SentinelCommand implements CustomCommand {
|
||||
@@ -51,6 +57,20 @@ public class SentinelCommand implements CustomCommand {
|
||||
debugMode = !debugMode;
|
||||
p.sendMessage(Text.prefix((debugMode ? "Enabled" : "Disabled") + " debug mode."));
|
||||
}
|
||||
case "encrypt" -> {
|
||||
final String enc = CipherUtils.encrypt(args.getAll(2).toString());
|
||||
final String check = CipherUtils.decrypt(enc);
|
||||
final String main = Text.prefix("Successfully encrypted \"&e" + check + "&7\" using AES.\n &7> &b" + enc);
|
||||
Sentinel.log.info(args.getAll(2).toString() + "\n" + enc + "\n" + check);
|
||||
TextComponent message = new TextComponent();
|
||||
message.setText(main);
|
||||
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new net.md_5.bungee.api.chat.hover.content.Text("&bClick to copy!")));
|
||||
message.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, enc));
|
||||
p.spigot().sendMessage(message);
|
||||
}
|
||||
case "tele" -> {
|
||||
p.sendMessage(Telemetry.fetchTelemetryHook());
|
||||
}
|
||||
}
|
||||
}
|
||||
case "getHeat" -> {
|
||||
|
||||
@@ -122,7 +122,7 @@ public class FilterAction {
|
||||
description.append("%1$sPlayer: `%2$s` %3$s".formatted(Emojis.rightSort,offender.getName(),Emojis.target));
|
||||
switch (type) {
|
||||
case SPAM_PUNISH -> {
|
||||
description.append("%1$s%2$sHeat: `%3$s/%4$s`".formatted(
|
||||
description.append("\n%1$s%2$sHeat: `%3$s/%4$s`".formatted(
|
||||
Emojis.space,
|
||||
Emojis.arrowRight,
|
||||
heatMap.get(offender),
|
||||
@@ -135,7 +135,7 @@ public class FilterAction {
|
||||
currentValue = e.getMessage();
|
||||
}
|
||||
case SWEAR_PUNISH -> {
|
||||
description.append("%1$s%2$sScore: `%3$s/%4$s`".formatted(
|
||||
description.append("\n%1$s%2$sScore: `%3$s/%4$s`".formatted(
|
||||
Emojis.space,
|
||||
Emojis.arrowRight,
|
||||
scoreMap.get(offender),
|
||||
@@ -158,7 +158,7 @@ public class FilterAction {
|
||||
.setDescription(String.valueOf(description))
|
||||
.addField(new WebhookEmbed.EmbedField(true,historyTitle,historyValue))
|
||||
.addField(new WebhookEmbed.EmbedField(true,currentTitle,currentValue))
|
||||
.addField(new WebhookEmbed.EmbedField(false,"Executed: ", executed))
|
||||
.addField(new WebhookEmbed.EmbedField(false,"Executed: ", executed.replaceAll("%player%",offender.getName())))
|
||||
.setThumbnailUrl("https://crafatar.com/avatars/" + offender.getUniqueId() + "?size=64&&overlay")
|
||||
.setColor(type.getColor().getRGB())
|
||||
.build())
|
||||
|
||||
@@ -23,8 +23,8 @@ public class Authenticator {
|
||||
public static String getServerID() {
|
||||
try {
|
||||
return MathUtils.SHA512(getPublicIPAddress());
|
||||
} catch (IOException e) {
|
||||
return e.getMessage();
|
||||
} catch (Exception e) {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,145 +1,137 @@
|
||||
package io.github.thetrouper.sentinel.server.functions;
|
||||
|
||||
import club.minnced.discord.webhook.WebhookClient;
|
||||
import club.minnced.discord.webhook.WebhookClientBuilder;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbed;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbedBuilder;
|
||||
import club.minnced.discord.webhook.send.WebhookMessage;
|
||||
import club.minnced.discord.webhook.send.WebhookMessageBuilder;
|
||||
import io.github.thetrouper.sentinel.Sentinel;
|
||||
import io.github.thetrouper.sentinel.discord.DiscordWebhook;
|
||||
import io.github.thetrouper.sentinel.data.Emojis;
|
||||
import io.github.thetrouper.sentinel.server.util.CipherUtils;
|
||||
import io.github.thetrouper.sentinel.server.util.ServerUtils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Telemetry {
|
||||
|
||||
public Telemetry() throws UnknownHostException {
|
||||
}
|
||||
static InetAddress IP;
|
||||
|
||||
static {
|
||||
try {
|
||||
IP = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
public static WebhookClient telemetryHook;
|
||||
public static void initTelemetryHook() {
|
||||
WebhookClientBuilder builder = new WebhookClientBuilder(fetchTelemetryHook());
|
||||
builder.setThreadFactory((job) -> {
|
||||
Thread thread = new Thread(job);
|
||||
thread.setName("WebhookThread");
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
builder.setWait(true);
|
||||
telemetryHook = builder.build();
|
||||
}
|
||||
|
||||
public static String telemetryHook;
|
||||
|
||||
public static String loadTelemetryHook(String serverID, String licenseKey) {
|
||||
String hook = "";
|
||||
public static boolean sendStartupLog() {
|
||||
WebhookMessage embed = new WebhookMessageBuilder()
|
||||
.setUsername("Sentinel Anti-Nuke | Telemetry")
|
||||
.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png").
|
||||
addEmbeds(new WebhookEmbedBuilder()
|
||||
.setAuthor(new WebhookEmbed.EmbedAuthor("Server Startup Log",null,"https://builtbybit.com/resources/sentinel-anti-nuke.30130/"))
|
||||
.setTitle(new WebhookEmbed.EmbedTitle("A server has started up successfully",null))
|
||||
.setDescription("Server " + Sentinel.serverID + "\n" +
|
||||
Emojis.rightSort + " License: ||" + Sentinel.license + "||\n" +
|
||||
Emojis.rightSort + " IP: ||" + Sentinel.IP + "||")
|
||||
.setColor(Color.GREEN.getRGB())
|
||||
.build())
|
||||
.build();
|
||||
try {
|
||||
URL url = new URL("https://sentinelauth.000webhostapp.com/telemetrykey.html");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
|
||||
List<String> lines = readLines(reader);
|
||||
|
||||
for (String line : lines) {
|
||||
if (line.contains("data-id")) {
|
||||
hook = extractValue(line, "data-hook");
|
||||
telemetryHook = hook;
|
||||
Map<String,String> response = sendStartupLog(serverID,licenseKey);
|
||||
|
||||
if (response.containsKey("SUCCESS")) {
|
||||
Sentinel.log.info("Successfully grabbed telemetry hook");
|
||||
return "SUCCESS";
|
||||
} else {
|
||||
Sentinel.log.info("An Error occurred while attempting to connect to the telemetry hook: " + response.get("ERROR"));
|
||||
return "FAIL";
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
public static Map<String, String> testWebhook(String hook) {
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("SUCCESS", "NULL");
|
||||
DiscordWebhook webhook = new DiscordWebhook(hook);
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setAuthor("Test Success!", "", "")
|
||||
.setDescription("Connected to webhook")
|
||||
.setColor(Color.GREEN);
|
||||
webhook.addEmbed(embed);
|
||||
try {
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
response.clear();
|
||||
response.put("ERROR", e.toString());
|
||||
return response;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
public static List<String> readLines(BufferedReader reader) {
|
||||
try {
|
||||
List<String> lines = new ArrayList<>();
|
||||
String line = reader.readLine();
|
||||
while (line != null) {
|
||||
lines.add(line);
|
||||
line = reader.readLine();
|
||||
}
|
||||
reader.close();
|
||||
return lines;
|
||||
telemetryHook.send(embed);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.info("Failed to initialize dynamic auth!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sendShutdownLog() {
|
||||
WebhookMessage embed = new WebhookMessageBuilder()
|
||||
.setUsername("Sentinel Anti-Nuke | Telemetry")
|
||||
.setAvatarUrl("https://r2.e-z.host/d440b58a-ba90-4839-8df6-8bba298cf817/3lwit5nt.png").
|
||||
addEmbeds(new WebhookEmbedBuilder()
|
||||
.setAuthor(new WebhookEmbed.EmbedAuthor("Server Shutdown Log",null,"https://builtbybit.com/resources/sentinel-anti-nuke.30130/"))
|
||||
.setTitle(new WebhookEmbed.EmbedTitle("A server has shut down successfully",null))
|
||||
.setDescription("Server " + Sentinel.serverID + "\n" +
|
||||
Emojis.rightSort + " License: ||" + Sentinel.license + "||\n" +
|
||||
Emojis.rightSort + " IP: ||" + Sentinel.IP + "||")
|
||||
.setColor(Color.RED.getRGB())
|
||||
.build())
|
||||
.build();
|
||||
try {
|
||||
telemetryHook.send(embed);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.info("Failed to send dynamic shutdown!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String fetchTelemetryHook() {
|
||||
try {
|
||||
final String webhook = extractWebhook(fetchHtmlContent("https://trouper.me/auth/telemetry"));
|
||||
ServerUtils.sendDebugMessage("Original Webhook: " + webhook);
|
||||
|
||||
String webhookIdPart = webhook.replaceAll(".*/(\\d+)/([^/]+.*)$", "/$1/");
|
||||
ServerUtils.sendDebugMessage("Webhook ID Part: " + webhookIdPart);
|
||||
|
||||
String encrypted = webhook.replaceAll(".*/\\d+/([^/]+.*)$", "$1");
|
||||
ServerUtils.sendDebugMessage("Encrypted Part: " + encrypted);
|
||||
|
||||
String isolated = webhook.replaceAll("/\\d+/([^/]+.*)$", "");
|
||||
ServerUtils.sendDebugMessage("Isolated Part: " + isolated);
|
||||
|
||||
String decrypted = isolated + webhookIdPart + CipherUtils.decrypt(encrypted);
|
||||
ServerUtils.sendDebugMessage("Decrypted Result: " + decrypted);
|
||||
|
||||
return decrypted;
|
||||
} catch (Exception ex) {
|
||||
Sentinel.log.warning("FAILED TO LOAD TELEMETRY (Are the servers up?)");
|
||||
ex.printStackTrace();
|
||||
return "NULL";
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public static String extractValue(String line, String attribute) {
|
||||
int start = line.indexOf(attribute + "=\"") + attribute.length() + 2;
|
||||
int end = line.indexOf("\"", start);
|
||||
return line.substring(start, end);
|
||||
}
|
||||
private static String fetchHtmlContent(String urlString) throws Exception {
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
public static Map<String, String> sendStartupLog(String serverID, String licenseKey) {
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("SUCCESS", "NULL");
|
||||
DiscordWebhook webhook = new DiscordWebhook(telemetryHook);
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setAuthor("Server Startup Log", "", "")
|
||||
.setTitle("Dynamic IP server connected")
|
||||
.setDescription("License key: `"+ licenseKey + "`\\n" +
|
||||
"Server ID: `" + serverID + "`")
|
||||
.setColor(Color.GREEN);
|
||||
webhook.addEmbed(embed);
|
||||
try {
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
response.clear();
|
||||
response.put("ERROR", e.toString());
|
||||
return response;
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
return response;
|
||||
|
||||
reader.close();
|
||||
connection.disconnect();
|
||||
|
||||
return response.toString();
|
||||
}
|
||||
public static Map<String, String> sendShutdownLog(String serverID, String licenseKey) {
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("SUCCESS", "NULL");
|
||||
DiscordWebhook webhook = new DiscordWebhook(telemetryHook);
|
||||
DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject()
|
||||
.setAuthor("Server Shutdown Log", "", "")
|
||||
.setTitle("Dynamic IP server disconnected")
|
||||
.setDescription("License key: `"+ licenseKey + "`\\n" +
|
||||
"Server ID: `" + serverID + "`")
|
||||
.setColor(Color.RED);
|
||||
webhook.addEmbed(embed);
|
||||
try {
|
||||
webhook.execute();
|
||||
} catch (IOException e) {
|
||||
response.clear();
|
||||
response.put("ERROR", e.toString());
|
||||
return response;
|
||||
|
||||
private static String extractWebhook(String htmlContent) {
|
||||
String pattern = "data-hook=\"(.*?)\"";
|
||||
Pattern r = Pattern.compile(pattern);
|
||||
Matcher m = r.matcher(htmlContent);
|
||||
|
||||
if (m.find()) {
|
||||
return m.group(1);
|
||||
} else {
|
||||
return "Webhook ID not found";
|
||||
}
|
||||
return response;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.github.thetrouper.sentinel.server.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
public class CipherUtils {
|
||||
private static final String secretKey = "GG8T885O4Yd/86OMVFdL0w=="; // 16, 24, or 32 bytes
|
||||
private static final String algorithm = "AES";
|
||||
public static String encrypt(String strToEncrypt) {
|
||||
try {
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
|
||||
byte[] encryptedBytes = cipher.doFinal(strToEncrypt.getBytes());
|
||||
return Base64.getEncoder().encodeToString(encryptedBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String decrypt(String strToDecrypt) {
|
||||
try {
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
|
||||
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(strToDecrypt));
|
||||
return new String(decryptedBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user