diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TSchemClipboardFormat.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TSchemClipboardFormat.java
new file mode 100644
index 00000000..4ebbb95d
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TSchemClipboardFormat.java
@@ -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 .
+ */
+
+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 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 getFileExtensions() {
+ return new HashSet<>(Arrays.asList("tschem"));
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TypedClipboard.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TypedClipboard.java
new file mode 100644
index 00000000..72deea9d
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TypedClipboard.java
@@ -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 .
+ */
+
+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> blocks;
+
+ public TypedClipboard(Clipboard parent, Map> 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;
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TypedCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TypedCommand.java
new file mode 100644
index 00000000..dc251a1c
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/TypedCommand.java
@@ -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 .
+ */
+
+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> 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");
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/io/TSchemWriter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/io/TSchemWriter.java
new file mode 100644
index 00000000..5a901363
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/cuboid2/io/TSchemWriter.java
@@ -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 .
+ */
+
+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 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 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> entry : typedClipboard.getBlocks().entrySet()) {
+ if (entry.getValue().contains(blockVector3)) {
+ blockMap.get(entry.getKey()).set(index);
+ }
+ }
+ });
+ out.writeLazyCompoundTag("Blocks", out2 -> {
+ for (Map.Entry entry : blockMap.entrySet()) {
+ out2.writeNamedTag(entry.getKey().getAsString(), entry.getValue().toByteArray());
+ }
+ });
+ });
+ }
+
+ private static void writeVarInt(int value, List 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();
+ }
+}