Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/java/simplexity/simplepms/SimplePMs.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import simplexity.simplepms.commands.SocialSpy;
import simplexity.simplepms.commands.Unblock;
import simplexity.simplepms.config.ConfigHandler;
import simplexity.simplepms.hooks.DiscordWebHook;
import simplexity.simplepms.listeners.JoinListener;
import simplexity.simplepms.listeners.PreCommandListener;
import simplexity.simplepms.listeners.PrivateMessageListener;
import simplexity.simplepms.listeners.QuitListener;
import simplexity.simplepms.logic.Constants;
import simplexity.simplepms.saving.SqlHandler;
Expand Down Expand Up @@ -47,6 +49,7 @@ private void registerListeners() {
getServer().getPluginManager().registerEvents(new QuitListener(), this);
getServer().getPluginManager().registerEvents(new PreCommandListener(), this);
getServer().getPluginManager().registerEvents(new JoinListener(), this);
getServer().getPluginManager().registerEvents(new PrivateMessageListener(), this);
}

private void loadConfigStuff() {
Expand Down Expand Up @@ -91,6 +94,7 @@ private void registerPermissions() {
@Override
public void onDisable() {
SqlHandler.getInstance().shutdownConnection();
DiscordWebHook.removeClient();
}

public static MiniMessage getMiniMessage() {
Expand Down
35 changes: 33 additions & 2 deletions src/main/java/simplexity/simplepms/config/ConfigHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import simplexity.simplepms.SimplePMs;
import simplexity.simplepms.hooks.DiscordWebHook;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ConfigHandler {
Expand All @@ -22,12 +25,13 @@ public static ConfigHandler getInstance() {

private final Logger logger = SimplePMs.getInstance().getLogger();
private boolean mysqlEnabled, playersSendToConsole, playersSendToHiddenPlayers, consoleHasSocialSpy,
commandSpyEnabled, consoleHasCommandSpy, receiveSoundEnabled, sendSoundEnabled, spySoundEnabled;
commandSpyEnabled, consoleHasCommandSpy, receiveSoundEnabled, sendSoundEnabled, spySoundEnabled, webhookEnabled;
private NamespacedKey receiveSound = Registry.SOUNDS.getKey(Sound.BLOCK_NOTE_BLOCK_XYLOPHONE);
private NamespacedKey sendSound = Registry.SOUNDS.getKey(Sound.ENTITY_ALLAY_ITEM_THROWN);
private NamespacedKey spySound = Registry.SOUNDS.getKey(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM);
private float receivePitch, receiveVolume, sendPitch, sendVolume, spyPitch, spyVolume;
private String mysqlIp, mysqlName, mysqlUsername, mysqlPassword, normalFormat, socialSpyFormat;
private String mysqlIp, mysqlName, mysqlUsername, mysqlPassword, normalFormat, socialSpyFormat, webhookBody;
private URI webhookUri;
private final List<String> validNamesForConsole = new ArrayList<>();
private final HashSet<String> commandsToSpy = new HashSet<>();

Expand All @@ -54,9 +58,11 @@ public void loadConfigValues() {
receiveSoundEnabled = config.getBoolean("sounds.received.enabled", false);
sendSoundEnabled = config.getBoolean("sounds.sent.enabled", false);
spySoundEnabled = config.getBoolean("sounds.spy.enabled", false);
webhookEnabled = config.getBoolean("webhook.enabled", false);
if (receiveSoundEnabled) loadReceiveSoundInfo(config);
if (sendSoundEnabled) loadSendSoundInfo(config);
if (spySoundEnabled) loadSpySoundInfo(config);
if (webhookEnabled) loadWebhook(config);
}

private void updateHashSet(HashSet<String> set, List<String> list) {
Expand Down Expand Up @@ -85,6 +91,25 @@ private void loadSpySoundInfo(FileConfiguration config) {
spyVolume = getValidFloat(config.getDouble("sounds.spy.volume", 0.5));
}

private void loadWebhook(FileConfiguration config) {
webhookBody = config.getString("webhook.json-body", null);
String uri = config.getString("webhook.url", null);
if (uri == null || uri.isBlank()) {
logger.warning(LocaleMessage.LOG_ERROR_WEBHOOK_URL_BLANK.getMessage());
webhookEnabled = false;
return;
}
try {
webhookUri = URI.create(uri);
}
catch (IllegalArgumentException e) {
logger.log(Level.WARNING, LocaleMessage.LOG_ERROR_WEBHOOK_URL_MALFORMED.getMessage(), e);
webhookEnabled = false;
return;
}
if (webhookEnabled) DiscordWebHook.createClient();
}

private NamespacedKey getValidSound(String soundString, NamespacedKey defaultSound) {
NamespacedKey key = NamespacedKey.fromString(soundString);
if (key == null || Registry.SOUNDS.get(key) == null) {
Expand Down Expand Up @@ -219,4 +244,10 @@ public float getSpyPitch() {
public float getSpyVolume() {
return spyVolume;
}

public boolean isWebhookEnabled() { return webhookEnabled; }

public URI getWebhookUri() { return webhookUri; }

public String getWebhookBody() { return webhookBody; }
}
5 changes: 4 additions & 1 deletion src/main/java/simplexity/simplepms/config/LocaleMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ public enum LocaleMessage {
"https://jd.papermc.io/paper/1.21.5/io/papermc/paper/registry/keys/SoundEventKeys.html"),
LOG_ERROR_USING_DEFAULT_SOUND("console-error.using-default-sound", "Using %default-sound% until a valid sound is provided"),
LOG_ERROR_FLOAT_OUT_OF_RANGE("console-error.float-out-of-range", "The number %number% is out of range! Volume and pitch values must be a number between 0 and 2!"),
LOG_ERROR_USING_DEFAULT_FLOAT("console-error.using-default-float", "Setting to 1.0 until a valid value is provided");
LOG_ERROR_USING_DEFAULT_FLOAT("console-error.using-default-float", "Setting to 1.0 until a valid value is provided"),
LOG_ERROR_WEBHOOK_URL_BLANK("console-error.webhook.url.blank", "Webhook URL cannot be null or blank. Disabling webhooks."),
LOG_ERROR_WEBHOOK_URL_MALFORMED("console-error.webhook.url.malformed", "Webhook URL is malformed and does not meet expected standards. Disabling webhooks."),
LOG_ERROR_WEBHOOK_CLIENT_NOT_CREATED("console-error.webhook.client-not-created", "HTTP Client was not created, this should be impossible. Let Simplexity what happened.");
Comment thread
Peashooter101 marked this conversation as resolved.
Outdated


private final String path;
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/simplexity/simplepms/hooks/DiscordWebHook.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package simplexity.simplepms.hooks;

import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import simplexity.simplepms.SimplePMs;
import simplexity.simplepms.config.ConfigHandler;
import simplexity.simplepms.config.LocaleMessage;
import simplexity.simplepms.logic.MessageUtils;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;

public class DiscordWebHook {

public static HttpClient client;

public static void sendWebHook(CommandSender sender, CommandSender recipient, String message) {

if (client == null) {
SimplePMs.getInstance().getLogger().log(Level.WARNING, LocaleMessage.LOG_ERROR_WEBHOOK_CLIENT_NOT_CREATED.getMessage());
createClient();
}

String content = MessageUtils.getInstance().format(
ConfigHandler.getInstance().getWebhookBody(),
Map.of(
"sender", sender.getName(),
"sender_display_name", (sender instanceof Player player) ? PlainTextComponentSerializer.plainText().serialize(player.displayName()) : sender.getName(),
"sender_uuid", (sender instanceof Player player) ? player.getUniqueId().toString() : "",
"recipient", recipient.getName(),
"recipient_display_name", (recipient instanceof Player player) ? PlainTextComponentSerializer.plainText().serialize(player.displayName()) : recipient.getName(),
"recipient_uuid", (recipient instanceof Player player) ? player.getUniqueId().toString() : "",
"message", message,
"timestamp", Long.toString(System.currentTimeMillis()/1000)
)
);

try {
HttpRequest request = HttpRequest.newBuilder()
.uri(ConfigHandler.getInstance().getWebhookUri())
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(content))
.build();

CompletableFuture<HttpResponse<String>> asyncResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
asyncResponse.thenAccept(response -> {
if (response.statusCode() < 200 || response.statusCode() >= 300) {
//noinspection StringTemplateMigration: String Template is considered preview and may be removed in a future release.
SimplePMs.getInstance().getLogger().log(Level.WARNING, "Webhook has failed to send, HTTP Status " + response.statusCode() + " with JSON Body:\n" + response.body());
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}

public static void createClient() {
removeClient();
client = HttpClient.newHttpClient();
}

public static void removeClient() {
if (client == null) return;
client.close();
client = null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package simplexity.simplepms.listeners;

import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import simplexity.simplepms.config.ConfigHandler;
import simplexity.simplepms.events.PrivateMessageEvent;
import simplexity.simplepms.hooks.DiscordWebHook;

public class PrivateMessageListener implements Listener {

@EventHandler(priority = EventPriority.MONITOR)
public void onPrivateMessage(PrivateMessageEvent event) {
if (!ConfigHandler.getInstance().isWebhookEnabled()) return;
DiscordWebHook.sendWebHook(event.getInitiator(), event.getRecipient(), event.getMessageContent());
}

}
25 changes: 25 additions & 0 deletions src/main/java/simplexity/simplepms/logic/MessageUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@
import simplexity.simplepms.config.ConfigHandler;
import simplexity.simplepms.config.LocaleMessage;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MessageUtils {
private static MessageUtils instance;
private final MiniMessage miniMessage = SimplePMs.getMiniMessage();
private final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{([a-zA-Z0-9_]+)}");

private MessageUtils() {
}
Expand Down Expand Up @@ -87,4 +92,24 @@ public TagResolver papiTag(final Player player) {
});
}

public String format(String message, Map<String, String> values) {
Matcher matcher = PLACEHOLDER_PATTERN.matcher(message);
StringBuilder result = new StringBuilder();

int lastEnd = 0;
while (matcher.find()) {
result.append(message, lastEnd, matcher.start());

String key = matcher.group(1);
String value = values.get(key);

if (value != null) result.append(value);
else result.append(matcher.group());
lastEnd = matcher.end();
}
result.append(message, lastEnd, message.length());

return result.toString();
}

}
23 changes: 23 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,26 @@ sounds:
sound: minecraft:entity.item_frame.rotate_item
pitch: 1.8
volume: 0.5
###
# This adds Webhook Support focused for Discord
###
webhook:
enabled: false
url: ""
# This is the JSON Body to send to the webhook.
# The default value is modeled after https://docs.discord.com/developers/resources/webhook#execute-webhook
# These are the placeholders that can be used:
# <sender>: Sender's Username
# <sender_display_name>: Sender's Display Name (Nickname), Non-players will have the same name as <sender>
# <sender_uuid>: Sender's UUID, formatted as xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, this is blank for non-players.
# <recipient>: Recipient's Username
# <recipient_display_name>: Recipient's Display Name (Nickname), Non-players will have the same name as <recipient>
# <recipient_uuid>: Recipient's UUID, formatted as xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, this is blank for non-players.
# <message>: The message sent through SimplePMs.
# <timestamp>: Unix Timestamp (https://www.unixtimestamp.com/)
json-body: |
{
"content": "{message}\n-# {sender_display_name} ({sender}) sent {recipient_display_name} ({recipient}) this on <t:{timestamp}>",
"avatar_url": "https://mc-heads.net/avatar/{sender_uuid}",
"username": "{sender} > {recipient}"
}