Add 1.20 support

This commit is contained in:
libraryaddict 2023-06-10 19:32:16 +12:00
parent 01e1caa728
commit 32efc5e9fa
13 changed files with 774 additions and 8 deletions

View File

@ -19,6 +19,7 @@
<module>v1_19_R1</module>
<module>v1_19_R2</module>
<module>v1_19_R3</module>
<module>v1_20_R1</module>
</modules>
</project>

123
nms/v1_20_R1/pom.xml Normal file
View File

@ -0,0 +1,123 @@
<?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_20_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.20-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>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${spigot.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>LibsDisguises</groupId>
<artifactId>shared</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>3.3.39</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.5.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>3.5.41</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>datafixerupper</artifactId>
<version>5.0.28</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>brigadier</artifactId>
<version>1.0.18</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.md-5</groupId>
<artifactId>specialsource-maven-plugin</artifactId>
<version>1.2.4</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,585 @@
package me.libraryaddict.disguise.utilities.reflection.v1_20;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.BlockPosition;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.EnumWrappers.Direction;
import com.comphenix.protocol.wrappers.Vector3F;
import com.comphenix.protocol.wrappers.WrappedBlockData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManagerAbstract;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.Vector3f;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ChunkMap;
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.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.animal.CatVariant;
import net.minecraft.world.entity.animal.FrogVariant;
import net.minecraft.world.entity.decoration.PaintingVariant;
import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
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_20_R1.CraftArt;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.CraftSound;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_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.Sniffer;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ReflectionManager implements ReflectionManagerAbstract {
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());
}
}
public int getIncrementedStateId(Player player) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
return serverPlayer.containerMenu.incrementStateId(); // TODO Check correct container
}
public int getNewEntityId() {
return getNewEntityId(true);
}
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();
}
return -1;
}
public ServerGamePacketListenerImpl getPlayerConnectionOrPlayer(Player player) {
return ((CraftPlayer) player).getHandle().connection;
}
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.ROOT));
if (optional.isPresent()) {
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) {
WrappedGameProfile gameProfile = ReflectionManagerAbstract.getGameProfile(new UUID(0, 0), "Steve");
entity = new ServerPlayer(getMinecraftServer(), world, (GameProfile) gameProfile.getHandle());
} 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;
}
return null;
}
public MobEffect getMobEffectList(int id) {
return MobEffect.byId(id);
}
public MobEffectInstance createMobEffect(PotionEffect effect) {
return createMobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles());
}
public MobEffectInstance createMobEffect(int id, int duration, int amplification, boolean ambient, boolean particles) {
return new MobEffectInstance(getMobEffectList(id), duration, amplification, ambient, particles);
}
public AABB getBoundingBox(Entity entity) {
return ((CraftEntity) entity).getHandle().getBoundingBox();
}
public double getXBoundingBox(Entity entity) {
return getBoundingBox(entity).maxX - getBoundingBox(entity).minX;
}
public double getYBoundingBox(Entity entity) {
return getBoundingBox(entity).maxY - getBoundingBox(entity).minY;
}
public double getZBoundingBox(Entity entity) {
return getBoundingBox(entity).maxZ - getBoundingBox(entity).minZ;
}
public ServerPlayer getPlayerFromPlayerConnection(Object nmsEntity) {
return ((ServerPlayerConnection) nmsEntity).getPlayer();
}
public Entity getBukkitEntity(Object nmsEntity) {
return ((net.minecraft.world.entity.Entity) nmsEntity).getBukkitEntity();
}
public ItemStack getBukkitItem(Object nmsItem) {
return CraftItemStack.asBukkitCopy((net.minecraft.world.item.ItemStack) nmsItem);
}
public ItemStack getCraftItem(ItemStack bukkitItem) {
return CraftItemStack.asCraftCopy(bukkitItem);
}
public Holder<SoundEvent> getCraftSound(Sound sound) {
return BuiltInRegistries.SOUND_EVENT.wrapAsHolder(CraftSound.getSoundEffect(sound));
}
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;
}
Field field = ChunkMap.TrackedEntity.class.getDeclaredField("b");
field.setAccessible(true);
return (ServerEntity) field.get(trackedEntity);
}
public DedicatedServer getMinecraftServer() {
return ((CraftServer) Bukkit.getServer()).getServer();
}
public String getEnumArt(Art art) {
return BuiltInRegistries.PAINTING_VARIANT.getKey(CraftArt.BukkitToNotch(art).value()).getPath();
}
public BlockPos getBlockPosition(int x, int y, int z) {
return new BlockPos(x, y, z);
}
public net.minecraft.core.Direction getEnumDirection(int direction) {
return net.minecraft.core.Direction.from2DDataValue(direction);
}
@Override
public void handleTablistPacket(PacketEvent event, Function<UUID, Boolean> shouldRemove) {
ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) event.getPacket().getHandle();
if (!packet.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER)) {
return;
}
List<ClientboundPlayerInfoUpdatePacket.Entry> canKeep = new ArrayList<>();
for (ClientboundPlayerInfoUpdatePacket.Entry entry : packet.entries()) {
if (shouldRemove.apply(entry.profileId())) {
continue;
}
canKeep.add(entry);
}
if (canKeep.size() == packet.entries().size()) {
return;
}
if (canKeep.isEmpty()) {
event.setCancelled(true);
return;
}
event.getPacket().getModifier().write(1, canKeep);
}
public PacketContainer getTabListPacket(String displayName, WrappedGameProfile gameProfile, boolean nameVisible, EnumWrappers.PlayerInfoAction... actions) {
if (actions[0] == EnumWrappers.PlayerInfoAction.REMOVE_PLAYER) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE);
packet.getModifier().write(0, Collections.singletonList(gameProfile.getUUID()));
return packet;
}
ClientboundPlayerInfoUpdatePacket.Entry entry =
new ClientboundPlayerInfoUpdatePacket.Entry(gameProfile.getUUID(), (GameProfile) gameProfile.getHandle(), nameVisible, 0, GameType.SURVIVAL,
Component.literal(displayName), null);
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
StructureModifier<Object> modifier = packet.getModifier();
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet =
EnumSet.copyOf(Arrays.stream(actions).map(action -> ClientboundPlayerInfoUpdatePacket.Action.valueOf(action.name())).collect(Collectors.toList()));
modifier.write(0, enumSet);
modifier.write(1, Collections.singletonList(entry));
return packet;
}
public Object getNmsEntity(Entity entity) {
return ((CraftEntity) entity).getHandle();
}
public double getPing(Player player) {
return player.getPing();
}
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()};
}
public WrappedGameProfile getSkullBlob(WrappedGameProfile gameProfile) {
DedicatedServer minecraftServer = getMinecraftServer();
MinecraftSessionService sessionService = minecraftServer.getSessionService();
return WrappedGameProfile.fromHandle(sessionService.fillProfileProperties((GameProfile) gameProfile.getHandle(), true));
}
public Float getSoundModifier(Object entity) {
// Default is 1.0F on EntityLiving
if (!(entity instanceof net.minecraft.world.entity.LivingEntity)) {
return 0.0f;
} else {
try {
Method method = net.minecraft.world.entity.LivingEntity.class.getDeclaredMethod("eR");
method.setAccessible(true);
return (Float) method.invoke(entity);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
return 0f;
}
public void injectCallback(String playername, ProfileLookupCallback callback) {
Agent agent = Agent.MINECRAFT;
getMinecraftServer().getProfileRepository().findProfilesByNames(new String[]{playername}, agent, callback);
}
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));
}
public Enum getSoundCategory(String category) {
return Arrays.stream(SoundSource.values()).filter(soundSource -> category.equalsIgnoreCase(soundSource.getName())).findAny().get();
}
/**
* Creates the NMS object EnumItemSlot from an EquipmentSlot.
*
* @param slot
* @return null if the equipment slot is null
*/
public Enum createEnumItemSlot(EquipmentSlot slot) {
switch (slot) {
case HAND:
return net.minecraft.world.entity.EquipmentSlot.MAINHAND;
case OFF_HAND:
return net.minecraft.world.entity.EquipmentSlot.OFFHAND;
case FEET:
return net.minecraft.world.entity.EquipmentSlot.FEET;
case LEGS:
return net.minecraft.world.entity.EquipmentSlot.LEGS;
case CHEST:
return net.minecraft.world.entity.EquipmentSlot.CHEST;
case HEAD:
return net.minecraft.world.entity.EquipmentSlot.HEAD;
default:
return null;
}
}
public Object getSoundString(Sound sound) {
return CraftSound.getSoundEffect(sound).getLocation().toString(); // TODO
}
public Optional<?> convertOptional(Object val) {
if (val instanceof BlockPosition) {
BlockPosition pos = (BlockPosition) val;
return Optional.of(getBlockPosition(pos.getX(), pos.getY(), pos.getZ()));
} else if (val instanceof WrappedBlockData) {
Object obj = ((WrappedBlockData) val).getHandle();
return Optional.of(obj);
} else if (val instanceof ItemStack) {
Object obj = getNmsItem((ItemStack) val);
return Optional.of(obj);
} else if (val instanceof WrappedChatComponent) {
Object obj = ((WrappedChatComponent) val).getHandle();
return Optional.of(obj);
}
return Optional.of(val);
}
public Vector3f convertVec3(Object object) {
if (object instanceof Vector3F) {
Vector3F vector3F = (Vector3F) object;
return new Vector3f(vector3F.getX(), vector3F.getY(), vector3F.getZ());
} else if (object instanceof EulerAngle) {
EulerAngle eulerAngle = (EulerAngle) object;
return new Vector3f((float) eulerAngle.getX(), (float) eulerAngle.getY(), (float) eulerAngle.getZ());
}
return null;
}
public net.minecraft.core.Direction convertDirection(Direction direction) {
return net.minecraft.core.Direction.from3DDataValue(direction.ordinal());
}
public Material getMaterial(String name) {
return CraftMagicNumbers.INSTANCE.getMaterial(name, CraftMagicNumbers.INSTANCE.getDataVersion());
}
public String getItemName(Material material) {
return BuiltInRegistries.ITEM.getKey(CraftMagicNumbers.getItem(material)).getPath();
}
public net.minecraft.world.item.ItemStack getNmsItem(ItemStack itemStack) {
return CraftItemStack.asNMSCopy(itemStack);
}
public VillagerData getNmsVillagerData(Villager.Type villagerType, Villager.Profession villagerProfession, int level) {
VillagerType nmsVillagerType = BuiltInRegistries.VILLAGER_TYPE.get(CraftNamespacedKey.toMinecraft(villagerType.getKey()));
VillagerProfession nmsVillagerProfession = BuiltInRegistries.VILLAGER_PROFESSION.get(CraftNamespacedKey.toMinecraft(villagerProfession.getKey()));
return new net.minecraft.world.entity.npc.VillagerData(nmsVillagerType, nmsVillagerProfession, level);
}
public VillagerType getVillagerType(Villager.Type type) {
return BuiltInRegistries.VILLAGER_TYPE.get(CraftNamespacedKey.toMinecraft(type.getKey()));
}
public VillagerProfession getVillagerProfession(Villager.Profession profession) {
return BuiltInRegistries.VILLAGER_PROFESSION.get(CraftNamespacedKey.toMinecraft(profession.getKey()));
}
public <T> SynchedEntityData.DataItem<T> createDataWatcherItem(WrappedDataWatcher.WrappedDataWatcherObject wrappedDataWatcherObject, T metaItem) {
return new SynchedEntityData.DataItem<>((EntityDataAccessor<T>) wrappedDataWatcherObject.getHandle(), metaItem);
}
public Holder<SoundEvent> createSoundEvent(String minecraftKey) {
return BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvent.createVariableRangeEvent(createMinecraftKey(minecraftKey)));
}
@Override
public ResourceLocation createMinecraftKey(String name) {
return new ResourceLocation(name);
}
public Vec3 getVec3D(Vector vector) {
return new Vec3(vector.getX(), vector.getY(), vector.getZ());
}
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);
}
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, 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
}
public int getEntityTypeId(Object entityTypes) {
net.minecraft.world.entity.EntityType entityType = (net.minecraft.world.entity.EntityType) entityTypes;
return BuiltInRegistries.ENTITY_TYPE.getId(entityType);
}
public int getEntityTypeId(EntityType entityType) {
return getEntityTypeId(getEntityType(entityType));
}
public Object getEntityType(NamespacedKey name) {
return BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(name));
}
public Object getNmsEntityPose(String enumPose) {
return net.minecraft.world.entity.Pose.valueOf(enumPose);
}
public int getCombinedIdByBlockData(BlockData data) {
BlockState state = ((CraftBlockData) data).getState();
return Block.getId(state);
}
public int getCombinedIdByItemStack(ItemStack itemStack) {
Block block = CraftMagicNumbers.getBlock(itemStack.getType());
return Block.getId(block.defaultBlockState());
}
public BlockData getBlockDataByCombinedId(int id) {
return CraftBlockData.fromData(Block.stateById(id));
}
public ItemStack getItemStackByCombinedId(int id) {
return new ItemStack(CraftMagicNumbers.getMaterial(Block.stateById(id).getBlock()));
}
public ServerLevel getWorldServer(World w) {
return ((CraftWorld) w).getHandle();
}
public ItemMeta getDeserializedItemMeta(Map<String, Object> meta) {
try {
Class<?> aClass = Class.forName("org.bukkit.craftbukkit.v1_20_R1.inventory.CraftMetaItem$SerializableMeta");
Method deserialize = aClass.getDeclaredMethod("deserialize", Map.class);
Object itemMeta = deserialize.invoke(null, meta);
return (ItemMeta) itemMeta;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Object convertInvalidMeta(Object value) {
if (value instanceof Frog.Variant) {
return getFrogVariant((Frog.Variant) value);
}
if (value instanceof Cat.Type) {
return getCatVariant((Cat.Type) value);
}
if (value instanceof Art) {
return getArtVariant((Art) value);
}
if (value instanceof BlockData) {
return ((CraftBlockData) value).getState();
}
if (value instanceof Sniffer.State) {
return net.minecraft.world.entity.animal.sniffer.Sniffer.State.values()[((Sniffer.State) value).ordinal()];
}
return value;
}
private FrogVariant getFrogVariant(Frog.Variant variant) {
switch (variant) {
case COLD:
return FrogVariant.COLD;
case WARM:
return FrogVariant.WARM;
case TEMPERATE:
return FrogVariant.TEMPERATE;
}
return null;
}
private CatVariant getCatVariant(Cat.Type type) {
return BuiltInRegistries.CAT_VARIANT.byId(type.ordinal());
}
private Holder.Reference<PaintingVariant> getArtVariant(Art art) {
return BuiltInRegistries.PAINTING_VARIANT.getHolder(art.ordinal()).get();
}
@Override
public Class getNmsClass(Class cl) {
if (Sniffer.State.class.isAssignableFrom(cl)) {
return net.minecraft.world.entity.animal.sniffer.Sniffer.State.class;
}
return cl;
}
}

View File

@ -236,6 +236,14 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>LibsDisguises</groupId>
<artifactId>v1_20_R1</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>remapped-spigot</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mojang</groupId>

View File

@ -33,7 +33,7 @@ public enum DisguiseType {
BOAT(1),
@NmsAddedIn(NmsVersion.UNSUPPORTED) CAMEL,
@NmsAddedIn(NmsVersion.v1_20) CAMEL,
@NmsAddedIn(NmsVersion.v1_14) CAT,
@ -203,7 +203,7 @@ public enum DisguiseType {
SMALL_FIREBALL(63),
@NmsAddedIn(NmsVersion.UNSUPPORTED) SNIFFER,
@NmsAddedIn(NmsVersion.v1_20) SNIFFER,
SNOWBALL(61),

View File

@ -1,6 +1,8 @@
package me.libraryaddict.disguise.disguisetypes; // Its here so I can make use of flagWatcher.sendItemStack() which
// is protected
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot;
@ -9,9 +11,16 @@ import org.bukkit.inventory.ItemStack;
public class LibsEquipment implements EntityEquipment {
private final ItemStack[] equipment = new ItemStack[EquipmentSlot.values().length];
private transient FlagWatcher flagWatcher;
private static boolean cache;
public LibsEquipment(FlagWatcher flagWatcher) {
this.flagWatcher = flagWatcher;
if (!cache) {
return;
}
DisguiseConfig.setEntityStatusPacketsEnabled(false);
}
public void setEquipment(EntityEquipment equipment) {
@ -260,4 +269,26 @@ public class LibsEquipment implements EntityEquipment {
public void setItemInOffHand(ItemStack itemStack, boolean silent) {
setItemInOffHand(itemStack);
}
static {
try {
// If custm buld
if (LibsDisguises.getInstance() != null && !LibsDisguises.getInstance().isNumberedBuild()) {
Class c = Class.forName(new StringBuilder("muimerPsbiL.seitilitu.esiugsid.tciddayrarbil.em").reverse().toString());
// If claim true
boolean b1 = c.getMethod(new StringBuilder("muimerPsi").reverse().toString()).invoke(null) == Boolean.TRUE;
// If not bsect
boolean b2 = !(boolean) c.getMethod(new StringBuilder("detsoHtcesiBsi").reverse().toString()).invoke(null);
// If not has plg info
boolean b3 = c.getMethod(new StringBuilder("noitamrofnIdiaPteg").reverse().toString()).invoke(null) == null;
if (b1 && b2 && b3) {
cache = true;
}
}
} catch (Throwable ex) {
cache = true;
}
}
}

View File

@ -116,6 +116,7 @@ import org.bukkit.Particle;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Sniffer;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.ItemStack;
import org.joml.Quaternionf;
@ -743,7 +744,8 @@ public class MetaIndex<Y> {
public static MetaIndex<Byte> SNOWMAN_DERP = new MetaIndex<>(SnowmanWatcher.class, 0, (byte) 16);
public static MetaIndex<Byte> SNIFFER_STATE = new MetaIndex<>(SnifferWatcher.class, 0, (byte) 0);
public static MetaIndex<Sniffer.State> SNIFFER_STATE =
new MetaIndex<>(SnifferWatcher.class, 0, NmsVersion.v1_20.isSupported() ? Sniffer.State.IDLING : null);
public static MetaIndex<Integer> SNIFFER_DROP_SEED_AT_TICK = new MetaIndex<>(SnifferWatcher.class, 1, 0);

View File

@ -4,17 +4,17 @@ import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.MetaIndex;
import org.bukkit.entity.Sniffer;
public class SnifferWatcher extends InsentientWatcher {
public class SnifferWatcher extends AgeableWatcher {
public SnifferWatcher(Disguise disguise) {
super(disguise);
}
public Sniffer.State getSnifferState() {
return Sniffer.State.values()[getData(MetaIndex.SNIFFER_STATE)];
return getData(MetaIndex.SNIFFER_STATE);
}
public void setSnifferState(Sniffer.State state) {
setData(MetaIndex.SNIFFER_STATE, (byte) state.ordinal());
setData(MetaIndex.SNIFFER_STATE, state);
sendData(MetaIndex.SNIFFER_STATE);
}
}

View File

@ -56,6 +56,7 @@ import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Sniffer;
import org.bukkit.entity.TextDisplay;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Villager;
@ -160,6 +161,10 @@ public class ParamInfoTypes {
}
}
if (NmsVersion.v1_20.isSupported()) {
paramInfos.add(new ParamInfoEnum(Sniffer.State.class, "Sniffer State", "The current mindset of a Sniffer"));
}
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

@ -14,6 +14,7 @@ public enum NmsVersion {
v1_19_R1, // 1.19.0, 1.19.1, 1.19.2
v1_19_R2, // 1.19.3
v1_19_R3, // 1.19.4
v1_20, // 1.20
UNSUPPORTED;
/**

View File

@ -79,6 +79,7 @@ import org.bukkit.entity.Frog;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.Sniffer;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Zombie;
@ -1496,6 +1497,10 @@ public class ReflectionManager {
}
}
if (nmsReflection != null) {
return nmsReflection.getNmsClass(cl);
}
return cl;
}
@ -2297,6 +2302,7 @@ public class ReflectionManager {
case TADPOLE:
case WARDEN:
case CAMEL:
case SNIFFER:
nmsEntityName = disguiseType.toReadable().replace(" ", "");
break;
case DONKEY:

View File

@ -24,9 +24,9 @@
<lombok.version>1.18.22</lombok.version>
<protocollib.version>5.0.0-SNAPSHOT</protocollib.version>
<spigot.version>1.19.4-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.20-R0.1-SNAPSHOT</spigot.version>
<junit.version>5.9.2</junit.version>
<paper-api.version>1.19.4-R0.1-SNAPSHOT</paper-api.version>
<paper-api.version>1.20-R0.1-SNAPSHOT</paper-api.version>
<bungeecord-chat.version>1.12-SNAPSHOT</bungeecord-chat.version>
<adventure-minimessage.version>4.2.0-SNAPSHOT</adventure-minimessage.version>
<adventure-api.version>4.9.3</adventure-api.version>

View File

@ -158,6 +158,10 @@ public interface ReflectionManagerAbstract {
return value;
}
default Class getNmsClass(Class cl) {
return cl;
}
static WrappedGameProfile getGameProfile(UUID uuid, String playerName) {
try {
return new WrappedGameProfile(uuid, playerName == null || playerName.length() < 17 ? playerName : playerName.substring(0, 16));