mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-06-27 19:24:44 +02:00
Updating modified block storage to a region-style format.
This commit is contained in:
168
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManager.java
Executable file
168
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManager.java
Executable file
@ -0,0 +1,168 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public interface ChunkManager {
|
||||
public void closeAll();
|
||||
public ChunkStore readChunkStore(World world, int x, int z) throws IOException;
|
||||
public void writeChunkStore(World world, int x, int z, ChunkStore data);
|
||||
public void closeChunkStore(World world, int x, int z);
|
||||
|
||||
/**
|
||||
* Loads a specific chunklet
|
||||
*
|
||||
* @param cx Chunklet X coordinate that needs to be loaded
|
||||
* @param cy Chunklet Y coordinate that needs to be loaded
|
||||
* @param cz Chunklet Z coordinate that needs to be loaded
|
||||
* @param world World that the chunklet needs to be loaded in
|
||||
*/
|
||||
public void loadChunklet(int cx, int cy, int cz, World world);
|
||||
|
||||
/**
|
||||
* Unload a specific chunklet
|
||||
*
|
||||
* @param cx Chunklet X coordinate that needs to be unloaded
|
||||
* @param cy Chunklet Y coordinate that needs to be unloaded
|
||||
* @param cz Chunklet Z coordinate that needs to be unloaded
|
||||
* @param world World that the chunklet needs to be unloaded from
|
||||
*/
|
||||
public void unloadChunklet(int cx, int cy, int cz, World world);
|
||||
|
||||
/**
|
||||
* Load a given Chunk's Chunklet data
|
||||
*
|
||||
* @param cx Chunk X coordinate that is to be loaded
|
||||
* @param cz Chunk Z coordinate that is to be loaded
|
||||
* @param world World that the Chunk is in
|
||||
*/
|
||||
public void loadChunk(int cx, int cz, World world);
|
||||
|
||||
/**
|
||||
* Unload a given Chunk's Chunklet data
|
||||
*
|
||||
* @param cx Chunk X coordinate that is to be unloaded
|
||||
* @param cz Chunk Z coordinate that is to be unloaded
|
||||
* @param world World that the Chunk is in
|
||||
*/
|
||||
public void unloadChunk(int cx, int cz, World world);
|
||||
|
||||
/**
|
||||
* Saves a given Chunk's Chunklet data
|
||||
*
|
||||
* @param cx Chunk X coordinate that is to be saved
|
||||
* @param cz Chunk Z coordinate that is to be saved
|
||||
* @param world World that the Chunk is in
|
||||
*/
|
||||
public void saveChunk(int cx, int cz, World world);
|
||||
|
||||
public boolean isChunkLoaded(int cx, int cz, World world);
|
||||
/**
|
||||
* Informs the ChunkletManager a chunk is loaded
|
||||
*
|
||||
* @param cx Chunk X coordinate that is loaded
|
||||
* @param cz Chunk Z coordinate that is loaded
|
||||
* @param world World that the chunk was loaded in
|
||||
*/
|
||||
public void chunkLoaded(int cx, int cz, World world);
|
||||
|
||||
/**
|
||||
* Informs the ChunkletManager a chunk is unloaded
|
||||
*
|
||||
* @param cx Chunk X coordinate that is unloaded
|
||||
* @param cz Chunk Z coordinate that is unloaded
|
||||
* @param world World that the chunk was unloaded in
|
||||
*/
|
||||
public void chunkUnloaded(int cx, int cz, World world);
|
||||
|
||||
/**
|
||||
* Save all ChunkletStores related to the given world
|
||||
*
|
||||
* @param world World to save
|
||||
*/
|
||||
public void saveWorld(World world);
|
||||
|
||||
/**
|
||||
* Unload all ChunkletStores from memory related to the given world after saving them
|
||||
*
|
||||
* @param world World to unload
|
||||
*/
|
||||
public void unloadWorld(World world);
|
||||
|
||||
/**
|
||||
* Load all ChunkletStores from all loaded chunks from this world into memory
|
||||
*
|
||||
* @param world World to load
|
||||
*/
|
||||
public void loadWorld(World world);
|
||||
|
||||
/**
|
||||
* Save all ChunkletStores
|
||||
*/
|
||||
public void saveAll();
|
||||
|
||||
/**
|
||||
* Unload all ChunkletStores after saving them
|
||||
*/
|
||||
public void unloadAll();
|
||||
|
||||
/**
|
||||
* Check to see if a given location is set to true
|
||||
*
|
||||
* @param x X coordinate to check
|
||||
* @param y Y coordinate to check
|
||||
* @param z Z coordinate to check
|
||||
* @param world World to check in
|
||||
* @return true if the given location is set to true, false if otherwise
|
||||
*/
|
||||
public boolean isTrue(int x, int y, int z, World world);
|
||||
|
||||
/**
|
||||
* Check to see if a given block location is set to true
|
||||
*
|
||||
* @param block Block location to check
|
||||
* @return true if the given block location is set to true, false if otherwise
|
||||
*/
|
||||
public boolean isTrue(Block block);
|
||||
|
||||
/**
|
||||
* Set a given location to true, should create stores as necessary if the location does not exist
|
||||
*
|
||||
* @param x X coordinate to set
|
||||
* @param y Y coordinate to set
|
||||
* @param z Z coordinate to set
|
||||
* @param world World to set in
|
||||
*/
|
||||
public void setTrue(int x, int y, int z, World world);
|
||||
|
||||
/**
|
||||
* Set a given block location to true, should create stores as necessary if the location does not exist
|
||||
*
|
||||
* @param block Block location to set
|
||||
*/
|
||||
public void setTrue(Block block);
|
||||
|
||||
/**
|
||||
* Set a given location to false, should not create stores if one does not exist for the given location
|
||||
*
|
||||
* @param x X coordinate to set
|
||||
* @param y Y coordinate to set
|
||||
* @param z Z coordinate to set
|
||||
* @param world World to set in
|
||||
*/
|
||||
public void setFalse(int x, int y, int z, World world);
|
||||
|
||||
/**
|
||||
* Set a given block location to false, should not create stores if one does not exist for the given location
|
||||
*
|
||||
* @param block Block location to set
|
||||
*/
|
||||
public void setFalse(Block block);
|
||||
|
||||
/**
|
||||
* Delete any ChunkletStores that are empty
|
||||
*/
|
||||
public void cleanUp();
|
||||
}
|
15
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManagerFactory.java
Executable file
15
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManagerFactory.java
Executable file
@ -0,0 +1,15 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import com.gmail.nossr50.config.HiddenConfig;
|
||||
|
||||
public class ChunkManagerFactory {
|
||||
public static ChunkManager getChunkManager() {
|
||||
HiddenConfig hConfig = HiddenConfig.getInstance();
|
||||
|
||||
if(hConfig.getChunkletsEnabled()) {
|
||||
return new HashChunkManager();
|
||||
} else {
|
||||
return new NullChunkManager();
|
||||
}
|
||||
}
|
||||
}
|
72
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkStore.java
Executable file
72
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkStore.java
Executable file
@ -0,0 +1,72 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A ChunkStore should be responsible for a 16x16xWorldHeight area of data
|
||||
*/
|
||||
public interface ChunkStore extends Serializable {
|
||||
/**
|
||||
* Checks the chunk's save state
|
||||
*
|
||||
* @return true if the has been modified since it was last saved
|
||||
*/
|
||||
public boolean isDirty();
|
||||
/**
|
||||
* Checks the chunk's save state
|
||||
*
|
||||
* @param dirty the save state of the current chunk
|
||||
*/
|
||||
public void setDirty(boolean dirty);
|
||||
/**
|
||||
* Checks the chunk's x coordinate
|
||||
*
|
||||
* @return the chunk's x coordinate.
|
||||
*/
|
||||
public int getChunkX();
|
||||
/**
|
||||
* Checks the chunk's z coordinate
|
||||
*
|
||||
* @return the chunk's z coordinate.
|
||||
*/
|
||||
public int getChunkZ();
|
||||
/**
|
||||
* Checks the value at the given coordinates
|
||||
*
|
||||
* @param x x coordinate in current chunklet
|
||||
* @param y y coordinate in current chunklet
|
||||
* @param z z coordinate in current chunklet
|
||||
* @return true if the value is true at the given coordinates, false if otherwise
|
||||
*/
|
||||
public boolean isTrue(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Set the value to true at the given coordinates
|
||||
*
|
||||
* @param x x coordinate in current chunklet
|
||||
* @param y y coordinate in current chunklet
|
||||
* @param z z coordinate in current chunklet
|
||||
*/
|
||||
public void setTrue(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Set the value to false at the given coordinates
|
||||
*
|
||||
* @param x x coordinate in current chunklet
|
||||
* @param y y coordinate in current chunklet
|
||||
* @param z z coordinate in current chunklet
|
||||
*/
|
||||
public void setFalse(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* @return true if all values in the chunklet are false, false if otherwise
|
||||
*/
|
||||
public boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Set all values in this ChunkletStore to the values from another provided ChunkletStore
|
||||
*
|
||||
* @param otherStore Another ChunkletStore that this one should copy all data from
|
||||
*/
|
||||
public void copyFrom(ChunkletStore otherStore);
|
||||
}
|
10
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkStoreFactory.java
Executable file
10
src/main/java/com/gmail/nossr50/util/blockmeta/ChunkStoreFactory.java
Executable file
@ -0,0 +1,10 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
public class ChunkStoreFactory {
|
||||
protected static ChunkStore getChunkStore(World world, int x, int z) {
|
||||
// TODO: Add in loading from config what type of store we want.
|
||||
return new PrimitiveChunkStore(world, x, z);
|
||||
}
|
||||
}
|
374
src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkManager.java
Executable file
374
src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkManager.java
Executable file
@ -0,0 +1,374 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.Integer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.runnables.ChunkletUnloader;
|
||||
|
||||
import org.getspout.spoutapi.chunkstore.SimpleRegionFile;
|
||||
|
||||
public class HashChunkManager implements ChunkManager {
|
||||
private HashMap<UUID, HashMap<Long, SimpleRegionFile>> regionFiles = new HashMap<UUID, HashMap<Long, SimpleRegionFile>>();
|
||||
public HashMap<String, ChunkStore> store = new HashMap<String, ChunkStore>();
|
||||
|
||||
@Override
|
||||
public void closeAll() {
|
||||
for (UUID uid : regionFiles.keySet()) {
|
||||
HashMap<Long, SimpleRegionFile> worldRegions = regionFiles.get(uid);
|
||||
Iterator<SimpleRegionFile> itr = worldRegions.values().iterator();
|
||||
while (itr.hasNext()) {
|
||||
SimpleRegionFile rf = itr.next();
|
||||
if (rf != null) {
|
||||
rf.close();
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
regionFiles.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkStore readChunkStore(World world, int x, int z) throws IOException {
|
||||
SimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
InputStream in = rf.getInputStream(x, z);
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
ObjectInputStream objectStream = new ObjectInputStream(in);
|
||||
try {
|
||||
Object o = objectStream.readObject();
|
||||
if (o instanceof ChunkStore) {
|
||||
return (ChunkStore) o;
|
||||
} else {
|
||||
throw new RuntimeException("Wrong class type read for chunk meta data for " + x + ", " + z);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Assume the format changed
|
||||
return null;
|
||||
//throw new RuntimeException("Unable to process chunk meta data for " + x + ", " + z, e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Assume the format changed
|
||||
//System.out.println("[SpoutPlugin] is Unable to find serialized class for " + x + ", " + z + ", " + e.getMessage());
|
||||
return null;
|
||||
//throw new RuntimeException("Unable to find serialized class for " + x + ", " + z, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChunkStore(World world, int x, int z, ChunkStore data) {
|
||||
if (!data.isDirty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
ObjectOutputStream objectStream = new ObjectOutputStream(rf.getOutputStream(x, z));
|
||||
objectStream.writeObject(data);
|
||||
objectStream.flush();
|
||||
objectStream.close();
|
||||
data.setDirty(false);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unable to write chunk meta data for " + x + ", " + z, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChunkStore(World world, int x, int z) {
|
||||
SimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
if (rf != null) {
|
||||
rf.close();
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleRegionFile getSimpleRegionFile(World world, int x, int z) {
|
||||
File directory = new File(world.getWorldFolder(), "mcmmo_regions");
|
||||
|
||||
directory.mkdirs();
|
||||
|
||||
UUID key = world.getUID();
|
||||
|
||||
HashMap<Long, SimpleRegionFile> worldRegions = regionFiles.get(key);
|
||||
|
||||
if (worldRegions == null) {
|
||||
worldRegions = new HashMap<Long, SimpleRegionFile>();
|
||||
regionFiles.put(key, worldRegions);
|
||||
}
|
||||
|
||||
int rx = x >> 5;
|
||||
int rz = z >> 5;
|
||||
|
||||
long key2 = (((long) rx) << 32) | (((long) rz) & 0xFFFFFFFFL);
|
||||
|
||||
SimpleRegionFile regionFile = worldRegions.get(key2);
|
||||
|
||||
if (regionFile == null) {
|
||||
File file = new File(directory, "mcmmo_" + rx + "_" + rz + "_.mcm");
|
||||
regionFile = new SimpleRegionFile(file, rx, rz);
|
||||
worldRegions.put(key2, regionFile);
|
||||
}
|
||||
|
||||
return regionFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadChunklet(int cx, int cy, int cz, World world) {
|
||||
loadChunk(cx, cz, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadChunklet(int cx, int cy, int cz, World world) {
|
||||
unloadChunk(cx, cz, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadChunk(int cx, int cz, World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
if(store.containsKey(world.getName() + "," + cx + "," + cz))
|
||||
return;
|
||||
|
||||
ChunkStore in = null;
|
||||
|
||||
try {
|
||||
in = readChunkStore(world, cx, cz);
|
||||
}
|
||||
catch(Exception e) {}
|
||||
|
||||
if(in != null) {
|
||||
store.put(world.getName() + "," + cx + "," + cz, in);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadChunk(int cx, int cz, World world) {
|
||||
saveChunk(cx, cz, world);
|
||||
|
||||
if(store.containsKey(world.getName() + "," + cx + "," + cz)) {
|
||||
store.remove(world.getName() + "," + cx + "," + cz);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunk(int cx, int cz, World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
if(store.containsKey(world.getName() + "," + cx + "," + cz)) {
|
||||
ChunkStore out = store.get(world.getName() + "," + cx + "," + cz);
|
||||
|
||||
if(!out.isDirty())
|
||||
return;
|
||||
|
||||
writeChunkStore(world, cx, cz, out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int cx, int cz, World world) {
|
||||
if(world == null)
|
||||
return false;
|
||||
|
||||
return store.containsKey(world.getName() + "," + cx + "," + cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chunkLoaded(int cx, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void chunkUnloaded(int cx, int cz, World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
ChunkletUnloader.addToList(cx, cx, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveWorld(World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
closeAll();
|
||||
String worldName = world.getName();
|
||||
|
||||
for(String key : store.keySet()) {
|
||||
String[] info = key.split(",");
|
||||
if(worldName.equals(info[0])) {
|
||||
int cx = 0;
|
||||
int cz = 0;
|
||||
|
||||
try {
|
||||
cx = Integer.parseInt(info[1]);
|
||||
cz = Integer.parseInt(info[2]);
|
||||
}
|
||||
catch(Exception e) {
|
||||
return;
|
||||
}
|
||||
saveChunk(cx, cz, world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadWorld(World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
closeAll();
|
||||
String worldName = world.getName();
|
||||
|
||||
for(String key : store.keySet()) {
|
||||
String[] info = key.split(",");
|
||||
if(worldName.equals(info[0])) {
|
||||
int cx = 0;
|
||||
int cz = 0;
|
||||
|
||||
try {
|
||||
cx = Integer.parseInt(info[1]);
|
||||
cz = Integer.parseInt(info[2]);
|
||||
}
|
||||
catch(Exception e) {
|
||||
return;
|
||||
}
|
||||
unloadChunk(cx, cz, world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadWorld(World world) {}
|
||||
|
||||
@Override
|
||||
public void saveAll() {
|
||||
closeAll();
|
||||
|
||||
for(World world : Bukkit.getWorlds()) {
|
||||
saveWorld(world);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadAll() {
|
||||
closeAll();
|
||||
|
||||
for(World world : Bukkit.getWorlds()) {
|
||||
unloadWorld(world);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrue(int x, int y, int z, World world) {
|
||||
if(world == null)
|
||||
return false;
|
||||
|
||||
int cx = x / 16;
|
||||
int cz = z / 16;
|
||||
String key = world.getName() + "," + cx + "," + cz;
|
||||
|
||||
if (!store.containsKey(key)) {
|
||||
loadChunk(cx, cz, world);
|
||||
}
|
||||
|
||||
if (!store.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ChunkStore check = store.get(key);
|
||||
int ix = Math.abs(x) % 16;
|
||||
int iz = Math.abs(z) % 16;
|
||||
|
||||
return check.isTrue(ix, y, iz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrue(Block block) {
|
||||
if(block == null)
|
||||
return false;
|
||||
|
||||
return isTrue(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrue(int x, int y, int z, World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
int cx = x / 16;
|
||||
int cz = z / 16;
|
||||
|
||||
int ix = Math.abs(x) % 16;
|
||||
int iz = Math.abs(z) % 16;
|
||||
|
||||
String key = world.getName() + "," + cx + "," + cz;
|
||||
|
||||
if (!store.containsKey(key)) {
|
||||
loadChunk(cx, cz, world);
|
||||
}
|
||||
|
||||
ChunkStore cStore = store.get(key);
|
||||
|
||||
if (cStore == null) {
|
||||
cStore = ChunkStoreFactory.getChunkStore(world, cx, cz);
|
||||
store.put(key, cStore);
|
||||
}
|
||||
|
||||
cStore.setTrue(ix, y, iz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrue(Block block) {
|
||||
if(block == null)
|
||||
return;
|
||||
|
||||
setTrue(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFalse(int x, int y, int z, World world) {
|
||||
if(world == null)
|
||||
return;
|
||||
|
||||
int cx = x / 16;
|
||||
int cz = z / 16;
|
||||
|
||||
int ix = Math.abs(x) % 16;
|
||||
int iz = Math.abs(z) % 16;
|
||||
|
||||
String key = world.getName() + "," + cx + "," + cz;
|
||||
|
||||
if (!store.containsKey(key)) {
|
||||
loadChunk(cx, cz, world);
|
||||
}
|
||||
|
||||
ChunkStore cStore = store.get(key);
|
||||
|
||||
if (cStore == null) {
|
||||
return; //No need to make a store for something we will be setting to false
|
||||
}
|
||||
|
||||
cStore.setFalse(ix, y, iz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFalse(Block block) {
|
||||
if(block == null)
|
||||
return;
|
||||
|
||||
setFalse(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {}
|
||||
}
|
@ -19,7 +19,7 @@ import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.runnables.ChunkletUnloader;
|
||||
|
||||
public class HashChunkletManager implements ChunkletManager {
|
||||
private HashMap<String, ChunkletStore> store = new HashMap<String, ChunkletStore>();
|
||||
public HashMap<String, ChunkletStore> store = new HashMap<String, ChunkletStore>();
|
||||
|
||||
@Override
|
||||
public void loadChunklet(int cx, int cy, int cz, World world) {
|
||||
|
89
src/main/java/com/gmail/nossr50/util/blockmeta/NullChunkManager.java
Executable file
89
src/main/java/com/gmail/nossr50/util/blockmeta/NullChunkManager.java
Executable file
@ -0,0 +1,89 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class NullChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public void closeAll() {}
|
||||
|
||||
@Override
|
||||
public ChunkStore readChunkStore(World world, int x, int z) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChunkStore(World world, int x, int z, ChunkStore data) {}
|
||||
|
||||
@Override
|
||||
public void closeChunkStore(World world, int x, int z) {}
|
||||
|
||||
@Override
|
||||
public void loadChunklet(int cx, int cy, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void unloadChunklet(int cx, int cy, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void loadChunk(int cx, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void unloadChunk(int cx, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void saveChunk(int cx, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int cx, int cz, World world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chunkLoaded(int cx, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void chunkUnloaded(int cx, int cz, World world) {}
|
||||
|
||||
@Override
|
||||
public void saveWorld(World world) {}
|
||||
|
||||
@Override
|
||||
public void unloadWorld(World world) {}
|
||||
|
||||
@Override
|
||||
public void loadWorld(World world) {}
|
||||
|
||||
@Override
|
||||
public void saveAll() {}
|
||||
|
||||
@Override
|
||||
public void unloadAll() {}
|
||||
|
||||
@Override
|
||||
public boolean isTrue(int x, int y, int z, World world) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrue(Block block) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrue(int x, int y, int z, World world) {}
|
||||
|
||||
@Override
|
||||
public void setTrue(Block block) {}
|
||||
|
||||
@Override
|
||||
public void setFalse(int x, int y, int z, World world) {}
|
||||
|
||||
@Override
|
||||
public void setFalse(Block block) {}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {}
|
||||
}
|
144
src/main/java/com/gmail/nossr50/util/blockmeta/PrimitiveChunkStore.java
Executable file
144
src/main/java/com/gmail/nossr50/util/blockmeta/PrimitiveChunkStore.java
Executable file
@ -0,0 +1,144 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
|
||||
public class PrimitiveChunkStore implements ChunkStore {
|
||||
private static final long serialVersionUID = -1L;
|
||||
transient private boolean dirty = false;
|
||||
/** X, Z, Y */
|
||||
public boolean[][][] store;
|
||||
private static final int CURRENT_VERSION = 4;
|
||||
private static final int MAGIC_NUMBER = 0xEA5EDEBB;
|
||||
private int cx;
|
||||
private int cz;
|
||||
private UUID worldUid;
|
||||
transient private int worldHeight;
|
||||
transient private int xBitShifts;
|
||||
transient private int zBitShifts;
|
||||
transient private boolean conversionNeeded;
|
||||
|
||||
public PrimitiveChunkStore(World world, int cx, int cz) {
|
||||
this.cx = cx;
|
||||
this.cz = cz;
|
||||
this.worldUid = world.getUID();
|
||||
|
||||
this.worldHeight = world != null ? world.getMaxHeight() : 128;
|
||||
this.xBitShifts = 11;
|
||||
this.zBitShifts = 7;
|
||||
|
||||
this.store = new boolean[16][16][this.worldHeight - 1];
|
||||
|
||||
conversionNeeded = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
return dirty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty(boolean dirty) {
|
||||
this.dirty = dirty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkX() {
|
||||
return cx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkZ() {
|
||||
return cz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrue(int x, int y, int z) {
|
||||
return store[x][z][y];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrue(int x, int y, int z) {
|
||||
store[x][z][y] = true;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFalse(int x, int y, int z) {
|
||||
store[x][z][y] = false;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
for(int y = 0; y < this.worldHeight; y++) {
|
||||
if(store[x][z][y]) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(ChunkletStore otherStore) {
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
for(int y = 0; y < this.worldHeight; y++) {
|
||||
store[x][z][y] = otherStore.isTrue(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.writeInt(MAGIC_NUMBER);
|
||||
out.writeInt(CURRENT_VERSION);
|
||||
|
||||
out.writeLong(worldUid.getLeastSignificantBits());
|
||||
out.writeLong(worldUid.getMostSignificantBits());
|
||||
out.writeInt(cx);
|
||||
out.writeInt(cz);
|
||||
out.writeObject(store);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
int fileVersionNumber; // Can be used to determine the format of the file
|
||||
|
||||
long lsb = in.readLong();
|
||||
if (((int) (lsb >> 32)) == MAGIC_NUMBER) {
|
||||
fileVersionNumber = (int) lsb;
|
||||
lsb = in.readLong();
|
||||
} else {
|
||||
fileVersionNumber = 0;
|
||||
}
|
||||
|
||||
long msb = in.readLong();
|
||||
worldUid = new UUID(msb, lsb);
|
||||
cx = in.readInt();
|
||||
cz = in.readInt();
|
||||
|
||||
// Constructor is not invoked, need to set these fields
|
||||
World world = mcMMO.p.getServer().getWorld(this.worldUid);
|
||||
|
||||
this.worldHeight = world.getMaxHeight();
|
||||
this.xBitShifts = 11;
|
||||
this.zBitShifts = 7;
|
||||
|
||||
store = (boolean[][][]) in.readObject();
|
||||
|
||||
if (fileVersionNumber < CURRENT_VERSION) {
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ public class PrimitiveChunkletStore implements ChunkletStore {
|
||||
private static final long serialVersionUID = -3453078050608607478L;
|
||||
|
||||
/** X, Z, Y */
|
||||
private boolean[][][] store = new boolean[16][16][64];
|
||||
public boolean[][][] store = new boolean[16][16][64];
|
||||
|
||||
@Override
|
||||
public boolean isTrue(int x, int y, int z) {
|
||||
|
@ -9,7 +9,7 @@ public class PrimitiveExChunkletStore implements ChunkletStore, Externalizable {
|
||||
private static final long serialVersionUID = 8603603827094383873L;
|
||||
|
||||
/** X, Z, Y */
|
||||
private boolean[][][] store = new boolean[16][16][64];
|
||||
public boolean[][][] store = new boolean[16][16][64];
|
||||
|
||||
@Override
|
||||
public boolean isTrue(int x, int y, int z) {
|
||||
|
Reference in New Issue
Block a user