Update to JoinGamePacket and RespawnPacket (#1640)

* Add death location support to JoinGamePacket
This commit is contained in:
Alexander 2023-03-22 03:22:24 +00:00 committed by GitHub
parent 784875943a
commit c496ee3572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 14 deletions

View File

@ -55,6 +55,7 @@ import net.minestom.server.network.packet.server.SendablePacket;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.login.LoginDisconnectPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.packet.server.play.data.DeathLocation;
import net.minestom.server.network.player.GameProfile;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.network.player.PlayerSocketConnection;
@ -250,10 +251,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
"minecraft:chat_type", Messenger.chatRegistry(),
"minecraft:dimension_type", MinecraftServer.getDimensionTypeManager().toNBT(),
"minecraft:worldgen/biome", MinecraftServer.getBiomeManager().toNBT()));
// TODO: Add some way to determine last death location
final DeathLocation deathLocation = null;
final JoinGamePacket joinGamePacket = new JoinGamePacket(getEntityId(), false, gameMode, null,
List.of(dimensionType.getName().asString()), nbt, dimensionType.toString(), dimensionType.getName().asString(),
0, 0, MinecraftServer.getChunkViewDistance(), MinecraftServer.getChunkViewDistance(),
false, true, false, levelFlat);
false, true, false, levelFlat, deathLocation);
sendPacket(joinGamePacket);
// Server brand name
@ -443,8 +448,11 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
setFireForDuration(0);
setOnFire(false);
refreshHealth();
// TODO: Add some way to determine last death location
final DeathLocation deathLocation = null;
sendPacket(new RespawnPacket(getDimensionType().toString(), getDimensionType().getName().asString(),
0, gameMode, gameMode, false, levelFlat, true));
0, gameMode, gameMode, false, levelFlat, true, deathLocation));
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(this);
EventDispatcher.call(respawnEvent);
@ -968,8 +976,10 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
final PlayerInfoPacket removePlayerPacket = getRemovePlayerToList();
final PlayerInfoPacket addPlayerPacket = getAddPlayerToList();
// TODO: Add some way to determine last death location
final DeathLocation deathLocation = null;
RespawnPacket respawnPacket = new RespawnPacket(getDimensionType().toString(), getDimensionType().getName().asString(),
0, gameMode, gameMode, false, levelFlat, true);
0, gameMode, gameMode, false, levelFlat, true, deathLocation);
sendPacket(removePlayerPacket);
sendPacket(destroyEntitiesPacket);
@ -1341,8 +1351,10 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
Check.argCondition(dimensionType.equals(getDimensionType()),
"The dimension needs to be different than the current one!");
this.dimensionType = dimensionType;
// TODO: Add some way to determine last death location
final DeathLocation deathLocation = null;
sendPacket(new RespawnPacket(dimensionType.toString(), getDimensionType().getName().asString(),
0, gameMode, gameMode, false, levelFlat, true));
0, gameMode, gameMode, false, levelFlat, true, deathLocation));
refreshClientStateAfterRespawn();
}

View File

@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.data.DeathLocation;
import net.minestom.server.utils.Direction;
import net.minestom.server.utils.Either;
import org.jetbrains.annotations.ApiStatus;
@ -57,6 +58,7 @@ public final class NetworkBuffer {
public static final Type<int[]> VILLAGER_DATA = NetworkBufferTypes.VILLAGER_DATA;
public static final Type<Integer> OPT_VAR_INT = NetworkBufferTypes.OPT_VAR_INT;
public static final Type<Entity.Pose> POSE = NetworkBufferTypes.POSE;
public static final Type<DeathLocation> DEATH_LOCATION = NetworkBufferTypes.DEATH_LOCATION;
ByteBuffer nioBuffer;
final boolean resizable;

View File

@ -7,6 +7,7 @@ import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.data.DeathLocation;
import net.minestom.server.utils.Direction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnknownNullability;
@ -505,6 +506,23 @@ final class NetworkBufferTypes {
final int ordinal = buffer.read(VAR_INT);
return Entity.Pose.values()[ordinal];
});
static final TypeImpl<DeathLocation> DEATH_LOCATION = new TypeImpl<>(DeathLocation.class,
(buffer, value) -> {
if (value == null) {
buffer.write(BOOLEAN, false);
} else {
buffer.write(BOOLEAN, true);
buffer.write(STRING, value.dimension());
buffer.write(BLOCK_POSITION, value.position());
}
return -1;
},
buffer -> {
if (buffer.read(BOOLEAN)) {
return new DeathLocation(buffer.read(STRING), buffer.read(BLOCK_POSITION));
}
return null;
});
record TypeImpl<T>(@NotNull Class<T> type,
@NotNull TypeWriter<T> writer,

View File

@ -4,7 +4,9 @@ import net.minestom.server.entity.GameMode;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.network.packet.server.play.data.DeathLocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.List;
@ -14,17 +16,18 @@ import static net.minestom.server.network.NetworkBuffer.*;
public record JoinGamePacket(int entityId, boolean isHardcore, GameMode gameMode, GameMode previousGameMode,
List<String> worlds, NBTCompound dimensionCodec, String dimensionType, String world,
long hashedSeed, int maxPlayers, int viewDistance, int simulationDistance,
boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug,
boolean isFlat) implements ServerPacket {
boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, boolean isFlat,
DeathLocation deathLocation) implements ServerPacket {
public JoinGamePacket {
worlds = List.copyOf(worlds);
}
public JoinGamePacket(@NotNull NetworkBuffer reader) {
this(reader.read(VAR_INT), reader.read(BOOLEAN), GameMode.fromId(reader.read(BYTE)), GameMode.fromId(reader.read(BYTE)),
this(reader.read(INT), reader.read(BOOLEAN), GameMode.fromId(reader.read(BYTE)), getNullableGameMode(reader.read(BYTE)),
reader.readCollection(STRING), (NBTCompound) reader.read(NBT), reader.read(STRING), reader.read(STRING),
reader.read(LONG), reader.read(VAR_INT), reader.read(VAR_INT), reader.read(VAR_INT),
reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN));
reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN),
reader.read(DEATH_LOCATION));
}
@Override
@ -54,7 +57,7 @@ public record JoinGamePacket(int entityId, boolean isHardcore, GameMode gameMode
//is flat
writer.write(BOOLEAN, isFlat);
writer.write(BOOLEAN, false);
writer.write(DEATH_LOCATION, deathLocation);
}
@Override
@ -62,4 +65,14 @@ public record JoinGamePacket(int entityId, boolean isHardcore, GameMode gameMode
return ServerPacketIdentifier.JOIN_GAME;
}
/**
* This method exists in lieu of a NetworkBufferType since -1 is only a
* valid value in this packet and changing behaviour of GameMode.fromId()
* to be nullable would be too big of a change. Also, game modes are often
* represented as other data types, including floats.
*/
private static @Nullable GameMode getNullableGameMode(final byte id) {
return id == (byte) -1 ? null : GameMode.fromId(id);
}
}

View File

@ -4,17 +4,19 @@ import net.minestom.server.entity.GameMode;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.network.packet.server.play.data.DeathLocation;
import org.jetbrains.annotations.NotNull;
import static net.minestom.server.network.NetworkBuffer.*;
public record RespawnPacket(String dimensionType, String worldName,
long hashedSeed, GameMode gameMode, GameMode previousGameMode,
boolean isDebug, boolean isFlat, boolean copyMeta) implements ServerPacket {
boolean isDebug, boolean isFlat, boolean copyMeta,
DeathLocation deathLocation) implements ServerPacket {
public RespawnPacket(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), reader.read(STRING),
reader.read(LONG), GameMode.values()[reader.read(BYTE)], GameMode.values()[reader.read(BYTE)],
reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN));
reader.read(LONG), GameMode.fromId(reader.read(BYTE)), GameMode.fromId(reader.read(BYTE)),
reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(DEATH_LOCATION));
}
@Override
@ -27,8 +29,7 @@ public record RespawnPacket(String dimensionType, String worldName,
writer.write(BOOLEAN, isDebug);
writer.write(BOOLEAN, isFlat);
writer.write(BOOLEAN, copyMeta);
writer.write(BOOLEAN, false);
writer.write(DEATH_LOCATION, deathLocation);
}
@Override

View File

@ -0,0 +1,8 @@
package net.minestom.server.network.packet.server.play.data;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
public record DeathLocation(@NotNull String dimension, @NotNull Point position) {
}