예제 #1
0
  /**
   * Retrieve a structure modifier that automatically marshalls between NBT wrappers and their NMS
   * counterpart.
   *
   * @param stack - the stack that will store the NBT compound.
   * @return The structure modifier.
   */
  private static StructureModifier<NbtBase<?>> getStackModifier(ItemStack stack) {
    Object nmsStack = MinecraftReflection.getMinecraftItemStack(stack);

    if (itemStackModifier == null) {
      itemStackModifier = new StructureModifier<Object>(nmsStack.getClass(), Object.class, false);
    }

    // Use the first and best NBT tag
    return itemStackModifier
        .withTarget(nmsStack)
        .withType(MinecraftReflection.getNBTBaseClass(), BukkitConverters.getNbtConverter());
  }
예제 #2
0
  /**
   * Create a new NBT wrapper from a given type.
   *
   * @param <T> Type
   * @param type - the NBT type.
   * @param name - the name of the NBT tag.
   * @return The new wrapped NBT tag.
   * @throws FieldAccessException If we're unable to create the underlying tag.
   */
  public static <T> NbtWrapper<T> ofWrapper(NbtType type, String name) {
    if (type == null) throw new IllegalArgumentException("type cannot be NULL.");
    if (type == NbtType.TAG_END) throw new IllegalArgumentException("Cannot create a TAG_END.");

    if (methodCreateTag == null) {
      Class<?> base = MinecraftReflection.getNBTBaseClass();

      // Use the base class
      try {
        methodCreateTag = findCreateMethod(base, byte.class, String.class);
        methodCreateWithName = true;

      } catch (Exception e) {
        methodCreateTag = findCreateMethod(base, byte.class);
        methodCreateWithName = false;
      }
    }

    try {
      // Delegate to the correct version
      if (methodCreateWithName) return createTagWithName(type, name);
      else return createTagSetName(type, name);

    } catch (Exception e) {
      // Inform the caller
      throw new FieldAccessException(
          String.format("Cannot create NBT element %s (type: %s)", name, type), e);
    }
  }
  @Override
  public void injectManager() {

    if (serverHandlerRef == null) throw new IllegalStateException("Cannot find server handler.");
    // Don't inject twice
    if (serverHandlerRef.getValue() instanceof Factory) return;

    if (!tryInjectManager()) {

      // Try to override the proxied object
      if (proxyServerField != null) {
        serverHandlerRef = new VolatileField(proxyServerField, serverHandler, true);
        serverHandler = serverHandlerRef.getValue();

        if (serverHandler == null)
          throw new RuntimeException("Cannot hook player: Inner proxy object is NULL.");

        // Try again
        if (tryInjectManager()) {
          // It worked - probably
          return;
        }
      }

      throw new RuntimeException(
          "Cannot hook player: Unable to find a valid constructor for the "
              + MinecraftReflection.getNetServerHandlerClass().getName()
              + " object.");
    }
  }
예제 #4
0
 /**
  * Retrieves a read/write structure for collections of chunk positions.
  *
  * <p>This modifier will automatically marshall between the visible ProtocolLib ChunkPosition and
  * the internal Minecraft ChunkPosition.
  *
  * @return A modifier for ChunkPosition list fields.
  */
 public StructureModifier<List<ChunkPosition>> getPositionCollectionModifier() {
   // Convert to and from the ProtocolLib wrapper
   return structureModifier.withType(
       Collection.class,
       BukkitConverters.getListConverter(
           MinecraftReflection.getChunkPositionClass(), ChunkPosition.getConverter()));
 }
예제 #5
0
  /**
   * Retrieve the packet ID of a given packet.
   *
   * @param packet - the type of packet to check.
   * @return The ID of the given packet.
   * @throws IllegalArgumentException If this is not a valid packet.
   */
  public static int getPacketID(Class<?> packet) {
    if (packet == null) throw new IllegalArgumentException("Packet type class cannot be NULL.");
    if (!MinecraftReflection.getPacketClass().isAssignableFrom(packet))
      throw new IllegalArgumentException("Type must be a packet.");

    // The registry contains both the overridden and original packets
    return getPacketToID().get(packet);
  }
예제 #6
0
 /**
  * Ensure that the given stack can store arbitrary NBT information.
  *
  * @param stack - the stack to check.
  */
 private static void checkItemStack(ItemStack stack) {
   if (stack == null) throw new IllegalArgumentException("Stack cannot be NULL.");
   if (!MinecraftReflection.isCraftItemStack(stack))
     throw new IllegalArgumentException("Stack must be a CraftItemStack.");
   if (stack.getType() == Material.AIR)
     throw new IllegalArgumentException(
         "ItemStacks representing air cannot store NMS information.");
 }
예제 #7
0
 /**
  * Retrieves a read/write structure for collections of watchable objects.
  *
  * <p>This modifier will automatically marshall between the visible WrappedWatchableObject and the
  * internal Minecraft WatchableObject.
  *
  * @return A modifier for watchable object list fields.
  */
 public StructureModifier<List<WrappedWatchableObject>> getWatchableCollectionModifier() {
   // Convert to and from the ProtocolLib wrapper
   return structureModifier.withType(
       Collection.class,
       BukkitConverters.getListConverter(
           MinecraftReflection.getWatchableObjectClass(),
           BukkitConverters.getWatchableObjectConverter()));
 }
  private void registerSpigot(DelayedPacketManager delayed) {
    // Use netty if we have a non-standard ServerConnection class
    nettyEnabled =
        !MinecraftReflection.isMinecraftObject(
            InjectedServerConnection.getServerConnection(reporter, server));

    // Switch to the standard manager
    delayed.setDelegate(buildInternal());
  }
  /**
   * Create a new packet filter manager.
   *
   * @return A new packet filter manager.
   */
  public InternalManager build() {
    if (reporter == null) throw new IllegalArgumentException("reporter cannot be NULL.");
    if (classLoader == null) throw new IllegalArgumentException("classLoader cannot be NULL.");

    asyncManager = new AsyncFilterManager(reporter, server.getScheduler());
    nettyEnabled = false;

    // Spigot
    if (SpigotPacketInjector.canUseSpigotListener()) {
      // If the server hasn't loaded yet - wait
      if (InjectedServerConnection.getServerConnection(reporter, server) == null) {
        // We need to delay this until we know if Netty is enabled
        final DelayedPacketManager delayed = new DelayedPacketManager(reporter, mcVersion);

        // They must reference each other
        delayed.setAsynchronousManager(asyncManager);
        asyncManager.setManager(delayed);

        Futures.addCallback(
            BukkitFutures.nextEvent(library, WorldInitEvent.class),
            new FutureCallback<WorldInitEvent>() {
              @Override
              public void onSuccess(WorldInitEvent event) {
                // Nevermind
                if (delayed.isClosed()) return;

                try {
                  registerSpigot(delayed);
                } catch (Exception e) {
                  onFailure(e);
                }
              }

              @Override
              public void onFailure(Throwable error) {
                reporter.reportWarning(
                    PacketFilterBuilder.this,
                    Report.newBuilder(REPORT_TEMPORARY_EVENT_ERROR).error(error));
              }
            });

        System.out.println("Delaying due to Spigot");

        // Let plugins use this version instead
        return delayed;
      } else {
        nettyEnabled =
            !MinecraftReflection.isMinecraftObject(
                InjectedServerConnection.getServerConnection(reporter, server));
      }
    }

    // Otherwise - construct the packet filter manager right away
    return buildInternal();
  }
  /**
   * Read an ItemStack from a input stream without "scrubbing" the NBT content.
   *
   * @param input - the input stream.
   * @return The deserialized item stack.
   * @throws IOException If anything went wrong.
   */
  @Override
  public ItemStack deserializeItemStack(DataInputStream input) throws IOException {
    ItemStack result = null;
    short type = input.readShort();

    if (type >= 0) {
      byte amount = input.readByte();
      short damage = input.readShort();

      result = new ItemStack(type, amount, damage);
      NbtCompound tag = super.deserializeCompound(input);

      if (tag != null) {
        result = MinecraftReflection.getBukkitItemStack(result);
        NbtFactory.setItemTag(result, tag);
      }
    }
    return result;
  }
예제 #11
0
  /**
   * Retrieves a read/write structure for arrays of ItemStacks.
   *
   * <p>This modifier will automatically marshall between the Bukkit ItemStack and the internal
   * Minecraft ItemStack.
   *
   * @return A modifier for ItemStack array fields.
   */
  public StructureModifier<ItemStack[]> getItemArrayModifier() {

    final EquivalentConverter<ItemStack> stackConverter = BukkitConverters.getItemStackConverter();

    // Convert to and from the Bukkit wrapper
    return structureModifier.<ItemStack[]>withType(
        MinecraftReflection.getItemStackArrayClass(),
        BukkitConverters.getIgnoreNull(
            new EquivalentConverter<ItemStack[]>() {

              public Object getGeneric(Class<?> genericType, ItemStack[] specific) {
                Class<?> nmsStack = MinecraftReflection.getItemStackClass();
                Object[] result = (Object[]) Array.newInstance(nmsStack, specific.length);

                // Unwrap every item
                for (int i = 0; i < result.length; i++) {
                  result[i] = stackConverter.getGeneric(nmsStack, specific[i]);
                }
                return result;
              }

              @Override
              public ItemStack[] getSpecific(Object generic) {
                Object[] input = (Object[]) generic;
                ItemStack[] result = new ItemStack[input.length];

                // Add the wrapper
                for (int i = 0; i < result.length; i++) {
                  result[i] = stackConverter.getSpecific(input[i]);
                }
                return result;
              }

              @Override
              public Class<ItemStack[]> getSpecificType() {
                return ItemStack[].class;
              }
            }));
  }
예제 #12
0
 private Class<?> getFirstMinecraftSuperClass(Class<?> clazz) {
   if (clazz.getName().startsWith(MinecraftReflection.getMinecraftPackage())) return clazz;
   else if (clazz.equals(Object.class)) return clazz;
   else return getFirstMinecraftSuperClass(clazz.getSuperclass());
 }
예제 #13
0
 /**
  * Retrieves a read/write structure for ItemStack.
  *
  * <p>This modifier will automatically marshall between the Bukkit ItemStack and the internal
  * Minecraft ItemStack.
  *
  * @return A modifier for ItemStack fields.
  */
 public StructureModifier<ItemStack> getItemModifier() {
   // Convert to and from the Bukkit wrapper
   return structureModifier.<ItemStack>withType(
       MinecraftReflection.getItemStackClass(), BukkitConverters.getItemStackConverter());
 }
예제 #14
0
 /**
  * Retrieves a read/write structure for the world type enum.
  *
  * <p>This modifier will automatically marshall between the Bukkit world type and the internal
  * Minecraft world type.
  *
  * @return A modifier for world type fields.
  */
 public StructureModifier<WorldType> getWorldTypeModifier() {
   // Convert to and from the Bukkit wrapper
   return structureModifier.<WorldType>withType(
       MinecraftReflection.getWorldTypeClass(), BukkitConverters.getWorldTypeConverter());
 }
예제 #15
0
 /**
  * Retrieves a read/write structure for data watchers.
  *
  * @return A modifier for data watchers.
  */
 public StructureModifier<WrappedDataWatcher> getDataWatcherModifier() {
   // Convert to and from the Bukkit wrapper
   return structureModifier.<WrappedDataWatcher>withType(
       MinecraftReflection.getDataWatcherClass(), BukkitConverters.getDataWatcherConverter());
 }
예제 #16
0
 /**
  * Retrieve the cached fuzzy reflection instance allowing access to the packet registry.
  *
  * @return Reflected packet registry.
  */
 private static FuzzyReflection getPacketRegistry() {
   if (packetRegistry == null)
     packetRegistry = FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true);
   return packetRegistry;
 }
예제 #17
0
 /**
  * Retrieves a read/write structure for chunk positions.
  *
  * @return A modifier for a ChunkPosition.
  */
 public StructureModifier<ChunkPosition> getPositionModifier() {
   // Convert to and from the Bukkit wrapper
   return structureModifier.withType(
       MinecraftReflection.getChunkPositionClass(), ChunkPosition.getConverter());
 }
예제 #18
0
 /**
  * Retrieves a read/write structure for NBT classes.
  *
  * @return A modifier for NBT classes.
  */
 public StructureModifier<NbtBase<?>> getNbtModifier() {
   // Allow access to the NBT class in packet 130
   return structureModifier.withType(
       MinecraftReflection.getNBTBaseClass(), BukkitConverters.getNbtConverter());
 }