TagAPI icon

TagAPI -----

An open source API that allows developers to easily add extra lines above an entity.



Been a while! 1.19
Hello! It has certainly been a very long time since I have posted an update here. I have been great about keeping the github updated - a meh job of keeping the maven repo updated - a sad job of updating the spigot resource updated.

1.19

There are quite a lot of changes, actually. First, I will address 1.19. The latest version of MC had removed one of the entity spawn packets in favor of a singular spawn packet that does both. I had worked out a way to solve this issue with ease. The issue came with, what I believe is a yet-to-be-patched bug in ProtocolLib. To be fair, I never submitted a ticket for it. The bug in question was that ProtocolLibs method of getting an entity from an ID would not work in the same 'stack' as an intercepted spawn packet. This worked perfectly in all versions prior, but does not work in 1.19. I decided to wait, but eventually decided to make a patch that simply delays the code by a tick. And here we are!

New Features

Okay, enough of that mess. What about what has been added since 1.03?
Well, even if you exclude stuff like the versions file not appearing when shading the API.. Still quite a lot.


1. Packet Injecting
The TagEntity class now has a method named "injectPacket" that takes a function. The function must have an argument that takes "TagEntity" and it must return a "PacketContainer" instance (Class from ProtocolLib). By using this method, the 'injected' packet will fire to the viewing player along with the other packets TagAPI naturally fires.

2. Metadata Injecting
I'm a bit of a broken fiddle here with this one. This is practically the same as the previous, but allows you to change data in the metadata packet sent out. This simply takes a BiConsumer accepting the TagEntity, and a "WrappedDataWatcher" from ProtocolLib.

3. Bottom Entity
This version of TagAPI introduces a new, small TagLine at the very bottom of all tags that has no text whatsoever. This TagLine is also visible to any player it is placed on. This empty TagLine can be grabbed using Tag#getBottomTagLine.

These all sound very specific, and not very useful at all, huh? Well, they can be quite powerful when combined. Allow me to just throw some code your way.

Code (Text):

final ItemStack backpack = new ItemStack(Material.LEATHER_HORSE_ARMOR);
LeatherArmorMeta meta = (LeatherArmorMeta) backpack.getItemMeta();
meta.setCustomModelData(10034); // The model is 10034 in my pack
meta.setColor(Color.AQUA); // We can color the backpack c:
backpack.setItemMeta(meta);

TagAPI.setDefaultTag(EntityType.PLAYER, player -> { // Create a default tag for all players.
    Tag tag = Tag.create(player);
    tag.addTagLine(9).setGetName(viewer -> player.getName());
    tag.addTagLine(8).setGetName(viewer -> player.getEntityId() + ""); // These can be anything, really.
   
    tag.getBottomTagLine().getBottomEntity().injectPacket(te -> { //Inject a new packet into the bottom entity
        PacketContainer container = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT); // Equipment packet
        container.getIntegers().write(0, te.getEntityID()); // Pass the tag entities entityID
        List<Pair<EnumWrappers.ItemSlot, ItemStack>> slots = container.getSlotStackPairLists().read(0); // Get the equipment list
        slots.add(new Pair<>(EnumWrappers.ItemSlot.HEAD, backpack)); // Set the head slot to the backpack we created way up there
        container.getSlotStackPairLists().write(0, slots); // Write our equipment list to the packet.
        return container;
    }).injectPacket(te -> { // Inject more.
        PacketContainer container = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION); // Head rotation packet
        container.getIntegers().write(0, te.getEntityID()); // Pass the tag entities entityID
        container.getBytes().write(0, (byte) (int) (player.getLocation().getYaw() * 256.0F / 360.0F)); // We are going to match the players yaw so that it rotates with the player.
        return container;
    }).injectPacket(te -> { // Practically does the same as the injection above it.
        PacketContainer container = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
        container.getIntegers().write(0, te.getEntityID());
        container.getBytes().write(0, (byte) (int) (player.getLocation().getYaw() * 256.0F / 360.0F));
        container.getBytes().write(1, (byte) (int) player.getLocation().getPitch());
        container.getBooleans().write(0, true);
        return container;
    });

    return tag;
});
 
Okay, cool. We have all that gibberish. What does it do, though? Well, this is just one example of how you could use this system... But coupled with a correctly setup resource pack, this code creates this:
[​IMG]
(accept with only an aqua backpack. I had it randomized here)​

By all means, I did not and do not intend for this to go in the direction of a cosmetics plugin with features like this built in. There are already way too many plugins out there that control resource packs. I just wanted to give plugin develops the option to have both TagAPI and stuff like backpacks and whatnot. It would be cool to see said plugins adopt support for TagAPI using this method, but I have doubts that will happen. At the very least, I imagine most people who are developing with TagAPI will be more hands on.
----------, Jul 2, 2022
Resource Information
Author:
----------
Total Downloads: 2,012
First Release: Nov 5, 2021
Last Update: Jul 8, 2022
Category: ---------------
All-Time Rating:
3 ratings
Find more info at github.com...
Version -----
Released: --------------------
Downloads: ------
Version Rating:
----------------------
-- ratings