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 boolean ENABLE_HARD_LIMIT = true;
|
||||
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 COMPRESSION_LEVEL = 0;
|
||||
public static int BUFFER_SIZE = 531441;
|
||||
@ -83,6 +85,7 @@ public class Settings {
|
||||
options.put("crash-mitigation", ENABLE_HARD_LIMIT);
|
||||
options.put("lighting.fix-all", FIX_ALL_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.compress", false);
|
||||
options.put("history.chunk-wait-ms", CHUNK_WAIT);
|
||||
@ -132,7 +135,7 @@ public class Settings {
|
||||
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms");
|
||||
ALLOWED_3RDPARTY_EXTENTS = config.getStringList("extent.allowed-plugins");
|
||||
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")) {
|
||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||
|
@ -1,54 +1,166 @@
|
||||
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.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
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.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* // TODO
|
||||
* A clipboard with disk backed storage. (lower memory + loads on crash)
|
||||
* - 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.
|
||||
*
|
||||
* TODO load on join
|
||||
*/
|
||||
public class DiskOptimizedClipboard extends FaweClipboard {
|
||||
|
||||
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
|
||||
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);
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
public List<? extends Entity> getEntities() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
|
||||
return new ArrayList<>(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
||||
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.MemoryOptimizedClipboard;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
@ -73,7 +75,7 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
checkNotNull(region);
|
||||
this.region = region.clone();
|
||||
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.mx = origin.getBlockX();
|
||||
this.my = origin.getBlockY();
|
||||
|
Loading…
Reference in New Issue
Block a user