Support entities with non nms placer

This commit is contained in:
Jesse Boyd 2017-08-13 16:07:34 +10:00
parent f0066bbd26
commit ae1e05fda4
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
4 changed files with 212 additions and 12 deletions

View File

@ -1,22 +1,37 @@
package com.boydti.fawe.bukkit.v0; package com.boydti.fawe.bukkit.v0;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.MutableBlockVector2D; import com.sk89q.worldedit.MutableBlockVector2D;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.bukkit.BukkitUtil; import com.sk89q.worldedit.bukkit.BukkitUtil;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> { public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
@ -135,6 +150,70 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
final int bx = getX() << 4; final int bx = getX() << 4;
final int bz = getZ() << 4; final int bz = getZ() << 4;
if (layer == -1) { if (layer == -1) {
BukkitImplAdapter adapter = BukkitQueue_0.getAdapter();
if (adapter != null)
{
// Run change task
RunnableVal2<FaweChunk, FaweChunk> task = parent.getChangeTask();
BukkitChunk_All_ReadonlySnapshot previous;
if (task != null){
ChunkSnapshot snapshot = parent.ensureChunkLoaded(getX(), getZ());
previous = new BukkitChunk_All_ReadonlySnapshot(parent, snapshot, biomes != null);
for (BlockState tile : chunk.getTileEntities()) {
int x = tile.getX();
int y = tile.getY();
int z = tile.getZ();
if (getBlockCombinedId(x & 15, y, z & 15) != 0) {
CompoundTag nbt = adapter.getBlock(new Location(world, x, y, z)).getNbtData();
if (nbt != null) {
previous.setTile(x & 15, y, z & 15, nbt);
}
}
}
} else {
previous = null;
}
// Set entities
if (adapter != null) {
Set<CompoundTag> entitiesToSpawn = this.getEntities();
if (!entitiesToSpawn.isEmpty()) {
for (CompoundTag tag : entitiesToSpawn) {
String id = tag.getString("Id");
ListTag posTag = tag.getListTag("Pos");
ListTag rotTag = tag.getListTag("Rotation");
if (id == null || posTag == null || rotTag == null) {
Fawe.debug("Unknown entity tag: " + tag);
continue;
}
double x = posTag.getDouble(0);
double y = posTag.getDouble(1);
double z = posTag.getDouble(2);
float yaw = rotTag.getFloat(0);
float pitch = rotTag.getFloat(1);
Location loc = new Location(world, x, y, z, yaw, pitch);
Entity created = adapter.createEntity(loc, new BaseEntity(id, tag));
if (previous != null) {
UUID uuid = created.getUniqueId();
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
map.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
map.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
}
}
}
HashSet<UUID> entsToRemove = this.getEntityRemoves();
if (!entsToRemove.isEmpty()) {
for (Entity entity : chunk.getEntities()) {
if (entsToRemove.contains(entity.getUniqueId())) {
entity.remove();
}
}
}
}
if (previous != null) {
task.run(previous, this);
}
}
// Biomes // Biomes
if (layer == 0) { if (layer == 0) {
final byte[] biomes = getBiomeArray(); final byte[] biomes = getBiomeArray();

View File

@ -0,0 +1,128 @@
package com.boydti.fawe.bukkit.v0;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.ChunkSnapshot;
import org.bukkit.block.Biome;
public class BukkitChunk_All_ReadonlySnapshot extends FaweChunk {
private final ChunkSnapshot snapshot;
private final boolean hasBiomes;
private Set<CompoundTag> entities = new HashSet<>();
private Map<Short, CompoundTag> tiles = new HashMap<>();
public BukkitChunk_All_ReadonlySnapshot(BukkitQueue_All parent, ChunkSnapshot snapshot, boolean biomes) {
super(parent, snapshot.getX(), snapshot.getZ());
this.snapshot = snapshot;
this.hasBiomes = biomes;
}
public void setTiles(Map<Short, CompoundTag> tiles) {
this.tiles = tiles;
}
public void setEntities(Set<CompoundTag> entities) {
this.entities = entities;
}
@Override
public BukkitQueue_All getParent() {
return (BukkitQueue_All) super.getParent();
}
@Override
public int getBitMask() {
return Character.MAX_VALUE;
}
@Override
public int getBlockCombinedId(int x, int y, int z) {
int id = snapshot.getBlockTypeId(x, y, z);
return FaweCache.getCombined(id, FaweCache.hasData(id) ? snapshot.getBlockData(x, y, z) : 0);
}
@Override
public byte[] getBiomeArray() {
if (!hasBiomes) return null;
BukkitImplAdapter adapter = getParent().getAdapter();
byte[] biomes = new byte[256];
int index = 0;
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++, index++) {
Biome biome = snapshot.getBiome(x, z);
biomes[index] = (byte) adapter.getBiomeId(biome);
}
}
return biomes;
}
@Override
public Object getChunk() {
return snapshot;
}
@Override
public void setTile(int x, int y, int z, CompoundTag tile) {
tiles.put(MathMan.tripleBlockCoord(x, y, z), tile);
}
@Override
public void setEntity(CompoundTag entity) {
entities.add(entity);
}
@Override
public void removeEntity(UUID uuid) {
throw new UnsupportedOperationException("Read only");
}
@Override
public void setBlock(int x, int y, int z, int id, int data) {
throw new UnsupportedOperationException("Read only");
}
@Override
public Set<CompoundTag> getEntities() {
return entities;
}
@Override
public Set<UUID> getEntityRemoves() {
throw new UnsupportedOperationException("Read only");
}
@Override
public Map<Short, CompoundTag> getTiles() {
return tiles;
}
@Override
public CompoundTag getTile(int x, int y, int z) {
if (tiles == null) return null;
short pair = MathMan.tripleBlockCoord(x, y, z);
return tiles.get(pair);
}
@Override
public void setBiome(int x, int z, byte biome) {
throw new UnsupportedOperationException("Read only");
}
@Override
public FaweChunk copy(boolean shallow) {
return null;
}
@Override
public FaweChunk call() {
return null;
}
}

View File

@ -195,6 +195,10 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
fieldAdapter.set(instance, adapter); fieldAdapter.set(instance, adapter);
} else { } else {
BukkitQueue_0.adapter = adapter = (BukkitImplAdapter) fieldAdapter.get(instance); BukkitQueue_0.adapter = adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
if (adapter == null) {
BukkitQueue_0.adapter = adapter = new FaweAdapter_All();
fieldAdapter.set(instance, adapter);
}
} }
if (adapter != null) { if (adapter != null) {
for (Method method : adapter.getClass().getDeclaredMethods()) { for (Method method : adapter.getClass().getDeclaredMethods()) {
@ -214,17 +218,6 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
} catch (Throwable ignore) { } catch (Throwable ignore) {
ignore.printStackTrace(); ignore.printStackTrace();
} }
if (BukkitQueue_0.adapter == null) {
if (backupAdaper == null) {
try {
backupAdaper = new FaweAdapter_All();
Fawe.debug("Native adapter failed. Backup adapter is functional.");
} catch (Throwable ignore) {
Fawe.debug("Native and backup adapter failed! (Try updating the plugin)");
ignore.printStackTrace();
}
}
}
} }
@Override @Override

View File

@ -308,7 +308,7 @@ public class BukkitQueue_All extends BukkitQueue_0<ChunkSnapshot, ChunkSnapshot,
@Override @Override
public boolean supportsChangeTask() { public boolean supportsChangeTask() {
return false; return getAdapter() != null;
} }
private int skip; private int skip;