Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snake improvements #595

Draft
wants to merge 6 commits into
base: fabric
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.logging.LogUtils;
import net.earthcomputer.clientcommands.c2c.packets.MessageC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.*;
import net.earthcomputer.clientcommands.command.SnakeCommand;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.network.encryption.PlayerPublicKey;
import net.minecraft.network.encryption.PublicPlayerSession;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.HoverEvent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.slf4j.Logger;

import java.security.PublicKey;
import java.util.List;
import java.util.Optional;

public class CCNetworkHandler implements CCPacketListener {

Expand All @@ -32,6 +37,16 @@ public static CCNetworkHandler getInstance() {
return instance;
}

public static Optional<PlayerListEntry> getPlayerByName(String name) {
assert MinecraftClient.getInstance().getNetworkHandler() != null;
return MinecraftClient.getInstance()
.getNetworkHandler()
.getPlayerList()
.stream()
.filter(p -> p.getProfile().getName().equalsIgnoreCase(name))
.findFirst();
}

public void sendPacket(C2CPacket packet, PlayerListEntry recipient) throws CommandSyntaxException {
Integer id = CCPacketHandler.getId(packet.getClass());
if (id == null) {
Expand Down Expand Up @@ -63,6 +78,7 @@ public void sendPacket(C2CPacket packet, PlayerListEntry recipient) throws Comma
if (commandString.length() >= 256) {
throw MESSAGE_TOO_LONG_EXCEPTION.create();
}
assert MinecraftClient.getInstance().getNetworkHandler() != null;
MinecraftClient.getInstance().getNetworkHandler().sendChatCommand(commandString);
OutgoingPacketFilter.addPacket(packetString);
}
Expand All @@ -79,4 +95,76 @@ public void onMessageC2CPacket(MessageC2CPacket packet) {
Text text = prefix.append(Text.translatable("ccpacket.messageC2CPacket.incoming", sender, message).formatted(Formatting.GRAY));
MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(text);
}

@Override
public void onSnakeInviteC2CPacket(SnakeInviteC2CPacket packet) {
// TODO: Use Text.translatable
MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(
Text.literal(packet.sender())
.append(" invited you to a game of snake. ")
.append(
Text.literal("[Join]")
.styled(style ->
style.withColor(Formatting.GREEN)
.withHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT, Text.literal("Join game")
))
.withClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND, "/csnake join " + packet.sender()
))
)
)
.styled(style -> style.withColor(Formatting.GRAY))
);
}

@Override
public void onSnakeJoinC2CPacket(SnakeJoinC2CPacket packet) {
if (!(MinecraftClient.getInstance().currentScreen instanceof SnakeCommand.SnakeGameScreen snakeScreen)) return;
final SnakeAddPlayersC2CPacket addPlayersPacket = new SnakeAddPlayersC2CPacket(List.of(packet.sender()));
for (final String otherPlayer : snakeScreen.getOtherSnakes().keySet()) {
getPlayerByName(otherPlayer).ifPresent(actualPlayer -> {
try {
sendPacket(addPlayersPacket, actualPlayer);
} catch (CommandSyntaxException e) {
LOGGER.warn("Failed to recast snake player join", e);
}
});
}
getPlayerByName(packet.sender()).ifPresent(sender -> {
try {
sendPacket(new SnakeAddPlayersC2CPacket(snakeScreen.getOtherSnakes().keySet()), sender);
sendPacket(new SnakeSyncAppleC2CPacket(snakeScreen.getApple()), sender);
} catch (CommandSyntaxException e) {
LOGGER.warn("Failed to reply to snake player join", e);
}
});
snakeScreen.getOtherSnakes().put(packet.sender(), List.of()); // Reserve entry in player list
}

@Override
public void onSnakeAddPlayersC2CPacket(SnakeAddPlayersC2CPacket packet) {
if (!(MinecraftClient.getInstance().currentScreen instanceof SnakeCommand.SnakeGameScreen snakeScreen)) return;
for (final String player : packet.players()) {
snakeScreen.getOtherSnakes().put(player, List.of());
}
}

@Override
public void onSnakeBodyC2CPacket(SnakeBodyC2CPacket packet) {
if (!(MinecraftClient.getInstance().currentScreen instanceof SnakeCommand.SnakeGameScreen snakeScreen)) return;
snakeScreen.getOtherSnakes().put(packet.sender(), packet.segments());
}

@Override
public void onSnakeRemovePlayerC2CPacket(SnakeRemovePlayerC2CPacket packet) {
if (!(MinecraftClient.getInstance().currentScreen instanceof SnakeCommand.SnakeGameScreen snakeScreen)) return;
snakeScreen.getOtherSnakes().remove(packet.player());
}

@Override
public void onSnakeSyncAppleC2CPacket(SnakeSyncAppleC2CPacket packet) {
if (!(MinecraftClient.getInstance().currentScreen instanceof SnakeCommand.SnakeGameScreen snakeScreen)) return;
snakeScreen.setApple(packet.applePos());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.earthcomputer.clientcommands.c2c.packets.MessageC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.*;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;

Expand All @@ -17,6 +17,12 @@ public class CCPacketHandler {

static {
CCPacketHandler.register(MessageC2CPacket.class, MessageC2CPacket::new);
CCPacketHandler.register(SnakeInviteC2CPacket.class, SnakeInviteC2CPacket::new);
CCPacketHandler.register(SnakeJoinC2CPacket.class, SnakeJoinC2CPacket::new);
CCPacketHandler.register(SnakeAddPlayersC2CPacket.class, SnakeAddPlayersC2CPacket::new);
CCPacketHandler.register(SnakeBodyC2CPacket.class, SnakeBodyC2CPacket::new);
CCPacketHandler.register(SnakeRemovePlayerC2CPacket.class, SnakeRemovePlayerC2CPacket::new);
CCPacketHandler.register(SnakeSyncAppleC2CPacket.class, SnakeSyncAppleC2CPacket::new);
}

public static <P extends C2CPacket> void register(Class<P> packet, Function<StringBuf, P> packetFactory) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package net.earthcomputer.clientcommands.c2c;

import net.earthcomputer.clientcommands.c2c.packets.MessageC2CPacket;
import net.earthcomputer.clientcommands.c2c.packets.*;

public interface CCPacketListener {
void onMessageC2CPacket(MessageC2CPacket packet);

void onSnakeInviteC2CPacket(SnakeInviteC2CPacket packet);

void onSnakeJoinC2CPacket(SnakeJoinC2CPacket packet);

void onSnakeAddPlayersC2CPacket(SnakeAddPlayersC2CPacket packet);

void onSnakeBodyC2CPacket(SnakeBodyC2CPacket packet);

void onSnakeRemovePlayerC2CPacket(SnakeRemovePlayerC2CPacket packet);

void onSnakeSyncAppleC2CPacket(SnakeSyncAppleC2CPacket packet);
}
20 changes: 20 additions & 0 deletions src/main/java/net/earthcomputer/clientcommands/c2c/StringBuf.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package net.earthcomputer.clientcommands.c2c;

import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.IntFunction;

public class StringBuf {

Expand Down Expand Up @@ -35,11 +39,27 @@ public int readInt() {
return Integer.parseInt(this.readString());
}

public <E, C extends Collection<E>> C readCollection(IntFunction<C> collectionCreator, Function<StringBuf, E> elementReader) {
final int count = readInt();
final C result = collectionCreator.apply(count);
for (int i = 0; i < count; i++) {
result.add(elementReader.apply(this));
}
return result;
}

public void writeString(String string) {
this.buffer.append(string).append('\0');
}

public void writeInt(int integer) {
this.buffer.append(integer).append('\0');
}

public <E> void writeCollection(Collection<E> collection, BiConsumer<StringBuf, E> elementWriter) {
writeInt(collection.size());
for (final E element : collection) {
elementWriter.accept(this, element);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.CCPacketListener;
import net.earthcomputer.clientcommands.c2c.StringBuf;

import java.util.ArrayList;
import java.util.Collection;

public record SnakeAddPlayersC2CPacket(Collection<String> players) implements C2CPacket {
public SnakeAddPlayersC2CPacket(StringBuf buf) {
this((Collection<String>)buf.readCollection(ArrayList::new, StringBuf::readString));
}

@Override
public void write(StringBuf buf) {
buf.writeCollection(players, StringBuf::writeString);
}

@Override
public void apply(CCPacketListener listener) {
listener.onSnakeAddPlayersC2CPacket(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.CCPacketListener;
import net.earthcomputer.clientcommands.c2c.StringBuf;
import net.earthcomputer.clientcommands.command.SnakeCommand;

import java.util.ArrayList;
import java.util.List;

public record SnakeBodyC2CPacket(String sender, List<SnakeCommand.Vec2i> segments) implements C2CPacket {
public SnakeBodyC2CPacket(StringBuf buf) {
this(buf.readString(), buf.readCollection(ArrayList::new, SnakeCommand.Vec2i::new));
}

@Override
public void write(StringBuf buf) {
buf.writeString(sender);
buf.writeCollection(segments, SnakeCommand.Vec2i::write);
}

@Override
public void apply(CCPacketListener listener) {
listener.onSnakeBodyC2CPacket(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.CCPacketListener;
import net.earthcomputer.clientcommands.c2c.StringBuf;

public record SnakeInviteC2CPacket(String sender) implements C2CPacket {
public SnakeInviteC2CPacket(StringBuf buf) {
this(buf.readString());
}

@Override
public void write(StringBuf buf) {
buf.writeString(sender);
}

@Override
public void apply(CCPacketListener listener) {
listener.onSnakeInviteC2CPacket(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.CCPacketListener;
import net.earthcomputer.clientcommands.c2c.StringBuf;

public record SnakeJoinC2CPacket(String sender) implements C2CPacket {
public SnakeJoinC2CPacket(StringBuf buf) {
this(buf.readString());
}

@Override
public void write(StringBuf buf) {
buf.writeString(sender);
}

@Override
public void apply(CCPacketListener listener) {
listener.onSnakeJoinC2CPacket(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.CCPacketListener;
import net.earthcomputer.clientcommands.c2c.StringBuf;

public record SnakeRemovePlayerC2CPacket(String player) implements C2CPacket {
public SnakeRemovePlayerC2CPacket(StringBuf buf) {
this(buf.readString());
}

@Override
public void write(StringBuf buf) {
buf.writeString(player);
}

@Override
public void apply(CCPacketListener listener) {
listener.onSnakeRemovePlayerC2CPacket(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.earthcomputer.clientcommands.c2c.packets;

import net.earthcomputer.clientcommands.c2c.C2CPacket;
import net.earthcomputer.clientcommands.c2c.CCPacketListener;
import net.earthcomputer.clientcommands.c2c.StringBuf;
import net.earthcomputer.clientcommands.command.SnakeCommand;

public record SnakeSyncAppleC2CPacket(SnakeCommand.Vec2i applePos) implements C2CPacket {
public SnakeSyncAppleC2CPacket(StringBuf buf) {
this(new SnakeCommand.Vec2i(buf));
}

@Override
public void write(StringBuf buf) {
SnakeCommand.Vec2i.write(buf, applePos);
}

@Override
public void apply(CCPacketListener listener) {
listener.onSnakeSyncAppleC2CPacket(this);
}
}
Loading