Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ org.gradle.jvmargs=-Xmx2G
minecraft_version_list=1.21.11
minecraft_version_list_presentable=1.21.11
loader_version=0.18.1
loom_version=1.14-SNAPSHOT
loom_version=1.15-SNAPSHOT

# check these on https://maven.parchmentmc.org/org/parchmentmc/data/
parchment_mcversion=1.21.10
parchment_version=2025.10.12
parchment_mcversion=1.21.11
parchment_version=2025.12.20

# Mod Properties
mod_version=2.13.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ public static void registerCommands(CommandDispatcher<FabricClientCommandSource>
CalcCommand.register(dispatcher);
CalcStackCommand.register(dispatcher, context);
CallbackCommand.register(dispatcher);
ChessCommand.register(dispatcher);
CDebugCommand.register(dispatcher);
CEnchantCommand.register(dispatcher, context);
CFunctionCommand.register(dispatcher);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@
import com.mojang.logging.LogUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.earthcomputer.clientcommands.c2c.chess.ChessGame;
import net.earthcomputer.clientcommands.c2c.packets.ChessDrawOfferC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.ChessMoveC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.ChessResignC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.MessageC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.PutConnectFourPieceC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.PutTicTacToeMarkC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.StartTwoPlayerGameC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.StopTwoPlayerGameC2CPacket;
import net.earthcomputer.clientcommands.command.ClientCommandHelper;
import net.earthcomputer.clientcommands.command.ConnectFourCommand;
import net.earthcomputer.clientcommands.command.ListenCommand;
import net.earthcomputer.clientcommands.command.TicTacToeCommand;
import net.earthcomputer.clientcommands.command.arguments.ExtendedMarkdownArgument;
import net.earthcomputer.clientcommands.features.TwoPlayerGame;
import net.earthcomputer.clientcommands.util.CComponentUtil;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.ChatFormatting;
import net.minecraft.SharedConstants;
Expand All @@ -28,6 +35,7 @@
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.ProtocolInfo;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.RemoteChatSession;
import net.minecraft.network.protocol.Packet;
Expand All @@ -52,8 +60,12 @@ public class C2CPacketHandler implements C2CPacketListener {
public static final ProtocolInfo<C2CPacketListener> C2C = ProtocolInfoBuilder.<C2CPacketListener, C2CFriendlyByteBuf>clientboundProtocol(ConnectionProtocol.PLAY, builder -> builder
.addPacket(MessageC2CPacket.ID, MessageC2CPacket.CODEC)
.addPacket(StartTwoPlayerGameC2CPacket.ID, StartTwoPlayerGameC2CPacket.CODEC)
.addPacket(StopTwoPlayerGameC2CPacket.ID, StopTwoPlayerGameC2CPacket.CODEC)
.addPacket(PutTicTacToeMarkC2CPacket.ID, PutTicTacToeMarkC2CPacket.CODEC)
.addPacket(PutConnectFourPieceC2CPacket.ID, PutConnectFourPieceC2CPacket.CODEC)
.addPacket(ChessResignC2CPacket.ID, ChessResignC2CPacket.CODEC)
.addPacket(ChessMoveC2CPacket.ID, ChessMoveC2CPacket.CODEC)
.addPacket(ChessDrawOfferC2CPacket.ID, ChessDrawOfferC2CPacket.CODEC)
).bind(b -> (C2CFriendlyByteBuf) b);

public static final String C2C_PACKET_HEADER = "CCΕNC:";
Expand Down Expand Up @@ -211,6 +223,11 @@ public void onStartTwoPlayerGameC2CPacket(StartTwoPlayerGameC2CPacket packet) {
TwoPlayerGame.onStartTwoPlayerGame(packet);
}

@Override
public void onStopTwoPlayerGameC2CPacket(StopTwoPlayerGameC2CPacket packet) {
TwoPlayerGame.onStopTwoPlayerGame(packet);
}

@Override
public void onPutTicTacToeMarkC2CPacket(PutTicTacToeMarkC2CPacket packet) {
TicTacToeCommand.onPutTicTacToeMarkC2CPacket(packet);
Expand All @@ -221,6 +238,72 @@ public void onPutConnectFourPieceC2CPacket(PutConnectFourPieceC2CPacket packet)
ConnectFourCommand.onPutConnectFourPieceC2CPacket(packet);
}

@Override
public void onChessResignPacket(ChessResignC2CPacket packet) {
ChessGame activeGame = TwoPlayerGame.CHESS_TYPE.getActiveGame(packet.senderUUID());
if (activeGame == null) {
return;
}
String opponent = activeGame.opponent.getProfile().name();
TwoPlayerGame.CHESS_TYPE.removeActiveGame(packet.senderUUID());
ClientCommandHelper.sendFeedback(Component.translatable("chessGame.opponentResigned", opponent));
}

@Override
public void onChessMovePacket(ChessMoveC2CPacket packet) {
ChessGame activeGame = TwoPlayerGame.CHESS_TYPE.getActiveGame(packet.senderUUID());
if (activeGame == null) {
return;
}

// validate move
if (activeGame.colorToMove == activeGame.yourColor) {
return;
}
if (!activeGame.legalMoves().contains(packet.move())) {
return;
}

String moveNotation = activeGame.getAlgebraicNotation(packet.move());
activeGame.makeMove(packet.move());

Component clickable = CComponentUtil.getCommandTextComponent("twoPlayerGame.clickToMakeYourMove", "/cchess open " + packet.sender());
ClientCommandHelper.sendFeedback(Component.translatable("chessGame.opponentMoved", activeGame.opponent.getProfile().name(), moveNotation, ComponentUtils.wrapInSquareBrackets(clickable)));

Component endCondition = activeGame.detectEndCondition();
if (endCondition != null) {
TwoPlayerGame.CHESS_TYPE.removeActiveGame(packet.senderUUID());
ClientCommandHelper.sendFeedback(endCondition);
}
}

@Override
public void onChessDrawOfferPacket(ChessDrawOfferC2CPacket packet) {
ChessGame activeGame = TwoPlayerGame.CHESS_TYPE.getActiveGame(packet.senderUUID());
if (activeGame == null) {
return;
}

String opponent = activeGame.opponent.getProfile().name();

// TODO: there are possibilities of desyncs here, not really sure how to fix it tbh
switch (packet.operation()) {
case OFFER -> {
activeGame.drawOfferedBy = activeGame.yourColor.opposite();
ClientCommandHelper.sendFeedback(Component.translatable("chessGame.drawOffered", opponent));
}
case RETRACT -> {
activeGame.drawOfferedBy = null;
ClientCommandHelper.sendFeedback(Component.translatable("chessGame.drawOfferRetracted", opponent));
}
case ACCEPT -> {
TwoPlayerGame.CHESS_TYPE.removeActiveGame(packet.senderUUID());
ClientCommandHelper.sendFeedback(Component.translatable("chessGame.drawOfferAccepted", opponent));
ClientCommandHelper.sendFeedback(Component.translatable("chessGame.draw.agreement"));
}
}
}

public static @Nullable C2CFriendlyByteBuf wrapByteBuf(ByteBuf buf, @Nullable String sender, @Nullable UUID senderUUID) {
ClientPacketListener connection = Minecraft.getInstance().getConnection();
if (connection == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
package net.earthcomputer.clientcommands.c2c;

import net.earthcomputer.clientcommands.c2c.packets.ChessDrawOfferC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.ChessMoveC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.ChessResignC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.MessageC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.PutConnectFourPieceC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.PutTicTacToeMarkC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.StartTwoPlayerGameC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.StopTwoPlayerGameC2CPacket;
import net.minecraft.network.ClientboundPacketListener;

public interface C2CPacketListener extends ClientboundPacketListener {
void onMessageC2CPacket(MessageC2CPacket packet);

void onStartTwoPlayerGameC2CPacket(StartTwoPlayerGameC2CPacket packet);

void onStopTwoPlayerGameC2CPacket(StopTwoPlayerGameC2CPacket packet);

void onPutTicTacToeMarkC2CPacket(PutTicTacToeMarkC2CPacket packet);

void onPutConnectFourPieceC2CPacket(PutConnectFourPieceC2CPacket packet);

void onChessResignPacket(ChessResignC2CPacket packet);

void onChessMovePacket(ChessMoveC2CPacket packet);

void onChessDrawOfferPacket(ChessDrawOfferC2CPacket packet);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.earthcomputer.clientcommands.c2c.chess;

public enum ChessColor {
WHITE, BLACK;

public ChessColor opposite() {
return this == WHITE ? BLACK : WHITE;
}
}
Loading