mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-10-31 09:13:43 +01:00 
			
		
		
		
	Offloading chunk conversion. SHould alleviate lag.
This commit is contained in:
		| @@ -15,7 +15,7 @@ import com.gmail.nossr50.util.blockmeta.HashChunkletManager; | ||||
| import com.gmail.nossr50.util.blockmeta.chunkmeta.HashChunkManager; | ||||
|  | ||||
| public class BlockStoreConversionZDirectory implements Runnable { | ||||
|     private int taskID, cx, cz, x, y, z, y2, xPos, zPos, cxPos, czPos; | ||||
|     public int taskID, cx, cz, x, y, z, y2, xPos, zPos, cxPos, czPos; | ||||
|     private String cxs, czs, chunkletName, chunkName; | ||||
|     private org.bukkit.World world; | ||||
|     private BukkitScheduler scheduler; | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import java.io.ObjectInputStream; | ||||
| import java.io.ObjectOutputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.lang.Integer; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.UUID; | ||||
| @@ -17,6 +18,7 @@ import org.bukkit.block.Block; | ||||
|  | ||||
| import com.gmail.nossr50.mcMMO; | ||||
| import com.gmail.nossr50.runnables.ChunkletUnloader; | ||||
| import com.gmail.nossr50.runnables.blockstoreconversion.BlockStoreConversionZDirectory; | ||||
| import com.gmail.nossr50.util.blockmeta.ChunkletStore; | ||||
| import com.gmail.nossr50.util.blockmeta.PrimitiveChunkletStore; | ||||
| import com.gmail.nossr50.util.blockmeta.PrimitiveExChunkletStore; | ||||
| @@ -27,6 +29,7 @@ import org.getspout.spoutapi.chunkstore.mcMMOSimpleRegionFile; | ||||
| public class HashChunkManager implements ChunkManager { | ||||
|     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>(); | ||||
|  | ||||
|     @Override | ||||
|     public void closeAll() { | ||||
| @@ -377,88 +380,32 @@ public class HashChunkManager implements ChunkManager { | ||||
|     public void cleanUp() {} | ||||
|  | ||||
|     public void convertChunk(File dataDir, int cx, int cz, World world) { | ||||
|         HashChunkletManager manager = new HashChunkletManager(); | ||||
|         manager.loadChunk(cx, cz, world); | ||||
|  | ||||
|         for(int y = 0; y < (world.getMaxHeight() / 64); y++) { | ||||
|             String chunkletName = world.getName() + "," + cx + "," + cz + "," + y; | ||||
| 	    ChunkletStore tempChunklet = manager.store.get(chunkletName); | ||||
|             PrimitiveChunkletStore primitiveChunklet = null; | ||||
|             PrimitiveExChunkletStore primitiveExChunklet = null; | ||||
|             if(tempChunklet instanceof PrimitiveChunkletStore) | ||||
|                 primitiveChunklet = (PrimitiveChunkletStore) tempChunklet; | ||||
|             else if(tempChunklet instanceof PrimitiveExChunkletStore) | ||||
|                 primitiveExChunklet = (PrimitiveExChunkletStore) tempChunklet; | ||||
|             if(tempChunklet == null) { | ||||
|                 continue; | ||||
|             } else { | ||||
|                 String chunkName = world.getName() + "," + cx + "," + cz; | ||||
|                 PrimitiveChunkStore cChunk = (PrimitiveChunkStore) store.get(chunkName); | ||||
|  | ||||
|                 if(cChunk != null) { | ||||
|                     int xPos = cx * 16; | ||||
|                     int zPos = cz * 16; | ||||
|  | ||||
|                     for(int x = 0; x < 16; x++) { | ||||
|                         for(int z = 0; z < 16; z++) { | ||||
|                             int cxPos = xPos + x; | ||||
|                             int czPos = zPos + z; | ||||
|  | ||||
|                             for(int y2 = (64 * y); y2 < (64 * y + 64); y2++) { | ||||
|                                 if(!manager.isTrue(cxPos, y2, czPos, world)) | ||||
|                                     continue; | ||||
|  | ||||
|                                 setTrue(cxPos, y2, czPos, world); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 setTrue(cx * 16, 0, cz * 16, world); | ||||
| 		setFalse(cx * 16, 0, cz * 16, world); | ||||
|                 cChunk = (PrimitiveChunkStore) store.get(chunkName); | ||||
|  | ||||
|                 for(int x = 0; x < 16; x++) { | ||||
|                     for(int z = 0; z < 16; z++) { | ||||
|                         boolean[] oldArray; | ||||
|                         if(primitiveChunklet != null) | ||||
|                             oldArray = primitiveChunklet.store[x][z]; | ||||
|                         if(primitiveExChunklet != null) | ||||
|                             oldArray = primitiveExChunklet.store[x][z]; | ||||
|                         else | ||||
|                             return; | ||||
|                         boolean[] newArray = cChunk.store[x][z]; | ||||
|                         if(oldArray.length < 64) | ||||
|                             return; | ||||
|                         else if(newArray.length < ((y * 64) + 64)) | ||||
|                             return; | ||||
|                         System.arraycopy(oldArray, 0, newArray, (y * 64), 64); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         manager.unloadChunk(cx, cz, world); | ||||
|         unloadChunk(cx, cz, world); | ||||
|  | ||||
|         if(!dataDir.exists()) return; | ||||
|         File cxDir = new File(dataDir, "" + cx); | ||||
|         if(!cxDir.exists()) return; | ||||
|         File czDir = new File(cxDir, "" + cz); | ||||
|         if(!czDir.exists()) return; | ||||
|  | ||||
|         for(File yFile : czDir.listFiles()) { | ||||
|             if(!yFile.exists()) | ||||
|         boolean conversionSet = false; | ||||
|  | ||||
|         for(BlockStoreConversionZDirectory converter : this.converters) { | ||||
|             if(converter == null) | ||||
|                 continue; | ||||
|  | ||||
|             yFile.delete(); | ||||
|             if(converter.taskID >= 0) | ||||
|                 continue; | ||||
|  | ||||
|             if(conversionSet) | ||||
|                 converters.remove(converter); | ||||
|  | ||||
|             converter.start(world, cxDir, czDir); | ||||
|             conversionSet = true; | ||||
|         } | ||||
|  | ||||
|         if(czDir.listFiles().length <= 0) | ||||
|             czDir.delete(); | ||||
|         if(cxDir.listFiles().length <= 0) | ||||
|             cxDir.delete(); | ||||
|         if(dataDir.listFiles().length <= 0) | ||||
|             dataDir.delete(); | ||||
|         if(!conversionSet) { | ||||
|             BlockStoreConversionZDirectory converter = new BlockStoreConversionZDirectory(); | ||||
|             converter.start(world, cxDir, czDir); | ||||
|             converters.add(converter); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -102,7 +102,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public final RandomAccessFile getFile() { | ||||
| 	public synchronized final RandomAccessFile getFile() { | ||||
| 		lastAccessTime = System.currentTimeMillis(); | ||||
| 		if (file == null) { | ||||
| 			try { | ||||
| @@ -150,7 +150,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		return file; | ||||
| 	} | ||||
|  | ||||
| 	public boolean testCloseTimeout() { | ||||
| 	public synchronized boolean testCloseTimeout() { | ||||
| 		/*if (System.currentTimeMillis() - TIMEOUT_TIME > lastAccessTime) { | ||||
| 			close(); | ||||
| 			return true; | ||||
| @@ -158,12 +158,12 @@ public class mcMMOSimpleRegionFile { | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	public DataOutputStream getOutputStream(int x, int z) { | ||||
| 	public synchronized DataOutputStream getOutputStream(int x, int z) { | ||||
| 		int index = getChunkIndex(x, z); | ||||
| 		return new DataOutputStream(new DeflaterOutputStream(new mcMMOSimpleChunkBuffer(this, index))); | ||||
| 	} | ||||
|  | ||||
| 	public DataInputStream getInputStream(int x, int z) throws IOException { | ||||
| 	public synchronized DataInputStream getInputStream(int x, int z) throws IOException { | ||||
| 		int index = getChunkIndex(x, z); | ||||
| 		int actualLength = dataActualLength[index]; | ||||
| 		if (actualLength == 0) { | ||||
| @@ -176,7 +176,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		return new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data))); | ||||
| 	} | ||||
|  | ||||
| 	void write(int index, byte[] buffer, int size) throws IOException { | ||||
| 	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); | ||||
| @@ -188,7 +188,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		saveFAT(); | ||||
| 	} | ||||
|  | ||||
| 	public void close() { | ||||
| 	public synchronized void close() { | ||||
| 		try { | ||||
| 			if (file != null) { | ||||
| 				file.seek(4096 * 2); | ||||
| @@ -200,7 +200,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private int setInUse(int index, boolean used) { | ||||
| 	private synchronized int setInUse(int index, boolean used) { | ||||
| 		if (dataActualLength[index] == 0) { | ||||
| 			return dataStart[index]; | ||||
| 		} | ||||
| @@ -225,7 +225,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		return dataStart[index]; | ||||
| 	} | ||||
|  | ||||
| 	private void extendFile() throws IOException { | ||||
| 	private synchronized void extendFile() throws IOException { | ||||
| 		long extend = (-getFile().length()) & segmentMask; | ||||
|  | ||||
| 		getFile().seek(getFile().length()); | ||||
| @@ -235,7 +235,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private int findSpace(int oldStart, int size) { | ||||
| 	private synchronized int findSpace(int oldStart, int size) { | ||||
| 		int segments = sizeToSegments(size); | ||||
|  | ||||
| 		boolean oldFree = true; | ||||
| @@ -268,7 +268,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		return start; | ||||
| 	} | ||||
|  | ||||
| 	private int sizeToSegments(int size) { | ||||
| 	private synchronized int sizeToSegments(int size) { | ||||
| 		if (size <= 0) { | ||||
| 			return 1; | ||||
| 		} else { | ||||
| @@ -276,7 +276,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private Integer getChunkIndex(int x, int z) { | ||||
| 	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); | ||||
| 		} | ||||
| @@ -287,7 +287,7 @@ public class mcMMOSimpleRegionFile { | ||||
| 		return (x << 5) + z; | ||||
| 	} | ||||
|  | ||||
| 	private void saveFAT() throws IOException { | ||||
| 	private synchronized void saveFAT() throws IOException { | ||||
| 		getFile().seek(0); | ||||
| 		for (int i = 0; i < 1024; i++) { | ||||
| 			getFile().writeInt(dataStart[i]); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Glitchfinder
					Glitchfinder