From 2df617c51f7dbf96ba59703ad8c08ad6a7ec20fa Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 13:53:01 +0800 Subject: [PATCH 01/36] =?UTF-8?q?=E5=BC=80=E5=A7=8B=E7=A7=BB=E6=A4=8D?= =?UTF-8?q?=E5=88=B0Mojang=20Mappings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 22 +++++++++++----------- common.gradle | 2 +- gradle.properties | 1 - versions/1.19.2/gradle.properties | 1 - versions/1.19.3/gradle.properties | 1 - versions/1.19.4/gradle.properties | 1 - versions/1.20.1/gradle.properties | 1 - versions/1.20.2/gradle.properties | 1 - versions/1.20.4/gradle.properties | 1 - versions/compat_1.15.2/gradle.properties | 1 - versions/compat_1.16.5/gradle.properties | 1 - versions/compat_1.17.1/gradle.properties | 1 - versions/compat_1.18.2/gradle.properties | 1 - versions/compat_1.19/gradle.properties | 1 - wrapper/active/build.gradle | 2 +- wrapper/compat/build.gradle | 2 +- 16 files changed, 14 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index 1c7064c7..4773f4f9 100644 --- a/build.gradle +++ b/build.gradle @@ -4,17 +4,17 @@ plugins { } preprocess { - def mc1152 = createNode("compat_1.15.2", 1_15_02, "yarn") - def mc1165 = createNode("compat_1.16.5", 1_16_05, "yarn") - def mc1171 = createNode("compat_1.17.1", 1_17_01, "yarn") - def mc1182 = createNode("compat_1.18.2", 1_18_02, "yarn") - def mc1190 = createNode("compat_1.19" , 1_19_00, "yarn") - def mc1192 = createNode("1.19.2", 1_19_02, "yarn") - def mc1193 = createNode("1.19.3", 1_19_03, "yarn") - 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 mc1204 = createNode("1.20.4", 1_20_04, "yarn") + def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") + def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") + def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") + def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") + def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") + def mc1192 = createNode("1.19.2", 1_19_02, "mojang") + def mc1193 = createNode("1.19.3", 1_19_03, "mojang") + def mc1194 = createNode("1.19.4", 1_19_04, "mojang") + def mc1201 = createNode("1.20.1", 1_20_01, "mojang") + def mc1202 = createNode("1.20.2", 1_20_02, "mojang") + def mc1204 = createNode("1.20.4", 1_20_04, "mojang") mc1152.link(mc1165, null) mc1165.link(mc1171, null) diff --git a/common.gradle b/common.gradle index ad9a5ea9..575543e0 100644 --- a/common.gradle +++ b/common.gradle @@ -25,7 +25,7 @@ base { dependencies { minecraft("com.mojang:minecraft:${minecraft_version}") - mappings("net.fabricmc:yarn:${yarn_mappings}:v2") + mappings(loom.officialMojangMappings()) modImplementation("net.fabricmc:fabric-loader:${loader_version}") modApi("net.fabricmc.fabric-api:fabric-api:${fabric_version}") diff --git a/gradle.properties b/gradle.properties index bb25fa0e..7af6b4ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,6 @@ archives_base_name=MC-Discord-Chat # Wrapper Properties # check these on https://fabricmc.net/develop minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.3 loader_version=0.15.6 fabric_version=0.93.1+1.20.4 # cannot use 0.94.0 (loom & okio) \ No newline at end of file diff --git a/versions/1.19.2/gradle.properties b/versions/1.19.2/gradle.properties index 9167ad0e..14be25a4 100644 --- a/versions/1.19.2/gradle.properties +++ b/versions/1.19.2/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.19.2 -yarn_mappings=1.19.2+build.28 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/1.19.3/gradle.properties b/versions/1.19.3/gradle.properties index 0f2a76fd..eff6d95f 100644 --- a/versions/1.19.3/gradle.properties +++ b/versions/1.19.3/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.19.3 -yarn_mappings=1.19.3+build.5 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/1.19.4/gradle.properties b/versions/1.19.4/gradle.properties index b6324354..cddedc15 100644 --- a/versions/1.19.4/gradle.properties +++ b/versions/1.19.4/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.19.4 -yarn_mappings=1.19.4+build.2 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/1.20.1/gradle.properties b/versions/1.20.1/gradle.properties index e2e8ba46..d9557dd8 100644 --- a/versions/1.20.1/gradle.properties +++ b/versions/1.20.1/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.20.1 -yarn_mappings=1.20.1+build.10 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/1.20.2/gradle.properties b/versions/1.20.2/gradle.properties index 21c49e6c..57463135 100644 --- a/versions/1.20.2/gradle.properties +++ b/versions/1.20.2/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.20.2 -yarn_mappings=1.20.2+build.4 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/1.20.4/gradle.properties b/versions/1.20.4/gradle.properties index f89f7146..c957814c 100644 --- a/versions/1.20.4/gradle.properties +++ b/versions/1.20.4/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.3 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/compat_1.15.2/gradle.properties b/versions/compat_1.15.2/gradle.properties index f5cd0673..2b2c0e37 100644 --- a/versions/compat_1.15.2/gradle.properties +++ b/versions/compat_1.15.2/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.15.2 -yarn_mappings=1.15.2+build.17 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/compat_1.16.5/gradle.properties b/versions/compat_1.16.5/gradle.properties index 27655e72..4d3f8692 100644 --- a/versions/compat_1.16.5/gradle.properties +++ b/versions/compat_1.16.5/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.16.5 -yarn_mappings=1.16.5+build.10 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/compat_1.17.1/gradle.properties b/versions/compat_1.17.1/gradle.properties index 4ccee564..3b6f313b 100644 --- a/versions/compat_1.17.1/gradle.properties +++ b/versions/compat_1.17.1/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.17.1 -yarn_mappings=1.17.1+build.65 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/compat_1.18.2/gradle.properties b/versions/compat_1.18.2/gradle.properties index af8df06c..a6926e63 100644 --- a/versions/compat_1.18.2/gradle.properties +++ b/versions/compat_1.18.2/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.18.2 -yarn_mappings=1.18.2+build.4 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/versions/compat_1.19/gradle.properties b/versions/compat_1.19/gradle.properties index 3a05188c..05d36d36 100644 --- a/versions/compat_1.19/gradle.properties +++ b/versions/compat_1.19/gradle.properties @@ -1,7 +1,6 @@ # Fabric Properties # check these on https://fabricmc.net/develop minecraft_version=1.19 -yarn_mappings=1.19+build.4 loader_version=0.15.6 # Fabric Mod Metadata diff --git a/wrapper/active/build.gradle b/wrapper/active/build.gradle index 6f29c75b..35251e13 100644 --- a/wrapper/active/build.gradle +++ b/wrapper/active/build.gradle @@ -21,7 +21,7 @@ sourceSets { dependencies { minecraft("com.mojang:minecraft:${minecraft_version}") - mappings("net.fabricmc:yarn:${yarn_mappings}:v2") + mappings(loom.officialMojangMappings()) modImplementation("net.fabricmc:fabric-loader:${loader_version}") modApi("net.fabricmc.fabric-api:fabric-api:${fabric_version}") diff --git a/wrapper/compat/build.gradle b/wrapper/compat/build.gradle index d79f846a..6c6ad74a 100644 --- a/wrapper/compat/build.gradle +++ b/wrapper/compat/build.gradle @@ -21,7 +21,7 @@ sourceSets { dependencies { minecraft("com.mojang:minecraft:${minecraft_version}") - mappings("net.fabricmc:yarn:${yarn_mappings}:v2") + mappings(loom.officialMojangMappings()) modImplementation("net.fabricmc:fabric-loader:${loader_version}") modApi("net.fabricmc.fabric-api:fabric-api:${fabric_version}") From 92d32448deed202b7a7fb95e60019889cd2c380a Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 16:49:12 +0800 Subject: [PATCH 02/36] =?UTF-8?q?=E6=9A=82=E6=97=B6=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E5=85=B6=E5=AE=83MC=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 40 ++++++++++++++++++++-------------------- settings.gradle | 20 ++++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index 4773f4f9..c6241c22 100644 --- a/build.gradle +++ b/build.gradle @@ -4,26 +4,26 @@ plugins { } preprocess { - def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") - def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") - def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") - def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") - def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") - def mc1192 = createNode("1.19.2", 1_19_02, "mojang") - def mc1193 = createNode("1.19.3", 1_19_03, "mojang") - def mc1194 = createNode("1.19.4", 1_19_04, "mojang") - def mc1201 = createNode("1.20.1", 1_20_01, "mojang") - def mc1202 = createNode("1.20.2", 1_20_02, "mojang") +// def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") +// def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") +// def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") +// def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") +// def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") +// def mc1192 = createNode("1.19.2", 1_19_02, "mojang") +// def mc1193 = createNode("1.19.3", 1_19_03, "mojang") +// def mc1194 = createNode("1.19.4", 1_19_04, "mojang") +// def mc1201 = createNode("1.20.1", 1_20_01, "mojang") +// def mc1202 = createNode("1.20.2", 1_20_02, "mojang") def mc1204 = createNode("1.20.4", 1_20_04, "mojang") - mc1152.link(mc1165, null) - mc1165.link(mc1171, null) - mc1171.link(mc1182, null) - mc1182.link(mc1190, null) - mc1190.link(mc1192, null) - mc1192.link(mc1193, null) - mc1193.link(mc1194, null) - mc1194.link(mc1201, null) - mc1201.link(mc1202, null) - mc1202.link(mc1204, null) +// mc1152.link(mc1165, null) +// mc1165.link(mc1171, null) +// mc1171.link(mc1182, null) +// mc1182.link(mc1190, null) +// mc1190.link(mc1192, null) +// mc1192.link(mc1193, null) +// mc1193.link(mc1194, null) +// mc1194.link(mc1201, null) +// mc1201.link(mc1202, null) +// mc1202.link(mc1204, null) } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f5200636..4c27842f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,16 +24,16 @@ pluginManagement { } def versions = Arrays.asList( - "compat_1.15.2", - "compat_1.16.5", - "compat_1.17.1", - "compat_1.18.2", - "compat_1.19" , - "1.19.2", - "1.19.3", - "1.19.4", - "1.20.1", - "1.20.2", +// "compat_1.15.2", +// "compat_1.16.5", +// "compat_1.17.1", +// "compat_1.18.2", +// "compat_1.19" , +// "1.19.2", +// "1.19.3", +// "1.19.4", +// "1.20.1", +// "1.20.2", "1.20.4" ) for (String version : versions) { From 889b96322d459db4774ffe71b7e67953765fec92 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 17:47:22 +0800 Subject: [PATCH 03/36] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8TPS=E6=98=BE=E7=A4=BA=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #217 --- .../xujiayao/mcdiscordchat/utils/Utils.java | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java index deaffe06..c3aba74b 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java @@ -414,15 +414,10 @@ public static String getInfoCommandMessage() { } // Server TPS - //#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)))); + message.append(Translations.translate("utils.utils.gicMessage.serverTps", String.format("%.2f", SERVER.tickRateManager().tickrate()))); // Server MSPT - message.append(Translations.translate("utils.utils.gicMessage.serverMspt", String.format("%.2f", serverTickTime))); + message.append(Translations.translate("utils.utils.gicMessage.serverMspt", String.format("%.2f", SERVER.getCurrentSmoothedTickTime()))); // Server used memory message.append(Translations.translate("utils.utils.gicMessage.serverUsedMemory", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024, Runtime.getRuntime().totalMemory() / 1024 / 1024)); @@ -527,11 +522,7 @@ public static void initMsptMonitor() { MSPT_MONITOR_TIMER.schedule(new TimerTask() { @Override public void run() { - //#if MC >= 12003 - double mspt = average(SERVER.getTickTimes()) * 1.0E-6D; - //#else - //$$ double mspt = average(SERVER.lastTickLengths) * 1.0E-6D; - //#endif + double mspt = SERVER.getCurrentSmoothedTickTime(); if (mspt > CONFIG.generic.msptLimit) { String message = Translations.translateMessage("message.highMspt") @@ -597,13 +588,4 @@ public void run() { } }, 3600000, 21600000); } - - public static double average(long[] array) { - long sum = 0L; - for (final long i : array) { - sum += i; - } - - return sum / (double) array.length; - } } From b2e30b04c15404202db3414afb6c03ef6e7cbcfb Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 17:55:47 +0800 Subject: [PATCH 04/36] =?UTF-8?q?=E9=9D=9EMinecraft=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/xujiayao/mcdiscordchat/Main.java | 3 + .../discord/DiscordCommandOutput.java | 22 +--- .../discord/DiscordEventListener.java | 122 +++++++----------- .../minecraft/MinecraftCommands.java | 80 ++---------- .../multi_server/client/ReadThread.java | 62 +++------ .../mcdiscordchat/utils/MarkdownParser.java | 12 +- .../mcdiscordchat/utils/Translations.java | 14 +- .../xujiayao/mcdiscordchat/utils/Utils.java | 52 +++----- 8 files changed, 121 insertions(+), 246 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/Main.java b/src/main/java/com/xujiayao/mcdiscordchat/Main.java index 4ffc582b..8d6d2b8d 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/Main.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/Main.java @@ -1,5 +1,6 @@ package com.xujiayao.mcdiscordchat; +import com.xujiayao.mcdiscordchat.minecraft.MinecraftEventListener; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Webhook; @@ -212,6 +213,8 @@ public void onInitializeServer() { shutdown(); } }); + + MinecraftEventListener.init(); } private void shutdown() { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java index fb4680f1..51eb1d9a 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java @@ -1,19 +1,16 @@ package com.xujiayao.mcdiscordchat.discord; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.minecraft.server.command.CommandOutput; -import net.minecraft.text.Text; +import net.minecraft.commands.CommandSource; +import net.minecraft.network.chat.Component; import java.util.Timer; import java.util.TimerTask; -//#if MC <= 11802 -//$$ import java.util.UUID; -//#endif /** * @author Xujiayao */ -public class DiscordCommandOutput implements CommandOutput { +public class DiscordCommandOutput implements CommandSource { private final SlashCommandInteractionEvent e; private StringBuilder output = new StringBuilder("```\n"); @@ -24,11 +21,7 @@ public DiscordCommandOutput(SlashCommandInteractionEvent e) { } @Override - //#if MC >= 11900 || MC <= 11502 - public void sendMessage(Text message) { - //#else - //$$ public void sendSystemMessage(Text message, UUID sender) { - //#endif + public void sendSystemMessage(Component message) { long currentOutputMillis = System.currentTimeMillis(); if (output.length() > 1500) { @@ -54,18 +47,17 @@ public void run() { } @Override - public boolean shouldReceiveFeedback() { + public boolean acceptsSuccess() { return true; } @Override - public boolean shouldTrackOutput() { + public boolean acceptsFailure() { return true; } @Override - public boolean shouldBroadcastConsoleToOps() { + public boolean shouldInformAdmins() { return true; } - } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java index 47c20607..9e74016a 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java @@ -5,6 +5,9 @@ import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.tree.CommandNode; +import com.xujiayao.mcdiscordchat.utils.MarkdownParser; +import com.xujiayao.mcdiscordchat.utils.Translations; +import com.xujiayao.mcdiscordchat.utils.Utils; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Role; @@ -18,28 +21,15 @@ import net.dv8tion.jda.api.utils.MarkdownSanitizer; import net.fabricmc.loader.api.FabricLoader; import net.fellbaum.jemoji.EmojiManager; -import net.minecraft.server.command.ServerCommandSource; -//#if MC <= 11802 -//$$ import net.minecraft.text.LiteralText; -//#endif -import net.minecraft.text.Text; -//#if MC >= 11900 -import net.minecraft.text.Texts; -//#endif -import net.minecraft.util.Formatting; -//#if MC <= 11605 -//$$ import net.minecraft.util.math.Vec2f; -//$$ import net.minecraft.util.math.Vec3d; -//#endif -//#if MC <= 11502 -//$$ import net.minecraft.world.dimension.DimensionType; -//#endif +import net.minecraft.ChatFormatting; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.phys.Vec2; +import net.minecraft.world.phys.Vec3; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; -import com.xujiayao.mcdiscordchat.utils.MarkdownParser; -import com.xujiayao.mcdiscordchat.utils.Translations; -import com.xujiayao.mcdiscordchat.utils.Utils; import java.io.ByteArrayOutputStream; import java.io.File; @@ -94,32 +84,21 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { .replace("%command%", e.getCommandString()))); if (CONFIG.generic.broadcastSlashCommandExecution) { - Text commandNoticeText = Text.Serialization.fromJson(Translations.translateMessage("message.formattedCommandNotice") + MutableComponent commandNoticeText = Component.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage") + .replace("%server%", (CONFIG.multiServer.enable ? CONFIG.multiServer.name : "Discord")) + .replace("%message%", "")); + + Objects.requireNonNull(commandNoticeText).append(Component.Serializer.fromJson(Translations.translateMessage("message.formattedCommandNotice") .replace("%name%", (CONFIG.generic.useServerNickname ? e.getMember().getEffectiveName() : e.getMember().getUser().getName()).replace("\\", "\\\\").replace("\"", "\\\"")) .replace("%roleName%", roleName) .replace("%roleColor%", String.format("#%06X", (0xFFFFFF & e.getMember().getColorRaw()))) - .replace("%command%", e.getCommandString())); - - //#if MC <= 11802 - //$$ SERVER.getPlayerManager().getPlayerList().forEach( - //$$ player -> player.sendMessage(new LiteralText("") - //$$ .append(Text.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage") - //$$ .replace("%server%", (CONFIG.multiServer.enable ? CONFIG.multiServer.name : "Discord")) - //$$ .replace("%message%", ""))) - //$$ .append(commandNoticeText), false)); - //#else - List commandNoticeTextList = new ArrayList<>(); - commandNoticeTextList.add(Text.Serialization.fromJson(Translations.translateMessage("message.formattedOtherMessage") - .replace("%server%", (CONFIG.multiServer.enable ? CONFIG.multiServer.name : "Discord")) - .replace("%message%", ""))); - commandNoticeTextList.add(commandNoticeText); + .replace("%command%", e.getCommandString()))); - SERVER.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(Texts.join(commandNoticeTextList, Text.of("")), false)); - //#endif + SERVER.getPlayerList().getPlayers().forEach( + player -> player.displayClientMessage(commandNoticeText, false)); if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, true, null, Text.Serialization.toJsonString(commandNoticeText)); + MULTI_SERVER.sendMessage(false, false, true, null, Component.Serializer.toJson(commandNoticeText)); } } @@ -151,20 +130,15 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { if ("stop".equals(command) || "/stop".equals(command)) { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.stoppingServer")) .submit() - .whenComplete((v, ex) -> SERVER.stop(true)); + .whenComplete((v, ex) -> SERVER.halt(false)); } else { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.executingCommand")) .submit() - .whenComplete((v, ex) -> SERVER.getCommandManager() - //#if MC >= 11900 - .executeWithPrefix(SERVER.getCommandSource().withOutput(new DiscordCommandOutput(e)), command)); - //#elseif MC >= 11700 - //$$ .execute(SERVER.getCommandSource().withOutput(new DiscordCommandOutput(e)), command)); - //#elseif MC >= 11600 - //$$ .execute(new ServerCommandSource(new DiscordCommandOutput(e), Vec3d.ZERO, Vec2f.ZERO, SERVER.getOverworld(), 4, "MC-Discord-Chat", new LiteralText("MC-Discord-Chat"), SERVER, null), command)); - //#else - //$$ .execute(new ServerCommandSource(new DiscordCommandOutput(e), Vec3d.ZERO, Vec2f.ZERO, SERVER.getWorld(DimensionType.OVERWORLD), 4, "MC-Discord-Chat", new LiteralText("MC-Discord-Chat"), SERVER, null), command)); - //#endif + .whenComplete((v, ex) -> { + CommandSourceStack source = new CommandSourceStack(new DiscordCommandOutput(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", Component.literal("MC-Discord-Chat"), SERVER, null); + ParseResults results = SERVER.getCommands().getDispatcher().parse(command, source); + SERVER.getCommands().performCommand(results, command); + }); } } else { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.noPermission")).queue(); @@ -209,7 +183,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { if (Utils.isAdmin(e.getMember())) { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.stoppingServer")) .submit() - .whenComplete((v, ex) -> SERVER.stop(true)); + .whenComplete((v, ex) -> SERVER.halt(false)); } else { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.noPermission")).queue(); } @@ -236,7 +210,7 @@ public void onCommandAutoCompleteInteraction(CommandAutoCompleteInteractionEvent e.replyChoices(options).queue(); } else if ("console".equals(e.getName()) && "command".equals(e.getFocusedOption().getName())) { - CommandDispatcher dispatcher = SERVER.getCommandManager().getDispatcher(); + CommandDispatcher dispatcher = SERVER.getCommands().getDispatcher(); try { String input = e.getFocusedOption().getValue(); @@ -246,12 +220,12 @@ public void onCommandAutoCompleteInteraction(CommandAutoCompleteInteractionEvent List temp = new ArrayList<>(); - ParseResults results = dispatcher.parse(input, SERVER.getCommandSource()); + ParseResults results = dispatcher.parse(input, SERVER.createCommandSourceStack()); Suggestions suggestions = dispatcher.getCompletionSuggestions(results).get(); int size = results.getContext().getNodes().size(); if (size > 0) { - Map, String> map = dispatcher.getSmartUsage(results.getContext().getNodes().get(size - 1).getNode(), SERVER.getCommandSource()); + Map, String> map = dispatcher.getSmartUsage(results.getContext().getNodes().get(size - 1).getNode(), SERVER.createCommandSourceStack()); for (String string : map.values()) { temp.add((string.length() > 100) ? string.substring(0, 99) : string); @@ -377,7 +351,7 @@ public void onMessageReceived(MessageReceivedEvent e) { referencedMessage.append(" "); } for (Message.Attachment attachment : e.getMessage().getReferencedMessage().getAttachments()) { - referencedMessage.append(Formatting.YELLOW).append(attachment.isSpoiler() ? ""); } else if (attachment.isVideo()) { @@ -393,7 +367,7 @@ public void onMessageReceived(MessageReceivedEvent e) { referencedMessage.append(" "); } for (int i = 0; i < e.getMessage().getReferencedMessage().getStickers().size(); i++) { - referencedMessage.append(Formatting.YELLOW).append(""); + referencedMessage.append(ChatFormatting.YELLOW).append(""); } } @@ -402,7 +376,7 @@ public void onMessageReceived(MessageReceivedEvent e) { for (String emojiName : emojiNames) { List emojis = JDA.getEmojisByName(emojiName, true); if (!emojis.isEmpty() || EmojiManager.getByAlias(emojiName).isPresent()) { - referencedMessage = new StringBuilder(StringUtils.replaceIgnoreCase(referencedMessage.toString(), (":" + emojiName + ":"), (Formatting.YELLOW + ":" + emojiName + ":" + Formatting.RESET))); + referencedMessage = new StringBuilder(StringUtils.replaceIgnoreCase(referencedMessage.toString(), (":" + emojiName + ":"), (ChatFormatting.YELLOW + ":" + emojiName + ":" + ChatFormatting.RESET))); } } } @@ -413,7 +387,7 @@ public void onMessageReceived(MessageReceivedEvent e) { for (Member member : CHANNEL.getMembers()) { String usernameMention = "@" + member.getUser().getName(); String displayNameMention = "@" + member.getUser().getEffectiveName(); - String formattedMention = Formatting.YELLOW + "@" + member.getEffectiveName() + Formatting.RESET; + String formattedMention = ChatFormatting.YELLOW + "@" + member.getEffectiveName() + ChatFormatting.RESET; temp = StringUtils.replaceIgnoreCase(temp, usernameMention, MarkdownSanitizer.escape(formattedMention)); temp = StringUtils.replaceIgnoreCase(temp, displayNameMention, MarkdownSanitizer.escape(formattedMention)); @@ -424,11 +398,11 @@ public void onMessageReceived(MessageReceivedEvent e) { } for (Role role : CHANNEL.getGuild().getRoles()) { String roleMention = "@" + role.getName(); - String formattedMention = Formatting.YELLOW + "@" + role.getName() + Formatting.RESET; + String formattedMention = ChatFormatting.YELLOW + "@" + role.getName() + ChatFormatting.RESET; temp = StringUtils.replaceIgnoreCase(temp, roleMention, MarkdownSanitizer.escape(formattedMention)); } - temp = StringUtils.replaceIgnoreCase(temp, "@everyone", Formatting.YELLOW + "@everyone" + Formatting.RESET); - temp = StringUtils.replaceIgnoreCase(temp, "@here", Formatting.YELLOW + "@here" + Formatting.RESET); + temp = StringUtils.replaceIgnoreCase(temp, "@everyone", ChatFormatting.YELLOW + "@everyone" + ChatFormatting.RESET); + temp = StringUtils.replaceIgnoreCase(temp, "@here", ChatFormatting.YELLOW + "@here" + ChatFormatting.RESET); referencedMessage = new StringBuilder(temp); } @@ -466,7 +440,7 @@ public void onMessageReceived(MessageReceivedEvent e) { message.append(" "); } for (Message.Attachment attachment : e.getMessage().getAttachments()) { - message.append(Formatting.YELLOW).append(attachment.isSpoiler() ? ""); } else if (attachment.isVideo()) { @@ -482,7 +456,7 @@ public void onMessageReceived(MessageReceivedEvent e) { message.append(" "); } for (int i = 0; i < e.getMessage().getStickers().size(); i++) { - message.append(Formatting.YELLOW).append(""); + message.append(ChatFormatting.YELLOW).append(""); } } @@ -491,7 +465,7 @@ public void onMessageReceived(MessageReceivedEvent e) { for (String emojiName : emojiNames) { List emojis = JDA.getEmojisByName(emojiName, true); if (!emojis.isEmpty() || EmojiManager.getByAlias(emojiName).isPresent()) { - message = new StringBuilder(StringUtils.replaceIgnoreCase(message.toString(), (":" + emojiName + ":"), (Formatting.YELLOW + ":" + emojiName + ":" + Formatting.RESET))); + message = new StringBuilder(StringUtils.replaceIgnoreCase(message.toString(), (":" + emojiName + ":"), (ChatFormatting.YELLOW + ":" + emojiName + ":" + ChatFormatting.RESET))); } } } @@ -502,7 +476,7 @@ public void onMessageReceived(MessageReceivedEvent e) { for (Member member : CHANNEL.getMembers()) { String usernameMention = "@" + member.getUser().getName(); String displayNameMention = "@" + member.getUser().getEffectiveName(); - String formattedMention = Formatting.YELLOW + "@" + member.getEffectiveName() + Formatting.RESET; + String formattedMention = ChatFormatting.YELLOW + "@" + member.getEffectiveName() + ChatFormatting.RESET; temp = StringUtils.replaceIgnoreCase(temp, usernameMention, MarkdownSanitizer.escape(formattedMention)); temp = StringUtils.replaceIgnoreCase(temp, displayNameMention, MarkdownSanitizer.escape(formattedMention)); @@ -513,11 +487,11 @@ public void onMessageReceived(MessageReceivedEvent e) { } for (Role role : CHANNEL.getGuild().getRoles()) { String roleMention = "@" + role.getName(); - String formattedMention = Formatting.YELLOW + "@" + role.getName() + Formatting.RESET; + String formattedMention = ChatFormatting.YELLOW + "@" + role.getName() + ChatFormatting.RESET; temp = StringUtils.replaceIgnoreCase(temp, roleMention, MarkdownSanitizer.escape(formattedMention)); } - temp = StringUtils.replaceIgnoreCase(temp, "@everyone", Formatting.YELLOW + "@everyone" + Formatting.RESET); - temp = StringUtils.replaceIgnoreCase(temp, "@here", Formatting.YELLOW + "@here" + Formatting.RESET); + temp = StringUtils.replaceIgnoreCase(temp, "@everyone", ChatFormatting.YELLOW + "@everyone" + ChatFormatting.RESET); + temp = StringUtils.replaceIgnoreCase(temp, "@here", ChatFormatting.YELLOW + "@here" + ChatFormatting.RESET); message = new StringBuilder(temp); } @@ -551,7 +525,7 @@ public void onMessageReceived(MessageReceivedEvent e) { if (CONFIG.generic.broadcastChatMessages) { if (e.getMessage().getReferencedMessage() != null) { String s = Translations.translateMessage("message.formattedResponseMessage"); - Text referenceFinalText = Text.Serialization.fromJson(s + MutableComponent referenceFinalText = Component.Serializer.fromJson(s .replace("%message%", (CONFIG.generic.formatChatMessages ? finalReferencedMessage : EmojiManager.replaceAllEmojis(referencedMessageTemp, emoji -> emoji.getDiscordAliases().get(0)).replace("\"", "\\\"")) .replace("\n", "\n" + textAfterPlaceholder[0] + "}," + s.substring(1, s.indexOf("%message%")))) .replace("%server%", "Discord") @@ -559,12 +533,12 @@ public void onMessageReceived(MessageReceivedEvent e) { .replace("%roleName%", referencedMemberRoleName) .replace("%roleColor%", String.format("#%06X", (0xFFFFFF & ((referencedMember != null) ? referencedMember.getColorRaw() : Role.DEFAULT_COLOR_RAW))))); - SERVER.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(referenceFinalText, false)); + SERVER.getPlayerList().getPlayers().forEach( + player -> player.displayClientMessage(referenceFinalText, false)); } String s = Translations.translateMessage("message.formattedChatMessage"); - Text finalText = Text.Serialization.fromJson(s + MutableComponent finalText = Component.Serializer.fromJson(s .replace("%message%", (CONFIG.generic.formatChatMessages ? finalMessage : EmojiManager.replaceAllEmojis(messageTemp, emoji -> emoji.getDiscordAliases().get(0)).replace("\"", "\\\"")) .replace("\n", "\n" + textAfterPlaceholder[1] + "}," + s.substring(1, s.indexOf("%message%")))) .replace("%server%", "Discord") @@ -572,8 +546,8 @@ public void onMessageReceived(MessageReceivedEvent e) { .replace("%roleName%", memberRoleName) .replace("%roleColor%", String.format("#%06X", (0xFFFFFF & e.getMember().getColorRaw())))); - SERVER.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(finalText, false)); + SERVER.getPlayerList().getPlayers().forEach( + player -> player.displayClientMessage(finalText, false)); } } } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java index 0dccf985..bcc04f65 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java @@ -2,56 +2,32 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; -import net.minecraft.server.command.ServerCommandSource; -//#if MC < 11900 -//$$ import net.minecraft.text.LiteralText; -//#endif -import net.minecraft.text.Text; import com.xujiayao.mcdiscordchat.utils.MarkdownParser; import com.xujiayao.mcdiscordchat.utils.Translations; import com.xujiayao.mcdiscordchat.utils.Utils; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.network.chat.Component; -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; import static com.xujiayao.mcdiscordchat.Main.CONFIG; +import static net.minecraft.commands.Commands.argument; +import static net.minecraft.commands.Commands.literal; /** * @author Xujiayao */ public class MinecraftCommands { - public static void register(CommandDispatcher dispatcher) { + public static void register(CommandDispatcher dispatcher) { dispatcher.register(literal("mcdc").executes(context -> { - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal(MarkdownParser.parseMarkdown( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal(MarkdownParser.parseMarkdown( - //#else - //$$ context.getSource().sendFeedback(new LiteralText(MarkdownParser.parseMarkdown( - //#endif - Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); return 1; }) .then(literal("help").executes(context -> { - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal(MarkdownParser.parseMarkdown( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal(MarkdownParser.parseMarkdown( - //#else - //$$ context.getSource().sendFeedback(new LiteralText(MarkdownParser.parseMarkdown( - //#endif - Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); return 1; })) .then(literal("info").executes(context -> { - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal( - //#else - //$$ context.getSource().sendFeedback(new LiteralText( - //#endif - Utils.getInfoCommandMessage()), false); + context.getSource().sendSuccess(() -> Component.literal(Utils.getInfoCommandMessage()), false); return 1; })) .then(literal("stats") @@ -60,53 +36,25 @@ public static void register(CommandDispatcher dispatcher) { .executes(context -> { String type = StringArgumentType.getString(context, "type"); String name = StringArgumentType.getString(context, "name"); - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal( - //#else - //$$ context.getSource().sendFeedback(new LiteralText( - //#endif - Utils.getStatsCommandMessage(type, name)), false); + context.getSource().sendSuccess(() -> Component.literal(Utils.getStatsCommandMessage(type, name)), false); return 1; })))) .then(literal("update").executes(context -> { - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal( - //#else - //$$ context.getSource().sendFeedback(new LiteralText( - //#endif - MarkdownParser.parseMarkdown(Utils.checkUpdate(true))), false); + context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.checkUpdate(true))), false); return 1; })) .then(literal("whitelist") - .requires(source -> source.hasPermissionLevel(CONFIG.generic.whitelistRequiresAdmin ? 4 : 0)) + .requires(source -> source.hasPermission(CONFIG.generic.whitelistRequiresAdmin ? 4 : 0)) .then(argument("player", StringArgumentType.word()) .executes(context -> { String player = StringArgumentType.getString(context, "player"); - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal( - //#else - //$$ context.getSource().sendFeedback(new LiteralText( - //#endif - MarkdownParser.parseMarkdown(Utils.whitelist(player))), false); + context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.whitelist(player))), false); return 1; }))) .then(literal("reload") - .requires(source -> source.hasPermissionLevel(4)) + .requires(source -> source.hasPermission(4)) .executes(context -> { - //#if MC >= 12000 - context.getSource().sendFeedback(() -> Text.literal( - //#elseif MC >= 11900 - //$$ context.getSource().sendFeedback(Text.literal( - //#else - //$$ context.getSource().sendFeedback(new LiteralText( - //#endif - MarkdownParser.parseMarkdown(Utils.reload())), false); + context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.reload())), false); return 1; }))); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/multi_server/client/ReadThread.java b/src/main/java/com/xujiayao/mcdiscordchat/multi_server/client/ReadThread.java index a0b774ab..2a639b70 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/multi_server/client/ReadThread.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/multi_server/client/ReadThread.java @@ -3,19 +3,14 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -//#if MC <= 11802 -//$$ import net.minecraft.text.LiteralText; -//#endif -import net.minecraft.text.Text; -//#if MC >= 11900 -import net.minecraft.text.Texts; -//#endif -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.exception.ExceptionUtils; import com.xujiayao.mcdiscordchat.utils.MarkdownParser; import com.xujiayao.mcdiscordchat.utils.Translations; import com.xujiayao.mcdiscordchat.utils.Utils; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; import java.io.BufferedReader; import java.io.File; @@ -23,14 +18,8 @@ import java.io.InputStreamReader; import java.net.Socket; import java.nio.charset.StandardCharsets; -//#if MC >= 11900 -import java.util.ArrayList; -//#endif import java.util.Arrays; import java.util.HashSet; -//#if MC >= 11900 -import java.util.List; -//#endif import java.util.Objects; import java.util.Properties; import java.util.Set; @@ -69,18 +58,14 @@ public void run() { Objects.requireNonNull(channel).sendMessage("```\n" + Utils.getInfoCommandMessage() + "\n```").queue(); } else if ("updateChannelTopic".equals(message.get("type").getAsString())) { JsonObject channelTopicInfo = new JsonObject(); - channelTopicInfo.addProperty("onlinePlayerCount", SERVER.getPlayerManager().getPlayerList().size()); - channelTopicInfo.addProperty("maxPlayerCount", SERVER.getPlayerManager().getMaxPlayerCount()); + channelTopicInfo.addProperty("onlinePlayerCount", SERVER.getPlayerCount()); + channelTopicInfo.addProperty("maxPlayerCount", SERVER.getMaxPlayers()); Properties properties = new Properties(); properties.load(new FileInputStream("server.properties")); Set uniquePlayers = new HashSet<>(); - //#if MC >= 11600 FileUtils.listFiles(new File((properties.getProperty("level-name") + "/stats/")), null, false).forEach(file -> uniquePlayers.add(file.getName())); - //#else - //$$ FileUtils.listFiles(new File((properties.getProperty("level-name") + "/stats/")), null, false).forEach(file -> uniquePlayers.add(file.getName())); - //#endif channelTopicInfo.add("uniquePlayers", new Gson().fromJson(Arrays.toString(uniquePlayers.toArray()), JsonArray.class)); channelTopicInfo.addProperty("serverName", CONFIG.multiServer.name); @@ -98,48 +83,39 @@ public void run() { .replace("%name%", json.get("playerName").getAsString()) .replace("%message%", json.get("message").getAsString())); - Text text = Text.Serialization.fromJson(Translations.translateMessage("message.formattedChatMessage") + MutableComponent text = Component.Serializer.fromJson(Translations.translateMessage("message.formattedChatMessage") .replace("%server%", json.get("serverName").getAsString()) .replace("%name%", json.get("playerName").getAsString()) .replace("%roleColor%", "white") .replace("%message%", MarkdownParser.parseMarkdown(json.get("message").getAsString()))); - SERVER.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(text, false)); + SERVER.getPlayerList().getPlayers().forEach( + player -> player.displayClientMessage(text, false)); } else { if (json.get("isText").getAsBoolean()) { LOGGER.info(Translations.translateMessage("message.unformattedOtherMessage") .replace("%server%", json.get("serverName").getAsString()) - .replace("%message%", Objects.requireNonNull(Text.Serialization.fromJson(json.get("message").getAsString())).getString())); + .replace("%message%", Objects.requireNonNull(Component.Serializer.fromJson(json.get("message").getAsString())).getString())); - Text text = Text.Serialization.fromJson(Translations.translateMessage("message.formattedOtherMessage") + MutableComponent text = Component.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage") .replace("%server%", json.get("serverName").getAsString()) .replace("%message%", "")); - //#if MC <= 11802 - //$$ SERVER.getPlayerManager().getPlayerList().forEach( - //$$ player -> player.sendMessage(new LiteralText("") - //$$ .append(text) - //$$ .append(Text.Serializer.fromJson(json.get("message").getAsString())), false)); - //#else - List textList = new ArrayList<>(); - textList.add(text); - textList.add(Text.Serialization.fromJson(json.get("message").getAsString())); - - SERVER.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(Texts.join(textList, Text.of("")), false)); - //#endif + Objects.requireNonNull(text).append(Component.Serializer.fromJson(json.get("message").getAsString())); + + SERVER.getPlayerList().getPlayers().forEach( + player -> player.displayClientMessage(text, false)); } else { LOGGER.info(Translations.translateMessage("message.unformattedOtherMessage") .replace("%server%", json.get("serverName").getAsString()) .replace("%message%", json.get("message").getAsString())); - Text text = Text.Serialization.fromJson(Translations.translateMessage("message.formattedOtherMessage") + MutableComponent text = Component.Serializer.fromJson(Translations.translateMessage("message.formattedOtherMessage") .replace("%server%", json.get("serverName").getAsString()) .replace("%message%", MarkdownParser.parseMarkdown(json.get("message").getAsString()))); - SERVER.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(text, false)); + SERVER.getPlayerList().getPlayers().forEach( + player -> player.displayClientMessage(text, false)); } } } catch (Exception e) { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/MarkdownParser.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/MarkdownParser.java index 5863c7ea..f33ee856 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/MarkdownParser.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/MarkdownParser.java @@ -20,7 +20,7 @@ package com.xujiayao.mcdiscordchat.utils; -import net.minecraft.util.Formatting; +import net.minecraft.ChatFormatting; import java.util.ArrayList; import java.util.List; @@ -34,11 +34,11 @@ public class MarkdownParser { public static String parseMarkdown(String message) { - message = replaceWith(message, "(?= 11600 - String translation2 = Language.getInstance().get(key); - //#else - //$$ String translation2 = Language.getInstance().translate(key); - //#endif + String translation2 = Language.getInstance().getOrDefault(key); if (!translation2.equals(key)) { return String.format(translation2, args); } else { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java index c3aba74b..c83213e5 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java @@ -5,6 +5,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; +import com.xujiayao.mcdiscordchat.multi_server.MultiServer; import net.dv8tion.jda.api.entities.Activity; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; @@ -13,10 +14,10 @@ import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.SharedConstants; -import net.minecraft.server.Whitelist; -import net.minecraft.server.WhitelistEntry; -import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.DetectedVersion; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.UserWhiteList; +import net.minecraft.server.players.UserWhiteListEntry; import okhttp3.CacheControl; import okhttp3.Request; import okhttp3.Response; @@ -24,7 +25,6 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; -import com.xujiayao.mcdiscordchat.multi_server.MultiServer; import java.io.File; import java.io.FileInputStream; @@ -104,7 +104,7 @@ public static String checkUpdate(boolean isManualCheck) { try (Response response = HTTP_CLIENT.newCall(request).execute()) { String result = Objects.requireNonNull(response.body()).string(); - String minecraftVersion = SharedConstants.getGameVersion().getName(); + String minecraftVersion = DetectedVersion.tryDetectVersion().getName(); CONFIG.latestVersion = ""; String latestChangelog = ""; @@ -208,7 +208,7 @@ public static String checkUpdate(boolean isManualCheck) { } public static String whitelist(String player) { - Whitelist whitelist = SERVER.getPlayerManager().getWhitelist(); + UserWhiteList whitelist = SERVER.getPlayerList().getWhiteList(); Request request = new Request.Builder() .url("https://api.mojang.com/users/profiles/minecraft/" + player) @@ -223,10 +223,10 @@ public static String whitelist(String player) { String name = json.get("name").getAsString(); GameProfile profile = new GameProfile(uuid, name); - if (whitelist.isAllowed(profile)) { + if (whitelist.isWhiteListed(profile)) { return Translations.translate("utils.utils.whitelist.whitelistFailed"); } else { - whitelist.add(new WhitelistEntry(profile)); + whitelist.add(new UserWhiteListEntry(profile)); return Translations.translate("utils.utils.whitelist.whitelistSuccess", name); } } else if (response.code() == 404) { @@ -396,20 +396,14 @@ public static String getInfoCommandMessage() { .append(" ===============\n\n"); // Online players - List onlinePlayers = SERVER.getPlayerManager().getPlayerList(); - message.append(Translations.translate("utils.utils.gicMessage.onlinePlayers", onlinePlayers.size(), SERVER.getPlayerManager().getMaxPlayerCount())); + List onlinePlayers = SERVER.getPlayerList().getPlayers(); + message.append(Translations.translate("utils.utils.gicMessage.onlinePlayers", onlinePlayers.size(), SERVER.getMaxPlayers())); if (onlinePlayers.isEmpty()) { message.append(Translations.translate("utils.utils.gicMessage.noPlayersOnline")); } else { - for (ServerPlayerEntity player : onlinePlayers) { - //#if MC >= 12003 - message.append("[").append(player.networkHandler.getLatency()).append("ms] ").append(Objects.requireNonNull(player.getDisplayName()).getString()).append("\n"); - //#elseif MC >= 12002 - //$$ message.append("[").append(player.networkHandler.getLatency()).append("ms] ").append(Objects.requireNonNull(player.getDisplayName()).getString()).append("\n"); - //#else - //$$ message.append("[").append(player.pingMilliseconds).append("ms] ").append(Objects.requireNonNull(player.getDisplayName()).getString()).append("\n"); - //#endif + for (ServerPlayer player : onlinePlayers) { + message.append("[").append(player.connection.latency()).append("ms] ").append(Objects.requireNonNull(player.getDisplayName()).getString()).append("\n"); } } @@ -439,11 +433,7 @@ public static String getStatsCommandMessage(String type, String name) { Properties properties = new Properties(); properties.load(new FileInputStream("server.properties")); - //#if MC >= 11600 FileUtils.listFiles(new File((properties.getProperty("level-name") + "/stats/")), null, false).forEach(file -> { - //#else - //$$ FileUtils.listFiles(new File((properties.getProperty("level-name") + "/stats/")), null, false).forEach(file -> { - //#endif try { for (JsonElement player : players) { if (player.getAsJsonObject().get("uuid").getAsString().equals(file.getName().replace(".json", ""))) { @@ -488,12 +478,12 @@ public static void setBotActivity() { } if (!CONFIG.generic.botPlayingStatus.isEmpty()) { JDA.getPresence().setActivity(Activity.playing(CONFIG.generic.botPlayingStatus - .replace("%onlinePlayerCount%", Integer.toString(SERVER.getPlayerManager().getPlayerList().size())) - .replace("%maxPlayerCount%", Integer.toString(SERVER.getPlayerManager().getMaxPlayerCount())))); + .replace("%onlinePlayerCount%", Integer.toString(SERVER.getPlayerCount())) + .replace("%maxPlayerCount%", Integer.toString(SERVER.getMaxPlayers())))); } else if (!CONFIG.generic.botListeningStatus.isEmpty()) { JDA.getPresence().setActivity(Activity.listening(CONFIG.generic.botListeningStatus - .replace("%onlinePlayerCount%", Integer.toString(SERVER.getPlayerManager().getPlayerList().size())) - .replace("%maxPlayerCount%", Integer.toString(SERVER.getPlayerManager().getMaxPlayerCount())))); + .replace("%onlinePlayerCount%", Integer.toString(SERVER.getPlayerCount())) + .replace("%maxPlayerCount%", Integer.toString(SERVER.getMaxPlayers())))); } else { JDA.getPresence().setActivity(null); } @@ -549,13 +539,9 @@ public void run() { properties.load(new FileInputStream("server.properties")); String topic = Translations.translateMessage("message.onlineChannelTopic") - .replace("%onlinePlayerCount%", Integer.toString(SERVER.getPlayerManager().getPlayerList().size())) - .replace("%maxPlayerCount%", Integer.toString(SERVER.getPlayerManager().getMaxPlayerCount())) - //#if MC >= 11600 + .replace("%onlinePlayerCount%", Integer.toString(SERVER.getPlayerCount())) + .replace("%maxPlayerCount%", Integer.toString(SERVER.getMaxPlayers())) .replace("%uniquePlayerCount%", Integer.toString(FileUtils.listFiles(new File((properties.getProperty("level-name") + "/stats/")), null, false).size())) - //#else - //$$ .replace("%uniquePlayerCount%", Integer.toString(FileUtils.listFiles(new File((properties.getProperty("level-name") + "/stats/")), null, false).size())) - //#endif .replace("%serverStartedTime%", SERVER_STARTED_TIME) .replace("%lastUpdateTime%", Long.toString(epochSecond)) .replace("%nextUpdateTime%", Long.toString(epochSecond + CONFIG.generic.channelTopicUpdateInterval / 1000)); From 72d1e192d344d479406e0fa3adbf9d8394249a14 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 18:02:26 +0800 Subject: [PATCH 05/36] =?UTF-8?q?=E5=A4=84=E7=90=86=20Join=20&=20Leave?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 47 ++++++ .../minecraft/MinecraftEvents.java | 31 ++++ .../minecraft/mixins/MixinPlayerList.java | 28 ++++ .../minecraft/mixins/MixinPlayerManager.java | 147 ------------------ 4 files changed, 106 insertions(+), 147 deletions(-) create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java delete mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java new file mode 100644 index 00000000..caf1a06b --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -0,0 +1,47 @@ +package com.xujiayao.mcdiscordchat.minecraft; + +import com.xujiayao.mcdiscordchat.utils.Translations; +import com.xujiayao.mcdiscordchat.utils.Utils; +import net.dv8tion.jda.api.utils.MarkdownSanitizer; + +import java.util.Objects; + +import static com.xujiayao.mcdiscordchat.Main.CHANNEL; +import static com.xujiayao.mcdiscordchat.Main.CONFIG; +import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; + +/** + * @author Xujiayao + */ +public class MinecraftEventListener { + + public static void init() { + // TODO Server /say + + MinecraftEvents.PLAYER_JOIN.register(player -> { + Utils.setBotActivity(); + + if (CONFIG.generic.announcePlayerJoinLeave) { + CHANNEL.sendMessage(Translations.translateMessage("message.joinServer") + .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); + if (CONFIG.multiServer.enable) { + MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.joinServer") + .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); + } + } + }); + + MinecraftEvents.PLAYER_QUIT.register(player -> { + Utils.setBotActivity(); + + if (CONFIG.generic.announcePlayerJoinLeave) { + CHANNEL.sendMessage(Translations.translateMessage("message.leftServer") + .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); + if (CONFIG.multiServer.enable) { + MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.leftServer") + .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); + } + } + }); + } +} diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java new file mode 100644 index 00000000..afcf06ec --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -0,0 +1,31 @@ +package com.xujiayao.mcdiscordchat.minecraft; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.server.level.ServerPlayer; + +/** + * @author Xujiayao + */ +public interface MinecraftEvents { + + Event PLAYER_JOIN = EventFactory.createArrayBacked(PlayerJoin.class, callbacks -> player -> { + for (PlayerJoin callback : callbacks) { + callback.join(player); + } + }); + + Event PLAYER_QUIT = EventFactory.createArrayBacked(PlayerQuit.class, callbacks -> player -> { + for (PlayerQuit callback : callbacks) { + callback.quit(player); + } + }); + + interface PlayerJoin { + void join(ServerPlayer player); + } + + interface PlayerQuit { + void quit(ServerPlayer player); + } +} diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java new file mode 100644 index 00000000..9d0a6246 --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -0,0 +1,28 @@ +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; +import net.minecraft.network.Connection; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.CommonListenerCookie; +import net.minecraft.server.players.PlayerList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author Xujiayao + */ +@Mixin(PlayerList.class) +public class MixinPlayerList { + + @Inject(method = "placeNewPlayer", at = @At("RETURN")) + private void placeNewPlayer(Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { + MinecraftEvents.PLAYER_JOIN.invoker().join(serverPlayer); + } + + @Inject(method = "remove", at = @At("HEAD")) + private void remove(ServerPlayer serverPlayer, CallbackInfo ci) { + MinecraftEvents.PLAYER_QUIT.invoker().quit(serverPlayer); + } +} diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java deleted file mode 100644 index b3bfe82b..00000000 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import net.dv8tion.jda.api.utils.MarkdownSanitizer; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.message.MessageType; -//#if MC >= 11900 -import net.minecraft.network.message.SignedMessage; -//#endif -import net.minecraft.server.PlayerManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.network.ConnectedClientData; -import net.minecraft.server.network.ServerPlayerEntity; -//#if MC < 11900 -//$$ import net.minecraft.text.Text; -//#endif -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.xujiayao.mcdiscordchat.utils.Translations; -import com.xujiayao.mcdiscordchat.utils.Utils; - -//#if MC < 11900 -//$$ import java.util.UUID; -//#endif - -import java.util.Objects; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(PlayerManager.class) -public class MixinPlayerManager { - - @Inject(method = "broadcast(Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/network/message/MessageType$Parameters;)V", at = @At("RETURN")) - private void broadcast(SignedMessage message, ServerCommandSource source, MessageType.Parameters params, CallbackInfo ci) { - sendMessage(message.getSignedContent(), source.getName()); - } - - private void sendMessage(String content, String username) { - if (CONFIG.generic.broadcastChatMessages) { - if (!CONFIG.generic.useWebhook) { - if (CONFIG.multiServer.enable) { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhookForMultiServer") - .replace("%server%", CONFIG.multiServer.name) - .replace("%name%", username) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", username) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + username) : username)); - body.addProperty("avatar_url", JDA.getSelfUser().getAvatarUrl()); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, username, content); - } - } - } - - @Inject(method = "onPlayerConnect", at = @At("RETURN")) - private void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) { - Utils.setBotActivity(); - - if (CONFIG.generic.announcePlayerJoinLeave) { - CHANNEL.sendMessage(Translations.translateMessage("message.joinServer") - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); - //#endif - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.joinServer") - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); - //#endif - } - } - } - - @Inject(method = "remove", at = @At("RETURN")) - private void remove(ServerPlayerEntity player, CallbackInfo ci) { - Utils.setBotActivity(); - - if (CONFIG.generic.announcePlayerJoinLeave) { - CHANNEL.sendMessage(Translations.translateMessage("message.leftServer") - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); - //#endif - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.leftServer") - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); - //#endif - } - } - } -} - From 603b1af9762da4f79adcccee343073d317f32ac7 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 18:03:57 +0800 Subject: [PATCH 06/36] =?UTF-8?q?=E5=A4=84=E7=90=86=20Die?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 6 ++ .../minecraft/MinecraftEvents.java | 11 +++ .../minecraft/mixins/MixinServerPlayer.java | 21 +++++ .../mixins/MixinServerPlayerEntity.java | 86 ------------------- 4 files changed, 38 insertions(+), 86 deletions(-) create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java delete mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayerEntity.java diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index caf1a06b..3acc0e7b 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -16,6 +16,12 @@ public class MinecraftEventListener { public static void init() { + MinecraftEvents.PLAYER_DIE.register((player, source) -> { + if (CONFIG.generic.announceDeathMessages) { + System.out.println(source.getLocalizedDeathMessage(player)); + } + }); + // TODO Server /say MinecraftEvents.PLAYER_JOIN.register(player -> { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index afcf06ec..9dc2e8d3 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -3,12 +3,19 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.damagesource.DamageSource; /** * @author Xujiayao */ public interface MinecraftEvents { + Event PLAYER_DIE = EventFactory.createArrayBacked(PlayerDie.class, callbacks -> (player, source) -> { + for (PlayerDie callback : callbacks) { + callback.die(player, source); + } + }); + Event PLAYER_JOIN = EventFactory.createArrayBacked(PlayerJoin.class, callbacks -> player -> { for (PlayerJoin callback : callbacks) { callback.join(player); @@ -21,6 +28,10 @@ public interface MinecraftEvents { } }); + interface PlayerDie { + void die(ServerPlayer player, DamageSource source); + } + interface PlayerJoin { void join(ServerPlayer player); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java new file mode 100644 index 00000000..844f6b55 --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java @@ -0,0 +1,21 @@ +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.damagesource.DamageSource; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author Xujiayao + */ +@Mixin(ServerPlayer.class) +public class MixinServerPlayer { + + @Inject(method = "die", at = @At("HEAD")) + private void die(DamageSource damageSource, CallbackInfo ci) { + MinecraftEvents.PLAYER_DIE.invoker().die((ServerPlayer) (Object) this, damageSource); + } +} diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayerEntity.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayerEntity.java deleted file mode 100644 index 8bdde6b6..00000000 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayerEntity.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.mojang.authlib.GameProfile; -import net.dv8tion.jda.api.utils.MarkdownSanitizer; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.player.PlayerEntity; -//#if MC >= 11900 && MC < 11903 -//$$ import net.minecraft.network.encryption.PlayerPublicKey; -//#endif -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableTextContent; -//#if MC >= 11600 -import net.minecraft.util.math.BlockPos; -//#endif -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.xujiayao.mcdiscordchat.utils.Translations; - -import java.util.Objects; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; - -/** - * @author Xujiayao - */ -@Mixin(ServerPlayerEntity.class) -public abstract class MixinServerPlayerEntity extends PlayerEntity { - - //#if MC >= 11900 && MC < 11903 - //$$ private MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile profile, PlayerPublicKey publicKey) { - //$$ super(world, pos, yaw, profile, publicKey); - //$$ } - //#elseif MC >= 11600 - protected MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile) { - super(world, pos, yaw, gameProfile); - } - //#else - //$$ private MixinServerPlayerEntity(World world, GameProfile profile) { - //$$ super(world, profile); - //$$ } - //#endif - - @Inject(method = "onDeath", at = @At("HEAD")) - private void onDeath(DamageSource source, CallbackInfo ci) { - if (CONFIG.generic.announceDeathMessages) { - //#if MC >= 11900 - TranslatableTextContent deathMessage = (TranslatableTextContent) getDamageTracker().getDeathMessage().getContent(); - //#else - //$$ TranslatableText deathMessage = (TranslatableText) getDamageTracker().getDeathMessage(); - //#endif - String key = deathMessage.getKey(); - Object[] args = new String[deathMessage.getArgs().length]; - for (int i = 0; i < deathMessage.getArgs().length; i++) { - Object object = deathMessage.getArgs()[i]; - if (object instanceof Text text) { - args[i] = text.getString(); - } else { - args[i] = object == null ? "null" : object.toString(); - } - } - - CHANNEL.sendMessage(Translations.translateMessage("message.deathMessage") - .replace("%deathMessage%", MarkdownSanitizer.escape(Translations.translate(key, args))) - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(this.getDisplayName()).getString()))).queue(); - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(this.getDisplayName()).getString()))).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))) - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(this.getDisplayName().getString()))); - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(this.getDisplayName().getString()))); - //#endif - } - } - } -} From d19726fe40c1c61ec38136bf9e4599c3398d0583 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 18:06:06 +0800 Subject: [PATCH 07/36] =?UTF-8?q?=E5=A4=84=E7=90=86=20Advancement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 30 +++++++++ .../minecraft/MinecraftEvents.java | 11 +++ .../mixins/MixinPlayerAdvancementTracker.java | 67 ------------------- .../mixins/MixinPlayerAdvancements.java | 30 +++++++++ 4 files changed, 71 insertions(+), 67 deletions(-) delete mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 3acc0e7b..4f6aecea 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -3,6 +3,7 @@ import com.xujiayao.mcdiscordchat.utils.Translations; import com.xujiayao.mcdiscordchat.utils.Utils; import net.dv8tion.jda.api.utils.MarkdownSanitizer; +import net.minecraft.world.level.GameRules; import java.util.Objects; @@ -16,6 +17,35 @@ public class MinecraftEventListener { public static void init() { + MinecraftEvents.PLAYER_ADVANCEMENT.register((player, advancementHolder, isDone) -> { + if (CONFIG.generic.announceAdvancements + && isDone + && advancementHolder.value().display().isPresent() + && advancementHolder.value().display().get().shouldAnnounceChat() + && player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { + String message = "null"; + + switch (advancementHolder.value().display().get().getType()) { + case GOAL -> message = Translations.translateMessage("message.advancementGoal"); + case TASK -> message = Translations.translateMessage("message.advancementTask"); + case CHALLENGE -> message = Translations.translateMessage("message.advancementChallenge"); + } + + String title = Translations.translate("advancements." + advancementHolder.id().getPath().replace("/", ".") + ".title"); + String description = Translations.translate("advancements." + advancementHolder.id().getPath().replace("/", ".") + ".description"); + + message = message + .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString())) + .replace("%advancement%", title.contains("TranslateError") ? advancementHolder.value().display().get().getTitle().getString() : title) + .replace("%description%", description.contains("TranslateError") ? advancementHolder.value().display().get().getDescription().getString() : description); + + CHANNEL.sendMessage(message).queue(); + if (CONFIG.multiServer.enable) { + MULTI_SERVER.sendMessage(false, false, false, null, message); + } + } + }); + MinecraftEvents.PLAYER_DIE.register((player, source) -> { if (CONFIG.generic.announceDeathMessages) { System.out.println(source.getLocalizedDeathMessage(player)); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index 9dc2e8d3..d3a48b9a 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -2,6 +2,7 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.advancements.AdvancementHolder; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; @@ -10,6 +11,12 @@ */ public interface MinecraftEvents { + Event PLAYER_ADVANCEMENT = EventFactory.createArrayBacked(PlayerAdvancement.class, callbacks -> (player, advancementHolder, isDone) -> { + for (PlayerAdvancement callback : callbacks) { + callback.advancement(player, advancementHolder, isDone); + } + }); + Event PLAYER_DIE = EventFactory.createArrayBacked(PlayerDie.class, callbacks -> (player, source) -> { for (PlayerDie callback : callbacks) { callback.die(player, source); @@ -28,6 +35,10 @@ public interface MinecraftEvents { } }); + interface PlayerAdvancement { + void advancement(ServerPlayer player, AdvancementHolder advancementHolder, boolean isDone); + } + interface PlayerDie { void die(ServerPlayer player, DamageSource source); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java deleted file mode 100644 index 973ede59..00000000 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import net.dv8tion.jda.api.utils.MarkdownSanitizer; -import net.minecraft.advancement.AdvancementEntry; -import net.minecraft.advancement.AdvancementProgress; -import net.minecraft.advancement.PlayerAdvancementTracker; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.world.GameRules; -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.CallbackInfoReturnable; -import com.xujiayao.mcdiscordchat.utils.Translations; - -import java.util.Objects; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; - -/** - * @author Xujiayao - */ -@Mixin(PlayerAdvancementTracker.class) -public abstract class MixinPlayerAdvancementTracker { - - @Shadow - private ServerPlayerEntity owner; - - @Shadow - public abstract AdvancementProgress getProgress(AdvancementEntry advancement); - - @Inject(method = "grantCriterion", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancement/PlayerAdvancementTracker;onStatusUpdate(Lnet/minecraft/advancement/AdvancementEntry;)V")) - private void grantCriterion(AdvancementEntry advancement, String criterionName, CallbackInfoReturnable cir) { - if (CONFIG.generic.announceAdvancements - && getProgress(advancement).isDone() - && advancement.value().display().isPresent() - && advancement.value().display().get().shouldAnnounceToChat() - && owner.getWorld().getGameRules().getBoolean(GameRules.ANNOUNCE_ADVANCEMENTS)) { - String message = "null"; - - switch (advancement.value().display().get().getFrame()) { - case GOAL -> message = Translations.translateMessage("message.advancementGoal"); - case TASK -> message = Translations.translateMessage("message.advancementTask"); - case CHALLENGE -> message = Translations.translateMessage("message.advancementChallenge"); - } - - String title = Translations.translate("advancements." + advancement.id().getPath().replace("/", ".") + ".title"); - String description = Translations.translate("advancements." + advancement.id().getPath().replace("/", ".") + ".description"); - - message = message - //#if MC >= 12003 - .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(owner.getDisplayName()).getString())) - //#else - //$$ .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(owner.getDisplayName()).getString())) - //#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); - - CHANNEL.sendMessage(message).queue(); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, false, null, message); - } - } - } -} diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java new file mode 100644 index 00000000..b7094033 --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java @@ -0,0 +1,30 @@ +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; +import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.advancements.AdvancementProgress; +import net.minecraft.server.PlayerAdvancements; +import net.minecraft.server.level.ServerPlayer; +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.CallbackInfoReturnable; + +/** + * @author Xujiayao + */ +@Mixin(PlayerAdvancements.class) +public abstract class MixinPlayerAdvancements { + + @Shadow + private ServerPlayer player; + + @Shadow + public abstract AdvancementProgress getOrStartProgress(AdvancementHolder advancementHolder); + + @Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = At.Shift.AFTER)) + private void award(AdvancementHolder advancementHolder, String string, CallbackInfoReturnable cir) { + MinecraftEvents.PLAYER_ADVANCEMENT.invoker().advancement(player, advancementHolder, getOrStartProgress(advancementHolder).isDone()); + } +} From 6a43f8385598b68ce00b9eb013cfa35f938bb7e1 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 18:06:40 +0800 Subject: [PATCH 08/36] =?UTF-8?q?=E6=B5=8B=E8=AF=95GitHub=20Actions?= =?UTF-8?q?=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/mcdiscordchat.mixins.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/resources/mcdiscordchat.mixins.json b/src/main/resources/mcdiscordchat.mixins.json index b87eabb1..d2221f43 100644 --- a/src/main/resources/mcdiscordchat.mixins.json +++ b/src/main/resources/mcdiscordchat.mixins.json @@ -3,11 +3,9 @@ "package": "com.xujiayao.mcdiscordchat.minecraft.mixins", "compatibilityLevel": "JAVA_17", "mixins": [ - "MixinLanguage", - "MixinPlayerAdvancementTracker", - "MixinPlayerManager", - "MixinServerPlayerEntity", - "MixinServerPlayNetworkHandler" + "MixinPlayerAdvancements", + "MixinPlayerList", + "MixinServerPlayer" ], "injectors": { "defaultRequire": 1 From 9b307ac208879956c85d78e9e0f02ed5008e0a16 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 18:10:11 +0800 Subject: [PATCH 09/36] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/mixins/MixinLanguage.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java deleted file mode 100644 index 98e6d8d2..00000000 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java +++ /dev/null @@ -1,13 +0,0 @@ -//#if MC >= 11900 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import net.minecraft.util.Language; -import org.spongepowered.asm.mixin.Mixin; - -/** - * @author Xujiayao - */ -@Mixin(Language.class) -public abstract class MixinLanguage { -} -//#endif \ No newline at end of file From e529721e96ce3874837eb3a80d6afa705c66432b Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 20:45:57 +0800 Subject: [PATCH 10/36] =?UTF-8?q?=E5=A4=84=E7=90=86=20Message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 157 +++++++++ .../minecraft/MinecraftEvents.java | 16 + .../MixinServerGamePacketListenerImpl.java | 36 ++ .../mixins/MixinServerPlayNetworkHandler.java | 320 ------------------ src/main/resources/mcdiscordchat.mixins.json | 1 + 5 files changed, 210 insertions(+), 320 deletions(-) create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java delete mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 4f6aecea..08644a58 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -1,15 +1,39 @@ package com.xujiayao.mcdiscordchat.minecraft; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.xujiayao.mcdiscordchat.utils.MarkdownParser; import com.xujiayao.mcdiscordchat.utils.Translations; import com.xujiayao.mcdiscordchat.utils.Utils; +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.fellbaum.jemoji.EmojiManager; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; import net.minecraft.world.level.GameRules; +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 java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import static com.xujiayao.mcdiscordchat.Main.CHANNEL; import static com.xujiayao.mcdiscordchat.Main.CONFIG; +import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; +import static com.xujiayao.mcdiscordchat.Main.JDA; +import static com.xujiayao.mcdiscordchat.Main.LOGGER; import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; +import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; /** * @author Xujiayao @@ -17,6 +41,98 @@ public class MinecraftEventListener { public static void init() { + MinecraftEvents.PLAYER_MESSAGE.register((player, playerChatMessage) -> { + String contentToDiscord = playerChatMessage.decoratedContent().getString(); + String contentToMinecraft = playerChatMessage.decoratedContent().getString(); + + if (StringUtils.countMatches(contentToDiscord, ":") >= 2) { + String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":"); + for (String emojiName : emojiNames) { + List emojis = JDA.getEmojisByName(emojiName, true); + if (!emojis.isEmpty()) { + contentToDiscord = StringUtils.replaceIgnoreCase(contentToDiscord, (":" + emojiName + ":"), emojis.get(0).getAsMention()); + contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, (":" + emojiName + ":"), (ChatFormatting.YELLOW + ":" + emojiName + ":" + ChatFormatting.RESET)); + } else if (EmojiManager.getByAlias(emojiName).isPresent()) { + contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, (":" + emojiName + ":"), (ChatFormatting.YELLOW + ":" + emojiName + ":" + ChatFormatting.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 = ChatFormatting.YELLOW + "@" + member.getEffectiveName() + ChatFormatting.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 = ChatFormatting.YELLOW + "@" + role.getName() + ChatFormatting.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", ChatFormatting.YELLOW + "@everyone" + ChatFormatting.RESET); + contentToMinecraft = StringUtils.replaceIgnoreCase(contentToMinecraft, "@here", ChatFormatting.YELLOW + "@here" + ChatFormatting.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\":\"\",\"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.broadcastChatMessages) { + sendDiscordMessage(contentToDiscord, Objects.requireNonNull(player.getDisplayName()).getString(), (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString())); + if (CONFIG.multiServer.enable) { + MULTI_SERVER.sendMessage(false, true, false, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : playerChatMessage.decoratedContent().getString()); + } + } + + if (CONFIG.generic.formatChatMessages) { + return Optional.ofNullable(Component.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]")); + } else { + return Optional.empty(); + } + }); + MinecraftEvents.PLAYER_ADVANCEMENT.register((player, advancementHolder, isDone) -> { if (CONFIG.generic.announceAdvancements && isDone @@ -53,6 +169,7 @@ public static void init() { }); // TODO Server /say + // avatar_url = JDA.getSelfUser().getAvatarUrl() MinecraftEvents.PLAYER_JOIN.register(player -> { Utils.setBotActivity(); @@ -80,4 +197,44 @@ public static void init() { } }); } + + private static void sendDiscordMessage(String content, String username, String avatar_url) { + if (!CONFIG.generic.useWebhook) { + if (CONFIG.multiServer.enable) { + CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhookForMultiServer") + .replace("%server%", CONFIG.multiServer.name) + .replace("%name%", username) + .replace("%message%", content)).queue(); + } else { + CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") + .replace("%name%", username) + .replace("%message%", content)).queue(); + } + } else { + JsonObject body = new JsonObject(); + body.addProperty("content", content); + body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + username) : username)); + body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", avatar_url)); + + 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(); + + ExecutorService executor = Executors.newFixedThreadPool(1); + executor.submit(() -> { + try { + Response response = HTTP_CLIENT.newCall(request).execute(); + response.close(); + } catch (Exception e) { + LOGGER.error(ExceptionUtils.getStackTrace(e)); + } + }); + executor.shutdown(); + } + } } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index d3a48b9a..4c613053 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -3,14 +3,26 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; +import java.util.Optional; + /** * @author Xujiayao */ public interface MinecraftEvents { + Event PLAYER_MESSAGE = EventFactory.createArrayBacked(PlayerMessage.class, callbacks -> (player, playerChatMessage) -> { + Optional result = Optional.empty(); + for (PlayerMessage callback : callbacks) { + result = callback.message(player, playerChatMessage); + } + return result; + }); + Event PLAYER_ADVANCEMENT = EventFactory.createArrayBacked(PlayerAdvancement.class, callbacks -> (player, advancementHolder, isDone) -> { for (PlayerAdvancement callback : callbacks) { callback.advancement(player, advancementHolder, isDone); @@ -35,6 +47,10 @@ public interface MinecraftEvents { } }); + interface PlayerMessage { + Optional message(ServerPlayer player, PlayerChatMessage playerChatMessage); + } + interface PlayerAdvancement { void advancement(ServerPlayer player, AdvancementHolder advancementHolder, boolean isDone); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java new file mode 100644 index 00000000..d2a9d7c5 --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -0,0 +1,36 @@ +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; +import net.minecraft.network.chat.ChatType; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +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 java.util.Optional; + +import static com.xujiayao.mcdiscordchat.Main.SERVER; + +/** + * @author Xujiayao + */ +@Mixin(ServerGamePacketListenerImpl.class) +public class MixinServerGamePacketListenerImpl { + + @Shadow + private ServerPlayer player; + + @Inject(method = "broadcastChatMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V"), cancellable = true) + private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackInfo ci) { + Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage); + if (result.isPresent()) { + SERVER.getPlayerList().broadcastChatMessage(playerChatMessage.withUnsignedContent(result.get()), this.player, ChatType.bind(ChatType.CHAT, player)); + ci.cancel(); + } + } +} diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index 1621ef3a..00000000 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,320 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; -import com.xujiayao.mcdiscordchat.utils.Translations; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.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 filterText(String text); - - @Shadow - public abstract Optional validateMessage(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 optional = validateMessage(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 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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.Serialization.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 completableFuture = filterText(signedMessage.getSignedContent()); - Text text = server.getMessageDecorator().decorate(player, signedMessage.getContent()); - messageChainTaskQueue.append(completableFuture, (filtered) -> { - SignedMessage signedMessage2 = signedMessage.withUnsignedContent(text).withFilterMask(filtered.mask()); - handleDecoratedMessage(signedMessage2); - }); - }); - } - - if (CONFIG.generic.broadcastChatMessages) { - sendMessage(contentToDiscord, false); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, Objects.requireNonNull(player.getDisplayName()).getString(), 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 optional = validateMessage(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("<" + Objects.requireNonNull(player.getDisplayName()).getString() + "> " + 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.getDisplayName().getString(), 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%", Objects.requireNonNull(player.getDisplayName()).getString()) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", Objects.requireNonNull(player.getDisplayName()).getString()) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + Objects.requireNonNull(player.getDisplayName()).getString()) : Objects.requireNonNull(player.getDisplayName()).getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } - - private boolean hasIllegalCharacter(String message) { - for (int i = 0; i < message.length(); ++i) { - if (!SharedConstants.isValidChar(message.charAt(i))) { - return true; - } - } - - return false; - } -} diff --git a/src/main/resources/mcdiscordchat.mixins.json b/src/main/resources/mcdiscordchat.mixins.json index d2221f43..7c38e246 100644 --- a/src/main/resources/mcdiscordchat.mixins.json +++ b/src/main/resources/mcdiscordchat.mixins.json @@ -5,6 +5,7 @@ "mixins": [ "MixinPlayerAdvancements", "MixinPlayerList", + "MixinServerGamePacketListenerImpl", "MixinServerPlayer" ], "injectors": { From 91611d8974233ac548a5d0b6d5dc8cb100a42588 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 22:31:17 +0800 Subject: [PATCH 11/36] =?UTF-8?q?=E7=AE=80=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/mixins/MixinServerGamePacketListenerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index d2a9d7c5..d599859c 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -25,7 +25,7 @@ public class MixinServerGamePacketListenerImpl { @Shadow private ServerPlayer player; - @Inject(method = "broadcastChatMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V"), cancellable = true) + @Inject(method = "broadcastChatMessage", at = @At("HEAD"), cancellable = true) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackInfo ci) { Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage); if (result.isPresent()) { From 13741ef7bd7a301146fca70cf858d59846e77fe4 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 22:54:57 +0800 Subject: [PATCH 12/36] =?UTF-8?q?=E5=A4=84=E7=90=86=20Command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 37 ++++++++++++++++++- .../minecraft/MinecraftEvents.java | 12 ++++++ .../MixinServerGamePacketListenerImpl.java | 7 ++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 08644a58..a32093c8 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -12,6 +12,7 @@ import net.fellbaum.jemoji.EmojiManager; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.level.GameRules; import okhttp3.MediaType; import okhttp3.Request; @@ -32,7 +33,10 @@ import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; import static com.xujiayao.mcdiscordchat.Main.JDA; import static com.xujiayao.mcdiscordchat.Main.LOGGER; +import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; +import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; +import static com.xujiayao.mcdiscordchat.Main.SERVER; import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; /** @@ -120,7 +124,7 @@ public static void init() { } if (CONFIG.generic.broadcastChatMessages) { - sendDiscordMessage(contentToDiscord, Objects.requireNonNull(player.getDisplayName()).getString(), (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString())); + sendDiscordMessage(contentToDiscord, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); if (CONFIG.multiServer.enable) { MULTI_SERVER.sendMessage(false, true, false, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : playerChatMessage.decoratedContent().getString()); } @@ -133,6 +137,35 @@ public static void init() { } }); + MinecraftEvents.PLAYER_COMMAND.register((player, packet) -> { + String input = "/" + packet.command(); + + for (String command : CONFIG.generic.excludedCommands) { + if (input.startsWith(command + " ")) { + 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) { + MutableComponent message = Component.literal("<" + Objects.requireNonNull(player.getDisplayName()).getString() + "> " + input); + + SERVER.getPlayerList().getPlayers().forEach( + player1 -> player1.displayClientMessage(message, false)); + SERVER.sendSystemMessage(message); + + sendDiscordMessage(MarkdownSanitizer.escape(input), Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); + if (CONFIG.multiServer.enable) { + MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), MarkdownSanitizer.escape(input)); + } + } + }); + MinecraftEvents.PLAYER_ADVANCEMENT.register((player, advancementHolder, isDone) -> { if (CONFIG.generic.announceAdvancements && isDone @@ -214,7 +247,7 @@ private static void sendDiscordMessage(String content, String username, String a JsonObject body = new JsonObject(); body.addProperty("content", content); body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + username) : username)); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", avatar_url)); + body.addProperty("avatar_url", avatar_url); JsonObject allowedMentions = new JsonObject(); allowedMentions.add("parse", new Gson().toJsonTree(CONFIG.generic.allowedMentions).getAsJsonArray()); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index 4c613053..e1716e4e 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -5,6 +5,7 @@ import net.minecraft.advancements.AdvancementHolder; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.network.protocol.game.ServerboundChatCommandPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; @@ -23,6 +24,12 @@ public interface MinecraftEvents { return result; }); + Event PLAYER_COMMAND = EventFactory.createArrayBacked(PlayerCommand.class, callbacks -> (player, packet) -> { + for (PlayerCommand callback : callbacks) { + callback.command(player, packet); + } + }); + Event PLAYER_ADVANCEMENT = EventFactory.createArrayBacked(PlayerAdvancement.class, callbacks -> (player, advancementHolder, isDone) -> { for (PlayerAdvancement callback : callbacks) { callback.advancement(player, advancementHolder, isDone); @@ -51,6 +58,11 @@ interface PlayerMessage { Optional message(ServerPlayer player, PlayerChatMessage playerChatMessage); } + interface PlayerCommand { + void command(ServerPlayer player, ServerboundChatCommandPacket packet); + } + + interface PlayerAdvancement { void advancement(ServerPlayer player, AdvancementHolder advancementHolder, boolean isDone); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index d599859c..20f476c2 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -3,7 +3,9 @@ import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.LastSeenMessages; import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.network.protocol.game.ServerboundChatCommandPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import org.spongepowered.asm.mixin.Mixin; @@ -33,4 +35,9 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI ci.cancel(); } } + + @Inject(method = "performChatCommand", at = @At("HEAD"), cancellable = true) + private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, LastSeenMessages lastSeenMessages, CallbackInfo ci) { + MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket); + } } From b209913d2031977967892b39793889125105150f Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 8 Feb 2024 23:13:09 +0800 Subject: [PATCH 13/36] =?UTF-8?q?=E5=A4=84=E7=90=86=20Server=20/say=20mess?= =?UTF-8?q?age?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 7 +++++++ .../mcdiscordchat/minecraft/MinecraftEvents.java | 11 +++++++++++ .../minecraft/mixins/MixinPlayerList.java | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index a32093c8..605714ef 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -45,6 +45,13 @@ public class MinecraftEventListener { public static void init() { + MinecraftEvents.SERVER_MESSAGE.register((playerChatMessage, commandSourceStack) -> { + sendDiscordMessage(playerChatMessage.decoratedContent().getString(), commandSourceStack.getDisplayName().getString(), JDA.getSelfUser().getAvatarUrl()); + if (CONFIG.multiServer.enable) { + MULTI_SERVER.sendMessage(false, true, false, commandSourceStack.getDisplayName().getString(), playerChatMessage.decoratedContent().getString()); + } + }); + MinecraftEvents.PLAYER_MESSAGE.register((player, playerChatMessage) -> { String contentToDiscord = playerChatMessage.decoratedContent().getString(); String contentToMinecraft = playerChatMessage.decoratedContent().getString(); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index e1716e4e..6a95ac35 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -3,6 +3,7 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.network.protocol.game.ServerboundChatCommandPacket; @@ -16,6 +17,12 @@ */ public interface MinecraftEvents { + Event SERVER_MESSAGE = EventFactory.createArrayBacked(ServerMessage.class, callbacks -> (playerChatMessage, commandSourceStack) -> { + for (ServerMessage callback : callbacks) { + callback.message(playerChatMessage, commandSourceStack); + } + }); + Event PLAYER_MESSAGE = EventFactory.createArrayBacked(PlayerMessage.class, callbacks -> (player, playerChatMessage) -> { Optional result = Optional.empty(); for (PlayerMessage callback : callbacks) { @@ -54,6 +61,10 @@ public interface MinecraftEvents { } }); + interface ServerMessage { + void message(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack); + } + interface PlayerMessage { Optional message(ServerPlayer player, PlayerChatMessage playerChatMessage); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 9d0a6246..3e848210 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -1,7 +1,10 @@ package com.xujiayao.mcdiscordchat.minecraft.mixins; import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; +import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.Connection; +import net.minecraft.network.chat.ChatType; +import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.players.PlayerList; @@ -16,6 +19,11 @@ @Mixin(PlayerList.class) public class MixinPlayerList { + @Inject(method = "broadcastChatMessage", at = @At("HEAD")) + private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack, ChatType.Bound bound, CallbackInfo ci) { + MinecraftEvents.SERVER_MESSAGE.invoker().message(playerChatMessage, commandSourceStack); + } + @Inject(method = "placeNewPlayer", at = @At("RETURN")) private void placeNewPlayer(Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { MinecraftEvents.PLAYER_JOIN.invoker().join(serverPlayer); From 2183c64a621adb80b70beb2fe26ffffce0fe576a Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Fri, 9 Feb 2024 01:57:41 +0800 Subject: [PATCH 14/36] =?UTF-8?q?=E5=A4=9A=E7=89=88=E6=9C=AC=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E8=A6=81=E6=B1=82=E5=86=99=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcdiscordchat/minecraft/mixins/MixinPlayerList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 3e848210..5a9d061f 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -19,7 +19,7 @@ @Mixin(PlayerList.class) public class MixinPlayerList { - @Inject(method = "broadcastChatMessage", at = @At("HEAD")) + @Inject(method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/commands/CommandSourceStack;Lnet/minecraft/network/chat/ChatType$Bound;)V", at = @At("HEAD")) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack, ChatType.Bound bound, CallbackInfo ci) { MinecraftEvents.SERVER_MESSAGE.invoker().message(playerChatMessage, commandSourceStack); } From dc96afc03a3d69e121d8691cfcf0fde51ed42fa3 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Fri, 9 Feb 2024 16:09:24 +0800 Subject: [PATCH 15/36] CommandOutput -> CommandSource --- .../{DiscordCommandOutput.java => DiscordCommandSource.java} | 4 ++-- .../xujiayao/mcdiscordchat/discord/DiscordEventListener.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/com/xujiayao/mcdiscordchat/discord/{DiscordCommandOutput.java => DiscordCommandSource.java} (91%) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java similarity index 91% rename from src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java rename to src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java index 51eb1d9a..aaad3ba4 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandOutput.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java @@ -10,13 +10,13 @@ /** * @author Xujiayao */ -public class DiscordCommandOutput implements CommandSource { +public class DiscordCommandSource implements CommandSource { private final SlashCommandInteractionEvent e; private StringBuilder output = new StringBuilder("```\n"); private long lastOutputMillis = 0; - public DiscordCommandOutput(SlashCommandInteractionEvent e) { + public DiscordCommandSource(SlashCommandInteractionEvent e) { this.e = e; } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java index 9e74016a..432affd7 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java @@ -135,7 +135,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.executingCommand")) .submit() .whenComplete((v, ex) -> { - CommandSourceStack source = new CommandSourceStack(new DiscordCommandOutput(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", Component.literal("MC-Discord-Chat"), SERVER, null); + CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", Component.literal("MC-Discord-Chat"), SERVER, null); ParseResults results = SERVER.getCommands().getDispatcher().parse(command, source); SERVER.getCommands().performCommand(results, command); }); From d6845a8a99012789463ebedd8ab836b6cf4c767d Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Fri, 9 Feb 2024 16:16:01 +0800 Subject: [PATCH 16/36] =?UTF-8?q?=E4=BD=BF=E7=94=A8Carpet=E6=B3=95?= =?UTF-8?q?=E8=8E=B7=E5=8F=96TPS=E5=92=8CMSPT=EF=BC=881.20.3+=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relates to #217 --- .../xujiayao/mcdiscordchat/utils/Utils.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java index c83213e5..7419aa8a 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java @@ -15,9 +15,12 @@ import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.DetectedVersion; +import net.minecraft.server.ServerTickRateManager; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.UserWhiteList; import net.minecraft.server.players.UserWhiteListEntry; +import net.minecraft.util.TimeUtil; +import net.minecraft.util.Tuple; import okhttp3.CacheControl; import okhttp3.Request; import okhttp3.Response; @@ -408,10 +411,10 @@ public static String getInfoCommandMessage() { } // Server TPS - message.append(Translations.translate("utils.utils.gicMessage.serverTps", String.format("%.2f", SERVER.tickRateManager().tickrate()))); + message.append(Translations.translate("utils.utils.gicMessage.serverTps", String.format("%.2f", getTickInfo().getA()))); // Server MSPT - message.append(Translations.translate("utils.utils.gicMessage.serverMspt", String.format("%.2f", SERVER.getCurrentSmoothedTickTime()))); + message.append(Translations.translate("utils.utils.gicMessage.serverMspt", String.format("%.2f", getTickInfo().getB()))); // Server used memory message.append(Translations.translate("utils.utils.gicMessage.serverUsedMemory", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024, Runtime.getRuntime().totalMemory() / 1024 / 1024)); @@ -512,7 +515,7 @@ public static void initMsptMonitor() { MSPT_MONITOR_TIMER.schedule(new TimerTask() { @Override public void run() { - double mspt = SERVER.getCurrentSmoothedTickTime(); + double mspt = getTickInfo().getB(); if (mspt > CONFIG.generic.msptLimit) { String message = Translations.translateMessage("message.highMspt") @@ -574,4 +577,17 @@ public void run() { } }, 3600000, 21600000); } + + private static Tuple getTickInfo() { + ServerTickRateManager manager = SERVER.tickRateManager(); + + double mspt = ((double) SERVER.getAverageTickTimeNanos()) / TimeUtil.NANOSECONDS_PER_MILLISECOND; + + double tps = 1000.0D / Math.max(manager.isSprinting() ? 0.0 : manager.millisecondsPerTick(), mspt); + if (manager.isFrozen()) { + tps = 0; + } + + return new Tuple<>(tps, mspt); + } } From e0742e09e65a1fd14edb47101141c6afeb8eb467 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Fri, 9 Feb 2024 23:04:38 +0800 Subject: [PATCH 17/36] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=B7=B2=E5=AE=8C?= =?UTF-8?q?=E6=88=90TODO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcdiscordchat/minecraft/MinecraftEventListener.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 605714ef..774bff78 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -208,9 +208,6 @@ public static void init() { } }); - // TODO Server /say - // avatar_url = JDA.getSelfUser().getAvatarUrl() - MinecraftEvents.PLAYER_JOIN.register(player -> { Utils.setBotActivity(); From 304a7a2eb8d4ebf59ecceb28e493d7184995c542 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Fri, 9 Feb 2024 23:11:21 +0800 Subject: [PATCH 18/36] Compat TODO Relates to #217 --- src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java index 7419aa8a..9cc7ceb8 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java @@ -15,7 +15,9 @@ import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.DetectedVersion; +//#if MC > 12002 import net.minecraft.server.ServerTickRateManager; +//#endif import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.UserWhiteList; import net.minecraft.server.players.UserWhiteListEntry; @@ -579,6 +581,7 @@ public void run() { } private static Tuple getTickInfo() { + //#if MC > 12002 ServerTickRateManager manager = SERVER.tickRateManager(); double mspt = ((double) SERVER.getAverageTickTimeNanos()) / TimeUtil.NANOSECONDS_PER_MILLISECOND; @@ -587,6 +590,11 @@ private static Tuple getTickInfo() { if (manager.isFrozen()) { tps = 0; } + //#else + //$$ // TODO Compat TPS & MSPT (Issue #217) + //$$ double tps = 0; + //$$ double mspt = 0; + //#endif return new Tuple<>(tps, mspt); } From 04c0f01d9b1c23e1cc4f7c47ccd2bab2fdf9145c Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Fri, 9 Feb 2024 23:11:39 +0800 Subject: [PATCH 19/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.20.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- settings.gradle | 2 +- .../mixins/MixinServerPlayNetworkHandler.java | 323 ------------------ 3 files changed, 3 insertions(+), 326 deletions(-) delete mode 100644 versions/1.20.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java diff --git a/build.gradle b/build.gradle index c6241c22..c55a0287 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ preprocess { // def mc1193 = createNode("1.19.3", 1_19_03, "mojang") // def mc1194 = createNode("1.19.4", 1_19_04, "mojang") // def mc1201 = createNode("1.20.1", 1_20_01, "mojang") -// def mc1202 = createNode("1.20.2", 1_20_02, "mojang") + def mc1202 = createNode("1.20.2", 1_20_02, "mojang") def mc1204 = createNode("1.20.4", 1_20_04, "mojang") // mc1152.link(mc1165, null) @@ -25,5 +25,5 @@ preprocess { // mc1193.link(mc1194, null) // mc1194.link(mc1201, null) // mc1201.link(mc1202, null) -// mc1202.link(mc1204, null) + mc1202.link(mc1204, null) } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 4c27842f..721f9301 100644 --- a/settings.gradle +++ b/settings.gradle @@ -33,7 +33,7 @@ def versions = Arrays.asList( // "1.19.3", // "1.19.4", // "1.20.1", -// "1.20.2", + "1.20.2", "1.20.4" ) for (String version : versions) { diff --git a/versions/1.20.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/versions/1.20.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index e570a011..00000000 --- a/versions/1.20.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,323 +0,0 @@ -//#if MC >= 12002 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; -import com.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 java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.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 filterText(String text); - - @Shadow - public abstract Optional 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 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 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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 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.getDisplayName().getString(), 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 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.getDisplayName().getString() + "> " + 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.getDisplayName().getString(), 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.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", player.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getDisplayName().getString()) : player.getDisplayName().getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } - - private boolean hasIllegalCharacter(String message) { - for (int i = 0; i < message.length(); ++i) { - if (!SharedConstants.isValidChar(message.charAt(i))) { - return true; - } - } - - return false; - } -} -//#endif \ No newline at end of file From 285961e622582525b0dc6738e3a5562cfa7ee64a Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 01:02:10 +0800 Subject: [PATCH 20/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.20.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- settings.gradle | 2 +- .../minecraft/MinecraftEventListener.java | 22 +- .../minecraft/mixins/MixinPlayerList.java | 6 + .../xujiayao/mcdiscordchat/utils/Utils.java | 4 + .../mixins/MixinPlayerAdvancementTracker.java | 65 ---- .../minecraft/mixins/MixinPlayerManager.java | 145 -------- .../mixins/MixinServerPlayNetworkHandler.java | 325 ------------------ versions/mapping-1.20.1-1.20.2.txt | 2 + 9 files changed, 32 insertions(+), 543 deletions(-) delete mode 100644 versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java delete mode 100644 versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java delete mode 100644 versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java create mode 100644 versions/mapping-1.20.1-1.20.2.txt diff --git a/build.gradle b/build.gradle index c55a0287..f41395ee 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ preprocess { // def mc1192 = createNode("1.19.2", 1_19_02, "mojang") // def mc1193 = createNode("1.19.3", 1_19_03, "mojang") // def mc1194 = createNode("1.19.4", 1_19_04, "mojang") -// def mc1201 = createNode("1.20.1", 1_20_01, "mojang") + def mc1201 = createNode("1.20.1", 1_20_01, "mojang") def mc1202 = createNode("1.20.2", 1_20_02, "mojang") def mc1204 = createNode("1.20.4", 1_20_04, "mojang") @@ -24,6 +24,6 @@ preprocess { // mc1192.link(mc1193, null) // mc1193.link(mc1194, null) // mc1194.link(mc1201, null) -// mc1201.link(mc1202, null) + mc1201.link(mc1202, file("versions/mapping-1.20.1-1.20.2.txt")) mc1202.link(mc1204, null) } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 721f9301..0b96d278 100644 --- a/settings.gradle +++ b/settings.gradle @@ -32,7 +32,7 @@ def versions = Arrays.asList( // "1.19.2", // "1.19.3", // "1.19.4", -// "1.20.1", + "1.20.1", "1.20.2", "1.20.4" ) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 774bff78..48c59022 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -11,6 +11,7 @@ import net.dv8tion.jda.api.utils.MarkdownSanitizer; import net.fellbaum.jemoji.EmojiManager; import net.minecraft.ChatFormatting; +import net.minecraft.advancements.DisplayInfo; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.level.GameRules; @@ -174,14 +175,25 @@ public static void init() { }); MinecraftEvents.PLAYER_ADVANCEMENT.register((player, advancementHolder, isDone) -> { + //#if MC >= 12002 + if (advancementHolder.value().display().isEmpty()) { + return; + } + DisplayInfo display = advancementHolder.value().display().get(); + //#else + //$$ if (advancementHolder.getDisplay() == null) { + //$$ return; + //$$ } + //$$ DisplayInfo display = advancementHolder.getDisplay(); + //#endif + if (CONFIG.generic.announceAdvancements && isDone - && advancementHolder.value().display().isPresent() - && advancementHolder.value().display().get().shouldAnnounceChat() + && display.shouldAnnounceChat() && player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { String message = "null"; - switch (advancementHolder.value().display().get().getType()) { + switch (display.getType()) { case GOAL -> message = Translations.translateMessage("message.advancementGoal"); case TASK -> message = Translations.translateMessage("message.advancementTask"); case CHALLENGE -> message = Translations.translateMessage("message.advancementChallenge"); @@ -192,8 +204,8 @@ public static void init() { message = message .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString())) - .replace("%advancement%", title.contains("TranslateError") ? advancementHolder.value().display().get().getTitle().getString() : title) - .replace("%description%", description.contains("TranslateError") ? advancementHolder.value().display().get().getDescription().getString() : description); + .replace("%advancement%", title.contains("TranslateError") ? display.getTitle().getString() : title) + .replace("%description%", description.contains("TranslateError") ? display.getDescription().getString() : description); CHANNEL.sendMessage(message).queue(); if (CONFIG.multiServer.enable) { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 5a9d061f..1ace4aec 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -6,7 +6,9 @@ import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.server.level.ServerPlayer; +//#if MC >= 12002 import net.minecraft.server.network.CommonListenerCookie; +//#endif import net.minecraft.server.players.PlayerList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -25,7 +27,11 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSo } @Inject(method = "placeNewPlayer", at = @At("RETURN")) + //#if MC >= 12002 private void placeNewPlayer(Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { + //#else + //$$ private void placeNewPlayer(Connection connection, ServerPlayer serverPlayer, CallbackInfo ci) { + //#endif MinecraftEvents.PLAYER_JOIN.invoker().join(serverPlayer); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java index 9cc7ceb8..4a0257bf 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java @@ -408,7 +408,11 @@ public static String getInfoCommandMessage() { message.append(Translations.translate("utils.utils.gicMessage.noPlayersOnline")); } else { for (ServerPlayer player : onlinePlayers) { + //#if MC >= 12002 message.append("[").append(player.connection.latency()).append("ms] ").append(Objects.requireNonNull(player.getDisplayName()).getString()).append("\n"); + //#else + //$$ message.append("[").append(player.latency).append("ms] ").append(Objects.requireNonNull(player.getDisplayName()).getString()).append("\n"); + //#endif } } diff --git a/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java b/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java deleted file mode 100644 index bee2a10b..00000000 --- a/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancementTracker.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import net.dv8tion.jda.api.utils.MarkdownSanitizer; -import net.minecraft.advancement.Advancement; -import net.minecraft.advancement.AdvancementProgress; -import net.minecraft.advancement.PlayerAdvancementTracker; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.world.GameRules; -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.CallbackInfoReturnable; -import com.xujiayao.mcdiscordchat.utils.Translations; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; - -/** - * @author Xujiayao - */ -@Mixin(PlayerAdvancementTracker.class) -public abstract class MixinPlayerAdvancementTracker { - - @Shadow - private ServerPlayerEntity owner; - - @Shadow - public abstract AdvancementProgress getProgress(Advancement advancement); - - //#if MC >= 11904 - @Inject(method = "grantCriterion", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancement/PlayerAdvancementTracker;onStatusUpdate(Lnet/minecraft/advancement/Advancement;)V")) - //#else - //$$ @Inject(method = "grantCriterion", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancement/PlayerAdvancementTracker;updateDisplay(Lnet/minecraft/advancement/Advancement;)V")) - //#endif - private void grantCriterion(Advancement advancement, String criterionName, CallbackInfoReturnable cir) { - if (CONFIG.generic.announceAdvancements - && getProgress(advancement).isDone() - && advancement.getDisplay() != null - && advancement.getDisplay().shouldAnnounceToChat() - && owner.getWorld().getGameRules().getBoolean(GameRules.ANNOUNCE_ADVANCEMENTS)) { - String message = "null"; - - switch (advancement.getDisplay().getFrame()) { - case GOAL -> message = Translations.translateMessage("message.advancementGoal"); - case TASK -> message = Translations.translateMessage("message.advancementTask"); - case CHALLENGE -> message = Translations.translateMessage("message.advancementChallenge"); - } - - String title = Translations.translate("advancements." + advancement.getId().getPath().replace("/", ".") + ".title"); - String description = Translations.translate("advancements." + advancement.getId().getPath().replace("/", ".") + ".description"); - - message = message - .replace("%playerName%", MarkdownSanitizer.escape(owner.getDisplayName().getString())) - .replace("%advancement%", title.contains("TranslateError") ? advancement.getDisplay().getTitle().getString() : title) - .replace("%description%", description.contains("TranslateError") ? advancement.getDisplay().getDescription().getString() : description); - - CHANNEL.sendMessage(message).queue(); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, false, null, message); - } - } - } -} \ No newline at end of file diff --git a/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java b/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java deleted file mode 100644 index a8e0e514..00000000 --- a/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerManager.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import net.dv8tion.jda.api.utils.MarkdownSanitizer; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.message.MessageType; -//#if MC >= 11900 -import net.minecraft.network.message.SignedMessage; -//#endif -//#if MC == 11900 -//$$ import net.minecraft.util.registry.RegistryKey; -//#endif -import net.minecraft.server.PlayerManager; -import net.minecraft.server.command.ServerCommandSource; -//#if MC == 11900 -//$$ import net.minecraft.server.filter.FilteredMessage; -//#endif -import net.minecraft.server.network.ServerPlayerEntity; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.xujiayao.mcdiscordchat.utils.Translations; -import com.xujiayao.mcdiscordchat.utils.Utils; - -//#if MC == 11900 -//$$ import java.util.Objects; -//#endif - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(PlayerManager.class) -public class MixinPlayerManager { - - //#if MC >= 11903 - @Inject(method = "broadcast(Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/network/message/MessageType$Parameters;)V", at = @At("RETURN")) - private void broadcast(SignedMessage message, ServerCommandSource source, MessageType.Parameters params, CallbackInfo ci) { - sendMessage(message.getSignedContent(), source.getName()); - } - //#elseif MC >= 11901 - //$$ @Inject(method = "broadcast(Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/network/message/MessageType$Parameters;)V", at = @At("RETURN")) - //$$ private void broadcast(SignedMessage message, ServerCommandSource source, MessageType.Parameters params, CallbackInfo ci) { - //$$ sendMessage(message.getSignedContent().plain(), source.getName()); - //$$ } - //#elseif MC >= 11900 - //$$ @Inject(method = "broadcast(Lnet/minecraft/server/filter/FilteredMessage;Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/util/registry/RegistryKey;)V", at = @At("RETURN")) - //$$ private void broadcast(FilteredMessage message, ServerCommandSource source, RegistryKey typeKey, CallbackInfo ci) { - //$$ sendMessage(Objects.requireNonNull(message.filtered()).signedContent().getString(), source.getName()); - //$$ } - //#endif - // This feature has been removed in versions 1.18.2 and below due to compatibility issues (#197) - - private void sendMessage(String content, String username) { - if (CONFIG.generic.broadcastChatMessages) { - if (!CONFIG.generic.useWebhook) { - if (CONFIG.multiServer.enable) { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhookForMultiServer") - .replace("%server%", CONFIG.multiServer.name) - .replace("%name%", username) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", username) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + username) : username)); - body.addProperty("avatar_url", JDA.getSelfUser().getAvatarUrl()); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, username, content); - } - } - } - - @Inject(method = "onPlayerConnect", at = @At("RETURN")) - private void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) { - Utils.setBotActivity(); - - if (CONFIG.generic.announcePlayerJoinLeave) { - CHANNEL.sendMessage(Translations.translateMessage("message.joinServer") - .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))).queue(); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.joinServer") - .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); - } - } - } - - @Inject(method = "remove", at = @At("RETURN")) - private void remove(ServerPlayerEntity player, CallbackInfo ci) { - Utils.setBotActivity(); - - if (CONFIG.generic.announcePlayerJoinLeave) { - CHANNEL.sendMessage(Translations.translateMessage("message.leftServer") - .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))).queue(); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, false, false, null, Translations.translateMessage("message.leftServer") - .replace("%playerName%", MarkdownSanitizer.escape(player.getDisplayName().getString()))); - } - } - } -} - diff --git a/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index db55858d..00000000 --- a/versions/1.20.1/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,325 +0,0 @@ -//#if MC >= 11903 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -import net.minecraft.SharedConstants; -import net.minecraft.network.listener.ServerPlayPacketListener; -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.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.EntityTrackingListener; -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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; -import com.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 java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(ServerPlayNetworkHandler.class) -public abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener, ServerPlayPacketListener { - - @Shadow - private ServerPlayerEntity player; - - @Final - @Shadow - private MinecraftServer server; - - @Final - @Shadow - private MessageChainTaskQueue messageChainTaskQueue; - - @Shadow - public abstract void checkForSpam(); - - @Shadow - public abstract void disconnect(Text reason); - - @Shadow - public abstract CompletableFuture filterText(String text); - - @Shadow - public abstract Optional 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 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 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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 completableFuture = filterText(signedMessage.getSignedContent()); - CompletableFuture completableFuture2 = server.getMessageDecorator().decorate(player, signedMessage.getContent()); - messageChainTaskQueue.append(executor -> CompletableFuture.allOf(completableFuture, completableFuture2).thenAcceptAsync(void_ -> { - SignedMessage signedMessage2 = signedMessage.withUnsignedContent(completableFuture2.join()).withFilterMask(completableFuture.join().mask()); - handleDecoratedMessage(signedMessage2); - }, executor)); - }); - } - - if (CONFIG.generic.broadcastChatMessages) { - sendMessage(contentToDiscord, false); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), 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 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.getDisplayName().getString() + "> " + 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.getDisplayName().getString(), 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.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", player.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getDisplayName().getString()) : player.getDisplayName().getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } - - private boolean hasIllegalCharacter(String message) { - for (int i = 0; i < message.length(); ++i) { - if (!SharedConstants.isValidChar(message.charAt(i))) { - return true; - } - } - - return false; - } -} -//#endif \ No newline at end of file diff --git a/versions/mapping-1.20.1-1.20.2.txt b/versions/mapping-1.20.1-1.20.2.txt new file mode 100644 index 00000000..1af0ae5f --- /dev/null +++ b/versions/mapping-1.20.1-1.20.2.txt @@ -0,0 +1,2 @@ +net.minecraft.advancements.Advancement net.minecraft.advancements.AdvancementHolder +net.minecraft.advancements.Advancement getId() id() \ No newline at end of file From 5fccf6a94a58819d1a6fc7fc8bc2aa263500ed4b Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 01:13:23 +0800 Subject: [PATCH 21/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.19.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- settings.gradle | 2 +- .../minecraft/MinecraftCommands.java | 49 ++++++++++++++++--- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index f41395ee..19ed1446 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ preprocess { // def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") // def mc1192 = createNode("1.19.2", 1_19_02, "mojang") // def mc1193 = createNode("1.19.3", 1_19_03, "mojang") -// def mc1194 = createNode("1.19.4", 1_19_04, "mojang") + def mc1194 = createNode("1.19.4", 1_19_04, "mojang") def mc1201 = createNode("1.20.1", 1_20_01, "mojang") def mc1202 = createNode("1.20.2", 1_20_02, "mojang") def mc1204 = createNode("1.20.4", 1_20_04, "mojang") @@ -23,7 +23,7 @@ preprocess { // mc1190.link(mc1192, null) // mc1192.link(mc1193, null) // mc1193.link(mc1194, null) -// mc1194.link(mc1201, null) + mc1194.link(mc1201, null) mc1201.link(mc1202, file("versions/mapping-1.20.1-1.20.2.txt")) mc1202.link(mc1204, null) } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 0b96d278..703de93a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,7 +31,7 @@ def versions = Arrays.asList( // "compat_1.19" , // "1.19.2", // "1.19.3", -// "1.19.4", + "1.19.4", "1.20.1", "1.20.2", "1.20.4" diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java index bcc04f65..5442a60d 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java @@ -19,15 +19,30 @@ public class MinecraftCommands { public static void register(CommandDispatcher dispatcher) { dispatcher.register(literal("mcdc").executes(context -> { - context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); return 1; }) .then(literal("help").executes(context -> { - context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); return 1; })) .then(literal("info").executes(context -> { - context.getSource().sendSuccess(() -> Component.literal(Utils.getInfoCommandMessage()), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(Utils.getInfoCommandMessage()), false); return 1; })) .then(literal("stats") @@ -36,11 +51,21 @@ public static void register(CommandDispatcher dispatcher) { .executes(context -> { String type = StringArgumentType.getString(context, "type"); String name = StringArgumentType.getString(context, "name"); - context.getSource().sendSuccess(() -> Component.literal(Utils.getStatsCommandMessage(type, name)), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(Utils.getStatsCommandMessage(type, name)), false); return 1; })))) .then(literal("update").executes(context -> { - context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.checkUpdate(true))), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(MarkdownParser.parseMarkdown(Utils.checkUpdate(true))), false); return 1; })) .then(literal("whitelist") @@ -48,13 +73,23 @@ public static void register(CommandDispatcher dispatcher) { .then(argument("player", StringArgumentType.word()) .executes(context -> { String player = StringArgumentType.getString(context, "player"); - context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.whitelist(player))), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(MarkdownParser.parseMarkdown(Utils.whitelist(player))), false); return 1; }))) .then(literal("reload") .requires(source -> source.hasPermission(4)) .executes(context -> { - context.getSource().sendSuccess(() -> Component.literal(MarkdownParser.parseMarkdown(Utils.reload())), false); + //#if MC > 11904 + context.getSource().sendSuccess(() -> + //#else + //$$ context.getSource().sendSuccess( + //#endif + Component.literal(MarkdownParser.parseMarkdown(Utils.reload())), false); return 1; }))); } From 42f60967336b96370cef8e4f6ba25dda0a765ae0 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 01:18:06 +0800 Subject: [PATCH 22/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.19.3=EF=BC=88?= =?UTF-8?q?=E6=88=96=E8=AE=B8=E4=B8=8D=E9=9C=80=E8=A6=81=EF=BC=9F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++-- settings.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 19ed1446..30da0044 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ preprocess { // def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") // def mc1192 = createNode("1.19.2", 1_19_02, "mojang") -// def mc1193 = createNode("1.19.3", 1_19_03, "mojang") + def mc1193 = createNode("1.19.3", 1_19_03, "mojang") def mc1194 = createNode("1.19.4", 1_19_04, "mojang") def mc1201 = createNode("1.20.1", 1_20_01, "mojang") def mc1202 = createNode("1.20.2", 1_20_02, "mojang") @@ -22,7 +22,7 @@ preprocess { // mc1182.link(mc1190, null) // mc1190.link(mc1192, null) // mc1192.link(mc1193, null) -// mc1193.link(mc1194, null) + mc1193.link(mc1194, null) mc1194.link(mc1201, null) mc1201.link(mc1202, file("versions/mapping-1.20.1-1.20.2.txt")) mc1202.link(mc1204, null) diff --git a/settings.gradle b/settings.gradle index 703de93a..f89ea96e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -30,7 +30,7 @@ def versions = Arrays.asList( // "compat_1.18.2", // "compat_1.19" , // "1.19.2", -// "1.19.3", + "1.19.3", "1.19.4", "1.20.1", "1.20.2", From d60baa3aae66b39c2e7493bfe59713a1176a05a5 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 01:26:00 +0800 Subject: [PATCH 23/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.19.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- settings.gradle | 2 +- .../mixins/MixinServerPlayNetworkHandler.java | 314 ------------------ versions/mapping-1.19.2-1.19.3.txt | 1 + 4 files changed, 4 insertions(+), 317 deletions(-) delete mode 100644 versions/1.19.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java create mode 100644 versions/mapping-1.19.2-1.19.3.txt diff --git a/build.gradle b/build.gradle index 30da0044..55d04970 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ preprocess { // def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") // def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") -// def mc1192 = createNode("1.19.2", 1_19_02, "mojang") + def mc1192 = createNode("1.19.2", 1_19_02, "mojang") def mc1193 = createNode("1.19.3", 1_19_03, "mojang") def mc1194 = createNode("1.19.4", 1_19_04, "mojang") def mc1201 = createNode("1.20.1", 1_20_01, "mojang") @@ -21,7 +21,7 @@ preprocess { // mc1171.link(mc1182, null) // mc1182.link(mc1190, null) // mc1190.link(mc1192, null) -// mc1192.link(mc1193, null) + mc1192.link(mc1193, file("versions/mapping-1.19.2-1.19.3.txt")) mc1193.link(mc1194, null) mc1194.link(mc1201, null) mc1201.link(mc1202, file("versions/mapping-1.20.1-1.20.2.txt")) diff --git a/settings.gradle b/settings.gradle index f89ea96e..0bcac9d9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,7 +29,7 @@ def versions = Arrays.asList( // "compat_1.17.1", // "compat_1.18.2", // "compat_1.19" , -// "1.19.2", + "1.19.2", "1.19.3", "1.19.4", "1.20.1", diff --git a/versions/1.19.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/versions/1.19.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index 392ac56a..00000000 --- a/versions/1.19.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,314 +0,0 @@ -//#if MC >= 11901 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -import net.minecraft.SharedConstants; -import net.minecraft.network.message.FilterMask; -import net.minecraft.network.message.LastSeenMessageList; -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.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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; -import com.xujiayao.mcdiscordchat.utils.Translations; - -import java.time.Instant; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(ServerPlayNetworkHandler.class) -public abstract class MixinServerPlayNetworkHandler { - - @Shadow - private ServerPlayerEntity player; - - @Final - @Shadow - private MinecraftServer server; - - @Final - @Shadow - private MessageChainTaskQueue messageChainTaskQueue; - - @Shadow - public abstract void checkForSpam(); - - @Shadow - public abstract void disconnect(Text reason); - - @Shadow - public abstract boolean canAcceptMessage(SignedMessage message); - - @Shadow - public abstract boolean canAcceptMessage(String message, Instant timestamp, LastSeenMessageList.Acknowledgment acknowledgment); - - @Shadow - public abstract CompletableFuture filterText(String text); - - @Shadow - public abstract void handleCommandExecution(CommandExecutionC2SPacket packet); - - @Shadow - public abstract SignedMessage getSignedMessage(ChatMessageC2SPacket packet); - - @Shadow - public abstract void handleDecoratedMessage(SignedMessage message); - - @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 { - if (canAcceptMessage(packet.chatMessage(), packet.timestamp(), packet.acknowledgment())) { - String contentToDiscord = packet.chatMessage(); - String contentToMinecraft = packet.chatMessage(); - - if (StringUtils.countMatches(contentToDiscord, ":") >= 2) { - String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":"); - for (String emojiName : emojiNames) { - List 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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) { - SignedMessage signedMessage = getSignedMessage(packet); - server.getPlayerManager().broadcast(signedMessage.withUnsignedContent(Objects.requireNonNull(Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]"))), player, MessageType.params(MessageType.CHAT, player)); - } else { - server.submit(() -> { - SignedMessage signedMessage = getSignedMessage(packet); - if (canAcceptMessage(signedMessage)) { - messageChainTaskQueue.append(() -> { - CompletableFuture completableFuture = filterText(signedMessage.getSignedContent().plain()); - CompletableFuture completableFuture2 = server.getMessageDecorator().decorate(player, signedMessage); - return CompletableFuture.allOf(completableFuture, completableFuture2).thenAcceptAsync((void_) -> { - FilterMask filterMask = completableFuture.join().mask(); - SignedMessage signedMessage2 = completableFuture2.join().withFilterMask(filterMask); - handleDecoratedMessage(signedMessage2); - }, server); - }); - } - }); - } - - if (CONFIG.generic.broadcastChatMessages) { - sendMessage(contentToDiscord, false); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), 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 { - if (canAcceptMessage(packet.command(), packet.timestamp(), packet.acknowledgment())) { - server.submit(() -> { - handleCommandExecution(packet); - 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.getDisplayName().getString() + "> " + 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.getDisplayName().getString(), 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.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", player.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getDisplayName().getString()) : player.getDisplayName().getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } - - private boolean hasIllegalCharacter(String message) { - for (int i = 0; i < message.length(); ++i) { - if (!SharedConstants.isValidChar(message.charAt(i))) { - return true; - } - } - - return false; - } -} -//#endif \ No newline at end of file diff --git a/versions/mapping-1.19.2-1.19.3.txt b/versions/mapping-1.19.2-1.19.3.txt new file mode 100644 index 00000000..4569f24b --- /dev/null +++ b/versions/mapping-1.19.2-1.19.3.txt @@ -0,0 +1 @@ +net.minecraft.network.chat.PlayerChatMessage serverContent() decoratedContent() \ No newline at end of file From c870eb07ee353dcb662378693f5d0bf1fa26177f Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 01:49:07 +0800 Subject: [PATCH 24/36] =?UTF-8?q?PLAYER=5FCOMMAND=20=E6=94=B9=E4=B8=BA=20(?= =?UTF-8?q?player,=20command)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcdiscordchat/minecraft/MinecraftEventListener.java | 8 ++++---- .../xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java | 6 +++--- .../mixins/MixinServerGamePacketListenerImpl.java | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 48c59022..56b8e01e 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -145,11 +145,11 @@ public static void init() { } }); - MinecraftEvents.PLAYER_COMMAND.register((player, packet) -> { - String input = "/" + packet.command(); + MinecraftEvents.PLAYER_COMMAND.register((player, command) -> { + String input = "/" + command; - for (String command : CONFIG.generic.excludedCommands) { - if (input.startsWith(command + " ")) { + for (String excludedCommand : CONFIG.generic.excludedCommands) { + if (input.startsWith(excludedCommand + " ")) { return; } } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index 6a95ac35..479b25ae 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -31,9 +31,9 @@ public interface MinecraftEvents { return result; }); - Event PLAYER_COMMAND = EventFactory.createArrayBacked(PlayerCommand.class, callbacks -> (player, packet) -> { + Event PLAYER_COMMAND = EventFactory.createArrayBacked(PlayerCommand.class, callbacks -> (player, command) -> { for (PlayerCommand callback : callbacks) { - callback.command(player, packet); + callback.command(player, command); } }); @@ -70,7 +70,7 @@ interface PlayerMessage { } interface PlayerCommand { - void command(ServerPlayer player, ServerboundChatCommandPacket packet); + void command(ServerPlayer player, String command); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 20f476c2..1921178a 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -36,8 +36,8 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI } } - @Inject(method = "performChatCommand", at = @At("HEAD"), cancellable = true) + @Inject(method = "performChatCommand", at = @At("HEAD")) private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, LastSeenMessages lastSeenMessages, CallbackInfo ci) { - MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket); + MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket.command()); } } From b9f301d1fc52c8033e91f9e7c312c85d13a2beff Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 02:19:45 +0800 Subject: [PATCH 25/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- settings.gradle | 2 +- .../discord/DiscordEventListener.java | 4 + .../minecraft/mixins/MixinPlayerList.java | 14 + .../MixinServerGamePacketListenerImpl.java | 16 + .../mixins/MixinServerPlayNetworkHandler.java | 287 ------------------ 6 files changed, 37 insertions(+), 290 deletions(-) delete mode 100644 versions/compat_1.19/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java diff --git a/build.gradle b/build.gradle index 55d04970..4300f26d 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ preprocess { // def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") // def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") // def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") -// def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") + def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") def mc1192 = createNode("1.19.2", 1_19_02, "mojang") def mc1193 = createNode("1.19.3", 1_19_03, "mojang") def mc1194 = createNode("1.19.4", 1_19_04, "mojang") @@ -20,7 +20,7 @@ preprocess { // mc1165.link(mc1171, null) // mc1171.link(mc1182, null) // mc1182.link(mc1190, null) -// mc1190.link(mc1192, null) + mc1190.link(mc1192, null) mc1192.link(mc1193, file("versions/mapping-1.19.2-1.19.3.txt")) mc1193.link(mc1194, null) mc1194.link(mc1201, null) diff --git a/settings.gradle b/settings.gradle index 0bcac9d9..948b797e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -28,7 +28,7 @@ def versions = Arrays.asList( // "compat_1.16.5", // "compat_1.17.1", // "compat_1.18.2", -// "compat_1.19" , + "compat_1.19" , "1.19.2", "1.19.3", "1.19.4", diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java index 432affd7..9cb5cec2 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java @@ -136,8 +136,12 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { .submit() .whenComplete((v, ex) -> { CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", Component.literal("MC-Discord-Chat"), SERVER, null); + //#if MC > 11900 ParseResults results = SERVER.getCommands().getDispatcher().parse(command, source); SERVER.getCommands().performCommand(results, command); + //#else + //$$ SERVER.getCommands().performCommand(source, command); + //#endif }); } } else { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 1ace4aec..116ead07 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -5,10 +5,16 @@ import net.minecraft.network.Connection; import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.PlayerChatMessage; +//#if MC <= 11900 +//$$ import net.minecraft.resources.ResourceKey; +//#endif import net.minecraft.server.level.ServerPlayer; //#if MC >= 12002 import net.minecraft.server.network.CommonListenerCookie; //#endif +//#if MC <= 11900 +//$$ import net.minecraft.server.network.FilteredText; +//#endif import net.minecraft.server.players.PlayerList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -21,10 +27,18 @@ @Mixin(PlayerList.class) public class MixinPlayerList { + //#if MC > 11900 @Inject(method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/commands/CommandSourceStack;Lnet/minecraft/network/chat/ChatType$Bound;)V", at = @At("HEAD")) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack, ChatType.Bound bound, CallbackInfo ci) { MinecraftEvents.SERVER_MESSAGE.invoker().message(playerChatMessage, commandSourceStack); } + //#else + //$$ @Inject(method = "broadcastChatMessage", at = @At("HEAD")) + //$$ private void broadcastChatMessage(FilteredText filteredText, CommandSourceStack commandSourceStack, ResourceKey resourceKey, CallbackInfo ci) { + //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered(), commandSourceStack); + //$$ // TODO filtered() or raw() ? + //$$ } + //#endif @Inject(method = "placeNewPlayer", at = @At("RETURN")) //#if MC >= 12002 diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 1921178a..51b16474 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -3,10 +3,15 @@ import com.xujiayao.mcdiscordchat.minecraft.MinecraftEvents; import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; +//#if MC > 11900 import net.minecraft.network.chat.LastSeenMessages; +//#endif import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.network.protocol.game.ServerboundChatCommandPacket; import net.minecraft.server.level.ServerPlayer; +//#if MC <= 11900 +//$$ import net.minecraft.server.network.FilteredText; +//#endif import net.minecraft.server.network.ServerGamePacketListenerImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -31,13 +36,24 @@ public class MixinServerGamePacketListenerImpl { private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackInfo ci) { Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage); if (result.isPresent()) { + //#if MC > 11900 SERVER.getPlayerList().broadcastChatMessage(playerChatMessage.withUnsignedContent(result.get()), this.player, ChatType.bind(ChatType.CHAT, player)); + //#else + //$$ SERVER.getPlayerList().broadcastChatMessage(FilteredText.passThrough(playerChatMessage.withUnsignedContent(result.get())), this.player, ChatType.CHAT); + //#endif ci.cancel(); } } + //#if MC > 11900 @Inject(method = "performChatCommand", at = @At("HEAD")) private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, LastSeenMessages lastSeenMessages, CallbackInfo ci) { MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket.command()); } + //#else + //$$ @Inject(method = "handleChatCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)V")) + //$$ private void handleChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) { + //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket.command()); + //$$ } + //#endif } diff --git a/versions/compat_1.19/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/versions/compat_1.19/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index d5add593..00000000 --- a/versions/compat_1.19/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,287 +0,0 @@ -//#if MC >= 11900 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -import net.minecraft.SharedConstants; -import net.minecraft.network.NetworkThreadUtils; -import net.minecraft.network.listener.ServerPlayPacketListener; -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.command.ServerCommandSource; -import net.minecraft.server.filter.FilteredMessage; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.EntityTrackingListener; -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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; -import com.xujiayao.mcdiscordchat.utils.Translations; - -import java.time.Instant; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(ServerPlayNetworkHandler.class) -public abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener, ServerPlayPacketListener { - - @Shadow - private ServerPlayerEntity player; - - @Final - @Shadow - private MinecraftServer server; - - @Shadow - public abstract void checkForSpam(); - - @Shadow - public abstract void disconnect(Text reason); - - @Shadow - public abstract boolean canAcceptMessage(String message, Instant timestamp); - - @Shadow - public abstract void filterText(String text, Consumer> consumer); - - @Shadow - public abstract void handleMessage(ChatMessageC2SPacket packet, FilteredMessage message); - - @Inject(method = "onChatMessage", at = @At("HEAD"), cancellable = true) - private void onChatMessage(ChatMessageC2SPacket packet, CallbackInfo ci) { - if (hasIllegalCharacter(packet.getChatMessage())) { - disconnect(Text.translatable("multiplayer.disconnect.illegal_characters")); - } else { - if (canAcceptMessage(packet.getChatMessage(), packet.getTimestamp())) { - String contentToDiscord = packet.getChatMessage(); - String contentToMinecraft = packet.getChatMessage(); - - if (StringUtils.countMatches(contentToDiscord, ":") >= 2) { - String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":"); - for (String emojiName : emojiNames) { - List 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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) { - server.getPlayerManager().broadcast(FilteredMessage.permitted(SignedMessage.of(Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]"))), player, MessageType.CHAT); - } else { - filterText(packet.getChatMessage(), (message) -> handleMessage(packet, message)); - } - - if (CONFIG.generic.broadcastChatMessages) { - sendMessage(contentToDiscord, false); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : packet.getChatMessage()); - } - } - } - } - - 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 { - NetworkThreadUtils.forceMainThread(packet, this, player.getWorld()); - if (canAcceptMessage(packet.command(), packet.timestamp())) { - ServerCommandSource serverCommandSource = this.player.getCommandSource().withSigner(packet.createArgumentsSigner(this.player.getUuid())); - server.getCommandManager().execute(serverCommandSource, packet.command()); - 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.getDisplayName().getString() + "> " + 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.getDisplayName().getString(), 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.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } else { - CHANNEL.sendMessage(Translations.translateMessage("message.messageWithoutWebhook") - .replace("%name%", player.getDisplayName().getString()) - .replace("%message%", content)).queue(); - } - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getDisplayName().getString()) : player.getDisplayName().getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } - - private boolean hasIllegalCharacter(String message) { - for (int i = 0; i < message.length(); ++i) { - if (!SharedConstants.isValidChar(message.charAt(i))) { - return true; - } - } - - return false; - } -} -//#endif \ No newline at end of file From ed54cf6a7603c4fddfe3f8014cea52f05c0333b2 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 21:06:45 +0800 Subject: [PATCH 26/36] =?UTF-8?q?PLAYER=5FCOMMAND=20=E4=BC=A0=20/=20?= =?UTF-8?q?=E5=BC=80=E5=A4=B4=E7=9A=84=E6=8C=87=E4=BB=A4=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 10 ++++------ .../mixins/MixinServerGamePacketListenerImpl.java | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 56b8e01e..ca78c548 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -146,10 +146,8 @@ public static void init() { }); MinecraftEvents.PLAYER_COMMAND.register((player, command) -> { - String input = "/" + command; - for (String excludedCommand : CONFIG.generic.excludedCommands) { - if (input.startsWith(excludedCommand + " ")) { + if (command.startsWith(excludedCommand + " ")) { return; } } @@ -161,15 +159,15 @@ public static void init() { MINECRAFT_SEND_COUNT++; if (MINECRAFT_SEND_COUNT <= 20) { - MutableComponent message = Component.literal("<" + Objects.requireNonNull(player.getDisplayName()).getString() + "> " + input); + MutableComponent message = Component.literal("<" + Objects.requireNonNull(player.getDisplayName()).getString() + "> " + command); SERVER.getPlayerList().getPlayers().forEach( player1 -> player1.displayClientMessage(message, false)); SERVER.sendSystemMessage(message); - sendDiscordMessage(MarkdownSanitizer.escape(input), Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); + sendDiscordMessage(MarkdownSanitizer.escape(command), Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), MarkdownSanitizer.escape(input)); + MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), MarkdownSanitizer.escape(command)); } } }); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 51b16474..7cc8b911 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -48,12 +48,12 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI //#if MC > 11900 @Inject(method = "performChatCommand", at = @At("HEAD")) private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, LastSeenMessages lastSeenMessages, CallbackInfo ci) { - MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket.command()); + MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); } //#else //$$ @Inject(method = "handleChatCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)V")) //$$ private void handleChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) { - //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, serverboundChatCommandPacket.command()); + //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); //$$ } //#endif } From a28a8733433ac5018e093dc0ee32026ea87dd5ab Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 21:32:13 +0800 Subject: [PATCH 27/36] =?UTF-8?q?SERVER=5FMESSAGE=20=E5=92=8C=20PLAYER=5FM?= =?UTF-8?q?ESSAGE=20=E7=9B=B4=E6=8E=A5=E4=BC=A0=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 14 +++++++------- .../mcdiscordchat/minecraft/MinecraftEvents.java | 14 ++++++-------- .../minecraft/mixins/MixinPlayerList.java | 4 ++-- .../mixins/MixinServerGamePacketListenerImpl.java | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index ca78c548..32f9697e 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -46,16 +46,16 @@ public class MinecraftEventListener { public static void init() { - MinecraftEvents.SERVER_MESSAGE.register((playerChatMessage, commandSourceStack) -> { - sendDiscordMessage(playerChatMessage.decoratedContent().getString(), commandSourceStack.getDisplayName().getString(), JDA.getSelfUser().getAvatarUrl()); + MinecraftEvents.SERVER_MESSAGE.register((message, commandSourceStack) -> { + sendDiscordMessage(message, commandSourceStack.getDisplayName().getString(), JDA.getSelfUser().getAvatarUrl()); if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, commandSourceStack.getDisplayName().getString(), playerChatMessage.decoratedContent().getString()); + MULTI_SERVER.sendMessage(false, true, false, commandSourceStack.getDisplayName().getString(), message); } }); - MinecraftEvents.PLAYER_MESSAGE.register((player, playerChatMessage) -> { - String contentToDiscord = playerChatMessage.decoratedContent().getString(); - String contentToMinecraft = playerChatMessage.decoratedContent().getString(); + MinecraftEvents.PLAYER_MESSAGE.register((player, message) -> { + String contentToDiscord = message; + String contentToMinecraft = message; if (StringUtils.countMatches(contentToDiscord, ":") >= 2) { String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":"); @@ -134,7 +134,7 @@ public static void init() { if (CONFIG.generic.broadcastChatMessages) { sendDiscordMessage(contentToDiscord, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : playerChatMessage.decoratedContent().getString()); + MULTI_SERVER.sendMessage(false, true, false, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : message); } } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java index 479b25ae..a0ed89a9 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEvents.java @@ -5,8 +5,6 @@ import net.minecraft.advancements.AdvancementHolder; import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.PlayerChatMessage; -import net.minecraft.network.protocol.game.ServerboundChatCommandPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; @@ -17,16 +15,16 @@ */ public interface MinecraftEvents { - Event SERVER_MESSAGE = EventFactory.createArrayBacked(ServerMessage.class, callbacks -> (playerChatMessage, commandSourceStack) -> { + Event SERVER_MESSAGE = EventFactory.createArrayBacked(ServerMessage.class, callbacks -> (message, commandSourceStack) -> { for (ServerMessage callback : callbacks) { - callback.message(playerChatMessage, commandSourceStack); + callback.message(message, commandSourceStack); } }); - Event PLAYER_MESSAGE = EventFactory.createArrayBacked(PlayerMessage.class, callbacks -> (player, playerChatMessage) -> { + Event PLAYER_MESSAGE = EventFactory.createArrayBacked(PlayerMessage.class, callbacks -> (player, message) -> { Optional result = Optional.empty(); for (PlayerMessage callback : callbacks) { - result = callback.message(player, playerChatMessage); + result = callback.message(player, message); } return result; }); @@ -62,11 +60,11 @@ public interface MinecraftEvents { }); interface ServerMessage { - void message(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack); + void message(String message, CommandSourceStack commandSourceStack); } interface PlayerMessage { - Optional message(ServerPlayer player, PlayerChatMessage playerChatMessage); + Optional message(ServerPlayer player, String message); } interface PlayerCommand { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 116ead07..9e4974e6 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -30,12 +30,12 @@ public class MixinPlayerList { //#if MC > 11900 @Inject(method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/commands/CommandSourceStack;Lnet/minecraft/network/chat/ChatType$Bound;)V", at = @At("HEAD")) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack, ChatType.Bound bound, CallbackInfo ci) { - MinecraftEvents.SERVER_MESSAGE.invoker().message(playerChatMessage, commandSourceStack); + MinecraftEvents.SERVER_MESSAGE.invoker().message(playerChatMessage.decoratedContent().getString(), commandSourceStack); } //#else //$$ @Inject(method = "broadcastChatMessage", at = @At("HEAD")) //$$ private void broadcastChatMessage(FilteredText filteredText, CommandSourceStack commandSourceStack, ResourceKey resourceKey, CallbackInfo ci) { - //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered(), commandSourceStack); + //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered().serverContent().getString(), commandSourceStack); //$$ // TODO filtered() or raw() ? //$$ } //#endif diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 7cc8b911..86a76923 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -34,7 +34,7 @@ public class MixinServerGamePacketListenerImpl { @Inject(method = "broadcastChatMessage", at = @At("HEAD"), cancellable = true) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackInfo ci) { - Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage); + Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage.decoratedContent().getString()); if (result.isPresent()) { //#if MC > 11900 SERVER.getPlayerList().broadcastChatMessage(playerChatMessage.withUnsignedContent(result.get()), this.player, ChatType.bind(ChatType.CHAT, player)); From 2f3fe0c883eccd81e0c4c4fb96f116c7d4d68803 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 22:16:09 +0800 Subject: [PATCH 28/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.18.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 +- settings.gradle | 2 +- .../discord/DiscordCommandSource.java | 7 + .../discord/DiscordEventListener.java | 7 + .../minecraft/MinecraftCommands.java | 31 ++ .../minecraft/MinecraftEventListener.java | 11 + .../minecraft/mixins/MixinPlayerList.java | 23 +- .../MixinServerGamePacketListenerImpl.java | 29 +- .../minecraft/mixins/MixinLanguage.java | 65 ----- .../mixins/MixinServerPlayNetworkHandler.java | 275 ------------------ 10 files changed, 107 insertions(+), 349 deletions(-) delete mode 100644 versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java delete mode 100644 versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java diff --git a/build.gradle b/build.gradle index 4300f26d..41b34648 100644 --- a/build.gradle +++ b/build.gradle @@ -4,10 +4,10 @@ plugins { } preprocess { -// def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") +// def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") // TODO Check MixinLanguage // def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") // def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") -// def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") + def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // TODO Check MixinLanguage def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") def mc1192 = createNode("1.19.2", 1_19_02, "mojang") def mc1193 = createNode("1.19.3", 1_19_03, "mojang") @@ -19,7 +19,7 @@ preprocess { // mc1152.link(mc1165, null) // mc1165.link(mc1171, null) // mc1171.link(mc1182, null) -// mc1182.link(mc1190, null) + mc1182.link(mc1190, null) mc1190.link(mc1192, null) mc1192.link(mc1193, file("versions/mapping-1.19.2-1.19.3.txt")) mc1193.link(mc1194, null) diff --git a/settings.gradle b/settings.gradle index 948b797e..3e00b613 100644 --- a/settings.gradle +++ b/settings.gradle @@ -27,7 +27,7 @@ def versions = Arrays.asList( // "compat_1.15.2", // "compat_1.16.5", // "compat_1.17.1", -// "compat_1.18.2", + "compat_1.18.2", "compat_1.19" , "1.19.2", "1.19.3", diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java index aaad3ba4..a6827e7d 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java @@ -4,6 +4,9 @@ import net.minecraft.commands.CommandSource; import net.minecraft.network.chat.Component; +//#if MC < 11900 +//$$ import java.util.UUID; +//#endif import java.util.Timer; import java.util.TimerTask; @@ -21,7 +24,11 @@ public DiscordCommandSource(SlashCommandInteractionEvent e) { } @Override + //#if MC >= 11900 public void sendSystemMessage(Component message) { + //#else + //$$ public void sendMessage(Component message, UUID uUID) { + //#endif long currentOutputMillis = System.currentTimeMillis(); if (output.length() > 1500) { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java index 9cb5cec2..0dacbe67 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java @@ -25,6 +25,9 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +//#if MC < 11900 +//$$ import net.minecraft.network.chat.TextComponent; +//#endif import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.apache.commons.lang3.ArrayUtils; @@ -135,7 +138,11 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { e.getHook().sendMessage(Translations.translate("discord.deListener.oscInteraction.executingCommand")) .submit() .whenComplete((v, ex) -> { + //#if MC >= 11900 CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", Component.literal("MC-Discord-Chat"), SERVER, null); + //#else + //$$ CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", new TextComponent("MC-Discord-Chat"), SERVER, null); + //#endif //#if MC > 11900 ParseResults results = SERVER.getCommands().getDispatcher().parse(command, source); SERVER.getCommands().performCommand(results, command); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java index 5442a60d..10ced663 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftCommands.java @@ -7,6 +7,9 @@ import com.xujiayao.mcdiscordchat.utils.Utils; import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; +//#if MC < 11900 +//$$ import net.minecraft.network.chat.TextComponent; +//#endif import static com.xujiayao.mcdiscordchat.Main.CONFIG; import static net.minecraft.commands.Commands.argument; @@ -24,7 +27,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + //#else + //$$ new TextComponent(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + //#endif return 1; }) .then(literal("help").executes(context -> { @@ -33,7 +40,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + //#else + //$$ new TextComponent(MarkdownParser.parseMarkdown(Utils.getHelpCommandMessage(false) + Translations.translate("minecraft.mcCommands.register.helpMessageExplanation"))), false); + //#endif return 1; })) .then(literal("info").executes(context -> { @@ -42,7 +53,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(Utils.getInfoCommandMessage()), false); + //#else + //$$ new TextComponent(Utils.getInfoCommandMessage()), false); + //#endif return 1; })) .then(literal("stats") @@ -56,7 +71,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(Utils.getStatsCommandMessage(type, name)), false); + //#else + //$$ new TextComponent(Utils.getStatsCommandMessage(type, name)), false); + //#endif return 1; })))) .then(literal("update").executes(context -> { @@ -65,7 +84,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(MarkdownParser.parseMarkdown(Utils.checkUpdate(true))), false); + //#else + //$$ new TextComponent(MarkdownParser.parseMarkdown(Utils.checkUpdate(true))), false); + //#endif return 1; })) .then(literal("whitelist") @@ -78,7 +101,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(MarkdownParser.parseMarkdown(Utils.whitelist(player))), false); + //#else + //$$ new TextComponent(MarkdownParser.parseMarkdown(Utils.whitelist(player))), false); + //#endif return 1; }))) .then(literal("reload") @@ -89,7 +116,11 @@ public static void register(CommandDispatcher dispatcher) { //#else //$$ context.getSource().sendSuccess( //#endif + //#if MC >= 11900 Component.literal(MarkdownParser.parseMarkdown(Utils.reload())), false); + //#else + //$$ new TextComponent(MarkdownParser.parseMarkdown(Utils.reload())), false); + //#endif return 1; }))); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index 32f9697e..b831c5fb 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -14,6 +14,9 @@ import net.minecraft.advancements.DisplayInfo; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +//#if MC < 11900 +//$$ import net.minecraft.network.chat.TextComponent; +//#endif import net.minecraft.world.level.GameRules; import okhttp3.MediaType; import okhttp3.Request; @@ -159,11 +162,19 @@ public static void init() { MINECRAFT_SEND_COUNT++; if (MINECRAFT_SEND_COUNT <= 20) { + //#if MC >= 11900 MutableComponent message = Component.literal("<" + Objects.requireNonNull(player.getDisplayName()).getString() + "> " + command); + //#else + //$$ MutableComponent message = new TextComponent("<" + Objects.requireNonNull(player.getDisplayName()).getString() + "> " + command); + //#endif SERVER.getPlayerList().getPlayers().forEach( player1 -> player1.displayClientMessage(message, false)); + //#if MC >= 11900 SERVER.sendSystemMessage(message); + //#else + //$$ SERVER.sendMessage(message, player.getUUID()); + //#endif sendDiscordMessage(MarkdownSanitizer.escape(command), Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); if (CONFIG.multiServer.enable) { diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 9e4974e6..dd93eb3e 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -4,7 +4,12 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.Connection; import net.minecraft.network.chat.ChatType; +//#if MC < 11900 +//$$ import net.minecraft.network.chat.Component; +//#endif +//#if MC >= 11900 import net.minecraft.network.chat.PlayerChatMessage; +//#endif //#if MC <= 11900 //$$ import net.minecraft.resources.ResourceKey; //#endif @@ -12,7 +17,7 @@ //#if MC >= 12002 import net.minecraft.server.network.CommonListenerCookie; //#endif -//#if MC <= 11900 +//#if MC == 11900 //$$ import net.minecraft.server.network.FilteredText; //#endif import net.minecraft.server.players.PlayerList; @@ -21,6 +26,12 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//#if MC < 11900 +//$$ import java.util.UUID; +//$$ +//$$ import static com.xujiayao.mcdiscordchat.Main.SERVER; +//#endif + /** * @author Xujiayao */ @@ -32,12 +43,18 @@ public class MixinPlayerList { private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSourceStack commandSourceStack, ChatType.Bound bound, CallbackInfo ci) { MinecraftEvents.SERVER_MESSAGE.invoker().message(playerChatMessage.decoratedContent().getString(), commandSourceStack); } - //#else - //$$ @Inject(method = "broadcastChatMessage", at = @At("HEAD")) + //#elseif MC == 11900 + //$$ @Inject(method = "broadcastChatMessage(Lnet/minecraft/server/network/FilteredText;Lnet/minecraft/commands/CommandSourceStack;Lnet/minecraft/resources/ResourceKey;)V", at = @At("HEAD")) //$$ private void broadcastChatMessage(FilteredText filteredText, CommandSourceStack commandSourceStack, ResourceKey resourceKey, CallbackInfo ci) { //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered().serverContent().getString(), commandSourceStack); //$$ // TODO filtered() or raw() ? //$$ } + //#else + //$$ @Inject(method = "broadcastMessage", at = @At("HEAD")) + //$$ private void broadcastMessage(Component component, ChatType chatType, UUID uUID, CallbackInfo ci) { + //$$ // TODO Check if need (uuid == Util.NIL_UUID) + //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(component.getString(), SERVER.createCommandSourceStack()); + //$$ } //#endif @Inject(method = "placeNewPlayer", at = @At("RETURN")) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 86a76923..178dacf4 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -6,13 +6,21 @@ //#if MC > 11900 import net.minecraft.network.chat.LastSeenMessages; //#endif +//#if MC >= 11900 import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.network.protocol.game.ServerboundChatCommandPacket; +//#endif +//#if MC <= 11802 +//$$ import net.minecraft.network.chat.TranslatableComponent; +//#endif import net.minecraft.server.level.ServerPlayer; -//#if MC <= 11900 +//#if MC == 11900 //$$ import net.minecraft.server.network.FilteredText; //#endif import net.minecraft.server.network.ServerGamePacketListenerImpl; +//#if MC <= 11802 +//$$ import net.minecraft.server.network.TextFilter; +//#endif import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -32,6 +40,7 @@ public class MixinServerGamePacketListenerImpl { @Shadow private ServerPlayer player; + //#if MC > 11802 @Inject(method = "broadcastChatMessage", at = @At("HEAD"), cancellable = true) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackInfo ci) { Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage.decoratedContent().getString()); @@ -44,16 +53,32 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI ci.cancel(); } } + //#else + //$$ @Inject(method = "handleChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Ljava/util/Function;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) + //$$ private void handleChat(TextFilter.FilteredText filteredText, CallbackInfo ci) { + //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, filteredText.getFiltered()); + //$$ if (result.isPresent()) { + //$$ Component component = new TranslatableComponent("chat.type.text", this.player.getDisplayName(), filteredText.getFiltered()); + //$$ SERVER.getPlayerList().broadcastMessage(component, ChatType.CHAT, this.player.getUUID()); + //$$ ci.cancel(); + //$$ } + //$$ } + //#endif //#if MC > 11900 @Inject(method = "performChatCommand", at = @At("HEAD")) private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, LastSeenMessages lastSeenMessages, CallbackInfo ci) { MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); } - //#else + //#elseif MC > 11802 //$$ @Inject(method = "handleChatCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)V")) //$$ private void handleChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) { //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); //$$ } + //#else + //$$ @Inject(method = "handleCommand", at = @At("HEAD")) + //$$ private void handleCommand(String string, CallbackInfo ci) { + //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, string); + //$$ } //#endif } diff --git a/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java b/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java deleted file mode 100644 index f1b0e90b..00000000 --- a/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java +++ /dev/null @@ -1,65 +0,0 @@ -//#if MC >= 11600 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.util.JsonHelper; -import net.minecraft.util.Language; -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.ModifyVariable; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import java.util.regex.Pattern; - -import static com.xujiayao.mcdiscordchat.Main.LOGGER; - -/** - * @author Xujiayao - */ -@Mixin(Language.class) -public abstract class MixinLanguage { - - @Final - @Shadow - private static Gson GSON; - - @Final - @Shadow - private static Pattern TOKEN_PATTERN; - - @ModifyVariable(method = "create", at = @At("STORE"), ordinal = 0) - private static Map mapInjected(Map originalMap) { - LinkedHashMap map = new LinkedHashMap<>(originalMap); - - FabricLoader.getInstance().getAllMods().forEach(modContainer -> { - Optional optional = modContainer.findPath("/assets/" + modContainer.getMetadata().getId() + "/lang/en_us.json"); - - if (optional.isPresent()) { - try (InputStream inputStream = Files.newInputStream(optional.get())) { - JsonObject json = GSON.fromJson(new InputStreamReader(inputStream, StandardCharsets.UTF_8), JsonObject.class); - for (Map.Entry entry : json.entrySet()) { - String string = TOKEN_PATTERN.matcher(JsonHelper.asString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); - map.put(entry.getKey(), string); - } - } catch (Exception e) { - LOGGER.error("Couldn't read strings from /assets/{}", modContainer.getMetadata().getId() + "/lang/en_us.json", e); - } - } - }); - - return map; - } -} -//#endif \ No newline at end of file diff --git a/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index 894e07c6..00000000 --- a/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,275 +0,0 @@ -//#if MC >= 11600 -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -import net.minecraft.client.option.ChatVisibility; -import net.minecraft.network.MessageType; -import net.minecraft.network.Packet; -import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; -import net.minecraft.server.MinecraftServer; -//#if MC >= 11700 -import net.minecraft.server.filter.TextStream.Message; -//#endif -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableText; -import net.minecraft.util.Formatting; -import net.minecraft.util.Util; -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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; - -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(ServerPlayNetworkHandler.class) -public abstract class MixinServerPlayNetworkHandler { - - @Shadow - private ServerPlayerEntity player; - - @Final - @Shadow - private MinecraftServer server; - - @Shadow - private int messageCooldown; - - @Shadow - public abstract void sendPacket(Packet packet); - - @Shadow - public abstract void executeCommand(String input); - - @Shadow - public abstract void disconnect(Text reason); - - //#if MC >= 11700 - @Inject(method = "handleMessage", at = @At("HEAD"), cancellable = true) - private void handleMessage(Message message, CallbackInfo ci) { - //#else - //$$ @Inject(method = "method_31286", at = @At("HEAD"), cancellable = true) - //$$ private void handleMessage(String string, CallbackInfo ci) { - //#endif - if (player.getClientChatVisibility() == ChatVisibility.HIDDEN) { - sendPacket(new GameMessageS2CPacket((new TranslatableText("chat.disabled.options")).formatted(Formatting.RED), MessageType.SYSTEM, Util.NIL_UUID)); - ci.cancel(); - } else { - player.updateLastActionTime(); - - //#if MC >= 11700 - if (message.getRaw().startsWith("/")) { - executeCommand(message.getRaw()); - //#else - //$$ if (string.startsWith("/")) { - //$$ executeCommand(string); - //#endif - ci.cancel(); - } else { - //#if MC >= 11700 - String contentToDiscord = message.getRaw(); - String contentToMinecraft = message.getRaw(); - //#else - //$$ String contentToDiscord = string; - //$$ String contentToMinecraft = string; - //#endif - - if (StringUtils.countMatches(contentToDiscord, ":") >= 2) { - String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":"); - for (String emojiName : emojiNames) { - List 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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) { - //#if MC >= 11800 - server.getPlayerManager().broadcast(new TranslatableText("chat.type.text", player.getDisplayName(), Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]")), MessageType.CHAT, player.getUuid()); - //#else - //$$ server.getPlayerManager().broadcastChatMessage(new TranslatableText("chat.type.text", player.getDisplayName(), Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]")), MessageType.CHAT, player.getUuid()); - //#endif - ci.cancel(); - } - - sendMessage(contentToDiscord, false); - if (CONFIG.multiServer.enable) { - //#if MC >= 11700 - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : message.getRaw()); - //#else - //$$ MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : string); - //#endif - } - } - - messageCooldown += 20; - if (messageCooldown > 200 && !server.getPlayerManager().isOperator(player.getGameProfile())) { - disconnect(new TranslatableText("disconnect.spam")); - } - } - } - - @Inject(method = "executeCommand", at = @At(value = "HEAD")) - private void executeCommand(String input, CallbackInfo ci) { - if (CONFIG.generic.broadcastPlayerCommandExecution) { - for (String command : CONFIG.generic.excludedCommands) { - if (input.startsWith(command + " ")) { - 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 = new LiteralText("<").append(player.getDisplayName().getString()).append("> ").append(input); - - server.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(text, false)); - - SERVER.sendSystemMessage(text, player.getUuid()); - - sendMessage(input, true); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), MarkdownSanitizer.escape(input)); - } - } - } - } - - private void sendMessage(String message, boolean escapeMarkdown) { - String content = (escapeMarkdown ? MarkdownSanitizer.escape(message) : message); - - if (!CONFIG.generic.useWebhook) { - CHANNEL.sendMessage(((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] <") : "<") + player.getDisplayName().getString() + "> " + content).queue(); - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getDisplayName().getString()) : player.getDisplayName().getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } -} -//#endif \ No newline at end of file From e3e97c630e8f1eb560acd35b922b5944736d9874 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 22:19:46 +0800 Subject: [PATCH 29/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.17.1=EF=BC=88?= =?UTF-8?q?=E6=88=96=E8=AE=B8=E4=B8=8D=E9=9C=80=E8=A6=81=EF=BC=9F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++-- settings.gradle | 2 +- .../mcdiscordchat/minecraft/mixins/MixinPlayerList.java | 2 +- .../minecraft/mixins/MixinServerGamePacketListenerImpl.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 41b34648..2503cae8 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { preprocess { // def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") // TODO Check MixinLanguage // def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") -// def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") + def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // TODO Check MixinLanguage def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") def mc1192 = createNode("1.19.2", 1_19_02, "mojang") @@ -18,7 +18,7 @@ preprocess { // mc1152.link(mc1165, null) // mc1165.link(mc1171, null) -// mc1171.link(mc1182, null) + mc1171.link(mc1182, null) mc1182.link(mc1190, null) mc1190.link(mc1192, null) mc1192.link(mc1193, file("versions/mapping-1.19.2-1.19.3.txt")) diff --git a/settings.gradle b/settings.gradle index 3e00b613..ac2abe28 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,7 +26,7 @@ pluginManagement { def versions = Arrays.asList( // "compat_1.15.2", // "compat_1.16.5", -// "compat_1.17.1", + "compat_1.17.1", "compat_1.18.2", "compat_1.19" , "1.19.2", diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index dd93eb3e..cda5a116 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -50,7 +50,7 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSo //$$ // TODO filtered() or raw() ? //$$ } //#else - //$$ @Inject(method = "broadcastMessage", at = @At("HEAD")) + //$$ @Inject(method = "broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V", at = @At("HEAD")) //$$ private void broadcastMessage(Component component, ChatType chatType, UUID uUID, CallbackInfo ci) { //$$ // TODO Check if need (uuid == Util.NIL_UUID) //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(component.getString(), SERVER.createCommandSourceStack()); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 178dacf4..044bf9a0 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -54,7 +54,7 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI } } //#else - //$$ @Inject(method = "handleChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Ljava/util/Function;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) + //$$ @Inject(method = "handleChat(Lnet/minecraft/server/network/TextFilter$FilteredText;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Ljava/util/Function;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) //$$ private void handleChat(TextFilter.FilteredText filteredText, CallbackInfo ci) { //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, filteredText.getFiltered()); //$$ if (result.isPresent()) { From ea5a512cd5f0d90882bf14b4300580c0167b8d64 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 22:22:50 +0800 Subject: [PATCH 30/36] =?UTF-8?q?=E5=82=BB=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/mixins/MixinServerGamePacketListenerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 044bf9a0..b32098b7 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -58,7 +58,7 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI //$$ private void handleChat(TextFilter.FilteredText filteredText, CallbackInfo ci) { //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, filteredText.getFiltered()); //$$ if (result.isPresent()) { - //$$ Component component = new TranslatableComponent("chat.type.text", this.player.getDisplayName(), filteredText.getFiltered()); + //$$ Component component = new TranslatableComponent("chat.type.text", this.player.getDisplayName(), result.get()); //$$ SERVER.getPlayerList().broadcastMessage(component, ChatType.CHAT, this.player.getUUID()); //$$ ci.cancel(); //$$ } From 26ebc2a8a19fd6a96b00c1c875af94e84893e248 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 22:26:11 +0800 Subject: [PATCH 31/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.16.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++-- settings.gradle | 2 +- .../mixins/MixinServerGamePacketListenerImpl.java | 12 +++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 2503cae8..bc65ee38 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { preprocess { // def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") // TODO Check MixinLanguage -// def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") + def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // TODO Check MixinLanguage def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") @@ -17,7 +17,7 @@ preprocess { def mc1204 = createNode("1.20.4", 1_20_04, "mojang") // mc1152.link(mc1165, null) -// mc1165.link(mc1171, null) + mc1165.link(mc1171, null) mc1171.link(mc1182, null) mc1182.link(mc1190, null) mc1190.link(mc1192, null) diff --git a/settings.gradle b/settings.gradle index ac2abe28..b758e6cb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,7 +25,7 @@ pluginManagement { def versions = Arrays.asList( // "compat_1.15.2", -// "compat_1.16.5", + "compat_1.16.5", "compat_1.17.1", "compat_1.18.2", "compat_1.19" , diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index b32098b7..36b6d66b 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -53,7 +53,7 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI ci.cancel(); } } - //#else + //#elseif MC > 11605 //$$ @Inject(method = "handleChat(Lnet/minecraft/server/network/TextFilter$FilteredText;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Ljava/util/Function;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) //$$ private void handleChat(TextFilter.FilteredText filteredText, CallbackInfo ci) { //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, filteredText.getFiltered()); @@ -63,6 +63,16 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI //$$ ci.cancel(); //$$ } //$$ } + //#else + //$$ @Inject(method = "handleChat(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) + //$$ private void handleChat(String string, CallbackInfo ci) { + //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, string); + //$$ if (result.isPresent()) { + //$$ Component component = new TranslatableComponent("chat.type.text", this.player.getDisplayName(), result.get()); + //$$ SERVER.getPlayerList().broadcastMessage(component, ChatType.CHAT, this.player.getUUID()); + //$$ ci.cancel(); + //$$ } + //$$ } //#endif //#if MC > 11900 From a138b4f43d514a4a5623b77a300c5b333ebfa8e0 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sat, 10 Feb 2024 23:01:38 +0800 Subject: [PATCH 32/36] =?UTF-8?q?=E5=85=BC=E5=AE=B91.15.2=EF=BC=8C?= =?UTF-8?q?=E5=BC=80=E5=A7=8B=E6=A3=80=E6=9F=A5=E5=90=84=E7=89=88=E6=9C=AC?= =?UTF-8?q?Runtime=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- settings.gradle | 2 +- .../discord/DiscordCommandSource.java | 4 +- .../discord/DiscordEventListener.java | 7 +- .../minecraft/MinecraftEventListener.java | 4 +- .../minecraft/mixins/MixinPlayerList.java | 9 +- .../MixinServerGamePacketListenerImpl.java | 17 +- .../xujiayao/mcdiscordchat/utils/Utils.java | 2 + .../minecraft/mixins/MixinLanguage.java | 61 ---- .../mixins/MixinServerPlayNetworkHandler.java | 260 ------------------ versions/mapping-1.15.2-1.16.5.txt | 2 + 11 files changed, 41 insertions(+), 331 deletions(-) delete mode 100644 versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java delete mode 100644 versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java create mode 100644 versions/mapping-1.15.2-1.16.5.txt diff --git a/build.gradle b/build.gradle index bc65ee38..f4f2c859 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } preprocess { -// def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") // TODO Check MixinLanguage + def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") // TODO Check MixinLanguage def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // TODO Check MixinLanguage @@ -16,7 +16,7 @@ preprocess { def mc1202 = createNode("1.20.2", 1_20_02, "mojang") def mc1204 = createNode("1.20.4", 1_20_04, "mojang") -// mc1152.link(mc1165, null) + mc1152.link(mc1165, file("versions/mapping-1.15.2-1.16.5.txt")) mc1165.link(mc1171, null) mc1171.link(mc1182, null) mc1182.link(mc1190, null) diff --git a/settings.gradle b/settings.gradle index b758e6cb..f5200636 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,7 +24,7 @@ pluginManagement { } def versions = Arrays.asList( -// "compat_1.15.2", + "compat_1.15.2", "compat_1.16.5", "compat_1.17.1", "compat_1.18.2", diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java index a6827e7d..c826bb31 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordCommandSource.java @@ -26,8 +26,10 @@ public DiscordCommandSource(SlashCommandInteractionEvent e) { @Override //#if MC >= 11900 public void sendSystemMessage(Component message) { - //#else + //#elseif MC > 11502 //$$ public void sendMessage(Component message, UUID uUID) { + //#else + //$$ public void sendMessage(Component message) { //#endif long currentOutputMillis = System.currentTimeMillis(); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java index 0dacbe67..48a02e8c 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/discord/DiscordEventListener.java @@ -28,6 +28,9 @@ //#if MC < 11900 //$$ import net.minecraft.network.chat.TextComponent; //#endif +//#if MC <= 11502 +//$$ import net.minecraft.world.level.dimension.DimensionType; +//#endif import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.apache.commons.lang3.ArrayUtils; @@ -140,8 +143,10 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent e) { .whenComplete((v, ex) -> { //#if MC >= 11900 CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", Component.literal("MC-Discord-Chat"), SERVER, null); - //#else + //#elseif MC > 11502 //$$ CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.overworld(), 4, "MC-Discord-Chat", new TextComponent("MC-Discord-Chat"), SERVER, null); + //#else + //$$ CommandSourceStack source = new CommandSourceStack(new DiscordCommandSource(e), Vec3.ZERO, Vec2.ZERO, SERVER.getLevel(DimensionType.OVERWORLD), 4, "MC-Discord-Chat", new TextComponent("MC-Discord-Chat"), SERVER, null); //#endif //#if MC > 11900 ParseResults results = SERVER.getCommands().getDispatcher().parse(command, source); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index b831c5fb..ac6d6acb 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -172,8 +172,10 @@ public static void init() { player1 -> player1.displayClientMessage(message, false)); //#if MC >= 11900 SERVER.sendSystemMessage(message); - //#else + //#elseif MC > 11502 //$$ SERVER.sendMessage(message, player.getUUID()); + //#else + //$$ SERVER.sendMessage(message); //#endif sendDiscordMessage(MarkdownSanitizer.escape(command), Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString()))); diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index cda5a116..9c25853d 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -10,7 +10,7 @@ //#if MC >= 11900 import net.minecraft.network.chat.PlayerChatMessage; //#endif -//#if MC <= 11900 +//#if MC > 11502 && MC <= 11900 //$$ import net.minecraft.resources.ResourceKey; //#endif import net.minecraft.server.level.ServerPlayer; @@ -49,12 +49,17 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSo //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered().serverContent().getString(), commandSourceStack); //$$ // TODO filtered() or raw() ? //$$ } - //#else + //#elseif MC > 11502 //$$ @Inject(method = "broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V", at = @At("HEAD")) //$$ private void broadcastMessage(Component component, ChatType chatType, UUID uUID, CallbackInfo ci) { //$$ // TODO Check if need (uuid == Util.NIL_UUID) //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(component.getString(), SERVER.createCommandSourceStack()); //$$ } + //#else + //$$ @Inject(method = "broadcastMessage(Lnet/minecraft/network/chat/Component;)V", at = @At("HEAD")) + //$$ private void broadcastMessage(Component component, CallbackInfo ci) { + //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(component.getString(), SERVER.createCommandSourceStack()); + //$$ } //#endif @Inject(method = "placeNewPlayer", at = @At("RETURN")) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index 36b6d66b..e69c4553 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -13,12 +13,15 @@ //#if MC <= 11802 //$$ import net.minecraft.network.chat.TranslatableComponent; //#endif +//#if MC < 11605 +//$$ import net.minecraft.network.protocol.game.ServerboundChatPacket; +//#endif import net.minecraft.server.level.ServerPlayer; //#if MC == 11900 //$$ import net.minecraft.server.network.FilteredText; //#endif import net.minecraft.server.network.ServerGamePacketListenerImpl; -//#if MC <= 11802 +//#if MC >= 11605 && MC <= 11802 //$$ import net.minecraft.server.network.TextFilter; //#endif import org.spongepowered.asm.mixin.Mixin; @@ -63,7 +66,7 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI //$$ ci.cancel(); //$$ } //$$ } - //#else + //#elseif MC == 11605 //$$ @Inject(method = "handleChat(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) //$$ private void handleChat(String string, CallbackInfo ci) { //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, string); @@ -73,6 +76,16 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI //$$ ci.cancel(); //$$ } //$$ } + //#else + //$$ @Inject(method = "handleChat(Lnet/minecraft/network/protocol/game/ServerboundChatPacket;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Z)V"), cancellable = true) + //$$ private void handleChat(ServerboundChatPacket serverboundChatPacket, CallbackInfo ci) { + //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, serverboundChatPacket.getMessage()); + //$$ if (result.isPresent()) { + //$$ Component component = new TranslatableComponent("chat.type.text", this.player.getDisplayName(), result.get()); + //$$ SERVER.getPlayerList().broadcastMessage(component, false); + //$$ ci.cancel(); + //$$ } + //$$ } //#endif //#if MC > 11900 diff --git a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java index 4a0257bf..124055b2 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/utils/Utils.java @@ -21,7 +21,9 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.UserWhiteList; import net.minecraft.server.players.UserWhiteListEntry; +//#if MC > 11502 import net.minecraft.util.TimeUtil; +//#endif import net.minecraft.util.Tuple; import okhttp3.CacheControl; import okhttp3.Request; diff --git a/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java b/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java deleted file mode 100644 index 82a3fd25..00000000 --- a/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.util.JsonHelper; -import net.minecraft.util.Language; -import org.apache.logging.log4j.Logger; -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 java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Map; -import java.util.Optional; -import java.util.regex.Pattern; - -/** - * @author Xujiayao - */ -@Mixin(Language.class) -public abstract class MixinLanguage { - - @Final - @Shadow - private static Logger LOGGER; - - @Final - @Shadow - private static Pattern field_11489; - - @Final - @Shadow - private Map translations; - - @Inject(method = "", at = @At(value = "RETURN")) - private void Language(CallbackInfo ci) { - FabricLoader.getInstance().getAllMods().forEach(modContainer -> { - Optional optional = modContainer.findPath("/assets/" + modContainer.getMetadata().getId() + "/lang/en_us.json"); - if (optional.isPresent()) { - try (InputStream inputStream = Files.newInputStream(optional.get())) { - JsonObject json = new Gson().fromJson(new InputStreamReader(inputStream, StandardCharsets.UTF_8), JsonObject.class); - for (Map.Entry entry : json.entrySet()) { - String string = field_11489.matcher(JsonHelper.asString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); - translations.put(entry.getKey(), string); - } - } catch (Exception e) { - LOGGER.error("Couldn't read strings from /assets/{}", modContainer.getMetadata().getId() + "/lang/en_us.json", e); - } - } - }); - } -} \ No newline at end of file diff --git a/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java b/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java deleted file mode 100644 index e8c3c5bf..00000000 --- a/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayNetworkHandler.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.xujiayao.mcdiscordchat.minecraft.mixins; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -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.fellbaum.jemoji.EmojiManager; -import net.minecraft.SharedConstants; -import net.minecraft.client.options.ChatVisibility; -import net.minecraft.network.NetworkThreadUtils; -import net.minecraft.network.Packet; -import net.minecraft.network.listener.ServerPlayPacketListener; -import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; -import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableText; -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 com.xujiayao.mcdiscordchat.utils.MarkdownParser; - -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static com.xujiayao.mcdiscordchat.Main.CHANNEL; -import static com.xujiayao.mcdiscordchat.Main.CONFIG; -import static com.xujiayao.mcdiscordchat.Main.HTTP_CLIENT; -import static com.xujiayao.mcdiscordchat.Main.JDA; -import static com.xujiayao.mcdiscordchat.Main.LOGGER; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_LAST_RESET_TIME; -import static com.xujiayao.mcdiscordchat.Main.MINECRAFT_SEND_COUNT; -import static com.xujiayao.mcdiscordchat.Main.MULTI_SERVER; -import static com.xujiayao.mcdiscordchat.Main.SERVER; -import static com.xujiayao.mcdiscordchat.Main.WEBHOOK; - -/** - * @author Xujiayao - */ -@Mixin(ServerPlayNetworkHandler.class) -public abstract class MixinServerPlayNetworkHandler implements ServerPlayPacketListener { - - @Shadow - private ServerPlayerEntity player; - - @Final - @Shadow - private MinecraftServer server; - - @Shadow - private int messageCooldown; - - @Shadow - public abstract void sendPacket(Packet packet); - - @Shadow - public abstract void executeCommand(String input); - - @Shadow - public abstract void disconnect(Text reason); - - @Inject(method = "onChatMessage", at = @At("HEAD"), cancellable = true) - public void onChatMessage(ChatMessageC2SPacket packet, CallbackInfo ci) { - NetworkThreadUtils.forceMainThread(packet, this, player.getServerWorld()); - if (player.getClientChatVisibility() == ChatVisibility.HIDDEN) { - sendPacket(new ChatMessageS2CPacket((new TranslatableText("chat.cannotSend")).formatted(Formatting.RED))); - ci.cancel(); - } else { - player.updateLastActionTime(); - String string = packet.getChatMessage(); - string = StringUtils.normalizeSpace(string); - - for (int i = 0; i < string.length(); ++i) { - if (!SharedConstants.isValidChar(string.charAt(i))) { - disconnect(new TranslatableText("multiplayer.disconnect.illegal_characters")); - ci.cancel(); - return; - } - } - - if (string.startsWith("/")) { - executeCommand(string); - ci.cancel(); - } else { - String contentToDiscord = string; - String contentToMinecraft = string; - - if (StringUtils.countMatches(contentToDiscord, ":") >= 2) { - String[] emojiNames = StringUtils.substringsBetween(contentToDiscord, ":", ":"); - for (String emojiName : emojiNames) { - List 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.getByAlias(emojiName).isPresent()) { - 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\":\"\",\"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) { - server.getPlayerManager().broadcastChatMessage(new TranslatableText("chat.type.text", player.getDisplayName(), Text.Serializer.fromJson("[{\"text\":\"" + contentToMinecraft + "\"}]")), false); - ci.cancel(); - } - - sendMessage(contentToDiscord, false); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : string); - } - } - - messageCooldown += 20; - if (messageCooldown > 200 && !server.getPlayerManager().isOperator(player.getGameProfile())) { - disconnect(new TranslatableText("disconnect.spam")); - } - } - } - - @Inject(method = "executeCommand", at = @At(value = "HEAD")) - private void executeCommand(String input, CallbackInfo ci) { - if (CONFIG.generic.broadcastPlayerCommandExecution) { - for (String command : CONFIG.generic.excludedCommands) { - if (input.startsWith(command + " ")) { - 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 = new LiteralText("<").append(player.getDisplayName().getString()).append("> ").append(input); - - server.getPlayerManager().getPlayerList().forEach( - player -> player.sendMessage(text)); - - SERVER.sendMessage(text); - - sendMessage(input, true); - if (CONFIG.multiServer.enable) { - MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), MarkdownSanitizer.escape(input)); - } - } - } - } - - private void sendMessage(String message, boolean escapeMarkdown) { - String content = (escapeMarkdown ? MarkdownSanitizer.escape(message) : message); - - if (!CONFIG.generic.useWebhook) { - CHANNEL.sendMessage(((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] <") : "<") + player.getDisplayName().getString() + "> " + content).queue(); - } else { - JsonObject body = new JsonObject(); - body.addProperty("content", content); - body.addProperty("username", ((CONFIG.multiServer.enable) ? ("[" + CONFIG.multiServer.name + "] " + player.getDisplayName().getString()) : player.getDisplayName().getString())); - body.addProperty("avatar_url", CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUuid().toString() : player.getDisplayName().getString()))); - - 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(); - - ExecutorService executor = Executors.newFixedThreadPool(1); - executor.submit(() -> { - try { - Response response = HTTP_CLIENT.newCall(request).execute(); - response.close(); - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - }); - executor.shutdown(); - } - } -} diff --git a/versions/mapping-1.15.2-1.16.5.txt b/versions/mapping-1.15.2-1.16.5.txt new file mode 100644 index 00000000..edcc8b95 --- /dev/null +++ b/versions/mapping-1.15.2-1.16.5.txt @@ -0,0 +1,2 @@ +net.minecraft.network.chat.Component net.minecraft.network.chat.MutableComponent +net.minecraft.locale.Language getElement() getOrDefault() \ No newline at end of file From 1c8961d9280ace97b017a4a78132fb914aa09d9c Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sun, 11 Feb 2024 00:01:45 +0800 Subject: [PATCH 33/36] =?UTF-8?q?=E6=AD=BB=E4=BA=A1=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9A=E6=9B=B4=E5=A5=BD=E7=9A=84=E5=A4=9A?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minecraft/MinecraftEventListener.java | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java index ac6d6acb..e60d63b0 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/MinecraftEventListener.java @@ -13,10 +13,14 @@ import net.minecraft.ChatFormatting; import net.minecraft.advancements.DisplayInfo; import net.minecraft.network.chat.Component; +//#if MC >= 11900 +import net.minecraft.network.chat.ComponentContents; +//#endif import net.minecraft.network.chat.MutableComponent; //#if MC < 11900 //$$ import net.minecraft.network.chat.TextComponent; //#endif +import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.world.level.GameRules; import okhttp3.MediaType; import okhttp3.Request; @@ -227,7 +231,40 @@ public static void init() { MinecraftEvents.PLAYER_DIE.register((player, source) -> { if (CONFIG.generic.announceDeathMessages) { - System.out.println(source.getLocalizedDeathMessage(player)); + //#if MC >= 11900 + TranslatableContents deathMessage = (TranslatableContents) source.getLocalizedDeathMessage(player).getContents(); + //#else + //$$ TranslatableComponent deathMessage = (TranslatableComponent) source.getLocalizedDeathMessage(player); + //#endif + String key = deathMessage.getKey(); + Object[] args = new String[deathMessage.getArgs().length]; + for (int i = 0; i < deathMessage.getArgs().length; i++) { + Object object = deathMessage.getArgs()[i]; + if (object instanceof Component component) { + //#if MC >= 11900 + ComponentContents componentContents = component.getContents(); + if (componentContents instanceof TranslatableContents) { + args[i] = Translations.translate(((TranslatableContents) componentContents).getKey()); + //#else + //$$ if (component instanceof TranslatableComponent) { + //$$ args[i] = Translations.translate(((TranslatableComponent) component).getKey()); + //#endif + } else { + args[i] = component.getString(); + } + } else { + args[i] = object == null ? "null" : object.toString(); + } + } + + CHANNEL.sendMessage(Translations.translateMessage("message.deathMessage") + .replace("%deathMessage%", MarkdownSanitizer.escape(Translations.translate(key, args))) + .replace("%playerName%", MarkdownSanitizer.escape(Objects.requireNonNull(player.getDisplayName()).getString()))).queue(); + 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(player.getDisplayName().getString()))); + } } }); From 41df66ed80d407a0c000ea3ffb0fea95fd289ff0 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sun, 11 Feb 2024 00:26:57 +0800 Subject: [PATCH 34/36] Compat --- .../minecraft/mixins/MixinPlayerList.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 9c25853d..365a3336 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -49,18 +49,8 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSo //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered().serverContent().getString(), commandSourceStack); //$$ // TODO filtered() or raw() ? //$$ } - //#elseif MC > 11502 - //$$ @Inject(method = "broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V", at = @At("HEAD")) - //$$ private void broadcastMessage(Component component, ChatType chatType, UUID uUID, CallbackInfo ci) { - //$$ // TODO Check if need (uuid == Util.NIL_UUID) - //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(component.getString(), SERVER.createCommandSourceStack()); - //$$ } - //#else - //$$ @Inject(method = "broadcastMessage(Lnet/minecraft/network/chat/Component;)V", at = @At("HEAD")) - //$$ private void broadcastMessage(Component component, CallbackInfo ci) { - //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(component.getString(), SERVER.createCommandSourceStack()); - //$$ } //#endif + // TODO This feature has been removed in versions 1.18.2 and below due to compatibility issues (#197) @Inject(method = "placeNewPlayer", at = @At("RETURN")) //#if MC >= 12002 From 3fd5fb35c957e2b011fab590fcf4a8ec2101ed2f Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sun, 11 Feb 2024 03:03:23 +0800 Subject: [PATCH 35/36] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=84=E7=89=88?= =?UTF-8?q?=E6=9C=ACMixin=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mixins/MixinPlayerAdvancements.java | 2 +- .../minecraft/mixins/MixinPlayerList.java | 6 +-- .../MixinServerGamePacketListenerImpl.java | 37 +++++++++++++------ .../minecraft/mixins/MixinServerPlayer.java | 2 +- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java index b7094033..6ed179ca 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerAdvancements.java @@ -23,7 +23,7 @@ public abstract class MixinPlayerAdvancements { @Shadow public abstract AdvancementProgress getOrStartProgress(AdvancementHolder advancementHolder); - @Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = At.Shift.AFTER)) + @Inject(method = "award(Lnet/minecraft/advancements/AdvancementHolder;Ljava/lang/String;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = At.Shift.AFTER)) private void award(AdvancementHolder advancementHolder, String string, CallbackInfoReturnable cir) { MinecraftEvents.PLAYER_ADVANCEMENT.invoker().advancement(player, advancementHolder, getOrStartProgress(advancementHolder).isDone()); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java index 365a3336..5433944d 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinPlayerList.java @@ -47,21 +47,21 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CommandSo //$$ @Inject(method = "broadcastChatMessage(Lnet/minecraft/server/network/FilteredText;Lnet/minecraft/commands/CommandSourceStack;Lnet/minecraft/resources/ResourceKey;)V", at = @At("HEAD")) //$$ private void broadcastChatMessage(FilteredText filteredText, CommandSourceStack commandSourceStack, ResourceKey resourceKey, CallbackInfo ci) { //$$ MinecraftEvents.SERVER_MESSAGE.invoker().message(filteredText.filtered().serverContent().getString(), commandSourceStack); - //$$ // TODO filtered() or raw() ? //$$ } //#endif // TODO This feature has been removed in versions 1.18.2 and below due to compatibility issues (#197) - @Inject(method = "placeNewPlayer", at = @At("RETURN")) //#if MC >= 12002 + @Inject(method = "placeNewPlayer(Lnet/minecraft/network/Connection;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/server/network/CommonListenerCookie;)V", at = @At("RETURN")) private void placeNewPlayer(Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { //#else + //$$ @Inject(method = "placeNewPlayer(Lnet/minecraft/network/Connection;Lnet/minecraft/server/level/ServerPlayer;)V", at = @At("RETURN")) //$$ private void placeNewPlayer(Connection connection, ServerPlayer serverPlayer, CallbackInfo ci) { //#endif MinecraftEvents.PLAYER_JOIN.invoker().join(serverPlayer); } - @Inject(method = "remove", at = @At("HEAD")) + @Inject(method = "remove(Lnet/minecraft/server/level/ServerPlayer;)V", at = @At("HEAD")) private void remove(ServerPlayer serverPlayer, CallbackInfo ci) { MinecraftEvents.PLAYER_QUIT.invoker().quit(serverPlayer); } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java index e69c4553..1bace8a1 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerGamePacketListenerImpl.java @@ -30,6 +30,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//#if MC == 11900 +//$$ import java.util.Objects; +//#endif import java.util.Optional; import static com.xujiayao.mcdiscordchat.Main.SERVER; @@ -43,21 +46,26 @@ public class MixinServerGamePacketListenerImpl { @Shadow private ServerPlayer player; - //#if MC > 11802 - @Inject(method = "broadcastChatMessage", at = @At("HEAD"), cancellable = true) + //#if MC > 11900 + @Inject(method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;)V", at = @At("HEAD"), cancellable = true) private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackInfo ci) { Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, playerChatMessage.decoratedContent().getString()); if (result.isPresent()) { - //#if MC > 11900 SERVER.getPlayerList().broadcastChatMessage(playerChatMessage.withUnsignedContent(result.get()), this.player, ChatType.bind(ChatType.CHAT, player)); - //#else - //$$ SERVER.getPlayerList().broadcastChatMessage(FilteredText.passThrough(playerChatMessage.withUnsignedContent(result.get())), this.player, ChatType.CHAT); - //#endif ci.cancel(); } } + //#elseif MC == 11900 + //$$ @Inject(method = "broadcastChatMessage(Lnet/minecraft/server/network/FilteredText;)V", at = @At("HEAD"), cancellable = true) + //$$ private void broadcastChatMessage(FilteredText filteredText, CallbackInfo ci) { + //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, Objects.requireNonNull(filteredText.filtered()).serverContent().getString()); + //$$ if (result.isPresent()) { + //$$ SERVER.getPlayerList().broadcastChatMessage(FilteredText.passThrough(filteredText.filtered().withUnsignedContent(result.get())), this.player, ChatType.CHAT); + //$$ ci.cancel(); + //$$ } + //$$ } //#elseif MC > 11605 - //$$ @Inject(method = "handleChat(Lnet/minecraft/server/network/TextFilter$FilteredText;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Ljava/util/Function;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) + //$$ @Inject(method = "handleChat(Lnet/minecraft/server/network/TextFilter$FilteredText;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Ljava/util/function/Function;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true) //$$ private void handleChat(TextFilter.FilteredText filteredText, CallbackInfo ci) { //$$ Optional result = MinecraftEvents.PLAYER_MESSAGE.invoker().message(player, filteredText.getFiltered()); //$$ if (result.isPresent()) { @@ -88,18 +96,23 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, CallbackI //$$ } //#endif - //#if MC > 11900 - @Inject(method = "performChatCommand", at = @At("HEAD")) + //#if MC >= 11903 + @Inject(method = "performChatCommand(Lnet/minecraft/network/protocol/game/ServerboundChatCommandPacket;Lnet/minecraft/network/chat/LastSeenMessages;)V", at = @At("HEAD")) private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, LastSeenMessages lastSeenMessages, CallbackInfo ci) { MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); } - //#elseif MC > 11802 - //$$ @Inject(method = "handleChatCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)V")) + //#elseif MC > 11900 + //$$ @Inject(method = "performChatCommand(Lnet/minecraft/network/protocol/game/ServerboundChatCommandPacket;)V", at = @At("HEAD")) + //$$ private void performChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) { + //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); + //$$ } + //#elseif MC == 11900 + //$$ @Inject(method = "handleChatCommand(Lnet/minecraft/network/protocol/game/ServerboundChatCommandPacket;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)I")) //$$ private void handleChatCommand(ServerboundChatCommandPacket serverboundChatCommandPacket, CallbackInfo ci) { //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, "/" + serverboundChatCommandPacket.command()); //$$ } //#else - //$$ @Inject(method = "handleCommand", at = @At("HEAD")) + //$$ @Inject(method = "handleCommand(Ljava/lang/String;)V", at = @At("HEAD")) //$$ private void handleCommand(String string, CallbackInfo ci) { //$$ MinecraftEvents.PLAYER_COMMAND.invoker().command(player, string); //$$ } diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java index 844f6b55..fc285512 100644 --- a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinServerPlayer.java @@ -14,7 +14,7 @@ @Mixin(ServerPlayer.class) public class MixinServerPlayer { - @Inject(method = "die", at = @At("HEAD")) + @Inject(method = "die(Lnet/minecraft/world/damagesource/DamageSource;)V", at = @At("HEAD")) private void die(DamageSource damageSource, CallbackInfo ci) { MinecraftEvents.PLAYER_DIE.invoker().die((ServerPlayer) (Object) this, damageSource); } From 979f18ffc4331d7bdea68235b0742207d0ef44f8 Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Sun, 11 Feb 2024 03:54:45 +0800 Subject: [PATCH 36/36] MixinLanguage --- build.gradle | 4 +- .../minecraft/mixins/MixinLanguage.java | 13 ++++ src/main/resources/mcdiscordchat.mixins.json | 1 + .../minecraft/mixins/MixinLanguage.java | 59 +++++++++++++++++ .../minecraft/mixins/MixinLanguage.java | 65 +++++++++++++++++++ 5 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java create mode 100644 versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java create mode 100644 versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java diff --git a/build.gradle b/build.gradle index f4f2c859..a53e4845 100644 --- a/build.gradle +++ b/build.gradle @@ -4,10 +4,10 @@ plugins { } preprocess { - def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") // TODO Check MixinLanguage + def mc1152 = createNode("compat_1.15.2", 1_15_02, "mojang") def mc1165 = createNode("compat_1.16.5", 1_16_05, "mojang") def mc1171 = createNode("compat_1.17.1", 1_17_01, "mojang") - def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") // TODO Check MixinLanguage + def mc1182 = createNode("compat_1.18.2", 1_18_02, "mojang") def mc1190 = createNode("compat_1.19" , 1_19_00, "mojang") def mc1192 = createNode("1.19.2", 1_19_02, "mojang") def mc1193 = createNode("1.19.3", 1_19_03, "mojang") diff --git a/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java new file mode 100644 index 00000000..c62cfe60 --- /dev/null +++ b/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java @@ -0,0 +1,13 @@ +//#if MC >= 11900 +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import net.minecraft.locale.Language; +import org.spongepowered.asm.mixin.Mixin; + +/** + * @author Xujiayao + */ +@Mixin(Language.class) +public class MixinLanguage { +} +//#endif diff --git a/src/main/resources/mcdiscordchat.mixins.json b/src/main/resources/mcdiscordchat.mixins.json index 7c38e246..1ba5c0b0 100644 --- a/src/main/resources/mcdiscordchat.mixins.json +++ b/src/main/resources/mcdiscordchat.mixins.json @@ -3,6 +3,7 @@ "package": "com.xujiayao.mcdiscordchat.minecraft.mixins", "compatibilityLevel": "JAVA_17", "mixins": [ + "MixinLanguage", "MixinPlayerAdvancements", "MixinPlayerList", "MixinServerGamePacketListenerImpl", diff --git a/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java b/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java new file mode 100644 index 00000000..915bf3b2 --- /dev/null +++ b/versions/compat_1.15.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java @@ -0,0 +1,59 @@ +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.locale.Language; +import net.minecraft.util.GsonHelper; +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 java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Pattern; + +import static com.xujiayao.mcdiscordchat.Main.LOGGER; + +/** + * @author Xujiayao + */ +@Mixin(Language.class) +public class MixinLanguage { + + @Final + @Shadow + private static Pattern UNSUPPORTED_FORMAT_PATTERN; + + @Final + @Shadow + private Map storage; + + @Inject(method = "", at = @At(value = "RETURN")) + private void Language(CallbackInfo ci) { + FabricLoader.getInstance().getAllMods().forEach(modContainer -> { + Optional optional = modContainer.findPath("/assets/" + modContainer.getMetadata().getId() + "/lang/en_us.json"); + + if (optional.isPresent()) { + try (InputStream inputStream = Files.newInputStream(optional.get())) { + JsonObject json = new Gson().fromJson(new InputStreamReader(inputStream, StandardCharsets.UTF_8), JsonObject.class); + for (Map.Entry entry : json.entrySet()) { + String string = UNSUPPORTED_FORMAT_PATTERN.matcher(GsonHelper.convertToString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); + storage.put(entry.getKey(), string); + } + } catch (Exception e) { + LOGGER.error("Couldn't read strings from /assets/{}", modContainer.getMetadata().getId() + "/lang/en_us.json", e); + } + } + }); + } +} diff --git a/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java b/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java new file mode 100644 index 00000000..f15b1043 --- /dev/null +++ b/versions/compat_1.18.2/src/main/java/com/xujiayao/mcdiscordchat/minecraft/mixins/MixinLanguage.java @@ -0,0 +1,65 @@ +//#if MC >= 11600 +package com.xujiayao.mcdiscordchat.minecraft.mixins; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.locale.Language; +import net.minecraft.util.GsonHelper; +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.ModifyVariable; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Pattern; + +import static com.xujiayao.mcdiscordchat.Main.LOGGER; + +/** + * @author Xujiayao + */ +@Mixin(Language.class) +public class MixinLanguage { + + @Final + @Shadow + private static Gson GSON; + + @Final + @Shadow + private static Pattern UNSUPPORTED_FORMAT_PATTERN; + + @ModifyVariable(method = "loadDefault()Lnet/minecraft/locale/Language;", at = @At("STORE"), ordinal = 0) + private static Map mapInjected(Map originalMap) { + Map map = new HashMap<>(originalMap); + + FabricLoader.getInstance().getAllMods().forEach(modContainer -> { + Optional optional = modContainer.findPath("/assets/" + modContainer.getMetadata().getId() + "/lang/en_us.json"); + + if (optional.isPresent()) { + try (InputStream inputStream = Files.newInputStream(optional.get())) { + JsonObject json = GSON.fromJson(new InputStreamReader(inputStream, StandardCharsets.UTF_8), JsonObject.class); + for (Map.Entry entry : json.entrySet()) { + String string = UNSUPPORTED_FORMAT_PATTERN.matcher(GsonHelper.convertToString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); + map.put(entry.getKey(), string); + } + } catch (Exception e) { + LOGGER.error("Couldn't read strings from /assets/{}", modContainer.getMetadata().getId() + "/lang/en_us.json", e); + } + } + }); + + return map; + } +} +//#endif