mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-12 13:44:28 +01:00
Seal snapshot interfaces
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
23d7df7cbb
commit
fdd3e2c53c
@ -23,10 +23,7 @@ import net.minestom.server.network.PacketProcessor;
|
|||||||
import net.minestom.server.network.socket.Server;
|
import net.minestom.server.network.socket.Server;
|
||||||
import net.minestom.server.recipe.RecipeManager;
|
import net.minestom.server.recipe.RecipeManager;
|
||||||
import net.minestom.server.scoreboard.TeamManager;
|
import net.minestom.server.scoreboard.TeamManager;
|
||||||
import net.minestom.server.snapshot.EntitySnapshot;
|
import net.minestom.server.snapshot.*;
|
||||||
import net.minestom.server.snapshot.InstanceSnapshot;
|
|
||||||
import net.minestom.server.snapshot.ServerSnapshot;
|
|
||||||
import net.minestom.server.snapshot.SnapshotUpdater;
|
|
||||||
import net.minestom.server.terminal.MinestomTerminal;
|
import net.minestom.server.terminal.MinestomTerminal;
|
||||||
import net.minestom.server.thread.Acquirable;
|
import net.minestom.server.thread.Acquirable;
|
||||||
import net.minestom.server.thread.ThreadDispatcher;
|
import net.minestom.server.thread.ThreadDispatcher;
|
||||||
@ -36,14 +33,12 @@ import net.minestom.server.utils.collection.MappedCollection;
|
|||||||
import net.minestom.server.world.DimensionTypeManager;
|
import net.minestom.server.world.DimensionTypeManager;
|
||||||
import net.minestom.server.world.biomes.BiomeManager;
|
import net.minestom.server.world.biomes.BiomeManager;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@ -274,21 +269,7 @@ final class ServerProcessImpl implements ServerProcess {
|
|||||||
entityRefs.put(entity.getEntityId(), updater.reference(entity));
|
entityRefs.put(entity.getEntityId(), updater.reference(entity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new SnapshotImpl(MappedCollection.plainReferences(instanceRefs), entityRefs);
|
return new SnapshotImpl.Server(MappedCollection.plainReferences(instanceRefs), entityRefs);
|
||||||
}
|
|
||||||
|
|
||||||
record SnapshotImpl(Collection<InstanceSnapshot> instances,
|
|
||||||
Int2ObjectOpenHashMap<AtomicReference<EntitySnapshot>> entityRefs) implements ServerSnapshot {
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<EntitySnapshot> entities() {
|
|
||||||
return MappedCollection.plainReferences(entityRefs.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @UnknownNullability EntitySnapshot entity(int id) {
|
|
||||||
var ref = entityRefs.get(id);
|
|
||||||
return ref != null ? ref.getPlain() : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class TickerImpl implements Ticker {
|
private final class TickerImpl implements Ticker {
|
||||||
|
@ -41,6 +41,7 @@ import net.minestom.server.potion.Potion;
|
|||||||
import net.minestom.server.potion.PotionEffect;
|
import net.minestom.server.potion.PotionEffect;
|
||||||
import net.minestom.server.potion.TimedPotion;
|
import net.minestom.server.potion.TimedPotion;
|
||||||
import net.minestom.server.snapshot.EntitySnapshot;
|
import net.minestom.server.snapshot.EntitySnapshot;
|
||||||
|
import net.minestom.server.snapshot.SnapshotImpl;
|
||||||
import net.minestom.server.snapshot.SnapshotUpdater;
|
import net.minestom.server.snapshot.SnapshotUpdater;
|
||||||
import net.minestom.server.snapshot.Snapshotable;
|
import net.minestom.server.snapshot.Snapshotable;
|
||||||
import net.minestom.server.tag.TagHandler;
|
import net.minestom.server.tag.TagHandler;
|
||||||
@ -1588,7 +1589,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
|||||||
final int[] viewersId = this.viewEngine.viewableOption.bitSet.toIntArray();
|
final int[] viewersId = this.viewEngine.viewableOption.bitSet.toIntArray();
|
||||||
final int[] passengersId = ArrayUtils.mapToIntArray(passengers, Entity::getEntityId);
|
final int[] passengersId = ArrayUtils.mapToIntArray(passengers, Entity::getEntityId);
|
||||||
final Entity vehicle = this.vehicle;
|
final Entity vehicle = this.vehicle;
|
||||||
return new EntitySnapshotImpl.Entity(entityType, uuid, id, position, velocity,
|
return new SnapshotImpl.Entity(entityType, uuid, id, position, velocity,
|
||||||
updater.reference(instance), chunk.getChunkX(), chunk.getChunkZ(),
|
updater.reference(instance), chunk.getChunkX(), chunk.getChunkZ(),
|
||||||
viewersId, passengersId, vehicle == null ? -1 : vehicle.getEntityId(),
|
viewersId, passengersId, vehicle == null ? -1 : vehicle.getEntityId(),
|
||||||
tagHandler.readableCopy());
|
tagHandler.readableCopy());
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
package net.minestom.server.entity;
|
|
||||||
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.coordinate.Vec;
|
|
||||||
import net.minestom.server.snapshot.ChunkSnapshot;
|
|
||||||
import net.minestom.server.snapshot.EntitySnapshot;
|
|
||||||
import net.minestom.server.snapshot.InstanceSnapshot;
|
|
||||||
import net.minestom.server.snapshot.PlayerSnapshot;
|
|
||||||
import net.minestom.server.tag.Tag;
|
|
||||||
import net.minestom.server.tag.TagReadable;
|
|
||||||
import net.minestom.server.utils.collection.IntMappedArray;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
final class EntitySnapshotImpl {
|
|
||||||
|
|
||||||
record Entity(EntityType type, UUID uuid, int id, Pos position, Vec velocity,
|
|
||||||
AtomicReference<InstanceSnapshot> instanceRef, int chunkX, int chunkZ,
|
|
||||||
int[] viewersId, int[] passengersId, int vehicleId,
|
|
||||||
TagReadable tagReadable) implements EntitySnapshot {
|
|
||||||
@Override
|
|
||||||
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
|
||||||
return tagReadable.getTag(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull InstanceSnapshot instance() {
|
|
||||||
return instanceRef.getPlain();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ChunkSnapshot chunk() {
|
|
||||||
return Objects.requireNonNull(instance().chunk(chunkX, chunkZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<@NotNull PlayerSnapshot> viewers() {
|
|
||||||
return new IntMappedArray<>(viewersId, id -> (PlayerSnapshot) instance().server().entity(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<@NotNull EntitySnapshot> passengers() {
|
|
||||||
return new IntMappedArray<>(passengersId, id -> instance().server().entity(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable EntitySnapshot vehicle() {
|
|
||||||
if (vehicleId == -1) return null;
|
|
||||||
return instance().server().entity(vehicleId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
record Player(EntitySnapshot snapshot, String username,
|
|
||||||
GameMode gameMode) implements PlayerSnapshot {
|
|
||||||
@Override
|
|
||||||
public @NotNull EntityType type() {
|
|
||||||
return snapshot.type();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull UUID uuid() {
|
|
||||||
return snapshot.uuid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int id() {
|
|
||||||
return snapshot.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Pos position() {
|
|
||||||
return snapshot.position();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Vec velocity() {
|
|
||||||
return snapshot.velocity();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull InstanceSnapshot instance() {
|
|
||||||
return snapshot.instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ChunkSnapshot chunk() {
|
|
||||||
return snapshot.chunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<@NotNull PlayerSnapshot> viewers() {
|
|
||||||
return snapshot.viewers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<@NotNull EntitySnapshot> passengers() {
|
|
||||||
return snapshot.passengers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable EntitySnapshot vehicle() {
|
|
||||||
return snapshot.vehicle();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
|
||||||
return snapshot.getTag(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,6 @@ import net.minestom.server.adventure.AdventurePacketConvertor;
|
|||||||
import net.minestom.server.adventure.Localizable;
|
import net.minestom.server.adventure.Localizable;
|
||||||
import net.minestom.server.adventure.audience.Audiences;
|
import net.minestom.server.adventure.audience.Audiences;
|
||||||
import net.minestom.server.attribute.Attribute;
|
import net.minestom.server.attribute.Attribute;
|
||||||
import net.minestom.server.collision.BoundingBox;
|
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
@ -67,6 +66,7 @@ import net.minestom.server.scoreboard.BelowNameTag;
|
|||||||
import net.minestom.server.scoreboard.Team;
|
import net.minestom.server.scoreboard.Team;
|
||||||
import net.minestom.server.snapshot.EntitySnapshot;
|
import net.minestom.server.snapshot.EntitySnapshot;
|
||||||
import net.minestom.server.snapshot.PlayerSnapshot;
|
import net.minestom.server.snapshot.PlayerSnapshot;
|
||||||
|
import net.minestom.server.snapshot.SnapshotImpl;
|
||||||
import net.minestom.server.snapshot.SnapshotUpdater;
|
import net.minestom.server.snapshot.SnapshotUpdater;
|
||||||
import net.minestom.server.statistic.PlayerStatistic;
|
import net.minestom.server.statistic.PlayerStatistic;
|
||||||
import net.minestom.server.timer.Scheduler;
|
import net.minestom.server.timer.Scheduler;
|
||||||
@ -1988,7 +1988,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||||||
@Override
|
@Override
|
||||||
public @NotNull PlayerSnapshot updateSnapshot(@NotNull SnapshotUpdater updater) {
|
public @NotNull PlayerSnapshot updateSnapshot(@NotNull SnapshotUpdater updater) {
|
||||||
final EntitySnapshot snapshot = super.updateSnapshot(updater);
|
final EntitySnapshot snapshot = super.updateSnapshot(updater);
|
||||||
return new EntitySnapshotImpl.Player(snapshot, username, gameMode);
|
return new SnapshotImpl.Player(snapshot, username, gameMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@ import net.minestom.server.network.packet.server.play.UpdateLightPacket;
|
|||||||
import net.minestom.server.network.packet.server.play.data.ChunkData;
|
import net.minestom.server.network.packet.server.play.data.ChunkData;
|
||||||
import net.minestom.server.network.packet.server.play.data.LightData;
|
import net.minestom.server.network.packet.server.play.data.LightData;
|
||||||
import net.minestom.server.snapshot.ChunkSnapshot;
|
import net.minestom.server.snapshot.ChunkSnapshot;
|
||||||
|
import net.minestom.server.snapshot.SnapshotImpl;
|
||||||
import net.minestom.server.snapshot.SnapshotUpdater;
|
import net.minestom.server.snapshot.SnapshotUpdater;
|
||||||
import net.minestom.server.utils.ArrayUtils;
|
import net.minestom.server.utils.ArrayUtils;
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
@ -253,7 +254,7 @@ public class DynamicChunk extends Chunk {
|
|||||||
clonedSections[i] = sections.get(i).clone();
|
clonedSections[i] = sections.get(i).clone();
|
||||||
var entities = instance.getEntityTracker().chunkEntities(chunkX, chunkZ, EntityTracker.Target.ENTITIES);
|
var entities = instance.getEntityTracker().chunkEntities(chunkX, chunkZ, EntityTracker.Target.ENTITIES);
|
||||||
final int[] entityIds = ArrayUtils.mapToIntArray(entities, Entity::getEntityId);
|
final int[] entityIds = ArrayUtils.mapToIntArray(entities, Entity::getEntityId);
|
||||||
return new InstanceSnapshotImpl.Chunk(minSection, chunkX, chunkZ,
|
return new SnapshotImpl.Chunk(minSection, chunkX, chunkZ,
|
||||||
clonedSections, entries.clone(), entityIds, updater.reference(instance),
|
clonedSections, entries.clone(), entityIds, updater.reference(instance),
|
||||||
tagHandler().readableCopy());
|
tagHandler().readableCopy());
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,7 @@ import net.minestom.server.instance.block.BlockHandler;
|
|||||||
import net.minestom.server.instance.generator.Generator;
|
import net.minestom.server.instance.generator.Generator;
|
||||||
import net.minestom.server.network.packet.server.play.BlockActionPacket;
|
import net.minestom.server.network.packet.server.play.BlockActionPacket;
|
||||||
import net.minestom.server.network.packet.server.play.TimeUpdatePacket;
|
import net.minestom.server.network.packet.server.play.TimeUpdatePacket;
|
||||||
import net.minestom.server.snapshot.ChunkSnapshot;
|
import net.minestom.server.snapshot.*;
|
||||||
import net.minestom.server.snapshot.InstanceSnapshot;
|
|
||||||
import net.minestom.server.snapshot.SnapshotUpdater;
|
|
||||||
import net.minestom.server.snapshot.Snapshotable;
|
|
||||||
import net.minestom.server.tag.TagHandler;
|
import net.minestom.server.tag.TagHandler;
|
||||||
import net.minestom.server.tag.Taggable;
|
import net.minestom.server.tag.Taggable;
|
||||||
import net.minestom.server.thread.ThreadDispatcher;
|
import net.minestom.server.thread.ThreadDispatcher;
|
||||||
@ -641,7 +638,7 @@ public abstract class Instance implements Block.Getter, Block.Setter,
|
|||||||
public @NotNull InstanceSnapshot updateSnapshot(@NotNull SnapshotUpdater updater) {
|
public @NotNull InstanceSnapshot updateSnapshot(@NotNull SnapshotUpdater updater) {
|
||||||
final Map<Long, AtomicReference<ChunkSnapshot>> chunksMap = updater.referencesMapLong(getChunks(), ChunkUtils::getChunkIndex);
|
final Map<Long, AtomicReference<ChunkSnapshot>> chunksMap = updater.referencesMapLong(getChunks(), ChunkUtils::getChunkIndex);
|
||||||
final int[] entities = ArrayUtils.mapToIntArray(entityTracker.entities(), Entity::getEntityId);
|
final int[] entities = ArrayUtils.mapToIntArray(entityTracker.entities(), Entity::getEntityId);
|
||||||
return new InstanceSnapshotImpl.Instance(updater.reference(MinecraftServer.process()),
|
return new SnapshotImpl.Instance(updater.reference(MinecraftServer.process()),
|
||||||
getDimensionType(), getWorldAge(), getTime(), chunksMap, entities,
|
getDimensionType(), getWorldAge(), getTime(), chunksMap, entities,
|
||||||
tagHandler.readableCopy());
|
tagHandler.readableCopy());
|
||||||
}
|
}
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
package net.minestom.server.instance;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.instance.block.Block;
|
|
||||||
import net.minestom.server.snapshot.ChunkSnapshot;
|
|
||||||
import net.minestom.server.snapshot.EntitySnapshot;
|
|
||||||
import net.minestom.server.snapshot.InstanceSnapshot;
|
|
||||||
import net.minestom.server.snapshot.ServerSnapshot;
|
|
||||||
import net.minestom.server.tag.Tag;
|
|
||||||
import net.minestom.server.tag.TagReadable;
|
|
||||||
import net.minestom.server.utils.collection.IntMappedArray;
|
|
||||||
import net.minestom.server.utils.collection.MappedCollection;
|
|
||||||
import net.minestom.server.world.DimensionType;
|
|
||||||
import net.minestom.server.world.biomes.Biome;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import static net.minestom.server.utils.chunk.ChunkUtils.*;
|
|
||||||
|
|
||||||
final class InstanceSnapshotImpl {
|
|
||||||
|
|
||||||
record Instance(AtomicReference<ServerSnapshot> serverRef,
|
|
||||||
DimensionType dimensionType, long worldAge, long time,
|
|
||||||
Map<Long, AtomicReference<ChunkSnapshot>> chunksMap,
|
|
||||||
int[] entitiesIds,
|
|
||||||
TagReadable tagReadable) implements InstanceSnapshot {
|
|
||||||
@Override
|
|
||||||
public @Nullable ChunkSnapshot chunk(int chunkX, int chunkZ) {
|
|
||||||
var ref = chunksMap.get(getChunkIndex(chunkX, chunkZ));
|
|
||||||
return Objects.requireNonNull(ref, "Chunk not found").getPlain();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<@NotNull ChunkSnapshot> chunks() {
|
|
||||||
return MappedCollection.plainReferences(chunksMap.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<EntitySnapshot> entities() {
|
|
||||||
return new IntMappedArray<>(entitiesIds, id -> server().entity(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ServerSnapshot server() {
|
|
||||||
return serverRef.getPlain();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
|
||||||
return tagReadable.getTag(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
record Chunk(int minSection, int chunkX, int chunkZ,
|
|
||||||
Section[] sections,
|
|
||||||
Int2ObjectOpenHashMap<Block> blockEntries,
|
|
||||||
int[] entitiesIds,
|
|
||||||
AtomicReference<InstanceSnapshot> instanceRef,
|
|
||||||
TagReadable tagReadable) implements ChunkSnapshot {
|
|
||||||
@Override
|
|
||||||
public @UnknownNullability Block getBlock(int x, int y, int z, @NotNull Condition condition) {
|
|
||||||
// Verify if the block object is present
|
|
||||||
if (condition != Condition.TYPE) {
|
|
||||||
final Block entry = !blockEntries.isEmpty() ?
|
|
||||||
blockEntries.get(getBlockIndex(x, y, z)) : null;
|
|
||||||
if (entry != null || condition == Condition.CACHED) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Retrieve the block from state id
|
|
||||||
final Section section = sections[getChunkCoordinate(y) - minSection];
|
|
||||||
final int blockStateId = section.blockPalette()
|
|
||||||
.get(toSectionRelativeCoordinate(x), toSectionRelativeCoordinate(y), toSectionRelativeCoordinate(z));
|
|
||||||
return Objects.requireNonNullElse(Block.fromStateId((short) blockStateId), Block.AIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Biome getBiome(int x, int y, int z) {
|
|
||||||
final Section section = sections[getChunkCoordinate(y) - minSection];
|
|
||||||
final int id = section.biomePalette()
|
|
||||||
.get(toSectionRelativeCoordinate(x) / 4, toSectionRelativeCoordinate(y) / 4, toSectionRelativeCoordinate(z) / 4);
|
|
||||||
return MinecraftServer.getBiomeManager().getById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
|
||||||
return tagReadable.getTag(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull InstanceSnapshot instance() {
|
|
||||||
return instanceRef.getPlain();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<@NotNull EntitySnapshot> entities() {
|
|
||||||
return new IntMappedArray<>(entitiesIds, id -> instance().server().entity(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface ChunkSnapshot extends Snapshot, Block.Getter, Biome.Getter, TagReadable {
|
public sealed interface ChunkSnapshot extends Snapshot, Block.Getter, Biome.Getter, TagReadable
|
||||||
|
permits SnapshotImpl.Chunk {
|
||||||
int chunkX();
|
int chunkX();
|
||||||
|
|
||||||
int chunkZ();
|
int chunkZ();
|
||||||
|
@ -10,7 +10,8 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface EntitySnapshot extends Snapshot, TagReadable {
|
public sealed interface EntitySnapshot extends Snapshot, TagReadable
|
||||||
|
permits PlayerSnapshot, SnapshotImpl.Entity {
|
||||||
@NotNull EntityType type();
|
@NotNull EntityType type();
|
||||||
|
|
||||||
@NotNull UUID uuid();
|
@NotNull UUID uuid();
|
||||||
|
@ -14,7 +14,8 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import static net.minestom.server.utils.chunk.ChunkUtils.getChunkCoordinate;
|
import static net.minestom.server.utils.chunk.ChunkUtils.getChunkCoordinate;
|
||||||
|
|
||||||
public interface InstanceSnapshot extends Snapshot, Block.Getter, Biome.Getter, TagReadable {
|
public sealed interface InstanceSnapshot extends Snapshot, Block.Getter, Biome.Getter, TagReadable
|
||||||
|
permits SnapshotImpl.Instance {
|
||||||
@NotNull DimensionType dimensionType();
|
@NotNull DimensionType dimensionType();
|
||||||
|
|
||||||
long worldAge();
|
long worldAge();
|
||||||
|
@ -3,7 +3,8 @@ package net.minestom.server.snapshot;
|
|||||||
import net.minestom.server.entity.GameMode;
|
import net.minestom.server.entity.GameMode;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public interface PlayerSnapshot extends EntitySnapshot {
|
public sealed interface PlayerSnapshot extends EntitySnapshot
|
||||||
|
permits SnapshotImpl.Player {
|
||||||
@NotNull String username();
|
@NotNull String username();
|
||||||
|
|
||||||
@NotNull GameMode gameMode();
|
@NotNull GameMode gameMode();
|
||||||
|
@ -12,7 +12,8 @@ import java.util.Collection;
|
|||||||
/**
|
/**
|
||||||
* Represents the complete state of the server at a given moment.
|
* Represents the complete state of the server at a given moment.
|
||||||
*/
|
*/
|
||||||
public interface ServerSnapshot extends Snapshot {
|
public sealed interface ServerSnapshot extends Snapshot
|
||||||
|
permits SnapshotImpl.Server {
|
||||||
@NotNull Collection<@NotNull InstanceSnapshot> instances();
|
@NotNull Collection<@NotNull InstanceSnapshot> instances();
|
||||||
|
|
||||||
@NotNull Collection<EntitySnapshot> entities();
|
@NotNull Collection<EntitySnapshot> entities();
|
||||||
|
218
src/main/java/net/minestom/server/snapshot/SnapshotImpl.java
Normal file
218
src/main/java/net/minestom/server/snapshot/SnapshotImpl.java
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
package net.minestom.server.snapshot;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.instance.Section;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.tag.Tag;
|
||||||
|
import net.minestom.server.tag.TagReadable;
|
||||||
|
import net.minestom.server.utils.collection.IntMappedArray;
|
||||||
|
import net.minestom.server.utils.collection.MappedCollection;
|
||||||
|
import net.minestom.server.world.DimensionType;
|
||||||
|
import net.minestom.server.world.biomes.Biome;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import static net.minestom.server.utils.chunk.ChunkUtils.*;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public final class SnapshotImpl {
|
||||||
|
public record Server(Collection<InstanceSnapshot> instances,
|
||||||
|
Int2ObjectOpenHashMap<AtomicReference<EntitySnapshot>> entityRefs) implements ServerSnapshot {
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<EntitySnapshot> entities() {
|
||||||
|
return MappedCollection.plainReferences(entityRefs.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @UnknownNullability EntitySnapshot entity(int id) {
|
||||||
|
var ref = entityRefs.get(id);
|
||||||
|
return ref != null ? ref.getPlain() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Instance(AtomicReference<ServerSnapshot> serverRef,
|
||||||
|
DimensionType dimensionType, long worldAge, long time,
|
||||||
|
Map<Long, AtomicReference<ChunkSnapshot>> chunksMap,
|
||||||
|
int[] entitiesIds,
|
||||||
|
TagReadable tagReadable) implements InstanceSnapshot {
|
||||||
|
@Override
|
||||||
|
public @Nullable ChunkSnapshot chunk(int chunkX, int chunkZ) {
|
||||||
|
var ref = chunksMap.get(getChunkIndex(chunkX, chunkZ));
|
||||||
|
return Objects.requireNonNull(ref, "Chunk not found").getPlain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<@NotNull ChunkSnapshot> chunks() {
|
||||||
|
return MappedCollection.plainReferences(chunksMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<EntitySnapshot> entities() {
|
||||||
|
return new IntMappedArray<>(entitiesIds, id -> server().entity(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ServerSnapshot server() {
|
||||||
|
return serverRef.getPlain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
||||||
|
return tagReadable.getTag(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Chunk(int minSection, int chunkX, int chunkZ,
|
||||||
|
Section[] sections,
|
||||||
|
Int2ObjectOpenHashMap<Block> blockEntries,
|
||||||
|
int[] entitiesIds,
|
||||||
|
AtomicReference<InstanceSnapshot> instanceRef,
|
||||||
|
TagReadable tagReadable) implements ChunkSnapshot {
|
||||||
|
@Override
|
||||||
|
public @UnknownNullability Block getBlock(int x, int y, int z, @NotNull Condition condition) {
|
||||||
|
// Verify if the block object is present
|
||||||
|
if (condition != Condition.TYPE) {
|
||||||
|
final Block entry = !blockEntries.isEmpty() ?
|
||||||
|
blockEntries.get(getBlockIndex(x, y, z)) : null;
|
||||||
|
if (entry != null || condition == Condition.CACHED) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Retrieve the block from state id
|
||||||
|
final Section section = sections[getChunkCoordinate(y) - minSection];
|
||||||
|
final int blockStateId = section.blockPalette()
|
||||||
|
.get(toSectionRelativeCoordinate(x), toSectionRelativeCoordinate(y), toSectionRelativeCoordinate(z));
|
||||||
|
return Objects.requireNonNullElse(Block.fromStateId((short) blockStateId), Block.AIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Biome getBiome(int x, int y, int z) {
|
||||||
|
final Section section = sections[getChunkCoordinate(y) - minSection];
|
||||||
|
final int id = section.biomePalette()
|
||||||
|
.get(toSectionRelativeCoordinate(x) / 4, toSectionRelativeCoordinate(y) / 4, toSectionRelativeCoordinate(z) / 4);
|
||||||
|
return MinecraftServer.getBiomeManager().getById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
||||||
|
return tagReadable.getTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull InstanceSnapshot instance() {
|
||||||
|
return instanceRef.getPlain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<@NotNull EntitySnapshot> entities() {
|
||||||
|
return new IntMappedArray<>(entitiesIds, id -> instance().server().entity(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Entity(EntityType type, UUID uuid, int id, Pos position, Vec velocity,
|
||||||
|
AtomicReference<InstanceSnapshot> instanceRef, int chunkX, int chunkZ,
|
||||||
|
int[] viewersId, int[] passengersId, int vehicleId,
|
||||||
|
TagReadable tagReadable) implements EntitySnapshot {
|
||||||
|
@Override
|
||||||
|
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
||||||
|
return tagReadable.getTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull InstanceSnapshot instance() {
|
||||||
|
return instanceRef.getPlain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ChunkSnapshot chunk() {
|
||||||
|
return Objects.requireNonNull(instance().chunk(chunkX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<@NotNull PlayerSnapshot> viewers() {
|
||||||
|
return new IntMappedArray<>(viewersId, id -> (PlayerSnapshot) instance().server().entity(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<@NotNull EntitySnapshot> passengers() {
|
||||||
|
return new IntMappedArray<>(passengersId, id -> instance().server().entity(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable EntitySnapshot vehicle() {
|
||||||
|
if (vehicleId == -1) return null;
|
||||||
|
return instance().server().entity(vehicleId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Player(EntitySnapshot snapshot, String username,
|
||||||
|
GameMode gameMode) implements PlayerSnapshot {
|
||||||
|
@Override
|
||||||
|
public @NotNull EntityType type() {
|
||||||
|
return snapshot.type();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull UUID uuid() {
|
||||||
|
return snapshot.uuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int id() {
|
||||||
|
return snapshot.id();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Pos position() {
|
||||||
|
return snapshot.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Vec velocity() {
|
||||||
|
return snapshot.velocity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull InstanceSnapshot instance() {
|
||||||
|
return snapshot.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ChunkSnapshot chunk() {
|
||||||
|
return snapshot.chunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<@NotNull PlayerSnapshot> viewers() {
|
||||||
|
return snapshot.viewers();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<@NotNull EntitySnapshot> passengers() {
|
||||||
|
return snapshot.passengers();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable EntitySnapshot vehicle() {
|
||||||
|
return snapshot.vehicle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
||||||
|
return snapshot.getTag(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user