Fix ghost players

This commit is contained in:
TheMode 2021-08-05 15:10:15 +02:00
parent 87f141ff50
commit 7ba8189a28
6 changed files with 26 additions and 40 deletions

View File

@ -33,6 +33,7 @@ import net.minestom.server.potion.TimedPotion;
import net.minestom.server.tag.Tag; import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagHandler; import net.minestom.server.tag.TagHandler;
import net.minestom.server.thread.ThreadProvider; import net.minestom.server.thread.ThreadProvider;
import net.minestom.server.utils.async.AsyncUtils;
import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.entity.EntityUtils; import net.minestom.server.utils.entity.EntityUtils;
import net.minestom.server.utils.player.PlayerUtils; import net.minestom.server.utils.player.PlayerUtils;
@ -708,6 +709,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
public CompletableFuture<Void> setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) { public CompletableFuture<Void> setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
Check.stateCondition(!instance.isRegistered(), Check.stateCondition(!instance.isRegistered(),
"Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance"); "Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance");
if (isRemoved()) return AsyncUtils.VOID_FUTURE;
if (this.instance != null) { if (this.instance != null) {
this.instance.UNSAFE_removeEntity(this); this.instance.UNSAFE_removeEntity(this);
} }
@ -1267,16 +1269,15 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
* WARNING: this does not trigger {@link EntityDeathEvent}. * WARNING: this does not trigger {@link EntityDeathEvent}.
*/ */
public void remove() { public void remove() {
if (isRemoved()) if (isRemoved()) return;
return;
MinecraftServer.getUpdateManager().getThreadProvider().removeEntity(this); MinecraftServer.getUpdateManager().getThreadProvider().removeEntity(this);
this.removed = true; this.removed = true;
this.shouldRemove = true; this.shouldRemove = true;
Entity.ENTITY_BY_ID.remove(id); Entity.ENTITY_BY_ID.remove(id);
Entity.ENTITY_BY_UUID.remove(uuid); Entity.ENTITY_BY_UUID.remove(uuid);
if (instance != null) if (instance != null) {
instance.UNSAFE_removeEntity(this); instance.UNSAFE_removeEntity(this);
}
} }
/** /**

View File

@ -441,18 +441,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
@Override @Override
public void remove() { public void remove() {
if (isRemoved()) if (isRemoved()) return;
return;
EventDispatcher.call(new PlayerDisconnectEvent(this)); EventDispatcher.call(new PlayerDisconnectEvent(this));
super.remove(); super.remove();
this.packets.clear(); this.packets.clear();
if (getOpenInventory() != null) if (getOpenInventory() != null) {
getOpenInventory().removeViewer(this); getOpenInventory().removeViewer(this);
}
MinecraftServer.getBossBarManager().removeAllBossBars(this); MinecraftServer.getBossBarManager().removeAllBossBars(this);
// Advancement tabs cache // Advancement tabs cache
{ {
Set<AdvancementTab> advancementTabs = AdvancementTab.getTabs(this); Set<AdvancementTab> advancementTabs = AdvancementTab.getTabs(this);
@ -462,15 +458,10 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
} }
} }
} }
// Clear all viewable entities // Clear all viewable entities
this.viewableEntities.forEach(entity -> entity.removeViewer(this)); this.viewableEntities.forEach(entity -> entity.removeViewer(this));
// Clear all viewable chunks // Clear all viewable chunks
this.viewableChunks.forEach(chunk -> { this.viewableChunks.forEach(chunk -> chunk.removeViewer(this));
if (chunk.isLoaded())
chunk.removeViewer(this);
});
playerConnection.disconnect();
} }
@Override @Override

View File

@ -268,7 +268,7 @@ public final class ConnectionManager {
* @param connection the player connection * @param connection the player connection
* @see PlayerConnection#disconnect() to properly disconnect a player * @see PlayerConnection#disconnect() to properly disconnect a player
*/ */
public void removePlayer(@NotNull PlayerConnection connection) { public synchronized void removePlayer(@NotNull PlayerConnection connection) {
final Player player = this.connectionPlayerMap.get(connection); final Player player = this.connectionPlayerMap.get(connection);
if (player == null) if (player == null)
return; return;
@ -344,7 +344,7 @@ public final class ConnectionManager {
/** /**
* Shutdowns the connection manager by kicking all the currently connected players. * Shutdowns the connection manager by kicking all the currently connected players.
*/ */
public void shutdown() { public synchronized void shutdown() {
DisconnectPacket disconnectPacket = new DisconnectPacket(shutdownText); DisconnectPacket disconnectPacket = new DisconnectPacket(shutdownText);
for (Player player : getOnlinePlayers()) { for (Player player : getOnlinePlayers()) {
final PlayerConnection playerConnection = player.getPlayerConnection(); final PlayerConnection playerConnection = player.getPlayerConnection();

View File

@ -101,7 +101,7 @@ public class NettyPlayerConnection extends PlayerConnection {
content = readBuffer; content = readBuffer;
} else { } else {
// Decompress to content buffer // Decompress to content buffer
content = workerContext.contentBuffer.clear(); content = workerContext.contentBuffer;
try { try {
final var inflater = workerContext.inflater; final var inflater = workerContext.inflater;
inflater.setInput(readBuffer); inflater.setInput(readBuffer);
@ -255,11 +255,7 @@ public class NettyPlayerConnection extends PlayerConnection {
@Override @Override
public void disconnect() { public void disconnect() {
try { this.worker.disconnect(this, channel);
this.worker.disconnect(this, channel);
} catch (IOException e) {
e.printStackTrace();
}
} }
public @NotNull SocketChannel getChannel() { public @NotNull SocketChannel getChannel() {

View File

@ -160,8 +160,7 @@ public abstract class PlayerConnection {
* *
* @return the player, can be null if not initialized yet * @return the player, can be null if not initialized yet
*/ */
@Nullable public @Nullable Player getPlayer() {
public Player getPlayer() {
return player; return player;
} }

View File

@ -61,11 +61,7 @@ public final class Worker {
connection.processPackets(workerContext, packetProcessor); connection.processPackets(workerContext, packetProcessor);
} catch (IOException e) { } catch (IOException e) {
// TODO print exception? (should ignore disconnection) // TODO print exception? (should ignore disconnection)
try { connection.disconnect();
disconnect(connection, channel);
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally { } finally {
workerContext.clearBuffers(); workerContext.clearBuffers();
} }
@ -84,15 +80,18 @@ public final class Worker {
this.selector.wakeup(); this.selector.wakeup();
} }
public void disconnect(NettyPlayerConnection connection, SocketChannel channel) throws IOException { public void disconnect(NettyPlayerConnection connection, SocketChannel channel) {
if (connectionMap.remove(channel) == null) return; try {
// Client close channel.close();
channel.close(); this.connectionMap.remove(channel);
connection.refreshOnline(false);
Player player = connection.getPlayer();
if (player != null) {
player.remove();
MinecraftServer.getConnectionManager().removePlayer(connection); MinecraftServer.getConnectionManager().removePlayer(connection);
connection.refreshOnline(false);
Player player = connection.getPlayer();
if (player != null) {
player.remove();
}
} catch (IOException e) {
e.printStackTrace();
} }
} }