mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-06-30 04:34:43 +02:00
Squashed commit of the following:
commit cb3e057dee1f2b29838ab654a526baac1baab7d6 Author: NuclearW <incongruency@gmail.com> Date: Fri Mar 1 00:43:57 2013 -0500 1.4.00 release commit 4f9628d2e4cde31c8946e9a911ee6f10e1fb6b35 Author: NuclearW <incongruency@gmail.com> Date: Fri Mar 1 00:07:30 2013 -0500 \r -> \n commit b2ca22e0477c747143b0f08a28a096967ee6ffd7 Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 23:53:56 2013 -0500 Commented-out code shouldn't be done like that. commit 92f131712cc671e3e616c14a22e22769ef6d6d0b Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 23:45:36 2013 -0500 More things we missed. commit 408b03766f6261a03a862a1ab7f5835772feda4a Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 23:20:13 2013 -0500 Format: util through spout and backup lib commit d6bd2c29bbb51bee3607247468cfe145d4f38c9e Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 22:50:08 2013 -0500 The things we missed the first time through... commit 393f0b889aa1b7011ee81ee7b15413d8824b8cfb Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 22:05:29 2013 -0500 Formatting: Skills commit c097a6e188a7b760dd1b4389ed81dca417146b16 Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 19:30:12 2013 -0500 Organize imports. commit 34c3e74be7eb5f983f21d969e30155c5d82c01c1 Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 19:09:45 2013 -0500 Fixed a missing fallthrough comment from ChatCommand commit b4a76c9f022a2fd98bdd8f083accfea03becfd71 Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 19:09:36 2013 -0500 Formatting: datatypes.* through events.* commit 3e57dd41d3265a7c8106c7eb026df926770a4d15 Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 17:56:15 2013 -0500 Fix issue with bad rebase commit e8c8e06b2971555b7334e49128257e3af6f36892 Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 17:35:32 2013 -0500 Formatting: DatabaseManager, LeaderboardManager, DatabaseUpdateType, and PlayerStat commit 13ecf1cc41f377a12991e357ac10abdcda24d6de Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 17:31:43 2013 -0500 Format: listeners.* through runnables.* commit 71686e3c0d96c2dcf25442b91703fadda1ea3bb0 Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 17:13:57 2013 -0500 Format PartyLockCommand commit d50abed10bf94e1a88df3dc5cc07c259aea920ea Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 16:54:08 2013 -0500 Format: base through config.* commit 7004823eeebbae5be7728bf9cafc3b04e57b64cf Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 15:21:40 2013 -0500 Example of using spaces to align like things commit 534190cfe2481e466fe459d65628550458cc2993 Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 15:12:19 2013 -0500 Capitalization commit 5b61d3ba4c8d81e6f358b0cf4f460abfe9798414 Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 15:07:43 2013 -0500 Updated readme, added standards.md commit 5ec0df70fb82c527420a2f437f27f31bd758f884 Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 14:42:16 2013 -0500 Markdown was here, Creole is a loser commit 70d557c59d086b6a5fb5e0e63c0c1d8eb4c8d19c Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 13:46:24 2013 -0500 Move MCStats shading to .metrics.mcstats commit eb9d67e66b1659d6abd2397ecf403343cfeffdda Author: GJ <gjmcferrin@gmail.com> Date: Thu Feb 28 13:37:37 2013 -0500 Move ALL the packages! commit 8ffa9e7b75417b6c7f158613d4b4ffb783dcf2d0 Author: NuclearW <incongruency@gmail.com> Date: Thu Feb 28 12:37:12 2013 -0500 /r/n -> /n
This commit is contained in:
@ -6,7 +6,7 @@ import org.bukkit.block.Block;
|
||||
public interface ChunkletManager {
|
||||
/**
|
||||
* 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
|
||||
|
@ -22,11 +22,17 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
public void loadChunklet(int cx, int cy, int cz, World world) {
|
||||
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||
File cxDir = new File(dataDir, "" + cx);
|
||||
if (!cxDir.exists()) return;
|
||||
if (!cxDir.exists()) {
|
||||
return;
|
||||
}
|
||||
File czDir = new File(cxDir, "" + cz);
|
||||
if (!czDir.exists()) return;
|
||||
if (!czDir.exists()) {
|
||||
return;
|
||||
}
|
||||
File yFile = new File(czDir, "" + cy);
|
||||
if (!yFile.exists()) return;
|
||||
if (!yFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ChunkletStore in = deserializeChunkletStore(yFile);
|
||||
if (in != null) {
|
||||
@ -39,9 +45,13 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||
if (store.containsKey(world.getName() + "," + cx + "," + cz + "," + cy)) {
|
||||
File cxDir = new File(dataDir, "" + cx);
|
||||
if (!cxDir.exists()) cxDir.mkdir();
|
||||
if (!cxDir.exists()) {
|
||||
cxDir.mkdir();
|
||||
}
|
||||
File czDir = new File(cxDir, "" + cz);
|
||||
if (!czDir.exists()) czDir.mkdir();
|
||||
if (!czDir.exists()) {
|
||||
czDir.mkdir();
|
||||
}
|
||||
File yFile = new File(czDir, "" + cy);
|
||||
|
||||
ChunkletStore out = store.get(world.getName() + "," + cx + "," + cz + "," + cy);
|
||||
@ -54,9 +64,13 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
public void loadChunk(int cx, int cz, World world) {
|
||||
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||
File cxDir = new File(dataDir, "" + cx);
|
||||
if (!cxDir.exists()) return;
|
||||
if (!cxDir.exists()) {
|
||||
return;
|
||||
}
|
||||
File czDir = new File(cxDir, "" + cz);
|
||||
if (!czDir.exists()) return;
|
||||
if (!czDir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int y = 0; y < 4; y++) {
|
||||
File yFile = new File(czDir, "" + y);
|
||||
@ -78,9 +92,13 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
for (int y = 0; y < 4; y++) {
|
||||
if (store.containsKey(world.getName() + "," + cx + "," + cz + "," + y)) {
|
||||
File cxDir = new File(dataDir, "" + cx);
|
||||
if (!cxDir.exists()) cxDir.mkdir();
|
||||
if (!cxDir.exists()) {
|
||||
cxDir.mkdir();
|
||||
}
|
||||
File czDir = new File(cxDir, "" + cz);
|
||||
if (!czDir.exists()) czDir.mkdir();
|
||||
if (!czDir.exists()) {
|
||||
czDir.mkdir();
|
||||
}
|
||||
File yFile = new File(czDir, "" + y);
|
||||
|
||||
ChunkletStore out = store.get(world.getName() + "," + cx + "," + cz + "," + y);
|
||||
@ -104,16 +122,21 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
public void saveWorld(World world) {
|
||||
String worldName = world.getName();
|
||||
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
|
||||
if (!dataDir.exists())
|
||||
if (!dataDir.exists()) {
|
||||
dataDir.mkdirs();
|
||||
}
|
||||
|
||||
for (String key : store.keySet()) {
|
||||
String[] info = key.split(",");
|
||||
if (worldName.equals(info[0])) {
|
||||
File cxDir = new File(dataDir, "" + info[1]);
|
||||
if (!cxDir.exists()) cxDir.mkdir();
|
||||
if (!cxDir.exists()) {
|
||||
cxDir.mkdir();
|
||||
}
|
||||
File czDir = new File(cxDir, "" + info[2]);
|
||||
if (!czDir.exists()) czDir.mkdir();
|
||||
if (!czDir.exists()) {
|
||||
czDir.mkdir();
|
||||
}
|
||||
|
||||
File yFile = new File(czDir, "" + info[3]);
|
||||
serializeChunkletStore(store.get(key), yFile);
|
||||
@ -139,7 +162,7 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
@Override
|
||||
public void loadWorld(World world) {
|
||||
//for (Chunk chunk : world.getLoadedChunks()) {
|
||||
// this.chunkLoaded(chunk.getX(), chunk.getZ(), world);
|
||||
// this.chunkLoaded(chunk.getX(), chunk.getZ(), world);
|
||||
//}
|
||||
}
|
||||
|
||||
@ -237,7 +260,7 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
ChunkletStore cStore = store.get(key);
|
||||
|
||||
if (cStore == null) {
|
||||
return; //No need to make a store for something we will be setting to false
|
||||
return; // No need to make a store for something we will be setting to false
|
||||
}
|
||||
|
||||
cStore.setFalse(ix, iy, iz);
|
||||
@ -256,16 +279,24 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
File dataDir = new File(Bukkit.getWorld(info[0]).getWorldFolder(), "mcmmo_data");
|
||||
|
||||
File cxDir = new File(dataDir, "" + info[1]);
|
||||
if (!cxDir.exists()) continue;
|
||||
if (!cxDir.exists()) {
|
||||
continue;
|
||||
}
|
||||
File czDir = new File(cxDir, "" + info[2]);
|
||||
if (!czDir.exists()) continue;
|
||||
if (!czDir.exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File yFile = new File(czDir, "" + info[3]);
|
||||
yFile.delete();
|
||||
|
||||
//Delete empty directories
|
||||
if (czDir.list().length == 0) czDir.delete();
|
||||
if (cxDir.list().length == 0) cxDir.delete();
|
||||
// Delete empty directories
|
||||
if (czDir.list().length == 0) {
|
||||
czDir.delete();
|
||||
}
|
||||
if (cxDir.list().length == 0) {
|
||||
cxDir.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -279,8 +310,9 @@ public class HashChunkletManager implements ChunkletManager {
|
||||
ObjectOutputStream objOut = null;
|
||||
|
||||
try {
|
||||
if (!location.exists())
|
||||
if (!location.exists()) {
|
||||
location.createNewFile();
|
||||
}
|
||||
fileOut = new FileOutputStream(location);
|
||||
objOut = new ObjectOutputStream(fileOut);
|
||||
objOut.writeObject(cStore);
|
||||
|
@ -26,7 +26,9 @@ public class PrimitiveChunkletStore implements ChunkletStore {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < 64; y++) {
|
||||
if (store[x][z][y]) return false;
|
||||
if (store[x][z][y]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ public class PrimitiveExChunkletStore implements ChunkletStore, Externalizable {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < 64; y++) {
|
||||
if (store[x][z][y]) return false;
|
||||
if (store[x][z][y]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,16 @@ import org.bukkit.entity.Entity;
|
||||
|
||||
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
|
||||
|
@ -12,4 +12,4 @@ public class ChunkManagerFactory {
|
||||
|
||||
return new NullChunkManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,24 +14,28 @@ public interface ChunkStore extends Serializable {
|
||||
* @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
|
||||
*
|
||||
@ -71,4 +75,4 @@ public interface ChunkStore extends Serializable {
|
||||
* @param otherStore Another ChunkletStore that this one should copy all data from
|
||||
*/
|
||||
public void copyFrom(ChunkletStore otherStore);
|
||||
}
|
||||
}
|
||||
|
@ -7,4 +7,4 @@ public class ChunkStoreFactory {
|
||||
// TODO: Add in loading from config what type of store we want.
|
||||
return new PrimitiveChunkStore(world, x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,12 +16,11 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.getspout.spoutapi.chunkstore.mcMMOSimpleRegionFile;
|
||||
|
||||
import com.gmail.nossr50.util.blockmeta.conversion.BlockStoreConversionZDirectory;
|
||||
|
||||
public class HashChunkManager implements ChunkManager {
|
||||
private HashMap<UUID, HashMap<Long, mcMMOSimpleRegionFile>> regionFiles = new HashMap<UUID, HashMap<Long, mcMMOSimpleRegionFile>>();
|
||||
private HashMap<UUID, HashMap<Long, McMMOSimpleRegionFile>> regionFiles = new HashMap<UUID, HashMap<Long, McMMOSimpleRegionFile>>();
|
||||
public HashMap<String, ChunkStore> store = new HashMap<String, ChunkStore>();
|
||||
public ArrayList<BlockStoreConversionZDirectory> converters = new ArrayList<BlockStoreConversionZDirectory>();
|
||||
private HashMap<UUID, Boolean> oldData = new HashMap<UUID, Boolean>();
|
||||
@ -29,9 +28,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
@Override
|
||||
public synchronized void closeAll() {
|
||||
for (UUID uid : regionFiles.keySet()) {
|
||||
HashMap<Long, mcMMOSimpleRegionFile> worldRegions = regionFiles.get(uid);
|
||||
for (Iterator<mcMMOSimpleRegionFile> worldRegionIterator = worldRegions.values().iterator(); worldRegionIterator.hasNext();) {
|
||||
mcMMOSimpleRegionFile rf = worldRegionIterator.next();
|
||||
HashMap<Long, McMMOSimpleRegionFile> worldRegions = regionFiles.get(uid);
|
||||
for (Iterator<McMMOSimpleRegionFile> worldRegionIterator = worldRegions.values().iterator(); worldRegionIterator.hasNext();) {
|
||||
McMMOSimpleRegionFile rf = worldRegionIterator.next();
|
||||
if (rf != null) {
|
||||
rf.close();
|
||||
worldRegionIterator.remove();
|
||||
@ -43,7 +42,7 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized ChunkStore readChunkStore(World world, int x, int z) throws IOException {
|
||||
mcMMOSimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
McMMOSimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
InputStream in = rf.getInputStream(x, z);
|
||||
if (in == null) {
|
||||
return null;
|
||||
@ -56,11 +55,13 @@ public class HashChunkManager implements ChunkManager {
|
||||
}
|
||||
|
||||
throw new RuntimeException("Wrong class type read for chunk meta data for " + x + ", " + z);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
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) {
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
// Assume the format changed
|
||||
//System.out.println("[SpoutPlugin] is Unable to find serialized class for " + x + ", " + z + ", " + e.getMessage());
|
||||
return null;
|
||||
@ -77,36 +78,37 @@ public class HashChunkManager implements ChunkManager {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mcMMOSimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
McMMOSimpleRegionFile 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) {
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("Unable to write chunk meta data for " + x + ", " + z, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void closeChunkStore(World world, int x, int z) {
|
||||
mcMMOSimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
McMMOSimpleRegionFile rf = getSimpleRegionFile(world, x, z);
|
||||
if (rf != null) {
|
||||
rf.close();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized mcMMOSimpleRegionFile getSimpleRegionFile(World world, int x, int z) {
|
||||
private synchronized McMMOSimpleRegionFile getSimpleRegionFile(World world, int x, int z) {
|
||||
File directory = new File(world.getWorldFolder(), "mcmmo_regions");
|
||||
|
||||
directory.mkdirs();
|
||||
|
||||
UUID key = world.getUID();
|
||||
|
||||
HashMap<Long, mcMMOSimpleRegionFile> worldRegions = regionFiles.get(key);
|
||||
HashMap<Long, McMMOSimpleRegionFile> worldRegions = regionFiles.get(key);
|
||||
|
||||
if (worldRegions == null) {
|
||||
worldRegions = new HashMap<Long, mcMMOSimpleRegionFile>();
|
||||
worldRegions = new HashMap<Long, McMMOSimpleRegionFile>();
|
||||
regionFiles.put(key, worldRegions);
|
||||
}
|
||||
|
||||
@ -115,11 +117,11 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
long key2 = (((long) rx) << 32) | ((rz) & 0xFFFFFFFFL);
|
||||
|
||||
mcMMOSimpleRegionFile regionFile = worldRegions.get(key2);
|
||||
McMMOSimpleRegionFile regionFile = worldRegions.get(key2);
|
||||
|
||||
if (regionFile == null) {
|
||||
File file = new File(directory, "mcmmo_" + rx + "_" + rz + "_.mcm");
|
||||
regionFile = new mcMMOSimpleRegionFile(file, rx, rz);
|
||||
regionFile = new McMMOSimpleRegionFile(file, rx, rz);
|
||||
worldRegions.put(key2, regionFile);
|
||||
}
|
||||
|
||||
@ -138,8 +140,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized void loadChunk(int cx, int cz, World world, Entity[] entities) {
|
||||
if (world == null || store.containsKey(world.getName() + "," + cx + "," + cz))
|
||||
if (world == null || store.containsKey(world.getName() + "," + cx + "," + cz)) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID key = world.getUID();
|
||||
|
||||
@ -147,8 +150,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
oldData.put(key, (new File(world.getWorldFolder(), "mcmmo_data")).exists());
|
||||
}
|
||||
else if (oldData.get(key)) {
|
||||
if (convertChunk(new File(world.getWorldFolder(), "mcmmo_data"), cx, cz, world, true))
|
||||
if (convertChunk(new File(world.getWorldFolder(), "mcmmo_data"), cx, cz, world, true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkStore chunkStore = null;
|
||||
@ -158,8 +162,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
if (chunkStore == null)
|
||||
if (chunkStore == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
store.put(world.getName() + "," + cx + "," + cz, chunkStore);
|
||||
}
|
||||
@ -171,22 +176,24 @@ public class HashChunkManager implements ChunkManager {
|
||||
if (store.containsKey(world.getName() + "," + cx + "," + cz)) {
|
||||
store.remove(world.getName() + "," + cx + "," + cz);
|
||||
|
||||
// closeChunkStore(world, cx, cz);
|
||||
//closeChunkStore(world, cx, cz);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void saveChunk(int cx, int cz, World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String key = world.getName() + "," + cx + "," + cz;
|
||||
|
||||
if (store.containsKey(key)) {
|
||||
ChunkStore out = store.get(world.getName() + "," + cx + "," + cz);
|
||||
|
||||
if (!out.isDirty())
|
||||
if (!out.isDirty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeChunkStore(world, cx, cz, out);
|
||||
}
|
||||
@ -194,8 +201,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized boolean isChunkLoaded(int cx, int cz, World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return store.containsKey(world.getName() + "," + cx + "," + cz);
|
||||
}
|
||||
@ -205,16 +213,18 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized void chunkUnloaded(int cx, int cz, World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unloadChunk(cx, cz, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void saveWorld(World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
closeAll();
|
||||
String worldName = world.getName();
|
||||
@ -230,7 +240,7 @@ public class HashChunkManager implements ChunkManager {
|
||||
cx = Integer.parseInt(info[1]);
|
||||
cz = Integer.parseInt(info[2]);
|
||||
}
|
||||
catch(Exception e) {
|
||||
catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
saveChunk(cx, cz, world);
|
||||
@ -240,8 +250,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized void unloadWorld(World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
closeAll();
|
||||
String worldName = world.getName();
|
||||
@ -257,7 +268,7 @@ public class HashChunkManager implements ChunkManager {
|
||||
cx = Integer.parseInt(info[1]);
|
||||
cz = Integer.parseInt(info[2]);
|
||||
}
|
||||
catch(Exception e) {
|
||||
catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
unloadChunk(cx, cz, world);
|
||||
@ -288,8 +299,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized boolean isTrue(int x, int y, int z, World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int cx = x / 16;
|
||||
int cz = z / 16;
|
||||
@ -312,8 +324,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized boolean isTrue(Block block) {
|
||||
if (block == null)
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTrue(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||
}
|
||||
@ -329,8 +342,9 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized void setTrue(int x, int y, int z, World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cx = x / 16;
|
||||
int cz = z / 16;
|
||||
@ -356,24 +370,27 @@ public class HashChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public synchronized void setTrue(Block block) {
|
||||
if (block == null)
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTrue(block.getX(), block.getY(), block.getZ(), block.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrue(BlockState blockState) {
|
||||
if (blockState == null)
|
||||
if (blockState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTrue(blockState.getX(), blockState.getY(), blockState.getZ(), blockState.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setFalse(int x, int y, int z, World world) {
|
||||
if (world == null)
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cx = x / 16;
|
||||
int cz = z / 16;
|
||||
@ -390,7 +407,7 @@ public class HashChunkManager implements ChunkManager {
|
||||
ChunkStore cStore = store.get(key);
|
||||
|
||||
if (cStore == null) {
|
||||
return; //No need to make a store for something we will be setting to false
|
||||
return; // No need to make a store for something we will be setting to false
|
||||
}
|
||||
|
||||
cStore.setFalse(ix, y, iz);
|
||||
@ -422,22 +439,30 @@ public class HashChunkManager implements ChunkManager {
|
||||
}
|
||||
|
||||
public synchronized boolean convertChunk(File dataDir, int cx, int cz, World world, boolean actually) {
|
||||
if (!actually)
|
||||
if (!actually || !dataDir.exists()) {
|
||||
return false;
|
||||
if (!dataDir.exists()) return false;
|
||||
}
|
||||
|
||||
File cxDir = new File(dataDir, "" + cx);
|
||||
if (!cxDir.exists()) return false;
|
||||
if (!cxDir.exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File czDir = new File(cxDir, "" + cz);
|
||||
if (!czDir.exists()) return false;
|
||||
if (!czDir.exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean conversionSet = false;
|
||||
|
||||
for (BlockStoreConversionZDirectory converter : this.converters) {
|
||||
if (converter == null)
|
||||
if (converter == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (converter.taskID >= 0)
|
||||
if (converter.taskID >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
converter.start(world, cxDir, czDir);
|
||||
conversionSet = true;
|
||||
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of SpoutPlugin.
|
||||
*
|
||||
* Copyright (c) 2011-2012, SpoutDev <http://www.spout.org/>
|
||||
* SpoutPlugin is licensed under the GNU Lesser General Public License.
|
||||
*
|
||||
* SpoutPlugin is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SpoutPlugin is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.gmail.nossr50.util.blockmeta.chunkmeta;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class McMMOSimpleChunkBuffer extends ByteArrayOutputStream {
|
||||
final McMMOSimpleRegionFile rf;
|
||||
final int index;
|
||||
|
||||
McMMOSimpleChunkBuffer(McMMOSimpleRegionFile rf, int index) {
|
||||
super(1024);
|
||||
this.rf = rf;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
rf.write(index, buf, count);
|
||||
}
|
||||
}
|
@ -0,0 +1,311 @@
|
||||
/*
|
||||
* This file is part of SpoutPlugin.
|
||||
*
|
||||
* Copyright (c) 2011-2012, SpoutDev <http://www.spout.org/>
|
||||
* SpoutPlugin is licensed under the GNU Lesser General Public License.
|
||||
*
|
||||
* SpoutPlugin is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SpoutPlugin is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.gmail.nossr50.util.blockmeta.chunkmeta;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class McMMOSimpleRegionFile {
|
||||
private RandomAccessFile file;
|
||||
private final int[] dataStart = new int[1024];
|
||||
private final int[] dataActualLength = new int[1024];
|
||||
private final int[] dataLength = new int[1024];
|
||||
private final ArrayList<Boolean> inuse = new ArrayList<Boolean>();
|
||||
private int segmentSize;
|
||||
private int segmentMask;
|
||||
private final int rx;
|
||||
private final int rz;
|
||||
private final int defaultSegmentSize;
|
||||
private final File parent;
|
||||
@SuppressWarnings("unused")
|
||||
private long lastAccessTime = System.currentTimeMillis();
|
||||
@SuppressWarnings("unused")
|
||||
private static long TIMEOUT_TIME = 300000; // 5 min
|
||||
|
||||
public McMMOSimpleRegionFile(File f, int rx, int rz) {
|
||||
this(f, rx, rz, 10);
|
||||
}
|
||||
|
||||
public McMMOSimpleRegionFile(File f, int rx, int rz, int defaultSegmentSize) {
|
||||
this.rx = rx;
|
||||
this.rz = rz;
|
||||
this.defaultSegmentSize = defaultSegmentSize;
|
||||
this.parent = f;
|
||||
|
||||
lastAccessTime = System.currentTimeMillis();
|
||||
if (file == null) {
|
||||
try {
|
||||
this.file = new RandomAccessFile(parent, "rw");
|
||||
|
||||
if (file.length() < 4096 * 3) {
|
||||
for (int i = 0; i < 1024 * 3; i++) {
|
||||
file.writeInt(0);
|
||||
}
|
||||
file.seek(4096 * 2);
|
||||
file.writeInt(defaultSegmentSize);
|
||||
}
|
||||
|
||||
file.seek(4096 * 2);
|
||||
|
||||
this.segmentSize = file.readInt();
|
||||
this.segmentMask = (1 << segmentSize) - 1;
|
||||
|
||||
int reservedSegments = this.sizeToSegments(4096 * 3);
|
||||
|
||||
for (int i = 0; i < reservedSegments; i++) {
|
||||
while (inuse.size() <= i) {
|
||||
inuse.add(false);
|
||||
}
|
||||
inuse.set(i, true);
|
||||
}
|
||||
|
||||
file.seek(0);
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
dataStart[i] = file.readInt();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
dataActualLength[i] = file.readInt();
|
||||
dataLength[i] = sizeToSegments(dataActualLength[i]);
|
||||
setInUse(i, true);
|
||||
}
|
||||
|
||||
extendFile();
|
||||
}
|
||||
catch (IOException fnfe) {
|
||||
throw new RuntimeException(fnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized final RandomAccessFile getFile() {
|
||||
lastAccessTime = System.currentTimeMillis();
|
||||
if (file == null) {
|
||||
try {
|
||||
this.file = new RandomAccessFile(parent, "rw");
|
||||
|
||||
if (file.length() < 4096 * 3) {
|
||||
for (int i = 0; i < 1024 * 3; i++) {
|
||||
file.writeInt(0);
|
||||
}
|
||||
file.seek(4096 * 2);
|
||||
file.writeInt(defaultSegmentSize);
|
||||
}
|
||||
|
||||
file.seek(4096 * 2);
|
||||
|
||||
this.segmentSize = file.readInt();
|
||||
this.segmentMask = (1 << segmentSize) - 1;
|
||||
|
||||
int reservedSegments = this.sizeToSegments(4096 * 3);
|
||||
|
||||
for (int i = 0; i < reservedSegments; i++) {
|
||||
while (inuse.size() <= i) {
|
||||
inuse.add(false);
|
||||
}
|
||||
inuse.set(i, true);
|
||||
}
|
||||
|
||||
file.seek(0);
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
dataStart[i] = file.readInt();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
dataActualLength[i] = file.readInt();
|
||||
dataLength[i] = sizeToSegments(dataActualLength[i]);
|
||||
setInUse(i, true);
|
||||
}
|
||||
|
||||
extendFile();
|
||||
}
|
||||
catch (IOException fnfe) {
|
||||
throw new RuntimeException(fnfe);
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public synchronized boolean testCloseTimeout() {
|
||||
/*
|
||||
if (System.currentTimeMillis() - TIMEOUT_TIME > lastAccessTime) {
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized DataOutputStream getOutputStream(int x, int z) {
|
||||
int index = getChunkIndex(x, z);
|
||||
return new DataOutputStream(new DeflaterOutputStream(new McMMOSimpleChunkBuffer(this, index)));
|
||||
}
|
||||
|
||||
public synchronized DataInputStream getInputStream(int x, int z) throws IOException {
|
||||
int index = getChunkIndex(x, z);
|
||||
int actualLength = dataActualLength[index];
|
||||
|
||||
if (actualLength == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] data = new byte[actualLength];
|
||||
|
||||
getFile().seek(dataStart[index] << segmentSize);
|
||||
getFile().readFully(data);
|
||||
return new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data)));
|
||||
}
|
||||
|
||||
synchronized void write(int index, byte[] buffer, int size) throws IOException {
|
||||
int oldStart = setInUse(index, false);
|
||||
int start = findSpace(oldStart, size);
|
||||
getFile().seek(start << segmentSize);
|
||||
getFile().write(buffer, 0, size);
|
||||
dataStart[index] = start;
|
||||
dataActualLength[index] = size;
|
||||
dataLength[index] = sizeToSegments(size);
|
||||
setInUse(index, true);
|
||||
saveFAT();
|
||||
}
|
||||
|
||||
public synchronized void close() {
|
||||
try {
|
||||
if (file != null) {
|
||||
file.seek(4096 * 2);
|
||||
file.close();
|
||||
}
|
||||
|
||||
file = null;
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new RuntimeException("Unable to close file", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized int setInUse(int index, boolean used) {
|
||||
if (dataActualLength[index] == 0) {
|
||||
return dataStart[index];
|
||||
}
|
||||
|
||||
int start = dataStart[index];
|
||||
int end = start + dataLength[index];
|
||||
|
||||
for (int i = start; i < end; i++) {
|
||||
while (i > inuse.size() - 1) {
|
||||
inuse.add(false);
|
||||
}
|
||||
|
||||
Boolean old = inuse.set(i, used);
|
||||
if (old != null && old == used) {
|
||||
if (old) {
|
||||
throw new IllegalStateException("Attempting to overwrite an in-use segment");
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Attempting to delete empty segment");
|
||||
}
|
||||
}
|
||||
|
||||
return dataStart[index];
|
||||
}
|
||||
|
||||
private synchronized void extendFile() throws IOException {
|
||||
long extend = (-getFile().length()) & segmentMask;
|
||||
|
||||
getFile().seek(getFile().length());
|
||||
|
||||
while ((extend--) > 0) {
|
||||
getFile().write(0);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized int findSpace(int oldStart, int size) {
|
||||
int segments = sizeToSegments(size);
|
||||
|
||||
boolean oldFree = true;
|
||||
for (int i = oldStart; i < inuse.size() && i < oldStart + segments; i++) {
|
||||
if (inuse.get(i)) {
|
||||
oldFree = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldFree) {
|
||||
return oldStart;
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
|
||||
while (end < inuse.size()) {
|
||||
if (inuse.get(end)) {
|
||||
end++;
|
||||
start = end;
|
||||
}
|
||||
else {
|
||||
end++;
|
||||
}
|
||||
|
||||
if (end - start >= segments) {
|
||||
return start;
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
private synchronized int sizeToSegments(int size) {
|
||||
if (size <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((size - 1) >> segmentSize) + 1;
|
||||
}
|
||||
|
||||
private synchronized Integer getChunkIndex(int x, int z) {
|
||||
if (rx != (x >> 5) || rz != (z >> 5)) {
|
||||
throw new RuntimeException(x + ", " + z + " not in region " + rx + ", " + rz);
|
||||
}
|
||||
|
||||
x = x & 0x1F;
|
||||
z = z & 0x1F;
|
||||
|
||||
return (x << 5) + z;
|
||||
}
|
||||
|
||||
private synchronized void saveFAT() throws IOException {
|
||||
getFile().seek(0);
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
getFile().writeInt(dataStart[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
getFile().writeInt(dataActualLength[i]);
|
||||
}
|
||||
}
|
||||
}
|
@ -99,4 +99,4 @@ public class NullChunkManager implements ChunkManager {
|
||||
|
||||
@Override
|
||||
public void cleanUp() {}
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,9 @@ public class PrimitiveChunkStore implements ChunkStore {
|
||||
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;
|
||||
if (store[x][z][y]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,7 +110,7 @@ public class PrimitiveChunkStore implements ChunkStore {
|
||||
int magic = in.readInt();
|
||||
// Can be used to determine the format of the file
|
||||
int fileVersionNumber = in.readInt();
|
||||
|
||||
|
||||
if (magic != MAGIC_NUMBER) {
|
||||
fileVersionNumber = 0;
|
||||
}
|
||||
@ -141,9 +143,9 @@ public class PrimitiveChunkStore implements ChunkStore {
|
||||
try {
|
||||
store[x][z][y] = temp[x][y][z];
|
||||
}
|
||||
catch(Exception e) {}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,9 @@ public class BlockStoreConversionMain implements Runnable {
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (this.taskID >= 0)
|
||||
if (this.taskID >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.taskID = this.scheduler.scheduleSyncDelayedTask(mcMMO.p, this, 1);
|
||||
return;
|
||||
|
@ -79,4 +79,4 @@ public class BlockStoreConversionXDirectory implements Runnable {
|
||||
this.scheduler = null;
|
||||
this.converters = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ import java.io.File;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.blockmeta.chunkmeta.HashChunkManager;
|
||||
import com.gmail.nossr50.util.blockmeta.chunkmeta.PrimitiveChunkStore;
|
||||
import com.gmail.nossr50.util.blockmeta.ChunkletStore;
|
||||
import com.gmail.nossr50.util.blockmeta.HashChunkletManager;
|
||||
import com.gmail.nossr50.util.blockmeta.PrimitiveChunkletStore;
|
||||
import com.gmail.nossr50.util.blockmeta.PrimitiveExChunkletStore;
|
||||
import com.gmail.nossr50.util.blockmeta.chunkmeta.HashChunkManager;
|
||||
import com.gmail.nossr50.util.blockmeta.chunkmeta.PrimitiveChunkStore;
|
||||
|
||||
public class BlockStoreConversionZDirectory implements Runnable {
|
||||
public int taskID, cx, cz, x, y, z, y2, xPos, zPos, cxPos, czPos;
|
||||
@ -74,7 +74,7 @@ public class BlockStoreConversionZDirectory implements Runnable {
|
||||
this.cx = Integer.parseInt(this.cxs);
|
||||
this.cz = Integer.parseInt(this.czs);
|
||||
}
|
||||
catch(Exception e) {
|
||||
catch (Exception e) {
|
||||
this.dataDir.delete();
|
||||
stop();
|
||||
return;
|
||||
@ -117,7 +117,7 @@ public class BlockStoreConversionZDirectory implements Runnable {
|
||||
|
||||
this.newManager.setTrue(this.cxPos, this.y2, this.czPos, this.world);
|
||||
}
|
||||
catch(Exception e) {}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,8 +171,9 @@ public class BlockStoreConversionZDirectory implements Runnable {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (this.taskID < 0)
|
||||
if (this.taskID < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.scheduler.cancelTask(taskID);
|
||||
this.taskID = -1;
|
||||
@ -189,4 +190,4 @@ public class BlockStoreConversionZDirectory implements Runnable {
|
||||
this.primitiveExChunklet = null;
|
||||
this.currentChunk = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user