From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Tue, 4 Feb 2025 01:49:17 +0300 Subject: [PATCH] Implement NoChatReports diff --git a/net/minecraft/network/FriendlyByteBuf.java b/net/minecraft/network/FriendlyByteBuf.java index d1daa3443446f47e2215f0c7c5823da58e053bab..61b1440ee7909946cd2d7a4d8622f79c6f6ac76b 100644 --- a/net/minecraft/network/FriendlyByteBuf.java +++ b/net/minecraft/network/FriendlyByteBuf.java @@ -105,7 +105,28 @@ public class FriendlyByteBuf extends ByteBuf { return this; } + @SuppressWarnings({"unchecked", "rawtypes"}) // DivineMC - Implement NoChatReports public T readJsonWithCodec(Codec codec) { + // DivineMC start - Implement NoChatReports + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { + JsonElement jsonElement = GsonHelper.fromJson(GSON, this.readUtf(), JsonElement.class); + DataResult dataResult = codec.parse(JsonOps.INSTANCE, jsonElement); + Object result; + try { + result = dataResult.getOrThrow(string -> new DecoderException("Failed to decode json: " + string)); + } catch (Throwable e) { + throw new RuntimeException("Unable to decode json!", e); + } + + if (jsonElement.getAsJsonObject().has("preventsChatReports")) { + ((net.minecraft.network.protocol.status.ServerStatus) result).setPreventsChatReports(jsonElement.getAsJsonObject().get("preventsChatReports").getAsBoolean()); + } + + return (T) (result); + } + } + // DivineMC end - Implement NoChatReports JsonElement jsonElement = GsonHelper.fromJson(GSON, this.readUtf(), JsonElement.class); DataResult dataResult = codec.parse(JsonOps.INSTANCE, jsonElement); return dataResult.getOrThrow(exception -> new DecoderException("Failed to decode json: " + exception)); @@ -117,6 +138,19 @@ public class FriendlyByteBuf extends ByteBuf { } public void writeJsonWithCodec(Codec codec, T value, int maxLength) { // Paper end - Adventure; add max length parameter + // DivineMC start - Implement NoChatReports + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + if (org.bxteam.divinemc.DivineConfig.noChatReportsAddQueryData && codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { + DataResult dataResult = codec.encodeStart(JsonOps.INSTANCE, value); + JsonElement element = dataResult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value)); + + element.getAsJsonObject().addProperty("preventsChatReports", true); + + this.writeUtf(GSON.toJson(element)); + return; + } + } + // DivineMC end - Implement NoChatReports DataResult dataResult = codec.encodeStart(JsonOps.INSTANCE, value); this.writeUtf(GSON.toJson(dataResult.getOrThrow(exception -> new EncoderException("Failed to encode: " + exception + " " + value))), maxLength); // Paper - Adventure; add max length parameter } diff --git a/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java b/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java index 07943553b562b95076bdce232d6f0796f469400f..61ecf4c6ae37b13ed42dff8d4165d32f3a5cc0c9 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java +++ b/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java @@ -36,4 +36,15 @@ public record ServerboundChatCommandSignedPacket( public void handle(ServerGamePacketListener handler) { handler.handleSignedChatCommand(this); } + + // DivineMC start - Implement NoChatReports + @Override + public ArgumentSignatures argumentSignatures() { + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + return ArgumentSignatures.EMPTY; + } + + return argumentSignatures; + } + // DivineMC end - Implement NoChatReports } diff --git a/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/net/minecraft/network/protocol/game/ServerboundChatPacket.java index b5afc05924ae899e020c303c8b86398e1d4ab8a0..3af0436ac2dff04cfaa1b3dda11a5417f2c0890c 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatPacket.java +++ b/net/minecraft/network/protocol/game/ServerboundChatPacket.java @@ -36,4 +36,16 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt public void handle(ServerGamePacketListener handler) { handler.handleChat(this); } + + // DivineMC start - Implement NoChatReports + @Override + @Nullable + public MessageSignature signature() { + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + return null; + } + + return signature; + } + // DivineMC end - Implement NoChatReports } diff --git a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java index 1df628ac0b414511aaed6e09d78f884c4170f730..d94858facc06d57139e953796ee09dad17648dbb 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java +++ b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java @@ -26,6 +26,19 @@ public record ServerboundChatSessionUpdatePacket(RemoteChatSession.Data chatSess @Override public void handle(ServerGamePacketListener handler) { + // DivineMC start - Implement NoChatReports + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + var impl = (net.minecraft.server.network.ServerGamePacketListenerImpl) handler; + + if (!impl.getPlayer().getServer().isSingleplayerOwner(impl.getPlayer().getGameProfile())) { + if (org.bxteam.divinemc.DivineConfig.noChatReportsDemandOnClient) { + impl.disconnect(net.minecraft.network.chat.Component.literal(org.bxteam.divinemc.DivineConfig.noChatReportsDisconnectDemandOnClientMessage)); + } + } + + return; + } + // DivineMC end - Implement NoChatReports handler.handleChatSessionUpdate(this); } } diff --git a/net/minecraft/network/protocol/status/ServerStatus.java b/net/minecraft/network/protocol/status/ServerStatus.java index 30bd254542d631676494f349ff3f44f52d54ab2f..6c728ae3b58bc1b8449d34c6c74091612b79f39e 100644 --- a/net/minecraft/network/protocol/status/ServerStatus.java +++ b/net/minecraft/network/protocol/status/ServerStatus.java @@ -15,13 +15,7 @@ import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentSerialization; -public record ServerStatus( - Component description, - Optional players, - Optional version, - Optional favicon, - boolean enforcesSecureChat -) { +public final class ServerStatus { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( ComponentSerialization.CODEC.lenientOptionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description), @@ -33,6 +27,63 @@ public record ServerStatus( .apply(instance, ServerStatus::new) ); + // DivineMC start - Implement NoChatReports - convert to class + private final Component description; + private final Optional players; + private final Optional version; + private final Optional favicon; + private final boolean enforcesSecureChat; + private boolean preventsChatReports; + + public ServerStatus( + Component description, + Optional players, + Optional version, + Optional favicon, + boolean enforcesSecureChat + ) { + this.description = description; + this.players = players; + this.version = version; + this.favicon = favicon; + this.enforcesSecureChat = enforcesSecureChat; + } + + public Component description() { + return description; + } + + public Optional players() { + return players; + } + + public Optional version() { + return version; + } + + public Optional favicon() { + return favicon; + } + + public boolean enforcesSecureChat() { + return enforcesSecureChat; + } + + public boolean preventsChatReports() { + var self = (ServerStatus) (Object) this; + + if (self.version().isPresent() && self.version().get().protocol() < 759 + && self.version().get().protocol() > 0) + return true; + + return this.preventsChatReports; + } + + public void setPreventsChatReports(boolean prevents) { + this.preventsChatReports = prevents; + } + // DivineMC end - Implement NoChatReports + public record Favicon(byte[] iconBytes) { private static final String PREFIX = "data:image/png;base64,"; public static final Codec CODEC = Codec.STRING.comapFlatMap(string -> { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java index d3431511fdc6c3e807ea4dfcf877ebe088ff90bd..fb02ec67234e46a55d68d2b4b1c7a6ba56f9995a 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -688,6 +688,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @Override public boolean enforceSecureProfile() { + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) return false; // DivineMC - Implement NoChatReports DedicatedServerProperties properties = this.getProperties(); // Paper start - Add setting for proxy online mode status return properties.enforceSecureProfile diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java index 801dd76a2c7f76fc6fdb7167cbf3ab1310be36c9..4fa55fac5dab26a505cba2c1876e9459a582da12 100644 --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java @@ -312,10 +312,64 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public void send(Packet packet) { + // DivineMC start - Implement NoChatReports + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + Object self = this; + boolean cancel = false; + + if (self instanceof ServerGamePacketListenerImpl listener) { + if (org.bxteam.divinemc.DivineConfig.noChatReportsDebugLog && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + MinecraftServer.LOGGER.info("Sending message: {}", chat.unsignedContent() != null ? chat.unsignedContent() + : chat.body().content()); + } + + if (org.bxteam.divinemc.DivineConfig.noChatReportsConvertToGameMessage) { + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().decorate( + chat.unsignedContent() != null ? chat.unsignedContent() + : Component.literal(chat.body().content()) + ), false); + + cancel = true; + listener.send(packet); + } + } + } + + if (cancel) { + return; + } + } + // DivineMC end - Implement NoChatReports this.send(packet, null); } public void send(Packet packet, @Nullable PacketSendListener listener) { + // DivineMC start - Implement NoChatReports + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { + Object self = this; + boolean cancel = false; + + if (self instanceof ServerGamePacketListenerImpl listenerImpl) { + if (org.bxteam.divinemc.DivineConfig.noChatReportsDebugLog && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + MinecraftServer.LOGGER.info("Sending message: {}", chat.unsignedContent() != null ? chat.unsignedContent() + : chat.body().content()); + } + + if (org.bxteam.divinemc.DivineConfig.noChatReportsConvertToGameMessage) { + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && listener != null) { + cancel = true; + listenerImpl.send(chat); + } + } + + } + + if (cancel) { + return; + } + } + // DivineMC end - Implement NoChatReports // CraftBukkit start if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java index 5ff0ce34cfacb745748d3dc627127842ac1df9fa..0483b754ab9c9da4eaa62101198007d12174cf84 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -274,7 +274,7 @@ public abstract class PlayerList { !_boolean, _boolean2, player.createCommonSpawnInfo(serverLevel), - this.server.enforceSecureProfile() + org.bxteam.divinemc.DivineConfig.noChatReportsEnabled || this.server.enforceSecureProfile() // DivineMC - Implement NoChatReports ) ); player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit @@ -1333,6 +1333,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public + if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) return true; // DivineMC - Implement NoChatReports return message.hasSignature() && !message.hasExpiredServer(Instant.now()); }