Add LazyPacket

This commit is contained in:
themode 2021-12-22 08:06:00 +01:00 committed by TheMode
parent 7df51ef606
commit 39a0923326
5 changed files with 44 additions and 4 deletions

View File

@ -27,6 +27,7 @@ import net.minestom.server.instance.InstanceManager;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.network.packet.server.CachedPacket;
import net.minestom.server.network.packet.server.LazyPacket;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.permission.Permission;
@ -431,7 +432,7 @@ public class Entity implements Viewable, Tickable, Schedulable, TagHandler, Perm
public void updateNewViewer(@NotNull Player player) {
player.sendPacket(getEntityType().registry().spawnType().getSpawnPacket(this));
if (hasVelocity()) player.sendPacket(getVelocityPacket());
player.sendPacket(getMetadataPacket());
player.sendPacket(new LazyPacket(this::getMetadataPacket));
// Passengers
final Set<Entity> passengers = this.passengers;
if (!passengers.isEmpty()) {

View File

@ -19,6 +19,7 @@ import net.minestom.server.instance.EntityTracker;
import net.minestom.server.inventory.EquipmentHandler;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.ConnectionState;
import net.minestom.server.network.packet.server.LazyPacket;
import net.minestom.server.network.packet.server.play.CollectItemPacket;
import net.minestom.server.network.packet.server.play.EntityAnimationPacket;
import net.minestom.server.network.packet.server.play.EntityPropertiesPacket;
@ -514,8 +515,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
@Override
public void updateNewViewer(@NotNull Player player) {
super.updateNewViewer(player);
player.sendPacket(getEquipmentsPacket());
player.sendPacket(getPropertiesPacket());
player.sendPacket(new LazyPacket(this::getEquipmentsPacket));
player.sendPacket(new LazyPacket(this::getPropertiesPacket));
if (getTeam() != null) player.sendPacket(getTeam().createTeamsCreationPacket());
}

View File

@ -0,0 +1,34 @@
package net.minestom.server.network.packet.server;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
/**
* Represents a packet that is lazily allocated. Potentially in a different thread.
* <p>
* Supplier must be thread-safe.
*/
@ApiStatus.Internal
public final class LazyPacket implements SendablePacket {
private final Supplier<ServerPacket> packetSupplier;
private volatile ServerPacket packet;
public LazyPacket(@NotNull Supplier<@NotNull ServerPacket> packetSupplier) {
this.packetSupplier = packetSupplier;
}
public @NotNull ServerPacket packet() {
ServerPacket packet = this.packet;
if (packet == null) {
synchronized (this) {
packet = this.packet;
if (packet == null) {
packet = this.packet = packetSupplier.get();
}
}
}
return packet;
}
}

View File

@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
*/
@ApiStatus.Experimental
public sealed interface SendablePacket
permits ServerPacket, CachedPacket, FramedPacket {
permits CachedPacket, FramedPacket, LazyPacket, ServerPacket {
@ApiStatus.Experimental
static @NotNull ServerPacket extractServerPacket(@NotNull SendablePacket packet) {
@ -19,6 +19,8 @@ public sealed interface SendablePacket
return cachedPacket.packet();
} else if (packet instanceof FramedPacket framedPacket) {
return framedPacket.packet();
} else if (packet instanceof LazyPacket lazyPacket) {
return lazyPacket.packet();
} else {
throw new RuntimeException("Unknown packet type: " + packet.getClass().getName());
}

View File

@ -357,6 +357,8 @@ public class PlayerSocketConnection extends PlayerConnection {
writeFramedPacketSync(framedPacket);
} else if (packet instanceof CachedPacket cachedPacket) {
writeBufferSync(cachedPacket.body());
} else if (packet instanceof LazyPacket lazyPacket) {
writeServerPacketSync(lazyPacket.packet(), compressed);
} else {
throw new RuntimeException("Unknown packet type: " + packet.getClass().getName());
}