Fixed inventory lookups/rollbacks missing block placement actions

This commit is contained in:
Intelli 2022-02-18 20:29:45 -07:00
parent 527be90249
commit 585d8b275a
14 changed files with 136 additions and 114 deletions

View File

@ -139,7 +139,7 @@ public class CoreProtectAPI extends Queue {
return false;
}
return Integer.parseInt(parse[8]) == 1;
return (Integer.parseInt(parse[8]) == 1 || Integer.parseInt(parse[8]) == 3);
}
public String worldName() {

View File

@ -869,7 +869,7 @@ public class LookupCommand {
int ddata = Integer.parseInt(data[6]);
int daction = Integer.parseInt(data[7]);
int amount = Integer.parseInt(data[10]);
String rbd = (Integer.parseInt(data[8]) == 1 ? Color.STRIKETHROUGH : "");
String rbd = ((Integer.parseInt(data[8]) == 2 || Integer.parseInt(data[8]) == 3) ? Color.STRIKETHROUGH : "");
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
String dname = Util.nameFilter(Util.getType(Integer.parseInt(dtype)).name().toLowerCase(Locale.ROOT), ddata);
@ -895,7 +895,7 @@ public class LookupCommand {
for (String[] data : lookupList) {
int drb = Integer.parseInt(data[8]);
String rbd = "";
if (drb == 1) {
if (drb == 1 || drb == 3) {
rbd = Color.STRIKETHROUGH;
}

View File

@ -44,6 +44,7 @@ public class Process {
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 final int BLOCK_INVENTORY_ROLLBACK_UPDATE = 29;
public static int lastLockUpdate = 0;
private static volatile int currentConsumerSize = 0;
@ -166,6 +167,9 @@ public class Process {
case Process.INVENTORY_CONTAINER_ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 3);
break;
case Process.BLOCK_INVENTORY_ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 4);
break;
case Process.WORLD_INSERT:
WorldInsertProcess.process(preparedStmtWorlds, i, statement, object, forceData);
break;

View File

@ -6,6 +6,7 @@ import java.util.Map;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
import net.coreprotect.utility.Util;
class RollbackUpdateProcess {
@ -16,8 +17,8 @@ class RollbackUpdateProcess {
for (Object[] listRow : list) {
long rowid = (Long) listRow[0];
int rolledBack = (Integer) listRow[9];
if (rolledBack == action) {
Database.performUpdate(statement, rowid, action, table);
if (Util.rolledBack(rolledBack, (table == 2 || table == 3 || table == 4)) == action) { // 1 = restore, 0 = rollback
Database.performUpdate(statement, rowid, rolledBack, table);
}
}
updateLists.remove(id);

View File

@ -96,7 +96,7 @@ public class ContainerRollback extends Queue {
int rowTypeRaw = (Integer) lookupRow[6];
int rowData = (Integer) lookupRow[7];
int rowAction = (Integer) lookupRow[8];
int rowRolledBack = (Integer) lookupRow[9];
int rowRolledBack = Util.rolledBack((Integer) lookupRow[9], false);
// int rowWid = (Integer)lookupRow[10];
int rowAmount = (Integer) lookupRow[11];
byte[] rowMetadata = (byte[]) lookupRow[12];

View File

@ -187,22 +187,15 @@ public class Database extends Queue {
}
}
public static void performUpdate(Statement statement, long id, int action, int table) {
public static void performUpdate(Statement statement, long id, int rb, int table) {
try {
int rolledBack = 1;
if (action == 1) {
rolledBack = 0;
}
if (table == 1) {
int rolledBack = Util.toggleRolledBack(rb, (table == 2 || table == 3 || table == 4)); // co_item, co_container, co_block
if (table == 1 || table == 3) {
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 + "'");
}
@ -218,7 +211,7 @@ 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, rolled_back_inventory) 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, 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 (?, ?, ?, ?, ?, ?, ?)";
@ -339,7 +332,7 @@ 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), rolled_back_inventory 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)" + 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), 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");
@ -417,7 +410,7 @@ 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, rolled_back_inventory 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);");
}
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, rolled_back INTEGER);");

View File

@ -297,6 +297,7 @@ public class Lookup extends Queue {
restrictWorld = true;
}
boolean inventoryQuery = (actionList.contains(4) && actionList.contains(11));
boolean validAction = false;
String queryBlock = "";
String queryEntity = "";
@ -530,7 +531,7 @@ public class Lookup extends Queue {
if (validAction) {
queryBlock = queryBlock + " action IN(" + action + ") AND";
}
else if (includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
else if (inventoryQuery || includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
queryBlock = queryBlock + " action NOT IN(-1) AND";
}
@ -666,23 +667,36 @@ public class Lookup extends Queue {
}
}
boolean itemLookup = (actionList.contains(4) && actionList.contains(11));
if (lookup && actionList.size() == 0) {
boolean itemLookup = inventoryQuery;
if ((lookup && actionList.size() == 0) || (itemLookup && !actionList.contains(0))) {
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,-1 as amount,action,rolled_back";
}
if (inventoryQuery) {
if (validAction) {
baseQuery = baseQuery.replace("action IN(" + action + ")", "action IN(1)");
}
else {
baseQuery = baseQuery.replace("action NOT IN(-1)", "action IN(1)");
}
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,1 as amount,action,rolled_back";
}
}
if (includeBlock.length() > 0 || excludeBlock.length() > 0) {
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(3)"); // if block specified for include/exclude, filter out entity data
}
query = unionSelect + "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery + unionLimit + ") UNION ALL ";
query = unionSelect + "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + "block " + 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_inventory as rolled_back";
rows = "rowid as id,time,user,wid,x,y,z,type,metadata,data,amount,action,rolled_back";
}
query = query + unionSelect + "SELECT " + "'1' as tbl," + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + unionLimit + ") UNION ALL ";
@ -735,7 +749,7 @@ public class Lookup extends Queue {
int z = block.getZ();
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(block.getWorld().getName());
String query = "SELECT user,type FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back = '0' AND action='1' ORDER BY rowid DESC LIMIT 0, 1";
String query = "SELECT user,type FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back IN(0,2) AND action='1' ORDER BY rowid DESC LIMIT 0, 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {

View File

@ -252,6 +252,7 @@ public class Rollback extends Queue {
// Perform update transaction(s) in consumer
if (preview == 0) {
if (actionList.contains(11)) {
List<Object[]> blockList = new ArrayList<>();
List<Object[]> inventoryList = new ArrayList<>();
List<Object[]> containerList = new ArrayList<>();
for (Object[] data : itemList) {
@ -259,12 +260,16 @@ public class Rollback extends Queue {
if (table == 2) { // item
inventoryList.add(data);
}
else {
else if (table == 1) { // container
containerList.add(data);
}
else { // block
blockList.add(data);
}
}
Queue.queueRollbackUpdate(userString, location, inventoryList, Process.INVENTORY_ROLLBACK_UPDATE, rollbackType);
Queue.queueRollbackUpdate(userString, location, containerList, Process.INVENTORY_CONTAINER_ROLLBACK_UPDATE, rollbackType);
Queue.queueRollbackUpdate(userString, location, blockList, Process.BLOCK_INVENTORY_ROLLBACK_UPDATE, rollbackType);
}
else {
Queue.queueRollbackUpdate(userString, location, lookupList, Process.ROLLBACK_UPDATE, rollbackType);
@ -320,7 +325,7 @@ public class Rollback extends Queue {
int rowTypeRaw = (Integer) row[6];
int rowData = (Integer) row[7];
int rowAction = (Integer) row[8];
int rowRolledBack = (Integer) row[9];
int rowRolledBack = Util.rolledBack((Integer) row[9], false);
int rowWorldId = (Integer) row[10];
byte[] rowMeta = (byte[]) row[12];
byte[] rowBlockData = (byte[]) row[13];
@ -1023,14 +1028,15 @@ public class Rollback extends Queue {
int rowTypeRaw = (Integer) row[6];
int rowData = (Integer) row[7];
int rowAction = (Integer) row[8];
int rowRolledBack = (Integer) row[9];
int rowRolledBack = Util.rolledBack((Integer) row[9], false);
int rowWorldId = (Integer) row[10];
int rowAmount = (Integer) row[11];
byte[] rowMetadata = (byte[]) row[12];
Material rowType = Util.getType(rowTypeRaw);
if (rowType != null && ((rollbackType == 0 && rowRolledBack == 0) || (rollbackType == 1 && rowRolledBack == 1))) {
if (inventoryRollback) {
int rolledBackInventory = Util.rolledBack((Integer) row[9], true);
if (rowType != null) {
if (inventoryRollback && ((rollbackType == 0 && rolledBackInventory == 0) || (rollbackType == 1 && rolledBackInventory == 1))) {
int rowUserId = (Integer) row[2];
String rowUser = ConfigHandler.playerIdCacheReversed.get(rowUserId);
if (rowUser == null) {
@ -1071,77 +1077,79 @@ public class Rollback extends Queue {
continue; // remove this for merged rollbacks in future? (be sure to re-enable chunk sorting)
}
if (rowAction > 1) {
if (inventoryRollback || rowAction > 1) {
continue; // skip inventory & ender chest transactions
}
ItemStack itemstack = new ItemStack(rowType, rowAmount, (short) rowData);
Object[] populatedStack = populateItemStack(itemstack, rowMetadata);
String faceData = (String) populatedStack[1];
if ((rollbackType == 0 && rowRolledBack == 0) || (rollbackType == 1 && rowRolledBack == 1)) {
ItemStack itemstack = new ItemStack(rowType, rowAmount, (short) rowData);
Object[] populatedStack = populateItemStack(itemstack, rowMetadata);
String faceData = (String) populatedStack[1];
if (!containerInit || rowX != lastX || rowY != lastY || rowZ != lastZ || rowWorldId != lastWorldId || !faceData.equals(lastFace)) {
container = null; // container patch 2.14.0
String world = Util.getWorldName(rowWorldId);
if (world.length() == 0) {
continue;
}
if (!containerInit || rowX != lastX || rowY != lastY || rowZ != lastZ || rowWorldId != lastWorldId || !faceData.equals(lastFace)) {
container = null; // container patch 2.14.0
String world = Util.getWorldName(rowWorldId);
if (world.length() == 0) {
continue;
}
World bukkitWorld = Bukkit.getServer().getWorld(world);
if (bukkitWorld == null) {
continue;
}
Block block = bukkitWorld.getBlockAt(rowX, rowY, rowZ);
if (!bukkitWorld.isChunkLoaded(block.getChunk())) {
bukkitWorld.getChunkAt(block.getLocation());
}
World bukkitWorld = Bukkit.getServer().getWorld(world);
if (bukkitWorld == null) {
continue;
}
Block block = bukkitWorld.getBlockAt(rowX, rowY, rowZ);
if (!bukkitWorld.isChunkLoaded(block.getChunk())) {
bukkitWorld.getChunkAt(block.getLocation());
}
if (BlockGroup.CONTAINERS.contains(block.getType())) {
container = Util.getContainerInventory(block.getState(), false);
containerType = block.getType();
}
else if (BlockGroup.CONTAINERS.contains(Material.ARMOR_STAND) || BlockGroup.CONTAINERS.contains(Material.ITEM_FRAME)) {
BlockFace blockFace = BlockFace.valueOf(faceData);
for (Entity entity : block.getChunk().getEntities()) {
if (entity.getLocation().getBlockX() == rowX && entity.getLocation().getBlockY() == rowY && entity.getLocation().getBlockZ() == rowZ) {
if (entity instanceof ArmorStand) {
container = Util.getEntityEquipment((LivingEntity) entity);
containerType = Material.ARMOR_STAND;
}
else if (entity instanceof ItemFrame) {
container = entity;
containerType = Material.ITEM_FRAME;
if (blockFace == ((ItemFrame) entity).getFacing()) {
break;
if (BlockGroup.CONTAINERS.contains(block.getType())) {
container = Util.getContainerInventory(block.getState(), false);
containerType = block.getType();
}
else if (BlockGroup.CONTAINERS.contains(Material.ARMOR_STAND) || BlockGroup.CONTAINERS.contains(Material.ITEM_FRAME)) {
BlockFace blockFace = BlockFace.valueOf(faceData);
for (Entity entity : block.getChunk().getEntities()) {
if (entity.getLocation().getBlockX() == rowX && entity.getLocation().getBlockY() == rowY && entity.getLocation().getBlockZ() == rowZ) {
if (entity instanceof ArmorStand) {
container = Util.getEntityEquipment((LivingEntity) entity);
containerType = Material.ARMOR_STAND;
}
else if (entity instanceof ItemFrame) {
container = entity;
containerType = Material.ITEM_FRAME;
if (blockFace == ((ItemFrame) entity).getFacing()) {
break;
}
}
}
}
}
lastX = rowX;
lastY = rowY;
lastZ = rowZ;
lastWorldId = rowWorldId;
lastFace = faceData;
}
lastX = rowX;
lastY = rowY;
lastZ = rowZ;
lastWorldId = rowWorldId;
lastFace = faceData;
if (container != null) {
int action = 0;
if (rollbackType == 0 && rowAction == 0) {
action = 1;
}
if (rollbackType == 1 && rowAction == 1) {
action = 1;
}
int slot = (Integer) populatedStack[0];
itemstack = (ItemStack) populatedStack[2];
modifyContainerItems(containerType, container, slot, itemstack, action);
itemCount1 = itemCount1 + rowAmount;
}
containerInit = true;
}
if (container != null) {
int action = 0;
if (rollbackType == 0 && rowAction == 0) {
action = 1;
}
if (rollbackType == 1 && rowAction == 1) {
action = 1;
}
int slot = (Integer) populatedStack[0];
itemstack = (ItemStack) populatedStack[2];
modifyContainerItems(containerType, container, slot, itemstack, action);
itemCount1 = itemCount1 + rowAmount;
}
containerInit = true;
}
ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount1, blockCount1, entityCount1, 0 });

View File

@ -104,7 +104,7 @@ public class BlockLookup {
}
String rbFormat = "";
if (resultRolledBack == 1) {
if (resultRolledBack == 1 || resultRolledBack == 3) {
rbFormat = Color.STRIKETHROUGH;
}

View File

@ -97,7 +97,7 @@ public class ChestTransactionLookup {
String selector = (resultAction != 0 ? Selector.FIRST : Selector.SECOND);
String tag = (resultAction != 0 ? Color.GREEN + "+" : Color.RED + "-");
String rbFormat = "";
if (resultRolledBack == 1) {
if (resultRolledBack == 1 || resultRolledBack == 3) {
rbFormat = Color.STRIKETHROUGH;
}

View File

@ -88,7 +88,7 @@ public class InteractionLookup {
found = true;
String rbFormat = "";
if (resultRolledBack == 1) {
if (resultRolledBack == 1 || resultRolledBack == 3) {
rbFormat = Color.STRIKETHROUGH;
}

View File

@ -25,7 +25,6 @@ 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

@ -21,17 +21,6 @@ public class __2_21_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 {
@ -40,17 +29,6 @@ public class __2_21_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()) {

View File

@ -1421,4 +1421,29 @@ public class Util extends Queue {
return result;
}
public static int rolledBack(int rolledBack, boolean isInventory) {
switch (rolledBack) {
case 1: // just block rolled back
return isInventory ? 0 : 1;
case 2: // just inventory rolled back
return isInventory ? 1 : 0;
case 3: // block and inventory rolled back
return 1;
default: // no rollbacks
return 0;
}
}
public static int toggleRolledBack(int rolledBack, boolean isInventory) {
switch (rolledBack) {
case 1: // just block rolled back
return isInventory ? 3 : 0;
case 2: // just inventory rolled back
return isInventory ? 0 : 3;
case 3: // block and inventory rolled back
return isInventory ? 1 : 2;
default: // no rollbacks
return isInventory ? 2 : 1;
}
}
}