mirror of
https://github.com/System-End/Discord-MC-Chat.git
synced 2026-04-19 22:05:11 +00:00
parent
1ba18ce63f
commit
96e98e11e4
14 changed files with 410 additions and 42 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())));
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
11
versions/1.20.3/gradle.properties
Normal file
11
versions/1.20.3/gradle.properties
Normal 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
|
||||
|
|
@ -1 +1 @@
|
|||
1.20.2
|
||||
1.20.3
|
||||
Loading…
Add table
Reference in a new issue