Skip to content

Instantly share code, notes, and snippets.

@natereprogle
Last active April 29, 2023 22:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natereprogle/adaaa32f2b3d852ca67590a1c11362bc to your computer and use it in GitHub Desktop.
Save natereprogle/adaaa32f2b3d852ca67590a1c11362bc to your computer and use it in GitHub Desktop.
A sneak peak at Honeypot 3.0's new Behavior Providers!

A little while ago I announced plans for Honeypot 3.0. One of these items was behavior providers. I'm excited to announce that Behavior Providers are nearly ready, and the rest of the functionality will soon follow!

10,000ft. overview

Behavior Providers are simple classes that provide two things:

  1. A name, which must be unique across all registered providers
  2. A process() method, which takes a player to be processed. This method should return true if processing is successful, and false if not. If the success state of processing doesn't matter, just return true.

Once a provider is created, it is registered in the plugin. The plugin uses a ConcurrentMap to ensure thread and memory safety, and synchronizes registrations to ensure each provider has their turn to register. Once all behavior providers are registered, Honeypot automatically locks registration.

After that, any time an action is triggered by one of Honeypot's built-in event handlers (BlockBreakEvent, for example), Honeypot will then request the correct behavior provider run their process method. Neat, right?

An internal sneak peak

Behavior providers, unfortunately, cannot be implemented via a config object. I'd have to account for too much variables (Like, what if staff wanted players to get struck by lighting, then have 1000 rabbits spawn around them? That's not possible). Instead, Behavior Providers function similar to WorldGuard Flags.

When you want to create a behavior provider, it's rather simple. The first thing you want to do is create a Spigot plugin. That is beyond the scope of this sneak peak, but it's really simple. The second thing you'll need to do is create a new class for your Behavior Provider. Here's the code for the included Ban provider:

package org.reprogle.honeypot.providers.included;

import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.reprogle.honeypot.commands.CommandFeedback;
import org.reprogle.honeypot.providers.Behavior;
import org.reprogle.honeypot.providers.BehaviorProvider;
import org.reprogle.honeypot.providers.BehaviorType;

@Behavior(type = BehaviorType.BAN, name = "Ban")
public class Ban extends BehaviorProvider {

	@Override
	public boolean process(Player p) {
		String banReason = CommandFeedback.sendCommandFeedback("ban");
		String chatPrefix = CommandFeedback.getChatPrefix();

		Bukkit.getBanList(BanList.Type.NAME).addBan(p.getName(), banReason, null,
				chatPrefix);
		p.kickPlayer(banReason);

		return true;
	}
}

Once you create your provider, it's important to register it with Honeypot. This is done in your plugin's onLoad() method, not in your onEnable()!

@Override
public void onLoad() {
  Honeypot.getRegistry().register(new Ban());    
}

As you can see, it's stupid simple!

Let's break it down piece by piece to explain what it's doing

  1. The first step is to annotate your class with the @Behavior annotation. This provides crucial information about the provider, namely the type and the name/unique key. Currently, the Type portion of the annotation doesn't do anything, but it will in the future, so make sure to type your provideres properly!
  2. Extend your class with the BehaviorProvider abstract class. This class includes utilities for equality checking, and also retrieving basic info about the class via the annotation.
  3. Override the default process() method and add your custom logic.
  4. In your plugin's onLoad() method, request Honeypot's behavior registry to register your Behavior Provider!

Once complete, your plugin's logic will essentially be transferred into Honeypot, ready for use. This feature is still in development, but the code you see here is already working! Here's a snippet of what you'll see in your server's logs

[16:49:40] [Server thread/INFO]: [Honeypot] Enabling Honeypot v3.0.0
[16:49:40] [Server thread/INFO]: [Honeypot] Successfully registered 1 behavior providers <==================
[16:49:40] [Server thread/INFO]: [Honeypot] Attempting to load all plugin config files...
[16:49:40] [Server thread/INFO]: [Honeypot] Language set to: en_US
[16:49:40] [Server thread/INFO]: [Honeypot] Successfully loaded all plugin config files!
[16:49:40] [Server thread/INFO]: [Honeypot] Using player interact for containers
[16:49:40] [Server thread/INFO]: [Honeypot] Starting the ghost checker task! If you need to disable this, update the config and restart the server
[16:49:40] [Server thread/INFO]:
[16:49:40] [Server thread/INFO]:  _____                         _
[16:49:40] [Server thread/INFO]: |  |  |___ ___ ___ _ _ ___ ___| |_
[16:49:40] [Server thread/INFO]: |     | . |   | -_| | | . | . |  _|    by TerrorByte
[16:49:40] [Server thread/INFO]: |__|__|___|_|_|___|_  |  _|___|_|      version 3.0.0
[16:49:40] [Server thread/INFO]:                   |___|_|

So far, the only Behavior Provider I've implemented is the default Ban behavior, however you can see that the plugin picked it up, and logged that it was registered. Then, when a Honeypot is triggered, it looks up the action name, or in this case, the behavior provider, and executes the process() method! Because custom actions via config will still be available, Behavior Providers will take higher precidence in the event of a duplicated value between the registry and the config (WIP).

Once Behavior Providers are fully implemented, you won't even be able to tell the difference between them and custom actions. They will be created the same way, and have the same, if not more, functionality! With Behavior Providers, it's all up to the imagination of the developer 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment