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,47 +42,77 @@ import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
|||
public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayerListEntryPacket> {
|
||||
@Override
|
||||
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();
|
||||
translate.setAction(packet.getAction() == PlayerListEntryAction.ADD_PLAYER ? PlayerListPacket.Action.ADD : PlayerListPacket.Action.REMOVE);
|
||||
|
||||
for (PlayerListEntry entry : packet.getEntries()) {
|
||||
if (packet.getAction() == PlayerListEntryAction.ADD_PLAYER) {
|
||||
boolean self = entry.getProfile().getId().equals(session.getPlayerEntity().getUuid());
|
||||
switch (packet.getAction()) {
|
||||
case ADD_PLAYER:
|
||||
PlayerEntity playerEntity;
|
||||
boolean self = entry.getProfile().getId().equals(session.getPlayerEntity().getUuid());
|
||||
|
||||
if (self) {
|
||||
// Entity is ourself
|
||||
playerEntity = session.getPlayerEntity();
|
||||
SkinUtils.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape -> {
|
||||
GeyserConnector.getInstance().getLogger().debug("Loading Local Bedrock Java Skin Data");
|
||||
});
|
||||
} else {
|
||||
playerEntity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
||||
}
|
||||
|
||||
if (playerEntity == null) {
|
||||
// It's a new player
|
||||
playerEntity = new PlayerEntity(
|
||||
entry.getProfile(),
|
||||
-1,
|
||||
session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO
|
||||
);
|
||||
}
|
||||
|
||||
session.getEntityCache().addPlayerEntity(playerEntity);
|
||||
|
||||
PlayerEntity playerEntity = session.getPlayerEntity();
|
||||
if (self) {
|
||||
playerEntity.setProfile(entry.getProfile());
|
||||
SkinUtils.requestAndHandleSkinAndCape(playerEntity, session, skinAndCape -> {
|
||||
GeyserConnector.getInstance().getLogger().debug("Loading Local Bedrock Java Skin Data");
|
||||
});
|
||||
} else {
|
||||
playerEntity = new PlayerEntity(
|
||||
entry.getProfile(),
|
||||
-1,
|
||||
session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO,
|
||||
Vector3f.ZERO
|
||||
);
|
||||
}
|
||||
playerEntity.setPlayerList(true);
|
||||
playerEntity.setValid(true);
|
||||
|
||||
playerEntity.setPlayerList(true);
|
||||
playerEntity.setValid(true);
|
||||
session.getEntityCache().addPlayerEntity(playerEntity);
|
||||
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(SkinUtils.buildCachedEntry(entry.getProfile(), playerEntity.getGeyserId()));
|
||||
} else {
|
||||
PlayerEntity entity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
||||
if (entity != null && entity.isValid()) {
|
||||
// remove from tablist but player entity is still there
|
||||
entity.setPlayerList(false);
|
||||
} else {
|
||||
// just remove it from caching
|
||||
session.getEntityCache().removePlayerEntity(entry.getProfile().getId());
|
||||
}
|
||||
translate.getEntries().add(new PlayerListPacket.Entry(entry.getProfile().getId()));
|
||||
translate.getEntries().add(playerListEntry);
|
||||
break;
|
||||
case REMOVE_PLAYER:
|
||||
PlayerEntity entity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
||||
if (entity != null && entity.isValid()) {
|
||||
// remove from tablist but player entity is still there
|
||||
entity.setPlayerList(false);
|
||||
} else {
|
||||
// just remove it from caching
|
||||
if (entity == null) {
|
||||
session.getEntityCache().removePlayerEntity(entry.getProfile().getId());
|
||||
} else {
|
||||
entity.setPlayerList(false);
|
||||
session.getEntityCache().removeEntity(entity, false);
|
||||
}
|
||||
}
|
||||
translate.getEntries().add(new PlayerListPacket.Entry(entry.getProfile().getId()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,19 @@ public class SkinUtils {
|
|||
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();
|
||||
playerRemovePacket.setAction(PlayerListPacket.Action.REMOVE);
|
||||
playerRemovePacket.getEntries().add(updatedEntry);
|
||||
|
|
Loading…
Reference in a new issue