Search in sources :

Example 1 with SnapshotRec

use of org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec 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)

Aggregations

ArrayList (java.util.ArrayList)1 Chunk (org.bukkit.Chunk)1 ChunkSnapshot (org.bukkit.ChunkSnapshot)1 DynmapChunk (org.dynmap.DynmapChunk)1 SnapshotRec (org.dynmap.bukkit.helper.SnapshotCache.SnapshotRec)1 DynIntHashMap (org.dynmap.utils.DynIntHashMap)1 VisibilityLimit (org.dynmap.utils.VisibilityLimit)1