424 lines
15 KiB
Java
424 lines
15 KiB
Java
package me.asofold.bpl.cncp;
|
|
|
|
import java.io.File;
|
|
import java.util.HashSet;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.logging.Level;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.command.Command;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.plugin.Plugin;
|
|
import org.bukkit.plugin.PluginDescriptionFile;
|
|
import org.bukkit.plugin.PluginManager;
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
|
|
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
|
import fr.neatmonster.nocheatplus.components.registry.feature.IDisableListener;
|
|
import fr.neatmonster.nocheatplus.components.registry.order.RegistrationOrder;
|
|
import fr.neatmonster.nocheatplus.hooks.NCPHook;
|
|
import fr.neatmonster.nocheatplus.hooks.NCPHookManager;
|
|
import me.asofold.bpl.cncp.config.Settings;
|
|
import me.asofold.bpl.cncp.config.compatlayer.CompatConfig;
|
|
import me.asofold.bpl.cncp.config.compatlayer.NewConfig;
|
|
import me.asofold.bpl.cncp.hooks.Hook;
|
|
import me.asofold.bpl.cncp.hooks.generic.ConfigurableHook;
|
|
import me.asofold.bpl.cncp.hooks.generic.HookBlockBreak;
|
|
import me.asofold.bpl.cncp.hooks.generic.HookBlockPlace;
|
|
import me.asofold.bpl.cncp.hooks.generic.HookEntityDamageByEntity;
|
|
import me.asofold.bpl.cncp.hooks.generic.HookInstaBreak;
|
|
import me.asofold.bpl.cncp.hooks.generic.HookPlayerClass;
|
|
import me.asofold.bpl.cncp.hooks.generic.HookPlayerInteract;
|
|
import me.asofold.bpl.cncp.utils.TickTask2;
|
|
|
|
/**
|
|
* Quick attempt to provide compatibility to NoCheatPlus (by NeatMonster) for
|
|
* some other plugins that change the vanilla game mechanichs, for instance by
|
|
* fast block breaking.
|
|
*
|
|
* @author asofold
|
|
*
|
|
*/
|
|
public class CompatNoCheatPlus extends JavaPlugin {
|
|
|
|
//TODO: Adjust, once NCP has order everywhere (generic + ncp-specific?).
|
|
|
|
public static final String tagEarlyFeature = "cncp.feature.early";
|
|
public static final String beforeTagEarlyFeature = ".*nocheatplus.*|.*NoCheatPlus.*";
|
|
|
|
public static final String tagLateFeature = "cncp.feature.late";
|
|
public static final String afterTagLateFeature = "cncp.system.early.*|.*nocheatplus.*|.*NoCheatPlus.*)";
|
|
|
|
public static final String tagEarlySystem = "cncp.system.early";
|
|
public static final String beforeTagEarlySystem = beforeTagEarlyFeature; // ...
|
|
|
|
public static final RegistrationOrder defaultOrderSystemEarly = new RegistrationOrder(
|
|
tagEarlySystem,
|
|
beforeTagEarlySystem,
|
|
null);
|
|
|
|
public static final RegistrationOrder defaultOrderFeatureEarly = new RegistrationOrder(
|
|
tagEarlyFeature,
|
|
beforeTagEarlyFeature,
|
|
"cncp.system.early.*");
|
|
|
|
public static final RegistrationOrder defaultOrderFeatureLate = new RegistrationOrder(
|
|
tagLateFeature,
|
|
null,
|
|
afterTagLateFeature);
|
|
|
|
private final Settings settings = new Settings();
|
|
|
|
/** Hooks registered with cncp */
|
|
private static final Set<Hook> registeredHooks = new HashSet<Hook>();
|
|
|
|
private final List<Hook> builtinHooks = new LinkedList<Hook>();
|
|
|
|
/**
|
|
* Flag if plugin is enabled.
|
|
*/
|
|
private static boolean enabled = false;
|
|
|
|
/**
|
|
* Static method to enable a plugin (might also be useful for hooks).
|
|
* @param plgName
|
|
* @return
|
|
*/
|
|
public static boolean enablePlugin(String plgName) {
|
|
PluginManager pm = Bukkit.getPluginManager();
|
|
Plugin plugin = pm.getPlugin(plgName);
|
|
if (plugin == null) return false;
|
|
if (pm.isPluginEnabled(plugin)) return true;
|
|
pm.enablePlugin(plugin);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Static method to disable a plugin (might also be useful for hooks).
|
|
* @param plgName
|
|
* @return
|
|
*/
|
|
public static boolean disablePlugin(String plgName){
|
|
PluginManager pm = Bukkit.getPluginManager();
|
|
Plugin plugin = pm.getPlugin(plgName);
|
|
if (plugin == null) return false;
|
|
if (!pm.isPluginEnabled(plugin)) return true;
|
|
pm.disablePlugin(plugin);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get the plugin instance.
|
|
* @return
|
|
*/
|
|
public static CompatNoCheatPlus getInstance(){
|
|
return CompatNoCheatPlus.getPlugin(CompatNoCheatPlus.class);
|
|
}
|
|
|
|
/**
|
|
* API to add a hook. Adds the hook AND registers listeners if enabled. Also respects the configuration for preventing hooks.<br>
|
|
* If you want to not register the listeners use NCPHookManager.
|
|
* @param hook
|
|
* @return
|
|
*/
|
|
public static boolean addHook(Hook hook){
|
|
if (Settings.preventAddHooks.contains(hook.getHookName())){
|
|
Bukkit.getLogger().info("[cncp] Prevented adding hook: "+hook.getHookName() + " / " + hook.getHookVersion());
|
|
return false;
|
|
}
|
|
registeredHooks.add(hook);
|
|
if (enabled) registerListeners(hook);
|
|
boolean added = checkAddNCPHook(hook); // Add if plugin is present, otherwise queue for adding.
|
|
Bukkit.getLogger().info("[cncp] Registered hook"+(added?"":"(NCPHook might get added later)")+": "+hook.getHookName() + " / " + hook.getHookVersion());
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* If already added to NCP
|
|
* @param hook
|
|
* @return
|
|
*/
|
|
private static boolean checkAddNCPHook(Hook hook) {
|
|
PluginManager pm = Bukkit.getPluginManager();
|
|
Plugin plugin = pm.getPlugin("NoCheatPlus");
|
|
if (plugin == null || !pm.isPluginEnabled(plugin))
|
|
return false;
|
|
NCPHook ncpHook = hook.getNCPHook();
|
|
if (ncpHook != null)
|
|
NCPHookManager.addHook(hook.getCheckTypes(), ncpHook);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Conveniently register the listeners, do not use if you add/added the hook with addHook.
|
|
* @param hook
|
|
* @return
|
|
*/
|
|
public static boolean registerListeners(Hook hook) {
|
|
if (!enabled) {
|
|
return false;
|
|
}
|
|
Listener[] listeners = hook.getListeners();
|
|
if (listeners != null){
|
|
// attempt to register events:
|
|
Plugin plg = CompatNoCheatPlus.getPlugin(CompatNoCheatPlus.class);
|
|
if (plg == null) {
|
|
return false;
|
|
}
|
|
for (Listener listener : listeners) {
|
|
NCPAPIProvider.getNoCheatPlusAPI().getEventRegistry().register(listener,
|
|
defaultOrderFeatureEarly, plg);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ----
|
|
|
|
/**
|
|
* Called before loading settings, adds available hooks into a list, so they will be able to read config.
|
|
*/
|
|
private void setupBuiltinHooks() {
|
|
builtinHooks.clear();
|
|
// Might-fail hooks:
|
|
// Set speed
|
|
try{
|
|
builtinHooks.add(new me.asofold.bpl.cncp.hooks.generic.HookSetSpeed());
|
|
}
|
|
catch (Throwable t){}
|
|
// Citizens 2
|
|
try{
|
|
builtinHooks.add(new me.asofold.bpl.cncp.hooks.citizens2.HookCitizens2());
|
|
}
|
|
catch (Throwable t){}
|
|
// mcMMO
|
|
try{
|
|
builtinHooks.add(new me.asofold.bpl.cncp.hooks.mcmmo.HookmcMMO());
|
|
}
|
|
catch (Throwable t){}
|
|
// // MagicSpells
|
|
// try{
|
|
// builtinHooks.add(new me.asofold.bpl.cncp.hooks.magicspells.HookMagicSpells());
|
|
// }
|
|
// catch (Throwable t){}
|
|
// Simple generic hooks
|
|
for (Hook hook : new Hook[]{
|
|
new HookPlayerClass(),
|
|
new HookBlockBreak(),
|
|
new HookBlockPlace(),
|
|
new HookInstaBreak(),
|
|
new HookEntityDamageByEntity(),
|
|
new HookPlayerInteract()
|
|
}){
|
|
builtinHooks.add(hook);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add standard hooks if enabled.
|
|
*/
|
|
private void addAvailableHooks() {
|
|
|
|
// Add built in hooks:
|
|
for (Hook hook : builtinHooks){
|
|
boolean add = true;
|
|
if (hook instanceof ConfigurableHook){
|
|
if (!((ConfigurableHook)hook).isEnabled()) add = false;
|
|
}
|
|
if (add){
|
|
try{
|
|
addHook(hook);
|
|
}
|
|
catch (Throwable t){}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onEnable() {
|
|
enabled = false; // make sure
|
|
// (no cleanup)
|
|
|
|
// Settings:
|
|
settings.clear();
|
|
setupBuiltinHooks();
|
|
loadSettings();
|
|
// Register own listener:
|
|
//NCPAPIProvider.getNoCheatPlusAPI().getEventRegistry().register(this, defaultOrderSystemEarly, this);
|
|
super.onEnable();
|
|
|
|
// Add Hooks:
|
|
addAvailableHooks(); // add before enable is set to not yet register listeners.
|
|
enabled = true;
|
|
|
|
// register all listeners:
|
|
for (Hook hook : registeredHooks){
|
|
registerListeners(hook);
|
|
}
|
|
|
|
// Register to remove hooks when NCP is disabling.
|
|
NCPAPIProvider.getNoCheatPlusAPI().addComponent(new IDisableListener(){
|
|
@Override
|
|
public void onDisable() {
|
|
// Remove all registered cncp hooks:
|
|
unregisterNCPHooks();
|
|
}
|
|
});
|
|
if (!registeredHooks.isEmpty()) {
|
|
registerHooks();
|
|
}
|
|
|
|
// Start ticktask 2
|
|
// TODO: Replace by using TickTask ? Needs order (depend is used now)?
|
|
getServer().getScheduler().scheduleSyncRepeatingTask(this, new TickTask2(), 1, 1);
|
|
|
|
// Finished.
|
|
getLogger().info(getDescription().getFullName() + " is enabled. Some hooks might get registered with NoCheatPlus later on.");
|
|
}
|
|
|
|
public boolean loadSettings() {
|
|
// Read and apply config to settings:
|
|
File file = new File(getDataFolder() , "cncp.yml");
|
|
CompatConfig cfg = new NewConfig(file);
|
|
cfg.load();
|
|
boolean changed = false;
|
|
// General settings:
|
|
if (Settings.addDefaults(cfg)) {
|
|
changed = true;
|
|
}
|
|
settings.fromConfig(cfg);
|
|
// Settings for builtin hooks:
|
|
for (Hook hook : builtinHooks){
|
|
if (hook instanceof ConfigurableHook){
|
|
try{
|
|
ConfigurableHook cfgHook = (ConfigurableHook) hook;
|
|
if (cfgHook.updateConfig(cfg, "hooks.")) changed = true;
|
|
cfgHook.applyConfig(cfg, "hooks.");
|
|
}
|
|
catch (Throwable t){
|
|
getLogger().severe("[cncp] Hook failed to process config ("+hook.getHookName() +" / " + hook.getHookVersion()+"): " + t.getClass().getSimpleName() + ": "+t.getMessage());
|
|
t.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
// save back config if changed:
|
|
if (changed) {
|
|
cfg.save();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onDisable() {
|
|
unregisterNCPHooks(); // Just in case.
|
|
enabled = false;
|
|
super.onDisable();
|
|
}
|
|
|
|
protected int unregisterNCPHooks() {
|
|
// TODO: Clear list here !? Currently done externally...
|
|
int n = 0;
|
|
for (Hook hook : registeredHooks) {
|
|
String hookDescr = null;
|
|
try {
|
|
NCPHook ncpHook = hook.getNCPHook();
|
|
if (ncpHook != null){
|
|
hookDescr = ncpHook.getHookName() + ": " + ncpHook.getHookVersion();
|
|
NCPHookManager.removeHook(ncpHook);
|
|
n ++;
|
|
}
|
|
} catch (Throwable e)
|
|
{
|
|
if (hookDescr != null) {
|
|
// Some error with removing a hook.
|
|
getLogger().log(Level.WARNING, "Failed to unregister hook: " + hookDescr, e);
|
|
}
|
|
}
|
|
}
|
|
getLogger().info("[cncp] Removed "+n+" registered hooks from NoCheatPlus.");
|
|
registeredHooks.clear();
|
|
return n;
|
|
}
|
|
|
|
private int registerHooks() {
|
|
int n = 0;
|
|
for (Hook hook : registeredHooks){
|
|
// TODO: try catch
|
|
NCPHook ncpHook = hook.getNCPHook();
|
|
if (ncpHook == null) continue;
|
|
NCPHookManager.addHook(hook.getCheckTypes(), ncpHook);
|
|
n ++;
|
|
}
|
|
getLogger().info("[cncp] Added "+n+" registered hooks to NoCheatPlus.");
|
|
return n;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see org.bukkit.plugin.java.JavaPlugin#onCommand(org.bukkit.command.CommandSender, org.bukkit.command.Command, java.lang.String, java.lang.String[])
|
|
*/
|
|
@Override
|
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
|
// Permission has already been checked.
|
|
sendInfo(sender);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Send general version and hooks info.
|
|
* @param sender
|
|
*/
|
|
private void sendInfo(CommandSender sender) {
|
|
List<String> infos = new LinkedList<String>();
|
|
infos.add("---- Version infomation ----");
|
|
// Server
|
|
infos.add("#### Server ####");
|
|
infos.add(getServer().getVersion());
|
|
// Core plugins (NCP + cncp)
|
|
infos.add("#### Core plugins ####");
|
|
infos.add(getDescription().getFullName());
|
|
String temp = getOtherVersion("NoCheatPlus");
|
|
infos.add(temp.isEmpty() ? "NoCheatPlus is missing or not yet enabled." : temp);
|
|
infos.add("#### Typical plugin dependencies ####");
|
|
for (String pluginName : new String[]{
|
|
"mcMMO", "Citizens", "MachinaCraft", "MagicSpells",
|
|
// TODO: extend
|
|
}){
|
|
temp = getOtherVersion(pluginName);
|
|
if (!temp.isEmpty()) infos.add(temp);
|
|
}
|
|
// Hooks
|
|
infos.add("#### Registered hooks (cncp) ###");
|
|
for (final Hook hook : registeredHooks){
|
|
temp = hook.getHookName() + ": " + hook.getHookVersion();
|
|
if (hook instanceof ConfigurableHook){
|
|
temp += ((ConfigurableHook) hook).isEnabled() ? " (enabled)" : " (disabled)";
|
|
}
|
|
infos.add(temp);
|
|
}
|
|
// TODO: Registered hooks (ncp) ?
|
|
infos.add("#### Registered hooks (ncp) ####");
|
|
for (final NCPHook hook : NCPHookManager.getAllHooks()){
|
|
infos.add(hook.getHookName() + ": " + hook.getHookVersion());
|
|
}
|
|
final String[] a = new String[infos.size()];
|
|
infos.toArray(a);
|
|
sender.sendMessage(a);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param pluginName Empty string or "name: version".
|
|
*/
|
|
private String getOtherVersion(String pluginName){
|
|
Plugin plg = getServer().getPluginManager().getPlugin(pluginName);
|
|
if (plg == null) return "";
|
|
PluginDescriptionFile pdf = plg.getDescription();
|
|
return pdf.getFullName();
|
|
}
|
|
|
|
}
|