Skip to content

Commit

Permalink
Rely on ClientboundPlayerChatPacket for C2C packets (#641)
Browse files Browse the repository at this point in the history
  • Loading branch information
xpple authored Jun 11, 2024
1 parent 2b7d072 commit 8e8f520
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.earthcomputer.clientcommands.c2c;

import net.minecraft.network.protocol.Packet;

public interface C2CPacket extends Packet<C2CPacketListener> {
String sender();
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class C2CPacketHandler implements C2CPacketListener {
.addPacket(PutTicTacToeMarkC2CPacket.ID, PutTicTacToeMarkC2CPacket.CODEC)
);

public static final String C2C_PACKET_HEADER = "CCΕNC:";

private static final C2CPacketHandler instance = new C2CPacketHandler();

private C2CPacketHandler() {
Expand Down Expand Up @@ -106,7 +108,7 @@ public void sendPacket(Packet<C2CPacketListener> packet, PlayerInfo recipient) t
System.arraycopy(encrypted[i], 0, joined, i * 256, 256);
}
String packetString = ConversionHelper.BaseUTF8.toUnicode(joined);
String commandString = "w " + recipient.getProfile().getName() + " CCENC:" + packetString;
String commandString = "w " + recipient.getProfile().getName() + ' ' + C2C_PACKET_HEADER + packetString;
if (commandString.length() >= SharedConstants.MAX_CHAT_LENGTH) {
throw MESSAGE_TOO_LONG_EXCEPTION.create(commandString.length());
}
Expand All @@ -115,7 +117,7 @@ public void sendPacket(Packet<C2CPacketListener> packet, PlayerInfo recipient) t
OutgoingPacketFilter.addPacket(packetString);
}

public static boolean handleC2CPacket(String content) {
public static boolean handleC2CPacket(String content, String sender) {
byte[] encrypted = ConversionHelper.BaseUTF8.fromUnicode(content);
// round down to multiple of 256 bytes
int length = encrypted.length & ~0xFF;
Expand Down Expand Up @@ -157,9 +159,9 @@ public static boolean handleC2CPacket(String content) {
return false;
}
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(uncompressed));
Packet<? super C2CPacketListener> packet;
C2CPacket packet;
try {
packet = protocolInfo.codec().decode(buf);
packet = (C2CPacket) protocolInfo.codec().decode(buf);
} catch (Throwable e) {
LOGGER.error("Error decoding C2C packet", e);
return false;
Expand All @@ -168,6 +170,10 @@ public static boolean handleC2CPacket(String content) {
LOGGER.error("Found extra bytes while reading C2C packet {}", packet.type());
return false;
}
if (!packet.sender().equals(sender)) {
LOGGER.error("Detected mismatching packet sender. Expected {}, got {}", sender, packet.sender());
return false;
}
ListenCommand.onPacket(packet, ListenCommand.PacketFlow.C2C_INBOUND);
try {
packet.handle(C2CPacketHandler.getInstance());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.C2CPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
Expand All @@ -9,7 +10,7 @@
import net.minecraft.network.protocol.PacketType;
import net.minecraft.resources.ResourceLocation;

public record MessageC2CPacket(String sender, String message) implements Packet<C2CPacketListener> {
public record MessageC2CPacket(String sender, String message) implements C2CPacket {
public static final StreamCodec<RegistryFriendlyByteBuf, MessageC2CPacket> CODEC = Packet.codec(MessageC2CPacket::write, MessageC2CPacket::new);
public static final PacketType<MessageC2CPacket> ID = new PacketType<>(PacketFlow.CLIENTBOUND, new ResourceLocation("clientcommands", "message"));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.C2CPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
Expand All @@ -9,7 +10,7 @@
import net.minecraft.network.protocol.PacketType;
import net.minecraft.resources.ResourceLocation;

public record PutTicTacToeMarkC2CPacket(String sender, byte x, byte y) implements Packet<C2CPacketListener> {
public record PutTicTacToeMarkC2CPacket(String sender, byte x, byte y) implements C2CPacket {
public static final StreamCodec<RegistryFriendlyByteBuf, PutTicTacToeMarkC2CPacket> CODEC = Packet.codec(PutTicTacToeMarkC2CPacket::write, PutTicTacToeMarkC2CPacket::new);
public static final PacketType<PutTicTacToeMarkC2CPacket> ID = new PacketType<>(PacketFlow.CLIENTBOUND, new ResourceLocation("clientcommands", "put_tic_tac_toe_mark"));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.C2CPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
Expand All @@ -9,7 +10,7 @@
import net.minecraft.network.protocol.PacketType;
import net.minecraft.resources.ResourceLocation;

public record StartTicTacToeGameC2CPacket(String sender, boolean accept) implements Packet<C2CPacketListener> {
public record StartTicTacToeGameC2CPacket(String sender, boolean accept) implements C2CPacket {
public static final StreamCodec<RegistryFriendlyByteBuf, StartTicTacToeGameC2CPacket> CODEC = Packet.codec(StartTicTacToeGameC2CPacket::write, StartTicTacToeGameC2CPacket::new);
public static final PacketType<StartTicTacToeGameC2CPacket> ID = new PacketType<>(PacketFlow.CLIENTBOUND, new ResourceLocation("clientcommands", "start_tic_tac_toe_game"));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,52 @@
package net.earthcomputer.clientcommands.mixin.c2c;

import com.mojang.authlib.GameProfile;
import net.earthcomputer.clientcommands.Configs;
import net.earthcomputer.clientcommands.c2c.C2CPacketHandler;
import net.earthcomputer.clientcommands.c2c.OutgoingPacketFilter;
import net.minecraft.ChatFormatting;
import net.minecraft.client.GuiMessageTag;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.ChatComponent;
import net.minecraft.client.multiplayer.chat.ChatListener;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MessageSignature;
import net.minecraft.network.chat.PlayerChatMessage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(ChatComponent.class)
public class ChatComponentMixin {
import java.time.Instant;

@Mixin(ChatListener.class)
public class ChatListenerMixin {
@Shadow @Final private Minecraft minecraft;

@Inject(method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/GuiMessageTag;)V", at = @At("HEAD"), cancellable = true)
private void onC2CPacket(Component message, MessageSignature signature, GuiMessageTag tag, CallbackInfo ci) {
handleIfPacket(message, ci);
}

@Unique
private void handleIfPacket(Component content, CallbackInfo ci) {
String string = content.getString();
int index = string.indexOf("CCENC:");
@Inject(method = "showMessageToPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/chat/ChatTrustLevel;createTag(Lnet/minecraft/network/chat/PlayerChatMessage;)Lnet/minecraft/client/GuiMessageTag;"), cancellable = true)
private void onC2CPacket(ChatType.Bound boundChatType, PlayerChatMessage chatMessage, Component decoratedServerContent, GameProfile gameProfile, boolean onlyShowSecureChat, Instant timestamp, CallbackInfoReturnable<Boolean> cir) {
String string = chatMessage.signedContent();
int index = string.indexOf(C2CPacketHandler.C2C_PACKET_HEADER);
if (index == -1) {
return;
}
String packetString = string.substring(index + 6);
String packetString = string.substring(index + C2CPacketHandler.C2C_PACKET_HEADER.length());
if (!Configs.acceptC2CPackets) {
if (OutgoingPacketFilter.removeIfContains(packetString)) {
this.minecraft.gui.getChat().addMessage(Component.translatable("c2cpacket.sentC2CPacket"));
} else {
this.minecraft.gui.getChat().addMessage(Component.translatable("c2cpacket.receivedC2CPacket").withStyle(s -> s.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, content))));
this.minecraft.gui.getChat().addMessage(Component.translatable("c2cpacket.receivedC2CPacket").withStyle(s -> s.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, boundChatType.decorate(chatMessage.decoratedContent())))));
}
ci.cancel();
cir.setReturnValue(false);
return;
}
if (OutgoingPacketFilter.removeIfContains(packetString)) {
ci.cancel();
cir.setReturnValue(false);
return;
}
if (C2CPacketHandler.handleC2CPacket(packetString)) {
ci.cancel();
if (C2CPacketHandler.handleC2CPacket(packetString, gameProfile.getName())) {
cir.setReturnValue(true);
} else {
this.minecraft.gui.getChat().addMessage(Component.translatable("c2cpacket.malformedPacket").withStyle(ChatFormatting.RED));
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/mixins.clientcommands.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"package": "net.earthcomputer.clientcommands.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"c2c.ChatComponentMixin",
"commands.enchant.EnchantmentDefinitionMixin",
"commands.enchant.EnchantmentHelperMixin",
"commands.enchant.EnchantmentScreenMixin",
Expand Down Expand Up @@ -65,6 +64,7 @@
"requireAnnotations": true
},
"client": [
"c2c.ChatListenerMixin",
"c2c.ClientPacketListenerMixin",
"commands.alias.ClientSuggestionProviderMixin",
"commands.enchant.MultiPlayerGameModeMixin",
Expand Down

0 comments on commit 8e8f520

Please sign in to comment.