No Description

Dawson Hessler 47ae3afc7f Added PotionBuilder 1 year ago
.github 8fbda899ba Update main.yml 2 years ago
AtlasParent 47ae3afc7f Added PotionBuilder 1 year ago
Example e6da54a013 Revert "Restructuring project" 3 years ago
docs e6da54a013 Revert "Restructuring project" 3 years ago
.gitattributes 937d051a28 Initial commit 6 years ago
.gitignore b121340d78 Adding 1.19 to ProtocolVersion 2 years ago
README.md 3d03b46f9b Update README.md 3 years ago

README.md

Download

Download the latest stable release on Spigot: https://www.spigotmc.org/resources/atlas-custom-packet-listening-numerous-utils-block-boundingboxes-1-7-1-13.66845/

Description

What is Atlas?

Atlas is an all-in-one and cohesive API for developers who want to improve their Bukkit plugins or anti-cheats.

What does it include?

  • An advanced and seemless custom packet-sniffing system, with individual packet-wrappers.
  • Custom event system, running asynchronously so servers using your plugin will not experience any slowdowns on the main-thread.
  • Enough math utilities to make you forget what you learned in math class.
  • Many useful methods for doing little things like sending a colored message to console.
  • The most accurate and light, public hitbox-grabbing system.
  • Numerous reflection methods and utilities, including grabbers for NMS.

JavaDocs

https://funkemunky.github.io/Atlas/

Using Code from This Repo

I'm aware that more people use Atlas as a means of learning rather than as an API, and therefore many people take parts of this repository and put it into their own projects. I have no problem with this. However, if you are using code from this repository in a closed source project, I would like easily-readable credit on any official distribution page for your project/product. Thanks!

Custom Event System

Creating an event

package cc.funkemunky.anticheat.api.event;

import cc.funkemunky.api.events.AtlasEvent;
import cc.funkemunky.api.events.Cancellable;
import lombok.AllArgsConstructor;
import lombok.Getter;


public class TickEvent extends AtlasEvent implements Cancellable {
    private int currentTick;

    public TickEvent(int currentTick) {
        this.currentTick = currentTick;
    }

    public int getCurrentTick() {
        return currentTick;
    }

    @Override
    public boolean isCancelled() {
        return false;
    }

    @Override
    public void setCancelled(boolean b) {

    }
}

Calling an event

new BukkitRunnable() {
            public void run() {
                TickEvent tickEvent = new TickEvent(currentTicks++);

                Atlas.getInstance().getEventManager().callEvent(tickEvent);
            }
        }.runTaskTimerAsynchronously(this, 1L, 1L);

Example Listener

package cc.funkemunky.anticheat.impl.listeners;

import cc.funkemunky.anticheat.Rock;
import cc.funkemunky.anticheat.api.data.PlayerData;
import cc.funkemunky.anticheat.api.event.TickEvent;
import cc.funkemunky.api.Atlas;
import cc.funkemunky.api.events.AtlasListener;
import cc.funkemunky.api.events.Listen;
import cc.funkemunky.api.utils.Init;

@Init
public class FunkeListeners implements AtlasListener {

    @Listen
    public void onTickEvent(TickEvent event) {
        Atlas.getInstance().executeTask(() -> Rock.getInstance().getDataManager().getDataObjects().keySet().forEach(key -> {
            PlayerData data = Rock.getInstance().getDataManager().getDataObjects().get(key);

            data.getActionProcessor().update(data);
        }));
    }
}

Registering a Listener

public void onEnable() {
        Atlas.getInstance().getEventManager().registerListeners(new FunkeListeners(), this);
}

Custom Packet System

Sending a packet

TinyProtocolHandler.sendPacket(e.getPlayer(), new WrappedOutKeepAlivePacket(233 + e.getPlayer().getEntityId() + 935));

Listening for Packets

Client Packets

@Listen
    public void onEvent(PacketRecieveEvent e) {
        if(e.getType().equals(Packet.Client.ENTITY_ACTION)) {
            WrappedInEntityActionPacket packet = new WrappedInEntityActionPacket(e.getPacket(), e.getPlayer());

            switch(packet.getAction()) {
                case START_SNEAKING:
                    data.skiderino.sneak = true;
                    break;
                case STOP_SNEAKING:
                    data.skiderino.sneak = false;
                    break;
                case START_SPRINTING:
                    data.skiderino.sprint = true;
                    break;
                case STOP_SPRINTING:
                    data.skiderino.sprint = false;
                    break;
            }
        }
    }

Server Packets

 @Listen
    public void onPacketSend(PacketSendEvent e) {
        PlayerData data = Fiona.getInstance().getDataManager().getPlayerData(e.getPlayer());

        if (data != null) {
            switch (e.getType()) {
                case Packet.Server.KEEP_ALIVE:
                    data.lastServerKeepAlive = System.currentTimeMillis();
                    break;
                case Packet.Server.ENTITY_METADATA:
                    WrappedOutEntityMetadata wrapper = new WrappedOutEntityMetadata(e.getPacket(), e.getPlayer());

                    if(wrapper.getObjects().size() > 0) {
                        if(wrapper.getObjects().get(0).getObject() instanceof Byte && (data.isUsingItem = ((Byte) wrapper.getObjects().get(0).getObject()) % 0x5 == 1)) {
                            data.lastUseItem.reset();
                        }
                    }
                break;
			}
        }
    }

Collision Hit-Boxes

Getting a specific block hit-box

@EventHandler(priority = EventPriority.HIGHEST)
    public void onEvent(PlayerInteractEvent event) {
        if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
            if (event.getItem() != null
                    && event.getItem().getType().equals(Material.BLAZE_ROD)
                    && event.getItem().getItemMeta().getDisplayName().equalsIgnoreCase(Color.Red + "Magic Box Wand")) {
                Block block = event.getClickedBlock();

                event.getPlayer().sendMessage(block.getType().name() + "'s Data: " + block.getData());
                for (BoundingBox box : Atlas.getInstance().getBlockBoxManager().getBlockBox().getSpecificBox(block.getLocation())) {
                    for (float x = box.minX; x < box.maxX; x += 0.2f) {
                        for (float y = box.minY; y < box.maxY; y += 0.2f) {
                            for (float z = box.minZ; z < box.maxZ; z += 0.2f) {
                                WrappedPacketPlayOutWorldParticle packet = new WrappedPacketPlayOutWorldParticle(WrappedEnumParticle.FLAME, true, x, y, z, 0f, 0f, 0f, 0f, 1, null);
                                packet.sendPacket(event.getPlayer());
                            }
                        }
                    }
                    event.getPlayer().sendMessage(ReflectionsUtil.getVanillaBlock(event.getClickedBlock()).getClass().getSimpleName() + ": " + box.toString());
                }
            }
        }
    }

Getting all collided hit-boxes

List<BoundingBox> box = Atlas.getInstance().getBlockBoxManager().getBlockBox().getCollidingBoxes(to.getWorld(), data.boundingBox.grow(0.5f, 0.1f, 0.5f).subtract(0, 0.5f, 0, 0, 0, 0));

        CollisionAssessment assessment = new CollisionAssessment(data.boundingBox, data);
        box.forEach(bb -> assessment.assessBox(bb, to.getWorld()));

Getting an entity hitbox

MiscUtils.getEntityBoundingBox(e.getPlayer());

Credits

TinyProtocol and Additions

Credits to @dmulloy2 and @aandk for the TinyProtocol and Reflection utilities. Thanks to @DeprecatedLuke for his useful additions to TinyProtocol and his initial packet wrappers.

Code Profile System

Credits to @DeprecatedLuke for the BaseProfiler and Profiler classes.