FIxes for MCPE

fix fixlighting
fix fixlighting
fix fawe commands not being registered
fix empty configs
fix tile placement
This commit is contained in:
Jesse Boyd 2016-09-05 16:01:39 +10:00
parent 9e297dc34a
commit e610b2fabb
11 changed files with 276 additions and 217 deletions

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.example;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MathMan;
import java.util.ArrayDeque;
@ -171,20 +172,18 @@ public class NMSRelighter {
RelightSkyEntry[] chunks = sorted.toArray(new RelightSkyEntry[sorted.size()]);
byte[] cacheX = FaweCache.CACHE_X[0];
byte[] cacheZ = FaweCache.CACHE_Z[0];
for (int y = 255; y > 0; y--) {
for (int y = FaweChunk.HEIGHT - 1; y > 0; y--) {
for (RelightSkyEntry chunk : chunks) { // Propogate skylight
int layer = y >> 4;
if (!chunk.fix[layer]) {
continue;
}
if (!chunk.fix[layer])continue;
int bx = chunk.x << 4;
int bz = chunk.z << 4;
byte[] mask = chunk.mask;
queue.ensureChunkLoaded(chunk.x, chunk.z);
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
if (sections == null) continue;
if (sections == null)continue;
Object section = queue.getCachedSection(sections, layer);
if (section == null) continue;
if (section == null)continue;
chunk.smooth = false;
for (int j = 0; j < 256; j++) {
int x = cacheX[j];
@ -229,14 +228,14 @@ public class NMSRelighter {
case 9:
case 11:
case 13:
if (opacity == 0) {
if (opacity <= 1) {
mask[j] = --value;
} else {
mask[j] = value = (byte) Math.max(0, value - opacity);
}
break;
case 15:
if (opacity != 0) {
if (opacity > 1) {
value -= opacity;
mask[j] = value;
}

View File

@ -118,7 +118,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent {
@Override
public boolean setBlock(int x, int y, int z, final BaseBlock block) throws WorldEditException {
if (y >= maxY) {
if (y > maxY) {
return false;
}
final short id = (short) block.getId();

View File

@ -14,6 +14,7 @@ import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -26,19 +27,51 @@ import java.util.Map.Entry;
*/
public final class NBTConverter {
private static Field tagsField;
private NBTConverter() {
}
// private static Tag fromNativeSlow(cn.nukkit.nbt.tag.CompoundTag other) {
// try {
// byte[] bytes = NBTIO.write(other);
// FastByteArrayInputStream in = new FastByteArrayInputStream(bytes);
// NBTInputStream nin = new NBTInputStream(in);
// return nin.readNamedTag();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
static {
try {
tagsField = cn.nukkit.nbt.tag.CompoundTag.class.getDeclaredField("tags");
tagsField.setAccessible(true);
} catch (Throwable e) {
e.printStackTrace();
}
}
public static Map<String, cn.nukkit.nbt.tag.Tag> getMap(cn.nukkit.nbt.tag.CompoundTag other) {
try {
return (Map<String, cn.nukkit.nbt.tag.Tag>) tagsField.get(other);
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
public static CompoundTag fromNativeLazy(cn.nukkit.nbt.tag.CompoundTag other) {
try {
Map tags = (Map) tagsField.get(other);
CompoundTag ct = new CompoundTag(tags);
return ct;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
public static cn.nukkit.nbt.tag.CompoundTag toNativeLazy(CompoundTag tag) {
try {
Map map = tag.getValue();
cn.nukkit.nbt.tag.CompoundTag ct = new cn.nukkit.nbt.tag.CompoundTag();
tagsField.set(ct, map);
return ct;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
public static CompoundTag fromNative(cn.nukkit.nbt.tag.CompoundTag other) {
Map<String, cn.nukkit.nbt.tag.Tag> tags = other.getTags();
@ -46,7 +79,8 @@ public final class NBTConverter {
for (Entry<String, cn.nukkit.nbt.tag.Tag> entry : tags.entrySet()) {
map.put(entry.getKey(), fromNative(entry.getValue()));
}
return new CompoundTag(map);
CompoundTag tag = new CompoundTag(map);
return tag;
}
public static cn.nukkit.nbt.tag.Tag toNative(Tag tag) {
@ -127,7 +161,9 @@ public final class NBTConverter {
private static cn.nukkit.nbt.tag.CompoundTag toNative(CompoundTag tag) {
cn.nukkit.nbt.tag.CompoundTag compound = new cn.nukkit.nbt.tag.CompoundTag();
for (Entry<String, Tag> child : tag.getValue().entrySet()) {
compound.put(child.getKey(), toNative(child.getValue()));
cn.nukkit.nbt.tag.Tag value = toNative(child.getValue());
value.setName(child.getKey());
compound.put(child.getKey(), value);
}
return compound;
}

View File

@ -21,6 +21,7 @@ package com.boydti.fawe.nukkit.core;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
import com.sk89q.worldedit.extension.platform.Actor;
@ -42,14 +43,12 @@ import javax.annotation.Nullable;
public class NukkitPlatform extends AbstractPlatform implements MultiUserPlatform {
private final NukkitWorldEdit mod;
private final NukkitTaskManager taskManager;
private boolean hookingEvents = false;
private NukkitCommandManager commandManager;
public NukkitPlatform(NukkitWorldEdit mod) {
this.mod = mod;
this.commandManager = new NukkitCommandManager(mod.getServer().getCommandMap());
this.taskManager = new NukkitTaskManager(mod);
}
boolean isHookingEvents() {
@ -79,7 +78,7 @@ public class NukkitPlatform extends AbstractPlatform implements MultiUserPlatfor
@Override
public int schedule(long delay, long period, Runnable task) {
this.taskManager.repeat(task, (int) period);
TaskManager.IMP.repeat(task, (int) period);
return 0; // TODO This isn't right, but we only check for -1 values
}
@ -93,10 +92,6 @@ public class NukkitPlatform extends AbstractPlatform implements MultiUserPlatfor
return ret;
}
public NukkitTaskManager getTaskManager() {
return taskManager;
}
@Nullable
@Override
public Player matchPlayer(Player player) {

View File

@ -127,7 +127,6 @@ public final class NukkitUtil {
public static com.sk89q.worldedit.entity.Entity createEntity(Level level, Location location, BaseEntity entity) {
// TODO
System.out.print("TODO create entity");
return null;
}

View File

@ -34,8 +34,15 @@ import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import static com.google.common.base.Preconditions.checkNotNull;
@ -66,18 +73,14 @@ public class NukkitWorldEdit extends PluginBase {
@Override
public void onEnable() {
try {
Fawe.set(new FaweNukkit(this));
logger = Logger.getLogger(NukkitWorldEdit.class.getCanonicalName());
File file = new File(getDataFolder(), "config-basic.yml");
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
config = new NukkitConfiguration(new YAMLProcessor(file, true), this);
createDefaultConfiguration("config-basic.yml");
config = new NukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-basic.yml"), true), this);
config.load();
this.platform = new NukkitPlatform(this);
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
WorldEdit.getInstance().getPlatformManager().register(platform);
Fawe.set(new FaweNukkit(this));
logger.info("WorldEdit for Nukkit (version " + getInternalVersion() + ") is loaded");
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
} catch (Throwable e) {
@ -90,6 +93,48 @@ public class NukkitWorldEdit extends PluginBase {
WorldEdit.getInstance().getPlatformManager().unregister(platform);
}
protected void createDefaultConfiguration(String name) throws IOException {
File actual = new File(getDataFolder(), name);
if (!actual.exists()) {
actual.getParentFile().mkdirs();
actual.createNewFile();
InputStream input = null;
try {
JarFile file = new JarFile(getFile());
ZipEntry copy = file.getEntry(name);
if (copy == null) throw new FileNotFoundException();
input = file.getInputStream(copy);
} catch (IOException e) {
getWELogger().severe("Unable to read default configuration: " + name);
}
if (input != null) {
FileOutputStream output = null;
try {
output = new FileOutputStream(actual);
byte[] buf = new byte[8192];
int length;
while ((length = input.read(buf)) > 0) {
output.write(buf, 0, length);
}
getWELogger().info("Default configuration file written: " + name);
} catch (IOException e) {
getWELogger().log(Level.WARNING, "Failed to write default config file", e);
} finally {
try {
input.close();
} catch (IOException ignored) {}
try {
if (output != null) {
output.close();
}
} catch (IOException ignored) {}
}
}
}
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
// Add the command to the array because the underlying command handling

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.nukkit.optimization;
import cn.nukkit.Player;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.IFawe;
import com.boydti.fawe.nukkit.core.NukkitTaskManager;
import com.boydti.fawe.nukkit.core.NukkitWorldEdit;
import com.boydti.fawe.nukkit.optimization.queue.NukkitQueue;
import com.boydti.fawe.object.FaweChunk;
@ -39,7 +40,7 @@ public class FaweNukkit implements IFawe {
@Override
public void setupCommand(String label, final FaweCommand cmd) {
plugin.getServer().getCommandMap().register(label, new NukkitCommand(cmd));
plugin.getServer().getCommandMap().register(label, new NukkitCommand(label, cmd));
}
@Override
@ -71,7 +72,7 @@ public class FaweNukkit implements IFawe {
@Override
public TaskManager getTaskManager() {
return plugin.getPlatform().getTaskManager();
return new NukkitTaskManager(plugin);
}
@Override

View File

@ -11,8 +11,8 @@ public class NukkitCommand extends Command {
private final FaweCommand cmd;
public NukkitCommand(final FaweCommand cmd) {
super(cmd.getPerm());
public NukkitCommand(String lavel, final FaweCommand cmd) {
super(lavel);
this.cmd = cmd;
}

View File

@ -3,17 +3,18 @@ package com.boydti.fawe.nukkit.optimization.queue;
import cn.nukkit.blockentity.BlockEntity;
import cn.nukkit.level.Level;
import cn.nukkit.level.format.generic.BaseFullChunk;
import cn.nukkit.nbt.tag.IntTag;
import cn.nukkit.nbt.tag.Tag;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.nukkit.core.NBTConverter;
import com.boydti.fawe.nukkit.core.NukkitUtil;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.ArrayList;
import java.util.Map;
public class NukkitChunk extends CharFaweChunk<BaseFullChunk> {
@ -38,22 +39,17 @@ public class NukkitChunk extends CharFaweChunk<BaseFullChunk> {
private int index;
private boolean place = true;
public void execute(long start) {
int recommended = 25 + NukkitQueue.ALLOCATE;
boolean more = true;
public void execute() {
NukkitQueue parent = (NukkitQueue) getParent();
Level world = ((NukkitQueue) getParent()).getWorld();
world.clearCache(true);
final BaseFullChunk chunk = (world.getChunk(getX(), getZ(), true));
char[][] sections = getCombinedIdArrays();
if (layer == -1) {
// Biomes
if (layer == 0) {
final int[][] biomes = getBiomeArray();
if (biomes != null) {
final LocalWorld lw = NukkitUtil.getLocalWorld(world);
final int X = getX() << 4;
final int Z = getZ() << 4;
if (biomes != null) {
final LocalWorld lw = NukkitUtil.getLocalWorld(world);
final BaseBiome bb = new BaseBiome(0);
int last = 0;
for (int x = 0; x < 16; x++) {
@ -74,142 +70,48 @@ public class NukkitChunk extends CharFaweChunk<BaseFullChunk> {
}
}
}
}
} else if (index != 0) {
if (place) {
layer--;
} else {
layer++;
}
}
mainloop:
do {
if (place) {
if (++layer >= sections.length) {
place = false;
layer = sections.length - 1;
}
} else if (--layer < 0) {
more = false;
break;
}
try {
// Efficiently merge sections
int changes = getCount(layer);
int lighting = getRelight(layer);
if (changes == 0) {
for (int layer = 0; layer < sections.length; layer++) {
char[] ids = sections[layer];
if (ids == null) {
continue;
}
final char[] newArray = sections[layer];
if (newArray == null) {
continue;
}
final byte[] cacheX = FaweCache.CACHE_X[layer];
final short[] cacheY = FaweCache.CACHE_Y[layer];
final byte[] cacheZ = FaweCache.CACHE_Z[layer];
boolean checkTime = !((getAir(layer) == 4096 || (getCount(layer) == 4096 && getAir(layer) == 0) || (getCount(layer) == getAir(layer))) && getRelight(layer) == 0);
if (!checkTime) {
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int k = 0; k < 16; k++) {
final int l = k << 8;
final int y = cacheY[l];
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int m = l; m < l + 256; m++) {
char combined = newArray[m];
int by = layer << 4;
int index = 0;
for (int y = by; y < by + 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++,index++) {
char combined = ids[index];
switch (combined) {
case 0:
continue;
case 1:
if (!place) {
int x = cacheX[m];
int z = cacheZ[m];
chunk.setBlockId(x, y, z, 0);
}
continue;
default:
if (place) {
int x = cacheX[m];
int z = cacheZ[m];
int id = combined >> 4;
chunk.setBlockId(x, y, z, id);
chunk.setBlockData(x, y, z, (combined & 0xF));
}
continue;
}
}
}
});
threads.add(thread);
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
} else {
for (;index < 4096; index++) {
int j = place ? index : 4095 - index;
char combined = newArray[j];
switch (combined) {
case 0:
continue;
case 1:
if (!place) {
int x = cacheX[j];
int z = cacheZ[j];
int y = cacheY[j];
chunk.setBlockId(x, y, z, 0);
}
break;
default:
int id = combined >> 4;
boolean light = FaweCache.hasLight(id);
if (light) {
if (place) {
continue;
}
} else if (!place) {
continue;
}
if (light != place) {
int data = combined & 0xF;
int x = cacheX[j];
int z = cacheZ[j];
int y = cacheY[j];
int id = FaweCache.getId(combined);
int data = FaweCache.getData(combined);
chunk.setBlockId(x, y, z, id);
chunk.setBlockData(x, y, z, data);
if (FaweCache.hasNBT(id)) {
CompoundTag tile = getTile(x, y, z);
if (tile != null) {
cn.nukkit.nbt.tag.CompoundTag tag = (cn.nukkit.nbt.tag.CompoundTag) NBTConverter.toNative(tile);
chunk.addBlockEntity(new BlockEntity(chunk, tag) {
@Override
public boolean isBlockEntityValid() {
return getBlock().getId() == id;
String tileId = tag.getString("id");
Map<String, Tag> map = NBTConverter.getMap(tag);
map.put("x", new IntTag("x", X + x));
map.put("y", new IntTag("y", y));
map.put("z", new IntTag("z", Z + z));
BlockEntity ent = BlockEntity.createBlockEntity(tileId, chunk, tag);
if (ent != null) {
chunk.addBlockEntity(ent);
}
});
break;
}
}
} else {
continue;
}
break;
}
if (checkTime && System.currentTimeMillis() - start > recommended) {
index++;
break mainloop;
}
}
index = 0;
}
} catch (final Throwable e) {
MainUtil.handleError(e);
}
} while (System.currentTimeMillis() - start < recommended);
if (more || place) {
this.addToQueue();
}
}
}
}

View File

@ -1,12 +1,12 @@
package com.boydti.fawe.nukkit.optimization.queue;
import cn.nukkit.Player;
import cn.nukkit.block.Block;
import cn.nukkit.blockentity.BlockEntity;
import cn.nukkit.level.Level;
import cn.nukkit.level.Position;
import cn.nukkit.level.format.generic.BaseFullChunk;
import cn.nukkit.math.Vector3;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.CharFaweChunk;
@ -15,6 +15,7 @@ import com.boydti.fawe.nukkit.core.NBTConverter;
import com.boydti.fawe.nukkit.optimization.FaweNukkit;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
import java.io.File;
import java.util.Collection;
@ -45,14 +46,26 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
}
@Override
public boolean execute(FaweChunk fc) {
if (super.execute(fc)) {
return true;
} else {
return false;
public int getOpacity(BaseFullChunk section, int x, int y, int z) {
int id = section.getBlockId(x & 15, y, z & 15);
return Block.lightFilter[id];
}
@Override
public int getBrightness(BaseFullChunk section, int x, int y, int z) {
int id = section.getBlockId(x & 15, y, z & 15);
return Block.light[id];
}
@Override
public int getOpacityBrightnessPair(BaseFullChunk section, int x, int y, int z) {
int id = section.getBlockId(x & 15, y, z & 15);
int opacity = Block.lightFilter[id];
int brightness = Block.light[id];
return MathMan.pair16(opacity, brightness);
}
@Override
public void refreshChunk(FaweChunk fs) {
NukkitChunk fc = (NukkitChunk) fs;
@ -78,16 +91,7 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
@Override
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
if (skip > 0) {
skip--;
fc.addToQueue();
return true;
}
long start = System.currentTimeMillis();
((NukkitChunk) fc).execute(start);
if (System.currentTimeMillis() - start > 50 || Fawe.get().getTPS() < TPS_TARGET) {
skip = 10;
}
((NukkitChunk) fc).execute();
return true;
}
@ -150,12 +154,12 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
@Override
public void setSkyLight(BaseFullChunk chunkSection, int x, int y, int z, int value) {
chunkSection.setBlockSkyLight(x & 15, y & 15, z & 15, value);
chunkSection.setBlockSkyLight(x & 15, y, z & 15, value);
}
@Override
public void setBlockLight(BaseFullChunk chunkSection, int x, int y, int z, int value) {
chunkSection.setBlockLight(x & 15, y & 15, z & 15, value);
chunkSection.setBlockLight(x & 15, y, z & 15, value);
}
@Override
@ -201,15 +205,20 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
@Override
public BaseFullChunk getCachedSections(Level level, int cx, int cz) {
BaseFullChunk chunk = (BaseFullChunk) world.getChunk(cx, cz);
BaseFullChunk chunk = world.getChunk(cx, cz);
return chunk;
}
@Override
public BaseFullChunk getCachedSection(BaseFullChunk baseFullChunk, int cy) {
return baseFullChunk;
}
@Override
public int getCombinedId4Data(BaseFullChunk chunkSection, int x, int y, int z) {
int id = chunkSection.getBlockId(x & 15, y & 15, z & 15);
int id = chunkSection.getBlockId(x & 15, y, z & 15);
if (FaweCache.hasData(id)) {
int data = chunkSection.getBlockData(x & 15, y & 15, z & 15);
int data = chunkSection.getBlockData(x & 15, y, z & 15);
return (id << 4) + data;
} else {
return (id << 4);
@ -218,11 +227,11 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
@Override
public int getSkyLight(BaseFullChunk sections, int x, int y, int z) {
return sections.getBlockSkyLight(x & 15, y & 15, z & 15);
return sections.getBlockSkyLight(x & 15, y, z & 15);
}
@Override
public int getEmmittedLight(BaseFullChunk sections, int x, int y, int z) {
return sections.getBlockLight(x & 15, y & 15, z & 15);
return sections.getBlockLight(x & 15, y, z & 15);
}
}

View File

@ -0,0 +1,73 @@
#
# WorldEdit's configuration file
#
# About editing this file:
# - DO NOT USE TABS. You MUST use spaces or Bukkit will complain. If
# you use an editor like Notepad++ (recommended for Windows users), you
# must configure it to "replace tabs with spaces." In Notepad++, this can
# be changed in Settings > Preferences > Language Menu.
# - Don't get rid of the indents. They are indented so some entries are
# in categories (like "max-blocks-changed" is in the "limits"
# category.
# - If you want to check the format of this file before putting it
# into WorldEdit, paste it into http://yaml-online-parser.appspot.com/
# and see if it gives "ERROR:".
# - Lines starting with # are commentsand so they are ignored.
#
limits:
allow-extra-data-values: false
max-blocks-changed:
default: -1
maximum: -1
max-polygonal-points:
default: -1
maximum: 20
max-radius: -1
max-super-pickaxe-size: 5
max-brush-radius: 5
butcher-radius:
default: -1
maximum: -1
disallowed-blocks: [6, 7, 14, 15, 16, 26, 27, 28, 29, 39, 31, 32, 33, 34, 36, 37, 38, 39, 40, 46, 50, 51, 56, 59, 69, 73, 74, 75, 76, 77, 81, 83]
use-inventory:
enable: false
allow-override: true
creative-mode-overrides: false
logging:
log-commands: false
file: worldedit.log
super-pickaxe:
drop-items: true
many-drop-items: false
snapshots:
directory:
navigation-wand:
item: 345
max-distance: 100
scripting:
timeout: 3000
dir: craftscripts
saving:
dir: schematics
files:
allow-symbolic-links: false
history:
size: 15
expiration: 10
wand-item: 271
shell-save-type:
no-double-slash: false
no-op-permissions: false
debug: false
show-help-on-first-use: true