Search in sources :

Example 1 with DynIntHashMap

use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.

the class AbstractMapChunkCache method loadChunks.

// Load chunk snapshots
public int loadChunks(int max_to_load) {
    if (dw.isLoaded() == false)
        return 0;
    Object queue = BukkitVersionHelper.helper.getUnloadQueue(w);
    int cnt = 0;
    if (iterator == null)
        iterator = chunks.listIterator();
    DynmapCore.setIgnoreChunkLoads(true);
    // Load the required chunks.
    while ((cnt < max_to_load) && iterator.hasNext()) {
        long startTime = System.nanoTime();
        DynmapChunk chunk = iterator.next();
        boolean vis = true;
        if (visible_limits != null) {
            vis = false;
            for (VisibilityLimit limit : visible_limits) {
                if (limit.doIntersectChunk(chunk.x, chunk.z)) {
                    vis = true;
                    break;
                }
            }
        }
        if (vis && (hidden_limits != null)) {
            for (VisibilityLimit limit : hidden_limits) {
                if (limit.doIntersectChunk(chunk.x, chunk.z)) {
                    vis = false;
                    break;
                }
            }
        }
        /* Check if cached chunk snapshot found */
        Snapshot ss = null;
        long inhabited_ticks = 0;
        DynIntHashMap tileData = null;
        SnapshotRec ssr = SnapshotCache.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
        if (ssr != null) {
            inhabited_ticks = ssr.inhabitedTicks;
            if (!vis) {
                if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
                    ss = STONE;
                else if (hidestyle == HiddenChunkStyle.FILL_OCEAN)
                    ss = OCEAN;
                else
                    ss = EMPTY;
            } else {
                ss = ssr.ss;
            }
            int idx = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
            snaparray[idx] = ss;
            snaptile[idx] = ssr.tileData;
            inhabitedTicks[idx] = inhabited_ticks;
            endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
            continue;
        }
        boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
        boolean didload = false;
        boolean isunloadpending = false;
        if (queue != null) {
            isunloadpending = BukkitVersionHelper.helper.isInUnloadQueue(queue, chunk.x, chunk.z);
        }
        if (isunloadpending) {
            /* Workaround: can't be pending if not loaded */
            wasLoaded = true;
        }
        try {
            didload = loadChunkNoGenerate(w, chunk.x, chunk.z);
        } catch (Throwable t) {
            /* Catch chunk error from Bukkit */
            Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName());
            if (!wasLoaded) {
                /* If wasn't loaded, we loaded it if it now is */
                didload = w.isChunkLoaded(chunk.x, chunk.z);
            }
        }
        /* If it did load, make cache of it */
        if (didload) {
            tileData = new DynIntHashMap();
            Chunk c = w.getChunkAt(chunk.x, chunk.z);
            /* Get the chunk */
            /* Get inhabited ticks count */
            inhabited_ticks = BukkitVersionHelper.helper.getInhabitedTicks(c);
            if (!vis) {
                if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
                    ss = STONE;
                else if (hidestyle == HiddenChunkStyle.FILL_OCEAN)
                    ss = OCEAN;
                else
                    ss = EMPTY;
            } else {
                ChunkSnapshot css;
                if (blockdata || highesty) {
                    css = c.getChunkSnapshot(highesty, biome, biomeraw);
                    ss = wrapChunkSnapshot(css);
                    /* Get tile entity data */
                    List<Object> vals = new ArrayList<Object>();
                    Map<?, ?> tileents = BukkitVersionHelper.helper.getTileEntitiesForChunk(c);
                    for (Object t : tileents.values()) {
                        int te_x = BukkitVersionHelper.helper.getTileEntityX(t);
                        int te_y = BukkitVersionHelper.helper.getTileEntityY(t);
                        int te_z = BukkitVersionHelper.helper.getTileEntityZ(t);
                        int cx = te_x & 0xF;
                        int cz = te_z & 0xF;
                        String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(ss.getBlockType(cx, te_y, cz));
                        if (te_fields != null) {
                            Object nbtcompound = BukkitVersionHelper.helper.readTileEntityNBT(t);
                            vals.clear();
                            for (String id : te_fields) {
                                Object val = BukkitVersionHelper.helper.getFieldValue(nbtcompound, id);
                                if (val != null) {
                                    vals.add(id);
                                    vals.add(val);
                                }
                            }
                            if (vals.size() > 0) {
                                Object[] vlist = vals.toArray(new Object[vals.size()]);
                                tileData.put(getIndexInChunk(cx, te_y, cz), vlist);
                            }
                        }
                    }
                } else {
                    css = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
                    ss = wrapChunkSnapshot(css);
                }
                if (ss != null) {
                    ssr = new SnapshotRec();
                    ssr.ss = ss;
                    ssr.inhabitedTicks = inhabited_ticks;
                    ssr.tileData = tileData;
                    SnapshotCache.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
                }
            }
            int chunkIndex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
            snaparray[chunkIndex] = ss;
            snaptile[chunkIndex] = tileData;
            inhabitedTicks[chunkIndex] = inhabited_ticks;
            /* If wasn't loaded before, we need to do unload */
            if (!wasLoaded) {
                /* Since we only remember ones we loaded, and we're synchronous, no player has
                     * moved, so it must be safe (also prevent chunk leak, which appears to happen
                     * because isChunkInUse defined "in use" as being within 256 blocks of a player,
                     * while the actual in-use chunk area for a player where the chunks are managed
                     * by the MC base server is 21x21 (or about a 160 block radius).
                     * Also, if we did generate it, need to save it */
                if (w.isChunkInUse(chunk.x, chunk.z) == false) {
                    if (BukkitVersionHelper.helper.isUnloadChunkBroken()) {
                        // Give up on broken unloadChunk API - lets see if this works
                        w.unloadChunkRequest(chunk.x, chunk.z);
                    } else {
                        BukkitVersionHelper.helper.unloadChunkNoSave(w, c, chunk.x, chunk.z);
                    }
                }
                endChunkLoad(startTime, ChunkStats.UNLOADED_CHUNKS);
            } else if (isunloadpending) {
                /* Else, if loaded and unload is pending */
                if (w.isChunkInUse(chunk.x, chunk.z) == false) {
                    w.unloadChunkRequest(chunk.x, chunk.z);
                /* Request new unload */
                }
                endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
            } else {
                endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
            }
        } else {
            endChunkLoad(startTime, ChunkStats.UNGENERATED_CHUNKS);
        }
        cnt++;
    }
    DynmapCore.setIgnoreChunkLoads(false);
    if (iterator.hasNext() == false) {
        /* If we're done */
        isempty = true;
        /* Fill missing chunks with empty dummy chunk */
        for (int i = 0; i < snaparray.length; i++) {
            if (snaparray[i] == null)
                snaparray[i] = EMPTY;
            else if (snaparray[i] != EMPTY)
                isempty = false;
        }
    }
    return cnt;
}
Also used : ChunkSnapshot(org.bukkit.ChunkSnapshot) ArrayList(java.util.ArrayList) Chunk(org.bukkit.Chunk) DynmapChunk(org.dynmap.DynmapChunk) DynIntHashMap(org.dynmap.utils.DynIntHashMap) DynmapChunk(org.dynmap.DynmapChunk) VisibilityLimit(org.dynmap.utils.VisibilityLimit) ChunkSnapshot(org.bukkit.ChunkSnapshot) SnapshotRec(org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec)

Example 2 with DynIntHashMap

use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.

the class ForgeMapChunkCache method prepChunkSnapshot.

// Prep snapshot and add to cache
private SnapshotRec prepChunkSnapshot(DynmapChunk chunk, CompoundNBT nbt) {
    ChunkSnapshot ss = new ChunkSnapshot(nbt, dw.worldheight);
    DynIntHashMap tileData = new DynIntHashMap();
    ListNBT tiles = nbt.getList("TileEntities", 10);
    if (tiles == null)
        tiles = new ListNBT();
    /* Get tile entity data */
    List<Object> vals = new ArrayList<Object>();
    for (int tid = 0; tid < tiles.size(); tid++) {
        CompoundNBT tc = tiles.getCompound(tid);
        int tx = tc.getInt("x");
        int ty = tc.getInt("y");
        int tz = tc.getInt("z");
        int cx = tx & 0xF;
        int cz = tz & 0xF;
        DynmapBlockState blk = ss.getBlockType(cx, ty, cz);
        String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blk);
        if (te_fields != null) {
            vals.clear();
            for (String id : te_fields) {
                INBT v = tc.get(id);
                /* Get field */
                if (v != null) {
                    Object val = getNBTValue(v);
                    if (val != null) {
                        vals.add(id);
                        vals.add(val);
                    }
                }
            }
            if (vals.size() > 0) {
                Object[] vlist = vals.toArray(new Object[vals.size()]);
                tileData.put(getIndexInChunk(cx, ty, cz), vlist);
            }
        }
    }
    SnapshotRec ssr = new SnapshotRec();
    ssr.ss = ss;
    ssr.tileData = tileData;
    DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
    return ssr;
}
Also used : CompoundNBT(net.minecraft.nbt.CompoundNBT) DynmapBlockState(org.dynmap.renderer.DynmapBlockState) ArrayList(java.util.ArrayList) DynIntHashMap(org.dynmap.utils.DynIntHashMap) SnapshotRec(org.dynmap.forge_1_15_2.SnapshotCache.SnapshotRec) ListNBT(net.minecraft.nbt.ListNBT) INBT(net.minecraft.nbt.INBT)

Example 3 with DynIntHashMap

use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.

the class ForgeMapChunkCache method getLoadedChunks.

/**
 * Read NBT data from loaded chunks - needs to be called from server/world thread to be safe
 * @returns number loaded
 */
public int getLoadedChunks() {
    int cnt = 0;
    if (!dw.isLoaded()) {
        isempty = true;
        unloadChunks();
        return 0;
    }
    ListIterator<DynmapChunk> iter = chunks.listIterator();
    while (iter.hasNext()) {
        long startTime = System.nanoTime();
        DynmapChunk chunk = iter.next();
        int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
        // Skip if already processed
        if (snaparray[chunkindex] != null)
            continue;
        boolean vis = isChunkVisible(chunk);
        /* Check if cached chunk snapshot found */
        if (tryChunkCache(chunk, vis)) {
            endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
            cnt++;
        } else // If chunk is loaded and not being unloaded, we're grabbing its NBT data
        if (cps.chunkExists(chunk.x, chunk.z)) {
            ChunkSnapshot ss;
            DynIntHashMap tileData;
            if (vis) {
                // If visible
                CompoundNBT nbt = ChunkSerializer.write((ServerWorld) w, cps.getChunk(chunk.x, chunk.z, false));
                if (nbt != null)
                    nbt = nbt.getCompound("Level");
                SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
                ss = ssr.ss;
                tileData = ssr.tileData;
            } else {
                if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) {
                    ss = STONE;
                } else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) {
                    ss = OCEAN;
                } else {
                    ss = EMPTY;
                }
                tileData = new DynIntHashMap();
            }
            snaparray[chunkindex] = ss;
            snaptile[chunkindex] = tileData;
            endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
            cnt++;
        }
    }
    return cnt;
}
Also used : DynmapChunk(org.dynmap.DynmapChunk) ServerWorld(net.minecraft.world.server.ServerWorld) SnapshotRec(org.dynmap.forge_1_15_2.SnapshotCache.SnapshotRec) CompoundNBT(net.minecraft.nbt.CompoundNBT) DynIntHashMap(org.dynmap.utils.DynIntHashMap)

Example 4 with DynIntHashMap

use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.

the class ForgeMapChunkCache method getLoadedChunks.

/**
 * Read NBT data from loaded chunks - needs to be called from server/world thread to be safe
 * @returns number loaded
 */
public int getLoadedChunks() {
    int cnt = 0;
    if (!dw.isLoaded()) {
        isempty = true;
        unloadChunks();
        return 0;
    }
    ListIterator<DynmapChunk> iter = chunks.listIterator();
    while (iter.hasNext()) {
        long startTime = System.nanoTime();
        DynmapChunk chunk = iter.next();
        int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
        // Skip if already processed
        if (snaparray[chunkindex] != null)
            continue;
        boolean vis = isChunkVisible(chunk);
        /* Check if cached chunk snapshot found */
        if (tryChunkCache(chunk, vis)) {
            endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
            cnt++;
        } else // If chunk is loaded and not being unloaded, we're grabbing its NBT data
        if (cps.chunkExists(chunk.x, chunk.z)) {
            ChunkSnapshot ss;
            DynIntHashMap tileData;
            if (vis) {
                // If visible
                CompoundNBT nbt = ChunkSerializer.write((ServerWorld) w, cps.getChunk(chunk.x, chunk.z, false));
                if (nbt != null)
                    nbt = nbt.getCompound("Level");
                SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
                ss = ssr.ss;
                tileData = ssr.tileData;
            } else {
                if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) {
                    ss = STONE;
                } else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) {
                    ss = OCEAN;
                } else {
                    ss = EMPTY;
                }
                tileData = new DynIntHashMap();
            }
            snaparray[chunkindex] = ss;
            snaptile[chunkindex] = tileData;
            endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
            cnt++;
        }
    }
    return cnt;
}
Also used : DynmapChunk(org.dynmap.DynmapChunk) ServerWorld(net.minecraft.world.server.ServerWorld) SnapshotRec(org.dynmap.forge_1_14_4.SnapshotCache.SnapshotRec) CompoundNBT(net.minecraft.nbt.CompoundNBT) DynIntHashMap(org.dynmap.utils.DynIntHashMap)

Example 5 with DynIntHashMap

use of org.dynmap.utils.DynIntHashMap in project dynmap by webbukkit.

the class ForgeMapChunkCache method getLoadedChunks.

/**
 * Read NBT data from loaded chunks - needs to be called from server/world thread to be safe
 * @returns number loaded
 */
public int getLoadedChunks() {
    int cnt = 0;
    if (!dw.isLoaded()) {
        isempty = true;
        unloadChunks();
        return 0;
    }
    ListIterator<DynmapChunk> iter = chunks.listIterator();
    while (iter.hasNext()) {
        long startTime = System.nanoTime();
        DynmapChunk chunk = iter.next();
        int chunkindex = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
        // Skip if already processed
        if (snaparray[chunkindex] != null)
            continue;
        boolean vis = isChunkVisible(chunk);
        /* Check if cached chunk snapshot found */
        if (tryChunkCache(chunk, vis)) {
            endChunkLoad(startTime, ChunkStats.CACHED_SNAPSHOT_HIT);
            cnt++;
        } else // If chunk is loaded and not being unloaded, we're grabbing its NBT data
        if (cps.chunkExists(chunk.x, chunk.z) && (!isChunkUnloadPending(chunk))) {
            ChunkSnapshot ss;
            DynIntHashMap tileData;
            if (vis) {
                // If visible
                NBTTagCompound nbt = new NBTTagCompound();
                try {
                    writechunktonbt.invoke(cps.chunkLoader, cps.loadChunk(chunk.x, chunk.z), w, nbt);
                } catch (IllegalAccessException e) {
                } catch (IllegalArgumentException e) {
                } catch (InvocationTargetException e) {
                }
                SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
                ss = ssr.ss;
                tileData = ssr.tileData;
            } else {
                if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) {
                    ss = STONE;
                } else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) {
                    ss = OCEAN;
                } else {
                    ss = EMPTY;
                }
                tileData = new DynIntHashMap();
            }
            snaparray[chunkindex] = ss;
            snaptile[chunkindex] = tileData;
            endChunkLoad(startTime, ChunkStats.LOADED_CHUNKS);
            cnt++;
        }
    }
    return cnt;
}
Also used : DynmapChunk(org.dynmap.DynmapChunk) SnapshotRec(org.dynmap.forge_1_12_2.SnapshotCache.SnapshotRec) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) DynIntHashMap(org.dynmap.utils.DynIntHashMap) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Aggregations

DynIntHashMap (org.dynmap.utils.DynIntHashMap)12 DynmapChunk (org.dynmap.DynmapChunk)7 CompoundNBT (net.minecraft.nbt.CompoundNBT)6 ArrayList (java.util.ArrayList)5 NBTTagCompound (net.minecraft.nbt.NBTTagCompound)3 SnapshotRec (org.dynmap.forge_1_12_2.SnapshotCache.SnapshotRec)3 SnapshotRec (org.dynmap.forge_1_14_4.SnapshotCache.SnapshotRec)3 SnapshotRec (org.dynmap.forge_1_15_2.SnapshotCache.SnapshotRec)3 DynmapBlockState (org.dynmap.renderer.DynmapBlockState)3 INBT (net.minecraft.nbt.INBT)2 ListNBT (net.minecraft.nbt.ListNBT)2 ServerWorld (net.minecraft.world.server.ServerWorld)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 NBTBase (net.minecraft.nbt.NBTBase)1 NBTTagList (net.minecraft.nbt.NBTTagList)1 NBTTagString (net.minecraft.nbt.NBTTagString)1 Chunk (org.bukkit.Chunk)1 ChunkSnapshot (org.bukkit.ChunkSnapshot)1 SnapshotRec (org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec)1 ChunkCacheRec (org.dynmap.common.chunk.GenericChunkCache.ChunkCacheRec)1