geforkt von Mirrors/FastAsyncWorldEdit
fix: improve FAWE stream history (#2844)
- reset "origin"/relative X/Z when larger than short min/max value so we do not write incorrect positions - history size can be larger than int max value - fixes #2583
Dieser Commit ist enthalten in:
Ursprung
6052fc3128
Commit
d1f9d3d6d5
@ -91,7 +91,7 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
|||||||
newClipboard.setOrigin(position);
|
newClipboard.setOrigin(position);
|
||||||
ClipboardHolder holder = new ClipboardHolder(newClipboard);
|
ClipboardHolder holder = new ClipboardHolder(newClipboard);
|
||||||
session.setClipboard(holder);
|
session.setClipboard(holder);
|
||||||
int blocks = builder.size();
|
long blocks = builder.longSize();
|
||||||
player.print(Caption.of("fawe.worldedit.copy.command.copy", blocks));
|
player.print(Caption.of("fawe.worldedit.copy.command.copy", blocks));
|
||||||
} else {
|
} else {
|
||||||
AffineTransform transform = null;
|
AffineTransform transform = null;
|
||||||
|
@ -64,26 +64,47 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
public Future<Boolean> init() {
|
public Future<Boolean> init() {
|
||||||
return call(() -> {
|
return call(() -> {
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("CREATE TABLE IF NOT EXISTS`" + this.prefix +
|
try (PreparedStatement stmt = connection.prepareStatement("CREATE TABLE IF NOT EXISTS`" + this.prefix +
|
||||||
"edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL, `time` INT NOT NULL,`x1`" +
|
"_edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL, `time` INT NOT NULL,`x1` " +
|
||||||
"INT NOT NULL,`x2` INT NOT NULL,`z1` INT NOT NULL,`z2` INT NOT NULL,`y1`" +
|
"INT NOT NULL,`x2` INT NOT NULL,`z1` INT NOT NULL,`z2` INT NOT NULL,`y1` " +
|
||||||
"INT NOT NULL, `y2` INT NOT NULL, `size` INT NOT NULL, `command` VARCHAR, PRIMARY KEY (player, id))")) {
|
"INT NOT NULL, `y2` INT NOT NULL, `size` BIGINT NOT NULL, `command` VARCHAR, PRIMARY KEY (player, id))")) {
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
}
|
}
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("ALTER TABLE`" + this.prefix + "edits` ADD COLUMN `command` VARCHAR")) {
|
String alterTablePrefix = "ALTER TABLE`" + this.prefix + "edits` ";
|
||||||
|
try (PreparedStatement stmt =
|
||||||
|
connection.prepareStatement(alterTablePrefix + "ADD COLUMN `command` VARCHAR")) {
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
} catch (SQLException ignored) {
|
} catch (SQLException ignored) {
|
||||||
} // Already updated
|
} // Already updated
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("ALTER TABLE`" + this.prefix + "edits` ADD SIZE INT DEFAULT 0 NOT NULL")) {
|
try (PreparedStatement stmt =
|
||||||
|
connection.prepareStatement(alterTablePrefix + "ADD COLUMN `size` BIGINT DEFAULT 0 NOT NULL")) {
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
} catch (SQLException ignored) {
|
} catch (SQLException ignored) {
|
||||||
} // Already updated
|
} // Already updated
|
||||||
|
|
||||||
|
boolean migrated = false;
|
||||||
|
try (PreparedStatement stmt =
|
||||||
|
connection.prepareStatement("INSERT INTO `" + this.prefix + "_edits` " +
|
||||||
|
"(player, id, time, x1, x2, z1, z2, y1, y2, size, command) " +
|
||||||
|
"SELECT player, id, time, x1, x2, z1, z2, y1, y2, size, command " +
|
||||||
|
"FROM `" + this.prefix + "edits`")) {
|
||||||
|
|
||||||
|
stmt.executeUpdate();
|
||||||
|
migrated = true;
|
||||||
|
} catch (SQLException ignored) {
|
||||||
|
} // Already updated
|
||||||
|
if (migrated) {
|
||||||
|
try (PreparedStatement stmt = connection.prepareStatement("DROP TABLE `" + this.prefix + "edits`")) {
|
||||||
|
stmt.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Integer> delete(UUID uuid, int id) {
|
public Future<Integer> delete(UUID uuid, int id) {
|
||||||
return call(() -> {
|
return call(() -> {
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "edits` WHERE `player`=? AND `id`=?")) {
|
try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "_edits` WHERE `player`=? " +
|
||||||
|
"AND `id`=?")) {
|
||||||
stmt.setBytes(1, toBytes(uuid));
|
stmt.setBytes(1, toBytes(uuid));
|
||||||
stmt.setInt(2, id);
|
stmt.setInt(2, id);
|
||||||
return stmt.executeUpdate();
|
return stmt.executeUpdate();
|
||||||
@ -94,7 +115,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
public Future<RollbackOptimizedHistory> getEdit(@Nonnull UUID uuid, int id) {
|
public Future<RollbackOptimizedHistory> getEdit(@Nonnull UUID uuid, int id) {
|
||||||
return call(() -> {
|
return call(() -> {
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM`" + this.prefix +
|
try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM`" + this.prefix +
|
||||||
"edits` WHERE `player`=? AND `id`=?")) {
|
"_edits` WHERE `player`=? AND `id`=?")) {
|
||||||
stmt.setBytes(1, toBytes(uuid));
|
stmt.setBytes(1, toBytes(uuid));
|
||||||
stmt.setInt(2, id);
|
stmt.setInt(2, id);
|
||||||
ResultSet result = stmt.executeQuery();
|
ResultSet result = stmt.executeQuery();
|
||||||
@ -119,7 +140,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
CuboidRegion region = new CuboidRegion(BlockVector3.at(x1, y1, z1), BlockVector3.at(x2, y2, z2));
|
CuboidRegion region = new CuboidRegion(BlockVector3.at(x1, y1, z1), BlockVector3.at(x2, y2, z2));
|
||||||
|
|
||||||
long time = result.getInt("time") * 1000L;
|
long time = result.getInt("time") * 1000L;
|
||||||
long size = result.getInt("size");
|
long size = result.getLong("size");
|
||||||
|
|
||||||
String command = result.getString("command");
|
String command = result.getString("command");
|
||||||
|
|
||||||
@ -135,7 +156,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
long now = System.currentTimeMillis() / 1000;
|
long now = System.currentTimeMillis() / 1000;
|
||||||
final int then = (int) (now - diff);
|
final int then = (int) (now - diff);
|
||||||
return call(() -> {
|
return call(() -> {
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "edits` WHERE `time`<?")) {
|
try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "_edits` WHERE `time`<?")) {
|
||||||
stmt.setInt(1, then);
|
stmt.setInt(1, then);
|
||||||
return stmt.executeUpdate();
|
return stmt.executeUpdate();
|
||||||
}
|
}
|
||||||
@ -160,7 +181,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
try {
|
try {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
String stmtStr = """
|
String stmtStr = """
|
||||||
SELECT * FROM `%sedits`
|
SELECT * FROM `%s_edits`
|
||||||
WHERE `time` > ?
|
WHERE `time` > ?
|
||||||
AND `x2` >= ?
|
AND `x2` >= ?
|
||||||
AND `x1` <= ?
|
AND `x1` <= ?
|
||||||
@ -202,7 +223,8 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
}
|
}
|
||||||
if (delete && uuid != null) {
|
if (delete && uuid != null) {
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix +
|
try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix +
|
||||||
"edits` WHERE `player`=? AND `time`>? AND `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=?")) {
|
"_edits` WHERE `player`=? AND `time`>? AND `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? " +
|
||||||
|
"AND `z1`<=?")) {
|
||||||
byte[] uuidBytes = ByteBuffer
|
byte[] uuidBytes = ByteBuffer
|
||||||
.allocate(16)
|
.allocate(16)
|
||||||
.putLong(uuid.getMostSignificantBits())
|
.putLong(uuid.getMostSignificantBits())
|
||||||
@ -249,7 +271,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
RollbackOptimizedHistory[] copy = IntStream.range(0, size)
|
RollbackOptimizedHistory[] copy = IntStream.range(0, size)
|
||||||
.mapToObj(i -> historyChanges.poll()).toArray(RollbackOptimizedHistory[]::new);
|
.mapToObj(i -> historyChanges.poll()).toArray(RollbackOptimizedHistory[]::new);
|
||||||
|
|
||||||
try (PreparedStatement stmt = connection.prepareStatement("INSERT OR REPLACE INTO`" + this.prefix + "edits`" +
|
try (PreparedStatement stmt = connection.prepareStatement("INSERT OR REPLACE INTO`" + this.prefix + "_edits`" +
|
||||||
" (`player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")) {
|
" (`player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")) {
|
||||||
// `player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)"
|
// `player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)"
|
||||||
for (RollbackOptimizedHistory change : copy) {
|
for (RollbackOptimizedHistory change : copy) {
|
||||||
@ -270,7 +292,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
stmt.setInt(8, pos1.y() - 128);
|
stmt.setInt(8, pos1.y() - 128);
|
||||||
stmt.setInt(9, pos2.y() - 128);
|
stmt.setInt(9, pos2.y() - 128);
|
||||||
stmt.setString(10, change.getCommand());
|
stmt.setString(10, change.getCommand());
|
||||||
stmt.setInt(11, change.size());
|
stmt.setLong(11, change.longSize());
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
stmt.clearParameters();
|
stmt.clearParameters();
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return queue.isEmpty() && workerSemaphore.availablePermits() == 1 && size() == 0;
|
return queue.isEmpty() && workerSemaphore.availablePermits() == 1 && longSize() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(BlockVector3 loc, BaseBlock from, BaseBlock to) {
|
public void add(BlockVector3 loc, BaseBlock from, BaseBlock to) {
|
||||||
|
@ -176,6 +176,11 @@ public class AbstractDelegateChangeSet extends AbstractChangeSet {
|
|||||||
return parent.size();
|
return parent.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long longSize() {
|
||||||
|
return parent.longSize();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
parent.delete();
|
parent.delete();
|
||||||
|
@ -25,6 +25,7 @@ import java.io.EOFException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
@ -35,11 +36,18 @@ import java.util.NoSuchElementException;
|
|||||||
public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
||||||
|
|
||||||
public static final int HEADER_SIZE = 9;
|
public static final int HEADER_SIZE = 9;
|
||||||
private static final int version = 1;
|
private static final int VERSION = 2;
|
||||||
|
// equivalent to Short#MIN_VALUE three times stored with [(x) & 0xff, ((rx) >> 8) & 0xff]
|
||||||
|
private static final byte[] MAGIC_NEW_RELATIVE = new byte[]{0, (byte) 128, 0, (byte) 128, 0, (byte) 128};
|
||||||
private int mode;
|
private int mode;
|
||||||
private final int compression;
|
private final int compression;
|
||||||
private final int minY;
|
private final int minY;
|
||||||
|
|
||||||
|
protected long blockSize;
|
||||||
|
private int originX;
|
||||||
|
private int originZ;
|
||||||
|
private int version;
|
||||||
|
|
||||||
protected FaweStreamIdDelegate idDel;
|
protected FaweStreamIdDelegate idDel;
|
||||||
protected FaweStreamPositionDelegate posDel;
|
protected FaweStreamPositionDelegate posDel;
|
||||||
|
|
||||||
@ -192,6 +200,20 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
int rx = -lx + (lx = x);
|
int rx = -lx + (lx = x);
|
||||||
int ry = -ly + (ly = y);
|
int ry = -ly + (ly = y);
|
||||||
int rz = -lz + (lz = z);
|
int rz = -lz + (lz = z);
|
||||||
|
// Use LE/GE to ensure we don't accidentally write MAGIC_NEW_RELATIVE
|
||||||
|
if (rx >= Short.MAX_VALUE || rz >= Short.MAX_VALUE || rx <= Short.MIN_VALUE || rz <= Short.MIN_VALUE) {
|
||||||
|
stream.write(MAGIC_NEW_RELATIVE);
|
||||||
|
stream.write((byte) (x >> 24));
|
||||||
|
stream.write((byte) (x >> 16));
|
||||||
|
stream.write((byte) (x >> 8));
|
||||||
|
stream.write((byte) (x));
|
||||||
|
stream.write((byte) (z >> 24));
|
||||||
|
stream.write((byte) (z >> 16));
|
||||||
|
stream.write((byte) (z >> 8));
|
||||||
|
stream.write((byte) (z));
|
||||||
|
rx = 0;
|
||||||
|
rz = 0;
|
||||||
|
}
|
||||||
stream.write((rx) & 0xff);
|
stream.write((rx) & 0xff);
|
||||||
stream.write(((rx) >> 8) & 0xff);
|
stream.write(((rx) >> 8) & 0xff);
|
||||||
stream.write((rz) & 0xff);
|
stream.write((rz) & 0xff);
|
||||||
@ -203,6 +225,12 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
@Override
|
@Override
|
||||||
public int readX(FaweInputStream is) throws IOException {
|
public int readX(FaweInputStream is) throws IOException {
|
||||||
is.readFully(buffer);
|
is.readFully(buffer);
|
||||||
|
// Don't break reading version 1 history (just in case)
|
||||||
|
if (version == 2 && Arrays.equals(buffer, MAGIC_NEW_RELATIVE)) {
|
||||||
|
lx = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
|
||||||
|
lz = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
|
||||||
|
is.readFully(buffer);
|
||||||
|
}
|
||||||
return lx = lx + ((buffer[0] & 0xFF) | (buffer[1] << 8));
|
return lx = lx + ((buffer[0] & 0xFF) | (buffer[1] << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +250,7 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
public void writeHeader(OutputStream os, int x, int y, int z) throws IOException {
|
public void writeHeader(OutputStream os, int x, int y, int z) throws IOException {
|
||||||
os.write(mode);
|
os.write(mode);
|
||||||
// Allows for version detection of history in case of changes to format.
|
// Allows for version detection of history in case of changes to format.
|
||||||
os.write(version);
|
os.write(VERSION);
|
||||||
setOrigin(x, z);
|
setOrigin(x, z);
|
||||||
os.write((byte) (x >> 24));
|
os.write((byte) (x >> 24));
|
||||||
os.write((byte) (x >> 16));
|
os.write((byte) (x >> 16));
|
||||||
@ -238,8 +266,8 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
public void readHeader(InputStream is) throws IOException {
|
public void readHeader(InputStream is) throws IOException {
|
||||||
// skip mode
|
// skip mode
|
||||||
int mode = is.read();
|
int mode = is.read();
|
||||||
int version = is.read();
|
version = is.read();
|
||||||
if (version != FaweStreamChangeSet.version) {
|
if (version != 1 && version != VERSION) { // version 1 is fine
|
||||||
throw new UnsupportedOperationException(String.format("Version %s history not supported!", version));
|
throw new UnsupportedOperationException(String.format("Version %s history not supported!", version));
|
||||||
}
|
}
|
||||||
// origin
|
// origin
|
||||||
@ -266,12 +294,17 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public long longSize() {
|
||||||
// Flush so we can accurately get the size
|
// Flush so we can accurately get the size
|
||||||
flush();
|
flush();
|
||||||
return blockSize;
|
return blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return (int) longSize();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract int getCompressedSize();
|
public abstract int getCompressedSize();
|
||||||
|
|
||||||
public abstract long getSizeInMemory();
|
public abstract long getSizeInMemory();
|
||||||
@ -304,11 +337,6 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
|
|
||||||
public abstract NBTInputStream getTileRemoveIS() throws IOException;
|
public abstract NBTInputStream getTileRemoveIS() throws IOException;
|
||||||
|
|
||||||
protected int blockSize;
|
|
||||||
|
|
||||||
private int originX;
|
|
||||||
private int originZ;
|
|
||||||
|
|
||||||
public void setOrigin(int x, int z) {
|
public void setOrigin(int x, int z) {
|
||||||
originX = x;
|
originX = x;
|
||||||
originZ = z;
|
originZ = z;
|
||||||
|
@ -217,7 +217,7 @@ public class MainUtil {
|
|||||||
// } else if (changeSet instanceof CPUOptimizedChangeSet) {
|
// } else if (changeSet instanceof CPUOptimizedChangeSet) {
|
||||||
// return changeSet.size() + 32;
|
// return changeSet.size() + 32;
|
||||||
} else if (changeSet != null) {
|
} else if (changeSet != null) {
|
||||||
return changeSet.size() * 128L;
|
return changeSet.longSize() * 128; // Approx
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -500,7 +500,7 @@ public class LocalSession implements TextureHolder {
|
|||||||
if (Settings.settings().HISTORY.USE_DISK) {
|
if (Settings.settings().HISTORY.USE_DISK) {
|
||||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
if (changeSet.size() == 0) {
|
if (changeSet.longSize() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loadSessionHistoryFromDisk(player.getUniqueId(), world);
|
loadSessionHistoryFromDisk(player.getUniqueId(), world);
|
||||||
|
@ -251,7 +251,7 @@ public class HistorySubCommands {
|
|||||||
long seconds = (System.currentTimeMillis() - edit.getBDFile().lastModified()) / 1000;
|
long seconds = (System.currentTimeMillis() - edit.getBDFile().lastModified()) / 1000;
|
||||||
String timeStr = MainUtil.secToTime(seconds);
|
String timeStr = MainUtil.secToTime(seconds);
|
||||||
|
|
||||||
int size = edit.size();
|
long size = edit.longSize();
|
||||||
boolean biomes = edit.getBioFile().exists();
|
boolean biomes = edit.getBioFile().exists();
|
||||||
boolean createdEnts = edit.getEnttFile().exists();
|
boolean createdEnts = edit.getEnttFile().exists();
|
||||||
boolean removedEnts = edit.getEntfFile().exists();
|
boolean removedEnts = edit.getEntfFile().exists();
|
||||||
@ -335,7 +335,7 @@ public class HistorySubCommands {
|
|||||||
long seconds = (System.currentTimeMillis() - rollback.getBDFile().lastModified()) / 1000;
|
long seconds = (System.currentTimeMillis() - rollback.getBDFile().lastModified()) / 1000;
|
||||||
String timeStr = MainUtil.secToTime(seconds);
|
String timeStr = MainUtil.secToTime(seconds);
|
||||||
|
|
||||||
int size = edit.size();
|
long size = edit.longSize();
|
||||||
|
|
||||||
TranslatableComponent elem = Caption.of(
|
TranslatableComponent elem = Caption.of(
|
||||||
"fawe.worldedit.history.find.element",
|
"fawe.worldedit.history.find.element",
|
||||||
|
@ -81,11 +81,24 @@ public interface ChangeSet extends Closeable {
|
|||||||
* Get the number of stored changes.
|
* Get the number of stored changes.
|
||||||
*
|
*
|
||||||
* @return the change count
|
* @return the change count
|
||||||
|
* @deprecated History could be larger than int max value so FAWE prefers {@link ChangeSet#longSize()}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "TODO")
|
||||||
int size();
|
int size();
|
||||||
|
|
||||||
//FAWE start
|
//FAWE start
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of stored changes.
|
||||||
|
* History could be larger than int max value so FAWE prefers this method.
|
||||||
|
*
|
||||||
|
* @return the change count
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
default long longSize() {
|
||||||
|
return size();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the changeset.
|
* Close the changeset.
|
||||||
*/
|
*/
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren