agentsclimarketplace

Events

Skill MrPippi/MJP-Claude-Skills/docs/velocity/events

Minecraft Java Plugin Claude SkillsFrom the repository description

Install
npx -y skills add MrPippi/MJP-Claude-Skills --skill events

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.4 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it

Events Skill — Velocity

Purpose

Reference this skill when handling events in a Velocity proxy plugin. Velocity's event system is fully async and uses @Subscribe annotations instead of Bukkit's @EventHandler.

When to Use This Skill

  • Responding to player connections, disconnections, or server switches
  • Intercepting login to apply bans, authentication checks, or queue systems
  • Broadcasting proxy-level events to your own subsystems
  • Registering event listeners on Velocity

API Quick Reference

Class / MethodPurposeNotes
EventManager#register(plugin, listener)Register all @Subscribe methods in an objectPass your plugin instance as first arg
@SubscribeMarks a method as an event listenerMethod takes exactly one event parameter
PostOrderControls listener orderingFIRST, EARLY, NORMAL, LATE, LAST, CUSTOM
ResultedEventEvents with a result (allow/deny)Set result via event.setResult(...)
EventManager#fire(Event)Fire a custom or built-in eventReturns CompletableFuture<E>
EventManager#fireAndForget(Event)Fire without waiting for resultFor events you don't need to read

Code Pattern

package com.yourorg.proxyplugin.listeners;

import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.LoginEvent;
import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.slf4j.Logger;

import java.util.Optional;

public class ConnectionListener {

    private final ProxyServer server;
    private final Logger logger;

    public ConnectionListener(ProxyServer server, Logger logger) {
        this.server = server;
        this.logger = logger;
    }

    // Fires before the player is fully logged in — can deny login
    @Subscribe(order = PostOrder.NORMAL)
    public void onLogin(LoginEvent event) {
        // Example: reject banned players (check your ban list here)
        String playerName = event.getPlayer().getUsername();
        if (isBanned(playerName)) {
            event.setResult(ResultedEvent.ComponentResult.denied(
                Component.text("You are banned from this network.")
                    .color(NamedTextColor.RED)
            ));
        }
    }

    // Fires after player is fully connected
    @Subscribe(order = PostOrder.NORMAL)
    public void onPostLogin(PostLoginEvent event) {
        Player player = event.getPlayer();
        logger.info("{} ({}) connected to the proxy.", player.getUsername(), player.getUniqueId());

        // Network-wide welcome broadcast
        server.getAllPlayers().forEach(p ->
            p.sendMessage(Component.text("→ ")
                .color(NamedTextColor.GREEN)
                .append(Component.text(player.getUsername() + " joined the network.")
                    .color(NamedTextColor.WHITE)))
        );
    }

    // Choose which backend server a player initially connects to
    @Subscribe(order = PostOrder.NORMAL)
    public void onChooseServer(PlayerChooseInitialServerEvent event) {
        Optional<RegisteredServer> lobby = server.getServer("lobby");
        lobby.ifPresent(event::setInitialServer);
    }

    // Fires after player successfully connects to a backend server
    @Subscribe(order = PostOrder.NORMAL)
    public void onServerConnected(ServerConnectedEvent event) {
        Player player = event.getPlayer();
        String serverName = event.getServer().getServerInfo().getName();
        String previousServer = event.getPreviousServer()
            .map(s -> s.getServerInfo().getName())
            .orElse("none");

        logger.info("{} switched from {} to {}", player.getUsername(), previousServer, serverName);
    }

    // Fires when player disconnects from the proxy
    @Subscribe(order = PostOrder.NORMAL)
    public void onDisconnect(DisconnectEvent event) {
        logger.info("{} disconnected ({}).",
            event.getPlayer().getUsername(),
            event.getLoginStatus());
    }

    private boolean isBanned(String playerName) {
        // Check your ban storage
        return false;
    }
}

Register the listener in your main class:

@Subscribe
public void onProxyInitialize(ProxyInitializeEvent event) {
    server.getEventManager().register(this, new ConnectionListener(server, logger));
}

Common Pitfalls

  • Using Bukkit event annotations on Velocity: @EventHandler is a Bukkit annotation. Velocity uses @Subscribe from com.velocitypowered.api.event. Methods annotated with @EventHandler will be silently ignored.

  • Blocking inside event handlers: All Velocity event handlers run on an async thread pool. Blocking with Thread.sleep() or synchronous IO will starve the event thread. Use CompletableFuture for async work.

  • Not setting a result on ResultedEvent: If you don't call event.setResult(...), the default result applies (usually allow). Always explicitly set results for login/connection events when making decisions.

  • Accessing full player game state (inventory, location): Velocity is a proxy — it has no knowledge of the player's in-game state. You can read Player.getUsername(), getUniqueId(), getCurrentServer(), getRemoteAddress(), etc., but not inventory or world data.

Version Notes

  • Velocity 3.3: @Subscribe with PostOrder is the standard. EventTask (returning EventTask from subscribe methods for async handling) is supported.
  • Velocity 3.3: DisconnectEvent.LoginStatus distinguishes SUCCESSFUL_LOGIN, CONFLICTING_LOGIN, PRE_SERVER_JOIN disconnect scenarios.

Related Skills

What ships with it: 2 files

15.8 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.