fix old object loading

This commit is contained in:
Julian Krings 2024-08-17 00:45:58 +02:00
parent b468478fcb
commit fc793592f7
10 changed files with 222 additions and 22 deletions

View File

@ -47,6 +47,7 @@ import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.math.Vector3d;
import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.plugin.VolmitSender;
import io.lumine.mythic.bukkit.adapters.BukkitEntity;
import net.jpountz.lz4.LZ4BlockInputStream;
@ -206,6 +207,23 @@ public class CommandDeveloper implements DecreeExecutor {
}
@Decree
public void objects(@Param(defaultValue = "overworld") IrisDimension dimension) {
var loader = dimension.getLoader().getObjectLoader();
var sender = sender();
var keys = loader.getPossibleKeys();
var burst = MultiBurst.burst.burst(keys.length);
AtomicInteger failed = new AtomicInteger();
for (String key : keys) {
burst.queue(() -> {
if (loader.load(key) == null)
failed.incrementAndGet();
});
}
burst.complete();
sender.sendMessage(C.RED + "Failed to load " + failed.get() + " of " + keys.length + " objects");
}
@Decree(description = "Test", aliases = {"ip"})
public void network() {
try {

View File

@ -50,10 +50,10 @@ public class ObjectResourceLoader extends ResourceLoader<IrisObject> {
try {
PrecisionStopwatch p = PrecisionStopwatch.start();
IrisObject t = new IrisObject(0, 0, 0);
t.read(j);
t.setLoadKey(name);
t.setLoader(manager);
t.setLoadFile(j);
t.read(j);
logLoad(j, t);
tlt.addAndGet(p.getMilliseconds());
return t;

View File

@ -108,7 +108,7 @@ public interface EngineMantle extends IObjectPlacer {
@Override
default void setTile(int x, int y, int z, TileData d) {
getMantle().set(x, y, z, d);
getMantle().set(x, y, z, new TileWrapper(d));
}
@Override

View File

@ -385,14 +385,14 @@ public class IrisObject extends IrisRegistrant {
}
public void read(File file) throws IOException {
FileInputStream fin = new FileInputStream(file);
var fin = new BufferedInputStream(new FileInputStream(file));
try {
read(fin);
fin.close();
} catch (Throwable e) {
Iris.reportError(e);
fin.close();
fin = new FileInputStream(file);
fin = new BufferedInputStream(new FileInputStream(file));
readLegacy(fin);
fin.close();
}

View File

@ -0,0 +1,139 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.scheduling.J;
import org.bukkit.DyeColor;
import org.bukkit.block.*;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.entity.EntityType;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class LegacyTileData extends TileData {
private static final Map<Short, Handler> legacy = Map.of(
(short) 0, new SignHandler(),
(short) 1, new SpawnerHandler(),
(short) 2, new BannerHandler());
private final short id;
private final KList<Object> properties;
public LegacyTileData(DataInputStream in) throws IOException {
id = in.readShort();
var handler = legacy.get(id);
if (handler == null)
throw new IOException("Unknown tile type: " + id);
properties = handler.read(in);
}
@Override
public void toBukkit(Block block) {
var handler = legacy.get(id);
J.s(() -> handler.toBukkit(properties, block));
}
@Override
public void toBinary(DataOutputStream out) throws IOException {
out.writeShort(id);
legacy.get(id).toBinary(properties, out);
}
private interface Handler {
KList<Object> read(DataInputStream in) throws IOException;
void toBinary(KList<Object> list, DataOutputStream out) throws IOException;
void toBukkit(KList<Object> list, Block block);
}
private static class SignHandler implements Handler {
@Override
public KList<Object> read(DataInputStream in) throws IOException {
return new KList<>()
.qadd(in.readUTF())
.qadd(in.readUTF())
.qadd(in.readUTF())
.qadd(in.readUTF())
.qadd(DyeColor.values()[in.readByte()]);
}
@Override
public void toBinary(KList<Object> list, DataOutputStream out) throws IOException {
out.writeUTF((String) list.get(0));
out.writeUTF((String) list.get(1));
out.writeUTF((String) list.get(2));
out.writeUTF((String) list.get(3));
out.writeByte(((DyeColor) list.get(4)).ordinal());
}
@Override
public void toBukkit(KList<Object> list, Block block) {
Sign sign = (Sign) block.getState();
sign.setLine(0, (String) list.get(0));
sign.setLine(1, (String) list.get(1));
sign.setLine(2, (String) list.get(2));
sign.setLine(3, (String) list.get(3));
sign.setColor((DyeColor) list.get(4));
sign.update();
}
}
private static class SpawnerHandler implements Handler {
@Override
public KList<Object> read(DataInputStream in) throws IOException {
return new KList<>().qadd(EntityType.values()[in.readShort()]);
}
@Override
public void toBinary(KList<Object> list, DataOutputStream out) throws IOException {
out.writeShort(((EntityType) list.get(0)).ordinal());
}
@Override
public void toBukkit(KList<Object> list, Block block) {
CreatureSpawner spawner = (CreatureSpawner) block.getState();
spawner.setSpawnedType((EntityType) list.get(0));
spawner.update();
}
}
private static class BannerHandler implements Handler {
@Override
public KList<Object> read(DataInputStream in) throws IOException {
KList<Object> list = new KList<>();
list.add(DyeColor.values()[in.readByte()]);
int listSize = in.readByte();
var patterns = new KList<>();
for (int i = 0; i < listSize; i++) {
DyeColor color = DyeColor.values()[in.readByte()];
PatternType type = PatternType.values()[in.readByte()];
patterns.add(new Pattern(color, type));
}
list.add(patterns);
return list;
}
@Override
public void toBinary(KList<Object> list, DataOutputStream out) throws IOException {
out.writeByte(((DyeColor) list.get(0)).ordinal());
out.writeByte(((List<Pattern>) list.get(1)).size());
for (Pattern i : (List<Pattern>) list.get(1)) {
out.writeByte(i.getColor().ordinal());
out.writeByte(i.getPattern().ordinal());
}
}
@Override
public void toBukkit(KList<Object> list, Block block) {
Banner banner = (Banner) block.getState();
banner.setBaseColor((DyeColor) list.get(0));
banner.setPatterns((List<Pattern>) list.get(1));
banner.update();
}
}
}

View File

@ -31,6 +31,7 @@ import org.bukkit.block.BlockState;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@ -57,10 +58,24 @@ public class TileData implements Cloneable {
}
public static TileData read(DataInputStream in) throws IOException {
TileData d = new TileData();
d.material = Material.matchMaterial(in.readUTF());
d.properties = gson.fromJson(in.readUTF(), KMap.class);
return d;
if (!in.markSupported())
throw new IOException("Mark not supported");
in.mark(Integer.MAX_VALUE);
try {
TileData d = new TileData();
var material = in.readUTF();
d.material = Material.matchMaterial(material);
if (d.material == null) throw new IOException("Unknown material: " + material);
var properties = in.readUTF();
d.properties = gson.fromJson(properties, KMap.class);
if (d.properties == null) throw new IOException("Invalid properties: " + properties);
return d;
} catch (Throwable e) {
in.reset();
return new LegacyTileData(in);
} finally {
in.mark(0);
}
}
public boolean isApplicable(BlockData data) {

View File

@ -86,10 +86,10 @@ public class TectonicPlate {
DataInputStream din;
if (file.getName().endsWith("ttp.lz4b")) {
LZ4BlockInputStream lz4 = new LZ4BlockInputStream(fin);
din = new DataInputStream(lz4);
din = new DataInputStream(new BufferedInputStream(lz4));
} else {
GZIPInputStream gzi = new GZIPInputStream(fin);
din = new DataInputStream(gzi);
din = new DataInputStream(new BufferedInputStream(gzi));
}
TectonicPlate p = new TectonicPlate(worldHeight, din);
din.close();

View File

@ -0,0 +1,27 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2024 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.matter;
import com.volmit.iris.engine.object.TileData;
import lombok.Data;
@Data
public class TileWrapper {
private final TileData data;
}

View File

@ -34,8 +34,8 @@ public class WorldMatter {
matter.slice(MatterEntityGroup.class).writeInto(at);
}
if (matter.hasSlice(TileData.class)) {
matter.slice(TileData.class).writeInto(at);
if (matter.hasSlice(TileWrapper.class)) {
matter.slice(TileWrapper.class).writeInto(at);
}
}
@ -46,7 +46,7 @@ public class WorldMatter {
s.getHeader().setAuthor(author);
s.slice(BlockData.class).readFrom(c.getLowerNE());
s.slice(MatterEntityGroup.class).readFrom(c.getLowerNE());
s.slice(TileData.class).readFrom(c.getLowerNE());
s.slice(TileWrapper.class).readFrom(c.getLowerNE());
s.trimSlices();
return s;

View File

@ -21,6 +21,7 @@ package com.volmit.iris.util.matter.slices;
import com.volmit.iris.engine.object.TileData;
import com.volmit.iris.util.data.palette.Palette;
import com.volmit.iris.util.matter.Sliced;
import com.volmit.iris.util.matter.TileWrapper;
import org.bukkit.Location;
import org.bukkit.World;
@ -30,28 +31,28 @@ import java.io.IOException;
@SuppressWarnings("rawtypes")
@Sliced
public class TileMatter extends RawMatter<TileData> {
public class TileMatter extends RawMatter<TileWrapper> {
public TileMatter() {
this(1, 1, 1);
}
public TileMatter(int width, int height, int depth) {
super(width, height, depth, TileData.class);
registerWriter(World.class, (w, d, x, y, z) -> TileData.setTileState(w.getBlockAt(new Location(w, x, y, z)), d));
registerReader(World.class, (w, x, y, z) -> TileData.getTileState(w.getBlockAt(new Location(w, x, y, z))));
super(width, height, depth, TileWrapper.class);
registerWriter(World.class, (w, d, x, y, z) -> TileData.setTileState(w.getBlockAt(new Location(w, x, y, z)), d.getData()));
registerReader(World.class, (w, x, y, z) -> new TileWrapper(TileData.getTileState(w.getBlockAt(new Location(w, x, y, z)))));
}
@Override
public Palette<TileData> getGlobalPalette() {
public Palette<TileWrapper> getGlobalPalette() {
return null;
}
public void writeNode(TileData b, DataOutputStream dos) throws IOException {
b.toBinary(dos);
public void writeNode(TileWrapper b, DataOutputStream dos) throws IOException {
b.getData().toBinary(dos);
}
public TileData readNode(DataInputStream din) throws IOException {
return TileData.read(din);
public TileWrapper readNode(DataInputStream din) throws IOException {
return new TileWrapper(TileData.read(din));
}
}