mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-01-04 15:41:30 +00:00
Pregenerator
This commit is contained in:
278
src/main/java/com/volmit/iris/pregen/DirectWorldWriter.java
Normal file
278
src/main/java/com/volmit/iris/pregen/DirectWorldWriter.java
Normal file
@@ -0,0 +1,278 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.nms.INMS;
|
||||
import com.volmit.iris.scaffold.cache.Cache;
|
||||
import com.volmit.iris.scaffold.parallel.BurstExecutor;
|
||||
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.B;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.KMap;
|
||||
import com.volmit.iris.util.M;
|
||||
import io.timeandspace.smoothie.SmoothieMap;
|
||||
import net.querz.mca.*;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
import net.querz.nbt.tag.StringTag;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class DirectWorldWriter {
|
||||
private final File worldFolder;
|
||||
private final Map<Long, MCAFile> writeBuffer;
|
||||
private final Map<Long, Long> lastUse;
|
||||
private static final Map<String, CompoundTag> blockDataCache = new KMap<>();
|
||||
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
|
||||
|
||||
public DirectWorldWriter(File worldFolder)
|
||||
{
|
||||
this.worldFolder = worldFolder;
|
||||
lastUse = SmoothieMap.<Long, Long>newBuilder().build();
|
||||
writeBuffer = new KMap<>();
|
||||
new File(worldFolder, "region").mkdirs();
|
||||
}
|
||||
|
||||
public void flush()
|
||||
{
|
||||
BurstExecutor ex2 = MultiBurst.burst.burst(writeBuffer.size());
|
||||
|
||||
for(Long i : new KList<>(writeBuffer.keySet()))
|
||||
{
|
||||
if(M.ms() - lastUse.get(i) < 10000)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ex2.queue(() -> {
|
||||
int x = Cache.keyX(i);
|
||||
int z = Cache.keyZ(i);
|
||||
try {
|
||||
File f = getMCAFile(x, z);
|
||||
|
||||
if(!f.exists())
|
||||
{
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
writeBuffer.get(i).cleanupPalettesAndBlockStates();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
lastUse.remove(i);
|
||||
MCAUtil.write(writeBuffer.get(i), f, true);
|
||||
writeBuffer.remove(i);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void optimizeChunk(int x, int z)
|
||||
{
|
||||
getChunk(x, z).cleanupPalettesAndBlockStates();
|
||||
}
|
||||
|
||||
public File getMCAFile(int x, int z)
|
||||
{
|
||||
return new File(worldFolder, "region/r." + x + "." + z + ".mca");
|
||||
}
|
||||
|
||||
public BlockData getBlockData(CompoundTag tag) {
|
||||
if (tag == null)
|
||||
{
|
||||
return B.getAir();
|
||||
}
|
||||
|
||||
String p = tag.getString("Name");
|
||||
|
||||
if(tag.containsKey("Properties"))
|
||||
{
|
||||
CompoundTag props = tag.getCompoundTag("Properties");
|
||||
p += "[";
|
||||
KList<String> m = new KList<>();
|
||||
|
||||
for(String i : props.keySet())
|
||||
{
|
||||
m.add(i + "=" + props.getString(i));
|
||||
}
|
||||
|
||||
p += m.toString(",") + "]";
|
||||
}
|
||||
|
||||
BlockData b = B.getOrNull(p);
|
||||
|
||||
if(b == null)
|
||||
{
|
||||
return B.getAir();
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public CompoundTag getCompound(BlockData blockData)
|
||||
{
|
||||
String data = blockData.getAsString(true);
|
||||
|
||||
if(blockDataCache.containsKey(data))
|
||||
{
|
||||
return blockDataCache.get(data).clone();
|
||||
}
|
||||
|
||||
CompoundTag s = new CompoundTag();
|
||||
NamespacedKey key = blockData.getMaterial().getKey();
|
||||
s.putString("Name", key.getNamespace() + ":" + key.getKey());
|
||||
|
||||
|
||||
if(data.contains("["))
|
||||
{
|
||||
String raw = data.split("\\Q[\\E")[1].replaceAll("\\Q]\\E", "");
|
||||
CompoundTag props = new CompoundTag();
|
||||
if(raw.contains(","))
|
||||
{
|
||||
for(String i : raw.split("\\Q,\\E"))
|
||||
{
|
||||
String[] m = i.split("\\Q=\\E");
|
||||
String k = m[0];
|
||||
String v = m[1];
|
||||
props.put(k, new StringTag(v));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
String[] m = raw.split("\\Q=\\E");
|
||||
String k = m[0];
|
||||
String v = m[1];
|
||||
props.put(k, new StringTag(v));
|
||||
}
|
||||
s.put("Properties", props);
|
||||
}
|
||||
|
||||
blockDataCache.put(data, s.clone());
|
||||
return s;
|
||||
}
|
||||
|
||||
public BlockData getBlockData(int x, int y, int z)
|
||||
{
|
||||
try
|
||||
{
|
||||
CompoundTag tag = getChunkSection(x >> 4, y >> 4, z >> 4).getBlockStateAt(x & 15, y & 15, z & 15);
|
||||
|
||||
if(tag == null)
|
||||
{
|
||||
return B.get("AIR");
|
||||
}
|
||||
|
||||
return getBlockData(tag);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
return B.get("AIR");
|
||||
}
|
||||
|
||||
public void setBlockData(int x, int y, int z, BlockData data)
|
||||
{
|
||||
getChunkSection(x >> 4, y >> 4, z >> 4).setBlockStateAt(x & 15, y & 15, z & 15, getCompound(data), false);
|
||||
}
|
||||
|
||||
public void setBiome(int x, int y, int z, Biome biome)
|
||||
{
|
||||
getChunk(x>>4, z>>4).setBiomeAt(x&15, y, z &15, biomeIds.get(biome));
|
||||
}
|
||||
|
||||
public Section getChunkSection(int x, int y, int z)
|
||||
{
|
||||
Chunk c = getChunk(x, z);
|
||||
Section s = c.getSection(y);
|
||||
|
||||
if(s == null)
|
||||
{
|
||||
s = Section.newSection();
|
||||
c.setSection(y, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public Chunk getChunk(int x, int z)
|
||||
{
|
||||
MCAFile mca = getMCA(x >> 5, z >> 5);
|
||||
Chunk c = mca.getChunk(x & 31, z & 31);
|
||||
|
||||
if(c == null)
|
||||
{
|
||||
c = Chunk.newChunk();
|
||||
lastUse.put(Cache.key(x >> 5, z >> 5), M.ms());
|
||||
mca.setChunk(x&31, z&31, c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public MCAFile getMCA(int x, int z)
|
||||
{
|
||||
long key = Cache.key(x, z);
|
||||
MCAFile mca = writeBuffer.get(key);
|
||||
|
||||
if(mca != null)
|
||||
{
|
||||
return mca;
|
||||
}
|
||||
|
||||
File f = getMCAFile(x, z);
|
||||
mca = new MCAFile(x, z);
|
||||
if(f.exists())
|
||||
{
|
||||
try {
|
||||
Iris.warn("HAD TO LOAD MCA REGION FILE " + x + " " + z + " which is EXPENSIVE!");
|
||||
mca = MCAUtil.read(f);
|
||||
try
|
||||
{
|
||||
mca.cleanupPalettesAndBlockStates();
|
||||
}
|
||||
|
||||
catch(Throwable ee)
|
||||
{
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Iris.warn("Failed to read RandomAccessFile " + f.getAbsolutePath() + ", assuming empty region!");
|
||||
}
|
||||
}
|
||||
|
||||
lastUse.put(key, M.ms());
|
||||
writeBuffer.put(key, mca);
|
||||
return mca;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return writeBuffer.size();
|
||||
}
|
||||
|
||||
private static Map<Biome, Integer> computeBiomeIDs() {
|
||||
Map<Biome, Integer> biomeIds = new KMap<>();
|
||||
|
||||
for(Biome i : Biome.values())
|
||||
{
|
||||
biomeIds.put(i, INMS.get().getBiomeId(i));
|
||||
}
|
||||
|
||||
return biomeIds;
|
||||
}
|
||||
}
|
||||
8
src/main/java/com/volmit/iris/pregen/Pregenerator.java
Normal file
8
src/main/java/com/volmit/iris/pregen/Pregenerator.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package com.volmit.iris.pregen;
|
||||
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class MCAPregenerator implements Listener
|
||||
{
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user