This is very basic and the first plugin system I've ever looked into making I'm sure there is great room to improve.
I'm also aware java isn't the best thing to use for plugins, I'm currently learning Scala but don't have a ton of free time atm.
Plugin.Java
PluginManager.javaCode:package org.hyperion.rs2.plugin;
import org.hyperion.rs2.model.Player;
/**
* A single instance of a plugin.
*
* @author Jon Hultin
*
* @param <T> The literal type of {@link Plugin#id}.
*/
public abstract class Plugin<T> {
/**
* The associated {@link Class}.
*/
private final Class<?> target;
/**
* The identifier used to target specific actions.
*/
private final T id;
/**
* Creates a new instance of {@link Plugin}.
*
* @param target The associated {@link Class}.
* @param id The identifier used to target specific actions.
*/
public Plugin(Class<?> target, T id) {
this.target = target;
this.id = id;
}
/**
* @return {@link #target}.
*/
public Class<?> getTarget() {
return target;
}
/**
* @return {@link #id}.
*/
public T getId() {
return id;
}
/**
* The context functionality of the {@link Plugin}.
*
* @param player The player making use of the {@link Plugin}
*/
public abstract void execute(Player player);
}
Example Usage:Code:package org.hyperion.rs2.plugin;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* A utility class, which manages {@link Plugin}s.
*
* @author Jon Hultin
*
*/
public final class PluginManager {
/**
* A {@link ArrayList} of allocated {@link Plugin}s.
*/
private static final List<Plugin<?>> plugins = new ArrayList<>();
/**
* Loads the initial directory of {@link Plugin}s.
*/
public static void load() {
load("./plugins/");
}
/**
* Loads the parameterized directory of {@link Plugin}s, as well as all sub directories.
*
* @param dir The directory path.
*/
private static void load(String dir) {
File directory = new File(dir);
System.out.println(dir);
try {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
load(file.getPath());
System.out.println(file.getPath());
break;
} else {
String packaging = file.getPath().replace(".\\plugins\\", "").replace("\\", ".").replace(".java", "");
System.out.println(packaging);
URLClassLoader loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
Plugin<?> plugin = (Plugin<?>) loader.loadClass(packaging).newInstance();
plugins.add(plugin);
loader.close();
}
}
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
/**
* Allocates a {@link Collection} of {@link Plugin}s based on the target of the plugin.
*
* @param target The associated {@link Class} of the {@link Plugin}.
*
* @return a new {@link Collection} of {@link Plugin}s based on the target.
*/
public static Collection<Plugin<?>> forTarget(Class<?> target) {
return plugins.stream().filter($it -> $it.getTarget() == target).collect(Collectors.toList());
}
}
LogoutButtonPlugin.java
Button Packet Event:Code:
import org.hyperion.rs2.model.Player;
import org.hyperion.rs2.packet.ActionButtonPacketHandler;
import org.hyperion.rs2.plugin.Plugin;
public final class LogoutButtonPlugin extends Plugin<Integer> {
public LogoutButtonPlugin() {
super(ActionButtonPacketHandler.class, 2458);
}
@Override
public void execute(Player player) {
player.getActionSender().sendLogout();
}
}
Code:public class ActionButtonPacketHandler implements PacketHandler {
@Override
public void handle(Player player, Packet packet) {
final int button = packet.getShort();
PluginManager.forTarget(ActionButtonPacketHandler.class).stream().filter($it -> button == (Integer) $it.getId())
.findFirst().ifPresent($it -> $it.execute(player));
}
}
