Commits vergleichen
9 Commits
master
...
BetterSche
Autor | SHA1 | Datum | |
---|---|---|---|
|
b17cd9acda | ||
|
42f8a044a4 | ||
|
176ee5e0cf | ||
|
fb4d803d92 | ||
|
c36e6f5d43 | ||
|
6fedbac3f9 | ||
|
7494b8abea | ||
|
3eeca6c349 | ||
|
91abbc25fc |
@ -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.cuboid;
|
||||
|
||||
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.cuboid.io.CSchemWriter;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class CSchemClipboardFormat implements ClipboardFormat {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "CSchem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAliases() {
|
||||
return new HashSet<>(Arrays.asList("cschem"));
|
||||
}
|
||||
|
||||
@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 CSchemWriter(new NBTOutputStream(new BufferedOutputStream(gzip)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
return file.getName().endsWith(".cschem");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "cschem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getFileExtensions() {
|
||||
return new HashSet<>(Arrays.asList("cschem"));
|
||||
}
|
||||
}
|
63
BauSystem_Main/src/de/steamwar/bausystem/features/cuboid/Cuboid.java
Normale Datei
63
BauSystem_Main/src/de/steamwar/bausystem/features/cuboid/Cuboid.java
Normale Datei
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
public class Cuboid {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int dx;
|
||||
int dy;
|
||||
int dz;
|
||||
private BlockState block;
|
||||
|
||||
public Cuboid(BlockVector3 origin, BlockState block) {
|
||||
this.x = origin.getBlockX();
|
||||
this.y = origin.getBlockY();
|
||||
this.z = origin.getBlockZ();
|
||||
|
||||
this.dx = 1;
|
||||
this.dy = 1;
|
||||
this.dz = 1;
|
||||
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public long size() {
|
||||
return (long) dx * (long) dy * (long) dz;
|
||||
}
|
||||
|
||||
public BlockVector3 getOrigin() {
|
||||
return BlockVector3.at(x, y, z);
|
||||
}
|
||||
|
||||
public BlockVector3 getSize() {
|
||||
return BlockVector3.at(dx, dy, dz);
|
||||
}
|
||||
|
||||
public BlockState getBlock() {
|
||||
return block;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public class CuboidClipboard implements Clipboard {
|
||||
|
||||
private Clipboard parent;
|
||||
private List<Cuboid> cuboids;
|
||||
private Map<BlockState, Integer> order;
|
||||
|
||||
public CuboidClipboard(Clipboard parent, List<Cuboid> cuboids, Map<BlockState, Integer> order) {
|
||||
this.parent = parent;
|
||||
this.cuboids = cuboids;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@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) {
|
||||
parent.removeEntity(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,95 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Linked
|
||||
public class CuboidCommand extends SWCommand {
|
||||
|
||||
static {
|
||||
ClipboardFormats.registerClipboardFormat(new CSchemClipboardFormat());
|
||||
}
|
||||
|
||||
public CuboidCommand() {
|
||||
super("cuboid");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void onCommand(Player player) {
|
||||
Clipboard clipboard = WorldEditUtils.getClipboard(player);
|
||||
if (clipboard == null) {
|
||||
player.sendMessage("§cDu hast keine Schematic geladen!");
|
||||
return;
|
||||
}
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
CuboidCreator4 cuboidCreator4 = new CuboidCreator4(clipboard);
|
||||
runAsync(cuboidCreator4, cuboids -> {
|
||||
long t2 = System.currentTimeMillis() - time;
|
||||
player.sendMessage("§aEs wurden " + cuboids.size() + " Cuboids erstellt!");
|
||||
player.sendMessage("§aDas hat " + t2 + "ms gedauert!");
|
||||
player.sendMessage("§aDas sind " + (cuboids.size() / (double) Math.max(t2, 1)) + " Cuboids/ms!");
|
||||
|
||||
CuboidClipboard cuboidClipboard = new CuboidClipboard(clipboard, cuboids, cuboidCreator4.applyOrder());
|
||||
AtomicLong size = new AtomicLong();
|
||||
try {
|
||||
cuboidClipboard.save(new OutputStream() {
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
size.incrementAndGet();
|
||||
}
|
||||
}, ClipboardFormats.findByAlias("cschem"));
|
||||
} catch (IOException e) {
|
||||
}
|
||||
player.sendMessage("§aDie Größe der Schematic beträgt " + size.get() + " Bytes!");
|
||||
});
|
||||
}
|
||||
|
||||
private <T> void runAsync(Iterator<T> iterator, Consumer<List<T>> result) {
|
||||
new BukkitRunnable() {
|
||||
private final List<T> list = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
iterator.forEachRemaining(list::add);
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
result.accept(list);
|
||||
}, 1);
|
||||
}
|
||||
}.runTaskAsynchronously(BauSystem.getInstance());
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CuboidCreator implements Iterator<Cuboid> {
|
||||
|
||||
private static final List<Axis[]> AXES = Arrays.asList(
|
||||
new Axis[]{Axis.X, Axis.Y, Axis.Z},
|
||||
new Axis[]{Axis.X, Axis.Z, Axis.Y},
|
||||
new Axis[]{Axis.Y, Axis.X, Axis.Z},
|
||||
new Axis[]{Axis.Y, Axis.Z, Axis.X},
|
||||
new Axis[]{Axis.Z, Axis.X, Axis.Y},
|
||||
new Axis[]{Axis.Z, Axis.Y, Axis.X}
|
||||
);
|
||||
|
||||
private Map<BlockVector3, BlockState> blocks = new HashMap<>();
|
||||
private Map<BlockState, Set<BlockVector3>> reverseBlocks = new HashMap<>();
|
||||
|
||||
private List<BlockVector3> left = new ArrayList<>();
|
||||
|
||||
public CuboidCreator(Clipboard clipboard) {
|
||||
clipboard.getRegion().forEach(blockVector3 -> {
|
||||
BlockVector3 position = blockVector3.subtract(clipboard.getMinimumPoint());
|
||||
BlockState block = clipboard.getBlock(blockVector3);
|
||||
blocks.put(position, block);
|
||||
reverseBlocks.computeIfAbsent(block, k -> new HashSet<>()).add(position);
|
||||
});
|
||||
|
||||
left.add(BlockVector3.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
left.removeIf(blockVector3 -> !blocks.containsKey(blockVector3));
|
||||
return !left.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cuboid next() {
|
||||
BlockVector3 origin = left.get(0);
|
||||
BlockState block = blocks.get(origin);
|
||||
|
||||
Cuboid cuboid = null;
|
||||
for (Axis[] axes : AXES) {
|
||||
Cuboid currentCuboid = new Cuboid(origin, block);
|
||||
expand(currentCuboid, new ArrayList<>(Arrays.asList(axes)));
|
||||
if (cuboid == null || cuboid.size() < currentCuboid.size()) {
|
||||
cuboid = currentCuboid;
|
||||
}
|
||||
}
|
||||
|
||||
Set<BlockVector3> cuboidBlocks = reverseBlocks.get(block);
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
BlockVector3 pos = BlockVector3.at(x, y, z);
|
||||
cuboidBlocks.remove(pos);
|
||||
blocks.remove(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
left.add(BlockVector3.at(origin.getBlockX() + cuboid.dx, origin.getBlockY(), origin.getBlockZ()));
|
||||
left.add(BlockVector3.at(origin.getBlockX(), origin.getBlockY() + cuboid.dy, origin.getBlockZ()));
|
||||
left.add(BlockVector3.at(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ() + cuboid.dz));
|
||||
return cuboid;
|
||||
}
|
||||
|
||||
private void expand(Cuboid cuboid, List<Axis> axes) {
|
||||
while (!axes.isEmpty()) {
|
||||
axes.removeIf(axis -> {
|
||||
org.bukkit.util.Vector direction = new Vector();
|
||||
switch (axis) {
|
||||
case X:
|
||||
direction.setX(1);
|
||||
break;
|
||||
case Y:
|
||||
direction.setY(1);
|
||||
break;
|
||||
case Z:
|
||||
direction.setZ(1);
|
||||
break;
|
||||
}
|
||||
return !expand(cuboid, direction);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean expand(Cuboid cuboid, Vector direction) {
|
||||
Set<BlockVector3> blocks = reverseBlocks.get(cuboid.getBlock());
|
||||
if (direction.getX() == 1) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
if (!blocks.contains(BlockVector3.at(cuboid.x + cuboid.dx, y, z))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getY() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
if (!blocks.contains(BlockVector3.at(x, cuboid.y + cuboid.dy, z))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getZ() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
if (!blocks.contains(BlockVector3.at(x, y, cuboid.z + cuboid.dz))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (direction.getX() == 1) {
|
||||
cuboid.dx++;
|
||||
} else if (direction.getY() == 1) {
|
||||
cuboid.dy++;
|
||||
} else if (direction.getZ() == 1) {
|
||||
cuboid.dz++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CuboidCreator2 implements Iterator<Cuboid> {
|
||||
|
||||
private static final List<Axis[]> AXES = Arrays.asList(
|
||||
new Axis[]{Axis.X, Axis.Y, Axis.Z},
|
||||
new Axis[]{Axis.X, Axis.Z, Axis.Y},
|
||||
new Axis[]{Axis.Y, Axis.X, Axis.Z},
|
||||
new Axis[]{Axis.Y, Axis.Z, Axis.X},
|
||||
new Axis[]{Axis.Z, Axis.X, Axis.Y},
|
||||
new Axis[]{Axis.Z, Axis.Y, Axis.X}
|
||||
);
|
||||
|
||||
private Map<BlockState, Set<BlockVector3>> reverseBlocks = new HashMap<>();
|
||||
|
||||
public CuboidCreator2(Clipboard clipboard) {
|
||||
clipboard.getRegion().forEach(blockVector3 -> {
|
||||
BlockVector3 position = blockVector3.subtract(clipboard.getMinimumPoint());
|
||||
BlockState block = clipboard.getBlock(blockVector3);
|
||||
reverseBlocks.computeIfAbsent(block, k -> new HashSet<>()).add(position);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !reverseBlocks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cuboid next() {
|
||||
Cuboid cuboid = null;
|
||||
BlockState toRemove = null;
|
||||
for (Map.Entry<BlockState, Set<BlockVector3>> entry : reverseBlocks.entrySet()) {
|
||||
BlockState block = entry.getKey();
|
||||
Set<BlockVector3> positions = entry.getValue();
|
||||
|
||||
for (BlockVector3 position : positions) {
|
||||
for (Axis[] axes : AXES) {
|
||||
Cuboid currentCuboid = new Cuboid(position, block);
|
||||
expand(currentCuboid, new ArrayList<>(Arrays.asList(axes)), entry.getValue());
|
||||
if (cuboid == null || cuboid.size() < currentCuboid.size()) {
|
||||
cuboid = currentCuboid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
positions.remove(BlockVector3.at(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (positions.isEmpty()) {
|
||||
toRemove = block;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (toRemove != null) {
|
||||
reverseBlocks.remove(toRemove);
|
||||
}
|
||||
return cuboid;
|
||||
}
|
||||
|
||||
private void expand(Cuboid cuboid, List<Axis> axes, Set<BlockVector3> blocks) {
|
||||
while (!axes.isEmpty()) {
|
||||
axes.removeIf(axis -> {
|
||||
org.bukkit.util.Vector direction = new org.bukkit.util.Vector();
|
||||
switch (axis) {
|
||||
case X:
|
||||
direction.setX(1);
|
||||
break;
|
||||
case Y:
|
||||
direction.setY(1);
|
||||
break;
|
||||
case Z:
|
||||
direction.setZ(1);
|
||||
break;
|
||||
}
|
||||
return !expand(cuboid, direction, blocks);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean expand(Cuboid cuboid, Vector direction, Set<BlockVector3> blocks) {
|
||||
if (direction.getX() == 1) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
if (!blocks.contains(BlockVector3.at(cuboid.x + cuboid.dx, y, z))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getY() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
if (!blocks.contains(BlockVector3.at(x, cuboid.y + cuboid.dy, z))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getZ() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
if (!blocks.contains(BlockVector3.at(x, y, cuboid.z + cuboid.dz))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (direction.getX() == 1) {
|
||||
cuboid.dx++;
|
||||
} else if (direction.getY() == 1) {
|
||||
cuboid.dy++;
|
||||
} else if (direction.getZ() == 1) {
|
||||
cuboid.dz++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CuboidCreator3 implements Iterator<Cuboid> {
|
||||
|
||||
private static final List<Axis[]> AXES = Arrays.asList(
|
||||
new Axis[]{Axis.X, Axis.Y, Axis.Z},
|
||||
new Axis[]{Axis.X, Axis.Z, Axis.Y},
|
||||
new Axis[]{Axis.Y, Axis.X, Axis.Z},
|
||||
new Axis[]{Axis.Y, Axis.Z, Axis.X},
|
||||
new Axis[]{Axis.Z, Axis.X, Axis.Y},
|
||||
new Axis[]{Axis.Z, Axis.Y, Axis.X}
|
||||
);
|
||||
|
||||
private static final Set<String> invisible = new HashSet<>();
|
||||
static {
|
||||
for (Material value : Material.values()) {
|
||||
if (!value.isOccluding() || value.isAir()) {
|
||||
invisible.add("minecraft:" + value.name().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Set<BlockVector3> invisibleBlocks = new HashSet<>();
|
||||
private Map<BlockState, Set<BlockVector3>> reverseBlocks = new HashMap<>();
|
||||
|
||||
public CuboidCreator3(Clipboard clipboard) {
|
||||
clipboard.getRegion().forEach(blockVector3 -> {
|
||||
BlockVector3 position = blockVector3.subtract(clipboard.getMinimumPoint());
|
||||
BlockState block = clipboard.getBlock(blockVector3);
|
||||
if (block.getAsString().startsWith("minecraft:redstone_wire") && !block.getAsString().equals("minecraft:redstone_wire[east=none,north=none,power=0,south=none,west=none]")) {
|
||||
block = BlockState.get("minecraft:redstone_wire[east=side,north=side,power=0,south=side,west=side]");
|
||||
}
|
||||
reverseBlocks.computeIfAbsent(block, k -> new HashSet<>()).add(position);
|
||||
if (invisible.contains(block.getBlockType().getId())) {
|
||||
invisibleBlocks.add(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !reverseBlocks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cuboid next() {
|
||||
Cuboid cuboid = null;
|
||||
BlockState toRemove = null;
|
||||
for (Map.Entry<BlockState, Set<BlockVector3>> entry : reverseBlocks.entrySet()) {
|
||||
BlockState block = entry.getKey();
|
||||
Set<BlockVector3> positions = entry.getValue();
|
||||
|
||||
for (BlockVector3 position : positions) {
|
||||
for (Axis[] axes : AXES) {
|
||||
Cuboid currentCuboid = new Cuboid(position, block);
|
||||
expand(currentCuboid, new ArrayList<>(Arrays.asList(axes)), entry.getValue());
|
||||
if (cuboid == null || cuboid.size() < currentCuboid.size()) {
|
||||
cuboid = currentCuboid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
positions.remove(BlockVector3.at(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (positions.isEmpty()) {
|
||||
toRemove = block;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (toRemove != null) {
|
||||
reverseBlocks.remove(toRemove);
|
||||
}
|
||||
return cuboid;
|
||||
}
|
||||
|
||||
private void expand(Cuboid cuboid, List<Axis> axes, Set<BlockVector3> blocks) {
|
||||
while (!axes.isEmpty()) {
|
||||
axes.removeIf(axis -> {
|
||||
Vector direction = new Vector();
|
||||
switch (axis) {
|
||||
case X:
|
||||
direction.setX(1);
|
||||
break;
|
||||
case Y:
|
||||
direction.setY(1);
|
||||
break;
|
||||
case Z:
|
||||
direction.setZ(1);
|
||||
break;
|
||||
}
|
||||
return !expand(cuboid, direction, blocks);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean expand(Cuboid cuboid, Vector direction, Set<BlockVector3> blocks) {
|
||||
boolean selfInvisible = invisibleBlocks.contains(BlockVector3.at(cuboid.x, cuboid.y, cuboid.z));
|
||||
if (direction.getX() == 1) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
BlockVector3 pos = BlockVector3.at(cuboid.x + cuboid.dx, y, z);
|
||||
if (!blocks.contains(pos) && (!invisibleBlocks.contains(pos) || selfInvisible)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getY() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
BlockVector3 pos = BlockVector3.at(x, cuboid.y + cuboid.dy, z);
|
||||
if (!blocks.contains(pos) && (!invisibleBlocks.contains(pos) || selfInvisible)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getZ() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
BlockVector3 pos = BlockVector3.at(x, y, cuboid.z + cuboid.dz);
|
||||
if (!blocks.contains(pos) && (!invisibleBlocks.contains(pos) || selfInvisible)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (direction.getX() == 1) {
|
||||
cuboid.dx++;
|
||||
} else if (direction.getY() == 1) {
|
||||
cuboid.dy++;
|
||||
} else if (direction.getZ() == 1) {
|
||||
cuboid.dz++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.cuboid;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CuboidCreator4 implements Iterator<Cuboid> {
|
||||
|
||||
private static final List<Axis[]> AXES = Arrays.asList(
|
||||
new Axis[]{Axis.X, Axis.Z, Axis.Y},
|
||||
new Axis[]{Axis.Z, Axis.X, Axis.Y}
|
||||
);
|
||||
|
||||
private List<BlockState> invisibleOrder = new ArrayList<>();
|
||||
private Map<BlockState, Set<BlockState>> invisible = new HashMap<>();
|
||||
|
||||
private Map<BlockVector3, BlockState> blocks = new HashMap<>();
|
||||
private Map<BlockState, Set<BlockVector3>> reverseBlocks = new HashMap<>();
|
||||
|
||||
public CuboidCreator4(Clipboard clipboard) {
|
||||
clipboard.getRegion().forEach(blockVector3 -> {
|
||||
BlockVector3 position = blockVector3.subtract(clipboard.getMinimumPoint());
|
||||
BlockState block = clipboard.getBlock(blockVector3);
|
||||
blocks.put(position, block);
|
||||
reverseBlocks.computeIfAbsent(block, k -> new HashSet<>()).add(position);
|
||||
});
|
||||
invisibleOrder.addAll(reverseBlocks.keySet());
|
||||
invisibleOrder.sort(Comparator.comparingInt(o -> -reverseBlocks.get(o).size()));
|
||||
invisibleOrder.remove(BlockState.get("minecraft:air"));
|
||||
invisibleOrder.add(BlockState.get("minecraft:air"));
|
||||
for (int i = 0; i < invisibleOrder.size(); i++) {
|
||||
BlockState block = invisibleOrder.get(i);
|
||||
for (int j = i + 1; j < invisibleOrder.size(); j++) {
|
||||
invisible.computeIfAbsent(block, k -> new HashSet<>()).add(invisibleOrder.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<BlockState, Integer> applyOrder() {
|
||||
Map<BlockState, Integer> order = new HashMap<>();
|
||||
for (int i = 0; i < invisibleOrder.size(); i++) {
|
||||
order.put(invisibleOrder.get(i), i);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !reverseBlocks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cuboid next() {
|
||||
Cuboid cuboid = null;
|
||||
BlockState toRemove = null;
|
||||
for (Map.Entry<BlockState, Set<BlockVector3>> entry : reverseBlocks.entrySet()) {
|
||||
BlockState block = entry.getKey();
|
||||
List<BlockVector3> positions = new ArrayList<>(entry.getValue());
|
||||
|
||||
for (int i = 0; i < positions.size(); i++) {
|
||||
BlockVector3 position = positions.get(i);
|
||||
for (Axis[] axes : AXES) {
|
||||
Cuboid currentCuboid = new Cuboid(position, block);
|
||||
expand(currentCuboid, new ArrayList<>(Arrays.asList(axes)), entry.getValue());
|
||||
if (cuboid == null || cuboid.size() < currentCuboid.size()) {
|
||||
cuboid = currentCuboid;
|
||||
if (cuboid.size() >= positions.size() * 0.5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cuboid.size() >= positions.size() * 0.5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
entry.getValue().remove(BlockVector3.at(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entry.getValue().isEmpty()) {
|
||||
toRemove = block;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (toRemove != null) {
|
||||
reverseBlocks.remove(toRemove);
|
||||
}
|
||||
return cuboid;
|
||||
}
|
||||
|
||||
private void expand(Cuboid cuboid, List<Axis> axes, Set<BlockVector3> blocks) {
|
||||
while (!axes.isEmpty()) {
|
||||
axes.removeIf(axis -> {
|
||||
Vector direction = new Vector();
|
||||
switch (axis) {
|
||||
case X:
|
||||
direction.setX(1);
|
||||
break;
|
||||
case Y:
|
||||
direction.setY(1);
|
||||
break;
|
||||
case Z:
|
||||
direction.setZ(1);
|
||||
break;
|
||||
}
|
||||
return !expand(cuboid, direction, blocks);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean expand(Cuboid cuboid, Vector direction, Set<BlockVector3> blocks) {
|
||||
Set<BlockState> invisible = this.invisible.getOrDefault(cuboid.getBlock(), new HashSet<>());
|
||||
if (direction.getX() == 1) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
BlockVector3 pos = BlockVector3.at(cuboid.x + cuboid.dx, y, z);
|
||||
if (!blocks.contains(pos) && !invisible.contains(this.blocks.get(pos))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getY() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
|
||||
BlockVector3 pos = BlockVector3.at(x, cuboid.y + cuboid.dy, z);
|
||||
if (!blocks.contains(pos) && !invisible.contains(this.blocks.get(pos))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (direction.getZ() == 1) {
|
||||
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
|
||||
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
|
||||
BlockVector3 pos = BlockVector3.at(x, y, cuboid.z + cuboid.dz);
|
||||
if (!blocks.contains(pos) && !invisible.contains(this.blocks.get(pos))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (direction.getX() == 1) {
|
||||
cuboid.dx++;
|
||||
} else if (direction.getY() == 1) {
|
||||
cuboid.dy++;
|
||||
} else if (direction.getZ() == 1) {
|
||||
cuboid.dz++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.cuboid.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.cuboid.Cuboid;
|
||||
import de.steamwar.bausystem.features.cuboid.CuboidClipboard;
|
||||
import de.steamwar.bausystem.features.cuboid.CuboidCreator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class CSchemWriter implements ClipboardWriter {
|
||||
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
private final NBTOutputStream outputStream;
|
||||
|
||||
public CSchemWriter(NBTOutputStream outputStream) {
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Clipboard clipboard) throws IOException {
|
||||
if (!(clipboard instanceof CuboidClipboard)) {
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
new CuboidCreator(clipboard).forEachRemaining(cuboidList::add);
|
||||
clipboard = new CuboidClipboard(clipboard, cuboidList, new HashMap<>());
|
||||
}
|
||||
CuboidClipboard cuboidClipboard = (CuboidClipboard) clipboard;
|
||||
|
||||
Region region = clipboard.getRegion();
|
||||
BlockVector3 origin = clipboard.getOrigin();
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
BlockVector3 offset = min.subtract(origin);
|
||||
|
||||
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));
|
||||
|
||||
List<Cuboid> cuboids = cuboidClipboard.getCuboids();
|
||||
Map<BlockState, List<Cuboid>> cuboidMap = new HashMap<>();
|
||||
for (Cuboid cuboid : cuboids) {
|
||||
cuboidMap.computeIfAbsent(cuboid.getBlock(), k -> new ArrayList<>()).add(cuboid);
|
||||
}
|
||||
|
||||
out.writeLazyCompoundTag("Cuboids", out1 -> {
|
||||
BlockState mostBytes = null;
|
||||
int mostBytesSize = 0;
|
||||
|
||||
Map<BlockState, byte[]> cuboidBytes = new HashMap<>();
|
||||
for (Map.Entry<BlockState, List<Cuboid>> entry : cuboidMap.entrySet()) {
|
||||
List<Byte> bytes = new ArrayList<>();
|
||||
writeVarInt(cuboidClipboard.getOrder().getOrDefault(entry.getKey(), 0), bytes);
|
||||
for (Cuboid cuboid : entry.getValue()) {
|
||||
writeVarInt(cuboid.getOrigin().getBlockX(), bytes);
|
||||
writeVarInt(cuboid.getOrigin().getBlockY(), bytes);
|
||||
writeVarInt(cuboid.getOrigin().getBlockZ(), bytes);
|
||||
if (cuboid.getSize().equals(BlockVector3.ONE)) {
|
||||
writeVarInt(0, bytes);
|
||||
} else if (cuboid.getSize().getBlockX() == cuboid.getSize().getBlockY() && cuboid.getSize().getBlockX() == cuboid.getSize().getBlockZ()) {
|
||||
writeVarInt(cuboid.getSize().getBlockX(), bytes);
|
||||
writeVarInt(0, bytes);
|
||||
} else {
|
||||
writeVarInt(cuboid.getSize().getBlockX(), bytes);
|
||||
writeVarInt(cuboid.getSize().getBlockY(), bytes);
|
||||
writeVarInt(cuboid.getSize().getBlockZ(), bytes);
|
||||
}
|
||||
}
|
||||
byte[] bytesArray = new byte[bytes.size()];
|
||||
for (int i = 0; i < bytesArray.length; i++) {
|
||||
bytesArray[i] = bytes.get(i);
|
||||
}
|
||||
cuboidBytes.put(entry.getKey(), bytesArray);
|
||||
|
||||
if (mostBytes == null || bytesArray.length > mostBytesSize) {
|
||||
mostBytes = entry.getKey();
|
||||
mostBytesSize = bytesArray.length;
|
||||
}
|
||||
}
|
||||
System.out.println("Most bytes: " + mostBytes.getAsString() + " (" + mostBytesSize + " bytes)");
|
||||
cuboidBytes.remove(mostBytes);
|
||||
out1.writeNamedTag("BASE", mostBytes.getAsString());
|
||||
for (Map.Entry<BlockState, byte[]> entry : cuboidBytes.entrySet()) {
|
||||
out1.writeLazyCompoundTag(entry.getKey().getAsString().substring(10), out2 -> {
|
||||
out2.writeTagPayload(new ByteArrayTag(entry.getValue()));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -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,152 @@
|
||||
/*
|
||||
* 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, byte[]> blocks = new HashMap<>();
|
||||
for (Map.Entry<BlockState, Set<BlockVector3>> entry : typedClipboard.getBlocks().entrySet()) {
|
||||
BitSet bitSet = new BitSet(volume);
|
||||
for (BlockVector3 blockVector3 : entry.getValue()) {
|
||||
int index = blockVector3.getBlockX() + blockVector3.getBlockY() * region.getWidth() + blockVector3.getBlockZ() * region.getWidth() * region.getHeight();
|
||||
bitSet.set(index);
|
||||
}
|
||||
byte[] bytes = bitSet.toByteArray();
|
||||
// RunLengthEncoding
|
||||
List<Byte> bytes2 = new ArrayList<>();
|
||||
int last = -1;
|
||||
int count = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
byte b = bytes[i];
|
||||
if (b == last) {
|
||||
count++;
|
||||
} else {
|
||||
if (count > 0) {
|
||||
writeVarInt((count - 1), bytes2);
|
||||
bytes2.add((byte) last);
|
||||
}
|
||||
last = b;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
writeVarInt((count - 1), bytes2);
|
||||
bytes2.add((byte) last);
|
||||
}
|
||||
// Convert to byte array
|
||||
bytes = new byte[bytes2.size()];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = bytes2.get(i);
|
||||
}
|
||||
System.out.println(entry.getKey().getAsString() + " " + bitSet.toByteArray().length + " -> " + bytes2.size());
|
||||
blocks.put(entry.getKey(), bytes);
|
||||
}
|
||||
|
||||
BlockState biggest = null;
|
||||
int biggestSize = 0;
|
||||
for (Map.Entry<BlockState, byte[]> entry : blocks.entrySet()) {
|
||||
if (entry.getValue().length > biggestSize) {
|
||||
biggest = entry.getKey();
|
||||
biggestSize = entry.getValue().length;
|
||||
}
|
||||
}
|
||||
System.out.println("Biggest: " + biggest.getAsString() + " " + biggestSize);
|
||||
blocks.remove(biggest);
|
||||
out.writeNamedTag("BaseBlock", biggest.getAsString());
|
||||
|
||||
out.writeLazyCompoundTag("Blocks", out2 -> {
|
||||
for (Map.Entry<BlockState, byte[]> entry : blocks.entrySet()) {
|
||||
out2.writeNamedTag(entry.getKey().getAsString(), entry.getValue());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -20,10 +20,12 @@
|
||||
package de.steamwar.bausystem.utils;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.extension.factory.PatternFactory;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
@ -95,4 +97,16 @@ public class WorldEditUtils {
|
||||
private Location adapt(World world, BlockVector3 blockVector3) {
|
||||
return new Location(world, blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ());
|
||||
}
|
||||
|
||||
public Clipboard getClipboard(Player player) {
|
||||
try {
|
||||
return WorldEdit.getInstance()
|
||||
.getSessionManager()
|
||||
.get(BukkitAdapter.adapt(player))
|
||||
.getClipboard()
|
||||
.getClipboard();
|
||||
} catch (EmptyClipboardException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren