diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/Application.java b/ProtocolLib/src/main/java/com/comphenix/protocol/Application.java index 34e304df..baa6be30 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/Application.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/Application.java @@ -17,14 +17,42 @@ package com.comphenix.protocol; +import org.bukkit.Bukkit; + /** * Ignore this class. * * @author Kristian */ public class Application { + private static Thread mainThread; + private static boolean primaryMethod = true; + public static void main(String[] args) { // For now, though we might consider making a proper application System.out.println("This is a Bukkit library. Place it in the plugin-folder and restart the server!"); } + + /** + * Determine if we are running on the main thread. + * @return TRUE if we are, FALSE otherwise. + */ + public static boolean isPrimaryThread() { + if (primaryMethod) { + try { + return Bukkit.isPrimaryThread(); + } catch (Throwable e) { + primaryMethod = false; + } + } + // Fallback method + return Thread.currentThread().equals(mainThread); + } + + /** + * Register the calling thread as the primary thread. + */ + static void registerPrimaryThread() { + mainThread = Thread.currentThread(); + } } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java b/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java index 693c0bb6..cc6375bf 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java @@ -737,7 +737,7 @@ public class PacketType implements Serializable, Comparable { }; // Execute in the main thread if possible - if (Bukkit.getServer() == null || Bukkit.isPrimaryThread()) { + if (Bukkit.getServer() == null || Application.isPrimaryThread()) { try { return Futures.immediateFuture(callable.call()); } catch (Exception e) { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java index 0a63a9bc..6ff8a6ec 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java @@ -101,6 +101,13 @@ public class ProtocolLibrary extends JavaPlugin { static final String BUKKIT_DEV_SLUG = "protocollib"; static final int BUKKIT_DEV_ID = 45564; + // Different commands + private enum ProtocolCommand { + FILTER, + PACKET, + PROTOCOL + } + /** * The number of milliseconds per second. */ @@ -159,6 +166,7 @@ public class ProtocolLibrary extends JavaPlugin { public void onLoad() { // Load configuration logger = getLoggerSafely(); + Application.registerPrimaryThread(); // Initialize enhancer factory EnhancerFactory.getInstance().setClassLoader(getClassLoader()); @@ -229,13 +237,9 @@ public class ProtocolLibrary extends JavaPlugin { } catch (IllegalArgumentException e) { reporter.reportWarning(config, Report.newBuilder(REPORT_CANNOT_PARSE_INJECTION_METHOD).error(e)); } - - // Initialize command handlers - commandProtocol = new CommandProtocol(reporter, this, updater, config); - commandFilter = new CommandFilter(reporter, this, config); - commandPacket = new CommandPacket(reporter, this, logger, commandFilter, protocolManager); - + // Send logging information to player listeners too + initializeCommands(); setupBroadcastUsers(PERMISSION_INFO); } catch (Throwable e) { @@ -243,6 +247,28 @@ public class ProtocolLibrary extends JavaPlugin { disablePlugin(); } } + + /** + * Initialize all command handlers. + */ + private void initializeCommands() { + // Initialize command handlers + for (ProtocolCommand command : ProtocolCommand.values()) { + try { + switch (command) { + case PROTOCOL: + commandProtocol = new CommandProtocol(reporter, this, updater, config); break; + case FILTER: + commandFilter = new CommandFilter(reporter, this, config); break; + case PACKET: + commandPacket = new CommandPacket(reporter, this, logger, commandFilter, protocolManager); break; + } + } catch (Throwable e) { + reporter.reportWarning(this, Report.newBuilder(REPORT_CANNOT_REGISTER_COMMAND). + messageParam(command.name(), e.getMessage()).error(e)); + } + } + } /** * Retrieve a error reporter that may be filtered by the configuration. @@ -461,8 +487,9 @@ public class ProtocolLibrary extends JavaPlugin { private void registerCommand(String name, CommandExecutor executor) { try { + // Ignore these - they must have printed an error already if (executor == null) - throw new RuntimeException("Executor was NULL."); + return; PluginCommand command = getCommand(name); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketEvent.java b/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketEvent.java index 055f6ad6..bfd7d468 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketEvent.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketEvent.java @@ -27,6 +27,7 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; +import com.comphenix.protocol.Application; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.async.AsyncMarker; import com.google.common.base.Preconditions; @@ -149,7 +150,7 @@ public class PacketEvent extends EventObject implements Cancellable { * @return TRUE if we are, FALSE otherwise. */ public boolean isAsync() { - return !Bukkit.isPrimaryThread(); + return !Application.isPrimaryThread(); } /** diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java index 991dda50..e1b2dc1c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java @@ -235,8 +235,15 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok this.classLoader = builder.getClassLoader(); this.reporter = builder.getReporter(); - // The plugin verifier - this.pluginVerifier = new PluginVerifier(builder.getLibrary()); + // The plugin verifier - we don't want to stop ProtocolLib just because its failing + try { + this.pluginVerifier = new PluginVerifier(builder.getLibrary()); + } catch (Throwable e) { + reporter.reportWarning(this, Report.newBuilder(REPORT_PLUGIN_VERIFIER_ERROR). + messageParam(e.getMessage()).error(e)); + } + + // Prepare version this.minecraftVersion = builder.getMinecraftVersion(); this.loginPackets = new LoginPackets(minecraftVersion); @@ -356,6 +363,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok * @param plugin - plugin to check. */ private void printPluginWarnings(Plugin plugin) { + if (pluginVerifier == null) + return; + try { switch (pluginVerifier.verify(plugin)) { case NO_DEPEND: