More precisely replicate GameMode encoding/decoding

This commit is contained in:
Camotoy 2022-12-07 22:48:54 -05:00
parent 2345f2b98f
commit 5506b94bf6
7 changed files with 37 additions and 26 deletions

View file

@ -155,12 +155,6 @@ public class MagicValues {
register(FillStackAction.FILL, 0);
register(GameMode.UNKNOWN, -1);
register(GameMode.SURVIVAL, 0);
register(GameMode.CREATIVE, 1);
register(GameMode.ADVENTURE, 2);
register(GameMode.SPECTATOR, 3);
register(Difficulty.PEACEFUL, 0);
register(Difficulty.EASY, 1);
register(Difficulty.NORMAL, 2);

View file

@ -1,11 +1,29 @@
package com.github.steveice10.mc.protocol.data.game.entity.player;
import com.github.steveice10.mc.protocol.data.game.level.notify.GameEventValue;
import org.jetbrains.annotations.Nullable;
public enum GameMode implements GameEventValue {
SURVIVAL,
CREATIVE,
ADVENTURE,
SPECTATOR,
UNKNOWN
SPECTATOR;
private static final GameMode[] VALUES = values();
public static GameMode byId(int id) {
return VALUES[id];
}
@Nullable
public static GameMode byNullableId(int id) {
return id == -1 ? null : VALUES[id];
}
public static int toNullableId(@Nullable GameMode gameMode) {
if (gameMode != null) {
return gameMode.ordinal();
}
return -1;
}
}

View file

@ -22,7 +22,7 @@ public class ClientboundLoginPacket implements MinecraftPacket {
private final int entityId;
private final boolean hardcore;
private final @NonNull GameMode gameMode;
private final GameMode previousGamemode;
private final @Nullable GameMode previousGamemode;
private final @NonNull String[] worldNames;
private final @NonNull CompoundTag registry;
private final @NonNull String dimension;
@ -40,8 +40,8 @@ public class ClientboundLoginPacket implements MinecraftPacket {
public ClientboundLoginPacket(ByteBuf in, MinecraftCodecHelper helper) throws IOException {
this.entityId = in.readInt();
this.hardcore = in.readBoolean();
this.gameMode = MagicValues.key(GameMode.class, in.readByte());
this.previousGamemode = MagicValues.key(GameMode.class, in.readByte());
this.gameMode = GameMode.byId(in.readByte());
this.previousGamemode = GameMode.byNullableId(in.readByte());
int worldCount = helper.readVarInt(in);
this.worldNames = new String[worldCount];
for (int i = 0; i < worldCount; i++) {
@ -69,8 +69,8 @@ public class ClientboundLoginPacket implements MinecraftPacket {
public void serialize(ByteBuf out, MinecraftCodecHelper helper) throws IOException {
out.writeInt(this.entityId);
out.writeBoolean(this.hardcore);
out.writeByte(MagicValues.value(Integer.class, this.gameMode));
out.writeByte(MagicValues.value(Integer.class, this.previousGamemode));
out.writeByte(this.gameMode.ordinal());
out.writeByte(GameMode.toNullableId(this.gameMode));
helper.writeVarInt(out, this.worldNames.length);
for (String worldName : this.worldNames) {
helper.writeString(out, worldName);

View file

@ -70,7 +70,7 @@ public class ClientboundPlayerInfoUpdatePacket implements MinecraftPacket {
}
case UPDATE_GAME_MODE: {
int rawGameMode = helper.readVarInt(in);
GameMode gameMode = MagicValues.key(GameMode.class, Math.max(rawGameMode, 0));
GameMode gameMode = GameMode.byId(Math.max(rawGameMode, 0));
entry.setGameMode(gameMode);
break;
@ -100,7 +100,7 @@ public class ClientboundPlayerInfoUpdatePacket implements MinecraftPacket {
}
}
public void serialize(ByteBuf out, MinecraftCodecHelper helper) throws IOException {
public void serialize(ByteBuf out, MinecraftCodecHelper helper) {
helper.writeEnumSet(out, this.actions, PlayerListEntryAction.VALUES);
helper.writeVarInt(out, this.entries.length);
for (PlayerListEntry entry : this.entries) {
@ -123,7 +123,7 @@ public class ClientboundPlayerInfoUpdatePacket implements MinecraftPacket {
}
break;
case UPDATE_GAME_MODE:
helper.writeVarInt(out, MagicValues.value(Integer.class, entry.getGameMode()));
helper.writeVarInt(out, entry.getGameMode().ordinal());
break;
case UPDATE_LISTED:
out.writeBoolean(entry.isListed());

View file

@ -23,7 +23,7 @@ public class ClientboundRespawnPacket implements MinecraftPacket {
private final @NonNull String worldName;
private final long hashedSeed;
private final @NonNull GameMode gamemode;
private final @NonNull GameMode previousGamemode;
private final @Nullable GameMode previousGamemode;
private final boolean debug;
private final boolean flat;
// The following two are the dataToKeep byte
@ -35,8 +35,8 @@ public class ClientboundRespawnPacket implements MinecraftPacket {
this.dimension = helper.readString(in);
this.worldName = helper.readString(in);
this.hashedSeed = in.readLong();
this.gamemode = MagicValues.key(GameMode.class, in.readUnsignedByte());
this.previousGamemode = MagicValues.key(GameMode.class, in.readUnsignedByte());
this.gamemode = GameMode.byId(in.readUnsignedByte()); // Intentionally unsigned as of 1.19.3
this.previousGamemode = GameMode.byNullableId(in.readByte());
this.debug = in.readBoolean();
this.flat = in.readBoolean();
byte dataToKeep = in.readByte();
@ -50,8 +50,8 @@ public class ClientboundRespawnPacket implements MinecraftPacket {
helper.writeString(out, this.dimension);
helper.writeString(out, this.worldName);
out.writeLong(this.hashedSeed);
out.writeByte(MagicValues.value(Integer.class, this.gamemode));
out.writeByte(MagicValues.value(Integer.class, this.previousGamemode));
out.writeByte(this.gamemode.ordinal());
out.writeByte(GameMode.toNullableId(this.previousGamemode));
out.writeBoolean(this.debug);
out.writeBoolean(this.flat);
byte dataToKeep = 0;

View file

@ -20,12 +20,12 @@ public class ClientboundGameEventPacket implements MinecraftPacket {
private final @NonNull GameEvent notification;
private final GameEventValue value;
public ClientboundGameEventPacket(ByteBuf in, MinecraftCodecHelper helper) throws IOException {
public ClientboundGameEventPacket(ByteBuf in, MinecraftCodecHelper helper) {
this.notification = MagicValues.key(GameEvent.class, in.readUnsignedByte());
float value = in.readFloat();
// TODO: Handle this in MinecraftCodecHelper
if (this.notification == GameEvent.CHANGE_GAMEMODE) {
this.value = MagicValues.key(GameMode.class, (int) value);
this.value = GameMode.byId((int) value);
} else if (this.notification == GameEvent.DEMO_MESSAGE) {
this.value = MagicValues.key(DemoMessageValue.class, (int) value);
} else if (this.notification == GameEvent.ENTER_CREDITS) {
@ -42,12 +42,12 @@ public class ClientboundGameEventPacket implements MinecraftPacket {
}
@Override
public void serialize(ByteBuf out, MinecraftCodecHelper helper) throws IOException {
public void serialize(ByteBuf out, MinecraftCodecHelper helper) {
out.writeByte(MagicValues.value(Integer.class, this.notification));
float value = 0;
// TODO: Handle this in MinecraftCodecHelper
if (this.value instanceof Enum<?>) {
value = MagicValues.value(Integer.class, (Enum<?>) this.value);
value = ((Enum<?>) this.value).ordinal();
} else if (this.value instanceof RainStrengthValue) {
value = ((RainStrengthValue) this.value).getStrength();
} else if (this.value instanceof ThunderStrengthValue) {

View file

@ -102,7 +102,6 @@ public class MagicValuesTest {
this.register(DropItemAction.class, Integer.class);
this.register(SpreadItemAction.class, Integer.class);
this.register(FillStackAction.class, Integer.class);
this.register(GameMode.class, Integer.class);
this.register(Difficulty.class, Integer.class);
this.register(Animation.class, Integer.class);
this.register(PositionElement.class, Integer.class);