Skip to content

Developer API

RONiN edited this page Oct 4, 2021 · 1 revision

Obtaining instance

Obtaining the Skyblock instance (Spigot)

private SkyblockPlugin getSkyblock() {
    return (SkyblockPlugin) Bukkit.getPluginManager().getPlugin("Skyblock");
}

Obtaining the Skyblock instance (Bungee)

private SkyblockBungeePlugin getSkyblock() {
    return (SkyblockBungeePlugin) getProxy().getPluginManager().getPlugin("SkyblockBungee");
}

Registering custom command

Spigot:

This is an example on how to implement a /is help command

public class MyHelpCommand implements SkyblockCommand {

    @Override
    public String getIdentifier() {
        return "island.help";
    }

    @Override
    public void execute(CommandSender sender, String... args) {
        sender.sendMessage("This is a help message!");
    }

}

Now to register the command

skyblock.getCommandManager().register(new MyHelpCommand());

Bungee:

There is no Bungee Command API (yet?)


Server Communication

When you need to do any communication between an instance and a proxy, or between proxies, it is suggested that you use the Packet system built-in to SkyblockCore.

Each packet has its own Identifier, which should be registered on the PacketManager class. Let's say you want to make a packet sent from the Proxy, to the Instance.

@Getter
public class WhateverMyPacketIs extends ProxyToServerPacket {

    private final int someData; // Some data stored in the packet

    public WhateverMyPacketIs(byte[] bytes) { // Used when reading
        super(bytes);

        someData = readInt(); // Read the data
    }

    public WhateverMyPacketIs(String proxyId, String targetServer, int someData) {
        super(proxyId, targetServer); // Write Proxy ID, along with the target server

        this.someData = someData; // Set internal data

        writeInt(someData); // Serialize the custom data
    } 
}

Before creating the packet, it must be registered, it is as simple as:

// ID Class PacketManager.registerPacket(0xFF, WhateverMyPacketIs.class);

And to send the packet (bungee way)

SkyblockBungeePlugin plugin = ...;
ProxiedPlayer player = ...;

PacketManager packetManager = plugin.getPacketManager();
String server = player.getServer().getInfo().getName();

WhateverMyPacketIs packet = new WhateverMyPacketIs(ProxyServer.getInstance().getName(), server, 32); // Custom data (payload) is 32 on this example

packetManager.send(packet);

Now, to listen to an incoming packet, you need to register the listener on the packet manager:

PacketManager packetManager = ...;

packetManager.subscribe(WhateverMyPacketIs.class, new PacketHandler<WhateverMyPacketIs>() {

    @Override
    public void onSend(WhateverMyPacketIs packet) {
        // Called when sending the packet
    }

    @Override
    public void onReceive(WhateverMyPacketIs packet) {
        Bukkit.broadcastMessage("Received payload " + packet.getSomeData());
    }

});

Let's say you want to implement a custom packet messaging service, such as RabbitMQ

public class PacketReceiver implements PacketProcessor {

    @Override
    public void send(Packet packet) {
        byte[] bytes = packet.getAllBytes();
        // ...
    }

    public void onReceive(byte[] array) { // Not part of PacketProcessor, Just use your messaging API
        PacketManager packetManager = ...;
        packetManager.read(array);
    }

}

And to register

PacketManager packetManager = ...;
PacketDirection direction = PacketDirection.PROXY_TO_PROXY; // Available types: INSTANCE_TO_PROXY, PROXY_TO_INSTANCE, PROXY_TO_PROXY
PacketProcessor receiver = new PacketReceiver();

packetManager.registerProcessor(direction, receiver);

Keep in mind you shouldn't store any Bukkit / Bungee specific data, as it is likely to cause NoClassDefFoundException errors when transferring.


Useful methods for Developers

These methods are included on the base SkyblockCore project and are free for any developer to grab:

  • ItemStack conversion to base64 -> here

  • Empty world generation -> here

  • Spigot plugin downloader -> here

  • MongoDB, MySQL and SQLite storage examples -> here

  • Usage of .mca files to paste data quickly on unloaded worlds -> here