Plex-FAWE/worldedit-core/src/main/java/com/boydti/fawe/command/Rollback.java
Jesse Boyd a629d15c74
Copy paste/merge FAWE classes to this WorldEdit fork
- so certain people can look at the diff and complain about my sloppy code :(

Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
2018-08-13 00:03:07 +10:00

201 lines
8.8 KiB
Java

package com.boydti.fawe.command;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FaweLocation;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class Rollback extends FaweCommand {
public Rollback() {
super("fawe.rollback");
}
@Override
public boolean execute(final FawePlayer player, final String... args) {
if (!Settings.IMP.HISTORY.USE_DATABASE) {
BBC.SETTING_DISABLE.send(player, "history.use-database (Import with /frb #import )");
return false;
}
if (args.length != 3) {
BBC.COMMAND_SYNTAX.send(player, "/frb u:<uuid> r:<radius> t:<time>");
return false;
}
switch (args[0]) {
case "i":
case "info":
case "undo":
case "revert":
BBC.COMMAND_SYNTAX.send(player, "/frb u:<uuid> r:<radius> t:<time>");
return false;
}
if (args.length < 1) {
BBC.COMMAND_SYNTAX.send(player, "/frb <info|undo> u:<uuid> r:<radius> t:<time>");
return false;
}
World world = player.getWorld();
switch (args[0]) {
default: {
BBC.COMMAND_SYNTAX.send(player, "/frb info u:<uuid> r:<radius> t:<time>");
return false;
}
case "i":
case "info": {
if (args.length < 2) {
BBC.COMMAND_SYNTAX.send(player, "/frb <info|undo> u:<uuid> r:<radius> t:<time>");
return false;
}
player.deleteMeta(FawePlayer.METADATA_KEYS.ROLLBACK);
final FaweLocation origin = player.getLocation();
rollback(player, !player.hasPermission("fawe.rollback.deep"), Arrays.copyOfRange(args, 1, args.length), new RunnableVal<List<DiskStorageHistory>>() {
@Override
public void run(List<DiskStorageHistory> edits) {
long total = 0;
player.sendMessage("&d=| Username | Bounds | Distance | Changes | Age |=");
for (DiskStorageHistory edit : edits) {
DiskStorageHistory.DiskStorageSummary summary = edit.summarize(new RegionWrapper(origin.x, origin.x, origin.z, origin.z), !player.hasPermission("fawe.rollback.deep"));
RegionWrapper region = new RegionWrapper(summary.minX, summary.maxX, summary.minZ, summary.maxZ);
int distance = region.distance(origin.x, origin.z);
String name = Fawe.imp().getName(edit.getUUID());
long seconds = (System.currentTimeMillis() - edit.getBDFile().lastModified()) / 1000;
total += edit.getBDFile().length();
int size = summary.getSize();
Map<Integer, Double> percents = summary.getPercents();
StringBuilder percentString = new StringBuilder();
String prefix = "";
for (Map.Entry<Integer, Double> entry : percents.entrySet()) {
int id = entry.getKey();
BlockStateHolder state = null;
try {
state = BlockState.get(id);
} catch (Throwable ignore) {};
String itemName = state == null ? "#" + id : state.getAsString();
percentString.append(prefix).append(entry.getValue()).append("% ").append(itemName);
prefix = ", ";
}
player.sendMessage("&c" + name + " | " + region + " | " + distance + "m | " + size + " | " + MainUtil.secToTime(seconds));
player.sendMessage("&8 - &7(" + percentString + ")");
}
player.sendMessage("&d==================================================");
player.sendMessage("&dSize: " + (((double) (total / 1024)) / 1000) + "MB");
player.sendMessage("&dTo rollback: /frb undo");
player.sendMessage("&d==================================================");
player.setMeta(FawePlayer.METADATA_KEYS.ROLLBACK, edits);
}
});
break;
}
case "undo":
case "revert": {
if (!player.hasPermission("fawe.rollback.perform")) {
BBC.NO_PERM.send(player, "fawe.rollback.perform");
return false;
}
final List<DiskStorageHistory> edits = (List<DiskStorageHistory>) player.getMeta(FawePlayer.METADATA_KEYS.ROLLBACK);
player.deleteMeta(FawePlayer.METADATA_KEYS.ROLLBACK);
if (edits == null) {
BBC.COMMAND_SYNTAX.send(player, "/frb info u:<uuid> r:<radius> t:<time>");
return false;
}
final Runnable task = new Runnable() {
@Override
public void run() {
if (edits.size() == 0) {
player.sendMessage("Rollback complete!");
return;
}
DiskStorageHistory edit = edits.remove(0);
player.sendMessage("&d" + edit.getBDFile());
EditSession session = edit.toEditSession(null);
session.undo(session);
edit.deleteFiles();
session.getQueue().addNotifyTask(this);
}
};
task.run();
}
}
return true;
}
public void rollback(final FawePlayer player, final boolean shallow, final String[] args, final RunnableVal<List<DiskStorageHistory>> result) {
UUID user = null;
int radius = Integer.MAX_VALUE;
long time = Long.MAX_VALUE;
for (int i = 0; i < args.length; i++) {
String[] split = args[i].split(":");
if (split.length != 2) {
BBC.COMMAND_SYNTAX.send(player, "/frb <info|undo> u:<uuid> r:<radius> t:<time>");
return;
}
switch (split[0].toLowerCase()) {
case "username":
case "user":
case "u": {
try {
if (split[1].length() > 16) {
user = UUID.fromString(split[1]);
} else {
user = Fawe.imp().getUUID(split[1]);
}
} catch (IllegalArgumentException e) {
}
if (user == null) {
player.sendMessage("&dInvalid user: " + split[1]);
return;
}
break;
}
case "r":
case "radius": {
if (!MathMan.isInteger(split[1])) {
player.sendMessage("&dInvalid radius: " + split[1]);
return;
}
radius = Integer.parseInt(split[1]);
break;
}
case "t":
case "time": {
time = MainUtil.timeToSec(split[1]) * 1000;
break;
}
default: {
BBC.COMMAND_SYNTAX.send(player, "/frb <info|undo> u:<uuid> r:<radius> t:<time>");
return;
}
}
}
FaweLocation origin = player.getLocation();
List<DiskStorageHistory> edits = FaweAPI.getBDFiles(origin, user, radius, time, shallow);
if (edits == null) {
player.sendMessage("&cToo broad, try refining your search!");
return;
}
if (edits.size() == 0) {
player.sendMessage("&cNo edits found!");
return;
}
result.run(edits);
}
}