mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-07 00:06:10 +00:00
Total rotation support
This commit is contained in:
162
src/main/java/com/volmit/iris/gen/atomics/AtomicRegionData.java
Normal file
162
src/main/java/com/volmit/iris/gen/atomics/AtomicRegionData.java
Normal file
@@ -0,0 +1,162 @@
|
||||
package com.volmit.iris.object.atomics;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.volmit.iris.IrisSettings;
|
||||
import com.volmit.iris.util.ByteArrayTag;
|
||||
import com.volmit.iris.util.CompoundTag;
|
||||
import com.volmit.iris.util.CustomOutputStream;
|
||||
import com.volmit.iris.util.KMap;
|
||||
import com.volmit.iris.util.NBTInputStream;
|
||||
import com.volmit.iris.util.NBTOutputStream;
|
||||
import com.volmit.iris.util.Tag;
|
||||
|
||||
public class AtomicRegionData
|
||||
{
|
||||
private final World world;
|
||||
private Tag[] tag;
|
||||
|
||||
public AtomicRegionData(World world)
|
||||
{
|
||||
this.world = world;
|
||||
tag = new Tag[1024];
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return tag.length;
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws IOException
|
||||
{
|
||||
NBTInputStream nin = new NBTInputStream(in);
|
||||
KMap<String, Tag> tags = new KMap<>();
|
||||
tags.putAll(((CompoundTag) nin.readTag()).getValue());
|
||||
|
||||
for(String i : tags.keySet())
|
||||
{
|
||||
int x = Integer.valueOf(i.split("\\Q.\\E")[0]);
|
||||
int z = Integer.valueOf(i.split("\\Q.\\E")[1]);
|
||||
tag[(z << 5) | x] = tags.get(i);
|
||||
}
|
||||
|
||||
nin.close();
|
||||
}
|
||||
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
NBTOutputStream nos = new NBTOutputStream(out);
|
||||
|
||||
KMap<String, Tag> tags = new KMap<>();
|
||||
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
for(int j = 0; j < 32; j++)
|
||||
{
|
||||
if(tag[(j << 5) | i] != null)
|
||||
{
|
||||
tags.put(i + "." + j, tag[(j << 5) | i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nos.writeTag(new CompoundTag("imca", tags));
|
||||
nos.close();
|
||||
}
|
||||
|
||||
public boolean contains(int rx, int rz)
|
||||
{
|
||||
return tag[(rz << 5) | rx] != null;
|
||||
}
|
||||
|
||||
public void delete(int rx, int rz)
|
||||
{
|
||||
tag[(rz << 5) | rx] = null;
|
||||
}
|
||||
|
||||
public void set(int rx, int rz, AtomicSliverMap data) throws IOException
|
||||
{
|
||||
if(data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OutputStream out;
|
||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||
out = boas;
|
||||
|
||||
if(IrisSettings.get().parallaxCompression)
|
||||
{
|
||||
out = new CustomOutputStream(boas, IrisSettings.get().parallaxCompressionLevel);
|
||||
}
|
||||
|
||||
data.write(out);
|
||||
out.flush();
|
||||
out.close();
|
||||
tag[(rz << 5) | rx] = new ByteArrayTag(rx + "." + rz, boas.toByteArray());
|
||||
}
|
||||
|
||||
public AtomicSliverMap get(int rx, int rz) throws IOException
|
||||
{
|
||||
AtomicSliverMap data = new AtomicSliverMap();
|
||||
|
||||
if(!contains(rx, rz))
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ByteArrayTag btag = (ByteArrayTag) tag[(rz << 5) | rx];
|
||||
|
||||
InputStream in;
|
||||
|
||||
if(IrisSettings.get().parallaxCompression)
|
||||
{
|
||||
in = new GZIPInputStream(new ByteArrayInputStream(btag.getValue()));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
in = new ByteArrayInputStream(btag.getValue());
|
||||
}
|
||||
|
||||
data.read(in);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
public long guessMemoryUsage()
|
||||
{
|
||||
long bytes = 0;
|
||||
|
||||
for(int i = 0; i < 1024; i++)
|
||||
{
|
||||
if(tag[i] != null && tag[i] instanceof ByteArrayTag)
|
||||
{
|
||||
bytes += 122;
|
||||
bytes += ((ByteArrayTag) tag[i]).getValue().length;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
243
src/main/java/com/volmit/iris/gen/atomics/AtomicSliver.java
Normal file
243
src/main/java/com/volmit/iris/gen/atomics/AtomicSliver.java
Normal file
@@ -0,0 +1,243 @@
|
||||
package com.volmit.iris.object.atomics;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
|
||||
import com.volmit.iris.object.IrisBiome;
|
||||
import com.volmit.iris.util.BlockDataTools;
|
||||
import com.volmit.iris.util.HeightMap;
|
||||
import com.volmit.iris.util.KMap;
|
||||
import com.volmit.iris.util.M;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AtomicSliver
|
||||
{
|
||||
public static final BlockData AIR = BlockDataTools.getBlockData("AIR");
|
||||
private KMap<Integer, BlockData> block;
|
||||
private KMap<Integer, IrisBiome> truebiome;
|
||||
private KMap<Integer, Biome> biome;
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
private int highestBlock = 0;
|
||||
private int highestBiome = 0;
|
||||
private long last = M.ms();
|
||||
private int x;
|
||||
private int z;
|
||||
boolean modified = false;
|
||||
|
||||
public AtomicSliver(int x, int z)
|
||||
{
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.block = new KMap<>();
|
||||
this.biome = new KMap<>();
|
||||
this.truebiome = new KMap<>();
|
||||
}
|
||||
|
||||
public Material getType(int h)
|
||||
{
|
||||
return get(h).getMaterial();
|
||||
}
|
||||
|
||||
public BlockData get(int h)
|
||||
{
|
||||
BlockData b = block.get(h);
|
||||
last = M.ms();
|
||||
|
||||
if(b == null)
|
||||
{
|
||||
return AIR;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public void set(int h, BlockData d)
|
||||
{
|
||||
if(d == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
block.put(h, d);
|
||||
modified = true;
|
||||
|
||||
if(d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR))
|
||||
{
|
||||
lock.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
highestBlock = h > highestBlock ? h : highestBlock;
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void setSilently(int h, BlockData d)
|
||||
{
|
||||
if(d == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
modified = true;
|
||||
block.put(h, d);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public boolean isSolid(int h)
|
||||
{
|
||||
return getType(h).isSolid();
|
||||
}
|
||||
|
||||
public Biome getBiome(int h)
|
||||
{
|
||||
last = M.ms();
|
||||
return biome.containsKey(h) ? biome.get(h) : Biome.THE_VOID;
|
||||
}
|
||||
|
||||
public IrisBiome getTrueBiome(int h)
|
||||
{
|
||||
last = M.ms();
|
||||
return truebiome.get(h);
|
||||
}
|
||||
|
||||
public void set(int h, Biome d)
|
||||
{
|
||||
lock.lock();
|
||||
biome.put(h, d);
|
||||
modified = true;
|
||||
highestBiome = h > highestBiome ? h : highestBiome;
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void set(int h, IrisBiome d)
|
||||
{
|
||||
lock.lock();
|
||||
modified = true;
|
||||
truebiome.put(h, d);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void write(ChunkData d)
|
||||
{
|
||||
lock.lock();
|
||||
for(int i = 0; i <= highestBlock; i++)
|
||||
{
|
||||
if(block.get(i) == null)
|
||||
{
|
||||
d.setBlock(x, i, z, AIR);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
d.setBlock(x, i, z, block.get(i));
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void write(BiomeGrid d)
|
||||
{
|
||||
lock.lock();
|
||||
for(int i = 0; i <= highestBiome; i++)
|
||||
{
|
||||
if(biome.get(i) != null)
|
||||
{
|
||||
d.setBiome(x, i, z, biome.get(i));
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void write(HeightMap height)
|
||||
{
|
||||
lock.lock();
|
||||
height.setHeight(x, z, highestBlock);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void read(DataInputStream din) throws IOException
|
||||
{
|
||||
lock.lock();
|
||||
this.block = new KMap<Integer, BlockData>();
|
||||
int h = din.readByte() - Byte.MIN_VALUE;
|
||||
highestBlock = h;
|
||||
|
||||
for(int i = 0; i <= h; i++)
|
||||
{
|
||||
BlockData v = BlockDataTools.getBlockData(din.readUTF());
|
||||
|
||||
if(v == null)
|
||||
{
|
||||
block.put(i, AIR);
|
||||
continue;
|
||||
}
|
||||
|
||||
block.put(i, v);
|
||||
}
|
||||
modified = false;
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void write(DataOutputStream dos) throws IOException
|
||||
{
|
||||
lock.lock();
|
||||
dos.writeByte(highestBlock + Byte.MIN_VALUE);
|
||||
|
||||
for(int i = 0; i <= highestBlock; i++)
|
||||
{
|
||||
BlockData dat = block.get(i);
|
||||
dos.writeUTF((dat == null ? AIR : dat).getAsString(true));
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void insert(AtomicSliver atomicSliver)
|
||||
{
|
||||
lock.lock();
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
if(block.get(i) == null || block.get(i).equals(AIR))
|
||||
{
|
||||
BlockData b = atomicSliver.block.get(i);
|
||||
if(b == null || b.equals(AIR))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
block.put(i, b);
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void inject(ChunkData currentData)
|
||||
{
|
||||
lock.lock();
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
if(block.get(i) != null && !block.get(i).equals(AIR))
|
||||
{
|
||||
BlockData b = block.get(i);
|
||||
currentData.setBlock(x, i, z, b);
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public boolean isOlderThan(long m)
|
||||
{
|
||||
return M.ms() - last > m;
|
||||
}
|
||||
}
|
||||
117
src/main/java/com/volmit/iris/gen/atomics/AtomicSliverMap.java
Normal file
117
src/main/java/com/volmit/iris/gen/atomics/AtomicSliverMap.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.volmit.iris.object.atomics;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
|
||||
import com.volmit.iris.util.HeightMap;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AtomicSliverMap
|
||||
{
|
||||
private final AtomicSliver[] slivers;
|
||||
private boolean parallaxGenerated;
|
||||
private boolean worldGenerated;
|
||||
|
||||
public AtomicSliverMap()
|
||||
{
|
||||
parallaxGenerated = false;
|
||||
worldGenerated = false;
|
||||
slivers = new AtomicSliver[256];
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
slivers[i * 16 + j] = new AtomicSliver(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(AtomicSliverMap map)
|
||||
{
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
slivers[i].insert(map.slivers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
DataOutputStream dos = new DataOutputStream(out);
|
||||
dos.writeBoolean(isParallaxGenerated());
|
||||
dos.writeBoolean(isWorldGenerated());
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
slivers[i].write(dos);
|
||||
}
|
||||
|
||||
dos.flush();
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws IOException
|
||||
{
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
parallaxGenerated = din.readBoolean();
|
||||
worldGenerated = din.readBoolean();
|
||||
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
slivers[i].read(din);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AtomicSliver getSliver(int x, int z)
|
||||
{
|
||||
return slivers[x * 16 + z];
|
||||
}
|
||||
|
||||
public void write(ChunkData data, BiomeGrid grid, HeightMap height)
|
||||
{
|
||||
for(AtomicSliver i : slivers)
|
||||
{
|
||||
if(i != null)
|
||||
{
|
||||
i.write(data);
|
||||
i.write(grid);
|
||||
i.write(height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inject(ChunkData currentData)
|
||||
{
|
||||
for(AtomicSliver i : slivers)
|
||||
{
|
||||
i.inject(currentData);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isModified()
|
||||
{
|
||||
for(AtomicSliver i : slivers)
|
||||
{
|
||||
if(i.isModified())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
348
src/main/java/com/volmit/iris/gen/atomics/AtomicWorldData.java
Normal file
348
src/main/java/com/volmit/iris/gen/atomics/AtomicWorldData.java
Normal file
@@ -0,0 +1,348 @@
|
||||
package com.volmit.iris.object.atomics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.ChunkPosition;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.KMap;
|
||||
import com.volmit.iris.util.M;
|
||||
|
||||
public class AtomicWorldData
|
||||
{
|
||||
private World world;
|
||||
private KMap<ChunkPosition, AtomicSliverMap> loadedChunks;
|
||||
private KMap<ChunkPosition, AtomicRegionData> loadedSections;
|
||||
private KMap<ChunkPosition, Long> lastRegion;
|
||||
private KMap<ChunkPosition, Long> lastChunk;
|
||||
private KList<ChunkPosition> unloadRegions;
|
||||
private KList<ChunkPosition> unloadChunks;
|
||||
private long last = M.ms();
|
||||
private String prefix;
|
||||
|
||||
public AtomicWorldData(World world, String prefix)
|
||||
{
|
||||
this.world = world;
|
||||
loadedSections = new KMap<>();
|
||||
loadedChunks = new KMap<>();
|
||||
lastRegion = new KMap<>();
|
||||
lastChunk = new KMap<>();
|
||||
unloadRegions = new KList<>();
|
||||
unloadChunks = new KList<>();
|
||||
this.prefix = prefix;
|
||||
getSubregionFolder().mkdirs();
|
||||
}
|
||||
|
||||
public KMap<ChunkPosition, AtomicRegionData> getLoadedRegions()
|
||||
{
|
||||
return loadedSections;
|
||||
}
|
||||
|
||||
public AtomicRegionData getSubregion(int x, int z) throws IOException
|
||||
{
|
||||
lastRegion.put(new ChunkPosition(x, z), M.ms());
|
||||
|
||||
if(!isSectionLoaded(x, z))
|
||||
{
|
||||
loadedSections.put(new ChunkPosition(x, z), loadSection(x, z));
|
||||
}
|
||||
|
||||
AtomicRegionData f = loadedSections.get(new ChunkPosition(x, z));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public void saveAll() throws IOException
|
||||
{
|
||||
saveChunks();
|
||||
|
||||
for(ChunkPosition i : loadedSections.keySet())
|
||||
{
|
||||
saveSection(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadAll(boolean save) throws IOException
|
||||
{
|
||||
saveChunks();
|
||||
|
||||
for(ChunkPosition i : loadedSections.keySet())
|
||||
{
|
||||
unloadSection(i, save);
|
||||
}
|
||||
|
||||
loadedSections.clear();
|
||||
loadedChunks.clear();
|
||||
lastRegion.clear();
|
||||
}
|
||||
|
||||
public void deleteSection(int x, int z) throws IOException
|
||||
{
|
||||
unloadSection(x, z, false);
|
||||
getSubregionFile(x, z).delete();
|
||||
}
|
||||
|
||||
public boolean isSectionLoaded(int x, int z)
|
||||
{
|
||||
return isSectionLoaded(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public boolean isSectionLoaded(ChunkPosition s)
|
||||
{
|
||||
return loadedSections.containsKey(s);
|
||||
}
|
||||
|
||||
public boolean unloadSection(int x, int z, boolean save) throws IOException
|
||||
{
|
||||
return unloadSection(new ChunkPosition(x, z), save);
|
||||
}
|
||||
|
||||
public boolean unloadSection(ChunkPosition s, boolean save) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(s))
|
||||
{
|
||||
Iris.warn("Cant unload because section isnt loaded?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(save)
|
||||
{
|
||||
saveSection(s);
|
||||
}
|
||||
|
||||
loadedSections.remove(s);
|
||||
lastRegion.remove(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean saveSection(int x, int z) throws IOException
|
||||
{
|
||||
return saveSection(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
public boolean saveSection(ChunkPosition s) throws IOException
|
||||
{
|
||||
if(!isSectionLoaded(s.getX(), s.getZ()))
|
||||
{
|
||||
Iris.warn("Cant save section " + s.getX() + " " + s.getZ() + " because section isnt loaded?");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
saveChunks(s);
|
||||
AtomicRegionData data = loadedSections.get(s);
|
||||
FileOutputStream fos = new FileOutputStream(getSubregionFile(s.getX(), s.getZ()));
|
||||
data.write(fos);
|
||||
fos.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void saveChunks() throws IOException
|
||||
{
|
||||
for(ChunkPosition i : loadedChunks.k())
|
||||
{
|
||||
saveChunk(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveChunks(ChunkPosition reg) throws IOException
|
||||
{
|
||||
for(ChunkPosition i : loadedChunks.k())
|
||||
{
|
||||
int x = i.getX();
|
||||
int z = i.getZ();
|
||||
|
||||
if(x >> 5 == reg.getX() && z >> 5 == reg.getZ())
|
||||
{
|
||||
saveChunk(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveChunk(ChunkPosition i) throws IOException
|
||||
{
|
||||
AtomicSliverMap m = loadedChunks.get(i);
|
||||
|
||||
if(m.isModified())
|
||||
{
|
||||
int x = i.getX();
|
||||
int z = i.getZ();
|
||||
AtomicRegionData dat = loadSection(x >> 5, z >> 5, true);
|
||||
dat.set(x & 31, z & 31, m);
|
||||
}
|
||||
|
||||
loadedChunks.remove(i);
|
||||
lastChunk.remove(i);
|
||||
}
|
||||
|
||||
public AtomicSliverMap loadChunk(int x, int z) throws IOException
|
||||
{
|
||||
ChunkPosition pos = new ChunkPosition(x, z);
|
||||
lastChunk.put(pos, M.ms());
|
||||
if(loadedChunks.containsKey(pos))
|
||||
{
|
||||
return loadedChunks.get(pos);
|
||||
}
|
||||
|
||||
AtomicRegionData dat = loadSection(x >> 5, z >> 5);
|
||||
AtomicSliverMap m = dat.get(x & 31, z & 31);
|
||||
loadedChunks.put(pos, m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
public boolean hasChunk(int x, int z) throws IOException
|
||||
{
|
||||
return loadSection(x >> 5, z >> 5).contains(x & 31, z & 31);
|
||||
}
|
||||
|
||||
public AtomicRegionData loadSection(int x, int z, boolean anonymous) throws IOException
|
||||
{
|
||||
ChunkPosition pos = new ChunkPosition(x, z);
|
||||
if(!anonymous)
|
||||
{
|
||||
lastRegion.put(pos, M.ms());
|
||||
}
|
||||
|
||||
if(isSectionLoaded(x, z))
|
||||
{
|
||||
return loadedSections.get(pos);
|
||||
}
|
||||
|
||||
File file = getSubregionFile(x, z);
|
||||
|
||||
if(!file.exists())
|
||||
{
|
||||
AtomicRegionData dat = createSection(x, z);
|
||||
loadedSections.put(pos, dat);
|
||||
return dat;
|
||||
}
|
||||
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
AtomicRegionData data = new AtomicRegionData(world);
|
||||
data.read(fin);
|
||||
fin.close();
|
||||
loadedSections.put(pos, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public AtomicRegionData loadSection(int x, int z) throws IOException
|
||||
{
|
||||
return loadSection(x, z, false);
|
||||
}
|
||||
|
||||
public AtomicRegionData createSection(int x, int z)
|
||||
{
|
||||
if(isSectionLoaded(x, z))
|
||||
{
|
||||
return loadedSections.get(new ChunkPosition(x, z));
|
||||
}
|
||||
|
||||
AtomicRegionData data = new AtomicRegionData(world);
|
||||
loadedSections.put(new ChunkPosition(x, z), data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public File getSubregionFile(int x, int z)
|
||||
{
|
||||
return new File(getSubregionFolder(), "sr." + x + "." + z + ".smca");
|
||||
}
|
||||
|
||||
public File getSubregionFolder()
|
||||
{
|
||||
return new File(world.getWorldFolder(), "subregion-" + prefix);
|
||||
}
|
||||
|
||||
public KMap<ChunkPosition, AtomicSliverMap> getLoadedChunks()
|
||||
{
|
||||
return loadedChunks;
|
||||
}
|
||||
|
||||
public void clean(int j)
|
||||
{
|
||||
if(M.ms() - last < getUnloadBatchSpeed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int m = 0;
|
||||
|
||||
for(ChunkPosition i : lastRegion.keySet())
|
||||
{
|
||||
if(m > 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(M.ms() - lastRegion.get(i) > 60000)
|
||||
{
|
||||
unloadRegions.add(i);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
m = 0;
|
||||
|
||||
for(ChunkPosition i : unloadRegions)
|
||||
{
|
||||
lastRegion.remove(i);
|
||||
|
||||
try
|
||||
{
|
||||
unloadSection(i, true);
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
unloadRegions.clear();
|
||||
|
||||
for(ChunkPosition i : lastChunk.keySet())
|
||||
{
|
||||
if(m > getUnloadBatchSize())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(M.ms() - lastChunk.get(i) > 15000)
|
||||
{
|
||||
m++;
|
||||
unloadChunks.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
for(ChunkPosition i : unloadChunks)
|
||||
{
|
||||
try
|
||||
{
|
||||
saveChunk(i);
|
||||
}
|
||||
|
||||
catch(IOException e)
|
||||
{
|
||||
Iris.warn("Failed to save chunk");
|
||||
}
|
||||
}
|
||||
|
||||
unloadChunks.clear();
|
||||
}
|
||||
|
||||
private int getUnloadBatchSize()
|
||||
{
|
||||
return Math.max(3, getLoadedRegions().size() / 125);
|
||||
}
|
||||
|
||||
private int getUnloadBatchSpeed()
|
||||
{
|
||||
return Math.max(250, 2000 - getLoadedRegions().size());
|
||||
}
|
||||
}
|
||||
48
src/main/java/com/volmit/iris/gen/atomics/MasterLock.java
Normal file
48
src/main/java/com/volmit/iris/gen/atomics/MasterLock.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.volmit.iris.object.atomics;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.volmit.iris.util.KMap;
|
||||
|
||||
public class MasterLock
|
||||
{
|
||||
private KMap<String, ReentrantLock> locks;
|
||||
private ReentrantLock lock;
|
||||
|
||||
public MasterLock()
|
||||
{
|
||||
locks = new KMap<>();
|
||||
lock = new ReentrantLock();
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
locks.clear();
|
||||
}
|
||||
|
||||
public void lock(String key)
|
||||
{
|
||||
lock.lock();
|
||||
if(!locks.containsKey(key))
|
||||
{
|
||||
locks.put(key, new ReentrantLock());
|
||||
}
|
||||
|
||||
ReentrantLock l = locks.get(key);
|
||||
lock.unlock();
|
||||
l.lock();
|
||||
}
|
||||
|
||||
public void unlock(String key)
|
||||
{
|
||||
lock.lock();
|
||||
if(!locks.containsKey(key))
|
||||
{
|
||||
locks.put(key, new ReentrantLock());
|
||||
}
|
||||
|
||||
ReentrantLock l = locks.get(key);
|
||||
lock.unlock();
|
||||
l.unlock();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user