mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-12 04:23:54 +00:00
Re-implement full Entity support in history, entity removal, entity creation, etc. (#1812)
Co-authored-by: Alexander Brandes <mc.cache@web.de>
This commit is contained in:
@ -67,9 +67,9 @@ import javax.annotation.Nonnull;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -316,21 +316,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
Entity entity = serverLevel.getEntity(uuid);
|
||||
if (entity != null) {
|
||||
org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity();
|
||||
return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData();
|
||||
}
|
||||
for (List<Entity> entry : /*getChunk().getEntitySlices()*/ new List[0]) {
|
||||
if (entry != null) {
|
||||
for (Entity ent : entry) {
|
||||
if (uuid.equals(ent.getUUID())) {
|
||||
org.bukkit.entity.Entity bukkitEnt = ent.getBukkitEntity();
|
||||
return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData();
|
||||
}
|
||||
}
|
||||
for (CompoundTag tag : getEntities()) {
|
||||
if (uuid.equals(tag.getUUID())) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -338,21 +332,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
List<Entity>[] slices = /*getChunk().getEntitySlices()*/ new List[0];
|
||||
int size = 0;
|
||||
for (List<Entity> slice : slices) {
|
||||
if (slice != null) {
|
||||
size += slice.size();
|
||||
}
|
||||
}
|
||||
if (slices.length == 0) {
|
||||
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
|
||||
if (entities.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
int finalSize = size;
|
||||
return new AbstractSet<CompoundTag>() {
|
||||
int size = entities.size();
|
||||
return new AbstractSet<>() {
|
||||
@Override
|
||||
public int size() {
|
||||
return finalSize;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -365,17 +353,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (!(get instanceof CompoundTag getTag)) {
|
||||
return false;
|
||||
}
|
||||
Map<String, Tag> value = getTag.getValue();
|
||||
CompoundTag getParts = (CompoundTag) value.get("UUID");
|
||||
UUID getUUID = new UUID(getParts.getLong("Most"), getParts.getLong("Least"));
|
||||
for (List<Entity> slice : slices) {
|
||||
if (slice != null) {
|
||||
for (Entity entity : slice) {
|
||||
UUID uuid = entity.getUUID();
|
||||
if (uuid.equals(getUUID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
UUID getUUID = getTag.getUUID();
|
||||
for (Entity entity : entities) {
|
||||
UUID uuid = entity.getUUID();
|
||||
if (uuid.equals(getUUID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -384,9 +366,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterator<CompoundTag> iterator() {
|
||||
Iterable<CompoundTag> result = StreamSupport.stream(Iterables.concat(slices).spliterator(), false).map(input -> {
|
||||
Iterable<CompoundTag> result = entities.stream().map(input -> {
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
return (CompoundTag) adapter.toNative(input.saveWithoutId(tag));
|
||||
input.save(tag);
|
||||
return (CompoundTag) adapter.toNative(tag);
|
||||
}).collect(Collectors.toList());
|
||||
return result.iterator();
|
||||
}
|
||||
@ -677,23 +660,31 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
|
||||
syncTasks[2] = () -> {
|
||||
final List<Entity>[] entities = /*nmsChunk.e()*/ new List[0];
|
||||
Set<UUID> entitiesRemoved = new HashSet<>();
|
||||
final List<Entity> entities = PaperweightPlatformAdapter.getEntities(nmsChunk);
|
||||
|
||||
for (final Collection<Entity> ents : entities) {
|
||||
if (!ents.isEmpty()) {
|
||||
final Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final Entity entity = iter.next();
|
||||
if (entityRemoves.contains(entity.getUUID())) {
|
||||
if (createCopy) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
iter.remove();
|
||||
removeEntity(entity);
|
||||
}
|
||||
for (Entity entity : entities) {
|
||||
UUID uuid = entity.getUUID();
|
||||
if (entityRemoves.contains(uuid)) {
|
||||
if (createCopy) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
entitiesRemoved.add(uuid);
|
||||
entityRemoves.remove(uuid);
|
||||
}
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||
for (UUID uuid : entityRemoves) {
|
||||
Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid);
|
||||
if (entity != null) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only save entities that were actually removed to history
|
||||
set.getEntityRemoves().clear();
|
||||
set.getEntityRemoves().addAll(entitiesRemoved);
|
||||
};
|
||||
}
|
||||
|
||||
@ -704,7 +695,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
|
||||
syncTasks[1] = () -> {
|
||||
for (final CompoundTag nativeTag : entities) {
|
||||
Iterator<CompoundTag> iterator = entities.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final CompoundTag nativeTag = iterator.next();
|
||||
final Map<String, Tag> entityTagMap = nativeTag.getValue();
|
||||
final StringTag idTag = (StringTag) entityTagMap.get("Id");
|
||||
final ListTag posTag = (ListTag) entityTagMap.get("Pos");
|
||||
@ -731,12 +724,23 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
entity.load(tag);
|
||||
entity.absMoveTo(x, y, z, yaw, pitch);
|
||||
nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
entity.setUUID(nativeTag.getUUID());
|
||||
if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
|
||||
LOGGER.warn(
|
||||
"Error creating entity of type `{}` in world `{}` at location `{},{},{}`",
|
||||
id,
|
||||
nmsWorld.getWorld().getName(),
|
||||
x,
|
||||
y,
|
||||
z
|
||||
);
|
||||
// Unsuccessful create should not be saved to history
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// set tiles
|
||||
|
@ -80,7 +80,8 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
protected void storeEntity(Entity entity) {
|
||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
|
||||
entities.add((CompoundTag) adapter.toNative(entity.save(compoundTag)));
|
||||
entity.save(compoundTag);
|
||||
entities.add((CompoundTag) adapter.toNative(compoundTag));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,18 +92,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
for (CompoundTag tag : entities) {
|
||||
UUID tagUUID;
|
||||
if (tag.containsKey("UUID")) {
|
||||
int[] arr = tag.getIntArray("UUID");
|
||||
tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL));
|
||||
} else if (tag.containsKey("UUIDMost")) {
|
||||
tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast"));
|
||||
} else if (tag.containsKey("PersistentIDMSB")) {
|
||||
tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB"));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (uuid.equals(tagUUID)) {
|
||||
if (uuid.equals(tag.getUUID())) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.util.SimpleBitStorage;
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import net.minecraft.util.ZeroBitStorage;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
@ -599,6 +600,10 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
static List<Entity> getEntities(LevelChunk chunk) {
|
||||
return chunk.level.entityManager.getEntities(new ChunkPos(chunk.locX, chunk.locZ));
|
||||
}
|
||||
|
||||
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user