diff options
author | HacktheTime <l4bg0jb7@duck.com> | 2023-10-12 20:17:28 +0200 |
---|---|---|
committer | HacktheTime <l4bg0jb7@duck.com> | 2023-10-12 20:17:28 +0200 |
commit | dba4a297e295d68980da31264b0069fe9b18a13e (patch) | |
tree | c7e0a99968ef34509037f969ab7b1beba04a996d /common/src | |
parent | e111619d66346a2309b86a00420681f4cddf3cea (diff) | |
download | BBsentials-dba4a297e295d68980da31264b0069fe9b18a13e.tar.gz BBsentials-dba4a297e295d68980da31264b0069fe9b18a13e.tar.bz2 BBsentials-dba4a297e295d68980da31264b0069fe9b18a13e.zip |
preperations to have a common code and different implementations for forge and fabric to ease up maintaining both versions
Diffstat (limited to 'common/src')
55 files changed, 3568 insertions, 0 deletions
diff --git a/common/src/main/java/de/hype/bbsentials/common/api/Discord.java b/common/src/main/java/de/hype/bbsentials/common/api/Discord.java new file mode 100644 index 0000000..6b2f468 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/api/Discord.java @@ -0,0 +1,70 @@ +package de.hype.bbsentials.common.api; + +import de.hype.bbsentials.common.chat.Chat; +import de.hype.bbsentials.common.client.BBsentials; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class Discord { + public static void sendWebhookMessage(String message) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + sendWebhookMessageNoThread(message); + } + }); + thread.start(); + } + + + public static void sendWebhookMessageNoThread(String message) { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String WEBHOOK_URL = "https://discord.com/api/v8/webhooks/1127524566407860276/" + BBsentials.getConfig().getApiKey(); + + + try { + HttpPost httpPost = new HttpPost(WEBHOOK_URL); + + StringEntity jsonEntity = new StringEntity("{\"content\": \"" + message + "\"}", StandardCharsets.UTF_8); + jsonEntity.setContentType("application/json"); + httpPost.setEntity(jsonEntity); + + CloseableHttpResponse response = httpClient.execute(httpPost); + HttpEntity responseEntity = response.getEntity(); + + if (responseEntity != null) { + InputStream inputStream = responseEntity.getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + + String line; + StringBuilder responseBuilder = new StringBuilder(); + while ((line = reader.readLine()) != null) { + responseBuilder.append(line); + } + + String responseString = responseBuilder.toString(); + Chat.sendPrivateMessageToSelfInfo(responseString); + } + + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/api/Formatting.java b/common/src/main/java/de/hype/bbsentials/common/api/Formatting.java new file mode 100644 index 0000000..c8702d4 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/api/Formatting.java @@ -0,0 +1,36 @@ +package de.hype.bbsentials.common.api; + +public enum Formatting{ + BLACK("§0"), + DARK_BLUE("§1"), + DARK_GREEN("§2"), + DARK_AQUA("§3"), + DARK_RED("§4"), + DARK_PURPLE("§5"), + GOLD("§6"), + GRAY("§7"), + DARK_GRAY("§8"), + BLUE("§9"), + GREEN("§a"), + AQUA("§b"), + RED("§c"), + LIGHT_PURPLE("§d"), + YELLOW("§e"), + BOLD("§l"), + ITALIC("§o"), + UNDERLINE("§n"), + STRIKETHROUGH("§m"), + RESET("§r"), + WHITE("§f"); + + private final String code; + + Formatting(String code) { + this.code = code; + } + + @Override + public String toString() { + return code; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/api/ISimpleOption.java b/common/src/main/java/de/hype/bbsentials/common/api/ISimpleOption.java new file mode 100644 index 0000000..28808d9 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/api/ISimpleOption.java @@ -0,0 +1,5 @@ +package de.hype.bbsentials.common.api; + +public interface ISimpleOption { + void set(Object value); +} diff --git a/common/src/main/java/de/hype/bbsentials/common/chat/Chat.java b/common/src/main/java/de/hype/bbsentials/common/chat/Chat.java new file mode 100644 index 0000000..1d7aef1 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/chat/Chat.java @@ -0,0 +1,441 @@ +package de.hype.bbsentials.common.chat; + +import de.hype.bbsentials.common.api.Formatting; +import de.hype.bbsentials.common.client.BBsentials; +import de.hype.bbsentials.common.client.Config; +import de.hype.bbsentials.common.packets.packets.SplashUpdatePacket; +import net.minecraft.text.Text; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.time.Instant; +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; + +import static de.hype.bbsentials.common.client.BBsentials.*; + +public class Chat { + + public static String[] getVariableInfo(String packageName, String className) { + List<String> variableInfoList = new ArrayList<>(); + + // Combine the class name with the package name + String fullClassName = packageName + "." + className; + + // Load the class + Class<?> clazz = null; + try { + clazz = Class.forName(fullClassName); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + // Extract fields of the class + Field[] fields = clazz.getDeclaredFields(); + + // Collect information for each field + for (Field field : fields) { + // Exclude transient fields + if (java.lang.reflect.Modifier.isTransient(field.getModifiers())) { + continue; + } + String variableName = field.getName(); + String variablePackageName = clazz.getPackage().getName(); + String variableClassName = clazz.getSimpleName(); + + variableInfoList.add(variableName); + } + + return variableInfoList.toArray(new String[variableInfoList.size()]); + } + + public static void setVariableValue(Object obj, String variableName, String value) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { + if (value == null) { + // Handle null value case + sendPrivateMessageToSelfError("Invalid value: null"); + return; + } + + Class<?> objClass = obj.getClass(); + Field field = objClass.getDeclaredField(variableName); + field.setAccessible(true); + + // Get the type of the field + Class<?> fieldType = field.getType(); + + // Convert the value to the appropriate type + Object convertedValue = parseValue(value, fieldType); + + if (Modifier.isStatic(field.getModifiers())) { + // If the field is static + field.set(null, convertedValue); + } + else { + field.set(obj, convertedValue); + } + + // Check and output the value of the variable + sendPrivateMessageToSelfSuccess("The variable " + field.getName() + " is now: " + field.get(obj)); + } + + private static Object parseValue(String value, Class<?> targetType) { + if (targetType == int.class || targetType == Integer.class) { + return Integer.parseInt(value); + } + else if (targetType == double.class || targetType == Double.class) { + return Double.parseDouble(value); + } + else if (targetType == float.class || targetType == Float.class) { + return Float.parseFloat(value); + } + else if (targetType == long.class || targetType == Long.class) { + return Long.parseLong(value); + } + else if (targetType == boolean.class || targetType == Boolean.class) { + return Boolean.parseBoolean(value); + } + else { + // For other types, return the original string value + return value; + } + } + + public static void getVariableValue(Object object, String variableName) throws NoSuchFieldException, IllegalAccessException { + Class<?> objClass = object.getClass(); + Field field = objClass.getDeclaredField(variableName); + field.setAccessible(true); + sendPrivateMessageToSelfSuccess("The variable " + field.getName() + " is: " + field.get(object)); + } + + public Message onEvent(Message text) { + if (!isSpam(text.toString())) { + if (getConfig().isDetailedDevModeEnabled()) { + System.out.println("got a message: " + text.getJson()); + } + Message message = new Message(text.toString(),text.getString()); + executionService.execute(() -> processThreaded(message)); + return processNotThreaded(message); + } + return text; // Return the original message if it is spam + } + + //Handle in the messages which need to be modified here + public Message processNotThreaded(Message message) { +// if (message.isFromParty()) { +// message.replaceInJson("\"action\":\"run_command\",\"value\":\"/viewprofile", "\"action\":\"run_command\",\"value\":\"/bviewprofile " + messageUnformatted.split(">", 1)[1].trim()); +// } + if (message.isFromReportedUser()) { + sendPrivateMessageToSelfBase(Formatting.RED + "B: " + message.getUnformattedString()); + return null; + } + if (config.doPartyChatCustomMenu && message.isFromParty()) { + message.replaceInJson("/viewprofile \\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}", "/socialoptions party " + message.getPlayerName() + " " + message.getUnformattedString()); + } + else if (config.doGuildChatCustomMenu && message.isFromGuild()) { + message.replaceInJson("/viewprofile \\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}", "/socialoptions guild " + message.getPlayerName() + " " + message.getUnformattedString()); + } + else if (config.doAllChatCustomMenu) { + System.out.println("User: '" + message.getPlayerName() + "' | Message: " + message.getUnformattedString()); + message.replaceInJson("/socialoptions " + message.getPlayerName(), "/socialoptions sb " + message.getPlayerName() + " " + message.getUnformattedString()); + } + + return message; + } + + public void processThreaded(Message message) { + if (message.getString() != null) { + String messageUnformatted = message.getUnformattedString(); + String username = message.getPlayerName(); + if (message.isFromReportedUser()) { + + } + else if (!MCUtils.isWindowFocused()) { + if (config.doDesktopNotifications) { + if ((messageUnformatted.endsWith("is visiting Your Garden !") || messageUnformatted.endsWith("is visiting Your Island !")) && !MCUtils.isWindowFocused() && config.doDesktopNotifications) { + sendNotification("BBsentials Visit-Watcher", messageUnformatted); + } + else if (message.isMsg()) { + sendNotification("BBsentials Message Notifier", username + " sent you the following message: " + message.getMessageContent()); + } + if (message.getMessageContent().toLowerCase().contains(getConfig().getUsername().toLowerCase()) || (message.getMessageContent().toLowerCase().contains(getConfig().getNickname().toLowerCase() + " ") && getConfig().getNotifForParty().toLowerCase().equals("nick")) || getConfig().getNotifForParty().toLowerCase().equals("all")) { + sendNotification("BBsentials Party Chat Notification", username + " : " + message.getMessageContent()); + } + else { + if (message.getMessageContent().toLowerCase().contains(getConfig().getUsername().toLowerCase()) || message.getMessageContent().toLowerCase().contains(config.getNickname().toLowerCase() + " ")) { + sendNotification("BBsentials Notifier", "You got mentioned in chat! " + message.getMessageContent()); + } + } + } + } + else if (message.isServerMessage()) { + if (messageUnformatted.contains("disbanded the party")) { + lastPartyDisbandedUsername = username; + partyDisbandedMap.put(username, Instant.now()); + } + else if (message.contains("invited you to join their party")) { + if (lastPartyDisbandedUsername != null && partyDisbandedMap != null) { + Instant lastDisbandedInstant = partyDisbandedMap.get(lastPartyDisbandedUsername); + if (config.acceptReparty) { + if (lastDisbandedInstant != null && lastDisbandedInstant.isAfter(Instant.now().minusSeconds(20)) && (username.equals(lastPartyDisbandedUsername))) { + sendCommand("/p accept " + username); + } + } + } + if (!MCUtils.isWindowFocused()) { + sendNotification("BBsentials Party Notifier", "You got invited too a party by: " + username); + } + } + else if (message.startsWith("Party Members (")) { + Config.partyMembers = new ArrayList<>(); + } + else if (message.startsWith("Party Moderators:")) { + String temp = messageUnformatted.replace("Party Moderators:", "").replace(" ●", "").replaceAll("\\s*\\[[^\\]]+\\]", "").trim(); + if (temp.contains(",")) { + for (int i = 0; i < temp.split(",").length; i++) { + Config.partyMembers.add(temp.split(",")[i - 1]); + } + } + else { + Config.partyMembers.add(temp); + } + } + else if (message.startsWith("Party Members:")) { + String temp = messageUnformatted.replace("Party Members:", "").replace(" ●", "").replaceAll("\\s*\\[[^\\]]+\\]", "").trim(); + if (temp.contains(",")) { + for (int i = 0; i < temp.split(",").length; i++) { + System.out.println("Added to plist: " + (temp.split(",")[i - 1])); + Config.partyMembers.add(temp.split(",")[i - 1]); + } + } + else { + Config.partyMembers.add(temp); + } + } + else if ((message.contains("Party Leader:") && !message.contains(getConfig().getUsername())) || message.equals("You are not currently in a party.") || (message.contains("warped the party into a Skyblock Dungeon") && !message.startsWith(getConfig().getUsername()) || (!message.startsWith("The party was transferred to " + getConfig().getUsername()) && message.startsWith("The party was transferred to"))) || messageUnformatted.endsWith(getConfig().getUsername() + " is now a Party Moderator") || (message.startsWith("The party was disbanded")) || (message.contains("You have joined ") && message.contains("'s party!")) || (message.contains("Party Leader, ") && message.contains(" , summoned you to their server.")) || (message.contains("warped to your dungeon"))) { + BBsentials.getConfig().setIsLeader(false); + if (getConfig().isDetailedDevModeEnabled()) { + sendPrivateMessageToSelfDebug("Leader: " + getConfig().isLeader()); + } + } + else if (config.getPlayersInParty().length == 0 && messageUnformatted.endsWith("to the party! They have 60 seconds to accept")) { + config.setIsLeader(true); + } + else if (messageUnformatted.startsWith("You'll be partying with:")) { + List<String> members = new ArrayList<>(); + for (String users : messageUnformatted.replace("You'll be partying with:", "").replaceAll("\\[[^\\]]*\\]","").trim().split(",")) { + if (users.contains("and ")){break;} + members.add(users); + } + Config.partyMembers=members; + } + else if (((messageUnformatted.startsWith("Party Leader: ") && messageUnformatted.endsWith(getConfig().getUsername() + " ●"))) || (message.contains(getConfig().getUsername() + " warped the party to a SkyBlock dungeon!")) || message.startsWith("The party was transferred to " + getConfig().getUsername()) || message.getUnformattedString().endsWith(" has promoted " + getConfig().getUsername() + " to Party Leader") || (message.contains("warped to your dungeon"))) { + BBsentials.getConfig().setIsLeader(true); + if (getConfig().isDetailedDevModeEnabled()) { + sendPrivateMessageToSelfDebug("Leader: " + getConfig().isLeader()); + } + } + else if (message.getUnformattedString().equals("Please type /report confirm to log your report for staff review.")) { + sendCommand("/report confirm"); + } + else if (messageUnformatted.startsWith("BUFF! You splashed yourself with")) { + if (splashStatusUpdateListener != null) { + splashStatusUpdateListener.setStatus(SplashUpdatePacket.STATUS_SPLASHING); + } + } + } + + else if (message.isFromGuild()) { + + } + else if (message.isFromParty()) { + + } + else if (message.isMsg()) { + if (messageUnformatted.endsWith("bb:party me")) { + if (BBsentials.getConfig().allowBBinviteMe()) { + sendCommand("/p " + username); + } + } + } + else { + if (message.contains("[OPEN MENU]") || message.contains("[YES]")) { + setChatPromtId(message.getJson()); + } + } + } + } + + //{"strikethrough":false,"extra":[{"strikethrough":false,"clickEvent":{"action":"run_command","value":"/viewprofile 4fa1228c-8dd6-47c4-8fe3-b04b580311b8"},"hoverEvent":{"action":"show_text","contents":{"strikethrough":false,"text":"§eClick here to view §bHype_the_Time§e's profile"}},"text":"§9Party §8> §b[MVP§2+§b] Hype_the_Time§f: "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"text":"h:test"}],"text":""}// {"strikethrough":false,"extra":[{"strikethrough":false,"clickEvent":{"action":"run_command","value":"/viewprofile f772b2c7-bd2a-46e1-b1a2-41fa561157d6"},"hoverEvent":{"action":"show_text","contents":{"strikethrough":false,"text":"§eClick here to view §bShourtu§e's profile"}},"text":"§9Party §8> §b[MVP§c+§b] Shourtu§f: "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"text":"Hype_the_Time TEST"}],"text":""} + //{"strikethrough":false,"extra":[{"strikethrough":false,"clickEvent":{"action":"run_command","value":"/viewprofile 4fa1228c-8dd6-47c4-8fe3-b04b580311b8"},"hoverEvent":{"action":"show_text","contents":{"strikethrough":false,"text":"§eClick here to view §bHype_the_Time§e's profile"}},"text":"§9Party §8> §b[MVP§2+§b] Hype_the_Time§f: "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"text":"h:test"}],"text":""} + private final Map<String, Instant> partyDisbandedMap = new HashMap<>(); + private String lastPartyDisbandedUsername = null; + + + public boolean isSpam(String message) { + if (message.contains("Mana")) return true; + if (message.contains("Status")) return true; + if (message.contains("Achievement Points")) return true; + return false; + } + + public String test() { + //put test code here + sendNotification("test", "This is an example which was run of the h:test test"); + return new String(); + } + + public static void sendPrivateMessageToSelfError(String message) { + sendPrivateMessageToSelfBase(Formatting.RED + message); + } + + public static void sendPrivateMessageToSelfFatal(String message) { + sendPrivateMessageToSelfBase(Formatting.DARK_RED + message); + } + + public static void sendPrivateMessageToSelfSuccess(String message) { + sendPrivateMessageToSelfBase(Formatting.GREEN + message); + } + + public static void sendPrivateMessageToSelfInfo(String message) { + sendPrivateMessageToSelfBase(Formatting.YELLOW + message); + } + + public static void sendPrivateMessageToSelfImportantInfo(String message) { + sendPrivateMessageToSelfBase(Formatting.GOLD + message); + } + + public static void sendPrivateMessageToSelfDebug(String message) { + sendPrivateMessageToSelfBase(Formatting.AQUA + message); + } + + private static void sendPrivateMessageToSelfBase(String message) { + MCUtils.sendClientSideMessage(Message.of(message)); + } + + public static void sendPrivateMessageToSelfText(Message message) { + MCUtils.sendClientSideMessage(message); + } + + public static void sendCommand(String s) { + getConfig().sender.addSendTask(s); + } + + public void sendNotification(String title, String text) { + executionService.execute(() -> { + try { + InputStream inputStream = getClass().getResourceAsStream("/sounds/mixkit-sci-fi-confirmation-914.wav"); + AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(inputStream); + Clip clip = AudioSystem.getClip(); + clip.open(audioInputStream); + clip.start(); + Thread.sleep(clip.getMicrosecondLength() / 1000); + clip.close(); + audioInputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + }); + List<String> argsList = new ArrayList<>(); + argsList.add("--title"); + argsList.add(title); + argsList.add("--passivepopup"); + argsList.add(text); + argsList.add("5"); + + try { + ProcessBuilder processBuilder = new ProcessBuilder(); + processBuilder.command("kdialog"); + processBuilder.command().addAll(argsList); + + Process process = processBuilder.start(); + process.waitFor(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + + public static Text createClientSideTellraw(String tellrawInput) { + Text formattedMessage = null; + try { + formattedMessage = Text.Serializer.fromJson(tellrawInput); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Invalid Json: \n" + tellrawInput); + } + return formattedMessage; + } + + public static void setChatPromtId(String logMessage) { + String cbUUIDPattern = "/cb ([a-fA-F0-9-]+)"; + Pattern cbPattern = Pattern.compile(cbUUIDPattern); + Matcher cbMatcher = cbPattern.matcher(logMessage); + + String yesClickAction = "/chatprompt ([a-fA-F0-9-]+) YES"; + Pattern yesPattern = Pattern.compile(yesClickAction); + Matcher yesMatcher = yesPattern.matcher(logMessage); + String lastPrompt = null; + if (cbMatcher.find()) { + lastPrompt = cbMatcher.group(1); + String finalLastPrompt1 = lastPrompt; + new Thread(new Runnable() { + @Override + public void run() { + String promptCommand = "/cb " + finalLastPrompt1; + BBsentials.getConfig().setLastChatPromptAnswer(promptCommand); + if (config.isDevModeEnabled()) { + Chat.sendPrivateMessageToSelfDebug("set the last prompt action too + \"" + promptCommand + "\""); + } + try { + Thread.sleep(10 * 1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + BBsentials.getConfig().setLastChatPromptAnswer(null); + return; + } + }).start(); + } + if (yesMatcher.find()) { + lastPrompt = yesMatcher.group(1); + String finalLastPrompt = lastPrompt; + new Thread(new Runnable() { + @Override + public void run() { + String promptCommand = "/chatprompt " + finalLastPrompt + " YES"; + getConfig().setLastChatPromptAnswer(promptCommand); + if (config.isDevModeEnabled()) { + Chat.sendPrivateMessageToSelfDebug("set the last prompt action too + \"" + promptCommand + "\""); + } + try { + Thread.sleep(10 * 1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + getConfig().setLastChatPromptAnswer(null); + return; + } + }).start(); + + } + } + + public static Text replaceAllForText(Text input, String replace, String replaceWith) { + String text = Text.Serializer.toJson(input); + if (text.contains(replace)) { + text = text.replaceAll("\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}", ""); + } + text = text.replace(replace, replaceWith); + Text output = Text.Serializer.fromJson(text); + return output; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/chat/Message.java b/common/src/main/java/de/hype/bbsentials/common/chat/Message.java new file mode 100644 index 0000000..506146f --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/chat/Message.java @@ -0,0 +1,110 @@ +package de.hype.bbsentials.common.chat; + +import de.hype.bbsentials.common.client.BBsentials; + +public class Message { + private String text; + private String unformattedString = null; + private String playerName = null; + private String string; + + public Message(String textJson,String string) { + this.text = text; + this.string=string; + } + public static Message of(String string){ + return new Message("{\"text\":\""+string+"\"}",string); + } + // + public String getJson() { + return text; + } + + public String getString() { + return string; + } + + public String getUnformattedString() { + if (unformattedString != null) return unformattedString; + unformattedString = string.replaceAll("§.", "").trim(); + return unformattedString; + } + + public String getMessageContent() { + if (isServerMessage()) return unformattedString; + return getUnformattedString().split(":", 2)[1]; + } + + Boolean guild = null; + + public boolean isFromGuild() { + if (guild != null) return guild; + guild = getUnformattedString().startsWith("Guild >"); + return guild; + } + + Boolean party = null; + + public boolean isFromParty() { + if (party != null) return party; + party = getUnformattedString().startsWith("Party >"); + return party; + } + + Boolean msg = null; + + public boolean isMsg() { + if (msg != null) return msg; + msg = getUnformattedString().startsWith("From") || getUnformattedString().startsWith("To"); + return msg; + } + + Boolean server = null; + + public boolean isServerMessage() { + if (server != null) return server; + int space = getUnformattedString().indexOf(" "); + int doublepoint = getUnformattedString().indexOf(":"); + return ((space + 2 < doublepoint)||doublepoint==-1||space==-1); + } + + public String getPlayerName() { + if (playerName != null) return playerName; + playerName = getUnformattedString(); + if (!playerName.contains(":")) { + playerName = ""; + return ""; + } + playerName = playerName.split(":", 2)[0]; + if (isMsg()) { + playerName = playerName.replaceFirst("From", "").replace("To", "").trim(); + } + if (playerName.contains(">")){ + playerName=playerName.split(">",2)[1]; + } +// playerName = playerName.replaceFirst("\\[[^\\]]*\\](?:\\s?[^\\x00-\\x7F]?\\s?\\[[^\\]]*\\])*", "").trim()// replaces every [] and unicode character before a asci character. + playerName = playerName.replaceAll("[^\\x00-\\x7F]","").replaceAll("\\[[^\\]]*\\]","").trim(); + if (playerName.matches("[^a-zA-Z0-9_-]+")) playerName = ""; + return playerName; + } + + public void replaceInJson(String replace, String replaceWith) { + text = text.replaceFirst(replace, replaceWith); + } + public boolean isFromReportedUser() { + return BBsentials.config.alreadyReported.contains(getPlayerName()) && !getPlayerName().isEmpty(); + } + + public boolean contains(String string) { + return getUnformattedString().contains(string); + } + + public boolean startsWith(String string) { + return getUnformattedString().startsWith(string); + } + + @Override + public String toString() { + return getUnformattedString(); + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/chat/Sender.java b/common/src/main/java/de/hype/bbsentials/common/chat/Sender.java new file mode 100644 index 0000000..3dfb13c --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/chat/Sender.java @@ -0,0 +1,104 @@ +package de.hype.bbsentials.common.chat; + +import de.hype.bbsentials.common.api.Formatting; + +import java.util.ArrayList; +import java.util.List; + +import static de.hype.bbsentials.common.chat.Chat.sendPrivateMessageToSelfInfo; +import static de.hype.bbsentials.common.chat.Chat.sendPrivateMessageToSelfText; + +public class Sender { + private final List<String> sendQueue; + private final List<Double> sendQueueTiming; + private final List<Boolean> hidden; + + + public Sender() { + this.sendQueue = new ArrayList<>(); + this.sendQueueTiming = new ArrayList<>(); + this.hidden = new ArrayList<>(); + startSendingThread(); + } + + public void addSendTask(String task, double timing) { + synchronized (sendQueue) { + sendPrivateMessageToSelfText(Message.of(Formatting.GREEN + "Scheduled send-task (as " + sendQueueTiming.size() + " in line): " + task + " | Delay: " + timing)); + sendQueueTiming.add(timing); + sendQueue.add(task); + hidden.add(false); + sendQueue.notify(); // Notify the waiting thread that a new String has been added + } + } + + public void addHiddenSendTask(String task, double timing) { + synchronized (sendQueue) { + sendQueueTiming.add(timing); + sendQueue.add(task); + hidden.add(true); + + sendQueue.notify(); // Notify the waiting thread that a new String has been added + } + } + + public void addImmediateSendTask(String task) { + synchronized (sendQueue) { + sendQueueTiming.add(0, 0.0); + sendQueue.add(0, task); + hidden.add(false); + + sendQueue.notify(); // Notify the waiting thread that a new String has been added + } + } + + public void addSendTask(String task) { + addSendTask(task, 1); + } + + public void startSendingThread() { + Thread sendingThread = new Thread(new SendingRunnable()); + sendingThread.start(); + } + + private class SendingRunnable implements Runnable { + @Override + public void run() { + while (true) { + String task = getNextTask(); + if (task != null) { + send(task, sendQueueTiming.remove(0), hidden.remove(0)); + } + else { + synchronized (sendQueue) { + try { + sendQueue.wait(); // Wait for new Send + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + } + } + + private String getNextTask() { + synchronized (sendQueue) { + if (!sendQueue.isEmpty()) { + return sendQueue.remove(0); + } + return null; + } + } + + private void send(String toSend, double timing, boolean hidden) { + try { + Thread.sleep((long) (timing * 1000)); // Simulate the send operation + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + MC.sendChatMessage(toSend); + if (!hidden) { + sendPrivateMessageToSelfInfo("Sent Command to Server: " + toSend); + } + } + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/client/BBsentials.java b/common/src/main/java/de/hype/bbsentials/common/client/BBsentials.java new file mode 100644 index 0000000..0d5535f --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/BBsentials.java @@ -0,0 +1,247 @@ +package de.hype.bbsentials.common.client; + +import com.mojang.brigadier.arguments.StringArgumentType; +import de.hype.bbsentials.common.chat.Chat; +import de.hype.bbsentials.common.client.Commands.CommandsOLD; +import de.hype.bbsentials.common.communication.BBsentialConnection; +import de.hype.bbsentials.fabric.BBsentialsConfigScreemFactory; +import de.hype.bbsentials.fabric.Options; +import org.lwjgl.glfw.GLFW; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class BBsentials { + public static Config config; + public static BBsentialConnection connection; + public static CommandsOLD coms; + public static ScheduledExecutorService executionService = Executors.newScheduledThreadPool(1000); + public static boolean splashLobby; + private static Thread bbthread; + private static boolean initialised = false; + public static SplashStatusUpdateListener splashStatusUpdateListener; + + public static Config getConfig() { + return config; + } + + public static void connectToBBserver() { + connectToBBserver(config.connectToBeta); + } + + /** + * Checks if still connected to the Server. + * + * @return true if it connected; false if old connection is kept. + */ + public static boolean conditionalReconnectToBBserver() { + if (!connection.isConnected()) { + Chat.sendPrivateMessageToSelfInfo("Reconnecting"); + connectToBBserver(config.connectToBeta); + return true; + } + return false; + } + + public static void connectToBBserver(boolean beta) { + if (connection != null) { + connection.sendHiddenMessage("exit"); + } + if (bbthread != null) { + if (bbthread.isAlive()) { + bbthread.interrupt(); + } + } + bbthread = new Thread(() -> { + connection = new BBsentialConnection(); + coms = new CommandsOLD(); + connection.setMessageReceivedCallback(message -> executionService.execute(() -> connection.onMessageReceived(message))); + if (beta) { + connection.connect(config.getBBServerURL(), 5011); + } + else { + connection.connect(config.getBBServerURL(), 5000); + } + executionService.scheduleAtFixedRate(new DebugThread(), 0, 20, TimeUnit.SECONDS); + }); + bbthread.start(); + } + + /** + * Runs the mod initializer on the client environment. + */ + + public static void onServerSwap() { + splashLobby = false; + if (!initialised) { + config = Config.load(); + if (config.doGammaOverride) Options.setGamma(10); + Chat chat = new Chat(); + if (Config.isBingoTime() || config.overrideBingoTime()) { + connectToBBserver(); + } + initialised = true; + } + } + + { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("bbi") + .then(ClientCommandManager.literal("reconnect") + .executes((context) -> { + connectToBBserver(); + return 1; + })) + .then(ClientCommandManager.literal("reconnect-stable-server") + .executes((context) -> { + connectToBBserver(false); + return 1; + })) + .then(ClientCommandManager.literal("reconnect-test-server") + .executes((context) -> { + connectToBBserver(true); + return 1; + })) + .then(ClientCommandManager.literal("config") + .then(ClientCommandManager.argument("category", StringArgumentType.string()) + .suggests((context, builder) -> { + // Provide tab-completion options for config subfolder + return CommandSource.suggestMatching(new String[]{"save", "reset", "load"}, builder); + }).executes((context) -> { + String category = StringArgumentType.getString(context, "category"); + switch (category) { + case "save": + getConfig().save(); + Chat.sendPrivateMessageToSelfSuccess("Saved config successfully"); + break; + case "load": + BBsentials.config = Config.load(); + break; + case "reset": + // Reset logic here + break; + } + return 1; + })) + .then(ClientCommandManager.literal("set-value") + .then(ClientCommandManager.argument("className", StringArgumentType.string()) + .suggests((context, builder) -> { + // Provide tab-completion options for classes + ArrayList<String> classNames = new ArrayList<>(); + classNames.add("Config"); + // Replace with your own logic to retrieve class names + return CommandSource.suggestMatching(classNames, builder); + }) + .then(ClientCommandManager.argument("variableName", StringArgumentType.string()) + .suggests((context, builder) -> { + // Provide tab-completion options for variable names + List<String> variableNames; + variableNames = List.of(Chat.getVariableInfo("de.hype.bbsentials.client", "Config")); + return CommandSource.suggestMatching(variableNames, builder); + }) + .then(ClientCommandManager.argument("variableValue", StringArgumentType.string()) + .executes((context) -> { + // Handle "variableName" and "variableValue" logic here + String variableName = StringArgumentType.getString(context, "variableName"); + String variableValue = StringArgumentType.getString(context, "variableValue"); + try { + if (!variableName.toLowerCase().contains("dev") || config.hasBBRoles("dev")) { + Chat.setVariableValue(getConfig(), variableName, variableValue); + } + getConfig().save(); + } catch (ClassNotFoundException | + NoSuchFieldException | + IllegalAccessException | + InstantiationException | + InvocationTargetException | + NoSuchMethodException e) { + Chat.sendPrivateMessageToSelfError("Invalid variable or value"); + } + return 1; + }))))) + .then(ClientCommandManager.literal("get-value") + .then(ClientCommandManager.argument("className", StringArgumentType.string()) + .suggests((context, builder) -> { + // Provide tab-completion options for classes + ArrayList<String> classNames = new ArrayList<>(); + classNames.add("Config"); + // Replace with your own logic to retrieve class names + return CommandSource.suggestMatching(classNames, builder); + }) + .then(ClientCommandManager.argument("variableName", StringArgumentType.string()) + .suggests((context, builder) -> { + // Provide tab-completion options for variable names + List<String> variableNames; + variableNames = List.of(Chat.getVariableInfo("de.hype.bbsentials.client", "Config")); + return CommandSource.suggestMatching(variableNames, builder); + }) + .executes((context) -> { + // Handle "variableName" and "variableValue" logic here + String variableName = StringArgumentType.getString(context, "variableName"); + try { + Chat.getVariableValue(getConfig(), variableName); + } catch (Exception e) { + e.printStackTrace(); + } + return 1; + }))).executes((context) -> { + // Handle the case when "config" argument is not provided + // ... + return 1; + }))) + ); + }); //bbi + + KeyBinding devKeyBind = new KeyBinding("Open Mod Menu Config", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_ADD, "BBsentials: Developing Tools"); + KeyBindingHelper.registerKeyBinding(devKeyBind); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (devKeyBind.wasPressed()) { + MinecraftClient.getInstance().setScreen(BBsentialsConfigScreemFactory.create(MinecraftClient.getInstance().currentScreen)); + } + }); + + KeyBinding promptKeyBind = new KeyBinding("Chat Prompt Yes / Open Menu", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, "BBsentials"); + KeyBindingHelper.registerKeyBinding(promptKeyBind); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (promptKeyBind.wasPressed()) { + if (config.getLastChatPromptAnswer() != null) { + if (config.isDetailedDevModeEnabled()) { + Chat.sendPrivateMessageToSelfDebug(config.getLastChatPromptAnswer()); + } + MinecraftClient.getInstance().getNetworkHandler().sendChatMessage(config.getLastChatPromptAnswer()); + } + config.setLastChatPromptAnswer(null); + } + }); + KeyBinding craftKeyBind = new KeyBinding("Craft", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_V, "BBsentials"); + KeyBindingHelper.registerKeyBinding(craftKeyBind); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (craftKeyBind.wasPressed()) MinecraftClient.getInstance().getNetworkHandler().sendChatMessage("/craft"); + }); + KeyBinding petKeyBind = new KeyBinding("Open Pet Menu", InputUtil.Type.KEYSYM, -1, "BBsentials"); + KeyBindingHelper.registerKeyBinding(petKeyBind); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (petKeyBind.wasPressed()) MinecraftClient.getInstance().getNetworkHandler().sendChatMessage("/pets"); + }); + for (int i = 1; i <= 9; i++) { + KeyBinding ecPageKeyBind = new KeyBinding("Ender Chest Page " + i, InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_1 + (i - 1), "BBsentials"); + KeyBindingHelper.registerKeyBinding(ecPageKeyBind); + int pageNum = i; // Capture the page number for lambda + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (ecPageKeyBind.wasPressed()) { + BBsentials.getConfig().sender.addImmediateSendTask("/ec " + pageNum); + } + }); + } + } // KeyBinds + + public void manualLoad() { + initialised = true; + config = Config.load(); + connectToBBserver(); + } +}
\ No newline at end of file diff --git a/common/src/main/java/de/hype/bbsentials/common/client/Commands/CommandsOLD.java b/common/src/main/java/de/hype/bbsentials/common/client/Commands/CommandsOLD.java new file mode 100644 index 0000000..92e801c --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/Commands/CommandsOLD.java @@ -0,0 +1,363 @@ +package de.hype.bbsentials.common.client.Commands; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import de.hype.bbsentials.common.chat.Chat; +import de.hype.bbsentials.common.client.BBsentials; +import de.hype.bbsentials.common.constants.enviromentShared.ChChestItems; +import de.hype.bbsentials.common.constants.enviromentShared.MiningEvents; +import de.hype.bbsentials.common.packets.AbstractPacket; +import de.hype.bbsentials.common.packets.packets.*; +import de.hype.bbsentials.fabric.BBUtils; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.fabricmc.fabric.api.event.Event; +import net.minecraft.command.CommandSource; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class CommandsOLD { + public CommandsOLD() { + Event<ClientCommandRegistrationCallback> event = ClientCommandRegistrationCallback.EVENT; + event.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("creport") + .then(ClientCommandManager.argument("Player_Name", StringArgumentType.string()) + .executes((context) -> { + String playerName = StringArgumentType.getString(context, "Player_Name"); + BBsentials.getConfig().sender.addSendTask("/creport " + playerName, 0); + BBsentials.getConfig().addReported(playerName); + return 1; + }))); + });//creport helper → no double report during same launch + event.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("socialoptions") + .then(ClientCommandManager.argument("playername", StringArgumentType.greedyString()) + .executes((context) -> { + String[] parameters = StringArgumentType.getString(context, "playername").trim().split(" ", 3); + Chat.sendPrivateMessageToSelfDebug(String.join(" ", parameters)); + String tellrawjson = ""; + if (parameters.length >= 3) { + if (parameters[0].equals("sb")) { + tellrawjson = "[\"\",{\"text\":\"\n\n$username\",\"underlined\":true,\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[{\"text\":\"Click to copy the username\",\"color\":\"blue\"}]}},\" \",{\"text\":\"[Party]\",\"color\":\"gold\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p invite $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to party player\"]}},\" \",{\"text\":\"[Invite]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/invite\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to invite them to visit your private island/garden\"]}},\" \",{\"text\":\"[Visit]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/visit $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to open the visit menu for that user\"]}},\" \",{\"text\":\"[creport]\",\"color\":\"dark_red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/creport $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to report the player for chat (public)\"]}},\" \",{\"text\":\"[Ignore add]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/ignore add $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to ignore add the user\"]}},\" \",{\"text\":\"[Copy content]\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$messagecontent\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the message content\"]}},\" \",{\"text\":\"[Copy message]\",\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the exact message\"]}},\" \",{\"text\":\"[Msg]\",\"color\":\"dark_purple\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/msg $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to msg the user\"]}},\" \",{\"text\":\"[Sky shiiyu]\",\"color\":\"aqua\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"https://sky.shiiyu.moe/stats/$username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to open the users sky shiiyu page.\"]}},\"\\n\"]"; + //{"jformat":8,"jobject":[{"bold":false,"italic":false,"underlined":true,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the username"}],"text":"$username"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gold","insertion":"","click_event_type":"run_command","click_event_value":"/p invite $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to party player"}],"text":"[Party]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"green","insertion":"","click_event_type":"run_command","click_event_value":"/invite","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to invite them to visit your private island/garden"}],"text":"[Invite]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"green","insertion":"","click_event_type":"run_command","click_event_value":"/visit $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to open the visit menu for that user"}],"text":"[Visit]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_red","insertion":"","click_event_type":"suggest_command","click_event_value":"/creport $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to report the player for chat (public)"}],"text":"[creport]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/ignore add $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to ignore add the user"}],"text":"[Ignore add]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gray","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$messagecontent","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the message content"}],"text":"[Copy content]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the exact message"}],"text":"[Copy message]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"suggest_command","click_event_value":"/msg $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to msg the user"}],"text":"[Msg]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"aqua","insertion":"","click_event_type":"open_url","click_event_value":"https://sky.shiiyu.moe/stats/$username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to open the users sky shiiyu page."}],"text":"[Sky shiiyu]"}],"command":"%s","jtemplate":"tellraw"} + } + else if (parameters[0].equals("guild")) { + tellrawjson = "[\"\",{\"text\":\"\n\n$username\",\"underlined\":true,\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[{\"text\":\"Click to copy the username\",\"color\":\"blue\"}]}},\" \",{\"text\":\"[Party]\",\"color\":\"gold\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p invite $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to party player\"]}},\" \",{\"text\":\"[SB Options]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/socialoptions sb $username $message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to open the SB options\"]}},\" \",{\"text\":\"[Member info]\",\"color\":\"dark_aqua\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/g member $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Show guild info about the user.\"]}},\" \",{\"text\":\"[Copy content]\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$messagecontent\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the message content\"]}},\" \",{\"text\":\"[Copy message]\",\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the exact message\"]}},\" \",{\"text\":\"[Msg]\",\"color\":\"dark_purple\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/msg $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to msg the user\"]}},\" \",{\"text\":\"[Ignore add]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/ignore add $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to ignore add the user\"]}},\"\\n\",{\"text\":\"G Admin: \",\"color\":\"dark_red\"},{\"text\":\"[kick]\",\"color\":\"dark_purple\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/g kick $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"suggest the command to kick the user\"]}},\" \",{\"text\":\"[mute]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/g mute $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Suggest a mute command for the user.\"]}},\" \",{\"text\":\"[promote]\",\"color\":\"dark_green\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/g promote $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to promote the user\"]}},\" \",{\"text\":\"[demote]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/g demote $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to demote the user\"]}}]"; + //{"jformat":8,"jobject":[{"bold":false,"italic":false,"underlined":true,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the username"}],"text":"$username"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gold","insertion":"","click_event_type":"run_command","click_event_value":"/p invite $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to party player"}],"text":"[Party]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"green","insertion":"","click_event_type":"run_command","click_event_value":"/socialoptions sb $username $message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to open the SB options"}],"text":"[SB Options]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_aqua","insertion":"","click_event_type":"run_command","click_event_value":"/g member $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Show guild info about the user."}],"text":"[Member info]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gray","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$messagecontent","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the message content"}],"text":"[Copy content]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the exact message"}],"text":"[Copy message]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"suggest_command","click_event_value":"/msg $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to msg the user"}],"text":"[Msg]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/ignore add $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to ignore add the user"}],"text":"[Ignore add]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"\n"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_red","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"G Admin: "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"suggest_command","click_event_value":"/g kick $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"suggest the command to kick the user"}],"text":"[kick]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/g mute $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Suggest a mute command for the user."}],"text":"[mute]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_green","insertion":"","click_event_type":"suggest_command","click_event_value":"/g promote $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to promote the user"}],"text":"[promote]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/g demote $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to demote the user"}],"text":"[demote]"}],"command":"%s","jtemplate":"tellraw"} + } + else if (parameters[0].equals("party")) { + if (BBsentials.config.isLeader()) { + tellrawjson = "[\"\",{\"text\":\"\n\n$username\",\"underlined\":true,\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[{\"text\":\"Click to copy the username\",\"color\":\"blue\"}]}},\" \",{\"text\":\"[Party]\",\"color\":\"gold\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p invite $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to party player\"]}},\" \",{\"text\":\"[SB Options]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/socialoptions sb $username $message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to open the SB options\"]}},\" \",{\"text\":\"[Copy content]\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$messagecontent\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the message content\"]}},\" \",{\"text\":\"[Copy message]\",\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the exact message\"]}},\" \",{\"text\":\"[Msg]\",\"color\":\"dark_purple\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/msg $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to msg the user\"]}},\" \",{\"text\":\"[Ignore add]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/ignore add $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to ignore add the user\"]}},\"\\n\",\"\\n\",{\"text\":\"P Leader: \",\"color\":\"dark_red\"},{\"text\":\"[kick]\",\"color\":\"dark_purple\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p kick $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"suggest the command to kick the user\"]}},\" \",{\"text\":\"[transfer]\",\"color\":\"dark_red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/p transfer $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Suggest a mute command for the user.\"]}},\" \",{\"text\":\"[promote]\",\"color\":\"dark_green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p promote $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to promote the user\"]}},\" \",{\"text\":\"[demote]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p demote $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to demote the user\"]}}]"; + //{"jformat":8,"jobject":[{"bold":false,"italic":false,"underlined":true,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the username"}],"text":"$username"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gold","insertion":"","click_event_type":"run_command","click_event_value":"/p invite $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to party player"}],"text":"[Party]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"green","insertion":"","click_event_type":"run_command","click_event_value":"/socialoptions sb $username $message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to open the SB options"}],"text":"[SB Options]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gray","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$messagecontent","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the message content"}],"text":"[Copy content]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the exact message"}],"text":"[Copy message]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"suggest_command","click_event_value":"/msg $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to msg the user"}],"text":"[Msg]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/ignore add $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to ignore add the user"}],"text":"[Ignore add]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"\n"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"\n"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_red","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"P Leader: "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"run_command","click_event_value":"/p kick $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"suggest the command to kick the user"}],"text":"[kick]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_red","insertion":"","click_event_type":"suggest_command","click_event_value":"/p transfer $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Suggest a mute command for the user."}],"text":"[transfer]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_green","insertion":"","click_event_type":"run_command","click_event_value":"/p promote $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to promote the user"}],"text":"[promote]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"run_command","click_event_value":"/p demote $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to demote the user"}],"text":"[demote]"}],"command":"%s","jtemplate":"tellraw"} + } + else { + tellrawjson = "[\"\",{\"text\":\"\n\n$username\",\"underlined\":true,\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[{\"text\":\"Click to copy the username\",\"color\":\"blue\"}]}},\" \",{\"text\":\"[Party]\",\"color\":\"gold\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/p invite $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to party player\"]}},\" \",{\"text\":\"[SB Options]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/socialoptions sb $username $message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to open the SB options\"]}},\" \",{\"text\":\"[Copy content]\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$messagecontent\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the message content\"]}},\" \",{\"text\":\"[Copy message]\",\"color\":\"blue\",\"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"$message\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to copy the exact message\"]}},\" \",{\"text\":\"[Msg]\",\"color\":\"dark_purple\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/msg $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to msg the user\"]}},\" \",{\"text\":\"[Ignore add]\",\"color\":\"red\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/ignore add $username\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"Click to ignore add the user\"]}}]"; + //{"jformat":8,"jobject":[{"bold":false,"italic":false,"underlined":true,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the username"}],"text":"$username"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gold","insertion":"","click_event_type":"run_command","click_event_value":"/p invite $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to party player"}],"text":"[Party]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"green","insertion":"","click_event_type":"run_command","click_event_value":"/socialoptions sb $username $message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to open the SB options"}],"text":"[SB Options]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gray","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$messagecontent","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the message content"}],"text":"[Copy content]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the exact message"}],"text":"[Copy message]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"suggest_command","click_event_value":"/msg $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to msg the user"}],"text":"[Msg]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/ignore add $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to ignore add the user"}],"text":"[Ignore add]"}],"command":"%s","jtemplate":"tellraw"} + } + //{"jformat":8,"jobject":[{"bold":false,"italic":false,"underlined":true,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the username"}],"text":"$username"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gold","insertion":"","click_event_type":"run_command","click_event_value":"/p invite $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to party player"}],"text":"[Party]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"green","insertion":"","click_event_type":"run_command","click_event_value":"/socialoptions sb $username $message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to open the SB options"}],"text":"[SB Options]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"gray","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$messagecontent","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the message content"}],"text":"[Copy content]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"blue","insertion":"","click_event_type":"copy_to_clipboard","click_event_value":"$message","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to copy the exact message"}],"text":"[Copy message]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"suggest_command","click_event_value":"/msg $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to msg the user"}],"text":"[Msg]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/ignore add $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to ignore add the user"}],"text":"[Ignore add]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"\n"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_red","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"P Leader: "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_purple","insertion":"","click_event_type":"run_command","click_event_value":"/p kick $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"suggest the command to kick the user"}],"text":"[kick]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"suggest_command","click_event_value":"/p mute $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Suggest a mute command for the user."}],"text":"[mute]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"dark_green","insertion":"","click_event_type":"run_command","click_event_value":"/p promote $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to promote the user"}],"text":"[promote]"},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":" "},{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"red","insertion":"","click_event_type":"run_command","click_event_value":"/p demote $username","hover_event_type":"show_text","hover_event_value":"","hover_event_children":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"font":null,"color":"none","insertion":"","click_event_type":"none","click_event_value":"","hover_event_type":"none","hover_event_value":"","hover_event_children":[],"text":"Click to demote the user"}],"text":"[demote]"}],"command":"%s","jtemplate":"tellraw"} + } + tellrawjson = tellrawjson.replace("$username", parameters[1]); + int doublepointIndex = parameters[2].indexOf(":"); + if (doublepointIndex != -1) { + tellrawjson = tellrawjson.replace("$messagecontent", parameters[2].substring(doublepointIndex + 1).trim()); + } + tellrawjson = tellrawjson.replace("$message", parameters[2]); + } + if (tellrawjson.isEmpty()) + Chat.sendCommand("/socialoptions " + String.join(" ", parameters)); + else { + Chat.sendPrivateMessageToSelfText(Chat.createClientSideTellraw(tellrawjson)); + } + return 1; + }))); + });//sbsocialoptions + event.register((dispatcher, registryAccess) -> { + miningEvent(dispatcher, "goblinraid", MiningEvents.GOBLIN_RAID); + });/*goblinraid*/ + event.register((dispatcher, registryAccess) -> { + miningEvent(dispatcher, "2xpowder", MiningEvents.DOUBLE_POWDER); + });/*2xpowder*/ + event.register((dispatcher, registryAccess) -> { + miningEvent(dispatcher, "bettertogether", MiningEvents.BETTER_TOGETHER); + });/*b2g*/ + event.register((dispatcher, registryAccess) -> { + miningEvent(dispatcher, "raffle", MiningEvents.RAFFLE); + });/*raffle*/ + event.register((dispatcher, registryAccess) -> { + miningEvent(dispatcher, "gonewiththewind", MiningEvents.GONE_WITH_THE_WIND); + });/*gonewiththewind*/ + event.register((dispatcher, registryAccess) -> { + miningEvent(dispatcher, "mithrilgourmand", MiningEvents.MITHRIL_GOURMAND); + });/*gonewiththewind*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("chchest") + .then(ClientCommandManager.argument("Item", StringArgumentType.string()) + .suggests((context, builder) -> { + String[] items = new String[]{"PrehistoricEgg", "Pickonimbus2000", "ElectronTransmitter", "FTX3070", "RobotronReflector", "ControlSwitch", "SyntheticHeart", "SuperliteMotor", "BlueGoblinEgg", "YellowGoblinEgg", "FlawlessAmberGemstone", "FlawlessJadeGemstone", "FlawlessSapphireGemstone", "FlawlessRubyGemstone", "FlawlessAmethystGemstone", "JungleHeart", "FlawlessTopazGemstone", "FlawlessJasperGemstone"}; + String input = builder.getRemaining().toLowerCase(); + int lastSemicolonIndex = input.lastIndexOf(";"); + List<String> suggestions = new ArrayList<>(); + if (lastSemicolonIndex >= 0) { + String inputBeforeSemicolon = input.substring(0, lastSemicolonIndex + 1); // Include the semicolon + + for (String item : items) { + suggestions.add(inputBeforeSemicolon + item); + } + } + return CommandSource.suggestMatching(suggestions, builder); + }) + .then(ClientCommandManager.argument("X", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("Y", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("Z", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("ContactWay", StringArgumentType.string()) + .suggests(((context, builder) -> { + return CommandSource.suggestMatching(new String[]{"\"/msg " + BBsentials.getConfig().getUsername() + " bb:party me\"", "\"/p join " + BBsentials.config.getUsername() + "\""}, builder); + })) + .executes((context) -> { + String item = StringArgumentType.getString(context, "Item"); + int x = IntegerArgumentType.getInteger(context, "X"); + int y = IntegerArgumentType.getInteger(context, "Y"); + int z = IntegerArgumentType.getInteger(context, "Z"); + String contactWay = StringArgumentType.getString(context, "ContactWay"); + + BBsentials.connection.sendPacket(new ChChestPacket("", ChChestItems.getItem(item.split(";")), x + " " + y + " " + z, contactWay, "")); + return 1; + } + ) + ) + ) + ) + ) + ) + ); + });/*chchest*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("bc") + .then(ClientCommandManager.argument("Message to Bingo Chat", StringArgumentType.greedyString()) + .executes((context) -> { + String message = StringArgumentType.getString(context, "Message to Bingo Chat"); + sendPacket(new BingoChatMessagePacket("", "", message, 0)); + return 1; + }) + ) + ); + });/*BincoChatShort*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("bingochat") + .then(ClientCommandManager.argument("Message to Bingo Chat", StringArgumentType.greedyString()) + .executes((context) -> { + String message = StringArgumentType.getString(context, "Message to Bingo Chat"); + sendPacket(new BingoChatMessagePacket("", "", message, 0)); + return 1; + }) + ) + ); + });/*BingoChatLong*/ + if (BBsentials.getConfig().bbsentialsRoles != null) { + if (BBsentials.getConfig().hasBBRoles("mod")) { + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("bannounce") + .then(ClientCommandManager.argument("message", StringArgumentType.greedyString()) + .executes((context) -> { + String message = StringArgumentType.getString(context, "message"); + sendCommand("?announce " + message); + return 1; + }) + ) + ); + });/*bAnnounce*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("bmute") + .then(ClientCommandManager.argument("userId/mcusername", StringArgumentType.string()) + .then(ClientCommandManager.argument("[Duration(d/h/m/s) | 0 forever]", StringArgumentType.string()) + .then(ClientCommandManager.argument("reason", StringArgumentType.greedyString()) + .executes((context) -> { + String identification = StringArgumentType.getString(context, "userId/mcusername"); + String duration = StringArgumentType.getString(context, "[Duration(d/h/m/s) | 0 forever]"); + String reason = StringArgumentType.getString(context, "reason"); + int userId = -1; + String mcusername = ""; + if (identification.replaceAll("[\\d]", "").trim().isEmpty()) { + userId = Integer.parseInt(identification); + } + else { + mcusername = identification; + } + sendPacket(new PunishUserPacket(PunishUserPacket.PUNISHMENT_TYPE_MUTE, userId, mcusername, duration, reason)); + return 1; + }) + ) + ) + ) + ); + });/*bmute*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("bban") + .then(ClientCommandManager.argument("userId/mcusername", StringArgumentType.string()) + .then(ClientCommandManager.argument("[Duration(d/h/m/s) | 0 forever]", StringArgumentType.string()) + .then(ClientCommandManager.argument("reason", StringArgumentType.greedyString()) + .executes((context) -> { + String identification = StringArgumentType.getString(context, "userId/mcusername"); + String duration = StringArgumentType.getString(context, "[Duration(d/h/m/s) | 0 forever]"); + String reason = StringArgumentType.getString(context, "reason"); + int userId = -1; + String mcusername = ""; + if (identification.replaceAll("[\\d]", "").trim().isEmpty()) { + userId = Integer.parseInt(identification); + } + else { + mcusername = identification; + } + sendPacket(new PunishUserPacket(PunishUserPacket.PUNISHMENT_TYPE_BAN, userId, mcusername, duration, reason)); + return 1; + }) + ) + ) + ) + ); + });/*ban*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register(ClientCommandManager.literal("bgetinfo") + .then(ClientCommandManager.argument("userId/mcusername", StringArgumentType.string()) + .executes((context) -> { + String identification = StringArgumentType.getString(context, "userId/mcusername"); + sendPacket(new InternalCommandPacket(InternalCommandPacket.GET_USER_INFO, new String[]{identification})); + return 1; + }) + ) + ); + });/*getInfo*/ + } + if (BBsentials.getConfig().hasBBRoles("splasher")) { + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("splashAnnounce") + .then(ClientCommandManager.argument("Hub", IntegerArgumentType.integer(1, 28)) + .then(ClientCommandManager.argument("location", StringArgumentType.string()) + .suggests((context, builder) -> { + return CommandSource.suggestMatching(new String[]{"kat", "bea", "guild-house"}, builder); + }) + .then(ClientCommandManager.argument("lasswaste", StringArgumentType.string()) + .suggests((context, builder) -> { + return CommandSource.suggestMatching(new String[]{"true", "false"}, builder); + }) + .then(ClientCommandManager.argument("extramessage", StringArgumentType.greedyString()) + .executes((context) -> { + int hub = IntegerArgumentType.getInteger(context, "Hub"); + String extramessage = StringArgumentType.getString(context, "extramessage"); + String location = StringArgumentType.getString(context, "location"); + boolean lessWaste = Boolean.parseBoolean(StringArgumentType.getString(context, "lasswaste")); + splashAnnounce(hub, location, extramessage, lessWaste); + return 1; + }) + ) + .executes((context) -> { + int hub = IntegerArgumentType.getInteger(context, "Hub"); + String location = StringArgumentType.getString(context, "location"); + boolean lessWaste = Boolean.parseBoolean(StringArgumentType.getString(context, "lasswaste")); + splashAnnounce(hub, location, "", lessWaste); + return 1; + }) + )) + .executes((context) -> { + int hub = IntegerArgumentType.getInteger(context, "Hub"); + String location = "bea"; + splashAnnounce(hub, location, "", true); + return 1; + }) + + ) + ); + });/*SplashAnnounce*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("requestpottimes") + .executes((context) -> { + sendPacket(new InternalCommandPacket(InternalCommandPacket.REQUEST_POT_DURATION, new String[0])); + return 1; + }) + ); + });/*requestpottimes*/ + } + if (BBsentials.getConfig().hasBBRoles("admin")) { + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("bshutdown") + .then(ClientCommandManager.argument("Reason", StringArgumentType.greedyString()) + .suggests((context, builder) -> { + return CommandSource.suggestMatching(new String[]{"Emergency Shutdown", "System Shutdown", "Other"}, builder); + }) + .executes((context) -> { + String reason = StringArgumentType.getString(context, "Reason"); + sendPacket(new InternalCommandPacket(InternalCommandPacket.SHUTDOWN_SERVER, new String[]{reason})); + return 1; + }) + ) + ); + });/*BBShutdown*/ + event.register((dispatcher, registryAccess) -> { + dispatcher.register( + ClientCommandManager.literal("bsetmotd") + .then(ClientCommandManager.argument("Message", StringArgumentType.greedyString()) + .suggests((context, builder) -> { + return CommandSource.suggestMatching(new String[]{""}, builder); + }) + .executes((context) -> { + String message = StringArgumentType.getString(context, "Message").trim(); + sendPacket(new InternalCommandPacket(InternalCommandPacket.SET_MOTD, new String[]{message})); + return 1; + }) + ) + ); + });/*BBServerMotd*/ + } + else { + } + } + } + + private static void simpleCommand(CommandDispatcher<FabricClientCommandSource> dispatcher, String commandName, String[] parameters) { + dispatcher.register( + ClientCommandManager.literal(commandName) + .executes((context) -> { + BBsentials.connection.sendPacket(new InternalCommandPacket(commandName, parameters)); + return 1; + }) + ); + } + + private static void miningEvent(CommandDispatcher<FabricClientCommandSource> dispatcher, String commandName, MiningEvents event) { + dispatcher.register( + ClientCommandManager.literal(commandName) + .executes((context) -> { + try { + BBsentials.connection.sendPacket(new MiningEventPacket(event, + BBsentials.config.getUsername(), Objects.requireNonNull(BBUtils.getCurrentIsland()))); + } catch (Exception e) { + Chat.sendPrivateMessageToSelfError(e.getMessage()); + } + return 1; + }) + ); + } + + public void splashAnnounce(int hubNumber, String locationInHub, String extramessage, boolean lessWaste) { + sendPacket(new SplashNotifyPacket(0, hubNumber, BBsentials.config.getUsername(), locationInHub, BBUtils.getCurrentIsland(), extramessage, lessWaste)); + } + + + public void sendCommand(String message) { + BBsentials.connection.sendCommand(message); + } + + public <E extends AbstractPacket> void sendPacket(E packet) { + BBsentials.connection.sendPacket(packet); + } +}
\ No newline at end of file diff --git a/common/src/main/java/de/hype/bbsentials/common/client/Config.java b/common/src/main/java/de/hype/bbsentials/common/client/Config.java new file mode 100644 index 0000000..f012c0c --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/Config.java @@ -0,0 +1,204 @@ +package de.hype.bbsentials.common.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import de.hype.bbsentials.common.chat.Sender; +import de.hype.bbsentials.fabric.MCUtils; + +import java.io.*; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +public class Config implements Serializable { + //DO NOT Change any of the following unless you know what you are doing! + public int apiVersion = 1; + public boolean allowServerPartyInvite = true; + public boolean devMode = false; + public boolean detailedDevMode = false; + //You can change again + + // set automatically + private transient boolean isLeader; + public transient String alreadyReported = ""; + public String[] bbsentialsRoles = {""}; + public static List<String> partyMembers = new ArrayList<>(); + public transient ToDisplayConfig toDisplayConfig = ToDisplayConfig.loadFromFile(); + public transient final Sender sender = new Sender(); + public transient boolean highlightitem = false; + public transient String lastChatPromptAnswer = null; + private transient String username; + + // Set via load / default you may change these + public boolean overrideBingoTime = false; + public boolean connectToBeta = false; + + public String bbServerURL = "localhost"; + public String apiKey = ""; + public boolean showBingoChat = true; + public boolean doAllChatCustomMenu=true; + public boolean doPartyChatCustomMenu=true; + public boolean doGuildChatCustomMenu=true; + + public boolean allowBBinviteMe = true; + public boolean doDesktopNotifications = false; + public boolean showSplashStatusUpdates = true; + public boolean doGammaOverride = true; + public boolean acceptReparty; + public boolean autoSplashStatusUpdates; + public String nickname; + public String notifForMessagesType; + + // Set default attribute values + private void setDefaults() { + username = MCUtils.getUsername(); + acceptReparty = true; + if (username.equals("Hype_the_Time")) { + nickname = "Hype"; + notifForMessagesType = "nick"; + doDesktopNotifications=true; + } //Gimmic for Developer due too things which dont make it into releases (bugs) + else { + nickname = ""; + notifForMessagesType = "none"; + } + } + + // Gson object for serialization + private final transient Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + // File object for storing the config + private final transient File CONFIG_FILE = new File(MCUtils.getConfigPath(), "BBsential_settings.json"); + + // Constructor + public Config() { + setDefaults(); + } + + // Load the config from file + public static Config load() { + Config settings; + File CONFIG_FILE = new File(MCUtils.getConfigPath(), "BBsential_settings.json"); + Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + if (CONFIG_FILE.exists()) { + try (FileReader reader = new FileReader(CONFIG_FILE)) { + settings = GSON.fromJson(reader, Config.class); + } catch (IOException e) { + e.printStackTrace(); + settings = new Config(); // Use default values if loading fails + settings.save(); + } catch (IllegalStateException e) { + System.out.println("Error loading config. Resetting it."); + settings = new Config(); + settings.save(); + } + } + else { + settings = new Config(); // Use default values if the file doesn't exist + settings.username = MCUtils.getUsername(); + } + if (!settings.hasBBRoles("dev")) { + settings.detailedDevMode = false; + settings.devMode = false; + } + settings.save(); + return settings; + } + + // Save the config to file + public void save() { + try (FileWriter writer = new FileWriter(CONFIG_FILE)) { + GSON.toJson(this, writer); + } catch (IOException e) { + e.printStackTrace(); + } + toDisplayConfig.saveToFile(); + } + + // Getter methods for various config attributes + public String getUsername() { + return username; + } + + public boolean isLeader() { + return isLeader; + } + + public void setIsLeader(boolean value) { + isLeader = value; + } + + public String getNickname() { + return nickname; + } + + public String getNotifForParty() { + return notifForMessagesType; + } + + public boolean isDevModeEnabled() { + return devMode; + } + + public boolean isDetailedDevModeEnabled() { + return detailedDevMode; + } + + public String[] getPlayersInParty() { + return partyMembers.toArray(new String[0]); + } + + public void addReported(String playerName) { + alreadyReported = alreadyReported + " , " + playerName; + } + + public String getApiKey() { + return apiKey; + } + + public String getBBServerURL() { + return bbServerURL; + } + + + public static boolean isBingoTime() { + LocalDate currentDate = LocalDate.now(); + LocalDate lastDayOfMonth = currentDate.withDayOfMonth(currentDate.lengthOfMonth()); + LocalDate firstDayOfMonth = currentDate.withDayOfMonth(1); + Boolean isBefore = currentDate.isAfter(lastDayOfMonth.minusDays(4)); + Boolean isInRange = currentDate.isBefore(firstDayOfMonth.plusDays(15)); + return isBefore || isInRange; + } + + public boolean overrideBingoTime() { + return overrideBingoTime; + } + + public String getLastChatPromptAnswer() { + return lastChatPromptAnswer; + } + + public boolean allowBBinviteMe() { + return allowBBinviteMe; + } + + public void setLastChatPromptAnswer(String lastChatPromptAnswer) { + this.lastChatPromptAnswer = lastChatPromptAnswer; + } + + public boolean hasBBRoles(String roleName) { + for (String role : bbsentialsRoles) { + if (role.equalsIgnoreCase(roleName)) { + return true; + } + } + return false; + } + + public int getApiVersion() { + return apiVersion; + } + + public String getMCUUID() { + return MCUtils.getMCUUID().replace("-", ""); + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/client/CustomGson.java b/common/src/main/java/de/hype/bbsentials/common/client/CustomGson.java new file mode 100644 index 0000000..31f2626 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/CustomGson.java @@ -0,0 +1,28 @@ +package de.hype.bbsentials.common.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class CustomGson { + public static Gson create() { + return new GsonBuilder() +// .registerTypeHierarchyAdapter(BBDisplayNameProvider.class, new BBDisplayNameProviderSerializer()) + .create(); + + } + +// private static class BBDisplayNameProviderSerializer implements JsonSerializer<BBDisplayNameProvider>, JsonDeserializer<BBDisplayNameProvider> { +// @Override +// public JsonElement serialize(BBDisplayNameProvider src, Type typeOfSrc, JsonSerializationContext context) { +// return new JsonPrimitive(src.serialize()); // Serialize using the provided method +// } +// +// @Override +// public BBDisplayNameProvider deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { +// String serializedValue = json.getAsString(); +// +// // Deserialize using the provided method (you need to implement this) +// return BBDisplayNameProvider.deserialize(serializedValue); +// } +// } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/client/DebugThread.java b/common/src/main/java/de/hype/bbsentials/common/client/DebugThread.java new file mode 100644 index 0000000..18ef94d --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/DebugThread.java @@ -0,0 +1,52 @@ +package de.hype.bbsentials.common.client; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.PlayerListEntry; + +import java.util.ArrayList; +import java.util.List; + +public class DebugThread implements Runnable { + + @Override + public void run() { + loop(); + //place a breakpoint for only this thread here. + } + + public void loop() { + + } + + public static List<String> test() { + List<PlayerListEntry> tabList = MinecraftClient.getInstance().player.networkHandler.getPlayerList().stream().toList(); + List<PlayerListEntry> goodTabList = MinecraftClient.getInstance().player.networkHandler.getPlayerList().stream().toList(); + for (PlayerListEntry playerListEntry : tabList) { + try { + if (!playerListEntry.getProfile().getName().startsWith("!")) { + goodTabList.add(playerListEntry); + } + } catch (Exception ignored) { + + } + } + List<String> stringList = new ArrayList<>(); + for (PlayerListEntry playerListEntry : goodTabList) { + try { + String string = playerListEntry.getDisplayName().getString(); + String string2 = (string.replaceAll("\\[\\d+\\]", "")); + if (!string.isEmpty()) { + if (!string.equals(string2)) { + stringList.add(string2); + } + } + } catch (Exception ignored) { + } + } + return stringList; + } + + public static List<String> playersOnTabList() { + return test().stream().map((string) -> string.replaceAll("[^\\p{L}\\p{N}]+", "")).toList(); + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/client/SplashManager.java b/common/src/main/java/de/hype/bbsentials/common/client/SplashManager.java new file mode 100644 index 0000000..5d7d464 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/SplashManager.java @@ -0,0 +1,58 @@ +package de.hype.bbsentials.common.client; + +import de.hype.bbsentials.common.chat.Chat; +import de.hype.bbsentials.common.constants.enviromentShared.Islands; +import de.hype.bbsentials.common.packets.packets.SplashNotifyPacket; +import de.hype.bbsentials.common.packets.packets.SplashUpdatePacket; + +import java.util.HashMap; +import java.util.Map; + +public class SplashManager { + public static Map<Integer, DisplaySplash> splashPool = new HashMap<>(); + + public SplashManager() { + + } + + public static void addSplash(SplashNotifyPacket packet) { + splashPool.put(packet.splashId, new DisplaySplash(packet)); + } + + public static void updateSplash(SplashUpdatePacket packet) { + DisplaySplash splash = splashPool.get(packet.splashId); + if (splash != null) { + if (splash.alreadyDisplayed) { + if (BBsentials.config.showSplashStatusUpdates) { + Chat.sendPrivateMessageToSelfImportantInfo(splash.hubType.getDisplayName() + " #" + splash.hub + " is " + packet.status); + } + } + else { + splashPool.remove(splash.splashId); + } + } + } + + public static void display(int splashId) { + SplashNotifyPacket splash = splashPool.get(splashId); + if (splash == null) return; + String where; + if (splash.hubType.equals(Islands.DUNGEON_HUB)) { + where = "§5DUNGEON HUB§6"; + } + else { + where = "Hub"; + } + BBsentials.connection.splashHighlightItem("HUB #" + splash.hub, 20); + Chat.sendPrivateMessageToSelfImportantInfo(splash.splasherUsername + " is Splashing in " + where + " #" + splash.hub + " at " + splash.location + ":" + splash.extraMessage); + } + + private static class DisplaySplash extends SplashNotifyPacket { + public boolean alreadyDisplayed; + + public DisplaySplash(SplashNotifyPacket packet) { + super(packet.splashId, packet.hub, packet.splasherUsername, packet.location, packet.hubType, packet.extraMessage, packet.lessWaste); + alreadyDisplayed = false; + } + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/client/SplashStatusUpdateListener.java b/common/src/main/java/de/hype/bbsentials/common/client/SplashStatusUpdateListener.java new file mode 100644 index 0000000..a250534 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/SplashStatusUpdateListener.java @@ -0,0 +1,62 @@ +package de.hype.bbsentials.common.client; + +import de.hype.bbsentials.common.communication.BBsentialConnection; +import de.hype.bbsentials.common.packets.packets.SplashNotifyPacket; +import de.hype.bbsentials.common.packets.packets.SplashUpdatePacket; + +import java.util.concurrent.TimeUnit; + +public class SplashStatusUpdateListener implements Runnable { + BBsentialConnection connection; + SplashNotifyPacket packet; + private String status = SplashUpdatePacket.STATUS_WAITING; + public String newStatus = SplashUpdatePacket.STATUS_WAITING; + public boolean splashed = false; + public boolean full = false; + + public SplashStatusUpdateListener(BBsentialConnection connection, SplashNotifyPacket packet) { + this.connection = connection; + this.packet = packet; + } + + @Override + public void run() { + BBsentials.splashLobby = true; + int maxPlayerCount = BBUtils.getMaximumPlayerCount() - 5; + while (BBsentials.splashLobby) { + if (!full&&(BBUtils.getPlayerCount() >= maxPlayerCount)) { + newStatus = SplashUpdatePacket.STATUS_FULL; + full=true; + } + if (!status.equals(newStatus)) { + status = newStatus; + connection.sendPacket(new SplashUpdatePacket(packet.splashId, status)); + } + try { + Thread.sleep(250); + } catch (InterruptedException ignored) { + } + } + if (splashed) { + newStatus = SplashUpdatePacket.STATUS_DONE; + } + else { + newStatus = SplashUpdatePacket.STATUS_CANCELED; + } + if (!status.equals(newStatus)) { + status = newStatus; + connection.sendPacket(new SplashUpdatePacket(packet.splashId, status)); + } + } + + public void setStatus(String newStatus) { + this.newStatus = newStatus; + if (newStatus.equals(SplashUpdatePacket.STATUS_SPLASHING)) { + splashed=true; + BBsentials.executionService.schedule(() -> { + setStatus(SplashUpdatePacket.STATUS_DONE); + BBsentials.splashLobby = false; + }, 1, TimeUnit.MINUTES); + } + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/client/ToDisplayConfig.java b/common/src/main/java/de/hype/bbsentials/common/client/ToDisplayConfig.java new file mode 100644 index 0000000..0a046d9 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/client/ToDisplayConfig.java @@ -0,0 +1,96 @@ +package de.hype.bbsentials.common.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import de.hype.bbsentials.fabric.MCUtils; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Field; + +public class ToDisplayConfig { + public boolean disableAll = false; + public boolean allChChestItem = true; + public boolean allRoboPart = false; + public boolean customChChestItem = false; + + public boolean prehistoricEgg = false; + public boolean pickonimbus2000 = false; + public boolean controlSwitch = false; + public boolean electronTransmitter = false; + public boolean ftx3070 = false; + public boolean robotronReflector = false; + public boolean superliteMotor = false; + public boolean syntheticHeart = false; + public boolean flawlessGemstone = false; + public boolean jungleHeart = false; + + //Mining Events. + public boolean allEvents = true; + public boolean blockChEvents = false; + + public String betterTogether = "none"; + public String doublePowder = "none"; + public String goneWithTheWind = "none"; + public boolean goblinRaid = false; + public boolean mithrilGourmand = false; + public boolean raffle = false; + + // Serialize the object to JSON and save to file + public void saveToFile() { + File configFile = new File(MCUtils.getConfigPath(), "BBsentials_display_Config.json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + try (FileWriter writer = new FileWriter(configFile)) { + gson.toJson(this, writer); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // Deserialize the object from JSON file + public static ToDisplayConfig loadFromFile() { + File configFile = new File(MCUtils.getConfigPath(), "BBsentials_display_Config.json"); + Gson gson = new Gson(); + + try (FileReader reader = new FileReader(configFile)) { + return gson.fromJson(reader, ToDisplayConfig.class); + } catch (IOException e) { + e.printStackTrace(); + } + + // If file doesn't exist or there's an error, return a new instance + return new ToDisplayConfig(); + } + + public void setValueAndSave(String propertyName, Object newValue) { + String lowerCasePropertyName = propertyName.toLowerCase(); + + try { + Field field = getClass().getDeclaredField(lowerCasePropertyName); + field.setAccessible(true); + + field.set(this, newValue); + saveToFile(); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + + // Method to get a value based on property name + public boolean getValue(String propertyName) { + if (disableAll) return false; + String lowerCasePropertyName = propertyName.toLowerCase(); + try { + Field field = getClass().getDeclaredField(lowerCasePropertyName); + field.setAccessible(true); + return field.getBoolean(this); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + + return false; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/communication/BBsentialConnection.java b/common/src/main/java/de/hype/bbsentials/common/communication/BBsentialConnection.java new file mode 100644 index 0000000..e7aa3a4 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/communication/BBsentialConnection.java @@ -0,0 +1,551 @@ +package de.hype.bbsentials.common.communication; + +import de.hype.bbsentials.common.chat.Message; +import de.hype.bbsentials.common.client.BBsentials; +import de.hype.bbsentials.common.client.SplashManager; +import de.hype.bbsentials.common.client.SplashStatusUpdateListener; +import de.hype.bbsentials.common.constants.enviromentShared.ChChestItem; +import de.hype.bbsentials.common.constants.enviromentShared.ChChestItems; +import de.hype.bbsentials.common.constants.enviromentShared.Islands; +import de.hype.bbsentials.common.constants.enviromentShared.MiningEvents; +import de.hype.bbsentials.common.packets.AbstractPacket; +import de.hype.bbsentials.common.packets.PacketManager; +import de.hype.bbsentials.common.packets.PacketUtils; +import de.hype.bbsentials.common.packets.packets.*; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.*; +import java.net.Socket; +import java.net.SocketException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +public class BBsentialConnection { + private Socket socket; + private BufferedReader reader; + private PrintWriter writer; + private LinkedBlockingQueue<String> messageQueue; + private MessageReceivedCallback messageReceivedCallback; + private String itemName = "Hub #0"; + private PacketManager packetManager; + + public BBsentialConnection() { + packetManager = new PacketManager(this); + } + + + + public static boolean isCommandSafe(String command) { + if (command.startsWith("/p ") || command.startsWith("/party ") || command.startsWith("/boop ") || command.startsWith("/msg ") || command.startsWith("/hub ")) { + return true; + } + else { + BBsentials.connection.sendCommand("?emergency server-hacked? chchest command " + command); + String emergencyMessage = "We detected that there was a command used which is not configured to be safe! " + command + " please check if its safe. IMMEDIATELY report this to the Admins and Developer Hype_the_Time (@hackthetime). If it is not safe immediately remove BBsentials!!!!!!!! "; + System.out.println(emergencyMessage); + Chat.sendPrivateMessageToSelfFatal("§4" + emergencyMessage + "\n\n"); + /*try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + throw new RuntimeException(emergencyMessage);*/ + } + return false; + } + + + + public void connect(String serverIP, int serverPort) { + // Enable SSL handshake debugging + System.setProperty("javax.net.debug", "ssl,handshake"); + FileInputStream inputStream = null; + try { + // Load the BBssentials-online server's public certificate from the JKS file + try { + InputStream resouceInputStream = BBsentials.class.getResourceAsStream("/assets/public_bbsentials_cert.crt"); + + // Check if the resource exists + if (resouceInputStream == null) { + System.out.println("The resource '/assets/public_bbsentials_cert.crt' was not found."); + return; + } + + File tempFile = File.createTempFile("public_bbsentials_cert", ".crt"); + tempFile.deleteOnExit(); + + FileOutputStream outputStream = new FileOutputStream(tempFile); + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = resouceInputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + outputStream.close(); + resouceInputStream.close(); + + // Now you have the .crt file as a FileInputStream in the tempFile + inputStream = new FileInputStream(tempFile); + + // Use the fileInputStream as needed + + } catch (IOException e) { + e.printStackTrace(); + } + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + X509Certificate serverCertificate = (X509Certificate) certFactory.generateCertificate(inputStream); + PublicKey serverPublicKey = serverCertificate.getPublicKey(); + + // Create a TrustManager that trusts only the server's public key + TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; // We don't need to check the client's certificates + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { + // Do nothing, client certificate validation not required + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { + // Check if the server certificate matches the expected one + if (certs.length == 1) { + PublicKey publicKey = certs[0].getPublicKey(); + if (!publicKey.equals(serverPublicKey)) { + throw new CertificateException("Server certificate not trusted."); + } + } + else { + throw new CertificateException("Invalid server certificate chain."); + } + } + }}; + + // Create an SSL context with the custom TrustManager + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustManagers, new SecureRandom()); + // Create an SSL socket factory + SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + socket = sslSocketFactory.createSocket(serverIP, serverPort); + + socket.setKeepAlive(true); // Enable Keep-Alive + + reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + writer = new PrintWriter(socket.getOutputStream(), true); + messageQueue = new LinkedBlockingQueue<>(); + + // Start message receiver thread + Thread messageReceiverThread = new Thread(() -> { + try { + while (true) { + String message = reader.readLine(); + if (message != null) { + if (messageReceivedCallback != null) { + messageReceivedCallback.onMessageReceived(message); + } + else { + Chat.sendPrivateMessageToSelfError("BB: It seemed like you disconnected. Reconnecting..."); + BBsentials.connectToBBserver(); + try { + Thread.sleep(1000 * 10); + } catch (Exception ignored) { + } + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + }); + messageReceiverThread.start(); + messageReceiverThread.setName("bb receiver thread"); + // Start message sender thread + Thread messageSenderThread = new Thread(() -> { + try { + while (true) { + String message = messageQueue.take(); + writer.println(message); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (NullPointerException ignored) { + } + }); + messageSenderThread.start(); + messageSenderThread.setName("bb sender thread"); + + } catch (IOException | NoSuchAlgorithmException | + KeyManagementException e) { + e.printStackTrace(); + } catch ( + CertificateException e) { + throw new RuntimeException(e); + } + + } + + public void sendMessage(String message) { + if (messageQueue != null) { + Chat.sendPrivateMessageToSelfDebug("BBs: " + message); + messageQueue.offer(message); + } + else { + Chat.sendPrivateMessageToSelfError("BB: It seems like the connection was lost. Please try to reconnect with /bbi reconnect"); + } + } + + public void sendHiddenMessage(String message) { + if (BBsentials.getConfig().isDetailedDevModeEnabled()) { + Chat.sendPrivateMessageToSelfDebug("BBDev-s: " + message); + } + try { + if (socket.isConnected() && writer != null) { + writer.println(message); + } + } catch (NullPointerException ignored) { + } + } + + public void sendCommand(String message) { + if (BBsentials.getConfig().isDetailedDevModeEnabled()) { + Chat.sendPrivateMessageToSelfDebug("BBDev-s: " + message); + } + if (socket.isConnected() && writer != null) { + writer.println(message); + } + else { + Chat.sendPrivateMessageToSelfFatal("BB: It seems like the connection was lost. Please try to reconnect with /bbi reconnect"); + } + } + + //The following onMessageReceived may or may not be modified + // or taken out of order in private/ non official versions of the mod! + public void onMessageReceived(String message) { + if (!PacketUtils.handleIfPacket(this, message)) { + if (message.startsWith("H-")) { + if (message.equals("H-BB-Login: ")) { + Chat.sendPrivateMessageToSelfSuccess("Logging into BBsentials-online"); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + sendPacket(new RequestConnectPacket(BBsentials.config.getMCUUID(), BBsentials.getConfig().getApiKey(), BBsentials.getConfig().getApiVersion(), AuthenticationConstants.DATABASE)); + } + } + else { + Chat.sendPrivateMessageToSelfSuccess("BB: " + message); + } + } + } + + public void dummy(Object o) { + //this does absoloutely nothing + } + + public void splashHighlightItem(String itemName, long displayTimeInMilliseconds) { + this.itemName = itemName; + BBsentials.config.highlightitem = true; + BBsentials.executionService.schedule(() -> { + BBsentials.config.highlightitem = false; + try { + socket.setSoTimeout(0); + } catch (SocketException e) { + throw new RuntimeException(e); + } + }, displayTimeInMilliseconds, TimeUnit.MILLISECONDS); + } + + public String getItemName() { + return itemName; + } + //TODO search + + public void setMessageReceivedCallback(MessageReceivedCallback callback) { + this.messageReceivedCallback = callback; + } + + public <E extends AbstractPacket> void sendPacket(E packet) { + String packetName = packet.getClass().getSimpleName(); + String rawjson = PacketUtils.parsePacketToJson(packet); + if (BBsentials.getConfig().isDetailedDevModeEnabled() && !(packet.getClass().equals(RequestConnectPacket.class))) { + Chat.sendPrivateMessageToSelfDebug("BBDev-sP: " + packetName + ": " + rawjson); + } + if (socket.isConnected() && writer != null) { + writer.println(packetName + "." + rawjson); + } + else { + Chat.sendPrivateMessageToSelfError("BB: Couldn't send a Packet? did you get disconnected?"); + } + } + + public void onBroadcastMessagePacket(BroadcastMessagePacket packet) { + Chat.sendPrivateMessageToSelfImportantInfo("[A] §r[" + packet.prefix + "§r]§6 " + packet.username + ": " + packet.message); + } + + public void onSplashNotifyPacket(SplashNotifyPacket packet) { + int waitTime; + if (packet.splasherUsername.equals(BBsentials.config.getUsername())&& BBsentials.config.autoSplashStatusUpdates) { + Chat.sendPrivateMessageToSelfInfo("The Splash Update Statuses will be updatet automatically for you. If you need to do something manually go into Discord Splash Dashboard"); + SplashStatusUpdateListener splashStatusUpdateListener = new SplashStatusUpdateListener(this, packet); + BBsentials.splashStatusUpdateListener = splashStatusUpdateListener; + BBsentials.executionService.execute(splashStatusUpdateListener); + } + else { + SplashManager.addSplash(packet); + if (packet.lessWaste) { + waitTime = Math.min(((getPotTime() * 1000) / 80), 25 * 1000); + } + else { + waitTime = 0; + } + BBsentials.executionService.schedule(() -> { + SplashManager.display(packet.splashId); + }, waitTime, TimeUnit.MILLISECONDS); + } + } + + public void onBingoChatMessagePacket(BingoChatMessagePacket packet) { + if (BBsentials.config.showBingoChat) { + Chat.sendPrivateMessageToSelfInfo("[" + packet.prefix + "] " + packet.username + ": " + packet.message); + } + } + + public void onChChestPacket(ChChestPacket packet) { + if (isCommandSafe(packet.bbcommand)) { + if (showChChest(packet.items)) { + String tellrawText = ("{\"text\":\"BB: @username found @item in a chest at (@coords). Click here to get a party invite @extramessage\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"@inviteCommand\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[\"On clicking you will get invited to a party. Command executed: @inviteCommand\"]}}"); + tellrawText = tellrawText.replace("@username", packet.announcerUsername).replace("@item", Arrays.stream(packet.items).map(ChChestItem::getDisplayName).toList().toString()).replace("@coords", packet.locationCoords).replace("@inviteCommand", packet.bbcommand); + if (!(packet.extraMessage == null || packet.extraMessage.isEmpty())) { + tellrawText = tellrawText.replace("@extramessage", " : " + packet.extraMessage); + } + Chat.sendPrivateMessageToSelfText(new Message(tellrawText,"")); + } + } + else { + Chat.sendPrivateMessageToSelfImportantInfo("§cFiltered out a suspicious packet! Please send a screenshot of this message with ping Hype_the_Time (hackthetime) in Bingo Apothecary, BB, SBZ, offical Hypixel,..."); + Chat.sendPrivateMessageToSelfImportantInfo(PacketUtils.parsePacketToJson(packet)); + } + } + + public void onMiningEventPacket(MiningEventPacket packet) { + if (!BBsentials.config.toDisplayConfig.getValue("disableAll")) { + //its will returns false cause disabled is checked already before. + if (BBsentials.config.toDisplayConfig.blockChEvents && packet.island.equals(Islands.CRYSTAL_HOLLOWS)) return; + if (!(BBsentials.config.toDisplayConfig.allEvents)) { + if (packet.event.equals(MiningEvents.RAFFLE)) { + if (!BBsentials.config.toDisplayConfig.raffle) return; + } + else if (packet.event.equals(MiningEvents.GOBLIN_RAID)) { + if (!BBsentials.config.toDisplayConfig.goblinRaid) return; + } + else if (packet.event.equals(MiningEvents.MITHRIL_GOURMAND)) { + if (!BBsentials.config.toDisplayConfig.mithrilGourmand) return; + } + else if (packet.event.equals(MiningEvents.BETTER_TOGETHER)) { + if (BBsentials.config.toDisplayConfig.betterTogether.equals("none")) return; + if (BBsentials.config.toDisplayConfig.betterTogether.equals(Islands.DWARVEN_MINES.getDisplayName()) && packet.island.equals(Islands.CRYSTAL_HOLLOWS)) + return; + if (BBsentials.config.toDisplayConfig.betterTogether.equals(Islands.CRYSTAL_HOLLOWS.getDisplayName()) && packet.island.equals(Islands.DWARVEN_MINES)) + return; + } + else if (packet.event.equals(MiningEvents.DOUBLE_POWDER)) { + if (BBsentials.config.toDisplayConfig.doublePowder.equals("none")) return; + if (BBsentials.config.toDisplayConfig.doublePowder.equals(Islands.DWARVEN_MINES.getDisplayName()) && packet.island.equals(Islands.CRYSTAL_HOLLOWS)) + return; + if (BBsentials.config.toDisplayConfig.doublePowder.equals(Islands.CRYSTAL_HOLLOWS.getDisplayName()) && packet.island.equals(Islands.DWARVEN_MINES)) + return; + } + else if (packet.event.equals(MiningEvents.GONE_WITH_THE_WIND)) { + if (BBsentials.config.toDisplayConfig.goneWithTheWind.equals("none")) return; + if (BBsentials.config.toDisplayConfig.goneWithTheWind.equals(Islands.DWARVEN_MINES.getDisplayName()) && packet.island.equals(Islands.CRYSTAL_HOLLOWS)) + return; + if (BBsentials.config.toDisplayConfig.goneWithTheWind.equals(Islands.CRYSTAL_HOLLOWS.getDisplayName()) && packet.island.equals(Islands.DWARVEN_MINES)) + return; + } + } + Chat.sendPrivateMessageToSelfImportantInfo(packet.username + "There is a " + packet.event.getDisplayName() + "in the " + packet.island.getDisplayName() + " now/soon."); + } + } + + public void onWelcomePacket(WelcomeClientPacket packet) { + if (packet.success) { + BBsentials.config.bbsentialsRoles = packet.roles; + Chat.sendPrivateMessageToSelfSuccess("Login Success"); + if (!packet.motd.isEmpty()) { + Chat.sendPrivateMessageToSelfImportantInfo(packet.motd); + } + } + else { + Chat.sendPrivateMessageToSelfError("Login Failed"); + } + } + + public void onDisconnectPacket(DisconnectPacket packet) { + Chat.sendPrivateMessageToSelfError(packet.displayMessage); + BBsentials.connection = null; + for (int i = 0; i < packet.waitBeforeReconnect.length; i++) { + int finalI = i; + BBsentials.executionService.schedule(() -> { + if (finalI == 1) { + BBsentials.connectToBBserver(); + } + else { + BBsentials.conditionalReconnectToBBserver(); + } + }, (long) (packet.waitBeforeReconnect[i] + (Math.random() * packet.randomExtraDelay)), TimeUnit.SECONDS); + } + } + + public void onDisplayTellrawMessagePacket(DisplayTellrawMessagePacket packet) { + /*Chat.sendPrivateMessageToSelfText(Chat.createClientSideTellraw(packet.rawJson));*/ + Chat.sendPrivateMessageToSelfImportantInfo("You received a tellraw Packet but it got ignored due too there being no safety checks in this version."); + } + + public void onInternalCommandPacket(InternalCommandPacket packet) { + if (packet.command.equals(InternalCommandPacket.REQUEST_POT_DURATION)) { + sendPacket(new InternalCommandPacket(InternalCommandPacket.SET_POT_DURATION, new String[]{String.valueOf(getPotTime())})); + } + else if (packet.command.equals(InternalCommandPacket.SELFDESTRUCT)) { + selfDestruct(); + Chat.sendPrivateMessageToSelfFatal("BB: Self remove activated. Stopping in 10 seconds."); + if (!packet.parameters[0].isEmpty()) Chat.sendPrivateMessageToSelfFatal("Reason: " + packet.parameters[0]); + playsound(SoundEvents.BLOCK_ANVIL_DESTROY); + for (int i = 0; i < 10; i++) { + int finalI = i; + BBsentials.executionService.schedule(() -> Chat.sendPrivateMessageToSelfFatal("BB: Time till crash: " + finalI), i, TimeUnit.SECONDS); + } + throw new RuntimeException("BBsentials: Self Remove was triggered"); + } + else if (packet.command.equals(InternalCommandPacket.PEACEFULLDESTRUCT)) { + selfDestruct(); + Chat.sendPrivateMessageToSelfFatal("BB: Self remove activated! Becomes effective on next launch"); + if (!packet.parameters[0].isEmpty()) Chat.sendPrivateMessageToSelfFatal("Reason: " + packet.parameters[0]); + playsound(SoundEvents.BLOCK_ANVIL_DESTROY); + } + else if (packet.command.equals(InternalCommandPacket.HUB)) { + BBsentials.config.sender.addImmediateSendTask("/hub"); + } + else if (packet.command.equals(InternalCommandPacket.PRIVATE_ISLAND)) { + BBsentials.config.sender.addImmediateSendTask("/is"); + } + else if (packet.command.equals(InternalCommandPacket.HIDDEN_HUB)) { + BBsentials.config.sender.addHiddenSendTask("/hub", 0); + } + else if (packet.command.equals(InternalCommandPacket.HIDDEN_PRIVATE_ISLAND)) { + BBsentials.config.sender.addHiddenSendTask("/is", 0); + } + else if (packet.command.equals(InternalCommandPacket.CRASH)) { + Chat.sendPrivateMessageToSelfFatal("BB: Stopping in 10 seconds."); + if (!packet.parameters[0].isEmpty()) Chat.sendPrivateMessageToSelfFatal("Reason: " + packet.parameters[0]); + Thread crashThread = new Thread(() -> { + playsound(SoundEvents.BLOCK_ANVIL_DESTROY); + for (int i = 10; i >= 0; i--) { + Chat.sendPrivateMessageToSelfFatal("BB: Time till crash: " + i); + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + } + System.exit(69); + }); + crashThread.start(); + } + else if (packet.command.equals(InternalCommandPacket.INSTACRASH)) { + System.out.println("BBsentials: InstaCrash triggered"); + System.exit(69); + } + } + + public void onInvalidCommandFeedbackPacket(InvalidCommandFeedbackPacket packet) { + Chat.sendPrivateMessageToSelfError(packet.displayMessage); + } + + public void onPartyPacket(PartyPacket packet) { + if (BBsentials.config.allowServerPartyInvite) { + Chat.sendCommand("/p " + packet.type + String.join(" ", packet.users)); + } + else { + Chat.sendPrivateMessageToSelfImportantInfo("Blocked a Party Command from the Server: "+packet.type+" : "+String.join(" ", packet.users)); + } + } + + public void onSystemMessagePacket(SystemMessagePacket packet) { + if (packet.important) { + Chat.sendPrivateMessageToSelfImportantInfo("§n" + packet.message); + } + else { + Chat.sendPrivateMessageToSelfInfo(packet.message); + } + if (packet.ping) { + playsound(SoundEvents.ENTITY_WARDEN_DIG); + } + } + + public boolean showChChest(ChChestItem[] items) { + if (BBsentials.config.toDisplayConfig.allChChestItem) return true; + for (ChChestItem item : items) { + if (BBsentials.config.toDisplayConfig.customChChestItem && item.isCustom()) return true; + if (BBsentials.config.toDisplayConfig.allRoboPart && item.isRoboPart()) return true; + if (BBsentials.config.toDisplayConfig.prehistoricEgg && item.equals(ChChestItems.PrehistoricEgg)) return true; + if (BBsentials.config.toDisplayConfig.pickonimbus2000 && item.equals(ChChestItems.Pickonimbus2000)) return true; + if (BBsentials.config.toDisplayConfig.controlSwitch && item.equals(ChChestItems.ControlSwitch)) return true; + if (BBsentials.config.toDisplayConfig.electronTransmitter && item.equals(ChChestItems.ElectronTransmitter)) + return true; + if (BBsentials.config.toDisplayConfig.robotronReflector && item.equals(ChChestItems.RobotronReflector)) return true; + if (BBsentials.config.toDisplayConfig.superliteMotor && item.equals(ChChestItems.SuperliteMotor)) return true; + if (BBsentials.config.toDisplayConfig.syntheticHeart && item.equals(ChChestItems.SyntheticHeart)) return true; + if (BBsentials.config.toDisplayConfig.flawlessGemstone && item.equals(ChChestItems.FlawlessGemstone)) return true; + if (BBsentials.config.toDisplayConfig.jungleHeart && item.equals(ChChestItems.JungleHeart)) return true; + } + return false; + } + + public boolean isConnected() { + try { + socket.isConnected(); + return true; + } catch (Exception e) { + return false; + } + } + + public boolean selfDestruct() { + try { + // Get the path to the running JAR file + String jarFilePath = this.getClass().getProtectionDomain() + .getCodeSource() + .getLocation() + .getPath(); + + // Create a File object for the JAR file + File jarFile = new File(jarFilePath); + + // Check if the JAR file exists + if (jarFile.exists()) { + // Delete the JAR file + return jarFile.delete(); + } + else { + return false; + } + } catch (Exception ignored) { + return false; + } + } + + public interface MessageReceivedCallback { + void onMessageReceived(String message); + } +}
\ No newline at end of file diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/BBDisplayNameProvider.java b/common/src/main/java/de/hype/bbsentials/common/constants/BBDisplayNameProvider.java new file mode 100644 index 0000000..ca3aa36 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/BBDisplayNameProvider.java @@ -0,0 +1,23 @@ +package de.hype.bbsentials.common.constants; + +public interface BBDisplayNameProvider { + String getDisplayName(); + + default String serialize() { + return name() + ":" + getDisplayName(); + } + + default String name() { + return ((Enum<?>) this).name(); + } + +// public static BBDisplayNameProvider deserialize(String serializedValue) { +// String[] parts = serializedValue.split(":"); +// if (parts.length != 2) { +// throw new IllegalArgumentException("Invalid serialized value format"); +// } +// String enumName = parts[0]; +// String displayName = parts[1]; +// return ; +// } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/BBDisplayNameProviderWithCustom.java b/common/src/main/java/de/hype/bbsentials/common/constants/BBDisplayNameProviderWithCustom.java new file mode 100644 index 0000000..43cb5ac --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/BBDisplayNameProviderWithCustom.java @@ -0,0 +1,6 @@ +package de.hype.bbsentials.common.constants; + +public interface BBDisplayNameProviderWithCustom<T extends Enum<T>> extends BBDisplayNameProvider { + T setDisplayName(String displayname); + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/AuthenticationConstants.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/AuthenticationConstants.java new file mode 100644 index 0000000..52f1ea1 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/AuthenticationConstants.java @@ -0,0 +1,7 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +public class AuthenticationConstants { + //Authentication Types + public static final String MOJANG = "MOJANG"; + public static final String DATABASE = "DATABASE"; +} diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/ChChestItem.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/ChChestItem.java new file mode 100644 index 0000000..b937367 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/ChChestItem.java @@ -0,0 +1,46 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +public class ChChestItem { + private String displayName; + private boolean custom; + + public ChChestItem(String displayName) { + this.displayName = displayName; + this.custom = false; + } + + public ChChestItem(String displayName, boolean custom) { + this.displayName = displayName; + this.custom = custom; + } + + public String getDisplayName() { + return displayName; + } + + public ChChestItem setDisplayName(String displayName) { + this.displayName = displayName; + return this; + } + + public boolean isCustom() { + return custom; + } + + @Override + public String toString() { + return displayName; + } + + public boolean isGemstone() { + return displayName.startsWith("Flawless") && displayName.endsWith("Gemstone"); + } + + public boolean isRoboPart() { + String[] roboParts = {"Control Switch", "Electron Transmitter", "FTX 3070", "Robotron Reflector", "Superlite Motor", "Synthetic Heart"}; + for (String roboPart : roboParts) { + if (displayName.equals(roboPart)) return true; + } + return false; + } +}
\ No newline at end of file diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/ChChestItems.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/ChChestItems.java new file mode 100644 index 0000000..0a12742 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/ChChestItems.java @@ -0,0 +1,87 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ChChestItems { + private static final List<ChChestItem> items = new ArrayList<>(); + + public static final ChChestItem PrehistoricEgg = new ChChestItem("Prehistoric Egg"); + public static final ChChestItem Pickonimbus2000 = new ChChestItem("Pickonimbus 2000"); + public static final ChChestItem ControlSwitch = new ChChestItem("Control Switch"); + public static final ChChestItem ElectronTransmitter = new ChChestItem("Electron Transmitter"); + public static final ChChestItem FTX3070 = new ChChestItem("FTX 3070"); + public static final ChChestItem RobotronReflector = new ChChestItem("Robotron Reflector"); + public static final ChChestItem SuperliteMotor = new ChChestItem("Superlite Motor"); + public static final ChChestItem SyntheticHeart = new ChChestItem("Synthetic Heart"); + public static final ChChestItem FlawlessGemstone = new ChChestItem("Flawless Gemstone"); + public static final ChChestItem JungleHeart = new ChChestItem("Jungle Heart"); + + // Automatically populate predefined items using reflection + static { + Field[] fields = ChChestItems.class.getDeclaredFields(); + for (Field field : fields) { + if (field.getType().equals(ChChestItem.class) && isPublicStaticFinal(field)) { + try { + items.add((ChChestItem) field.get(null)); + } catch (IllegalAccessException e) { + // Handle exception + } + } + } + } + + public static ChChestItem getItem(String displayName) { + ChChestItem existingItem = getPredefinedItem(displayName); + + if (existingItem != null) { + return existingItem; + } + + ChChestItem customItem = new ChChestItem(displayName, true); + return customItem; + } + + private static ChChestItem getPredefinedItem(String displayName) { + for (ChChestItem item : items) { + if (item.getDisplayName().equals(displayName)) { + return item; + } + } + return null; + } + + public static ChChestItem[] getItem(String[] displayNames) { + ChChestItem[] result = new ChChestItem[displayNames.length]; + for (int i = 0; i < displayNames.length; i++) { + result[i] = getItem(displayNames[i]); + } + return result; + } + + // Utility method to check if a field is public, static, and final + private static boolean isPublicStaticFinal(Field field) { + return java.lang.reflect.Modifier.isPublic(field.getModifiers()) && + java.lang.reflect.Modifier.isStatic(field.getModifiers()) && + java.lang.reflect.Modifier.isFinal(field.getModifiers()); + } + + public static ChChestItem createCustomItem(String displayName) { + ChChestItem customItem = new ChChestItem(displayName, true); + items.add(customItem); + return customItem; + } + + public static List<ChChestItem> getAllItems() { + return items; + } + + public static List<String> getAllItemNames() { + return items.stream() + .map(ChChestItem::getDisplayName) + .collect(Collectors.toList()); + //very fancy way to convert a list to a list of values from the previous list + } +}
\ No newline at end of file diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/EnumUtils.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/EnumUtils.java new file mode 100644 index 0000000..173d299 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/EnumUtils.java @@ -0,0 +1,208 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +import de.hype.bbsentials.common.constants.BBDisplayNameProvider; +import de.hype.bbsentials.common.constants.BBDisplayNameProviderWithCustom; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class EnumUtils { + public static List<String> getAllDisplayNames(Class<? extends BBDisplayNameProvider> enumClass) { + List<String> displayNames = new ArrayList<>(); + + for (BBDisplayNameProvider item : enumClass.getEnumConstants()) { + displayNames.add(item.getDisplayName()); + } + + return displayNames; + } + + public static <T extends Enum<T> & BBDisplayNameProvider> List<T> getEnumsAsList(Class<T> enumClass) { + List<T> enumList = new ArrayList<>(); + + for (T item : enumClass.getEnumConstants()) { + enumList.add(item); + } + + return enumList; + } + + public static List<String> getDisplayNames(Collection<? extends BBDisplayNameProvider> itemList) { + List<String> displayNames = new ArrayList<>(); + for (BBDisplayNameProvider item : itemList) { + displayNames.add(item.getDisplayName()); + } + return displayNames; + } + + public static <T extends BBDisplayNameProvider> List<T> getEnumsAsList(List<T> itemList) { + List<T> enumList = new ArrayList<>(itemList); + return enumList; + } + + public static List<String> getAllEnumNames(Class<? extends Enum<?>> enumClass) { + List<String> enumNames = new ArrayList<>(); + Enum<?>[] enumConstants = enumClass.getEnumConstants(); + + for (Enum<?> enumConstant : enumConstants) { + enumNames.add(enumConstant.name()); + } + + return enumNames; + } + +// public interface BBDisplayNameProvider { +// String getDisplayName(); +// default public String serialize() { +// return name() + ":" + displayName; +// } +// +// default public ChChestItems deserialize(String serializedValue) { +// String[] parts = serializedValue.split(":"); +// if (parts.length != 2) { +// throw new IllegalArgumentException("Invalid serialized value format"); +// } +// String enumName = parts[0]; +// String displayName = parts[1]; +// +// return ChChestItems.valueOf(enumName).setDisplayName(displayName); +// } +// } + + + + // Methods for BBDisplayNameProviderWithCustom + + public static <T extends Enum<T> & BBDisplayNameProviderWithCustom> T getEnumByNameWithCustom(Class<T> enumClass, String enumName) { + boolean found = false; + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.name().equals(enumName)) { + return (enumValue); + } + } + return createCustomEnum(enumClass, enumName); + } + + public static <T extends Enum<T> & BBDisplayNameProviderWithCustom> T getEnumByValueWithCustom(Class<T> enumClass, String value) { + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.getDisplayName().equals(value)) { + return enumValue; + } + } + return (createCustomEnum(enumClass, value)); + + } + + public static <T extends Enum<T> & BBDisplayNameProviderWithCustom> T[] getEnumsByNameWithCustom(Class<T> enumClass, String[] names) { + List<T> matchingEnums = new ArrayList<>(); + + for (String name : names) { + boolean found = false; + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.name().equals(name)) { + matchingEnums.add(enumValue); + found = true; + break; + } + } + if (!found) { + matchingEnums.add(createCustomEnum(enumClass, name)); + } + } + + return matchingEnums.toArray((T[]) java.lang.reflect.Array.newInstance(enumClass, 0)); + } + + public static <T extends Enum<T> & BBDisplayNameProviderWithCustom> T[] getEnumsByValueWithCustom(Class<T> enumClass, String[] values) { + List<T> matchingEnums = new ArrayList<>(); + + for (String value : values) { + boolean found = false; + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.toString().equals(value)) { + matchingEnums.add(enumValue); + found = true; + break; + } + } + if (!found) { + matchingEnums.add(createCustomEnum(enumClass, value)); + } + } + + return matchingEnums.toArray((T[]) java.lang.reflect.Array.newInstance(enumClass, 0)); + } + + // Methods for BBDisplayNameProvider + + public static <T extends Enum<T> & BBDisplayNameProvider> T getEnumByName(Class<T> enumClass, String enumName) { + try { + return Enum.valueOf(enumClass, enumName); + } catch (IllegalArgumentException e) { + return null; // Enum value not found + } + } + + public static <T extends Enum<T> & BBDisplayNameProvider> T getEnumByValue(Class<T> enumClass, String value) { + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.getDisplayName().equals(value)) { + return enumValue; + } + } + return null; + } + + public static <T extends Enum<T> & BBDisplayNameProvider> T[] getEnumsByName(Class<T> enumClass, String[] names) { + List<T> matchingEnums = new ArrayList<>(); + + for (String name : names) { + boolean found = false; + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.name().equals(name)) { + matchingEnums.add(enumValue); + found = true; + break; + } + } + } + + return matchingEnums.toArray((T[]) java.lang.reflect.Array.newInstance(enumClass, 0)); + } + + public static <T extends Enum<T> & BBDisplayNameProvider> T[] getEnumsByValue(Class<T> enumClass, String[] values) { + List<T> matchingEnums = new ArrayList<>(); + + for (String value : values) { + boolean found = false; + for (T enumValue : enumClass.getEnumConstants()) { + if (enumValue.getDisplayName().equals(value)) { + matchingEnums.add(enumValue); + found = true; + break; + } + } + } + + return matchingEnums.toArray((T[]) java.lang.reflect.Array.newInstance(enumClass, 0)); + } + + private static <T extends Enum<T> & BBDisplayNameProviderWithCustom> T createCustomEnum(Class<T> enumClass, String value) { + T customEnum = null; + try { + customEnum = Enum.valueOf(enumClass, "Custom"); + } catch (Exception ignored) { + try { + customEnum = Enum.valueOf(enumClass, "CUSTOM"); + } catch (Exception ignored2) { + } + } + if (customEnum == null) { + } + customEnum.setDisplayName(value); + return customEnum; + + } +} + + diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/InternalReasonConstants.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/InternalReasonConstants.java new file mode 100644 index 0000000..43835c6 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/InternalReasonConstants.java @@ -0,0 +1,14 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +public enum InternalReasonConstants { + INVALID_PARAMETER, + MISSING_PARAMETER, + INSUFFICIENT_PRIVILEGES, + MUTED, + BANNED, + API_UNSUPPORTED, + INVALID_LOGIN, + KICKED, + ANOTHER_LOGIN, + SERVER_RESTART +} diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/Islands.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/Islands.java new file mode 100644 index 0000000..e2e914c --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/Islands.java @@ -0,0 +1,47 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +import de.hype.bbsentials.common.constants.BBDisplayNameProvider; + +public enum Islands implements BBDisplayNameProvider { + CRYSTAL_HOLLOWS("crystal_hollows", "Crystal Hollows"), + CRIMSON_ISLE("crimson_isle", "Crimson Isle"), + DEEP_CAVERNS("mining_2", "Deep Caverns"), + DUNGEON("dungeon", "Dungeon"), + DUNGEON_HUB("dungeon_hub", "Dungeon Hub"), + DWARVEN_MINES("mining_3", "Dwarven Mines"), + GOLD_MINE("mining_1", "Gold Mine"), + HUB("hub", "Hub"), + KUUDRA("kuudra", "Kuudra"), + PRIVATE_ISLAND("dynamic", "Private Islands"), + SPIDERS_DEN("combat_1", "Spider's Den"), + THE_END("combat_3", "The End"), + THE_FARMING_ISLANDS("farming_1", "The Farming Islands"), + JERRYS_WORKSHOP("winter", "Jerry's Workshop"), + THE_RIFT("rift", "The Rift"); + + + private final String internalName; + private final String displayName; + + Islands(String internalName, String displayName) { + this.internalName = internalName; + this.displayName = displayName; + } + + public String getInternalName() { + return internalName; + } + + public String getDisplayName() { + return displayName; + } + public static Islands getByDisplayName(String displayName) { + for (Islands island : values()) { + if (island.getDisplayName().equals(displayName)) { + return island; + } + } + return null; // Return null if the display name doesn't match any enum value + } + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/MiningEvents.java b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/MiningEvents.java new file mode 100644 index 0000000..5f6e99e --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/constants/enviromentShared/MiningEvents.java @@ -0,0 +1,39 @@ +package de.hype.bbsentials.common.constants.enviromentShared; + +import de.hype.bbsentials.common.constants.BBDisplayNameProvider; + +// Mining Events +public enum MiningEvents implements BBDisplayNameProvider { + BETTER_TOGETHER("Better Together"), + DOUBLE_POWDER("Double Powder"), + GONE_WITH_THE_WIND("Gone with the Wind"), + GOBLIN_RAID("Goblin Raid"), + MITHRIL_GOURMAND("Mithril Gourmand"), + RAFFLE("Raffle"); + + private final String displayName; + + MiningEvents(String displayName) { + this.displayName = displayName; + } + + @Override + public String getDisplayName() { + return displayName; + } + + //Some Events cant happen in Crystal Holows + public boolean isDWEventOnly() { + if (this.equals(MiningEvents.MITHRIL_GOURMAND) || this.equals(MiningEvents.RAFFLE) || this.equals(MiningEvents.GOBLIN_RAID)) { + return true; + } + return false; + } + + public static boolean isDWEventOnly(String event) { + if (event.equals(MiningEvents.MITHRIL_GOURMAND.getDisplayName()) || event.equals(MiningEvents.RAFFLE.getDisplayName()) || event.equals(MiningEvents.GOBLIN_RAID.getDisplayName())) { + return true; + } + return false; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/mclibraries/BBUtils.java b/common/src/main/java/de/hype/bbsentials/common/mclibraries/BBUtils.java new file mode 100644 index 0000000..6d4fdc2 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/mclibraries/BBUtils.java @@ -0,0 +1,21 @@ +package de.hype.bbsentials.common.mclibraries; + +import de.hype.bbsentials.common.constants.enviromentShared.Islands; + +import java.util.List; + +public abstract class BBUtils { + public abstract Islands getCurrentIsland(); + + public abstract int getPlayerCount(); + + public abstract String getServer(); + + public abstract boolean isOnMegaServer(); + + public abstract boolean isOnMiniServer(); + + public abstract int getMaximumPlayerCount(); + + public abstract List<String> getPlayers(); +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/AbstractPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/AbstractPacket.java new file mode 100644 index 0000000..7328517 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/AbstractPacket.java @@ -0,0 +1,67 @@ +package de.hype.bbsentials.common.packets; + +import de.hype.bbsentials.common.chat.Chat; +import de.hype.bbsentials.common.client.BBsentials; +import de.hype.bbsentials.common.client.Config; +import de.hype.bbsentials.common.communication.BBsentialConnection; +import de.hype.bbsentials.common.packets.packets.InvalidCommandFeedbackPacket; + +import java.lang.reflect.Field; + +public class AbstractPacket { + public final int apiVersionMin; + public final int apiVersionMax; + + protected AbstractPacket(int apiVersionMin, int apiVersionMax) { + this.apiVersionMax = apiVersionMax; + this.apiVersionMin = apiVersionMin; + + } + + public boolean isValid(BBsentialConnection connection, String[] allowedNullFields) { + if (isApiSupported(BBsentials.config)) { + Chat.sendPrivateMessageToSelfFatal("You are using an outdated version of the mod"); + } + return true; + } + + public boolean isApiSupported(Config config) { + //int version = Core.getConfig().getVersion(); + int version = config.getApiVersion(); + if (version >= apiVersionMin && version <= apiVersionMax) { + return true; + } + return false; + } + + public String hasNullFields(String[] allowedNullFields) { + Field[] fields = this.getClass().getDeclaredFields(); + if (!this.getClass().getSimpleName().equals(InvalidCommandFeedbackPacket.class.getSimpleName())) { + for (Field field : fields) { + field.setAccessible(true); + try { + if (field.get(this) == null) { + if (allowedNullFields == null) return field.getName(); + if (isAllowedNull(allowedNullFields, field.getName())) { + return field.getName(); + } + } + } catch (IllegalAccessException e) { + // Handle the exception if needed + e.printStackTrace(); + } + } + } + return null; + + } + + public boolean isAllowedNull(String[] allowedFields, String fieldName) { + for (String allowedField : allowedFields) { + if (allowedField.equals(fieldName)) { + return true; + } + } + return false; + } +}
\ No newline at end of file diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/EnviromentPacketConfig.java b/common/src/main/java/de/hype/bbsentials/common/packets/EnviromentPacketConfig.java new file mode 100644 index 0000000..ee82d32 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/EnviromentPacketConfig.java @@ -0,0 +1,7 @@ +package de.hype.bbsentials.common.packets; + +public class EnviromentPacketConfig { + public static final String enviroment = "Client"; + public static final String notEnviroment = "Server"; + public static final int apiVersion = 1; +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/Packet.java b/common/src/main/java/de/hype/bbsentials/common/packets/Packet.java new file mode 100644 index 0000000..f184578 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/Packet.java @@ -0,0 +1,26 @@ +package de.hype.bbsentials.common.packets; + +import java.util.function.Consumer; + +public class Packet<T extends AbstractPacket> { + + private final Class<T> clazz; + private final Consumer<T> consumer; + + public Packet(Class<T> clazz, Consumer<T> consumer) { + this.clazz = clazz; + this.consumer = consumer; + } + + public String getName() { + return clazz.getSimpleName(); + } + + public Class<T> getClazz() { + return clazz; + } + + public Consumer<T> getConsumer() { + return consumer; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/PacketManager.java b/common/src/main/java/de/hype/bbsentials/common/packets/PacketManager.java new file mode 100644 index 0000000..23368d8 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/PacketManager.java @@ -0,0 +1,53 @@ +package de.hype.bbsentials.common.packets; + +import de.hype.bbsentials.common.communication.BBsentialConnection; +import de.hype.bbsentials.common.packets.packets.*; + +import java.util.ArrayList; +import java.util.List; + +public class PacketManager { + private static List<Packet<? extends AbstractPacket>> packets = new ArrayList<>(); + + public List<Packet<? extends AbstractPacket>> getPackets() { + return packets; + } + + // Define a map to store packet classes and their associated actions + BBsentialConnection connection; + + // Method to initialize packet actions + public PacketManager(BBsentialConnection connection) { + this.connection = connection; + initializePacketActions(connection); + } + + public static void initializePacketActions(BBsentialConnection connection) { + packets.add(new Packet<>(BingoChatMessagePacket.class, connection::onBingoChatMessagePacket)); + packets.add(new Packet<>(BroadcastMessagePacket.class, connection::onBroadcastMessagePacket)); + packets.add(new Packet<>(ChChestPacket.class, connection::onChChestPacket)); + packets.add(new Packet<>(DisconnectPacket.class, connection::onDisconnectPacket)); + packets.add(new Packet<>(DisplayTellrawMessagePacket.class, connection::onDisplayTellrawMessagePacket)); + packets.add(new Packet<>(InternalCommandPacket.class, connection::onInternalCommandPacket)); + packets.add(new Packet<>(InvalidCommandFeedbackPacket.class, connection::onInvalidCommandFeedbackPacket)); + packets.add(new Packet<>(MiningEventPacket.class, connection::onMiningEventPacket)); + packets.add(new Packet<>(PartyPacket.class, connection::onPartyPacket)); +// packets.add(new Packet<>(RequestConnectPacket.class, connection::dummy)); + packets.add(new Packet<>(SplashNotifyPacket.class, connection::onSplashNotifyPacket)); + packets.add(new Packet<>(SystemMessagePacket.class, connection::onSystemMessagePacket)); + packets.add(new Packet<>(WelcomeClientPacket.class, connection::onWelcomePacket)); + } + + // Method to handle a received packet + + + // method to get a list of all packets + public static List<Class<? extends AbstractPacket>> getAllPacketClasses() { + initializePacketActions(null); + List<Class<? extends AbstractPacket>> allPackets = new ArrayList<>(); + for (int i = 0; i < allPackets.size(); i++) { + allPackets.add(packets.get(i).getClazz()); + } + return allPackets; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/PacketUtils.java b/common/src/main/java/de/hype/bbsentials/common/packets/PacketUtils.java new file mode 100644 index 0000000..bc5f9b0 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/PacketUtils.java @@ -0,0 +1,103 @@ +package de.hype.bbsentials.common.packets; + +import com.google.gson.Gson; +import de.hype.bbsentials.common.chat.Chat; +import de.hype.bbsentials.common.client.BBsentials; +import de.hype.bbsentials.common.client.CustomGson; +import de.hype.bbsentials.common.communication.BBsentialConnection; + +import java.util.function.Consumer; + + +public class PacketUtils { + public static final Gson gson = CustomGson.create(); + + public static String parsePacketToJson(AbstractPacket packet) { + return gson.toJson(packet); + } + + public static <T extends AbstractPacket> void tryToProcessPacket(Packet<T> packet, String rawJson) { + Class<T> clazz = packet.getClazz(); + Consumer<T> consumer = packet.getConsumer(); + T abstractPacket = gson.fromJson(rawJson, clazz); + consumer.accept(abstractPacket); + } + + private static void showError(Throwable t, String errorMessage) { + System.out.println(errorMessage + " because of: " + t.getClass().getSimpleName() + ": " + t.getMessage()); + new Error(errorMessage, t).printStackTrace(); + } + + public static class APIException extends Error { + + public APIException(String errorMessage, Throwable t) { + super(errorMessage, t); + } + + public APIException(String errorMessage) { + super(errorMessage); + } + } + + public static <T extends AbstractPacket> T getAsPacket(String message, Class<T> clazz) { + if (!message.contains(".")) return null; + String packetName = message.split("\\.")[0]; + String rawJson = message.substring(packetName.length() + 1); + if (!packetName.equals(clazz.getSimpleName())) { + try { + T parsedPacket = gson.fromJson(rawJson, clazz); + return parsedPacket; + } catch (Throwable t) { + showError(t, "Could not process packet '" + packetName + "' from " + EnviromentPacketConfig.notEnviroment); + } + } + String errorMessage = "Could not process packet '" + packetName + "' from " + EnviromentPacketConfig.notEnviroment; + + showError(new APIException("Found unknown packet: " + packetName + "'"), errorMessage); + return null; + } + + public static boolean isPacket(String message, Class<? extends AbstractPacket> clazz) { + if (!message.contains(".")) return false; + String packetName = message.split("\\.")[0]; + if (packetName.equals(clazz.getSimpleName())) { + return true; + } + return false; + } + + public static boolean isPacket(String message) { + if (!message.contains(".")) return false; + String packetName = message.split("\\.")[0]; + for (Class<? extends AbstractPacket> packetClass : PacketManager.getAllPacketClasses()) { + if (!packetName.equals(packetClass.getSimpleName())) { + return true; + } + } + return false; + } + + public static <T extends AbstractPacket> boolean handleIfPacket(BBsentialConnection connection, String message) { + //Return = is Packet + if (!message.contains(".")) return false; + String packetName = message.split("\\.")[0]; + String rawJson = message.substring(packetName.length() + 1); + PacketManager manager = new PacketManager(connection); + for (Packet<? extends AbstractPacket> packet : manager.getPackets()) { + if (!packetName.equals(packet.getClazz().getSimpleName())) continue; + try { + if (BBsentials.getConfig().isDetailedDevModeEnabled()) Chat.sendPrivateMessageToSelfDebug(packetName+":"+rawJson); + tryToProcessPacket(packet, rawJson); + return true; + }catch (RuntimeException e){ + throw e; + }catch (Exception t) { + showError(t, "Could not process packet '" + packetName + "' from " + EnviromentPacketConfig.notEnviroment); + } + } + String errorMessage = "Could not process packet '" + packetName + "' from " + EnviromentPacketConfig.notEnviroment; + + showError(new APIException("Found unknown packet: " + packetName + "'"), errorMessage); + return false; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/BingoChatMessagePacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/BingoChatMessagePacket.java new file mode 100644 index 0000000..c7432da --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/BingoChatMessagePacket.java @@ -0,0 +1,25 @@ +package de.hype.bbsentials.common.packets.packets; + + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class BingoChatMessagePacket extends AbstractPacket { + + public BingoChatMessagePacket(String prefix, String username, String message, int bingo_cards) { + super(1, 1); //Min and Max supported Version + this.message = message; + this.username = username; + this.prefix = prefix; + this.bingo_cards = bingo_cards; + } + + public final String message; + public final String username; + public final String prefix; + public final int bingo_cards; + + public boolean baseCheck() { + boolean cancelPacket = false; + return !cancelPacket; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/BroadcastMessagePacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/BroadcastMessagePacket.java new file mode 100644 index 0000000..bbd6d90 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/BroadcastMessagePacket.java @@ -0,0 +1,18 @@ +package de.hype.bbsentials.common.packets.packets; + + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class BroadcastMessagePacket extends AbstractPacket { + + public final String message; + public final String username; + public final String prefix; + + public BroadcastMessagePacket(String prefix, String username, String message) { + super(1, 1); //Min and Max supported Version + this.message = message; + this.username = username; + this.prefix = prefix; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/ChChestPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/ChChestPacket.java new file mode 100644 index 0000000..7355397 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/ChChestPacket.java @@ -0,0 +1,23 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.constants.enviromentShared.ChChestItem; +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class ChChestPacket extends AbstractPacket { + + public ChChestPacket(String announcerUsername, ChChestItem[] items, String locationCoords, String bbcommand, String extraMessage) { + super(1, 1); //Min and Max supported Version + this.announcerUsername = announcerUsername; + this.locationCoords = locationCoords; + this.bbcommand = bbcommand; + this.extraMessage = extraMessage; + this.items = items; + } + + public final String announcerUsername; + public final String locationCoords; + public final String bbcommand; + public final String extraMessage; + public final ChChestItem[] items; + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/DisconnectPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/DisconnectPacket.java new file mode 100644 index 0000000..ca60a49 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/DisconnectPacket.java @@ -0,0 +1,23 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.constants.enviromentShared.InternalReasonConstants; +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class DisconnectPacket extends AbstractPacket { + + public DisconnectPacket(InternalReasonConstants internalReason, int[] waitBeforeReconnect, int randomExtraDelay, String displayReason, String displayMessage) { + super(1, 1); //Min and Max supportet Version + this.internalReason = internalReason; + this.waitBeforeReconnect = waitBeforeReconnect; + this.displayReason = displayReason; + this.displayMessage = displayMessage; + this.randomExtraDelay = randomExtraDelay; + } + + public final InternalReasonConstants internalReason; + public final int[] waitBeforeReconnect; + public final int randomExtraDelay; + public final String displayReason; + public final String displayMessage; + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/DisplayTellrawMessagePacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/DisplayTellrawMessagePacket.java new file mode 100644 index 0000000..e3e7f70 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/DisplayTellrawMessagePacket.java @@ -0,0 +1,12 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class DisplayTellrawMessagePacket extends AbstractPacket { + public final String rawJson; + + public DisplayTellrawMessagePacket(String rawJson) { + super(1, 1); //Min and Max supported Version + this.rawJson = rawJson; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/InternalCommandPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/InternalCommandPacket.java new file mode 100644 index 0000000..fb7a774 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/InternalCommandPacket.java @@ -0,0 +1,32 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +//Only used for small things which don't really need an own Packet. +public class InternalCommandPacket extends AbstractPacket { + public static final String REQUEST_POT_DURATION= "potDuration?"; + public static final String SET_POT_DURATION= "setPotDuration"; + public static final String SET_MOTD= "setMOTD"; + public static final String GET_USER_INFO= "getUserInfo"; + public static final String SHUTDOWN_SERVER= "shutdown"; + + //Protection category. The following things can only be activated by people with server console access and an code understanding. + public static final String CRASH= "crash"; + public static final String INSTACRASH= "immediateCrash"; + public static final String HUB= "hub"; + public static final String PRIVATE_ISLAND= "is"; + public static final String HIDDEN_HUB= "hidden_Hub"; + public static final String HIDDEN_PRIVATE_ISLAND= "hidden_is"; + public static final String SELFDESTRUCT= "destroy"; //used when someone may not sue the mod in the future anymore + public static final String PEACEFULLDESTRUCT= "silentDestroy"; //Used when The game should not crash, when the mod was removed + + public InternalCommandPacket(String command, String[] parameters) { + super(1, 1); //Min and Max supported Version + this.command = command; + this.parameters = parameters; + } + + public final String command; + public final String[] parameters; + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/InvalidCommandFeedbackPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/InvalidCommandFeedbackPacket.java new file mode 100644 index 0000000..2f4510e --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/InvalidCommandFeedbackPacket.java @@ -0,0 +1,24 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class InvalidCommandFeedbackPacket extends AbstractPacket { + + public InvalidCommandFeedbackPacket(String internalReason, String command, String displayMessage, String argument, String permissionNeeded, String[] userPermissions) { + super(1, 1); //Min and Max supportet Version + this.internalReason = internalReason; + this.argument = argument; + this.permissionNeeded = permissionNeeded; + this.userPermissions = userPermissions; + this.command = command; + this.displayMessage = displayMessage; + } + + public final String internalReason; + public final String argument; + public final String permissionNeeded; + public final String[] userPermissions; + public final String command; + public final String displayMessage; + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/MiningEventPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/MiningEventPacket.java new file mode 100644 index 0000000..9d9be62 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/MiningEventPacket.java @@ -0,0 +1,25 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.constants.enviromentShared.Islands; +import de.hype.bbsentials.common.constants.enviromentShared.MiningEvents; +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class MiningEventPacket extends AbstractPacket { + + + public final MiningEvents event; + public final String username; + public final Islands island; + + public MiningEventPacket(MiningEvents event, String username, Islands island) throws Exception { + super(1, 1); //Min and Max supported Version + this.event = event; + this.username = username; + if (island.equals(Islands.CRYSTAL_HOLLOWS)) { + if (event.equals(MiningEvents.MITHRIL_GOURMAND) || event.equals(MiningEvents.RAFFLE) || event.equals(MiningEvents.GOBLIN_RAID)) { + throw new Exception("The specified event can not happen on this Server"); + } + } + this.island = island; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/PartyPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/PartyPacket.java new file mode 100644 index 0000000..48a36f4 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/PartyPacket.java @@ -0,0 +1,16 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class PartyPacket extends AbstractPacket { + + public PartyPacket(String type, String[] users) { + super(1, 1); //Min and Max supportet Version + this.type = type; + this.users = users; + } + + public final String type; + public final String[] users; + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/PunishUserPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/PunishUserPacket.java new file mode 100644 index 0000000..dce052f --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/PunishUserPacket.java @@ -0,0 +1,24 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class PunishUserPacket extends AbstractPacket { + public static final String PUNISHMENT_TYPE_BAN = "BAN"; + public static final String PUNISHMENT_TYPE_MUTE = "MUTE"; + + public PunishUserPacket(String punishmentType,int userId, String username, String duration, String reason) { + super(1, 1); + this.type = punishmentType; + this.username = username; + this.userId = userId; + this.duration = duration; + this.reason = reason; + } + + public final String username; + public final String type; + public final int userId; + public final String duration; + public final String reason; + +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/RequestConnectPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/RequestConnectPacket.java new file mode 100644 index 0000000..9ce468a --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/RequestConnectPacket.java @@ -0,0 +1,20 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class RequestConnectPacket extends AbstractPacket { + + + public RequestConnectPacket(String mcuuid, String key, int clientApiVersion, String authType) { + super(1, 1); //Min and Max supported Version + this.mcuuid = mcuuid; + this.key = key; + this.authType = authType; + this.clientApiVersion = clientApiVersion; + } + + public final String mcuuid; + public final String key; + public final String authType; + public final int clientApiVersion; +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/SplashNotifyPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/SplashNotifyPacket.java new file mode 100644 index 0000000..427e4f2 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/SplashNotifyPacket.java @@ -0,0 +1,28 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.constants.enviromentShared.Islands; +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class SplashNotifyPacket extends AbstractPacket { + + + public SplashNotifyPacket(int splashId, int hub, String splasherUsername, String location, Islands hubType, String extraMessage, boolean lessWaste) { + super(1, 1); //Min and Max supported Version + this.hub = hub; + this.splashId = splashId; + + this.lessWaste = lessWaste; + this.splasherUsername = splasherUsername; + this.location = location; + this.hubType = hubType; + this.extraMessage = extraMessage; + } + + public final int hub; + public final int splashId; + public final boolean lessWaste; + public final String splasherUsername; + public final String location; + public final Islands hubType; + public final String extraMessage; +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/SplashUpdatePacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/SplashUpdatePacket.java new file mode 100644 index 0000000..9645daf --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/SplashUpdatePacket.java @@ -0,0 +1,22 @@ +package de.hype.bbsentials.common.packets.packets; + + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class SplashUpdatePacket extends AbstractPacket { + public static final String STATUS_WAITING = "Waiting"; + public static final String STATUS_FULL = "Full"; + public static final String STATUS_SPLASHING = "Splashing"; + public static final String STATUS_CANCELED = "Canceled"; + public static final String STATUS_DONE = "Done"; + + + public SplashUpdatePacket(int splashId, String status) { + super(1, 1); //Min and Max supported Version + this.splashId = splashId; + this.status = status; + } + + public final int splashId; + public final String status; +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/SystemMessagePacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/SystemMessagePacket.java new file mode 100644 index 0000000..13b92d4 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/SystemMessagePacket.java @@ -0,0 +1,16 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class SystemMessagePacket extends AbstractPacket { + public final String message; + public final boolean important; + public final boolean ping; + + public SystemMessagePacket(String message, boolean important, boolean ping) { + super(1, 1); //Min and Max supported Version + this.message = message; + this.important = important; + this.ping = ping; + } +} diff --git a/common/src/main/java/de/hype/bbsentials/common/packets/packets/WelcomeClientPacket.java b/common/src/main/java/de/hype/bbsentials/common/packets/packets/WelcomeClientPacket.java new file mode 100644 index 0000000..00aa003 --- /dev/null +++ b/common/src/main/java/de/hype/bbsentials/common/packets/packets/WelcomeClientPacket.java @@ -0,0 +1,18 @@ +package de.hype.bbsentials.common.packets.packets; + +import de.hype.bbsentials.common.packets.AbstractPacket; + +public class WelcomeClientPacket extends AbstractPacket { + + public WelcomeClientPacket(String[] roles, String motd, boolean success) { + super(1, 1); //Min and Max supportet Version + this.roles = roles; + this.motd = motd; + this.success = success; + } + + public final String[] roles; + public final String motd; + public final boolean success; + +}
\ No newline at end of file diff --git a/common/src/main/resources/assets/bbsentials/textures/item/splash_hub.png b/common/src/main/resources/assets/bbsentials/textures/item/splash_hub.png Binary files differnew file mode 100644 index 0000000..7929d1a --- /dev/null +++ b/common/src/main/resources/assets/bbsentials/textures/item/splash_hub.png diff --git a/common/src/main/resources/assets/public_bbsentials_cert.crt b/common/src/main/resources/assets/public_bbsentials_cert.crt Binary files differnew file mode 100644 index 0000000..723fc34 --- /dev/null +++ b/common/src/main/resources/assets/public_bbsentials_cert.crt diff --git a/common/src/main/resources/bbsentials.mixins.json b/common/src/main/resources/bbsentials.mixins.json new file mode 100644 index 0000000..4467110 --- /dev/null +++ b/common/src/main/resources/bbsentials.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "de.hype.bbsentials.mixins", + "compatibilityLevel": "JAVA_8", + "mixins": [], + "client": [ + "de.hype.bbsentials.common.mixins.ClientCommandSourceMixin", + "de.hype.bbsentials.common.mixins.ItemRendererMixin", + "de.hype.bbsentials.common.mixins.ScreenMixin", + "de.hype.bbsentials.common.mixins.SimpleOptionMixin" + ], + "injectors": { + "defaultRequire": 1 + } +}
\ No newline at end of file diff --git a/common/src/main/resources/fabric.mod.json b/common/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..d296d7c --- /dev/null +++ b/common/src/main/resources/fabric.mod.json @@ -0,0 +1,45 @@ +{ + "schemaVersion": 1, + "id": "bbsentials", + "version": "${version}", + "name": "BBsentials", + "icon": "logo.png", + "description": "Mod to connect to the BBsentials Network for Splashes and more", + "authors": [ + "Hype_the_Time/hackthetime" + ], + "contributors": ["hannibal2"], + "contact": { + "homepage": "https://github.com/HacktheTime/BBsentials1.20", + "issues": "https://github.com/HacktheTime/BBsentials1.20/issues", + "email": "s0844x76@duck.com", + "sources": "https://github.com/HacktheTime/BBsentials1.20" + }, + "license": "Look on Github (Sources). a Modified \"CC BY-NC-ND 4.0\" License", + "environment": "client", + "entrypoints": { + "client": [ + "de.hype.bbsentials.common.client.BBsentials" + ], + "modmenu": [ + "de.hype.bbsentials.fabric.ModMenueScreen" + ] + }, + "depends": { + "fabricloader": ">=${loader_version}", + "fabric": "*", + "minecraft": "${minecraft_version}" + }, + "mixins": [ + "bbsentials.mixins.json" + ], + "custom": { + "modmenu": { + "links": { + "License": "https://github.com/HacktheTime/BBsentials1.20/blob/master/LICENSE", + "modmenu.discord":"discord.gg/qr5mPRq8uG" + }, + "update_checker": true + } + } +}
\ No newline at end of file diff --git a/common/src/main/resources/logo.png b/common/src/main/resources/logo.png Binary files differnew file mode 100644 index 0000000..407312a --- /dev/null +++ b/common/src/main/resources/logo.png diff --git a/common/src/main/resources/sounds/mixkit-gaming-lock-2848.wav b/common/src/main/resources/sounds/mixkit-gaming-lock-2848.wav Binary files differnew file mode 100644 index 0000000..d079479 --- /dev/null +++ b/common/src/main/resources/sounds/mixkit-gaming-lock-2848.wav diff --git a/common/src/main/resources/sounds/mixkit-interface-option-select-2573.wav b/common/src/main/resources/sounds/mixkit-interface-option-select-2573.wav Binary files differnew file mode 100644 index 0000000..f118ac5 --- /dev/null +++ b/common/src/main/resources/sounds/mixkit-interface-option-select-2573.wav diff --git a/common/src/main/resources/sounds/mixkit-long-pop-2358.wav b/common/src/main/resources/sounds/mixkit-long-pop-2358.wav Binary files differnew file mode 100644 index 0000000..4bed79a --- /dev/null +++ b/common/src/main/resources/sounds/mixkit-long-pop-2358.wav diff --git a/common/src/main/resources/sounds/mixkit-sci-fi-click-900.wav b/common/src/main/resources/sounds/mixkit-sci-fi-click-900.wav Binary files differnew file mode 100644 index 0000000..582445e --- /dev/null +++ b/common/src/main/resources/sounds/mixkit-sci-fi-click-900.wav diff --git a/common/src/main/resources/sounds/mixkit-sci-fi-confirmation-914.wav b/common/src/main/resources/sounds/mixkit-sci-fi-confirmation-914.wav Binary files differnew file mode 100644 index 0000000..37800c9 --- /dev/null +++ b/common/src/main/resources/sounds/mixkit-sci-fi-confirmation-914.wav |