9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-30 12:29:20 +00:00
This commit is contained in:
Daniel Mills
2020-12-27 05:28:34 -05:00
parent 3d00e96f89
commit 7bbae51c7d
14 changed files with 1730 additions and 16 deletions

View File

@@ -0,0 +1,210 @@
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 net.querz.mca.Chunk;
import net.querz.mca.MCAFile;
import net.querz.mca.MCAUtil;
import net.querz.mca.Section;
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;
public class DirectWorldWriter {
private final File worldFolder;
private final KMap<Long, MCAFile> writeBuffer;
public DirectWorldWriter(File worldFolder)
{
this.worldFolder = worldFolder;
writeBuffer = new KMap<>();
new File(worldFolder, "region").mkdirs();
}
public void flush()
{
BurstExecutor ex = MultiBurst.burst.burst(writeBuffer.size());
writeBuffer.v().forEach((i) -> ex.queue(i::cleanupPalettesAndBlockStates));
ex.complete();
BurstExecutor ex2 = MultiBurst.burst.burst(writeBuffer.size());
for(Long i : writeBuffer.k())
{
int x = Cache.keyX(i);
int z = Cache.keyZ(i);
try {
File f = getMCAFile(x, z);
if(!f.exists())
{
f.getParentFile().mkdirs();
f.createNewFile();
}
MCAUtil.write(writeBuffer.get(i), f, true);
} catch (Throwable e) {
e.printStackTrace();
}
}
writeBuffer.clear();
}
public File getMCAFile(int x, int z)
{
return new File(worldFolder, "region/r." + x + "." + z + ".mca");
}
public BlockData getBlockData(CompoundTag tag)
{
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(",") + "]";
}
return B.get(p);
}
public CompoundTag getCompound(BlockData blockData)
{
CompoundTag s = new CompoundTag();
NamespacedKey key = blockData.getMaterial().getKey();
s.putString("Name", key.getNamespace() + ":" + key.getKey());
String data = blockData.getAsString(true);
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);
}
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, INMS.get().getBiomeId(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();
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 {
mca = MCAUtil.read(f);
} catch (IOException e) {
e.printStackTrace();
Iris.warn("Failed to read RandomAccessFile " + f.getAbsolutePath() + ", assuming empty region!");
}
}
writeBuffer.put(key, mca);
return mca;
}
}

View File

@@ -9,6 +9,8 @@ import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.scaffold.IrisWorlds;
import com.volmit.iris.scaffold.cache.Cache;
import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.scaffold.parallel.BurstExecutor;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.*;
import io.papermc.lib.PaperLib;
import lombok.Getter;
@@ -308,6 +310,129 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
return tc.getRaw();
}
public void directWriteMCA(World w, int x, int z, DirectWorldWriter writer, MultiBurst burst)
{
if(writer.getMCAFile(x, z).exists())
{
return;
}
BurstExecutor e = burst.burst(1024);
int mcaox = x << 5;
int mcaoz = z << 5;
for(int i = 0; i < 32; i++)
{
int ii = i;
for(int j = 0; j < 32; j++)
{
int jj = j;
e.queue(() -> directWriteChunk(w, ii + mcaox, jj + mcaoz, writer));
}
}
e.complete();
}
public void directWriteChunk(World w, int x, int z, DirectWorldWriter writer)
{
int ox = x << 4;
int oz = z << 4;
generateChunkRawData(w, x, z, new TerrainChunk() {
@Override
public void setRaw(ChunkData data) {
}
@Override
public Biome getBiome(int x, int z) {
return Biome.THE_VOID;
}
@Override
public Biome getBiome(int x, int y, int z) {
return Biome.THE_VOID;
}
@Override
public void setBiome(int x, int z, Biome bio) {
writer.setBiome(ox + x, 0, oz + z, bio);
}
@Override
public void setBiome(int x, int y, int z, Biome bio) {
writer.setBiome(ox + x, y, oz + z, bio);
}
@Override
public int getMaxHeight() {
return w.getMaxHeight();
}
@Override
public void setBlock(int x, int y, int z, BlockData blockData) {
writer.setBlockData(x+ox, y, z+oz, blockData);
}
@Override
public BlockData getBlockData(int x, int y, int z) {
return writer.getBlockData(x + ox, y, z + oz);
}
@Override
public ChunkData getRaw() {
return null;
}
@Override
public void inject(BiomeGrid biome) {
}
@Override
public void setBlock(int x, int y, int z, @NotNull Material material) {
}
@Override
public void setBlock(int x, int y, int z, @NotNull MaterialData material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) {
}
@NotNull
@Override
public Material getType(int x, int y, int z) {
return null;
}
@NotNull
@Override
public MaterialData getTypeAndData(int x, int y, int z) {
return null;
}
@Override
public byte getData(int x, int y, int z) {
return 0;
}
}).run();
}
public Chunk generatePaper(World world, int x, int z)
{
precache(world, x, z);

View File

@@ -151,15 +151,19 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer
PrecisionStopwatch p = PrecisionStopwatch.start();
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i,j;
BurstExecutor b = MultiBurst.burst.burst((s * 2) * (s * 2));
for(i = -s; i <= s; i++)
{
int ii = i;
for(j = -s; j <= s; j++)
{
generateParallaxLayer((i*16)+x, (j*16)+z);
int jj = j;
b.queue(() -> generateParallaxLayer((ii*16)+x, (jj*16)+z));
}
}
b.complete();
getParallaxAccess().setChunkGenerated(x>>4, z>>4);
p.end();
getEngine().getMetrics().getParallax().put(p.getMilliseconds());

View File

@@ -3,6 +3,7 @@ package com.volmit.iris.scaffold.engine;
import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.object.*;
import com.volmit.iris.scaffold.data.DataProvider;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.*;
import org.bukkit.Chunk;
import org.bukkit.Location;
@@ -16,6 +17,10 @@ import java.util.function.Consumer;
public interface IrisAccess extends Hotloadable, DataProvider {
public void directWriteMCA(World w, int x, int z, DirectWorldWriter writer, MultiBurst burst);
public void directWriteChunk(World w, int x, int z, DirectWorldWriter writer);
public int getGenerated();
public double getGeneratedPerSecond();