兼容1.20.3

Fixes #202
This commit is contained in:
Xujiayao 2023-12-06 23:56:00 +08:00
parent 1ba18ce63f
commit 96e98e11e4
14 changed files with 410 additions and 42 deletions

View file

@ -11,6 +11,7 @@ preprocess {
def mc1194 = createNode("1.19.4", 1_19_04, "yarn")
def mc1201 = createNode("1.20.1", 1_20_01, "yarn")
def mc1202 = createNode("1.20.2", 1_20_02, "yarn")
def mc1203 = createNode("1.20.3", 1_20_03, "yarn")
mc1152.link(mc1165, null)
mc1165.link(mc1171, null)
@ -18,4 +19,5 @@ preprocess {
mc1182.link(mc1194, null)
mc1194.link(mc1201, null)
mc1201.link(mc1202, null)
mc1202.link(mc1203, null)
}

View file

@ -9,7 +9,7 @@ archives_base_name=MC-Discord-Chat
# Wrapper Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.20.2
yarn_mappings=1.20.2+build.4
minecraft_version=1.20.3
yarn_mappings=1.20.3+build.1
loader_version=0.15.0
fabric_version=0.91.1+1.20.2
fabric_version=0.91.1+1.20.3

View file

@ -24,7 +24,8 @@ def versions = Arrays.asList(
"1.18.2",
"1.19.4",
"1.20.1",
"1.20.2"
"1.20.2",
"1.20.3"
)
for (String version : versions) {
include(":$version")

View file

@ -95,7 +95,7 @@ public class DiscordEventListener extends ListenerAdapter {
.replace("%command%", e.getCommandString())));
if (CONFIG.generic.broadcastSlashCommandExecution) {
Text commandNoticeText = Text.Serializer.fromJson(Translations.translateMessage("message.formattedCommandNotice")
Text commandNoticeText = Text.Serialization.fromJson(Translations.translateMessage("message.formattedCommandNotice")
.replace("%name%", (CONFIG.generic.useServerNickname ? e.getMember().getEffectiveName() : e.getMember().getUser().getName()).replace("\\", "\\\\").replace("\"", "\\\""))
.replace("%roleName%", roleName)
.replace("%roleColor%", "#" + Integer.toHexString(e.getMember().getColorRaw()))
@ -110,7 +110,7 @@ public class DiscordEventListener extends ListenerAdapter {
//$$ .append(commandNoticeText), false));
//#else
List<Text> commandNoticeTextList = new ArrayList<>();
commandNoticeTextList.add(Text.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage")
commandNoticeTextList.add(Text.Serialization.fromJson(Translations.translateMessage("message.formattedOtherMessage")
.replace("%server%", (CONFIG.multiServer.enable ? CONFIG.multiServer.name : "Discord"))
.replace("%message%", "")));
commandNoticeTextList.add(commandNoticeText);
@ -120,7 +120,7 @@ public class DiscordEventListener extends ListenerAdapter {
//#endif
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, false, true, null, Text.Serializer.toJson(commandNoticeText));
MULTI_SERVER.sendMessage(false, false, true, null, Text.Serialization.toJsonString(commandNoticeText));
}
}
@ -552,7 +552,7 @@ public class DiscordEventListener extends ListenerAdapter {
if (CONFIG.generic.broadcastChatMessages) {
if (e.getMessage().getReferencedMessage() != null) {
String s = Translations.translateMessage("message.formattedResponseMessage");
Text referenceFinalText = Text.Serializer.fromJson(s
Text referenceFinalText = Text.Serialization.fromJson(s
.replace("%message%", (CONFIG.generic.formatChatMessages ? finalReferencedMessage : EmojiParser.parseToAliases(referencedMessageTemp).replace("\"", "\\\""))
.replace("\n", "\n" + textAfterPlaceholder[0] + "}," + s.substring(1, s.indexOf("%message%"))))
.replace("%server%", "Discord")
@ -565,7 +565,7 @@ public class DiscordEventListener extends ListenerAdapter {
}
String s = Translations.translateMessage("message.formattedChatMessage");
Text finalText = Text.Serializer.fromJson(s
Text finalText = Text.Serialization.fromJson(s
.replace("%message%", (CONFIG.generic.formatChatMessages ? finalMessage : EmojiParser.parseToAliases(messageTemp).replace("\"", "\\\""))
.replace("\n", "\n" + textAfterPlaceholder[1] + "}," + s.substring(1, s.indexOf("%message%"))))
.replace("%server%", "Discord")

View file

@ -48,7 +48,11 @@ public abstract class MixinPlayerAdvancementTracker {
String description = Translations.translate("advancements." + advancement.id().getPath().replace("/", ".") + ".description");
message = message
.replace("%playerName%", MarkdownSanitizer.escape(owner.getEntityName()))
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(owner.getNameForScoreboard()))
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(owner.getEntityName()))
//#endif
.replace("%advancement%", title.contains("TranslateError") ? advancement.value().display().get().getTitle().getString() : title)
.replace("%description%", description.contains("TranslateError") ? advancement.value().display().get().getDescription().getString() : description);

View file

@ -98,10 +98,18 @@ public class MixinPlayerManager {
if (CONFIG.generic.announcePlayerJoinLeave) {
CHANNEL.sendMessage(Translations.translateMessage("message.joinServer")
.replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName()))).queue();
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(player.getNameForScoreboard()))).queue();
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName()))).queue();
//#endif
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.joinServer")
.replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName())));
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(player.getNameForScoreboard())));
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName())));
//#endif
}
}
}
@ -112,10 +120,18 @@ public class MixinPlayerManager {
if (CONFIG.generic.announcePlayerJoinLeave) {
CHANNEL.sendMessage(Translations.translateMessage("message.leftServer")
.replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName()))).queue();
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(player.getNameForScoreboard()))).queue();
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName()))).queue();
//#endif
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.leftServer")
.replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName())));
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(player.getNameForScoreboard())));
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(player.getEntityName())));
//#endif
}
}
}

View file

@ -40,7 +40,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import top.xujiayao.mcdiscordchat.utils.MarkdownParser;
import top.xujiayao.mcdiscordchat.utils.Translations;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -81,7 +80,7 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
public abstract CompletableFuture<FilteredMessage> filterText(String text);
@Shadow
public abstract Optional<LastSeenMessageList> validateMessage(String message, Instant timestamp, LastSeenMessageList.Acknowledgment acknowledgment);
public abstract Optional<LastSeenMessageList> validateMessage(LastSeenMessageList.Acknowledgment acknowledgment);
@Shadow
public abstract void handleCommandExecution(CommandExecutionC2SPacket packet, LastSeenMessageList lastSeenMessages);
@ -100,7 +99,7 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
if (hasIllegalCharacter(packet.chatMessage())) {
disconnect(Text.translatable("multiplayer.disconnect.illegal_characters"));
} else {
Optional<LastSeenMessageList> optional = validateMessage(packet.chatMessage(), packet.timestamp(), packet.acknowledgment());
Optional<LastSeenMessageList> optional = validateMessage(packet.acknowledgment());
if (optional.isPresent()) {
String contentToDiscord = packet.chatMessage();
String contentToMinecraft = packet.chatMessage();
@ -182,7 +181,7 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
if (CONFIG.generic.formatChatMessages) {
try {
SignedMessage signedMessage = getSignedMessage(packet, optional.get());
server.getPlayerManager().broadcast(signedMessage.withUnsignedContent(Objects.requireNonNull(Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]"))), player, MessageType.params(MessageType.CHAT, player));
server.getPlayerManager().broadcast(signedMessage.withUnsignedContent(Objects.requireNonNull(Text.Serialization.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]"))), player, MessageType.params(MessageType.CHAT, player));
} catch (MessageChain.MessageChainException e) {
handleMessageChainException(e);
}
@ -198,17 +197,17 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
CompletableFuture<FilteredMessage> completableFuture = filterText(signedMessage.getSignedContent());
Text text = server.getMessageDecorator().decorate(player, signedMessage.getContent());
messageChainTaskQueue.append((executor) -> completableFuture.thenAcceptAsync((filteredMessage) -> {
SignedMessage signedMessage2 = signedMessage.withUnsignedContent(text).withFilterMask(filteredMessage.mask());
messageChainTaskQueue.append(completableFuture, (filtered) -> {
SignedMessage signedMessage2 = signedMessage.withUnsignedContent(text).withFilterMask(filtered.mask());
handleDecoratedMessage(signedMessage2);
}, executor));
});
});
}
if (CONFIG.generic.broadcastChatMessages) {
sendMessage(contentToDiscord, false);
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, true, false, player.getEntityName(), CONFIG.generic.formatChatMessages ? contentToMinecraft : packet.chatMessage());
MULTI_SERVER.sendMessage(false, true, false, player.getNameForScoreboard(), CONFIG.generic.formatChatMessages ? contentToMinecraft : packet.chatMessage());
}
}
}
@ -223,7 +222,7 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
if (hasIllegalCharacter(packet.command())) {
disconnect(Text.translatable("multiplayer.disconnect.illegal_characters"));
} else {
Optional<LastSeenMessageList> optional = validateMessage(packet.command(), packet.timestamp(), packet.acknowledgment());
Optional<LastSeenMessageList> optional = validateMessage(packet.acknowledgment());
if (optional.isPresent()) {
server.submit(() -> {
handleCommandExecution(packet, optional.get());
@ -246,7 +245,7 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
MINECRAFT_SEND_COUNT++;
if (MINECRAFT_SEND_COUNT <= 20) {
Text text = Text.of("<" + player.getEntityName() + "> " + input);
Text text = Text.of("<" + player.getNameForScoreboard() + "> " + input);
server.getPlayerManager().getPlayerList().forEach(
player -> player.sendMessage(text, false));
@ -255,7 +254,7 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
sendMessage(input, true);
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, true, false, player.getEntityName(), MarkdownSanitizer.escape(input));
MULTI_SERVER.sendMessage(false, true, false, player.getNameForScoreboard(), MarkdownSanitizer.escape(input));
}
}
}
@ -272,18 +271,18 @@ public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkH
if (CONFIG.multiServer.enable) {
CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhookForMultiServer")
.replace("%server%", CONFIG.multiServer.name)
.replace("%name%", player.getEntityName())
.replace("%name%", player.getNameForScoreboard())
.replace("%message%", content)).queue();
} else {
CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook")
.replace("%name%", player.getEntityName())
.replace("%name%", player.getNameForScoreboard())
.replace("%message%", content)).queue();
}
} else {
JsonObject body = new JsonObject();
body.addProperty("content", content);
body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getEntityName()) : player.getEntityName()));
body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getEntityName())));
body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getNameForScoreboard()) : player.getNameForScoreboard()));
body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getNameForScoreboard())));
JsonObject allowedMentions = new JsonObject();
allowedMentions.add("parse", new Gson().toJsonTree(CONFIG.generic.allowedMentions).getAsJsonArray());

View file

@ -65,11 +65,19 @@ public abstract class MixinServerPlayerEntity extends PlayerEntity {
CHANNEL.sendMessage(Translations.translateMessage("message.deathMessage")
.replace("%deathMessage%", MarkdownSanitizer.escape(Translations.translate(key, args)))
.replace("%playerName%", MarkdownSanitizer.escape(this.getEntityName()))).queue();
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(this.getNameForScoreboard()))).queue();
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(this.getEntityName()))).queue();
//#endif
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.deathMessage")
.replace("%deathMessage%", MarkdownSanitizer.escape(Translations.translate(key, args)))
.replace("%playerName%", MarkdownSanitizer.escape(this.getEntityName())));
//#if MC >= 12003
.replace("%playerName%", MarkdownSanitizer.escape(this.getNameForScoreboard())));
//#else
//$$ .replace("%playerName%", MarkdownSanitizer.escape(this.getEntityName())));
//#endif
}
}
}

View file

@ -98,7 +98,7 @@ public class ReadThread extends Thread {
.replace("%name%", json.get("playerName").getAsString())
.replace("%message%", json.get("message").getAsString()));
Text text = Text.Serializer.fromJson(Translations.translateMessage("message.formattedChatMessage")
Text text = Text.Serialization.fromJson(Translations.translateMessage("message.formattedChatMessage")
.replace("%server%", json.get("serverName").getAsString())
.replace("%name%", json.get("playerName").getAsString())
.replace("%roleColor%", "white")
@ -110,9 +110,9 @@ public class ReadThread extends Thread {
if (json.get("isText").getAsBoolean()) {
LOGGER.info(Translations.translateMessage("message.unformattedOtherMessage")
.replace("%server%", json.get("serverName").getAsString())
.replace("%message%", Objects.requireNonNull(Text.Serializer.fromJson(json.get("message").getAsString())).getString()));
.replace("%message%", Objects.requireNonNull(Text.Serialization.fromJson(json.get("message").getAsString())).getString()));
Text text = Text.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage")
Text text = Text.Serialization.fromJson(Translations.translateMessage("message.formattedOtherMessage")
.replace("%server%", json.get("serverName").getAsString())
.replace("%message%", ""));
@ -124,7 +124,7 @@ public class ReadThread extends Thread {
//#else
List<Text> textList = new ArrayList<>();
textList.add(text);
textList.add(Text.Serializer.fromJson(json.get("message").getAsString()));
textList.add(Text.Serialization.fromJson(json.get("message").getAsString()));
SERVER.getPlayerManager().getPlayerList().forEach(
player -> player.sendMessage(Texts.join(textList, Text.of("")), false));
@ -134,7 +134,7 @@ public class ReadThread extends Thread {
.replace("%server%", json.get("serverName").getAsString())
.replace("%message%", json.get("message").getAsString()));
Text text = Text.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage")
Text text = Text.Serialization.fromJson(Translations.translateMessage("message.formattedOtherMessage")
.replace("%server%", json.get("serverName").getAsString())
.replace("%message%", MarkdownParser.parseMarkdown(json.get("message").getAsString())));

View file

@ -402,8 +402,10 @@ public class Utils {
message.append(Translations.translate("utils.utils.gicMessage.noPlayersOnline"));
} else {
for (ServerPlayerEntity player : onlinePlayers) {
//#if MC >= 12002
message.append("[").append(player.networkHandler.getLatency()).append("ms] ").append(player.getEntityName()).append("\n");
//#if MC >= 12003
message.append("[").append(player.networkHandler.getLatency()).append("ms] ").append(player.getNameForScoreboard()).append("\n");
//#elseif MC >= 12002
//$$ message.append("[").append(player.networkHandler.getLatency()).append("ms] ").append(player.getEntityName()).append("\n");
//#else
//$$ message.append("[").append(player.pingMilliseconds).append("ms] ").append(player.getEntityName()).append("\n");
//#endif
@ -411,7 +413,11 @@ public class Utils {
}
// Server TPS
double serverTickTime = average(SERVER.lastTickLengths) * 1.0E-6D;
//#if MC >= 12003
double serverTickTime = average(SERVER.getTickTimes()) * 1.0E-6D;
//#else
//$$ double serverTickTime = average(SERVER.lastTickLengths) * 1.0E-6D;
//#endif
message.append(Translations.translate("utils.utils.gicMessage.serverTps", String.format("%.2f", Math.min(1000.0 / serverTickTime, 20))));
// Server MSPT
@ -520,7 +526,11 @@ public class Utils {
MSPT_MONITOR_TIMER.schedule(new TimerTask() {
@Override
public void run() {
double mspt = average(SERVER.lastTickLengths) * 1.0E-6D;
//#if MC >= 12003
double mspt = average(SERVER.getTickTimes()) * 1.0E-6D;
//#else
//$$ double mspt = average(SERVER.lastTickLengths) * 1.0E-6D;
//#endif
if (mspt > CONFIG.generic.msptLimit) {
String message = Translations.translateMessage("message.highMspt")

View file

@ -5,7 +5,7 @@ yarn_mappings=1.20.2+build.4
loader_version=0.15.0
# Fabric Mod Metadata
minecraft_dependency=~1.20.2
minecraft_dependency=1.20.2
# Dependencies
fabric_version=0.91.1+1.20.2

View file

@ -0,0 +1,317 @@
//#if MC >= 12002
package top.xujiayao.mcdiscordchat.minecraft.mixins;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.vdurmont.emoji.EmojiManager;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji;
import net.dv8tion.jda.api.utils.MarkdownSanitizer;
import net.minecraft.SharedConstants;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.message.LastSeenMessageList;
import net.minecraft.network.message.MessageChain;
import net.minecraft.network.message.MessageChainTaskQueue;
import net.minecraft.network.message.MessageType;
import net.minecraft.network.message.SignedMessage;
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.filter.FilteredMessage;
import net.minecraft.server.network.ConnectedClientData;
import net.minecraft.server.network.ServerCommonNetworkHandler;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import top.xujiayao.mcdiscordchat.utils.MarkdownParser;
import top.xujiayao.mcdiscordchat.utils.Translations;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static top.xujiayao.mcdiscordchat.Main.CHANNEL;
import static top.xujiayao.mcdiscordchat.Main.CONFIG;
import static top.xujiayao.mcdiscordchat.Main.HTTP_CLIENT;
import static top.xujiayao.mcdiscordchat.Main.JDA;
import static top.xujiayao.mcdiscordchat.Main.LOGGER;
import static top.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME;
import static top.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT;
import static top.xujiayao.mcdiscordchat.Main.MULTI_SERVER;
import static top.xujiayao.mcdiscordchat.Main.SERVER;
import static top.xujiayao.mcdiscordchat.Main.WEBHOOK;
/**
* @author Xujiayao
*/
@Mixin(ServerPlayNetworkHandler.class)
public abstract class MixinServerPlayNetworkHandler extends ServerCommonNetworkHandler {
@Shadow
private ServerPlayerEntity player;
@Final
@Shadow
private MessageChainTaskQueue messageChainTaskQueue;
protected MixinServerPlayNetworkHandler(MinecraftServer server, ClientConnection connection, ConnectedClientData clientData) {
super(server, connection, clientData);
}
@Shadow
public abstract void checkForSpam();
@Shadow
public abstract CompletableFuture<FilteredMessage> filterText(String text);
@Shadow
public abstract Optional<LastSeenMessageList> validateMessage(String message, Instant timestamp, LastSeenMessageList.Acknowledgment acknowledgment);
@Shadow
public abstract void handleCommandExecution(CommandExecutionC2SPacket packet, LastSeenMessageList lastSeenMessages);
@Shadow
public abstract SignedMessage getSignedMessage(ChatMessageC2SPacket packet, LastSeenMessageList lastSeenMessages) throws MessageChain.MessageChainException;
@Shadow
public abstract void handleDecoratedMessage(SignedMessage message);
@Shadow
public abstract void handleMessageChainException(MessageChain.MessageChainException exception);
@Inject(method = "onChatMessage", at = @At("HEAD"), cancellable = true)
private void onChatMessage(ChatMessageC2SPacket packet, CallbackInfo ci) {
if (hasIllegalCharacter(packet.chatMessage())) {
disconnect(Text.translatable("multiplayer.disconnect.illegal_characters"));
} else {
Optional<LastSeenMessageList> optional = validateMessage(packet.chatMessage(), packet.timestamp(), packet.acknowledgment());
if (optional.isPresent()) {
String contentToDiscord = packet.chatMessage();
String contentToMinecraft = packet.chatMessage();
if (StringUtils.countMatches(contentToDiscord, ":") >= 2) {
String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":");
for (String emojiName : emojiNames) {
List<RichCustomEmoji> emojis = JDA.getEmojisByName(emojiName, true);
if (!emojis.isEmpty()) {
contentToDiscord = StringUtils.replaceIgnoreCase(contentToDiscord, (":" + emojiName + ":"), emojis.get(0).getAsMention());
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, (":" + emojiName + ":"), (Formatting.YELLOW + ":" + emojiName + ":" + Formatting.RESET));
} else if (EmojiManager.getForAlias(emojiName) != null) {
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, (":" + emojiName + ":"), (Formatting.YELLOW + ":" + emojiName + ":" + Formatting.RESET));
}
}
}
if (!CONFIG.generic.allowedMentions.isEmpty() && contentToDiscord.contains("@")) {
if (CONFIG.generic.allowedMentions.contains("users")) {
for (Member member : CHANNEL.getMembers()) {
String usernameMention = "@" + member.getUser().getName();
String displayNameMention = "@" + member.getUser().getEffectiveName();
String formattedMention = Formatting.YELLOW + "@" + member.getEffectiveName() + Formatting.RESET;
contentToDiscord = StringUtils.replaceIgnoreCase(contentToDiscord, usernameMention, member.getAsMention());
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, usernameMention, MarkdownSanitizer.escape(formattedMention));
contentToDiscord = StringUtils.replaceIgnoreCase(contentToDiscord, displayNameMention, member.getAsMention());
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, displayNameMention, MarkdownSanitizer.escape(formattedMention));
if (member.getNickname() != null) {
String nicknameMention = "@" + member.getNickname();
contentToDiscord = StringUtils.replaceIgnoreCase(contentToDiscord, nicknameMention, member.getAsMention());
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, nicknameMention, MarkdownSanitizer.escape(formattedMention));
}
}
}
if (CONFIG.generic.allowedMentions.contains("roles")) {
for (Role role : CHANNEL.getGuild().getRoles()) {
String roleMention = "@" + role.getName();
String formattedMention = Formatting.YELLOW + "@" + role.getName() + Formatting.RESET;
contentToDiscord = StringUtils.replaceIgnoreCase(contentToDiscord, roleMention, role.getAsMention());
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, roleMention, MarkdownSanitizer.escape(formattedMention));
}
}
if (CONFIG.generic.allowedMentions.contains("everyone")) {
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, "@everyone", Formatting.YELLOW + "@everyone" + Formatting.RESET);
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, "@here", Formatting.YELLOW + "@here" + Formatting.RESET);
}
}
contentToMinecraft = MarkdownParser.parseMarkdown(contentToMinecraft.replace("\\", "\\\\"));
for (String protocol : new String[]{"http://", "https://"}) {
if (contentToMinecraft.contains(protocol)) {
String[] links = StringUtils.substringsBetween(contentToMinecraft, protocol, " ");
if (!StringUtils.substringAfterLast(contentToMinecraft, protocol).contains(" ")) {
links = ArrayUtils.add(links, StringUtils.substringAfterLast(contentToMinecraft, protocol));
}
for (String link : links) {
if (link.contains("\n")) {
link = StringUtils.substringBefore(link, "\n");
}
String hyperlinkInsert;
if (StringUtils.containsIgnoreCase(link, "gif")
&& StringUtils.containsIgnoreCase(link, "tenor.com")) {
hyperlinkInsert = "\"},{\"text\":\"<gif>\",\"underlined\":true,\"color\":\"yellow\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + protocol + link + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[{\"text\":\"Open URL\"}]}},{\"text\":\"";
} else {
hyperlinkInsert = "\"},{\"text\":\"" + protocol + link + "\",\"underlined\":true,\"color\":\"yellow\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + protocol + link + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"contents\":[{\"text\":\"Open URL\"}]}},{\"text\":\"";
}
contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, (protocol + link), hyperlinkInsert);
}
}
}
if (CONFIG.generic.formatChatMessages) {
try {
SignedMessage signedMessage = getSignedMessage(packet, optional.get());
server.getPlayerManager().broadcast(signedMessage.withUnsignedContent(Objects.requireNonNull(Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]"))), player, MessageType.params(MessageType.CHAT, player));
} catch (MessageChain.MessageChainException e) {
handleMessageChainException(e);
}
} else {
server.submit(() -> {
SignedMessage signedMessage;
try {
signedMessage = getSignedMessage(packet, optional.get());
} catch (MessageChain.MessageChainException var6) {
handleMessageChainException(var6);
return;
}
CompletableFuture<FilteredMessage> completableFuture = filterText(signedMessage.getSignedContent());
Text text = server.getMessageDecorator().decorate(player, signedMessage.getContent());
messageChainTaskQueue.append((executor) -> completableFuture.thenAcceptAsync((filteredMessage) -> {
SignedMessage signedMessage2 = signedMessage.withUnsignedContent(text).withFilterMask(filteredMessage.mask());
handleDecoratedMessage(signedMessage2);
}, executor));
});
}
if (CONFIG.generic.broadcastChatMessages) {
sendMessage(contentToDiscord, false);
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, true, false, player.getEntityName(), CONFIG.generic.formatChatMessages ? contentToMinecraft : packet.chatMessage());
}
}
}
}
ci.cancel();
}
@Inject(method = "onCommandExecution", at = @At(value = "HEAD"), cancellable = true)
private void onCommandExecution(CommandExecutionC2SPacket packet, CallbackInfo ci) {
if (CONFIG.generic.broadcastPlayerCommandExecution) {
if (hasIllegalCharacter(packet.command())) {
disconnect(Text.translatable("multiplayer.disconnect.illegal_characters"));
} else {
Optional<LastSeenMessageList> optional = validateMessage(packet.command(), packet.timestamp(), packet.acknowledgment());
if (optional.isPresent()) {
server.submit(() -> {
handleCommandExecution(packet, optional.get());
checkForSpam();
});
String input = "/" + packet.command();
for (String command : CONFIG.generic.excludedCommands) {
if (input.startsWith(command + " ")) {
ci.cancel();
return;
}
}
if ((System.currentTimeMillis() - MINECRAFT_LAST_RESET_TIME) > 20000) {
MINECRAFT_SEND_COUNT = 0;
MINECRAFT_LAST_RESET_TIME = System.currentTimeMillis();
}
MINECRAFT_SEND_COUNT++;
if (MINECRAFT_SEND_COUNT <= 20) {
Text text = Text.of("<" + player.getEntityName() + "> " + input);
server.getPlayerManager().getPlayerList().forEach(
player -> player.sendMessage(text, false));
SERVER.sendMessage(text);
sendMessage(input, true);
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, true, false, player.getEntityName(), MarkdownSanitizer.escape(input));
}
}
}
}
ci.cancel();
}
}
private void sendMessage(String message, boolean escapeMarkdown) {
String content = (escapeMarkdown ? MarkdownSanitizer.escape(message) : message);
if (!CONFIG.generic.useWebhook) {
if (CONFIG.multiServer.enable) {
CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhookForMultiServer")
.replace("%server%", CONFIG.multiServer.name)
.replace("%name%", player.getEntityName())
.replace("%message%", content)).queue();
} else {
CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook")
.replace("%name%", player.getEntityName())
.replace("%message%", content)).queue();
}
} else {
JsonObject body = new JsonObject();
body.addProperty("content", content);
body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getEntityName()) : player.getEntityName()));
body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getEntityName())));
JsonObject allowedMentions = new JsonObject();
allowedMentions.add("parse", new Gson().toJsonTree(CONFIG.generic.allowedMentions).getAsJsonArray());
body.add("allowed_mentions", allowedMentions);
Request request = new Request.Builder()
.url(WEBHOOK.getUrl())
.post(RequestBody.create(body.toString(), MediaType.get("application/json")))
.build();
try {
Response response = HTTP_CLIENT.newCall(request).execute();
response.close();
} catch (Exception e) {
LOGGER.error(ExceptionUtils.getStackTrace(e));
}
}
}
private boolean hasIllegalCharacter(String message) {
for (int i = 0; i < message.length(); ++i) {
if (!SharedConstants.isValidChar(message.charAt(i))) {
return true;
}
}
return false;
}
}
//#endif

View file

@ -0,0 +1,11 @@
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.20.3
yarn_mappings=1.20.3+build.1
loader_version=0.15.0
# Fabric Mod Metadata
minecraft_dependency=~1.20.3
# Dependencies
fabric_version=0.91.1+1.20.3

View file

@ -1 +1 @@
1.20.2
1.20.3