mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 13:45:36 +01:00
Added option clipboard on disk
This commit is contained in:
parent
912ea44cc8
commit
362490938c
@ -21,6 +21,8 @@ public class Settings {
|
|||||||
public static long MEM_FREE = 95;
|
public static long MEM_FREE = 95;
|
||||||
public static boolean ENABLE_HARD_LIMIT = true;
|
public static boolean ENABLE_HARD_LIMIT = true;
|
||||||
public static boolean STORE_HISTORY_ON_DISK = false;
|
public static boolean STORE_HISTORY_ON_DISK = false;
|
||||||
|
public static boolean STORE_CLIPBOARD_ON_DISK = false;
|
||||||
|
|
||||||
public static int DELETE_HISTORY_AFTER_DAYS = 7;
|
public static int DELETE_HISTORY_AFTER_DAYS = 7;
|
||||||
public static int COMPRESSION_LEVEL = 0;
|
public static int COMPRESSION_LEVEL = 0;
|
||||||
public static int BUFFER_SIZE = 531441;
|
public static int BUFFER_SIZE = 531441;
|
||||||
@ -83,6 +85,7 @@ public class Settings {
|
|||||||
options.put("crash-mitigation", ENABLE_HARD_LIMIT);
|
options.put("crash-mitigation", ENABLE_HARD_LIMIT);
|
||||||
options.put("lighting.fix-all", FIX_ALL_LIGHTING);
|
options.put("lighting.fix-all", FIX_ALL_LIGHTING);
|
||||||
options.put("lighting.async", ASYNC_LIGHTING);
|
options.put("lighting.async", ASYNC_LIGHTING);
|
||||||
|
options.put("clipboard.use-disk", STORE_CLIPBOARD_ON_DISK);
|
||||||
options.put("history.use-disk", STORE_HISTORY_ON_DISK);
|
options.put("history.use-disk", STORE_HISTORY_ON_DISK);
|
||||||
options.put("history.compress", false);
|
options.put("history.compress", false);
|
||||||
options.put("history.chunk-wait-ms", CHUNK_WAIT);
|
options.put("history.chunk-wait-ms", CHUNK_WAIT);
|
||||||
@ -132,7 +135,7 @@ public class Settings {
|
|||||||
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms");
|
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms");
|
||||||
ALLOWED_3RDPARTY_EXTENTS = config.getStringList("extent.allowed-plugins");
|
ALLOWED_3RDPARTY_EXTENTS = config.getStringList("extent.allowed-plugins");
|
||||||
EXTENT_DEBUG = config.getBoolean("extent.debug");
|
EXTENT_DEBUG = config.getBoolean("extent.debug");
|
||||||
|
STORE_CLIPBOARD_ON_DISK = config.getBoolean("clipboard.use-disk");
|
||||||
|
|
||||||
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
|
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
|
||||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||||
|
@ -1,54 +1,166 @@
|
|||||||
package com.boydti.fawe.object.clipboard;
|
package com.boydti.fawe.object.clipboard;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.object.IntegerTrio;
|
import com.boydti.fawe.object.IntegerTrio;
|
||||||
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO
|
|
||||||
* A clipboard with disk backed storage. (lower memory + loads on crash)
|
* A clipboard with disk backed storage. (lower memory + loads on crash)
|
||||||
* - Uses an auto closable RandomAccessFile for getting / setting id / data
|
* - Uses an auto closable RandomAccessFile for getting / setting id / data
|
||||||
* - I don't know how to reduce nbt / entities to O(1) complexity, so it is stored in memory.
|
* - I don't know how to reduce nbt / entities to O(1) complexity, so it is stored in memory.
|
||||||
|
*
|
||||||
|
* TODO load on join
|
||||||
*/
|
*/
|
||||||
public class DiskOptimizedClipboard extends FaweClipboard {
|
public class DiskOptimizedClipboard extends FaweClipboard {
|
||||||
|
|
||||||
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
|
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
|
||||||
private final HashSet<ClipboardEntity> entities;
|
private final HashSet<ClipboardEntity> entities;
|
||||||
|
private final File file;
|
||||||
|
private final byte[] buffer;
|
||||||
|
|
||||||
public DiskOptimizedClipboard(int width, int height, int length) {
|
private volatile RandomAccessFile raf;
|
||||||
|
private long lastAccessed;
|
||||||
|
private int last;
|
||||||
|
|
||||||
|
public DiskOptimizedClipboard(int width, int height, int length, File file) {
|
||||||
super(width, height, length);
|
super(width, height, length);
|
||||||
nbtMap = new HashMap<>();
|
nbtMap = new HashMap<>();
|
||||||
entities = new HashSet<ClipboardEntity>();
|
entities = new HashSet<>();
|
||||||
|
this.file = file;
|
||||||
|
this.buffer = new byte[2];
|
||||||
|
this.lastAccessed = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiskOptimizedClipboard(int width, int height, int length) {
|
||||||
|
this(width, height, length, new File(Fawe.imp().getDirectory(), "clipboard" + File.separator + UUID.randomUUID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void open() throws IOException {
|
||||||
|
this.raf = new RandomAccessFile(file, "rw");
|
||||||
|
long size = width * height * length * 2l;
|
||||||
|
if (raf.length() != size) {
|
||||||
|
raf.setLength(size);
|
||||||
|
}
|
||||||
|
TaskManager.IMP.laterAsync(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (raf != null && System.currentTimeMillis() - lastAccessed > 10000) {
|
||||||
|
try {
|
||||||
|
RandomAccessFile tmp = raf;
|
||||||
|
raf = null;
|
||||||
|
tmp.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else if (raf == null) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
TaskManager.IMP.laterAsync(this, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getBlock(int x, int y, int z) {
|
public BaseBlock getBlock(int x, int y, int z) {
|
||||||
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
|
try {
|
||||||
|
if (raf == null) {
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
lastAccessed = System.currentTimeMillis();
|
||||||
|
int i = x + z * width + y * area;
|
||||||
|
if (i != last + 1) {
|
||||||
|
raf.seek(i << 1);
|
||||||
|
}
|
||||||
|
raf.read(buffer);
|
||||||
|
last = i;
|
||||||
|
int id = ((buffer[1] << 4) + (buffer[0] >> 4));
|
||||||
|
BaseBlock block;
|
||||||
|
if (!FaweCache.hasData(id)) {
|
||||||
|
block = FaweCache.CACHE_BLOCK[id << 4];
|
||||||
|
} else {
|
||||||
|
block = FaweCache.CACHE_BLOCK[(id << 4) + (buffer[0] & 0xf)];
|
||||||
|
}
|
||||||
|
if (FaweCache.hasNBT(id)) {
|
||||||
|
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
||||||
|
if (nbt != null) {
|
||||||
|
block = new BaseBlock(block.getId(), block.getData());
|
||||||
|
block.setNbtData(nbt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return block;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return EditSession.nullBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(int x, int y, int z, BaseBlock block) {
|
public boolean setBlock(int x, int y, int z, BaseBlock block) {
|
||||||
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
|
try {
|
||||||
|
if (raf == null) {
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
lastAccessed = System.currentTimeMillis();
|
||||||
|
int i = x + z * width + y * area;
|
||||||
|
if (i != last + 1) {
|
||||||
|
raf.seek(i << 1);
|
||||||
|
}
|
||||||
|
final int id = block.getId();
|
||||||
|
final int data = block.getData();
|
||||||
|
int combined = (id << 4) + data;
|
||||||
|
buffer[0] = (byte) ((combined) & 0xff);
|
||||||
|
buffer[1] = (byte) (((combined) >> 8) & 0xff);
|
||||||
|
raf.write(buffer);
|
||||||
|
if (FaweCache.hasNBT(id)) {
|
||||||
|
nbtMap.put(new IntegerTrio(x, y, z), block.getNbtData());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
||||||
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
|
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity);
|
||||||
|
entities.add(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends Entity> getEntities() {
|
public List<? extends Entity> getEntities() {
|
||||||
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
|
return new ArrayList<>(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(ClipboardEntity clipboardEntity) {
|
public boolean remove(ClipboardEntity clipboardEntity) {
|
||||||
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
|
return entities.remove(clipboardEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.extent.clipboard;
|
package com.sk89q.worldedit.extent.clipboard;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
|
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
@ -73,7 +75,7 @@ public class BlockArrayClipboard implements Clipboard {
|
|||||||
checkNotNull(region);
|
checkNotNull(region);
|
||||||
this.region = region.clone();
|
this.region = region.clone();
|
||||||
this.size = getDimensions();
|
this.size = getDimensions();
|
||||||
this.IMP = new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
|
this.IMP = Settings.STORE_CLIPBOARD_ON_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
|
||||||
this.origin = region.getMinimumPoint();
|
this.origin = region.getMinimumPoint();
|
||||||
this.mx = origin.getBlockX();
|
this.mx = origin.getBlockX();
|
||||||
this.my = origin.getBlockY();
|
this.my = origin.getBlockY();
|
||||||
|
Loading…
Reference in New Issue
Block a user