From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 Date: Mon, 29 Apr 2024 14:49:37 +0900 Subject: [PATCH] Implement FreedomChat ocelotpotpie/FreedomChat Copyright (C) 2022-2024 ocelotpotpie, Licensed under GNU GPL v3.0 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java index 560962109d43d27ba0681afe36e6324ae2a93867..97df4706150dd198dc9bbdd3bdcecea9094d3b62 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -710,6 +710,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface // Paper start - Add setting for proxy online mode status return dedicatedserverproperties.enforceSecureProfile && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() + && !org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.freedomChat.enabled // Plazma - Implement FreedomChat && this.services.canValidateProfileKeys(); // Paper end - Add setting for proxy online mode status } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index f78a0a224c86c0e3e5a44ce4f589cd8a61c546f9..69ff5380eedb3e0b214324dec50bb5c0eb65001b 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -135,6 +135,7 @@ public abstract class PlayerList { private static final Logger LOGGER = LogUtils.getLogger(); private static final int SEND_PLAYER_INFO_INTERVAL = 600; private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); + private static final ru.bk.oharass.freedomchat.FreedomChat FREEDOM_HANDLER = new ru.bk.oharass.freedomchat.FreedomChat(); // Plazma - Implement FreedomChat private final MinecraftServer server; public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety private final Map playersByUUID = Maps.newHashMap(); @@ -285,6 +286,7 @@ public abstract class PlayerList { // CraftBukkit - Moved message to after join // PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", new Object[]{entityplayer.getName().getString(), s1, entityplayer.getId(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ()}); LevelData worlddata = worldserver1.getLevelData(); + connection.channel.pipeline().addAfter("packet_handler", "freedom_handler", FREEDOM_HANDLER); // Plazma - Implement FreedomChat player.loadGameTypes((CompoundTag) optional.orElse(null)); // CraftBukkit - decompile error ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, clientData); diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java index 516a4545b67a4bf0d37cee3d1e26772831944fe6..451723377d505f1fe15ddd4ac535ca61fa253f17 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java @@ -29,6 +29,15 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean checkSpectatorMovedToQuickly = !OPTIMIZE; + public FreedomChat freedomChat; + public class FreedomChat extends ConfigurationPart { + + public boolean enabled = false; + public boolean rewriteChat = true; + public boolean noChatReports = true; + + } + } @Setting("world-generation") diff --git a/src/main/java/ru/bk/oharass/freedomchat/FreedomChat.java b/src/main/java/ru/bk/oharass/freedomchat/FreedomChat.java new file mode 100644 index 0000000000000000000000000000000000000000..49290983ef6b63bbacdef30f774ce683228e5755 --- /dev/null +++ b/src/main/java/ru/bk/oharass/freedomchat/FreedomChat.java @@ -0,0 +1,103 @@ +package ru.bk.oharass.freedomchat; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket; +import net.minecraft.network.protocol.game.ClientboundSystemChatPacket; +import net.minecraft.network.protocol.game.GameProtocols; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.server.MinecraftServer; + +import java.util.Objects; +import java.util.Optional; + +import static org.plazmamc.plazma.configurations.GlobalConfiguration.get; + +@ChannelHandler.Sharable +public class FreedomChat extends MessageToByteEncoder> { + + private static final StreamCodec> CODEC = GameProtocols.CLIENTBOUND_TEMPLATE + .bind(RegistryFriendlyByteBuf.decorator(MinecraftServer.getServer().registryAccess())).codec(); + + @Override + public boolean acceptOutboundMessage(final Object msg) { + return get().player.freedomChat.rewriteChat && msg instanceof ClientboundPlayerChatPacket + || get().player.freedomChat.noChatReports && msg instanceof ClientboundStatusResponsePacket; + } + + @Override + protected void encode( + final ChannelHandlerContext context, final Packet packet, final ByteBuf byteBuf + ) throws Exception { + final FriendlyByteBuf buf = new FriendlyByteBuf(byteBuf); + + switch (packet) { + case ClientboundPlayerChatPacket chat -> encodeChat(context, chat, buf); + case ClientboundStatusResponsePacket data -> encodeQuery(context, data, buf); + default -> {} + } + } + + private static void encodeChat( + final ChannelHandlerContext ignored, final ClientboundPlayerChatPacket packet, final FriendlyByteBuf byteBuf + ) { + final Component content = Objects.requireNonNullElseGet( + packet.unsignedContent(), + () -> Component.literal(packet.body().content()) + ); + + CODEC.encode(byteBuf, new ClientboundSystemChatPacket(packet.chatType().decorate(content), false)); + } + + private static void encodeQuery( + final ChannelHandlerContext ignored, final ClientboundStatusResponsePacket packet, final FriendlyByteBuf byteBuf + ) { + byteBuf.writeVarInt(0x00); + byteBuf.writeJsonWithCodec(NCRMetadata.CODEC, NCRMetadata.from(packet.status())); + } + + private record NCRMetadata( + Component description, + Optional players, + Optional version, + Optional favicon, + boolean enforcesSecureChat, + boolean preventsChatReports + ) { + + private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + ComponentSerialization.CODEC.lenientOptionalFieldOf("description", CommonComponents.EMPTY).forGetter(NCRMetadata::description), + ServerStatus.Players.CODEC.lenientOptionalFieldOf("players").forGetter(NCRMetadata::players), + ServerStatus.Version.CODEC.lenientOptionalFieldOf("version").forGetter(NCRMetadata::version), + ServerStatus.Favicon.CODEC.lenientOptionalFieldOf("favicon").forGetter(NCRMetadata::favicon), + Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", true).forGetter(NCRMetadata::enforcesSecureChat), + Codec.BOOL.lenientOptionalFieldOf("preventsChatReports", false).forGetter(NCRMetadata::preventsChatReports) + ).apply(instance, NCRMetadata::new)); + + private static NCRMetadata from(final ServerStatus status) { + return new NCRMetadata( + status.description(), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat() && !get().player.freedomChat.enabled, + get().player.freedomChat.noChatReports + ); + } + + } + +}