Fix client crash when receiving packets before playing state

This commit is contained in:
themode 2021-01-13 09:16:22 +01:00
parent e0afe62c66
commit 098ba1a6a4
4 changed files with 20 additions and 25 deletions

View File

@ -8,6 +8,7 @@ import net.minestom.server.event.player.PlayerLoginEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.packet.server.play.KeepAlivePacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
@ -41,8 +42,9 @@ public final class EntityManager {
for (Player player : CONNECTION_MANAGER.getOnlinePlayers()) {
final long lastKeepAlive = tickStart - player.getLastKeepAlive();
if (lastKeepAlive > KEEP_ALIVE_DELAY && player.didAnswerKeepAlive()) {
final PlayerConnection playerConnection = player.getPlayerConnection();
player.refreshKeepAlive(tickStart);
player.getPlayerConnection().sendPacket(keepAlivePacket);
playerConnection.sendPacket(keepAlivePacket);
} else if (lastKeepAlive >= KEEP_ALIVE_KICK) {
player.kick(TIMEOUT_TEXT);
}

View File

@ -53,11 +53,7 @@ public class FakePlayer extends Player {
});
}
if (option.isRegistered()) {
CONNECTION_MANAGER.registerPlayer(this);
}
CONNECTION_MANAGER.startPlayState(this);
CONNECTION_MANAGER.startPlayState(this, option.isRegistered());
}
/**

View File

@ -347,9 +347,10 @@ public final class ConnectionManager {
* Sends a {@link LoginSuccessPacket} if successful (not kicked)
* and change the connection state to {@link ConnectionState#PLAY}.
*
* @param player the player
* @param player the player
* @param register true to register the newly created player in {@link ConnectionManager} lists
*/
public void startPlayState(@NotNull Player player) {
public void startPlayState(@NotNull Player player, boolean register) {
// Init player (register events)
for (Consumer<Player> playerInitialization : getPlayerInitializations()) {
playerInitialization.accept(player);
@ -397,23 +398,30 @@ public final class ConnectionManager {
final PlayerConnection connection = player.getPlayerConnection();
LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(uuid, username);
connection.sendPacket(loginSuccessPacket);
if (connection instanceof NettyPlayerConnection) {
((NettyPlayerConnection) connection).writeAndFlush(loginSuccessPacket);
} else {
connection.sendPacket(loginSuccessPacket);
}
connection.setConnectionState(ConnectionState.PLAY);
}
// Add the player to the waiting list
MinecraftServer.getEntityManager().addWaitingPlayer(player);
if (register) {
registerPlayer(player);
}
});
}
/**
* Creates a {@link Player} using the defined {@link PlayerProvider}
* and execute {@link #startPlayState(Player)}.
* and execute {@link #startPlayState(Player, boolean)}.
*
* @param register true to register the newly created player in {@link ConnectionManager} lists
* @return the newly created player object
* @see #startPlayState(Player)
* @see #startPlayState(Player, boolean)
*/
@NotNull
public Player startPlayState(@NotNull PlayerConnection connection,
@ -421,11 +429,7 @@ public final class ConnectionManager {
boolean register) {
final Player player = getPlayerProvider().createPlayer(uuid, username, connection);
if (register) {
registerPlayer(player);
}
startPlayState(player);
startPlayState(player, register);
return player;
}

View File

@ -98,7 +98,7 @@ public class NettyPlayerConnection extends PlayerConnection {
Check.stateCondition(threshold == 0, "Compression cannot be enabled because the threshold is equal to 0");
this.compressed = true;
sendPacket(new SetCompressionPacket(threshold));
writeAndFlush(new SetCompressionPacket(threshold));
channel.pipeline().addAfter(NettyServer.FRAMER_HANDLER_NAME, NettyServer.COMPRESSOR_HANDLER_NAME,
new PacketCompressor(threshold));
}
@ -112,13 +112,6 @@ public class NettyPlayerConnection extends PlayerConnection {
*/
@Override
public void sendPacket(@NotNull ServerPacket serverPacket) {
// Directly send packet before playing state
if (getConnectionState() != ConnectionState.PLAY) {
writeAndFlush(serverPacket);
return;
}
if (shouldSendPacket(serverPacket)) {
if (getPlayer() != null) {
// Flush happen during #update()