Update for 1.21, fix a small bug or two

This commit is contained in:
libraryaddict 2024-06-26 17:53:42 +12:00
parent 5be355cf4d
commit e9d7e8fe24
16 changed files with 793 additions and 69 deletions

View File

@ -32,6 +32,7 @@
<module>v1_20_R2</module>
<module>v1_20_R3</module>
<module>v1_20_R4</module>
<module>v1_21_R1</module>
</modules>
</project>

View File

@ -73,7 +73,12 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ReflectionManager implements ReflectionManagerAbstract {
private Field dataItemsField;
private final Field trackedEntityField;
private final AtomicInteger entityCounter;
private final Method entityDefaultSoundMethod;
private final Method itemMetaDeserialize;
@SneakyThrows
public ReflectionManager() {
for (Field f : SynchedEntityData.class.getDeclaredFields()) {
if (Modifier.isStatic(f.getModifiers()) || !Int2ObjectMap.class.isAssignableFrom(f.getType())) {
@ -83,6 +88,20 @@ public class ReflectionManager implements ReflectionManagerAbstract {
f.setAccessible(true);
dataItemsField = f;
}
Field entityCounter = net.minecraft.world.entity.Entity.class.getDeclaredField("d");
entityCounter.setAccessible(true);
this.entityCounter = (AtomicInteger) entityCounter.get(null);
trackedEntityField = ChunkMap.TrackedEntity.class.getDeclaredField("b");
trackedEntityField.setAccessible(true);
// Default is protected method, 1.0F on EntityLiving.class
entityDefaultSoundMethod = net.minecraft.world.entity.LivingEntity.class.getDeclaredMethod("eW");
entityDefaultSoundMethod.setAccessible(true);
Class<?> aClass = Class.forName("org.bukkit.craftbukkit.v1_20_R3.inventory.CraftMetaItem$SerializableMeta");
itemMetaDeserialize = aClass.getDeclaredMethod("deserialize", Map.class);
}
public boolean hasInvul(Entity entity) {
@ -108,20 +127,11 @@ public class ReflectionManager implements ReflectionManagerAbstract {
@Override
public int getNewEntityId(boolean increment) {
try {
Field entityCounter = net.minecraft.world.entity.Entity.class.getDeclaredField("d");
entityCounter.setAccessible(true);
AtomicInteger atomicInteger = (AtomicInteger) entityCounter.get(null);
if (increment) {
return atomicInteger.incrementAndGet();
} else {
return atomicInteger.get();
}
} catch (ReflectiveOperationException e) {
e.printStackTrace();
if (increment) {
return entityCounter.incrementAndGet();
} else {
return entityCounter.get();
}
return -1;
}
@Override
@ -211,10 +221,7 @@ public class ReflectionManager implements ReflectionManagerAbstract {
return null;
}
Field field = ChunkMap.TrackedEntity.class.getDeclaredField("b");
field.setAccessible(true);
return (ServerEntity) field.get(trackedEntity);
return (ServerEntity) trackedEntityField.get(trackedEntity);
}
@Override
@ -251,11 +258,8 @@ public class ReflectionManager implements ReflectionManagerAbstract {
return 0.0f;
} else {
try {
Method method = net.minecraft.world.entity.LivingEntity.class.getDeclaredMethod("eW");
method.setAccessible(true);
return (Float) method.invoke(entity);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
return (Float) entityDefaultSoundMethod.invoke(entity);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
@ -358,11 +362,7 @@ public class ReflectionManager implements ReflectionManagerAbstract {
@Override
public ItemMeta getDeserializedItemMeta(Map<String, Object> meta) {
try {
Class<?> aClass = Class.forName("org.bukkit.craftbukkit.v1_20_R3.inventory.CraftMetaItem$SerializableMeta");
Method deserialize = aClass.getDeclaredMethod("deserialize", Map.class);
Object itemMeta = deserialize.invoke(null, meta);
return (ItemMeta) itemMeta;
return (ItemMeta) itemMetaDeserialize.invoke(null, meta);
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -58,6 +58,7 @@ import org.bukkit.craftbukkit.v1_20_R4.entity.CraftFrog;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftWolf;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R4.inventory.SerializableMeta;
import org.bukkit.craftbukkit.v1_20_R4.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_R4.util.CraftNamespacedKey;
import org.bukkit.entity.Cat;
@ -80,7 +81,11 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ReflectionManager implements ReflectionManagerAbstract {
private Field dataItemsField;
private final Field trackedEntityField;
private final AtomicInteger entityCounter;
private final Method entityDefaultSoundMethod;
@SneakyThrows
public ReflectionManager() {
for (Field f : SynchedEntityData.class.getDeclaredFields()) {
if (!f.getType().isArray()) {
@ -90,6 +95,17 @@ public class ReflectionManager implements ReflectionManagerAbstract {
f.setAccessible(true);
dataItemsField = f;
}
Field entityCounter = net.minecraft.world.entity.Entity.class.getDeclaredField("c");
entityCounter.setAccessible(true);
this.entityCounter = (AtomicInteger) entityCounter.get(null);
trackedEntityField = ChunkMap.TrackedEntity.class.getDeclaredField("b");
trackedEntityField.setAccessible(true);
// Default is protected method, 1.0F on EntityLiving.class
entityDefaultSoundMethod = net.minecraft.world.entity.LivingEntity.class.getDeclaredMethod("fe");
entityDefaultSoundMethod.setAccessible(true);
}
public boolean hasInvul(Entity entity) {
@ -115,20 +131,11 @@ public class ReflectionManager implements ReflectionManagerAbstract {
@Override
public int getNewEntityId(boolean increment) {
try {
Field entityCounter = net.minecraft.world.entity.Entity.class.getDeclaredField("c");
entityCounter.setAccessible(true);
AtomicInteger atomicInteger = (AtomicInteger) entityCounter.get(null);
if (increment) {
return atomicInteger.incrementAndGet();
} else {
return atomicInteger.get();
}
} catch (ReflectiveOperationException e) {
e.printStackTrace();
if (increment) {
return entityCounter.incrementAndGet();
} else {
return entityCounter.get();
}
return -1;
}
@Override
@ -218,10 +225,7 @@ public class ReflectionManager implements ReflectionManagerAbstract {
return null;
}
Field field = ChunkMap.TrackedEntity.class.getDeclaredField("b");
field.setAccessible(true);
return (ServerEntity) field.get(trackedEntity);
return (ServerEntity) trackedEntityField.get(trackedEntity);
}
@Override
@ -258,11 +262,8 @@ public class ReflectionManager implements ReflectionManagerAbstract {
return 0.0f;
} else {
try {
Method method = net.minecraft.world.entity.LivingEntity.class.getDeclaredMethod("fe");
method.setAccessible(true);
return (Float) method.invoke(entity);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
return (Float) entityDefaultSoundMethod.invoke(entity);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
@ -365,12 +366,8 @@ public class ReflectionManager implements ReflectionManagerAbstract {
@Override
public ItemMeta getDeserializedItemMeta(Map<String, Object> meta) {
try {
Class<?> aClass = Class.forName("org.bukkit.craftbukkit.v1_20_R4.inventory.CraftMetaItem$SerializableMeta");
Method deserialize = aClass.getDeclaredMethod("deserialize", Map.class);
Object itemMeta = deserialize.invoke(null, meta);
return (ItemMeta) itemMeta;
} catch (Exception e) {
return SerializableMeta.deserialize(meta);
} catch (Throwable e) {
e.printStackTrace();
}

120
nms/v1_21_R1/pom.xml Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nms</artifactId>
<groupId>LibsDisguises</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>v1_21_R1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spigot.version>1.21-R0.1-SNAPSHOT</spigot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>${spigot.version}</version>
<classifier>remapped-mojang</classifier>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${spigot.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.5.8</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>6.0.54</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>datafixerupper</artifactId>
<version>7.0.14</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>brigadier</artifactId>
<version>1.2.9</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>4.1.90.Final</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.md-5</groupId>
<artifactId>specialsource-maven-plugin</artifactId>
<version>2.0.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-obf</id>
<configuration>
<srgIn>org.spigotmc:minecraft-server:${spigot.version}:txt:maps-mojang</srgIn>
<reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:${spigot.version}:jar:remapped-mojang</remappedDependencies>
<remappedClassifierName>remapped-mojang</remappedClassifierName>
<remappedArtifactAttached>true</remappedArtifactAttached>
</configuration>
</execution>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-spigot</id>
<configuration>
<inputFile>target/${project.build.finalName}-remapped-mojang.jar</inputFile>
<srgIn>org.spigotmc:minecraft-server:${spigot.version}:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:${spigot.version}:jar:remapped-obf</remappedDependencies>
<remappedClassifierName>remapped-spigot</remappedClassifierName>
<remappedArtifactAttached>true</remappedArtifactAttached>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,481 @@
package me.libraryaddict.disguise.utilities.reflection.v1_21_R1;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.JavaOps;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.SneakyThrows;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManagerAbstract;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerEntity;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.animal.CatVariant;
import net.minecraft.world.entity.animal.FrogVariant;
import net.minecraft.world.entity.animal.WolfVariant;
import net.minecraft.world.entity.decoration.PaintingVariant;
import net.minecraft.world.entity.player.ChatVisiblity;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_21_R1.CraftArt;
import org.bukkit.craftbukkit.v1_21_R1.CraftServer;
import org.bukkit.craftbukkit.v1_21_R1.CraftSound;
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftCat;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftFrog;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftWolf;
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_21_R1.inventory.SerializableMeta;
import org.bukkit.craftbukkit.v1_21_R1.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_21_R1.util.CraftNamespacedKey;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
public class ReflectionManager implements ReflectionManagerAbstract {
private Field dataItemsField;
private final Field trackedEntityField;
private final AtomicInteger entityCounter;
private final Method entityDefaultSoundMethod;
@SneakyThrows
public ReflectionManager() {
for (Field f : SynchedEntityData.class.getDeclaredFields()) {
if (!f.getType().isArray()) {
continue;
}
f.setAccessible(true);
dataItemsField = f;
}
Field entityCounter = net.minecraft.world.entity.Entity.class.getDeclaredField("c");
entityCounter.setAccessible(true);
this.entityCounter = (AtomicInteger) entityCounter.get(null);
trackedEntityField = ChunkMap.TrackedEntity.class.getDeclaredField("b");
trackedEntityField.setAccessible(true);
// Default is protected method, 1.0F on EntityLiving.class
entityDefaultSoundMethod = net.minecraft.world.entity.LivingEntity.class.getDeclaredMethod("fa");
entityDefaultSoundMethod.setAccessible(true);
}
public boolean hasInvul(Entity entity) {
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
if (nmsEntity instanceof net.minecraft.world.entity.LivingEntity) {
return nmsEntity.invulnerableTime > 0;
} else {
return nmsEntity.isInvulnerableTo(nmsEntity.damageSources().generic());
}
}
@Override
public int getIncrementedStateId(Player player) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
return serverPlayer.containerMenu.incrementStateId(); // TODO Check correct container
}
@Override
public int getNewEntityId() {
return getNewEntityId(true);
}
@Override
public int getNewEntityId(boolean increment) {
if (increment) {
return entityCounter.incrementAndGet();
} else {
return entityCounter.get();
}
}
@Override
public ServerGamePacketListenerImpl getPlayerConnectionOrPlayer(Player player) {
return ((CraftPlayer) player).getHandle().connection;
}
@Override
public net.minecraft.world.entity.Entity createEntityInstance(String entityName) {
Optional<net.minecraft.world.entity.EntityType<?>> optional =
net.minecraft.world.entity.EntityType.byString(entityName.toLowerCase(Locale.ENGLISH));
if (!optional.isPresent()) {
return null;
}
net.minecraft.world.entity.EntityType<?> entityType = optional.get();
ServerLevel world = getWorldServer(Bukkit.getWorlds().get(0));
net.minecraft.world.entity.Entity entity;
if (entityType == net.minecraft.world.entity.EntityType.PLAYER) {
GameProfile gameProfile = new GameProfile(new UUID(0, 0), "Steve");
ClientInformation information =
new ClientInformation("english", 10, ChatVisiblity.FULL, true, 0, HumanoidArm.RIGHT, true, true);
entity = new ServerPlayer(getMinecraftServer(), world, gameProfile, information);
} else {
entity = entityType.create(world);
}
if (entity == null) {
return null;
}
// Workaround for paper being 2 smart 4 me
entity.setPos(1.0, 1.0, 1.0);
entity.setPos(0.0, 0.0, 0.0);
return entity;
}
@Override
public AABB getBoundingBox(Entity entity) {
return ((CraftEntity) entity).getHandle().getBoundingBox();
}
@Override
public double getXBoundingBox(Entity entity) {
return getBoundingBox(entity).maxX - getBoundingBox(entity).minX;
}
@Override
public double getYBoundingBox(Entity entity) {
return getBoundingBox(entity).maxY - getBoundingBox(entity).minY;
}
@Override
public double getZBoundingBox(Entity entity) {
return getBoundingBox(entity).maxZ - getBoundingBox(entity).minZ;
}
@Override
public ServerPlayer getPlayerFromPlayerConnection(Object nmsEntity) {
return ((ServerPlayerConnection) nmsEntity).getPlayer();
}
@Override
public Entity getBukkitEntity(Object nmsEntity) {
return ((net.minecraft.world.entity.Entity) nmsEntity).getBukkitEntity();
}
@Override
public ItemStack getBukkitItem(Object nmsItem) {
return CraftItemStack.asBukkitCopy((net.minecraft.world.item.ItemStack) nmsItem);
}
@Override
public ItemStack getCraftItem(ItemStack bukkitItem) {
return CraftItemStack.asCraftCopy(bukkitItem);
}
@Override
public ServerEntity getEntityTrackerEntry(Entity target) throws Exception {
ServerLevel world = ((CraftWorld) target.getWorld()).getHandle();
ServerChunkCache chunkSource = world.getChunkSource();
ChunkMap chunkMap = chunkSource.chunkMap;
Int2ObjectMap<ChunkMap.TrackedEntity> entityMap = chunkMap.entityMap;
ChunkMap.TrackedEntity trackedEntity = entityMap.get(target.getEntityId());
if (trackedEntity == null) {
return null;
}
return (ServerEntity) trackedEntityField.get(trackedEntity);
}
@Override
public DedicatedServer getMinecraftServer() {
return ((CraftServer) Bukkit.getServer()).getServer();
}
@Override
public Object getNmsEntity(Entity entity) {
return ((CraftEntity) entity).getHandle();
}
@Override
public double getPing(Player player) {
return player.getPing();
}
@Override
public float[] getSize(Entity entity) {
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
EntityDimensions dimensions = nmsEntity.getDimensions(net.minecraft.world.entity.Pose.STANDING);
return new float[]{dimensions.width(), nmsEntity.getEyeHeight()};
}
@Override
public MinecraftSessionService getMinecraftSessionService() {
return getMinecraftServer().getSessionService();
}
@Override
public Float getSoundModifier(Object entity) {
// Default is 1.0F on EntityLiving
if (!(entity instanceof net.minecraft.world.entity.LivingEntity)) {
return 0.0f;
} else {
try {
return (Float) entityDefaultSoundMethod.invoke(entity);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
return 0f;
}
@Override
public void injectCallback(String playername, ProfileLookupCallback callback) {
getMinecraftServer().getProfileRepository().findProfilesByNames(new String[]{playername}, callback);
}
@Override
public void setBoundingBox(Entity entity, double x, double y, double z) {
Location loc = entity.getLocation();
((CraftEntity) entity).getHandle().setBoundingBox(
new AABB(loc.getX() - x / 2, loc.getY() - y / 2, loc.getZ() - z / 2, loc.getX() + x / 2, loc.getY() + y / 2,
loc.getZ() + z / 2));
}
@Override
public String getSoundString(Sound sound) {
return CraftSound.bukkitToMinecraft(sound).getLocation().toString();
}
@Override
public Material getMaterial(String name) {
return CraftMagicNumbers.INSTANCE.getMaterial(name, CraftMagicNumbers.INSTANCE.getDataVersion());
}
@Override
public String getItemName(Material material) {
return BuiltInRegistries.ITEM.getKey(CraftMagicNumbers.getItem(material)).getPath();
}
@Override
public ResourceLocation createMinecraftKey(String name) {
return ResourceLocation.withDefaultNamespace(name);
}
@Override
public net.minecraft.world.entity.EntityType getEntityType(EntityType entityType) {
return net.minecraft.world.entity.EntityType.byString(
entityType.getName() == null ? entityType.name().toLowerCase(Locale.ENGLISH) : entityType.getName()).orElse(null);
}
@Override
public Object registerEntityType(NamespacedKey key) {
net.minecraft.world.entity.EntityType<net.minecraft.world.entity.Entity> newEntity =
new net.minecraft.world.entity.EntityType<>(null, null, false, false, false, false, null, null, 0, 0, 0, FeatureFlagSet.of());
Registry.register(BuiltInRegistries.ENTITY_TYPE, CraftNamespacedKey.toMinecraft(key), newEntity);
newEntity.getDescriptionId();
return newEntity; // TODO ??? Some reflection in legacy that I'm unsure about
}
@Override
public int getEntityTypeId(Object entityTypes) {
net.minecraft.world.entity.EntityType entityType = (net.minecraft.world.entity.EntityType) entityTypes;
return BuiltInRegistries.ENTITY_TYPE.getId(entityType);
}
@Override
public int getEntityTypeId(EntityType entityType) {
return getEntityTypeId(getEntityType(entityType));
}
@Override
public Object getEntityType(NamespacedKey name) {
return BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(name));
}
@Override
public int getCombinedIdByBlockData(BlockData data) {
BlockState state = ((CraftBlockData) data).getState();
return Block.getId(state);
}
@Override
public int getCombinedIdByItemStack(ItemStack itemStack) {
Block block = CraftMagicNumbers.getBlock(itemStack.getType());
return Block.getId(block.defaultBlockState());
}
@Override
public BlockData getBlockDataByCombinedId(int id) {
return CraftBlockData.fromData(Block.stateById(id));
}
@Override
public ItemStack getItemStackByCombinedId(int id) {
return new ItemStack(CraftMagicNumbers.getMaterial(Block.stateById(id).getBlock()));
}
@Override
public ServerLevel getWorldServer(World w) {
return ((CraftWorld) w).getHandle();
}
@Override
public ItemMeta getDeserializedItemMeta(Map<String, Object> meta) {
try {
return SerializableMeta.deserialize(meta);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
@SneakyThrows
@Override
public ByteBuf getDataWatcherValues(Entity entity) {
SynchedEntityData watcher = ((CraftEntity) entity).getHandle().getEntityData();
SynchedEntityData.DataItem[] dataItems = (SynchedEntityData.DataItem[]) dataItemsField.get(watcher);
ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer();
RegistryFriendlyByteBuf serializer = RegistryFriendlyByteBuf.decorator(this.getMinecraftServer().registryAccess()).apply(buf);
for (SynchedEntityData.DataItem dataItem : dataItems) {
dataItem.value().write(serializer);
}
serializer.writeByte(255);
return buf;
}
@Override
public GameProfile getMCGameProfile(Player player) {
return ((CraftPlayer) player).getProfile();
}
@Override
public Cat.Type getCatTypeFromInt(int catType) {
Registry<CatVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.CAT_VARIANT);
Holder.Reference<CatVariant> ref = registry.getHolder(catType).get();
return CraftCat.CraftType.minecraftHolderToBukkit(registry.getHolder(catType).get());
}
@Override
public int getCatVariantAsInt(Cat.Type type) {
Registry<CatVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.CAT_VARIANT);
return registry.getId(CraftCat.CraftType.bukkitToMinecraft(type));
}
@Override
public Frog.Variant getFrogVariantFromInt(int frogType) {
Registry<FrogVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.FROG_VARIANT);
Holder.Reference<FrogVariant> ref = registry.getHolder(frogType).get();
return CraftFrog.CraftVariant.minecraftHolderToBukkit(registry.getHolder(frogType).get());
}
@Override
public int getFrogVariantAsInt(Frog.Variant type) {
Registry<FrogVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.FROG_VARIANT);
return registry.getId(CraftFrog.CraftVariant.bukkitToMinecraft(type));
}
@Override
public Art getPaintingFromInt(int paintingId) {
Registry<PaintingVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.PAINTING_VARIANT);
Holder.Reference<PaintingVariant> ref = registry.getHolder(paintingId).get();
return CraftArt.minecraftHolderToBukkit(registry.getHolder(paintingId).get());
}
@Override
public int getPaintingAsInt(Art type) {
Registry<PaintingVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.PAINTING_VARIANT);
return registry.getId(CraftArt.bukkitToMinecraft(type));
}
@Override
public Wolf.Variant getWolfVariantFromInt(int wolfVariant) {
Registry<WolfVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.WOLF_VARIANT);
Holder.Reference<WolfVariant> ref = registry.getHolder(wolfVariant).get();
return CraftWolf.CraftVariant.minecraftHolderToBukkit(registry.getHolder(wolfVariant).get());
}
@Override
public int getWolfVariantAsInt(Wolf.Variant type) {
Registry<WolfVariant> registry = MinecraftServer.getDefaultRegistryAccess().registryOrThrow(Registries.WOLF_VARIANT);
return registry.getId(CraftWolf.CraftVariant.bukkitToMinecraft(type));
}
@Override
public Object serializeComponents(ItemStack itemStack) {
if (itemStack == null) {
return null;
}
net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(itemStack);
DataComponentPatch comps = item.getComponentsPatch();
if (comps == null) {
return null;
}
DataResult<Object> cond = DataComponentPatch.CODEC.encodeStart(JavaOps.INSTANCE, comps);
return cond.result().orElse(null);
}
}

View File

@ -239,6 +239,14 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>LibsDisguises</groupId>
<artifactId>v1_21_R1</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>remapped-spigot</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- Libraries -->
<dependency>
<groupId>it.unimi.dsi</groupId>

View File

@ -21,7 +21,7 @@ public enum DisguiseType {
AREA_EFFECT_CLOUD(3),
@NmsAddedIn(NmsVersion.UNSUPPORTED) ARMADILLO,
@NmsAddedIn(NmsVersion.v1_21_R1) ARMADILLO,
ARMOR_STAND(78),
@ -39,11 +39,11 @@ public enum DisguiseType {
BOAT(1),
@NmsAddedIn(NmsVersion.UNSUPPORTED) BOGGED,
@NmsAddedIn(NmsVersion.v1_21_R1) BOGGED,
@NmsAddedIn(NmsVersion.UNSUPPORTED) BREEZE,
@NmsAddedIn(NmsVersion.v1_21_R1) BREEZE,
@NmsAddedIn(NmsVersion.UNSUPPORTED) BREEZE_WIND_CHARGE,
@NmsAddedIn(NmsVersion.v1_21_R1) BREEZE_WIND_CHARGE,
@NmsAddedIn(NmsVersion.v1_20_R1) CAMEL,
@ -167,7 +167,7 @@ public enum DisguiseType {
OCELOT,
@NmsAddedIn(NmsVersion.UNSUPPORTED) OMINOUS_ITEM_SPAWNER,
@NmsAddedIn(NmsVersion.v1_21_R1) OMINOUS_ITEM_SPAWNER,
PAINTING,
@ -263,7 +263,7 @@ public enum DisguiseType {
@NmsAddedIn(NmsVersion.v1_19_R1) WARDEN,
@NmsAddedIn(NmsVersion.UNSUPPORTED) WIND_CHARGE,
@NmsAddedIn(NmsVersion.v1_21_R1) WIND_CHARGE,
WITCH,

View File

@ -1,5 +1,6 @@
package me.libraryaddict.disguise.disguisetypes;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
import com.github.retrooper.packetevents.protocol.entity.sniffer.SnifferState;
@ -23,6 +24,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.AbstractVillagerWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.AllayWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.AreaEffectCloudWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ArmadilloWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ArmorStandWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ArrowWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.AxolotlWatcher;
@ -31,6 +33,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.BeeWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.BlazeWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.BlockDisplayWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.BoatWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.BoggedWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.CamelWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.CatWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ChestedHorseWatcher;
@ -69,6 +72,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.MinecartFurnaceWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.MinecartWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.MushroomCowWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.OcelotWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.OminousItemSpawnerWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PaintingWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PandaWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ParrotWatcher;
@ -190,6 +194,9 @@ public class MetaIndex<Y> {
@NmsRemovedIn(NmsVersion.v1_13)
public static MetaIndex<Integer> AREA_EFFECT_PARTICLE_PARAM_2_OLD = new MetaIndex<>(AreaEffectCloudWatcher.class, 5, 0);
@NmsAddedIn(NmsVersion.v1_21_R1)
public static MetaIndex<ArmadilloState> ARMADILLO_STATE = new MetaIndex<>(ArmadilloWatcher.class, 0, ArmadilloState.IDLE);
/**
* Armorstand body eular vector
*/
@ -295,6 +302,9 @@ public class MetaIndex<Y> {
@NmsAddedIn(NmsVersion.v1_13)
public static MetaIndex<Integer> BOAT_SHAKE = new MetaIndex<>(BoatWatcher.class, 6, 0);
@NmsAddedIn(NmsVersion.v1_21_R1)
public static MetaIndex<Boolean> BOGGED_SHEARED = new MetaIndex<>(BoggedWatcher.class, 0, false);
@NmsAddedIn(NmsVersion.v1_19_R2)
public static MetaIndex<Boolean> CAMEL_DASHING = new MetaIndex<>(CamelWatcher.class, 0, false);
@ -343,12 +353,10 @@ public class MetaIndex<Y> {
public static MetaIndex<Vector3f> DISPLAY_SCALE = new MetaIndex<>(DisplayWatcher.class, 4, new Vector3f(1F, 1F, 1F));
@NmsAddedIn(NmsVersion.v1_19_R3)
public static MetaIndex<Quaternion4f> DISPLAY_LEFT_ROTATION =
new MetaIndex<>(DisplayWatcher.class, 5, new Quaternion4f(1F, 1F, 1F, 1F));
public static MetaIndex<Quaternion4f> DISPLAY_LEFT_ROTATION = new MetaIndex<>(DisplayWatcher.class, 5, new Quaternion4f(0, 0, 0, 1F));
@NmsAddedIn(NmsVersion.v1_19_R3)
public static MetaIndex<Quaternion4f> DISPLAY_RIGHT_ROTATION =
new MetaIndex<>(DisplayWatcher.class, 6, new Quaternion4f(1F, 1F, 1F, 1F));
public static MetaIndex<Quaternion4f> DISPLAY_RIGHT_ROTATION = new MetaIndex<>(DisplayWatcher.class, 6, new Quaternion4f(0, 0, 0, 1F));
public static MetaIndex<Byte> DISPLAY_BILLBOARD_RENDER_CONSTRAINTS = new MetaIndex<>(DisplayWatcher.class, 7, (byte) 0);
@ -680,6 +688,10 @@ public class MetaIndex<Y> {
@NmsAddedIn(NmsVersion.v1_14)
public static MetaIndex<Boolean> OCELOT_TRUST = new MetaIndex<>(OcelotWatcher.class, 0, false);
@NmsAddedIn(NmsVersion.v1_21_R1)
public static MetaIndex<ItemStack> OMINOUS_ITEM_SPAWNER_ITEM =
new MetaIndex<>(OminousItemSpawnerWatcher.class, 0, new ItemStack(Material.AIR));
@NmsAddedIn(NmsVersion.v1_19_R1)
public static MetaIndex<Art> PAINTING = new MetaIndex<>(PaintingWatcher.class, 0, NmsVersion.v1_19_R1.isSupported() ? Art.KEBAB : null);
@ -1251,7 +1263,8 @@ public class MetaIndex<Y> {
public boolean isItemStack() {
return this == ITEMFRAME_ITEM || this == ITEM_DISPLAY_ITEMSTACK || this == ENDER_SIGNAL_ITEM || this == DROPPED_ITEM ||
this == FIREBALL_ITEM || this == THROWABLE_ITEM || this == SPLASH_POTION_ITEM || this == FIREWORK_ITEM;
this == FIREBALL_ITEM || this == THROWABLE_ITEM || this == SPLASH_POTION_ITEM || this == FIREWORK_ITEM ||
this == OMINOUS_ITEM_SPAWNER_ITEM;
}
public boolean isBlock() {

View File

@ -0,0 +1,23 @@
package me.libraryaddict.disguise.disguisetypes.watchers;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.MetaIndex;
/**
* Created by libraryaddict on 6/05/2019.
*/
public class ArmadilloWatcher extends AgeableWatcher {
public ArmadilloWatcher(Disguise disguise) {
super(disguise);
}
public ArmadilloState getState() {
return getData(MetaIndex.ARMADILLO_STATE);
}
public void setState(ArmadilloState state) {
setData(MetaIndex.ARMADILLO_STATE, state);
sendData(MetaIndex.ARMADILLO_STATE);
}
}

View File

@ -0,0 +1,22 @@
package me.libraryaddict.disguise.disguisetypes.watchers;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.MetaIndex;
/**
* Created by libraryaddict on 15/06/2021.
*/
public class BoggedWatcher extends AbstractSkeletonWatcher {
public BoggedWatcher(Disguise disguise) {
super(disguise);
}
public void setSheared(boolean sheared) {
setData(MetaIndex.BOGGED_SHEARED, sheared);
sendData(MetaIndex.BOGGED_SHEARED);
}
public boolean isSheared() {
return getData(MetaIndex.BOGGED_SHEARED);
}
}

View File

@ -0,0 +1,36 @@
package me.libraryaddict.disguise.disguisetypes.watchers;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MetaIndex;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import me.libraryaddict.disguise.utilities.reflection.annotations.MethodDescription;
import me.libraryaddict.disguise.utilities.translations.TranslateType;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* @author Navid
*/
public class OminousItemSpawnerWatcher extends FlagWatcher {
public OminousItemSpawnerWatcher(Disguise disguise) {
super(disguise);
}
public ItemStack getItemStack() {
return getData(MetaIndex.OMINOUS_ITEM_SPAWNER_ITEM);
}
@MethodDescription("What item is displayed?")
public void setItemStack(ItemStack item) {
setData(MetaIndex.OMINOUS_ITEM_SPAWNER_ITEM, item);
sendData(MetaIndex.OMINOUS_ITEM_SPAWNER_ITEM);
if (!getDisguise().isCustomDisguiseName()) {
getDisguise().setDisguiseName(TranslateType.DISGUISES.get(DisguiseType.OMINOUS_ITEM_SPAWNER.toReadable()) + " " +
TranslateType.DISGUISE_OPTIONS_PARAMETERS.get(
ReflectionManager.toReadable((item == null ? Material.AIR : item.getType()).name(), " ")));
}
}
}

View File

@ -1,5 +1,6 @@
package me.libraryaddict.disguise.utilities.params;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
@ -191,6 +192,10 @@ public class ParamInfoTypes {
paramInfos.add(new ParamInfoEnum(Sniffer.State.class, "Sniffer State", "The current mindset of a Sniffer"));
}
if (NmsVersion.v1_21_R1.isSupported()) {
paramInfos.add(new ParamInfoEnum(ArmadilloState.class, "Armadillo State", "The current state of an Armadillo"));
}
paramInfos.add(new ParamInfoEnum(DisguiseConfig.NotifyBar.class, "NotifyBar", "Where the disguised indicator should appear"));
paramInfos.add(new ParamInfoEnum(BarColor.class, "BarColor", "The color of the boss bar"));
paramInfos.add(new ParamInfoEnum(BarStyle.class, "BarStyle", "The style of the boss bar"));

View File

@ -20,6 +20,7 @@ public enum NmsVersion {
v1_20_R2("1.20.2"),
v1_20_R3("1.20.3", "1.20.4"),
v1_20_R4("1.20.5", "1.20.6"),
v1_21_R1("1.21"),
UNSUPPORTED("N/A");
@Getter

View File

@ -1,6 +1,7 @@
package me.libraryaddict.disguise.utilities.reflection;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
@ -1557,7 +1558,8 @@ public class ReflectionManager {
return SpigotConversionUtil.fromBukkitItemStack((ItemStack) value);
} else if (value instanceof Rabbit.Type) {
return RabbitType.getTypeId((Rabbit.Type) value);
} else if (value instanceof Enum && !(value instanceof SnifferState || value instanceof EntityPose || value instanceof BlockFace)) {
} else if (value instanceof Enum && !(value instanceof SnifferState || value instanceof EntityPose || value instanceof BlockFace ||
value instanceof ArmadilloState)) {
int v = ((Enum) value).ordinal();
if (index.isByteValues()) {
@ -2111,6 +2113,10 @@ public class ReflectionManager {
case SNIFFER:
case BREEZE:
case WIND_CHARGE:
case BOGGED:
case ARMADILLO:
case BREEZE_WIND_CHARGE:
case OMINOUS_ITEM_SPAWNER:
nmsEntityName = disguiseType.toReadable().replace(" ", "");
break;
case DONKEY:
@ -2230,6 +2236,7 @@ public class ReflectionManager {
continue;
}
DisguiseUtilities.getLogger().severe(StringUtils.repeat("-", 20));
DisguiseUtilities.getLogger().severe("MetaIndex not found for " + disguiseType + "! Index: " + data.getIndex());
DisguiseUtilities.getLogger().severe(
"Value: " + data.getValue() + " (" + data.getValue().getClass() + ") (" + nmsEntity.getClass() + ") & " +
@ -2248,10 +2255,16 @@ public class ReflectionManager {
if (minecraftDefaultBukkit == null) {
minecraftDefaultBukkit = "nullsy";
}
if (ourDefaultBukkit == null) {
ourDefaultBukkit = "nullsa";
}
if (minecraftDefaultBukkit.getClass().getSimpleName().equals("CraftItemStack") &&
ourDefaultBukkit.getClass().getSimpleName().equals("ItemStack")) {
ourDefaultBukkit = ReflectionManager.getCraftItem((ItemStack) ourDefaultBukkit);
}
if (ourDefaultBukkit.getClass() != minecraftDefaultBukkit.getClass() || metaIndex.getDataType() != data.getType() ||
minecraftDefaultSerialized.getClass() != ourDefaultSerialized.getClass()) {
if (!loggedName) {
@ -2282,6 +2295,7 @@ public class ReflectionManager {
}
for (MetaIndex index : indexes) {
DisguiseUtilities.getLogger().severe(StringUtils.repeat("-", 20));
DisguiseUtilities.getLogger().severe(
disguiseType + " has MetaIndex remaining! " + index.getFlagWatcher().getSimpleName() + " at index " + index.getIndex());
}
@ -2494,6 +2508,8 @@ public class ReflectionManager {
return EntityDataTypes.ENTITY_POSE;
} else if (index == MetaIndex.SNIFFER_STATE) {
return EntityDataTypes.SNIFFER_STATE;
} else if (index == MetaIndex.ARMADILLO_STATE) {
return EntityDataTypes.ARMADILLO_STATE;
} else if (index == MetaIndex.SHULKER_FACING) {
return EntityDataTypes.BLOCK_FACE;
} else if (index == MetaIndex.AREA_EFFECT_CLOUD_COLOR) {

View File

@ -55,9 +55,10 @@ public class PacketEventsUpdater {
* Returns the min required version, as in any older version will just not work.
*/
public static String getMinimumPacketEventsVersion() {
// Unfortunately PacketEvents does not have build info, so we'll hope you are using the latest snapshot or release.
// Unfortunately PacketEvents does not have build info, so we'll hope you are using the latest snapshot if we fallback to that
// At time of writing, release is 2.3.0, and snapshot builds are all "2.3.1-SNAPSHOT"
// This means we'll always fail a release check!
return "2.3.1";
}

View File

@ -25,7 +25,7 @@
<lombok.version>1.18.32</lombok.version>
<packetevents.version>2.3.1-SNAPSHOT</packetevents.version>
<spigot.version>1.20.6-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.21-R0.1-SNAPSHOT</spigot.version>
<junit.version>4.13.2</junit.version>
<junit-jupiter.version>5.9.3</junit-jupiter.version>
<paper-api.version>1.20.3-R0.1-SNAPSHOT</paper-api.version>