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