Add completely new schematic format to reduce schematic size to about 7%
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
yoyosource 2023-02-10 21:47:10 +01:00
Ursprung 176ee5e0cf
Commit 42f8a044a4
4 geänderte Dateien mit 357 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,79 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cuboid2;
import com.fastasyncworldedit.core.internal.io.parallelgzip.ParallelGZIPOutputStream;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import de.steamwar.bausystem.features.cuboid2.io.TSchemWriter;
import java.io.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.GZIPOutputStream;
public class TSchemClipboardFormat implements ClipboardFormat {
@Override
public String getName() {
return "TSchem";
}
@Override
public Set<String> getAliases() {
return new HashSet<>(Arrays.asList("tschem"));
}
@Override
public ClipboardReader getReader(InputStream inputStream) throws IOException {
return null;
}
@Override
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
OutputStream gzip;
if (!(outputStream instanceof ParallelGZIPOutputStream) && !(outputStream instanceof GZIPOutputStream)) {
OutputStream outputStreamx = new BufferedOutputStream(outputStream);
gzip = new GZIPOutputStream(outputStreamx);
} else {
gzip = outputStream;
}
return new TSchemWriter(new NBTOutputStream(new BufferedOutputStream(gzip)));
}
@Override
public boolean isFormat(File file) {
return file.getName().endsWith(".tschem");
}
@Override
public String getPrimaryFileExtension() {
return "tschem";
}
@Override
public Set<String> getFileExtensions() {
return new HashSet<>(Arrays.asList("tschem"));
}
}

Datei anzeigen

@ -0,0 +1,84 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cuboid2;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import lombok.Getter;
import java.util.Map;
import java.util.Set;
@Getter
public class TypedClipboard implements Clipboard {
private Clipboard parent;
private Map<BlockState, Set<BlockVector3>> blocks;
public TypedClipboard(Clipboard parent, Map<BlockState, Set<BlockVector3>> blocks) {
this.parent = parent;
this.blocks = blocks;
}
@Override
public Region getRegion() {
return parent.getRegion();
}
@Override
public BlockVector3 getDimensions() {
return parent.getDimensions();
}
@Override
public BlockVector3 getOrigin() {
return parent.getOrigin();
}
@Override
public void setOrigin(BlockVector3 origin) {
parent.setOrigin(origin);
}
@Override
public void removeEntity(Entity entity) {
}
@Override
public BlockVector3 getMinimumPoint() {
return parent.getMinimumPoint();
}
@Override
public BlockVector3 getMaximumPoint() {
return parent.getMaximumPoint();
}
@Override
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
return false;
}
}

Datei anzeigen

@ -0,0 +1,80 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cuboid2;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@Linked
public class TypedCommand extends SWCommand {
static {
ClipboardFormats.registerClipboardFormat(new TSchemClipboardFormat());
}
public TypedCommand() {
super("typed");
}
@Register
public void test(Player player) {
Clipboard clipboard = WorldEditUtils.getClipboard(player);
if (clipboard == null) {
player.sendMessage("§cDu hast keine Schematic geladen!");
return;
}
long time = System.currentTimeMillis();
Map<BlockState, Set<BlockVector3>> blocks = new HashMap<>();
clipboard.getRegion().forEach(blockVector3 -> {
BlockVector3 position = blockVector3.subtract(clipboard.getMinimumPoint());
BlockState block = clipboard.getBlock(blockVector3);
blocks.computeIfAbsent(block, k -> new HashSet<>()).add(position);
});
TypedClipboard typedClipboard = new TypedClipboard(clipboard, blocks);
AtomicLong size = new AtomicLong();
try {
typedClipboard.save(new OutputStream() {
@Override
public void write(int b) throws IOException {
size.incrementAndGet();
}
}, ClipboardFormats.findByAlias("tschem"));
} catch (IOException e) {
}
long time2 = System.currentTimeMillis();
player.sendMessage("§aDie Größe der Schematic beträgt " + size.get() + " Bytes!");
player.sendMessage("§aTime: " + (time2 - time) + " ms");
}
}

Datei anzeigen

@ -0,0 +1,114 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cuboid2.io;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import de.steamwar.bausystem.features.cuboid2.TypedClipboard;
import java.io.IOException;
import java.util.*;
public class TSchemWriter implements ClipboardWriter {
private static final int CURRENT_VERSION = 1;
private final NBTOutputStream outputStream;
public TSchemWriter(NBTOutputStream outputStream) {
this.outputStream = outputStream;
}
@Override
public void write(Clipboard clipboard) throws IOException {
if (!(clipboard instanceof TypedClipboard)) {
return;
}
TypedClipboard typedClipboard = (TypedClipboard) clipboard;
Region region = clipboard.getRegion();
BlockVector3 origin = clipboard.getOrigin();
BlockVector3 min = region.getMinimumPoint();
BlockVector3 offset = min.subtract(origin);
int volume = (int) region.getVolume();
outputStream.writeLazyCompoundTag("Schematic", out -> {
out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion());
out.writeNamedTag("Version", CURRENT_VERSION);
List<Byte> bs = new ArrayList<>();
writeVarInt(region.getWidth(), bs);
writeVarInt(region.getHeight(), bs);
writeVarInt(region.getLength(), bs);
writeVarInt(min.getBlockX(), bs);
writeVarInt(min.getBlockY(), bs);
writeVarInt(min.getBlockZ(), bs);
writeVarInt(offset.getBlockX(), bs);
writeVarInt(offset.getBlockY(), bs);
writeVarInt(offset.getBlockZ(), bs);
byte[] bsArray = new byte[bs.size()];
for (int i = 0; i < bsArray.length; i++) {
bsArray[i] = bs.get(i);
}
out.writeNamedTag("SizeMinOffset", new ByteArrayTag(bsArray));
Map<BlockState, BitSet> blockMap = new HashMap<>();
typedClipboard.getBlocks().forEach((blockState, blockVector3s) -> {
blockMap.put(blockState, new BitSet(volume));
});
clipboard.getRegion().forEach(blockVector3 -> {
int index = blockVector3.getBlockX() + blockVector3.getBlockY() * region.getWidth() + blockVector3.getBlockZ() * region.getWidth() * region.getHeight();
for (Map.Entry<BlockState, Set<BlockVector3>> entry : typedClipboard.getBlocks().entrySet()) {
if (entry.getValue().contains(blockVector3)) {
blockMap.get(entry.getKey()).set(index);
}
}
});
out.writeLazyCompoundTag("Blocks", out2 -> {
for (Map.Entry<BlockState, BitSet> entry : blockMap.entrySet()) {
out2.writeNamedTag(entry.getKey().getAsString(), entry.getValue().toByteArray());
}
});
});
}
private static void writeVarInt(int value, List<Byte> bytes) {
while (true) {
if (value < 128) {
bytes.add((byte) value);
return;
} else {
bytes.add((byte) (value & 127 | 128));
value >>>= 7;
}
}
}
@Override
public void close() throws IOException {
outputStream.close();
}
}