mirror of https://github.com/webbukkit/dynmap.git
253 lines
7.4 KiB
Java
253 lines
7.4 KiB
Java
package org.dynmap.bukkit.helper;
|
|
/**
|
|
* Bukkit specific implementation of DynmapWorld
|
|
*/
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.RandomAccessFile;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
import org.bukkit.Chunk;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.World;
|
|
import org.bukkit.permissions.Permission;
|
|
import org.bukkit.permissions.PermissionDefault;
|
|
import org.dynmap.DynmapChunk;
|
|
import org.dynmap.DynmapLocation;
|
|
import org.dynmap.DynmapWorld;
|
|
import org.dynmap.utils.MapChunkCache;
|
|
import org.dynmap.utils.Polygon;
|
|
import org.dynmap.utils.TileFlags;
|
|
|
|
public class BukkitWorld extends DynmapWorld {
|
|
private World world;
|
|
private World.Environment env;
|
|
private boolean skylight;
|
|
private DynmapLocation spawnloc = new DynmapLocation();
|
|
|
|
public BukkitWorld(World w) {
|
|
this(w.getName(), w.getMaxHeight(), w.getSeaLevel(), w.getEnvironment(),
|
|
BukkitVersionHelper.helper.getWorldMinY(w));
|
|
setWorldLoaded(w);
|
|
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
|
|
}
|
|
public BukkitWorld(String name, int height, int sealevel, World.Environment env, int miny) {
|
|
super(name, height, sealevel, miny);
|
|
world = null;
|
|
this.env = env;
|
|
skylight = (env == World.Environment.NORMAL);
|
|
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
|
|
// Generate non-default environment lighting table
|
|
switch (env) {
|
|
case NETHER:
|
|
{
|
|
float f = 0.1F;
|
|
for (int i = 0; i <= 15; ++i) {
|
|
float f1 = 1.0F - (float)i / 15.0F;
|
|
this.setBrightnessTableEntry(i, (1.0F - f1) / (f1 * 3.0F + 1.0F) * (1.0F - f) + f);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
/**
|
|
* Set world online
|
|
* @param w - loaded world
|
|
*/
|
|
public void setWorldLoaded(World w) {
|
|
world = w;
|
|
env = world.getEnvironment();
|
|
skylight = (env == World.Environment.NORMAL);
|
|
}
|
|
/**
|
|
* Set world unloaded
|
|
*/
|
|
@Override
|
|
public void setWorldUnloaded() {
|
|
getSpawnLocation(); /* Remember spawn location before unload */
|
|
world = null;
|
|
}
|
|
/* Test if world is nether */
|
|
@Override
|
|
public boolean isNether() {
|
|
return env == World.Environment.NETHER;
|
|
}
|
|
/* Get world spawn location */
|
|
@Override
|
|
public DynmapLocation getSpawnLocation() {
|
|
if(world != null) {
|
|
Location sloc = world.getSpawnLocation();
|
|
spawnloc.x = sloc.getBlockX();
|
|
spawnloc.y = sloc.getBlockY();
|
|
spawnloc.z = sloc.getBlockZ();
|
|
spawnloc.world = normalizeWorldName(sloc.getWorld().getName());
|
|
}
|
|
return spawnloc;
|
|
}
|
|
/* Get world time */
|
|
@Override
|
|
public long getTime() {
|
|
if(world != null) {
|
|
return world.getTime();
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
/* World is storming */
|
|
@Override
|
|
public boolean hasStorm() {
|
|
if(world != null) {
|
|
return world.hasStorm();
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
/* World is thundering */
|
|
@Override
|
|
public boolean isThundering() {
|
|
if(world != null) {
|
|
return world.isThundering();
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
/* World is loaded */
|
|
@Override
|
|
public boolean isLoaded() {
|
|
return (world != null);
|
|
}
|
|
/* Get light level of block */
|
|
@Override
|
|
public int getLightLevel(int x, int y, int z) {
|
|
if(world != null) {
|
|
if ((y >= minY) && (y < this.worldheight)) {
|
|
return world.getBlockAt(x, y, z).getLightLevel();
|
|
}
|
|
return 0;
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
/* Get highest Y coord of given location */
|
|
@Override
|
|
public int getHighestBlockYAt(int x, int z) {
|
|
if(world != null) {
|
|
return world.getHighestBlockYAt(x, z);
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
/* Test if sky light level is requestable */
|
|
@Override
|
|
public boolean canGetSkyLightLevel() {
|
|
return skylight && (world != null);
|
|
}
|
|
/* Return sky light level */
|
|
@Override
|
|
public int getSkyLightLevel(int x, int y, int z) {
|
|
if(world != null) {
|
|
if ((y >= minY) && (y < this.worldheight)) {
|
|
return world.getBlockAt(x, y, z).getLightFromSky();
|
|
}
|
|
else {
|
|
return 15;
|
|
}
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
/**
|
|
* Get world environment ID (lower case - normal, the_end, nether)
|
|
*/
|
|
@Override
|
|
public String getEnvironment() {
|
|
return env.name().toLowerCase();
|
|
}
|
|
/**
|
|
* Get map chunk cache for world
|
|
*/
|
|
@Override
|
|
public MapChunkCache getChunkCache(List<DynmapChunk> chunks) {
|
|
if(isLoaded()) {
|
|
return BukkitVersionHelper.helper.getChunkCache(this, chunks);
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public World getWorld() {
|
|
return world;
|
|
}
|
|
|
|
// Return false if unimplemented
|
|
@Override
|
|
public int getChunkMap(TileFlags map) {
|
|
map.clear();
|
|
if (world == null) return -1;
|
|
int cnt = 0;
|
|
// Mark loaded chunks
|
|
for(Chunk c : world.getLoadedChunks()) {
|
|
map.setFlag(c.getX(), c.getZ(), true);
|
|
cnt++;
|
|
}
|
|
File f = world.getWorldFolder();
|
|
File regiondir = new File(f, "region");
|
|
File[] lst = regiondir.listFiles();
|
|
if(lst != null) {
|
|
byte[] hdr = new byte[4096];
|
|
for(File rf : lst) {
|
|
if(!rf.getName().endsWith(".mca")) {
|
|
continue;
|
|
}
|
|
String[] parts = rf.getName().split("\\.");
|
|
if((!parts[0].equals("r")) && (parts.length != 4)) continue;
|
|
|
|
RandomAccessFile rfile = null;
|
|
int x = 0, z = 0;
|
|
try {
|
|
x = Integer.parseInt(parts[1]);
|
|
z = Integer.parseInt(parts[2]);
|
|
rfile = new RandomAccessFile(rf, "r");
|
|
rfile.read(hdr, 0, hdr.length);
|
|
} catch (IOException iox) {
|
|
Arrays.fill(hdr, (byte)0);
|
|
} catch (NumberFormatException nfx) {
|
|
Arrays.fill(hdr, (byte)0);
|
|
} finally {
|
|
if(rfile != null) {
|
|
try { rfile.close(); } catch (IOException iox) {}
|
|
}
|
|
}
|
|
for (int i = 0; i < 1024; i++) {
|
|
int v = hdr[4*i] | hdr[4*i + 1] | hdr[4*i + 2] | hdr[4*i + 3];
|
|
if (v == 0) continue;
|
|
int xx = (x << 5) | (i & 0x1F);
|
|
int zz = (z << 5) | ((i >> 5) & 0x1F);
|
|
if (!map.setFlag(xx, zz, true)) {
|
|
cnt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return cnt;
|
|
}
|
|
private Polygon lastBorder;
|
|
@Override
|
|
public Polygon getWorldBorder() {
|
|
if (world != null) {
|
|
lastBorder = BukkitVersionHelper.helper.getWorldBorder(world);
|
|
}
|
|
return lastBorder;
|
|
}
|
|
}
|