forked from GeyserMC/Geyser
Use authData UUID when sending playerlist packets to the client (#654)
Bedrock knows its own UUID and when it receives the Java uuid it will either crash (MCEE) or add a ghost player onto the playerlist (Bedrock). This change will check if an entity is the client and if so replace the entities UUID with the AuthData UUID. A refactor of JavaPlayerListEntryTranslator was also done as I got confused each time what it was doing so it is now hopefully a bit clearer and also fixes the case where an entity is removed but still exists on the server (Vanished).
This commit is contained in:
parent
cc6c7fe78d
commit
a929c411d2
2 changed files with 75 additions and 32 deletions
|
@ -42,22 +42,30 @@ import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||||
public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayerListEntryPacket> {
|
public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayerListEntryPacket> {
|
||||||
@Override
|
@Override
|
||||||
public void translate(ServerPlayerListEntryPacket packet, GeyserSession session) {
|
public void translate(ServerPlayerListEntryPacket packet, GeyserSession session) {
|
||||||
if (packet.getAction() != PlayerListEntryAction.ADD_PLAYER && packet.getAction() != PlayerListEntryAction.REMOVE_PLAYER) return;
|
if (packet.getAction() != PlayerListEntryAction.ADD_PLAYER && packet.getAction() != PlayerListEntryAction.REMOVE_PLAYER)
|
||||||
|
return;
|
||||||
|
|
||||||
PlayerListPacket translate = new PlayerListPacket();
|
PlayerListPacket translate = new PlayerListPacket();
|
||||||
translate.setAction(packet.getAction() == PlayerListEntryAction.ADD_PLAYER ? PlayerListPacket.Action.ADD : PlayerListPacket.Action.REMOVE);
|
translate.setAction(packet.getAction() == PlayerListEntryAction.ADD_PLAYER ? PlayerListPacket.Action.ADD : PlayerListPacket.Action.REMOVE);
|
||||||
|
|
||||||
for (PlayerListEntry entry : packet.getEntries()) {
|
for (PlayerListEntry entry : packet.getEntries()) {
|
||||||
if (packet.getAction() == PlayerListEntryAction.ADD_PLAYER) {
|
switch (packet.getAction()) {
|
||||||
|
case ADD_PLAYER:
|
||||||
|
PlayerEntity playerEntity;
|
||||||
boolean self = entry.getProfile().getId().equals(session.getPlayerEntity().getUuid());
|
boolean self = entry.getProfile().getId().equals(session.getPlayerEntity().getUuid());
|
||||||
|
|
||||||
PlayerEntity playerEntity = session.getPlayerEntity();
|
|
||||||
if (self) {
|
if (self) {
|
||||||
playerEntity.setProfile(entry.getProfile());
|
// Entity is ourself
|
||||||
|
playerEntity = session.getPlayerEntity();
|
||||||
SkinUtils.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape -> {
|
SkinUtils.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape -> {
|
||||||
GeyserConnector.getInstance().getLogger().debug("Loading Local Bedrock Java Skin Data");
|
GeyserConnector.getInstance().getLogger().debug("Loading Local Bedrock Java Skin Data");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
playerEntity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerEntity == null) {
|
||||||
|
// It's a new player
|
||||||
playerEntity = new PlayerEntity(
|
playerEntity = new PlayerEntity(
|
||||||
entry.getProfile(),
|
entry.getProfile(),
|
||||||
-1,
|
-1,
|
||||||
|
@ -68,21 +76,43 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerEntity.setPlayerList(true);
|
|
||||||
playerEntity.setValid(true);
|
|
||||||
session.getEntityCache().addPlayerEntity(playerEntity);
|
session.getEntityCache().addPlayerEntity(playerEntity);
|
||||||
|
|
||||||
translate.getEntries().add(SkinUtils.buildCachedEntry(entry.getProfile(), playerEntity.getGeyserId()));
|
playerEntity.setProfile(entry.getProfile());
|
||||||
} else {
|
playerEntity.setPlayerList(true);
|
||||||
|
playerEntity.setValid(true);
|
||||||
|
|
||||||
|
PlayerListPacket.Entry playerListEntry = SkinUtils.buildCachedEntry(entry.getProfile(), playerEntity.getGeyserId());
|
||||||
|
if (self) {
|
||||||
|
// Copy the entry with our identity instead.
|
||||||
|
PlayerListPacket.Entry copy = new PlayerListPacket.Entry(session.getAuthData().getUUID());
|
||||||
|
copy.setName(playerListEntry.getName());
|
||||||
|
copy.setEntityId(playerListEntry.getEntityId());
|
||||||
|
copy.setSkin(playerListEntry.getSkin());
|
||||||
|
copy.setXuid(playerListEntry.getXuid());
|
||||||
|
copy.setPlatformChatId(playerListEntry.getPlatformChatId());
|
||||||
|
copy.setTeacher(playerListEntry.isTeacher());
|
||||||
|
playerListEntry = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
translate.getEntries().add(playerListEntry);
|
||||||
|
break;
|
||||||
|
case REMOVE_PLAYER:
|
||||||
PlayerEntity entity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
PlayerEntity entity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
||||||
if (entity != null && entity.isValid()) {
|
if (entity != null && entity.isValid()) {
|
||||||
// remove from tablist but player entity is still there
|
// remove from tablist but player entity is still there
|
||||||
entity.setPlayerList(false);
|
entity.setPlayerList(false);
|
||||||
} else {
|
} else {
|
||||||
// just remove it from caching
|
// just remove it from caching
|
||||||
|
if (entity == null) {
|
||||||
session.getEntityCache().removePlayerEntity(entry.getProfile().getId());
|
session.getEntityCache().removePlayerEntity(entry.getProfile().getId());
|
||||||
|
} else {
|
||||||
|
entity.setPlayerList(false);
|
||||||
|
session.getEntityCache().removeEntity(entity, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
translate.getEntries().add(new PlayerListPacket.Entry(entry.getProfile().getId()));
|
translate.getEntries().add(new PlayerListPacket.Entry(entry.getProfile().getId()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,19 @@ public class SkinUtils {
|
||||||
geometry.getGeometryData()
|
geometry.getGeometryData()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If it is our skin we replace the UUID with the authdata UUID
|
||||||
|
if (session.getPlayerEntity() == entity) {
|
||||||
|
// Copy the entry with our identity instead.
|
||||||
|
PlayerListPacket.Entry copy = new PlayerListPacket.Entry(session.getAuthData().getUUID());
|
||||||
|
copy.setName(updatedEntry.getName());
|
||||||
|
copy.setEntityId(updatedEntry.getEntityId());
|
||||||
|
copy.setSkin(updatedEntry.getSkin());
|
||||||
|
copy.setXuid(updatedEntry.getXuid());
|
||||||
|
copy.setPlatformChatId(updatedEntry.getPlatformChatId());
|
||||||
|
copy.setTeacher(updatedEntry.isTeacher());
|
||||||
|
updatedEntry = copy;
|
||||||
|
}
|
||||||
|
|
||||||
PlayerListPacket playerRemovePacket = new PlayerListPacket();
|
PlayerListPacket playerRemovePacket = new PlayerListPacket();
|
||||||
playerRemovePacket.setAction(PlayerListPacket.Action.REMOVE);
|
playerRemovePacket.setAction(PlayerListPacket.Action.REMOVE);
|
||||||
playerRemovePacket.getEntries().add(updatedEntry);
|
playerRemovePacket.getEntries().add(updatedEntry);
|
||||||
|
|
Loading…
Reference in a new issue