-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
218 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 34 additions & 50 deletions
84
fabric/src/main/java/ru/bk/oharass/freedomchat/FreedomHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,83 @@ | ||
package ru.bk.oharass.freedomchat; | ||
|
||
import com.google.gson.JsonObject; | ||
import com.mojang.serialization.JsonOps; | ||
import io.netty.buffer.ByteBuf; | ||
import io.netty.channel.ChannelHandler; | ||
import io.netty.channel.ChannelHandlerContext; | ||
import io.netty.handler.codec.EncoderException; | ||
import io.netty.handler.codec.MessageToByteEncoder; | ||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; | ||
import net.minecraft.network.ClientConnection; | ||
import net.minecraft.network.PacketByteBuf; | ||
import net.minecraft.network.RegistryByteBuf; | ||
import net.minecraft.network.codec.PacketCodec; | ||
import net.minecraft.network.listener.ClientPlayPacketListener; | ||
import net.minecraft.network.message.MessageType; | ||
import net.minecraft.network.packet.Packet; | ||
import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket; | ||
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; | ||
import net.minecraft.network.packet.s2c.play.ServerMetadataS2CPacket; | ||
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket; | ||
import net.minecraft.network.state.PlayStateFactories; | ||
import net.minecraft.registry.DynamicRegistryManager; | ||
import net.minecraft.server.ServerMetadata; | ||
import net.minecraft.text.Text; | ||
import ru.bk.oharass.freedomchat.rewrite.CustomServerMetadata; | ||
|
||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.function.Function; | ||
|
||
@ChannelHandler.Sharable | ||
public class FreedomHandler extends MessageToByteEncoder<Packet<?>> { | ||
|
||
private static final int STATUS_RESPONSE_PACKET_ID = 0x00; | ||
private final PacketCodec<ByteBuf, Packet<? super ClientPlayPacketListener>> s2cPlayPacketCodec; | ||
private final boolean rewriteChat; | ||
private final boolean claimSecureChatEnforced; | ||
private final boolean noChatReports; | ||
private final FreedomChat freedom; | ||
|
||
public FreedomHandler(boolean rewriteChat, boolean claimSecureChatEnforced, boolean noChatReports, final FreedomChat freedom) { | ||
public FreedomHandler(final FreedomChat freedom, final boolean rewriteChat, final boolean noChatReports) { | ||
final DynamicRegistryManager registryAccess = freedom.getServer().getRegistryManager(); | ||
final Function<ByteBuf, RegistryByteBuf> bufRegistryAccess = RegistryByteBuf.makeFactory(registryAccess); | ||
this.s2cPlayPacketCodec = PlayStateFactories.S2C.bind(bufRegistryAccess).codec(); | ||
this.rewriteChat = rewriteChat; | ||
this.claimSecureChatEnforced = claimSecureChatEnforced; | ||
this.noChatReports = noChatReports; | ||
this.freedom = freedom; | ||
} | ||
|
||
@Override | ||
public boolean acceptOutboundMessage(Object msg) { | ||
public boolean acceptOutboundMessage(final Object msg) { | ||
return rewriteChat && msg instanceof ChatMessageS2CPacket | ||
|| noChatReports && msg instanceof QueryResponseS2CPacket | ||
|| claimSecureChatEnforced && msg instanceof ServerMetadataS2CPacket; | ||
|| noChatReports && msg instanceof QueryResponseS2CPacket; | ||
} | ||
|
||
@Override | ||
protected void encode(ChannelHandlerContext ctx, Packet msg, ByteBuf out) { | ||
protected void encode(final ChannelHandlerContext ctx, final Packet msg, final ByteBuf out) { | ||
final PacketByteBuf fbb = new PacketByteBuf(out); | ||
|
||
if (msg instanceof ChatMessageS2CPacket packet) { | ||
encode(ctx, packet, fbb); | ||
} else if (msg instanceof ServerMetadataS2CPacket packet) { | ||
if (msg instanceof final ChatMessageS2CPacket packet) { | ||
encode(ctx, packet, fbb); | ||
} else if (msg instanceof QueryResponseS2CPacket packet) { | ||
} else if (msg instanceof final QueryResponseS2CPacket packet) { | ||
encode(ctx, packet, fbb); | ||
} | ||
} | ||
|
||
private void encode(final ChannelHandlerContext ctx, final ChatMessageS2CPacket msg, final PacketByteBuf buf) { | ||
private void encode(@SuppressWarnings("unused") final ChannelHandlerContext ctx, final ChatMessageS2CPacket msg, final PacketByteBuf buf) { | ||
final Text content = Objects.requireNonNullElseGet(msg.unsignedContent(), () -> Text.literal(msg.body().content())); | ||
|
||
final Optional<MessageType.Parameters> ctbo = msg.serializedParameters().toParameters(freedom.getServer().getRegistryManager()); | ||
if (ctbo.isEmpty()) { | ||
freedom.getLogger().warn("Processing packet with unknown ChatType " + msg.serializedParameters().typeId(), new Throwable()); | ||
return; | ||
} | ||
final Text decoratedContent = ctbo.orElseThrow().applyChatDecoration(content); | ||
final MessageType.Parameters chatType = msg.serializedParameters(); | ||
final Text decoratedContent = chatType.applyChatDecoration(content); | ||
|
||
final GameMessageS2CPacket system = new GameMessageS2CPacket(decoratedContent, false); | ||
writeId(ctx, system, buf); | ||
system.write(buf); | ||
} | ||
|
||
private void encode(final ChannelHandlerContext ctx, final ServerMetadataS2CPacket msg, final PacketByteBuf buf) { | ||
writeId(ctx, msg, buf); | ||
buf.writeText(msg.getDescription()); | ||
buf.writeOptional(msg.getFavicon(), PacketByteBuf::writeByteArray); | ||
buf.writeBoolean(true); | ||
s2cPlayPacketCodec.encode(buf, system); | ||
} | ||
|
||
private void encode(final ChannelHandlerContext ctx, final QueryResponseS2CPacket msg, final PacketByteBuf buf) { | ||
final JsonObject status = ServerMetadata.CODEC | ||
.encodeStart(JsonOps.INSTANCE, msg.metadata()) | ||
.get() | ||
.left() | ||
.orElseThrow(() -> new EncoderException("Failed to encode ServerStatus")) | ||
.getAsJsonObject(); | ||
|
||
status.addProperty("preventsChatReports", true); | ||
private void encode(@SuppressWarnings("unused") final ChannelHandlerContext ctx, final QueryResponseS2CPacket msg, final PacketByteBuf buf) { | ||
final ServerMetadata status = msg.metadata(); | ||
|
||
writeId(ctx, msg, buf); | ||
buf.writeString(GsonComponentSerializer.gson().serializer().toJson(status)); | ||
} | ||
final CustomServerMetadata customStatus = new CustomServerMetadata( | ||
status.description(), | ||
status.players(), | ||
status.version(), | ||
status.favicon(), | ||
status.secureChatEnforced(), | ||
true | ||
); | ||
|
||
private void writeId(final ChannelHandlerContext ctx, final Packet<?> packet, final PacketByteBuf buf) { | ||
buf.writeVarInt(ctx.channel().attr(ClientConnection.CLIENTBOUND_PROTOCOL_KEY).get().getId(packet)); | ||
buf.writeVarInt(STATUS_RESPONSE_PACKET_ID); | ||
buf.encodeAsJson(CustomServerMetadata.CODEC, customStatus); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
fabric/src/main/java/ru/bk/oharass/freedomchat/rewrite/CustomServerMetadata.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package ru.bk.oharass.freedomchat.rewrite; | ||
|
||
import com.mojang.serialization.Codec; | ||
import com.mojang.serialization.codecs.RecordCodecBuilder; | ||
import net.minecraft.screen.ScreenTexts; | ||
import net.minecraft.server.ServerMetadata; | ||
import net.minecraft.text.Text; | ||
import net.minecraft.text.TextCodecs; | ||
|
||
import java.util.Optional; | ||
|
||
public record CustomServerMetadata(Text description, Optional<ServerMetadata.Players> players, | ||
Optional<ServerMetadata.Version> version, Optional<ServerMetadata.Favicon> favicon, | ||
boolean secureChatEnforced, boolean preventsChatReports) { | ||
public static final Codec<CustomServerMetadata> CODEC = RecordCodecBuilder | ||
.create((instance) -> instance.group( | ||
TextCodecs.CODEC.lenientOptionalFieldOf("description", ScreenTexts.EMPTY) | ||
.forGetter(CustomServerMetadata::description), | ||
ServerMetadata.Players.CODEC.lenientOptionalFieldOf("players") | ||
.forGetter(CustomServerMetadata::players), | ||
ServerMetadata.Version.CODEC.lenientOptionalFieldOf("version") | ||
.forGetter(CustomServerMetadata::version), | ||
ServerMetadata.Favicon.CODEC.lenientOptionalFieldOf("favicon") | ||
.forGetter(CustomServerMetadata::favicon), | ||
Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", false) | ||
.forGetter(CustomServerMetadata::secureChatEnforced), | ||
Codec.BOOL.lenientOptionalFieldOf("preventsChatReports", true) | ||
.forGetter(CustomServerMetadata::preventsChatReports)) | ||
.apply(instance, CustomServerMetadata::new)); | ||
|
||
public Text description() { | ||
return this.description; | ||
} | ||
|
||
public Optional<ServerMetadata.Players> players() { | ||
return this.players; | ||
} | ||
|
||
public Optional<ServerMetadata.Version> version() { | ||
return this.version; | ||
} | ||
|
||
public Optional<ServerMetadata.Favicon> favicon() { | ||
return this.favicon; | ||
} | ||
|
||
public boolean secureChatEnforced() { | ||
return this.secureChatEnforced; | ||
} | ||
|
||
public boolean preventsChatReports() { | ||
return this.preventsChatReports; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.