Add Regional Reset History #211
@ -40,7 +40,7 @@ class Region_12 {
|
||||
private Region_12() {
|
||||
}
|
||||
|
||||
static void paste(File file, int x, int y, int z, boolean rotate) {
|
||||
static EditSession paste(File file, int x, int y, int z, boolean rotate) {
|
||||
World w = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||
Clipboard clipboard;
|
||||
try {
|
||||
@ -49,10 +49,10 @@ class Region_12 {
|
||||
throw new SecurityException("Bausystem schematic not found", e);
|
||||
}
|
||||
|
||||
paste(clipboard, x, y, z, rotate);
|
||||
return paste(clipboard, x, y, z, rotate);
|
||||
}
|
||||
|
||||
static void paste(Clipboard clipboard, int x, int y, int z, boolean rotate) {
|
||||
static EditSession paste(Clipboard clipboard, int x, int y, int z, boolean rotate) {
|
||||
World w = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||
|
||||
Vector dimensions = clipboard.getDimensions();
|
||||
@ -70,6 +70,6 @@ class Region_12 {
|
||||
ClipboardHolder ch = new ClipboardHolder(clipboard, w.getWorldData());
|
||||
ch.setTransform(aT);
|
||||
Operations.completeBlindly(ch.createPaste(e, w.getWorldData()).to(v).build());
|
||||
e.flushQueue();
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ package de.steamwar.bausystem.world;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
@ -29,14 +28,7 @@ import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import net.minecraft.server.v1_15_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -47,7 +39,7 @@ class Region_15 {
|
||||
private Region_15() {
|
||||
}
|
||||
|
||||
static void paste(File file, int x, int y, int z, boolean rotate) {
|
||||
static EditSession paste(File file, int x, int y, int z, boolean rotate) {
|
||||
Clipboard clipboard;
|
||||
try {
|
||||
clipboard = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file)).read();
|
||||
@ -55,10 +47,10 @@ class Region_15 {
|
||||
throw new SecurityException("Bausystem schematic not found", e);
|
||||
}
|
||||
|
||||
paste(clipboard, x, y, z, rotate);
|
||||
return paste(clipboard, x, y, z, rotate);
|
||||
|
||||
}
|
||||
|
||||
static void paste(Clipboard clipboard, int x, int y, int z, boolean rotate) {
|
||||
static EditSession paste(Clipboard clipboard, int x, int y, int z, boolean rotate) {
|
||||
BlockVector3 dimensions = clipboard.getDimensions();
|
||||
BlockVector3 v = BlockVector3.at(x, y, z);
|
||||
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||
@ -70,48 +62,11 @@ class Region_15 {
|
||||
v = v.subtract(dimensions.getX() / 2 - dimensions.getX() % 2, 0, dimensions.getZ() / 2 - dimensions.getZ() % 2).subtract(offset);
|
||||
}
|
||||
|
||||
EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1);
|
||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
||||
ClipboardHolder ch = new ClipboardHolder(clipboard);
|
||||
ch.setTransform(aT);
|
||||
Operations.completeBlindly(ch.createPaste(e).to(v).build());
|
||||
e.flushSession();
|
||||
}
|
||||
|
||||
static void fastpaste(File file, int x, int y, int z, boolean rotate) {
|
||||
Clipboard clipboard;
|
||||
try {
|
||||
clipboard = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file)).read();
|
||||
} catch (NullPointerException | IOException e) {
|
||||
throw new SecurityException("Bausystem schematic not found", e);
|
||||
}
|
||||
|
||||
BlockVector3 dimensions = clipboard.getDimensions();
|
||||
BlockVector3 v = BlockVector3.at(x, y, z);
|
||||
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||
if (rotate) {
|
||||
v = v.add(dimensions.getX() / 2 + dimensions.getX() % 2, 0, dimensions.getZ() / 2 + dimensions.getZ() % 2).subtract(offset.multiply(-1, 1, -1)).subtract(1, 0, 1);
|
||||
} else {
|
||||
v = v.subtract(dimensions.getX() / 2 - dimensions.getX() % 2, 0, dimensions.getZ() / 2 - dimensions.getZ() % 2).subtract(offset);
|
||||
}
|
||||
|
||||
WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
|
||||
v = v.add(offset);
|
||||
|
||||
for (int X = v.getBlockX(); X < v.getBlockX() + dimensions.getBlockX(); X++) {
|
||||
for (int Y = v.getBlockY(); Y < v.getBlockY() + dimensions.getBlockY(); Y++) {
|
||||
for (int Z = v.getBlockZ(); Z < v.getBlockZ() + dimensions.getBlockZ(); Z++) {
|
||||
BlockPosition blockPos = new BlockPosition(X, Y, Z);
|
||||
BaseBlock fullBlock = clipboard.getFullBlock(BlockVector3.at(X, Y, Z).subtract(v).add(clipboard.getRegion().getMinimumPoint()));
|
||||
BlockData replaceTo = BukkitAdapter.adapt(fullBlock);
|
||||
world.removeTileEntity(blockPos);
|
||||
if (replaceTo == null)
|
||||
world.setTypeAndData(blockPos, ((CraftBlockData) Material.AIR.createBlockData()).getState(), 1042);
|
||||
else
|
||||
world.setTypeAndData(new BlockPosition(X, Y, Z), ((CraftBlockData) replaceTo).getState(), 1042);
|
||||
|
||||
world.getChunkProvider().flagDirty(blockPos);
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
124
BauSystem_API/src/de/steamwar/bausystem/world/SizedStack.java
Normale Datei
124
BauSystem_API/src/de/steamwar/bausystem/world/SizedStack.java
Normale Datei
@ -0,0 +1,124 @@
|
||||
package de.steamwar.bausystem.world;
|
||||
|
||||
@SuppressWarnings({"unused", "UnusedReturnValue"})
|
||||
public class SizedStack<T> {
|
||||
|
||||
private int maxSize;
|
||||
private T[] data;
|
||||
private int size;
|
||||
private int head;
|
||||
|
||||
public SizedStack(int size) {
|
||||
this.maxSize = size;
|
||||
//noinspection unchecked
|
||||
this.data = (T[]) new Object[this.maxSize];
|
||||
this.head = 0;
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
public T push(final T element) {
|
||||
this.data[this.head] = element;
|
||||
this.increaseHead();
|
||||
this.increaseSize();
|
||||
return element;
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
this.decreaseHead();
|
||||
this.decreaseSize();
|
||||
final T result = this.data[this.head];
|
||||
this.data[this.head] = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public T peek() {
|
||||
return this.data[this.head];
|
||||
}
|
||||
|
||||
public boolean empty() {
|
||||
return this.size == 0;
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof SizedStack;
|
||||
}
|
||||
|
||||
private void increaseHead() {
|
||||
this.head++;
|
||||
while (this.head > this.maxSize - 1) {
|
||||
this.head -= this.maxSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void decreaseHead() {
|
||||
this.head--;
|
||||
while (this.head < 0) {
|
||||
this.head += this.maxSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void increaseSize() {
|
||||
if (this.size < this.maxSize) {
|
||||
this.size++;
|
||||
}
|
||||
}
|
||||
|
||||
private void decreaseSize() {
|
||||
if (this.size > 0) {
|
||||
this.size--;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
result = result * PRIME + this.maxSize;
|
||||
result = result * PRIME + this.toString().hashCode();
|
||||
result = result * PRIME + this.size;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SizedStack)) {
|
||||
return false;
|
||||
}
|
||||
final SizedStack<?> other = (SizedStack<?>) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (this.maxSize != other.maxSize) {
|
||||
return false;
|
||||
}
|
||||
if (this.size != other.size) {
|
||||
return false;
|
||||
}
|
||||
if (!this.data.getClass().equals(other.data.getClass())) {
|
||||
return false;
|
||||
}
|
||||
return this.toString().equals(other.toString());
|
||||
}
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder result = new StringBuilder("[");
|
||||
for (int i = 0; i < this.size - 1; i++) {
|
||||
result.append(this.data[(this.head - i - 1 < 0) ? (this.head - i - 1 + this.maxSize) : (this.head - i - 1)]).append(",");
|
||||
}
|
||||
result.append(this.data[(this.head - this.size < 0) ? (this.head - this.size + this.maxSize) : (this.head - this.size)]);
|
||||
result.append("]");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
@ -91,6 +91,7 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
new CommandRedstoneTester();
|
||||
new CommandGUI();
|
||||
new CommandWorldSpawn();
|
||||
new CommandRegion();
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, this);
|
||||
Bukkit.getPluginManager().registerEvents(new RegionListener(), this);
|
||||
|
73
BauSystem_Main/src/de/steamwar/bausystem/commands/CommandRegion.java
Normale Datei
73
BauSystem_Main/src/de/steamwar/bausystem/commands/CommandRegion.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
package de.steamwar.bausystem.commands;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.world.Region;
|
||||
import de.steamwar.bausystem.world.Welt;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CommandRegion extends SWCommand {
|
||||
|
||||
public CommandRegion() {
|
||||
super("region", "rg");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(Player player) {
|
||||
genericHelp(player);
|
||||
}
|
||||
|
||||
@Register(help = true)
|
||||
public void genericHelp(Player player, String... args) {
|
||||
player.sendMessage(BauSystem.PREFIX + "§8/§7region undo §8- §7Mache die letzten 10 /testblock oder /reset rückgängig");
|
||||
player.sendMessage(BauSystem.PREFIX + "§8/§7region redo §8- §7Wiederhohle die letzten 10 §8/§7rg undo");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void undoCommand(Player p, Action action) {
|
||||
if(!permissionCheck(p)) return;
|
||||
Region region = Region.getRegion(p.getLocation());
|
||||
if(checkGlobalRegion(region, p)) return;
|
||||
|
||||
switch (action) {
|
||||
case UNDO:
|
||||
if(region.undo()) {
|
||||
p.sendMessage(BauSystem.PREFIX + "Letzte Aktion rückgangig gemacht");
|
||||
} else {
|
||||
p.sendMessage(BauSystem.PREFIX + "§cNichts zum rückgängig machen");
|
||||
}
|
||||
break;
|
||||
case REDO:
|
||||
if(region.redo()) {
|
||||
p.sendMessage(BauSystem.PREFIX + "Letzte Aktion wiederhohlt");
|
||||
} else {
|
||||
p.sendMessage(BauSystem.PREFIX + "§cNichts zum wiederhohlen");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
genericHelp(p);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean checkGlobalRegion(Region region, Player p) {
|
||||
if(Region.GlobalRegion.isGlobalRegion(region)) {
|
||||
p.sendMessage(BauSystem.PREFIX + "§cDu bist in keiner Region");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean permissionCheck(Player player) {
|
||||
if (Welt.noPermission(player, Permission.worldedit)) {
|
||||
player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht die Region verändern");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
enum Action {
|
||||
UNDO,
|
||||
REDO
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ public class CommandReset extends SWCommand {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
region.reset(null);
|
||||
region.reset(schem);
|
||||
p.sendMessage(BauSystem.PREFIX + "§7Region zurückgesetzt");
|
||||
} catch (IOException e) {
|
||||
p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen der Region");
|
||||
|
@ -19,9 +19,10 @@
|
||||
|
||||
package de.steamwar.bausystem.world;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.bausystem.commands.CommandTNT.TNTMode;
|
||||
import de.steamwar.core.VersionedRunnable;
|
||||
import de.steamwar.core.VersionedCallable;
|
||||
import de.steamwar.sql.NoClipboardException;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -85,6 +86,8 @@ public class Region {
|
||||
private final Prototype prototype;
|
||||
private final String optionsLinkedWith; // nullable
|
||||
private Region linkedRegion = null; // nullable
|
||||
private SizedStack<EditSession> undosessions;
|
||||
private SizedStack<EditSession> redosessions;
|
||||
|
||||
private TNTMode tntMode = Region.buildAreaEnabled() ? TNTMode.ONLY_TB : TNTMode.OFF;
|
||||
private boolean freeze = false;
|
||||
@ -171,12 +174,14 @@ public class Region {
|
||||
return prototype.buildArea.inRegionExtension(this, l);
|
||||
}
|
||||
|
||||
public void fastreset() {
|
||||
prototype.fastreset(this);
|
||||
public void reset() throws IOException {
|
||||
initSessions();
|
||||
undosessions.push(prototype.reset(this, null));
|
||||
}
|
||||
|
||||
public void reset(Schematic schem) throws IOException, NoClipboardException {
|
||||
prototype.reset(this, schem);
|
||||
initSessions();
|
||||
undosessions.push(prototype.reset(this, schem));
|
||||
}
|
||||
|
||||
public boolean hasTestblock() {
|
||||
@ -184,7 +189,8 @@ public class Region {
|
||||
}
|
||||
|
||||
public void resetTestblock(Schematic schem) throws IOException, NoClipboardException {
|
||||
prototype.resetTestblock(this, schem);
|
||||
initSessions();
|
||||
undosessions.push(prototype.resetTestblock(this, schem));
|
||||
}
|
||||
|
||||
public boolean hasProtection() {
|
||||
@ -192,7 +198,8 @@ public class Region {
|
||||
}
|
||||
|
||||
public void protect(Schematic schem) throws IOException, NoClipboardException {
|
||||
prototype.protect(this, schem);
|
||||
initSessions();
|
||||
undosessions.push(prototype.protect(this, schem));
|
||||
}
|
||||
|
||||
public boolean hasExtensionAreaRegistered() {
|
||||
@ -203,6 +210,47 @@ public class Region {
|
||||
return prototype.testblock.extensionPrototypeArea;
|
||||
}
|
||||
|
||||
private void initSessions() {
|
||||
if(undosessions == null) {
|
||||
undosessions = new SizedStack<>(20);
|
||||
redosessions = new SizedStack<>(20);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean undo() {
|
||||
initSessions();
|
||||
EditSession session = null;
|
||||
try {
|
||||
session = undosessions.pop();
|
||||
if(session == null)
|
||||
return false;
|
||||
session.undo(session);
|
||||
redosessions.push(session);
|
||||
return true;
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.flushSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean redo() {
|
||||
initSessions();
|
||||
EditSession session = null;
|
||||
try {
|
||||
session = redosessions.pop();
|
||||
if(session == null)
|
||||
return false;
|
||||
session.redo(session);
|
||||
undosessions.push(session);
|
||||
return true;
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.flushSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class GlobalRegion extends Region {
|
||||
|
||||
private static final GlobalRegion GLOBAL_REGION = new GlobalRegion();
|
||||
@ -320,59 +368,50 @@ public class Region {
|
||||
inRange(l.getZ(), region.minZ + offsetZ - extensionNegativeZ + 1, sizeZ + extensionNegativeZ - 1 + extensionPositiveZ);
|
||||
}
|
||||
|
||||
public void fastreset(Region region) {
|
||||
File file = new File(schematic);
|
||||
int x = region.minX + offsetX + sizeX / 2;
|
||||
int y = region.minY + offsetY;
|
||||
int z = region.minZ + offsetZ + sizeZ / 2;
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> Region_12.paste(file, x, y, z, rotate), 8),
|
||||
new VersionedRunnable(() -> Region_15.fastpaste(file, x, y, z, rotate), 15));
|
||||
}
|
||||
|
||||
public void reset(Region region, Schematic schem) throws IOException, NoClipboardException {
|
||||
public EditSession reset(Region region, Schematic schem) throws IOException, NoClipboardException {
|
||||
int x = region.minX + offsetX + sizeX / 2;
|
||||
int y = region.minY + offsetY;
|
||||
int z = region.minZ + offsetZ + sizeZ / 2;
|
||||
if (schem == null)
|
||||
paste(new File(schematic), x, y, z, rotate);
|
||||
return paste(new File(schematic), x, y, z, rotate);
|
||||
else
|
||||
paste(schem.load(), x, y, z, rotate);
|
||||
return paste(schem.load(), x, y, z, rotate);
|
||||
}
|
||||
|
||||
public boolean hasProtection() {
|
||||
return protectSchematic != null;
|
||||
}
|
||||
|
||||
public void protect(Region region, Schematic schem) throws IOException, NoClipboardException {
|
||||
public EditSession protect(Region region, Schematic schem) throws IOException, NoClipboardException {
|
||||
int x = region.minX + offsetX + sizeX / 2;
|
||||
int y = region.minY + testblock.offsetY - 1;
|
||||
int z = region.minZ + offsetZ + sizeZ / 2;
|
||||
if (schem == null)
|
||||
paste(new File(protectSchematic), x, y, z, rotate);
|
||||
return paste(new File(protectSchematic), x, y, z, rotate);
|
||||
else
|
||||
paste(schem.load(), x, y, z, rotate);
|
||||
return paste(schem.load(), x, y, z, rotate);
|
||||
}
|
||||
|
||||
public boolean hasTestblock() {
|
||||
return testblock != null;
|
||||
}
|
||||
|
||||
public void resetTestblock(Region region, Schematic schem) throws IOException, NoClipboardException {
|
||||
testblock.reset(region, schem);
|
||||
public EditSession resetTestblock(Region region, Schematic schem) throws IOException, NoClipboardException {
|
||||
return testblock.reset(region, schem);
|
||||
}
|
||||
|
||||
private static boolean inRange(double l, int min, int size) {
|
||||
return min <= l && l <= min + size;
|
||||
}
|
||||
|
||||
private static void paste(File file, int x, int y, int z, boolean rotate) { //Type of protect
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> Region_12.paste(file, x, y, z, rotate), 8),
|
||||
new VersionedRunnable(() -> Region_15.paste(file, x, y, z, rotate), 15));
|
||||
private static EditSession paste(File file, int x, int y, int z, boolean rotate) { //Type of protect
|
||||
return (EditSession) VersionedCallable.call(new VersionedCallable(() -> Region_12.paste(file, x, y, z, rotate), 8),
|
||||
new VersionedCallable(() -> Region_15.paste(file, x, y, z, rotate), 15));
|
||||
}
|
||||
|
||||
private static void paste(Clipboard clipboard, int x, int y, int z, boolean rotate) {
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> Region_12.paste(clipboard, x, y, z, rotate), 8),
|
||||
new VersionedRunnable(() -> Region_15.paste(clipboard, x, y, z, rotate), 15));
|
||||
private static EditSession paste(Clipboard clipboard, int x, int y, int z, boolean rotate) {
|
||||
return (EditSession) VersionedCallable.call(new VersionedCallable(() -> Region_12.paste(clipboard, x, y, z, rotate), 8),
|
||||
new VersionedCallable(() -> Region_15.paste(clipboard, x, y, z, rotate), 15));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren
Was machst du mit dem fastreset? das muss auch da rein bzw du kannst es raus nehmen, wenn das WorldEdit fertig ist, weil das dann langsamer ist als WE.