Search in sources :

Example 6 with LanternEntity

use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.

the class LanternWorld method pulseEntities.

private void pulseEntities() {
    // Pulse the entities
    for (LanternEntity entity : new ArrayList<>(this.entitiesByUniqueId.values())) {
        if (entity.isRemoved()) {
            final Vector3i lastChunk = entity.getLastChunkSectionCoords();
            if (lastChunk != null && entity.getRemoveState() == LanternEntity.RemoveState.DESTROYED) {
                final LanternChunk chunk = this.chunkManager.getChunkIfLoaded(lastChunk.getX(), lastChunk.getZ());
                if (chunk != null) {
                    chunk.removeEntity(entity, lastChunk.getY());
                }
            }
            this.entityProtocolManager.remove(entity);
            this.entitiesByUniqueId.remove(entity.getUniqueId());
        } else {
            final Vector3i lastChunkSection = entity.getLastChunkSectionCoords();
            entity.pulse();
            final Vector3i pos = entity.getPosition().toInt();
            final Vector3i newChunk = new Vector3i(pos.getX() >> 4, fixEntityYSection(pos.getY() >> 4), pos.getZ() >> 4);
            if (lastChunkSection == null || !lastChunkSection.equals(newChunk)) {
                LanternChunk chunk;
                if (lastChunkSection != null && (chunk = this.chunkManager.getChunkIfLoaded(lastChunkSection.getX(), lastChunkSection.getZ())) != null) {
                    chunk.removeEntity(entity, lastChunkSection.getY());
                }
                chunk = this.chunkManager.getOrLoadChunk(newChunk.getX(), newChunk.getZ());
                chunk.addEntity(entity, newChunk.getY());
                entity.setLastChunkCoords(newChunk);
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Vector3i(com.flowpowered.math.vector.Vector3i) LanternEntity(org.lanternpowered.server.entity.LanternEntity) LanternChunk(org.lanternpowered.server.world.chunk.LanternChunk)

Example 7 with LanternEntity

use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.

the class LanternWorld method addEntity.

@Nullable
private LanternEntity addEntity(LanternEntity entity) {
    final LanternEntity entity1 = this.entitiesByUniqueId.putIfAbsent(entity.getUniqueId(), entity);
    if (entity1 != null) {
        return entity1;
    }
    final EntityProtocolType entityProtocolType = entity.getEntityProtocolType();
    if (entityProtocolType != null) {
        this.entityProtocolManager.add(entity, entityProtocolType);
    }
    entity.setPositionAndWorld(this, entity.getPosition());
    return null;
}
Also used : EntityProtocolType(org.lanternpowered.server.network.entity.EntityProtocolType) LanternEntity(org.lanternpowered.server.entity.LanternEntity) Nullable(javax.annotation.Nullable)

Example 8 with LanternEntity

use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.

the class LanternChunk method createEntity.

@SuppressWarnings("unchecked")
@Override
public Entity createEntity(EntityType type, Vector3d position) {
    checkNotNull(position, "position");
    final LanternEntityType entityType = (LanternEntityType) checkNotNull(type, "type");
    checkVolumeBounds(position.getFloorX(), position.getFloorY(), position.getFloorZ());
    // noinspection unchecked
    final LanternEntity entity = (LanternEntity) entityType.getEntityConstructor().apply(UUID.randomUUID());
    entity.setPositionAndWorld(this.world, position);
    return entity;
}
Also used : LanternEntityType(org.lanternpowered.server.entity.LanternEntityType) LanternEntity(org.lanternpowered.server.entity.LanternEntity)

Example 9 with LanternEntity

use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.

the class AnvilChunkIOService method write.

@Override
public void write(LanternChunk chunk) throws IOException {
    final int x = chunk.getX();
    final int z = chunk.getZ();
    final RegionFile region = this.cache.getRegionFileByChunk(x, z);
    final int regionX = x & REGION_MASK;
    final int regionZ = z & REGION_MASK;
    final DataContainer rootView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
    final DataView levelDataView = rootView.createView(LEVEL);
    // Core properties
    levelDataView.set(VERSION, (byte) 1);
    levelDataView.set(X, chunk.getX());
    levelDataView.set(Z, chunk.getZ());
    levelDataView.set(TERRAIN_POPULATED, (byte) (chunk.isPopulated() ? 1 : 0));
    levelDataView.set(LIGHT_POPULATED, (byte) (chunk.isLightPopulated() ? 1 : 0));
    levelDataView.set(LAST_UPDATE, 0L);
    levelDataView.set(INHABITED_TIME, chunk.getLongInhabitedTime());
    // Chunk sections
    final ChunkSectionSnapshot[] sections = chunk.getSectionSnapshots(true);
    final List<DataView> sectionDataViews = new ArrayList<>();
    final List<DataView> tileEntityDataViews = new ArrayList<>();
    for (byte i = 0; i < sections.length; ++i) {
        final ChunkSectionSnapshot section = sections[i];
        if (section == null) {
            continue;
        }
        final DataContainer sectionDataView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
        sectionDataView.set(Y, i);
        final byte[] rawTypes = new byte[section.types.length];
        final short[] types = section.types;
        NibbleArray extTypes = null;
        final NibbleArray data = new NibbleArray(rawTypes.length);
        for (int j = 0; j < rawTypes.length; j++) {
            rawTypes[j] = (byte) ((types[j] >> 4) & 0xff);
            byte extType = (byte) (types[j] >> 12);
            if (extType != 0) {
                if (extTypes == null) {
                    extTypes = new NibbleArray(rawTypes.length);
                }
                extTypes.set(j, extType);
            }
            data.set(j, (byte) (types[j] & 0xf));
        }
        sectionDataView.set(BLOCKS, rawTypes);
        if (extTypes != null) {
            sectionDataView.set(BLOCKS_EXTRA, extTypes.getPackedArray());
        }
        sectionDataView.set(DATA, data.getPackedArray());
        sectionDataView.set(BLOCK_LIGHT, section.lightFromBlock);
        final byte[] lightFromSky = section.lightFromSky;
        if (lightFromSky != null) {
            sectionDataView.set(SKY_LIGHT, lightFromSky);
        }
        sectionDataViews.add(sectionDataView);
        // noinspection unchecked
        final ObjectSerializer<LanternTileEntity> tileEntitySerializer = ObjectSerializerRegistry.get().get(LanternTileEntity.class).get();
        // Serialize the tile entities
        for (Short2ObjectMap.Entry<LanternTileEntity> tileEntityEntry : section.tileEntities.short2ObjectEntrySet()) {
            if (!tileEntityEntry.getValue().isValid()) {
                continue;
            }
            final DataView dataView = tileEntitySerializer.serialize(tileEntityEntry.getValue());
            final short pos = tileEntityEntry.getShortKey();
            dataView.set(TILE_ENTITY_X, x * 16 + (pos & 0xf));
            dataView.set(TILE_ENTITY_Y, (i << 4) | (pos >> 8));
            dataView.set(TILE_ENTITY_Z, z * 16 + ((pos >> 4) & 0xf));
            tileEntityDataViews.add(dataView);
        }
    }
    levelDataView.set(TILE_ENTITIES, tileEntityDataViews);
    levelDataView.set(SECTIONS, sectionDataViews);
    levelDataView.set(HEIGHT_MAP, chunk.getHeightMap());
    // noinspection unchecked
    final Short2ObjectMap<LanternChunk.TrackerData>[] trackerData = chunk.getTrackerData().getRawObjects();
    final List<DataView> trackerDataViews = new ArrayList<>();
    for (int i = 0; i < trackerData.length; i++) {
        final Short2ObjectMap<LanternChunk.TrackerData> trackerDataSection = trackerData[i];
        for (Short2ObjectMap.Entry<LanternChunk.TrackerData> entry : trackerDataSection.short2ObjectEntrySet()) {
            // index = y << 8 | z << 4 | x
            int index = entry.getShortKey() & 0xffff;
            // Convert the index to the column based system
            // index = z << 12 | y << 4 | x
            index = ((index >> 4) & 0xf) << 12 | i << 8 | (index >> 4) & 0xf0 | index & 0xf;
            final DataView trackerDataView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
            trackerDataView.set(TRACKER_BLOCK_POS, (short) index);
            trackerDataView.set(TRACKER_ENTRY_NOTIFIER, entry.getValue().getNotifierId());
            trackerDataView.set(TRACKER_ENTRY_CREATOR, entry.getValue().getCreatorId());
            trackerDataViews.add(trackerDataView);
        }
    }
    if (!trackerDataViews.isEmpty()) {
        levelDataView.createView(DataQueries.SPONGE_DATA).set(TRACKER_DATA_TABLE, trackerDataViews);
    }
    final short[] biomes = chunk.getBiomes();
    final byte[] biomes0 = new byte[biomes.length];
    byte[] biomes1 = null;
    for (int i = 0; i < biomes.length; i++) {
        biomes0[i] = (byte) (biomes[i] & 0xff);
        byte value = (byte) ((biomes[i] >> 4) & 0xff);
        if (value != 0) {
            if (biomes1 == null) {
                biomes1 = new byte[biomes0.length];
            }
            biomes1[i] = value;
        }
    }
    levelDataView.set(BIOMES, biomes0);
    if (biomes1 != null) {
        levelDataView.set(BIOMES_EXTRA, biomes1);
    }
    // noinspection unchecked
    final List<LanternEntity> entities = new ArrayList(chunk.getEntities(entity -> !(entity instanceof Player)));
    final ObjectSerializer<LanternEntity> entitySerializer = ObjectSerializerRegistry.get().get(LanternEntity.class).get();
    final List<DataView> entityViews = new ArrayList<>();
    for (LanternEntity entity : entities) {
        if (entity.getRemoveState() == LanternEntity.RemoveState.DESTROYED) {
            continue;
        }
        final DataView entityView = entitySerializer.serialize(entity);
        entityViews.add(entityView);
    }
    levelDataView.set(ENTITIES, entityViews);
    try (NbtDataContainerOutputStream nbt = new NbtDataContainerOutputStream(region.getChunkDataOutputStream(regionX, regionZ))) {
        nbt.write(rootView);
        nbt.flush();
    }
}
Also used : DataInputStream(java.io.DataInputStream) REGION_SIZE(org.lanternpowered.server.data.io.anvil.RegionFileCache.REGION_SIZE) ObjectSerializerRegistry(org.lanternpowered.server.data.io.store.ObjectSerializerRegistry) LanternEntity(org.lanternpowered.server.entity.LanternEntity) LanternTileEntity(org.lanternpowered.server.block.tile.LanternTileEntity) ChunkSection(org.lanternpowered.server.world.chunk.LanternChunk.ChunkSection) Inject(com.google.inject.Inject) LanternChunk(org.lanternpowered.server.world.chunk.LanternChunk) CompletableFuture(java.util.concurrent.CompletableFuture) DataQuery(org.spongepowered.api.data.DataQuery) DataQueries(org.lanternpowered.server.data.DataQueries) ArrayList(java.util.ArrayList) Matcher(java.util.regex.Matcher) DirectoryKeys(org.lanternpowered.server.game.DirectoryKeys) LanternScheduler(org.lanternpowered.server.scheduler.LanternScheduler) ChunkIOService(org.lanternpowered.server.data.io.ChunkIOService) NoSuchElementException(java.util.NoSuchElementException) LanternChunk.fixEntityYSection(org.lanternpowered.server.world.chunk.LanternChunk.fixEntityYSection) Path(java.nio.file.Path) Nullable(javax.annotation.Nullable) Location(org.spongepowered.api.world.Location) Short2ObjectOpenHashMap(it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap) Logger(org.slf4j.Logger) ObjectSerializer(org.lanternpowered.server.data.io.store.ObjectSerializer) Files(java.nio.file.Files) NibbleArray(org.lanternpowered.server.util.collect.array.NibbleArray) DataContainer(org.spongepowered.api.data.DataContainer) InvalidDataException(org.spongepowered.api.data.persistence.InvalidDataException) IOException(java.io.IOException) REGION_AREA(org.lanternpowered.server.data.io.anvil.RegionFileCache.REGION_AREA) ChunkSectionSnapshot(org.lanternpowered.server.world.chunk.LanternChunk.ChunkSectionSnapshot) ChunkDataStream(org.spongepowered.api.world.storage.ChunkDataStream) List(java.util.List) Short2ObjectMap(it.unimi.dsi.fastutil.shorts.Short2ObjectMap) REGION_MASK(org.lanternpowered.server.data.io.anvil.RegionFileCache.REGION_MASK) NbtDataContainerInputStream(org.lanternpowered.server.data.persistence.nbt.NbtDataContainerInputStream) DataView(org.spongepowered.api.data.DataView) Vector3i(com.flowpowered.math.vector.Vector3i) World(org.spongepowered.api.world.World) WorldProperties(org.spongepowered.api.world.storage.WorldProperties) Optional(java.util.Optional) Named(com.google.inject.name.Named) Player(org.spongepowered.api.entity.living.player.Player) NbtDataContainerOutputStream(org.lanternpowered.server.data.persistence.nbt.NbtDataContainerOutputStream) Singleton(com.google.inject.Singleton) ArrayList(java.util.ArrayList) LanternChunk(org.lanternpowered.server.world.chunk.LanternChunk) DataContainer(org.spongepowered.api.data.DataContainer) NibbleArray(org.lanternpowered.server.util.collect.array.NibbleArray) NbtDataContainerOutputStream(org.lanternpowered.server.data.persistence.nbt.NbtDataContainerOutputStream) ChunkSectionSnapshot(org.lanternpowered.server.world.chunk.LanternChunk.ChunkSectionSnapshot) LanternEntity(org.lanternpowered.server.entity.LanternEntity) Player(org.spongepowered.api.entity.living.player.Player) Short2ObjectMap(it.unimi.dsi.fastutil.shorts.Short2ObjectMap) DataView(org.spongepowered.api.data.DataView) LanternTileEntity(org.lanternpowered.server.block.tile.LanternTileEntity)

Example 10 with LanternEntity

use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.

the class EntitySerializer method deserialize.

@Override
public LanternEntity deserialize(DataView dataView) throws InvalidDataException {
    String id0 = dataView.getString(ID).get();
    final String id;
    // Fast fail if the data isn't old
    if (dataView.getInt(DATA_VERSION).orElse(0) < 704) {
        id = fixEntityId(dataView, id0);
    } else {
        id = id0;
    }
    dataView.remove(ID);
    final LanternEntityType entityType = (LanternEntityType) Sponge.getRegistry().getType(EntityType.class, id).orElseThrow(() -> new InvalidDataException("Unknown entity id: " + id));
    // noinspection unchecked
    final ObjectStore<LanternEntity> store = (ObjectStore) ObjectStoreRegistry.get().get(entityType.getEntityClass()).get();
    final UUID uniqueId;
    if (store instanceof IdentifiableObjectStore) {
        uniqueId = ((IdentifiableObjectStore) store).deserializeUniqueId(dataView);
    } else {
        uniqueId = UUID.randomUUID();
    }
    // noinspection unchecked
    final LanternEntity entity = (LanternEntity) entityType.getEntityConstructor().apply(uniqueId);
    store.deserialize(entity, dataView);
    return entity;
}
Also used : ObjectStore(org.lanternpowered.server.data.io.store.ObjectStore) IdentifiableObjectStore(org.lanternpowered.server.data.io.store.IdentifiableObjectStore) IdentifiableObjectStore(org.lanternpowered.server.data.io.store.IdentifiableObjectStore) InvalidDataException(org.spongepowered.api.data.persistence.InvalidDataException) LanternEntityType(org.lanternpowered.server.entity.LanternEntityType) UUID(java.util.UUID) LanternEntity(org.lanternpowered.server.entity.LanternEntity)

Aggregations

LanternEntity (org.lanternpowered.server.entity.LanternEntity)12 LanternChunk (org.lanternpowered.server.world.chunk.LanternChunk)4 Vector3i (com.flowpowered.math.vector.Vector3i)3 LanternEntityType (org.lanternpowered.server.entity.LanternEntityType)3 InvalidDataException (org.spongepowered.api.data.persistence.InvalidDataException)3 Entity (org.spongepowered.api.entity.Entity)3 Vector3d (com.flowpowered.math.vector.Vector3d)2 Short2ObjectMap (it.unimi.dsi.fastutil.shorts.Short2ObjectMap)2 Short2ObjectOpenHashMap (it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap)2 DataInputStream (java.io.DataInputStream)2 ArrayList (java.util.ArrayList)2 Nullable (javax.annotation.Nullable)2 LanternTileEntity (org.lanternpowered.server.block.tile.LanternTileEntity)2 IdentifiableObjectStore (org.lanternpowered.server.data.io.store.IdentifiableObjectStore)2 ObjectStore (org.lanternpowered.server.data.io.store.ObjectStore)2 NbtDataContainerInputStream (org.lanternpowered.server.data.persistence.nbt.NbtDataContainerInputStream)2 DataView (org.spongepowered.api.data.DataView)2 Inject (com.google.inject.Inject)1 Singleton (com.google.inject.Singleton)1 Named (com.google.inject.name.Named)1