buildcraft/common/buildcraft/robotics/map/MapWorld.java

162 lines
4 KiB
Java

package buildcraft.robotics.map;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import gnu.trove.map.hash.TLongLongHashMap;
import gnu.trove.set.hash.TLongHashSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.LongHashMap;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import buildcraft.core.lib.utils.NBTUtils;
public class MapWorld {
private final LongHashMap regionMap;
private final HashMap<Chunk, Integer> timeToUpdate = new HashMap<Chunk, Integer>();
private final TLongLongHashMap regionUpdateTime;
private final TLongHashSet updatedChunks;
private final File location;
public MapWorld(World world, File location) {
regionMap = new LongHashMap();
regionUpdateTime = new TLongLongHashMap();
updatedChunks = new TLongHashSet();
String saveFolder = world.provider.getSaveFolder();
if (saveFolder == null) {
saveFolder = "world";
}
this.location = new File(location, saveFolder);
try {
this.location.mkdirs();
} catch (Exception e) {
e.printStackTrace();
}
}
private MapRegion getRegion(int x, int z) {
long id = MapUtils.getIDFromCoords(x, z);
MapRegion region = (MapRegion) regionMap.getValueByKey(id);
if (region == null) {
region = new MapRegion(x, z);
// Check in the location first
File target = new File(location, "r" + x + "," + z + ".nbt");
if (target.exists()) {
try {
FileInputStream f = new FileInputStream(target);
byte[] data = new byte[(int) target.length()];
f.read(data);
f.close();
NBTTagCompound nbt = NBTUtils.load(data);
if (nbt != null) {
region.readFromNBT(nbt);
}
} catch (Exception e) {
e.printStackTrace();
}
}
regionMap.add(id, region);
}
return region;
}
private MapChunk getChunk(int x, int z) {
MapRegion region = getRegion(x >> 4, z >> 4);
return region.getChunk(x & 15, z & 15);
}
public boolean hasChunk(int x, int z) {
MapRegion region = getRegion(x >> 4, z >> 4);
return region.hasChunk(x & 15, z & 15);
}
public void save() {
long[] chunkList;
synchronized (updatedChunks) {
chunkList = updatedChunks.toArray();
updatedChunks.clear();
}
for (long id : chunkList) {
MapRegion region = (MapRegion) regionMap.getValueByKey(id);
if (region == null) {
continue;
}
NBTTagCompound output = new NBTTagCompound();
region.writeToNBT(output);
byte[] data = NBTUtils.save(output);
File file = new File(location, "r" + MapUtils.getXFromID(id) + "," + MapUtils.getZFromID(id) + ".nbt");
try {
FileOutputStream f = new FileOutputStream(file);
f.write(data);
f.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int getColor(int x, int z) {
MapChunk chunk = getChunk(x >> 4, z >> 4);
return chunk.getColor(x & 15, z & 15);
}
public void tick() {
if (timeToUpdate.size() > 0) {
synchronized (timeToUpdate) {
Set<Chunk> chunks = new HashSet<Chunk>();
chunks.addAll(timeToUpdate.keySet());
for (Chunk c : chunks) {
int v = timeToUpdate.get(c);
if (v > 1) {
timeToUpdate.put(c, v - 1);
} else {
try {
updateChunk(c);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
public void updateChunk(Chunk rchunk) {
long id = MapUtils.getIDFromCoords(rchunk.xPosition, rchunk.zPosition);
MapChunk chunk = getChunk(rchunk.xPosition, rchunk.zPosition);
chunk.update(rchunk);
synchronized (updatedChunks) {
updatedChunks.add(id);
}
synchronized (timeToUpdate) {
timeToUpdate.remove(rchunk);
}
regionUpdateTime.put(id, (new Date()).getTime());
}
public long getUpdateTime(int x, int z) {
return regionUpdateTime.get(MapUtils.getIDFromCoords(x, z));
}
public void updateChunkDelayed(Chunk chunk, byte time) {
synchronized (timeToUpdate) {
timeToUpdate.put(chunk, (int) time);
}
}
}