Fix data watcher cloning in 1.16

Fixes #925
This commit is contained in:
Dan Mulloy 2020-08-06 14:26:27 -04:00
parent 12e3a895b3
commit b871eb3d54
No known key found for this signature in database
GPG Key ID: 2B62F7DACFF133E8
3 changed files with 43 additions and 4 deletions

View File

@ -35,6 +35,7 @@ import com.google.common.base.Optional;
import com.google.common.collect.ImmutableBiMap;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
@ -132,7 +133,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
MinecraftReflection.getNmsWorldClass(), double.class, double.class, double.class);
}
return fakeEntity = eggConstructor.invoke(null, 0, 0, 0);
Object world = BukkitUnwrapper.getInstance().unwrapItem(Bukkit.getWorlds().get(0));
return fakeEntity = eggConstructor.invoke(world, 0, 0, 0);
}
// ---- Collection Methods
@ -569,7 +571,12 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
ENTITY_FIELD = Accessors.getFieldAccessor(HANDLE_TYPE, MinecraftReflection.getEntityClass(), true);
}
return (Entity) MinecraftReflection.getBukkitEntity(ENTITY_FIELD.get(handle));
Object entity = ENTITY_FIELD.get(handle);
if (entity == null) {
throw new NullPointerException(handle + "." + ENTITY_FIELD);
}
return (Entity) MinecraftReflection.getBukkitEntity(entity);
}
/**

View File

@ -1,17 +1,23 @@
package com.comphenix.protocol;
import java.util.Collections;
import java.util.List;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.utility.Constants;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import net.minecraft.server.v1_16_R1.DispenserRegistry;
import net.minecraft.server.v1_16_R1.WorldServer;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R1.CraftServer;
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.v1_16_R1.util.Versioning;
import org.spigotmc.SpigotWorldConfig;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -69,6 +75,22 @@ public class BukkitInitialization {
when(mockedServer.getItemFactory()).thenReturn(CraftItemFactory.instance());
when(mockedServer.isPrimaryThread()).thenReturn(true);
WorldServer nmsWorld = mock(WorldServer.class);
SpigotWorldConfig mockWorldConfig = mock(SpigotWorldConfig.class);
try {
FieldUtils.writeField(nmsWorld.getClass().getField("spigotConfig"), nmsWorld, mockWorldConfig, true);
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
CraftWorld world = mock(CraftWorld.class);
when(world.getHandle()).thenReturn(nmsWorld);
List<World> worlds = Collections.singletonList(world);
when(mockedServer.getWorlds()).thenReturn(worlds);
// Inject this fake server
Bukkit.setServer(mockedServer);
}

View File

@ -104,4 +104,14 @@ public class WrappedDataWatcherTest {
watcher.setObject(0, serializer, 1);
assertTrue(watcher.hasIndex(0));
}
@Test
public void testDeepClone() {
WrappedDataWatcher watcher = new WrappedDataWatcher();
watcher.setObject(0, Registry.get(Integer.class), 1);
WrappedDataWatcher cloned = watcher.deepClone();
assertEquals(1, cloned.asMap().size());
assertEquals(1, (Object) cloned.getInteger(0));
}
}