From 0201278bae940ecb98f2e9760681594018aac7e1 Mon Sep 17 00:00:00 2001 From: "Nicholas \"LB\" Braden" Date: Tue, 9 Sep 2014 00:16:26 -0500 Subject: [PATCH] Some progress on #20 --- .../location/LocChunkInDimension.java | 34 ++++ .../mcmodify/location/LocChunkInRegion.java | 31 +++ .../location/LocRegionInDimension.java | 31 +++ .../mcmodify/minecraft/FileRegion.java | 178 +++++------------- .../mcmodify/minecraft/MemoryRegion.java | 24 +-- .../lb_stuff/mcmodify/minecraft/Region.java | 91 ++++++--- .../lb_stuff/mcmodify/minecraft/World.java | 30 ++- .../mcmodify/test/minecraft/RegionTest.java | 6 +- 8 files changed, 228 insertions(+), 197 deletions(-) create mode 100644 src/main/java/com/lb_stuff/mcmodify/location/LocChunkInDimension.java create mode 100644 src/main/java/com/lb_stuff/mcmodify/location/LocChunkInRegion.java create mode 100644 src/main/java/com/lb_stuff/mcmodify/location/LocRegionInDimension.java diff --git a/src/main/java/com/lb_stuff/mcmodify/location/LocChunkInDimension.java b/src/main/java/com/lb_stuff/mcmodify/location/LocChunkInDimension.java new file mode 100644 index 0000000..46fac93 --- /dev/null +++ b/src/main/java/com/lb_stuff/mcmodify/location/LocChunkInDimension.java @@ -0,0 +1,34 @@ +package com.lb_stuff.mcmodify.location; + +import com.lb_stuff.mcmodify.minecraft.Region; + +/** + * Location of a Chunk in a Dimension. + */ +public class LocChunkInDimension +{ + public final int x; + public final int z; + public LocChunkInDimension(int cx, int cz) + { + x = cx; + z = cz; + } + + /** + * Returns the location of this chunk in a region. + * @return The location of this chunk in a region. + */ + public LocChunkInRegion getLocInRegion() + { + return new LocChunkInRegion(x - x/Region.CHUNK_X_SIZE*Region.CHUNK_X_SIZE, z - z/Region.CHUNK_Z_SIZE*Region.CHUNK_Z_SIZE); + } + /** + * Returns the region this chunk is in. + * @return The region this chunk is in. + */ + public LocRegionInDimension getRegionLoc() + { + return new LocRegionInDimension(x/Region.CHUNK_X_SIZE, z/Region.CHUNK_Z_SIZE); + } +} diff --git a/src/main/java/com/lb_stuff/mcmodify/location/LocChunkInRegion.java b/src/main/java/com/lb_stuff/mcmodify/location/LocChunkInRegion.java new file mode 100644 index 0000000..71352cd --- /dev/null +++ b/src/main/java/com/lb_stuff/mcmodify/location/LocChunkInRegion.java @@ -0,0 +1,31 @@ +package com.lb_stuff.mcmodify.location; + +import com.lb_stuff.mcmodify.minecraft.Region; + +/** + * Location of a Chunk in a Region. + */ +public class LocChunkInRegion +{ + public final int x; + public final int z; + public LocChunkInRegion(int cx, int cz) + { + if(cx < 0 || cx >= 32 || cz < 0 || cz >= 32) + { + throw new IllegalArgumentException("Invalid chunk location ("+cx+","+cz+") in region"); + } + x = cx; + z = cz; + } + + /** + * Returns the location of this chunk in a dimension. + * @param loc The region this chunk is in. + * @return The location of this chunk in a dimension. + */ + public LocChunkInDimension getLocInDimension(LocRegionInDimension loc) + { + return new LocChunkInDimension(loc.x*Region.CHUNK_X_SIZE + x, loc.z*Region.CHUNK_Z_SIZE + z); + } +} diff --git a/src/main/java/com/lb_stuff/mcmodify/location/LocRegionInDimension.java b/src/main/java/com/lb_stuff/mcmodify/location/LocRegionInDimension.java new file mode 100644 index 0000000..2834bbc --- /dev/null +++ b/src/main/java/com/lb_stuff/mcmodify/location/LocRegionInDimension.java @@ -0,0 +1,31 @@ +package com.lb_stuff.mcmodify.location; + +import com.lb_stuff.mcmodify.minecraft.Region; + +/** + * Location of a Region in a Dimension. + */ +public class LocRegionInDimension +{ + public final int x; + public final int z; + public LocRegionInDimension(int cx, int cz) + { + x = cx; + z = cz; + } + + /** + * Returns whether this region contains the given chunk. + * @param loc The chunk being tested. + * @return Whether this region contains the given chunk. + */ + public boolean containsChunk(LocChunkInDimension loc) + { + return + (x+0)*Region.CHUNK_X_SIZE <= loc.x && + (x+1)*Region.CHUNK_X_SIZE > loc.x && + (z+0)*Region.CHUNK_Z_SIZE <= loc.z && + (z+1)*Region.CHUNK_Z_SIZE > loc.z; + } +} diff --git a/src/main/java/com/lb_stuff/mcmodify/minecraft/FileRegion.java b/src/main/java/com/lb_stuff/mcmodify/minecraft/FileRegion.java index 9f8bbed..f43a82b 100644 --- a/src/main/java/com/lb_stuff/mcmodify/minecraft/FileRegion.java +++ b/src/main/java/com/lb_stuff/mcmodify/minecraft/FileRegion.java @@ -1,22 +1,16 @@ package com.lb_stuff.mcmodify.minecraft; -import com.lb_stuff.mcmodify.nbt.FormatException; +import com.lb_stuff.mcmodify.location.LocChunkInRegion; import com.lb_stuff.mcmodify.nbt.Tag; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.util.AbstractMap.SimpleEntry; -import java.util.Map.Entry; /** * Region file reader/writer @@ -24,9 +18,6 @@ */ public class FileRegion extends Region { - @Deprecated - private static final int NUMBER_OF_HEADER_SECTORS = 2; - /** * The Region File. */ @@ -45,81 +36,26 @@ public FileRegion(File mca) throws IOException rf.createNewFile(); try(FileOutputStream region = new FileOutputStream(rf)) { - region.write(new byte[8192]); - } - } - } - - /** - * Returns the offset and sector count for a chunk. - * @param region The RandomAccessFile to read the data from. - * @param index The chunk index, pre-calculated. - * @return The offset and sector count for a chunk. The offset is the key and the sector count is the value. - * @throws IOException if the input operation throws an exception. - */ - @Deprecated - private static Entry sectorOffset(RandomAccessFile region, int index) throws IOException - { - region.getChannel().position(4*index); - byte[] buf = new byte[4]; - region.readFully(buf); - int offset; - try(DataInputStream dis = new DataInputStream(new ByteArrayInputStream(new byte[]{0, buf[0], buf[1], buf[2]}))) - { - offset = dis.readInt()-NUMBER_OF_HEADER_SECTORS; - } - int sectors = buf[3]; - return new SimpleEntry<>(offset, sectors); - } - /** - * Writes the offset and sector count for a chunk. - * @param region The RandomAccessFile to write the data to. - * @param index The chunk index, pre-computed. - * @param offset The offset of the chunk. - * @param sectors The sector count of the chunk. - * @throws IOException if the output operation throws an exception. - */ - @Deprecated - private static void sectorOffset(RandomAccessFile region, int index, int offset, int sectors) throws IOException - { - try(ByteArrayOutputStream baos = new ByteArrayOutputStream(4)) - { - try(DataOutputStream dos = new DataOutputStream(baos)) - { - dos.writeInt(offset+NUMBER_OF_HEADER_SECTORS); + region.write(new byte[(int)CHUNK_SECTORS_START]); } - byte[] temp = baos.toByteArray(); - ByteBuffer buf = ByteBuffer.allocate(4); - buf.put(new byte[]{temp[1], temp[2], temp[3], (byte)sectors}); - region.getChannel().position(4*index); - region.write(buf.array()); } } - /** - * Reads a chunk from the region file. - * @param x The X chunk coordinate of the chunk. - * @param z The Z chunk coordinate of the chunk. - * @return The read chunk, or null if the chunk does not exist. - * @throws FormatException if the read chunk is invalid. - * @throws IOException if an input operation throws an exception. - */ @Override - public Chunk getChunk(int x, int z) throws FormatException, IOException + public Chunk getChunk(LocChunkInRegion pos) throws IOException { try(RandomAccessFile region = new RandomAccessFile(rf, "r")) { - Entry pair = sectorOffset(region, ((x%32) + (z%32)*32)); - int offset = pair.getKey(); - int sectors = pair.getValue(); - if(offset != -NUMBER_OF_HEADER_SECTORS && sectors != 0) + region.seek(LOCATIONS_SECTOR_START + chunkIndex(pos)*4); + LocationPair loc = new LocationPair(region); + if(loc.offset > 0 && loc.size > 0) { - region.seek(CHUNK_SECTORS_START+offset*SECTOR_BYTES); - int length = region.readInt()-1; - CompressionScheme compression = CompressionScheme.fromId(region.readByte()); - byte[] chunk = new byte[length]; + region.seek(loc.offset); + int length = region.readInt(); + CompressionScheme compressed = CompressionScheme.fromId(region.readByte()); + byte[] chunk = new byte[length-1]; region.readFully(chunk); - try(InputStream is = compression.getInputStream(new ByteArrayInputStream(chunk))) + try(InputStream is = compressed.getInputStream(new ByteArrayInputStream(chunk))) { return new Chunk((Tag.Compound)Tag.deserialize(is)); } @@ -127,97 +63,67 @@ public Chunk getChunk(int x, int z) throws FormatException, IOException } return null; } - /** - * Reads a chunk timestamp from the region file. - * @param x The X chunk coordinate of the chunk. - * @param z The Z chunk coordinate of the chunk. - * @return The read chunk timestamp. - * @throws IOException if an input operation throws an exception. - */ @Override - public int getTimestamp(int x, int z) throws IOException + public int getTimestamp(LocChunkInRegion pos) throws IOException { - try(FileInputStream region = new FileInputStream(rf)) + try(RandomAccessFile region = new RandomAccessFile(rf, "r")) { - region.getChannel().position(TIMESTAMPS_SECTOR_START+4*((x%32) + (z%32)*32)); - try(DataInputStream dis = new DataInputStream(region)) - { - return dis.readInt(); - } + region.seek(TIMESTAMPS_SECTOR_START + chunkIndex(pos)*4); + return region.readInt(); } } - /** - * Writes the given chunk to the region file in a lazy fashion. If the chunk exists in the region file and the given chunk can fit, it will be placed there and the sector size will be updated. Otherwise the chunk will be placed at the end of the region file without removing the old chunk, and the offset and sector size will be updated. - * @param x The X chunk coordinate of the chunk. - * @param z The Z chunk coordinate of the chunk. - * @param c The chunk to write. - * @throws IOException if an input or output operation throws an exception. - */ @Override - public void setChunk(int x, int z, Chunk c) throws IOException + public void setChunk(LocChunkInRegion pos, Chunk c) throws IOException { try(RandomAccessFile region = new RandomAccessFile(rf, "rw")) { - final int index = ((x%32) + (z%32)*32); + final int index = chunkIndex(pos); if(c == null) { - sectorOffset(region, index, -NUMBER_OF_HEADER_SECTORS, 0); + region.seek(LOCATIONS_SECTOR_START + index*4); + new LocationPair(0, 0).serialize(region); return; } - int chunksize, newsectors; - ByteBuffer chunkbytes; - try(ByteArrayOutputStream baos = new ByteArrayOutputStream(0)) + final byte[] chunkdata; + try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + baos.write(CompressionScheme.GZip.getId()); try(OutputStream os = CompressionScheme.GZip.getOutputStream(baos)) { c.ToNBT("").serialize(os); } - chunksize = baos.size(); - newsectors = (int)((chunksize+5)/SECTOR_BYTES+1); //TODO: remove cast - chunkbytes = ByteBuffer.allocate((int)(newsectors*SECTOR_BYTES)); //TODO: remove cast - chunkbytes.putInt(chunksize+1); - chunkbytes.put(CompressionScheme.GZip.getId()); - chunkbytes.put(baos.toByteArray()); + chunkdata = baos.toByteArray(); } + final long newsize = 4+chunkdata.length; - Entry pair = sectorOffset(region, index); - int offset = pair.getKey(); - int sectors = pair.getValue(); - - if((offset == -NUMBER_OF_HEADER_SECTORS && sectors == 0) || sectors < newsectors) + region.seek(LOCATIONS_SECTOR_START + index*4); + LocationPair loc = new LocationPair(region); + if((loc.offset == 0 && loc.size == 0) || loc.size < newsize) { - int newoffset = (int)((region.length()-CHUNK_SECTORS_START)/SECTOR_BYTES)+1; - newoffset = newoffset < 0 ? 0 : newoffset; - region.seek(CHUNK_SECTORS_START+SECTOR_BYTES*newoffset); - region.write(chunkbytes.array()); - sectorOffset(region, index, newoffset, newsectors); + final long offset = nextSector(region.length()); + region.seek(offset); + region.writeInt(chunkdata.length); + region.write(chunkdata); + loc = new LocationPair(offset, region.getFilePointer()-offset); + region.seek(LOCATIONS_SECTOR_START + index*4); + loc.serialize(region); } - else if(sectors >= newsectors) + else { - region.seek(CHUNK_SECTORS_START+SECTOR_BYTES*offset); - region.write(chunkbytes.array()); - sectorOffset(region, index, offset, newsectors); + region.seek(loc.offset); + region.writeInt(chunkdata.length); + region.write(chunkdata); } } } - /** - * Writes a chunk timestamp to the region file. - * @param x The X chunk coordinate of the chunk. - * @param z The Z chunk coordinate of the chunk. - * @param timestamp The new timestamp. - * @throws IOException if the output operation throws an exception. - */ @Override - public void setTimestamp(int x, int z, int timestamp) throws IOException + public void setTimestamp(LocChunkInRegion pos, int timestamp) throws IOException { - try(FileOutputStream region = new FileOutputStream(rf)) + try(RandomAccessFile region = new RandomAccessFile(rf, "rw")) { - region.getChannel().position(TIMESTAMPS_SECTOR_START+4*((x%32) + (z%32)*32)); - try(DataOutputStream dos = new DataOutputStream(region)) - { - dos.writeInt(timestamp); - } + region.seek(TIMESTAMPS_SECTOR_START + chunkIndex(pos)*4); + region.writeInt(timestamp); } } } \ No newline at end of file diff --git a/src/main/java/com/lb_stuff/mcmodify/minecraft/MemoryRegion.java b/src/main/java/com/lb_stuff/mcmodify/minecraft/MemoryRegion.java index 85b27ed..cae8c80 100644 --- a/src/main/java/com/lb_stuff/mcmodify/minecraft/MemoryRegion.java +++ b/src/main/java/com/lb_stuff/mcmodify/minecraft/MemoryRegion.java @@ -1,6 +1,6 @@ package com.lb_stuff.mcmodify.minecraft; -import com.lb_stuff.mcmodify.nbt.FormatException; +import com.lb_stuff.mcmodify.location.LocChunkInRegion; import com.lb_stuff.mcmodify.nbt.Tag; import org.apache.commons.io.IOUtils; @@ -35,7 +35,7 @@ public MemoryRegion(File mca, CompressionScheme preferred) throws IOException region.seek(TIMESTAMPS_SECTOR_START + i*4); timestamps[i] = region.readInt(); - if(loc.offset != 0 && loc.count != 0) + if(loc.offset > 0 && loc.size > 0) { region.seek(loc.offset); final int length = region.readInt(); @@ -73,7 +73,7 @@ public void saveToFile(File mca, CompressionScheme preferred) throws IOException for(int i = 0; i < MAX_CHUNKS; ++i) { region.seek(LOCATIONS_SECTOR_START + i*4); - region.writeInt(0); + new LocationPair(0, 0).serialize(region); region.seek(TIMESTAMPS_SECTOR_START + i*4); region.writeInt(timestamps[i]); @@ -98,7 +98,7 @@ public void saveToFile(File mca, CompressionScheme preferred) throws IOException region.write(chunk); final LocationPair loc = new LocationPair(offset, region.getFilePointer()-offset); - offset = LocationPair.nextSector(region.getFilePointer()); + offset = nextSector(region.getFilePointer()); region.seek(LOCATIONS_SECTOR_START + i*4); loc.serialize(region); } @@ -107,9 +107,9 @@ public void saveToFile(File mca, CompressionScheme preferred) throws IOException } @Override - public Chunk getChunk(int x, int z) throws IOException + public Chunk getChunk(LocChunkInRegion pos) throws IOException { - final int index = chunkIndex(x, z); + final int index = chunkIndex(pos); if(chunks[index] != null) { return new Chunk((Tag.Compound)Tag.deserialize(compression.getInputStream(new ByteArrayInputStream(chunks[index])))); @@ -117,15 +117,15 @@ public Chunk getChunk(int x, int z) throws IOException return null; } @Override - public int getTimestamp(int x, int z) + public int getTimestamp(LocChunkInRegion pos) { - return timestamps[chunkIndex(x, z)]; + return timestamps[chunkIndex(pos)]; } @Override - public void setChunk(int x, int z, Chunk c) throws IOException + public void setChunk(LocChunkInRegion pos, Chunk c) throws IOException { - final int index = chunkIndex(x, z); + final int index = chunkIndex(pos); try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) { try(OutputStream os = compression.getOutputStream(baos)) @@ -136,8 +136,8 @@ public void setChunk(int x, int z, Chunk c) throws IOException } } @Override - public void setTimestamp(int x, int z, int timestamp) + public void setTimestamp(LocChunkInRegion pos, int timestamp) { - timestamps[chunkIndex(x, z)] = timestamp; + timestamps[chunkIndex(pos)] = timestamp; } } diff --git a/src/main/java/com/lb_stuff/mcmodify/minecraft/Region.java b/src/main/java/com/lb_stuff/mcmodify/minecraft/Region.java index 20c2da5..6494834 100644 --- a/src/main/java/com/lb_stuff/mcmodify/minecraft/Region.java +++ b/src/main/java/com/lb_stuff/mcmodify/minecraft/Region.java @@ -1,6 +1,6 @@ package com.lb_stuff.mcmodify.minecraft; -import com.lb_stuff.mcmodify.nbt.FormatException; +import com.lb_stuff.mcmodify.location.LocChunkInRegion; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -9,12 +9,6 @@ import java.io.DataOutput; import java.io.DataOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; -import java.util.zip.InflaterInputStream; /** * @see Region file format on the Minecraft Wiki @@ -25,14 +19,22 @@ public abstract class Region * The number of bytes in a sector. */ protected static final long SECTOR_BYTES = 4096; + /** + * The number of chunks along the X axis. + */ + public static final int CHUNK_X_SIZE = 32; + /** + * The number of chunks along the Z axis. + */ + public static final int CHUNK_Z_SIZE = 32; /** * The maximum number of chunks in a single region. */ - public static final int MAX_CHUNKS = 32*32; + public static final int MAX_CHUNKS = CHUNK_X_SIZE*CHUNK_Z_SIZE; /** * The index of the first byte of the locations sector. */ - public static final long LOCATIONS_SECTOR_START = 0; + protected static final long LOCATIONS_SECTOR_START = 0; /** * The index of the first byte of the timestamps sector. */ @@ -44,8 +46,14 @@ public abstract class Region protected static final class LocationPair { + /** + * Offset in bytes. + */ public final long offset; - public final long count; + /** + * Length in bytes. + */ + public final long size; public LocationPair(long off, long c) { if(off > 0b11111111_11111111_11111111L*SECTOR_BYTES) @@ -57,7 +65,7 @@ public LocationPair(long off, long c) { throw new IllegalArgumentException("Unserializable count: "+c); } - count = c; + size = c; } public LocationPair(DataInput in) throws IOException { @@ -67,7 +75,7 @@ public LocationPair(DataInput in) throws IOException { offset = dis.readInt()*SECTOR_BYTES; } - count = temp[3]*SECTOR_BYTES; + size = temp[3]*SECTOR_BYTES; } public void serialize(DataOutput out) throws IOException { @@ -85,35 +93,58 @@ public void serialize(DataOutput out) throws IOException } } final byte[] temp = baos.toByteArray(); - if(count % SECTOR_BYTES == 0) + if(size % SECTOR_BYTES == 0) { - temp[3] = (byte)(count/SECTOR_BYTES); + temp[3] = (byte)(size/SECTOR_BYTES); } else { - temp[3] = (byte)((count/SECTOR_BYTES) + 1); + temp[3] = (byte)((size/SECTOR_BYTES) + 1); } out.write(temp); } } - - public static long nextSector(long offset) - { - if(offset % SECTOR_BYTES == 0) - { - return offset + SECTOR_BYTES; - } - return ((offset/SECTOR_BYTES) + 1)*SECTOR_BYTES; - } } - protected static int chunkIndex(int x, int z) + protected static int chunkIndex(LocChunkInRegion pos) { - return (x%32) + (z%32)*32; + return (pos.x%32) + (pos.z%32)*32; + } + protected static long nextSector(long offset) + { + if(offset % SECTOR_BYTES == 0) + { + return offset + SECTOR_BYTES; + } + return ((offset/SECTOR_BYTES) + 1)*SECTOR_BYTES; } - public abstract Chunk getChunk(int x, int z) throws IOException; - public abstract int getTimestamp(int x, int z) throws IOException; - public abstract void setChunk(int x, int z, Chunk c) throws IOException; - public abstract void setTimestamp(int x, int z, int timestamp) throws IOException; + /** + * Loads the requested chunk from the region. + * @param pos The chunk to load. + * @return The freshly-constructed requested chunk. + * @throws IOException If there is a problem with loading the chunk. + */ + public abstract Chunk getChunk(LocChunkInRegion pos) throws IOException; + /** + * Loads the timestamp of the requested chunk from the region. + * @param pos The chunk whose timestamp is desired. + * @return The timestamp of the requested chunk. + * @throws IOException If there is a problem with loading the timestamp. + */ + public abstract int getTimestamp(LocChunkInRegion pos) throws IOException; + /** + * Saves the given chunk to the region. + * @param pos The chunk coordinates. + * @param c The chunk to save. + * @throws IOException If there is a problem with saving the chunk. + */ + public abstract void setChunk(LocChunkInRegion pos, Chunk c) throws IOException; + /** + * Saves the timestamp of the indicated chunk to the region. + * @param pos The chunk whose timestamp should be altered. + * @param timestamp The new timestamp value. + * @throws IOException If there is a problem with saving the timestamp. + */ + public abstract void setTimestamp(LocChunkInRegion pos, int timestamp) throws IOException; } diff --git a/src/main/java/com/lb_stuff/mcmodify/minecraft/World.java b/src/main/java/com/lb_stuff/mcmodify/minecraft/World.java index dd72334..6c50f46 100644 --- a/src/main/java/com/lb_stuff/mcmodify/minecraft/World.java +++ b/src/main/java/com/lb_stuff/mcmodify/minecraft/World.java @@ -1,11 +1,12 @@ package com.lb_stuff.mcmodify.minecraft; +import com.lb_stuff.mcmodify.location.LocChunkInRegion; +import com.lb_stuff.mcmodify.location.LocRegionInDimension; import com.lb_stuff.mcmodify.nbt.FormatException; import java.io.File; import java.io.IOException; import java.io.PrintWriter; -import java.util.InputMismatchException; import java.util.NoSuchElementException; import java.util.Scanner; @@ -143,42 +144,39 @@ public void throwIfNotLocked() throws NotLockedException /** * Get a {@link FileRegion} instance tied to this world. - * @param d The dimension of the chunk/region. - * @param chunkX The X chunk coordinate of the chunk in the world. - * @param chunkZ The Z chunk coordinate of the chunk in the world. + * @param d The dimension of the region. + * @param pos The location of the region. * @return a {@link FileRegion} instance tied to this world. * @throws IOException if thrown by the FileRegion constructor. */ - public FileRegion getFileRegion(Dimension d, int chunkX, int chunkZ) throws IOException + public FileRegion getFileRegion(Dimension d, LocRegionInDimension pos) throws IOException { d.getFolder(this).mkdirs(); - int rx = (int)Math.floor(chunkX/32.0); - int rz = (int)Math.floor(chunkZ/32.0); - return new FileRegion(new File(d.getFolder(this), "r."+rx+"."+rz+".mca")) + return new FileRegion(new File(d.getFolder(this), "r."+pos.x+"."+pos.z+".mca")) { @Override - public Chunk getChunk(int x, int z) throws FormatException, IOException + public Chunk getChunk(LocChunkInRegion pos) throws FormatException, IOException { throwIfNotLocked(); - return super.getChunk(x, z); + return super.getChunk(pos); } @Override - public int getTimestamp(int x, int z) throws IOException + public int getTimestamp(LocChunkInRegion pos) throws IOException { throwIfNotLocked(); - return super.getTimestamp(x, z); + return super.getTimestamp(pos); } @Override - public void setChunk(int x, int z, Chunk c) throws IOException + public void setChunk(LocChunkInRegion pos, Chunk c) throws IOException { throwIfNotLocked(); - super.setChunk(x, z, c); + super.setChunk(pos, c); } @Override - public void setTimestamp(int x, int z, int timestamp) throws IOException + public void setTimestamp(LocChunkInRegion pos, int timestamp) throws IOException { throwIfNotLocked(); - super.setTimestamp(x, z, timestamp); + super.setTimestamp(pos, timestamp); } }; } diff --git a/src/test/java/com/lb_stuff/mcmodify/test/minecraft/RegionTest.java b/src/test/java/com/lb_stuff/mcmodify/test/minecraft/RegionTest.java index 4cf84af..dd5cd00 100644 --- a/src/test/java/com/lb_stuff/mcmodify/test/minecraft/RegionTest.java +++ b/src/test/java/com/lb_stuff/mcmodify/test/minecraft/RegionTest.java @@ -1,5 +1,6 @@ package com.lb_stuff.mcmodify.test.minecraft; +import com.lb_stuff.mcmodify.location.LocChunkInRegion; import com.lb_stuff.mcmodify.minecraft.Chunk; import com.lb_stuff.mcmodify.minecraft.FileRegion; import com.lb_stuff.mcmodify.minecraft.Mob; @@ -7,7 +8,6 @@ import org.junit.Test; -import java.io.File; public class RegionTest { @@ -20,12 +20,12 @@ public void modifyEveryChunk() throws Throwable { for(int z = 0; z < 31; ++z) { - Chunk chunk = region.getChunk(x, z); + Chunk chunk = region.getChunk(new LocChunkInRegion(x, z)); if(chunk != null) { chunk.Entities().add(new Mob.EnderDragon(x*16+8, 96, z*16+8)); } - newregion.setChunk(x, z, chunk); + newregion.setChunk(new LocChunkInRegion(x, z), chunk); } } }