mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
Fix connection crash
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
548cee55e0
commit
66b567597a
@ -8,8 +8,7 @@ import java.nio.ByteBuffer;
|
||||
* Represents a packet which is already framed. (packet id+payload) + optional compression
|
||||
* Can be used if you want to send the exact same buffer to multiple clients without processing it more than once.
|
||||
*/
|
||||
public class FramedPacket {
|
||||
|
||||
public final class FramedPacket {
|
||||
private final ByteBuffer body;
|
||||
|
||||
public FramedPacket(@NotNull ByteBuffer body) {
|
||||
|
@ -64,16 +64,12 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
private PlayerSkin bungeeSkin;
|
||||
|
||||
private final ByteBuffer tickBuffer = ByteBuffer.allocateDirect(Server.SOCKET_BUFFER_SIZE);
|
||||
private ByteBuffer cacheBuffer;
|
||||
private volatile ByteBuffer cacheBuffer;
|
||||
|
||||
public NettyPlayerConnection(@NotNull SocketChannel channel) {
|
||||
public NettyPlayerConnection(@NotNull SocketChannel channel, SocketAddress remoteAddress) {
|
||||
super();
|
||||
this.channel = channel;
|
||||
try {
|
||||
this.remoteAddress = channel.getRemoteAddress();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.remoteAddress = remoteAddress;
|
||||
}
|
||||
|
||||
public void processPackets(Worker.Context workerContext, PacketProcessor packetProcessor) {
|
||||
@ -133,8 +129,8 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
readBuffer.limit(limit).position(packetEnd);
|
||||
} catch (BufferUnderflowException e) {
|
||||
readBuffer.reset();
|
||||
this.cacheBuffer = ByteBuffer.allocateDirect(readBuffer.remaining());
|
||||
this.cacheBuffer.put(readBuffer).flip();
|
||||
this.cacheBuffer = ByteBuffer.allocateDirect(readBuffer.remaining())
|
||||
.put(readBuffer).flip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -191,7 +187,7 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
serverPacket = ((ComponentHoldingServerPacket) serverPacket).copyWithOperator(component ->
|
||||
GlobalTranslator.render(component, Objects.requireNonNullElseGet(getPlayer().getLocale(), MinestomAdventure::getDefaultLocale)));
|
||||
}
|
||||
attemptWrite(PacketUtils.createFramedPacket(serverPacket));
|
||||
attemptWrite(serverPacket);
|
||||
} else {
|
||||
// Player is probably not logged yet
|
||||
writeAndFlush(serverPacket);
|
||||
@ -208,17 +204,34 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
}
|
||||
|
||||
public void writeAndFlush(@NotNull ServerPacket packet) {
|
||||
synchronized (tickBuffer){
|
||||
PacketUtils.writeFramedPacket(tickBuffer, packet, compressed);
|
||||
synchronized (tickBuffer) {
|
||||
attemptWrite(packet);
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void attemptWrite(ServerPacket packet) {
|
||||
synchronized (tickBuffer) {
|
||||
final int position = tickBuffer.position();
|
||||
try {
|
||||
PacketUtils.writeFramedPacket(tickBuffer, packet, compressed);
|
||||
} catch (BufferOverflowException e) {
|
||||
try {
|
||||
this.channel.write(tickBuffer.position(position).flip());
|
||||
this.tickBuffer.clear();
|
||||
PacketUtils.writeFramedPacket(tickBuffer, packet, compressed);
|
||||
} catch (IOException ex) {
|
||||
disconnect();
|
||||
MinecraftServer.getExceptionManager().handleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void attemptWrite(ByteBuffer buffer) {
|
||||
buffer.flip();
|
||||
synchronized (tickBuffer) {
|
||||
try {
|
||||
this.tickBuffer.put(buffer);
|
||||
this.tickBuffer.put(buffer.flip());
|
||||
} catch (BufferOverflowException e) {
|
||||
try {
|
||||
this.channel.write(tickBuffer.flip());
|
||||
@ -235,13 +248,12 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
|
||||
public void flush() {
|
||||
synchronized (tickBuffer) {
|
||||
this.tickBuffer.flip();
|
||||
if (tickBuffer.remaining() == 0) {
|
||||
if (tickBuffer.position() == 0) {
|
||||
// Nothing to write
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.channel.write(tickBuffer);
|
||||
this.channel.write(tickBuffer.flip());
|
||||
} catch (IOException e) {
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
@ -402,9 +414,6 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseTickBuffer() {
|
||||
}
|
||||
|
||||
public byte[] getNonce() {
|
||||
return nonce;
|
||||
}
|
||||
|
@ -73,8 +73,7 @@ public class Worker {
|
||||
}
|
||||
|
||||
public void receiveConnection(SocketChannel channel) throws IOException {
|
||||
var connection = new NettyPlayerConnection(channel);
|
||||
this.connectionMap.put(channel, connection);
|
||||
this.connectionMap.put(channel, new NettyPlayerConnection(channel, channel.getRemoteAddress()));
|
||||
register(channel);
|
||||
this.selector.wakeup();
|
||||
}
|
||||
@ -91,7 +90,7 @@ public class Worker {
|
||||
private void disconnect(NettyPlayerConnection connection, SocketChannel channel) throws IOException {
|
||||
// Client close
|
||||
channel.close();
|
||||
connectionMap.remove(channel);
|
||||
this.connectionMap.remove(channel);
|
||||
// Remove the connection
|
||||
connection.refreshOnline(false);
|
||||
Player player = connection.getPlayer();
|
||||
|
@ -89,7 +89,8 @@ public final class PacketUtils {
|
||||
// Send grouped packet...
|
||||
final boolean success = PACKET_LISTENER_MANAGER.processServerPacket(packet, players);
|
||||
if (success) {
|
||||
final ByteBuffer finalBuffer = createFramedPacket(packet);
|
||||
ByteBuffer finalBuffer = ByteBuffer.allocate(2_000_000);
|
||||
writeFramedPacket(finalBuffer, packet, MinecraftServer.getCompressionThreshold() > 0);
|
||||
final FramedPacket framedPacket = new FramedPacket(finalBuffer);
|
||||
// Send packet to all players
|
||||
for (Player player : players) {
|
||||
@ -98,7 +99,6 @@ public final class PacketUtils {
|
||||
// Verify if the player should receive the packet
|
||||
if (playerValidator != null && !playerValidator.isValid(player))
|
||||
continue;
|
||||
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
if (playerConnection instanceof NettyPlayerConnection) {
|
||||
final NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) playerConnection;
|
||||
@ -114,8 +114,7 @@ public final class PacketUtils {
|
||||
// Verify if the player should receive the packet
|
||||
if (playerValidator != null && !playerValidator.isValid(player))
|
||||
continue;
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
playerConnection.sendPacket(packet, false);
|
||||
player.getPlayerConnection().sendPacket(packet, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,11 +153,11 @@ public final class PacketUtils {
|
||||
// Packet large enough, compress
|
||||
final int limitCache = buffer.limit();
|
||||
buffer.position(contentStart).limit(contentStart + packetSize);
|
||||
var uncompressedCopy = ByteBuffer.allocate(packetSize).put(buffer);
|
||||
var uncompressedCopy = ByteBuffer.allocate(packetSize).put(buffer).flip();
|
||||
buffer.position(contentStart).limit(limitCache);
|
||||
|
||||
var deflater = COMPRESSOR.get();
|
||||
deflater.setInput(uncompressedCopy.flip());
|
||||
deflater.setInput(uncompressedCopy);
|
||||
deflater.finish();
|
||||
deflater.deflate(buffer);
|
||||
deflater.reset();
|
||||
@ -170,17 +169,4 @@ public final class PacketUtils {
|
||||
Utils.writeVarIntHeader(buffer, uncompressedIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a "framed packet" (packet which can be send and understood by a Minecraft client)
|
||||
* from a server packet, directly into an output buffer.
|
||||
* <p>
|
||||
* Can be used if you want to store a raw buffer and send it later without the additional writing cost.
|
||||
* Compression is applied if {@link MinecraftServer#getCompressionThreshold()} is greater than 0.
|
||||
*/
|
||||
public static @NotNull ByteBuffer createFramedPacket(@NotNull ServerPacket serverPacket) {
|
||||
ByteBuffer packetBuf = ByteBuffer.allocate(2_000_000);
|
||||
writeFramedPacket(packetBuf, serverPacket, MinecraftServer.getCompressionThreshold() > 0);
|
||||
return packetBuf;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user