3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-09-08 12:32:53 +02:00

Ensure skull operations are done on the player thread

Dieser Commit ist enthalten in:
Camotoy 2021-08-21 19:38:13 -04:00
Ursprung ab540b1951
Commit a1d167d5f1
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
3 geänderte Dateien mit 37 neuen und 30 gelöschten Zeilen

Datei anzeigen

@ -34,7 +34,6 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket; import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -43,17 +42,16 @@ import org.geysermc.connector.network.session.GeyserSession;
* custom player skulls in Bedrock. * custom player skulls in Bedrock.
*/ */
public class SkullPlayerEntity extends PlayerEntity { public class SkullPlayerEntity extends PlayerEntity {
/** /**
* Stores the block state that the skull is associated with. Used to determine if the block in the skull's position * Stores the block state that the skull is associated with. Used to determine if the block in the skull's position
* has changed * has changed
*/ */
@Getter @Getter
@Setter private final int blockState;
private int blockState;
public SkullPlayerEntity(GameProfile gameProfile, long geyserId, Vector3f position, Vector3f rotation) { public SkullPlayerEntity(GameProfile gameProfile, long geyserId, Vector3f position, Vector3f rotation, int blockState) {
super(gameProfile, 0, geyserId, position, Vector3f.ZERO, rotation); super(gameProfile, 0, geyserId, position, Vector3f.ZERO, rotation);
this.blockState = blockState;
setPlayerList(false); setPlayerList(false);
//Set bounding box to almost nothing so the skull is able to be broken and not cause entity to cast a shadow //Set bounding box to almost nothing so the skull is able to be broken and not cause entity to cast a shadow

Datei anzeigen

@ -883,7 +883,7 @@ public class GeyserSession implements CommandSender {
try { try {
runnable.run(); runnable.run();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); connector.getLogger().error("Error thrown in " + getName() + "'s event loop!", e);
} }
}); });
} }
@ -896,7 +896,7 @@ public class GeyserSession implements CommandSender {
try { try {
runnable.run(); runnable.run();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); connector.getLogger().error("Error thrown in " + getName() + "'s event loop!", e);
} }
}, duration, timeUnit); }, duration, timeUnit);
} }

Datei anzeigen

@ -123,36 +123,45 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
Vector3i blockPosition = Vector3i.from(posX, posY, posZ); Vector3i blockPosition = Vector3i.from(posX, posY, posZ);
Vector3f entityPosition = Vector3f.from(x, y, z); Vector3f entityPosition = Vector3f.from(x, y, z);
Vector3f entityRotation = Vector3f.from(rotation, 0, rotation); Vector3f entityRotation = Vector3f.from(rotation, 0, rotation);
long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
getProfile(tag).whenComplete((gameProfile, throwable) -> { getProfile(tag).whenComplete((gameProfile, throwable) -> {
if (gameProfile == null) { if (gameProfile == null) {
session.getConnector().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition.toString() + " " + tag.toString()); session.getConnector().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag);
return; return;
} }
SkullPlayerEntity existingSkull = session.getSkullCache().get(blockPosition); if (session.getEventLoop().inEventLoop()) {
if (existingSkull != null) { spawnPlayer(session, gameProfile, blockPosition, entityPosition, entityRotation, blockState);
// Ensure that two skulls can't spawn on the same point } else {
existingSkull.despawnEntity(session, blockPosition); session.executeInEventLoop(() -> spawnPlayer(session, gameProfile, blockPosition, entityPosition, entityRotation, blockState));
}
SkullPlayerEntity player = new SkullPlayerEntity(gameProfile, geyserId, entityPosition, entityRotation);
player.setBlockState(blockState);
// Cache entity
session.getSkullCache().put(blockPosition, player);
// Only send to session if we are initialized, otherwise it will happen then.
if (session.getUpstream().isInitialized()) {
player.spawnEntity(session);
SkullSkinManager.requestAndHandleSkin(player, session, (skin -> session.scheduleInEventLoop(() -> {
// Delay to minimize split-second "player" pop-in
player.getMetadata().getFlags().setFlag(EntityFlag.INVISIBLE, false);
player.updateBedrockMetadata(session);
}, 250, TimeUnit.MILLISECONDS)));
} }
}); });
} }
private static void spawnPlayer(GeyserSession session, GameProfile profile, Vector3i blockPosition,
Vector3f entityPosition, Vector3f entityRotation, int blockState) {
long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
SkullPlayerEntity existingSkull = session.getSkullCache().get(blockPosition);
if (existingSkull != null) {
// Ensure that two skulls can't spawn on the same point
existingSkull.despawnEntity(session, blockPosition);
}
SkullPlayerEntity player = new SkullPlayerEntity(profile, geyserId, entityPosition, entityRotation, blockState);
// Cache entity
session.getSkullCache().put(blockPosition, player);
// Only send to session if we are initialized, otherwise it will happen then.
if (session.getUpstream().isInitialized()) {
player.spawnEntity(session);
SkullSkinManager.requestAndHandleSkin(player, session, (skin -> session.scheduleInEventLoop(() -> {
// Delay to minimize split-second "player" pop-in
player.getMetadata().getFlags().setFlag(EntityFlag.INVISIBLE, false);
player.updateBedrockMetadata(session);
}, 250, TimeUnit.MILLISECONDS)));
}
}
} }