Add completely new schematic format to reduce schematic size to about 7%
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
176ee5e0cf
Commit
42f8a044a4
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren