Added inventory rollback support for online players

This commit is contained in:
Intelli 2022-02-11 21:45:33 -07:00
parent 29d55e6ba9
commit a2353afd0a
13 changed files with 230 additions and 60 deletions

View File

@ -612,7 +612,7 @@ public class LookupCommand {
}
if (rollbackusers.contains("#container")) {
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10)) {
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10) || argAction.contains(11)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_USERNAME, "#container"));
return;
}

View File

@ -151,7 +151,7 @@ public class RollbackRestoreCommand {
final int finalAction = a;
int DEFAULT_RADIUS = Config.getGlobal().DEFAULT_RADIUS;
if ((player instanceof Player || player instanceof BlockCommandSender) && argRadius == null && DEFAULT_RADIUS > 0 && !forceglobal) {
if ((player instanceof Player || player instanceof BlockCommandSender) && argRadius == null && DEFAULT_RADIUS > 0 && !forceglobal && !argAction.contains(11)) {
Location location = lo;
int xmin = location.getBlockX() - DEFAULT_RADIUS;
int xmax = location.getBlockX() + DEFAULT_RADIUS;
@ -195,11 +195,11 @@ public class RollbackRestoreCommand {
return;
}
else if (preview > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CONTAINER));
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_TRANSACTION, !argAction.contains(11) ? Selector.FIRST : Selector.SECOND));
return;
}
}
if (argAction.contains(8) || argAction.contains(11) || (!argAction.contains(0) && !argAction.contains(1) && !argAction.contains(3) && !argAction.contains(4))) {
if (argAction.contains(8) || (argAction.contains(11) && !argAction.contains(4)) || (!argAction.contains(0) && !argAction.contains(1) && !argAction.contains(3) && !argAction.contains(4))) {
if (finalAction == 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
}
@ -210,7 +210,7 @@ public class RollbackRestoreCommand {
}
}
if (argAction.contains(4) && argAction.contains(11)) { // a:inventory
if (argAction.contains(4) && argAction.contains(11) && !argExcludeUsers.contains("#hopper")) { // a:inventory
argExcludeUsers.add("#hopper");
}
@ -220,13 +220,22 @@ public class RollbackRestoreCommand {
List<String> rollbackusers = argUsers;
int c = 0;
for (String ruser : rollbackusers) {
List<Player> players = Bukkit.getServer().matchPlayer(ruser);
List<Player> players = Bukkit.getServer().matchPlayer(ruser); // here
for (Player p : players) {
if (p.getName().equalsIgnoreCase(ruser)) {
rollbackusers.set(c, p.getName());
ruser = p.getName();
rollbackusers.set(c, ruser);
}
}
c++;
if (argAction.contains(4) && argAction.contains(11)) {
Player onlineUser = Bukkit.getServer().getPlayer(ruser);
if (onlineUser == null || !onlineUser.isOnline()) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.USER_OFFLINE, ruser));
return;
}
}
}
int wid = 0;
@ -234,6 +243,11 @@ public class RollbackRestoreCommand {
int y = 0;
int z = 0;
if (rollbackusers.contains("#container")) {
if (argAction.contains(11)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_USERNAME, "#container"));
return;
}
boolean valid = false;
if (ConfigHandler.lookupType.get(player.getName()) != null) {
int lookupType = ConfigHandler.lookupType.get(player.getName());
@ -248,7 +262,7 @@ public class RollbackRestoreCommand {
}
if (valid) {
if (preview > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CONTAINER));
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_TRANSACTION, Selector.FIRST));
return;
}
else {

View File

@ -216,18 +216,6 @@ public class Queue {
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static void queueContainerRollbackUpdate(String user, Location location, List<Object[]> list, int action) {
if (location == null) {
location = new Location(Bukkit.getServer().getWorlds().get(0), 0, 0, 0);
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.CONTAINER_ROLLBACK_UPDATE, null, 0, null, 0, action, null });
Consumer.consumerObjectArrayList.get(currentConsumer).put(consumerId, list);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static synchronized void queueContainerTransaction(String user, Location location, Material type, Object inventory, int chestId) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
@ -352,13 +340,14 @@ public class Queue {
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
}
protected static void queueRollbackUpdate(String user, Location location, List<Object[]> list, int action) {
protected static void queueRollbackUpdate(String user, Location location, List<Object[]> list, int table, int action) {
if (location == null) {
location = new Location(Bukkit.getServer().getWorlds().get(0), 0, 0, 0);
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ROLLBACK_UPDATE, null, 0, null, 0, action, null });
addConsumer(currentConsumer, new Object[] { consumerId, table, null, 0, null, 0, action, null });
Consumer.consumerObjectArrayList.get(currentConsumer).put(consumerId, list);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}

View File

@ -44,6 +44,8 @@ public class Process {
public static final int PLAYER_KILL = 24;
public static final int BLOCKDATA_INSERT = 25;
public static final int ITEM_TRANSACTION = 26;
public static final int INVENTORY_ROLLBACK_UPDATE = 27;
public static final int INVENTORY_CONTAINER_ROLLBACK_UPDATE = 28;
public static int lastLockUpdate = 0;
private static volatile int currentConsumerSize = 0;
@ -160,6 +162,12 @@ public class Process {
case Process.CONTAINER_ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 1);
break;
case Process.INVENTORY_ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 2);
break;
case Process.INVENTORY_CONTAINER_ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 3);
break;
case Process.WORLD_INSERT:
WorldInsertProcess.process(preparedStmtWorlds, i, statement, object, forceData);
break;

View File

@ -17,6 +17,7 @@ import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.language.Phrase;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Chat;
@ -38,7 +39,7 @@ public class ContainerRollback extends Queue {
userString = user.getName();
}
Queue.queueContainerRollbackUpdate(userString, location, lookupList, rollbackType); // Perform update transaction in consumer
Queue.queueRollbackUpdate(userString, location, lookupList, Process.CONTAINER_ROLLBACK_UPDATE, rollbackType); // Perform update transaction in consumer
final String finalUserString = userString;
ConfigHandler.rollbackHash.put(userString, new int[] { 0, 0, 0, 0 });

View File

@ -197,6 +197,12 @@ public class Database extends Queue {
if (table == 1) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "container SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
else if (table == 2) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "item SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
else if (table == 3) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "container SET rolled_back_inventory='" + rolledBack + "' WHERE rowid='" + id + "'");
}
else {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "block SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
@ -212,8 +218,8 @@ public class Database extends Queue {
String signInsert = "INSERT INTO " + ConfigHandler.prefix + "sign (time, user, wid, x, y, z, action, color, data, line_1, line_2, line_3, line_4) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String blockInsert = "INSERT INTO " + ConfigHandler.prefix + "block (time, user, wid, x, y, z, type, data, meta, blockdata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String skullInsert = "INSERT INTO " + ConfigHandler.prefix + "skull (time, owner) VALUES (?, ?)";
String containerInsert = "INSERT INTO " + ConfigHandler.prefix + "container (time, user, wid, x, y, z, type, data, amount, metadata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String itemInsert = "INSERT INTO " + ConfigHandler.prefix + "item (time, user, wid, x, y, z, type, data, amount, action) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String containerInsert = "INSERT INTO " + ConfigHandler.prefix + "container (time, user, wid, x, y, z, type, data, amount, metadata, action, rolled_back, rolled_back_inventory) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String itemInsert = "INSERT INTO " + ConfigHandler.prefix + "item (time, user, wid, x, y, z, type, data, amount, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String worldInsert = "INSERT INTO " + ConfigHandler.prefix + "world (id, world) VALUES (?, ?)";
String chatInsert = "INSERT INTO " + ConfigHandler.prefix + "chat (time, user, wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
String commandInsert = "INSERT INTO " + ConfigHandler.prefix + "command (time, user, wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
@ -333,9 +339,9 @@ public class Database extends Queue {
index = ", INDEX(time), INDEX(user,time), INDEX(wid,x,z,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "command(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data int(6), amount int(4), metadata blob, action int(2), rolled_back tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data int(6), amount int(4), metadata blob, action int(2), rolled_back tinyint(1), rolled_back_inventory tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data blob, amount int(4), action tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data blob, amount int(4), action tinyint(1), rolled_back tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),status tinyint(1),time int(10)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), data blob) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(id)";
@ -411,10 +417,10 @@ public class Database extends Queue {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "command (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, message TEXT);");
}
if (!tableData.contains(prefix + "container")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data INTEGER, amount INTEGER, metadata BLOB, action INTEGER, rolled_back INTEGER);");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data INTEGER, amount INTEGER, metadata BLOB, action INTEGER, rolled_back INTEGER, rolled_back_inventory INTEGER);");
}
if (!tableData.contains(prefix + "item")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data BLOB, amount INTEGER, action INTEGER);");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data BLOB, amount INTEGER, action INTEGER, rolled_back INTEGER);");
}
if (!tableData.contains(prefix + "database_lock")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock (status INTEGER, time INTEGER);");

View File

@ -56,7 +56,7 @@ public class Lookup extends Queue {
else if (i == 13 && map[i] instanceof Byte[]) {
results[newId] = Util.byteDataToString((byte[]) map[i], (int) map[6]);
}
else if (i > 0) {
else if (i > 0) { // skip rowid
if (map[i] instanceof Integer) {
results[newId] = map[i].toString();
}
@ -125,6 +125,10 @@ public class Lookup extends Queue {
invalidRollbackActions.add(3);
}
if (actionList.contains(4) && actionList.contains(11)) {
invalidRollbackActions.clear();
}
try {
while (Consumer.isPaused) {
Thread.sleep(1);
@ -211,6 +215,7 @@ public class Lookup extends Queue {
else {
int resultData = 0;
int resultAmount = -1;
int resultTable = 0;
byte[] resultMeta = null;
byte[] resultBlockData = null;
long resultId = results.getLong("id");
@ -224,10 +229,15 @@ public class Lookup extends Queue {
int resultZ = results.getInt("z");
int resultWorldId = results.getInt("wid");
boolean hasTbl = false;
if ((lookup && actionList.size() == 0) || actionList.contains(4) || actionList.contains(5) || actionList.contains(11)) {
resultData = results.getInt("data");
resultAmount = results.getInt("amount");
resultMeta = results.getBytes("metadata");
if (!lookup) {
resultTable = results.getInt("tbl");
hasTbl = true;
}
}
else {
resultData = results.getInt("data");
@ -236,7 +246,6 @@ public class Lookup extends Queue {
}
boolean valid = true;
if (!lookup) {
if (invalidRollbackActions.contains(resultAction)) {
valid = false;
@ -244,8 +253,14 @@ public class Lookup extends Queue {
}
if (valid) {
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData };
list.add(dataArray);
if (hasTbl) {
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData, resultTable };
list.add(dataArray);
}
else {
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData };
list.add(dataArray);
}
}
}
}
@ -661,25 +676,25 @@ public class Lookup extends Queue {
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(3)"); // if block specified for include/exclude, filter out entity data
}
query = unionSelect + "SELECT " + (count ? "'0' as tbl," : "") + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery + unionLimit + ") UNION ALL ";
query = unionSelect + "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery + unionLimit + ") UNION ALL ";
itemLookup = true;
}
if (itemLookup) {
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,metadata,data,amount,action,rolled_back";
rows = "rowid as id,time,user,wid,x,y,z,type,metadata,data,amount,action,rolled_back_inventory as rolled_back";
}
query = query + unionSelect + "SELECT " + (count ? "'1' as tbl," : "") + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + unionLimit + ") UNION ALL ";
query = query + unionSelect + "SELECT " + "'1' as tbl," + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + unionLimit + ") UNION ALL ";
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,0 as rolled_back";
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,rolled_back";
queryOrder = " ORDER BY time DESC, id DESC";
}
query = query + unionSelect + "SELECT " + (count ? "'2' as tbl," : "") + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock + unionLimit + ")";
query = query + unionSelect + "SELECT " + "'2' as tbl," + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock + unionLimit + ")";
}
if (query.length() == 0) {
query = "SELECT " + (count ? "'0' as tbl," : "") + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
query = "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
}
query = query + queryOrder + queryLimit + "";

View File

@ -15,6 +15,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
@ -75,6 +76,8 @@ import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.database.logger.ItemLogger;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -136,6 +139,7 @@ public class Rollback extends Queue {
TreeMap<Long, Integer> chunkList = new TreeMap<>();
HashMap<Long, ArrayList<Object[]>> dataList = new HashMap<>();
HashMap<Long, ArrayList<Object[]>> itemDataList = new HashMap<>();
boolean inventoryRollback = actionList.contains(11);
/*
int worldMin = BukkitAdapter.ADAPTER.getMinHeight(world);
@ -170,7 +174,7 @@ public class Rollback extends Queue {
int rowWorldId = (Integer) result[10];
int chunkX = rowX >> 4;
int chunkZ = rowZ >> 4;
long chunkKey = chunkX & 0xffffffffL | (chunkZ & 0xffffffffL) << 32;
long chunkKey = inventoryRollback ? 0 : (chunkX & 0xffffffffL | (chunkZ & 0xffffffffL) << 32);
// int rowAction = result[8];
// if (rowAction==10) result[8] = 0;
// if (rowAction==11) result[8] = 1;
@ -237,7 +241,7 @@ public class Rollback extends Queue {
String userString = "#server";
if (user != null) {
userString = user.getName();
if (verbose && preview == 0) {
if (verbose && preview == 0 && !actionList.contains(11)) {
Integer chunks = chunkList.size();
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_CHUNKS_FOUND, chunks.toString(), (chunks == 1 ? Selector.FIRST : Selector.SECOND)));
}
@ -245,8 +249,25 @@ public class Rollback extends Queue {
// Perform update transaction(s) in consumer
if (preview == 0) {
Queue.queueRollbackUpdate(userString, location, lookupList, rollbackType);
Queue.queueContainerRollbackUpdate(userString, location, itemList, rollbackType);
if (actionList.contains(11)) {
List<Object[]> inventoryList = new ArrayList<>();
List<Object[]> containerList = new ArrayList<>();
for (Object[] data : itemList) {
int table = (Integer) data[14];
if (table == 2) { // item
inventoryList.add(data);
}
else {
containerList.add(data);
}
}
Queue.queueRollbackUpdate(userString, location, inventoryList, Process.INVENTORY_ROLLBACK_UPDATE, rollbackType);
Queue.queueRollbackUpdate(userString, location, containerList, Process.INVENTORY_CONTAINER_ROLLBACK_UPDATE, rollbackType);
}
else {
Queue.queueRollbackUpdate(userString, location, lookupList, Process.ROLLBACK_UPDATE, rollbackType);
Queue.queueRollbackUpdate(userString, location, itemList, Process.CONTAINER_ROLLBACK_UPDATE, rollbackType);
}
}
ConfigHandler.rollbackHash.put(userString, new int[] { 0, 0, 0, 0 });
@ -272,7 +293,6 @@ public class Rollback extends Queue {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
try {
boolean clearInventories = false;
if (Config.getGlobal().ROLLBACK_ITEMS) {
clearInventories = true;
}
@ -1010,11 +1030,52 @@ public class Rollback extends Queue {
byte[] rowMetadata = (byte[]) row[12];
Material rowType = Util.getType(rowTypeRaw);
if (rowAction > 1) {
continue; // skip inventory & ender chest transactions
}
if ((rollbackType == 0 && rowRolledBack == 0) || (rollbackType == 1 && rowRolledBack == 1)) {
if (inventoryRollback) {
int rowUserId = (Integer) row[2];
String rowUser = ConfigHandler.playerIdCacheReversed.get(rowUserId);
if (rowUser == null) {
continue;
}
String uuid = ConfigHandler.uuidCache.get(rowUser.toLowerCase(Locale.ROOT));
if (uuid == null) {
continue;
}
Player player = Bukkit.getServer().getPlayer(UUID.fromString(uuid));
if (player == null) {
continue;
}
int inventoryAction = 0;
if (rowAction == ItemLogger.ITEM_DROP || rowAction == ItemLogger.ITEM_PICKUP) {
inventoryAction = (rowAction == ItemLogger.ITEM_PICKUP ? 1 : 0);
}
else if (rowAction == ItemLogger.ITEM_REMOVE_ENDER || rowAction == ItemLogger.ITEM_ADD_ENDER) {
inventoryAction = (rowAction == ItemLogger.ITEM_REMOVE_ENDER ? 1 : 0);
}
else {
inventoryAction = (rowAction == ItemLogger.ITEM_REMOVE ? 1 : 0);
}
int action = rollbackType == 0 ? (inventoryAction ^ 1) : inventoryAction;
ItemStack itemstack = new ItemStack(rowType, rowAmount, (short) rowData);
Object[] populatedStack = populateItemStack(itemstack, rowMetadata);
if (rowAction == ItemLogger.ITEM_REMOVE_ENDER || rowAction == ItemLogger.ITEM_ADD_ENDER) {
modifyContainerItems(containerType, player.getEnderChest(), (Integer) populatedStack[0], ((ItemStack) populatedStack[1]).clone(), action ^ 1);
}
modifyContainerItems(containerType, player.getInventory(), (Integer) populatedStack[0], (ItemStack) populatedStack[1], action);
itemCount1 = itemCount1 + rowAmount;
ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount1, blockCount1, entityCount1, 0 });
continue; // remove this for merged rollbacks in future? (be sure to re-enable chunk sorting)
}
if (rowAction > 1) {
continue; // skip inventory & ender chest transactions
}
if (!containerInit || rowX != lastX || rowY != lastY || rowZ != lastZ || rowWorldId != lastWorldId) {
container = null; // container patch 2.14.0
String world = Util.getWorldName(rowWorldId);
@ -1143,7 +1204,7 @@ public class Rollback extends Queue {
entityCount = rollbackHashData[2];
ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount, blockCount, entityCount, 0 });
if (verbose && user != null && preview == 0) {
if (verbose && user != null && preview == 0 && !actionList.contains(11)) {
Integer chunks = chunkList.size();
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_CHUNKS_MODIFIED, chunkCount.toString(), chunks.toString(), (chunks == 1 ? Selector.FIRST : Selector.SECOND)));
}
@ -1229,7 +1290,18 @@ public class Rollback extends Queue {
}
}
if (actionList.contains(4)) {
if (actionList.contains(4) && actionList.contains(11)) {
if (actionList.contains(0)) {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+inventory", Selector.SECOND));
}
else if (actionList.contains(1)) {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-inventory", Selector.SECOND));
}
else {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "inventory", Selector.SECOND));
}
}
else if (actionList.contains(4)) {
if (actionList.contains(0)) {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-container", Selector.SECOND));
}
@ -1346,6 +1418,13 @@ public class Rollback extends Queue {
int excludeCount = 0;
for (String excludeUser : excludeUserList) {
// don't display that excluded #hopper in inventory rollbacks
if (actionList.contains(4) && actionList.contains(11)) {
if (excludeUser.equals("#hopper")) {
continue;
}
}
if (excludeCount == 0) {
excludeUsers = excludeUsers.append("" + excludeUser + "");
}
@ -1356,7 +1435,9 @@ public class Rollback extends Queue {
excludeCount++;
}
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_EXCLUDED_USERS, excludeUsers.toString(), (excludeCount == 1 ? Selector.FIRST : Selector.SECOND)));
if (excludeCount > 0) {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_EXCLUDED_USERS, excludeUsers.toString(), (excludeCount == 1 ? Selector.FIRST : Selector.SECOND)));
}
}
StringBuilder modifiedData = new StringBuilder();
@ -1366,7 +1447,7 @@ public class Rollback extends Queue {
modifyCount++;
}
else if (preview == 0) {
if (itemCount > 0) {
if (itemCount > 0 || actionList.contains(4)) {
modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(itemCount), (itemCount == 1 ? Selector.FIRST : Selector.SECOND)));
modifyCount++;
}
@ -1379,11 +1460,13 @@ public class Rollback extends Queue {
modifyCount++;
}
if (modifyCount > 0) {
modifiedData.append(", ");
if (blockCount > 0 || !actionList.contains(4)) {
if (modifyCount > 0) {
modifiedData.append(", ");
}
modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
modifyCount++;
}
modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
modifyCount++;
}
else if (preview > 0) {
modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
@ -1391,7 +1474,7 @@ public class Rollback extends Queue {
}
StringBuilder modifiedDataVerbose = new StringBuilder();
if (verbose && preview == 0) {
if (verbose && preview == 0 && !actionList.contains(11)) {
if (chunkCount > -1 && modifyCount < 3) {
if (modifyCount > 0) {
modifiedData.append(", ");
@ -1428,7 +1511,7 @@ public class Rollback extends Queue {
try {
ItemStack[] contents = null;
if (type.equals(Material.ARMOR_STAND)) {
if (type != null && type.equals(Material.ARMOR_STAND)) {
EntityEquipment equipment = (EntityEquipment) container;
if (equipment != null) {
if (action == 1) {

View File

@ -25,6 +25,7 @@ public class ContainerStatement {
preparedStmt.setObject(10, byteData);
preparedStmt.setInt(11, action);
preparedStmt.setInt(12, rolledBack);
preparedStmt.setInt(13, 0); // rolled_back_inventory
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {

View File

@ -23,6 +23,7 @@ public class ItemStatement {
preparedStmt.setObject(8, byteData);
preparedStmt.setInt(9, amount);
preparedStmt.setInt(10, action);
preparedStmt.setInt(11, 0); // rolled_back
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {

View File

@ -167,8 +167,8 @@ public class Language {
phrases.put(Phrase.PLEASE_SELECT, "Please select: \"{0}\" or \"{1}\".");
phrases.put(Phrase.PREVIEW_CANCELLED, "Preview cancelled.");
phrases.put(Phrase.PREVIEW_CANCELLING, "Cancelling preview...");
phrases.put(Phrase.PREVIEW_CONTAINER, "You can't preview container transactions.");
phrases.put(Phrase.PREVIEW_IN_GAME, "You can only preview rollbacks in-game.");
phrases.put(Phrase.PREVIEW_TRANSACTION, "You can't preview {container|inventory} transactions.");
phrases.put(Phrase.PURGE_ABORTED, "Purge failed. Database may be corrupt.");
phrases.put(Phrase.PURGE_ERROR, "Unable to process {0} data!");
phrases.put(Phrase.PURGE_FAILED, "Purge failed. Please try again later.");
@ -217,6 +217,7 @@ public class Language {
phrases.put(Phrase.UPDATE_NOTICE, "Notice: {0} is now available.");
phrases.put(Phrase.UPGRADE_IN_PROGRESS, "Upgrade in progress. Please try again later.");
phrases.put(Phrase.USER_NOT_FOUND, "User \"{0}\" not found.");
phrases.put(Phrase.USER_OFFLINE, "The user \"{0}\" is not online.");
phrases.put(Phrase.USING_MYSQL, "Using MySQL for data storage.");
phrases.put(Phrase.USING_SQLITE, "Using SQLite for data storage.");
phrases.put(Phrase.VALID_DONATION_KEY, "Valid donation key.");

View File

@ -148,8 +148,8 @@ public enum Phrase {
PLEASE_SELECT,
PREVIEW_CANCELLED,
PREVIEW_CANCELLING,
PREVIEW_CONTAINER,
PREVIEW_IN_GAME,
PREVIEW_TRANSACTION,
PURGE_ABORTED,
PURGE_ERROR,
PURGE_FAILED,
@ -198,6 +198,7 @@ public enum Phrase {
UPDATE_NOTICE,
UPGRADE_IN_PROGRESS,
USER_NOT_FOUND,
USER_OFFLINE,
USING_MYSQL,
USING_SQLITE,
VALID_DONATION_KEY,

View File

@ -2,13 +2,63 @@ package net.coreprotect.patch.script;
import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigFile;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.patch.Patch;
import net.coreprotect.utility.Chat;
public class __2_21_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "item ADD COLUMN rolled_back tinyint(1) DEFAULT 0;");
}
catch (Exception e) {
Chat.console(Phrase.build(Phrase.PATCH_SKIP_UPDATE, ConfigHandler.prefix + "item", Selector.FIRST, Selector.FIRST));
}
if (!Patch.continuePatch()) {
return false;
}
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "container ADD COLUMN rolled_back_inventory tinyint(1) DEFAULT 0;");
}
catch (Exception e) {
Chat.console(Phrase.build(Phrase.PATCH_SKIP_UPDATE, ConfigHandler.prefix + "container", Selector.FIRST, Selector.FIRST));
}
}
else {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "item ADD COLUMN rolled_back INTEGER DEFAULT 0;");
}
catch (Exception e) {
Chat.console(Phrase.build(Phrase.PATCH_SKIP_UPDATE, ConfigHandler.prefix + "item", Selector.FIRST, Selector.FIRST));
}
if (!Patch.continuePatch()) {
return false;
}
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "container ADD COLUMN rolled_back_inventory INTEGER DEFAULT 0;");
}
catch (Exception e) {
Chat.console(Phrase.build(Phrase.PATCH_SKIP_UPDATE, ConfigHandler.prefix + "container", Selector.FIRST, Selector.FIRST));
}
}
if (!Patch.continuePatch()) {
return false;
}
ConfigFile.modifyLine("language.yml", "LOOKUP_VIEW_PAGE: \"To view a page, type \\\"{0}\\\".\"", null);
ConfigFile.modifyLine("language.yml", "PREVIEW_CONTAINER: \"You can't preview container transactions.\"", null);
}
catch (Exception e) {
e.printStackTrace();