Skip to content
LeeGod edited this page Dec 22, 2021 · 1 revision

Sidebar module is a powerful tool for developers to have cool sidebar (aka. scoreboard) to visually display items in the screen of players.

Setup

Sidebar uses Component to initialize life cycle, and the interface is io.fairyproject.sidebar.SidebarAdapter, which is where you customize the sidebar.

When you completed setup you should see something like this:

import io.fairyproject.mc.MCPlayer;
import io.fairyproject.sidebar.Sidebar;
import io.fairyproject.sidebar.SidebarAdapter;
import net.kyori.adventure.text.Component;

import java.util.List;

@io.fairyproject.container.Component
public class DebugSidebarAdapter implements SidebarAdapter {
    
    @Override
    public Component getTitle(MCPlayer mcPlayer) {
        // needed
        return null;
    }

    @Override
    public List<Component> getLines(MCPlayer mcPlayer) {
        // needed
        return null;
    }

    @Override
    public void onBoardCreate(MCPlayer player, Sidebar board) {
        // optional
    }

    @Override
    public int tick() {
        // optional
        return -1;
    }

    @Override
    public int priority() {
        // optional
        return 0;
    }
}

Title

The first method getTitle(MCPlayer) is where you customize the title of your sidebar. For example I want the sidebar to display user name, I can simply return Component.text(player.getName()).

NOTE: when you returned null this sidebar adapter will consider as disabled.

Lines

The second method getLines(MCPlayer) is where you customize the lines of your sidebar. The lines got displayed are the order of the list you returned, and there is no limit how you work with the list. lines will automatically added or removed depend on the returned list, provides the most intuitive experience for a sidebar module.

NOTE: when you returned null or empty list this sidebar adapter will consider as disabled.

onBoardCreate

The third method onBoardCreate(MCPlayer, Sidebar) is the method to listen whenever a sidebar is created for the target player, Simply overwrite it to listen the event.

Tick time

The fourth method tick() is the method for you to customize the interval to refresh sidebars. return -1 will use the default tick time which is 2.

Priority

The final method priority() is the method for you to customize the priority of this sidebar adapter. Priorities will decide he order of adapters to be displayed, And when the adapter at front is disabled (or consider as disabled) will use the second adapter and goes on

Having two adapters with same priority is not recommended.

Example

Here is the example code that displays sidebar like the gif shown above.

import io.fairyproject.mc.MCPlayer;
import io.fairyproject.sidebar.SidebarAdapter;
import io.fairyproject.util.CC;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;

import java.util.Arrays;
import java.util.List;

@io.fairyproject.container.Component
public class DebugSidebarAdapter implements SidebarAdapter {

    private final String title;
    private final ChatColor[] titleColors;

    private int offset;

    public DebugSidebarAdapter() {
        this.title = "SIDEBAR";
        this.titleColors = new ChatColor[this.title.length()];
        this.setTitleColorOffset(0);
    }

    @Override
    public Component getTitle(MCPlayer mcPlayer) {
        offset++;
        this.setTitleColorOffset(offset);

        Component component = Component.empty();
        final char[] charArray = this.title.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            component = component.append(Component.text(this.titleColors[i].toString() + charArray[i]));
        }

        return component;
    }

    @Override
    public List<Component> getLines(MCPlayer mcPlayer) {
        // Port MCPlayer to bukkit player
        final Player player = mcPlayer.as(Player.class);
        final Location location = player.getLocation();

        return Arrays.asList(
                // ----------------------
                Component.text(CC.SB_BAR),

                // Welcome: PLAYER!
                Component.text("User: ", NamedTextColor.AQUA)
                        .append(Component.text(mcPlayer.getName(), NamedTextColor.WHITE)),

                Component.empty(),

                // Your version: V1_8
                Component.text("Protocol: ", NamedTextColor.AQUA)
                        .append(Component.text(mcPlayer.getVersion().toString().toLowerCase(), NamedTextColor.WHITE)),

                Component.empty(),

                // Your gamemode: SURVIVAL
                Component.text("GameMode: ", NamedTextColor.AQUA)
                        .append(Component.text(player.getGameMode().toString(), NamedTextColor.WHITE)),

                Component.empty(),

                // Your location: 0, 0, 0
                Component.text("Location: ", NamedTextColor.AQUA)
                        .append(Component.text(location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ(), NamedTextColor.WHITE)),

                Component.empty(),

                // mc.testserver.com
                Component.text("mc.testserver.com", NamedTextColor.YELLOW),

                // ----------------------
                Component.text(CC.SB_BAR)
        );
    }

    private void setTitleColorOffset(int offset) {
        List<ChatColor> colors = Arrays.asList(
                ChatColor.BLUE,
                ChatColor.BLUE,
                ChatColor.AQUA,
                ChatColor.AQUA,
                ChatColor.WHITE,
                ChatColor.WHITE,
                ChatColor.AQUA,
                ChatColor.AQUA
        );
        final int length = colors.size();
        for (int i = 0; i < this.title.length(); i++) {
            this.titleColors[i] = colors.get((offset + i) % length);
        }
    }

}
Clone this wiki locally