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.TagHandler;
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.entity.EntityUtils;
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) {
Check.stateCondition(!instance.isRegistered(),
"Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance");
if (isRemoved()) return AsyncUtils.VOID_FUTURE;
if (this.instance != null) {
this.instance.UNSAFE_removeEntity(this);
}
@ -1267,16 +1269,15 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
* WARNING: this does not trigger {@link EntityDeathEvent}.
*/
public void remove() {
if (isRemoved())
return;
if (isRemoved()) return;
MinecraftServer.getUpdateManager().getThreadProvider().removeEntity(this);
this.removed = true;
this.shouldRemove = true;
Entity.ENTITY_BY_ID.remove(id);
Entity.ENTITY_BY_UUID.remove(uuid);
if (instance != null)
if (instance != null) {
instance.UNSAFE_removeEntity(this);
}
}
/**

View File

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

View File

@ -268,7 +268,7 @@ public final class ConnectionManager {
* @param connection the player connection
* @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);
if (player == null)
return;
@ -344,7 +344,7 @@ public final class ConnectionManager {
/**
* Shutdowns the connection manager by kicking all the currently connected players.
*/
public void shutdown() {
public synchronized void shutdown() {
DisconnectPacket disconnectPacket = new DisconnectPacket(shutdownText);
for (Player player : getOnlinePlayers()) {
final PlayerConnection playerConnection = player.getPlayerConnection();

View File

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

View File

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

View File

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