Wait 5 seconds before unhooking every player in the server.
Dieser Commit ist enthalten in:
Ursprung
476a918794
Commit
4cd5d04cae
@ -29,6 +29,7 @@ import com.comphenix.protocol.async.AsyncFilterManager;
|
||||
import com.comphenix.protocol.events.ConnectionSide;
|
||||
import com.comphenix.protocol.events.MonitorAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.injector.DelayedSingleTask;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager;
|
||||
import com.comphenix.protocol.metrics.Statistics;
|
||||
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
|
||||
@ -58,13 +59,17 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
private int tickCounter = 0;
|
||||
private static final int ASYNC_PACKET_DELAY = 1;
|
||||
|
||||
// Used to unhook players after a delay
|
||||
private DelayedSingleTask unhookTask;
|
||||
|
||||
// Used for debugging
|
||||
private boolean debugListener;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
logger = getLoggerSafely();
|
||||
protocolManager = new PacketFilterManager(getClassLoader(), getServer(), logger);
|
||||
unhookTask = new DelayedSingleTask(this);
|
||||
protocolManager = new PacketFilterManager(getClassLoader(), getServer(), unhookTask, logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -181,6 +186,7 @@ public class ProtocolLibrary extends JavaPlugin {
|
||||
asyncPacketTask = -1;
|
||||
}
|
||||
|
||||
unhookTask.close();
|
||||
protocolManager.close();
|
||||
protocolManager = null;
|
||||
statistisc = null;
|
||||
|
@ -0,0 +1,132 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
/**
|
||||
* Represents a single delayed task.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class DelayedSingleTask {
|
||||
|
||||
protected int taskID = -1;
|
||||
protected Plugin plugin;
|
||||
protected BukkitScheduler scheduler;
|
||||
protected boolean closed;
|
||||
|
||||
/**
|
||||
* Create a single task scheduler.
|
||||
* @param plugin - owner plugin.
|
||||
*/
|
||||
public DelayedSingleTask(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.scheduler = plugin.getServer().getScheduler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single task scheduler.
|
||||
* @param plugin - owner plugin.
|
||||
* @param scheduler - specialized scheduler.
|
||||
*/
|
||||
public DelayedSingleTask(Plugin plugin, BukkitScheduler scheduler) {
|
||||
this.plugin = plugin;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a single task for execution.
|
||||
* <p>
|
||||
* Any previously scheduled task will be automatically cancelled.
|
||||
* <p>
|
||||
* Note that a tick delay of zero will execute the task immediately.
|
||||
*
|
||||
* @param ticksDelay - number of ticks before the task is executed.
|
||||
* @param task - the task to schedule.
|
||||
* @return TRUE if the task was successfully scheduled or executed, FALSE otherwise.
|
||||
*/
|
||||
public boolean schedule(long ticksDelay, Runnable task) {
|
||||
if (ticksDelay < 0)
|
||||
throw new IllegalArgumentException("Tick delay cannot be negative.");
|
||||
if (task == null)
|
||||
throw new IllegalArgumentException("task cannot be NULL");
|
||||
if (closed)
|
||||
return false;
|
||||
|
||||
// Special case
|
||||
if (ticksDelay == 0) {
|
||||
task.run();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Boilerplate, boilerplate
|
||||
final Runnable dispatch = task;
|
||||
|
||||
// Don't run multiple tasks!
|
||||
cancel();
|
||||
taskID = scheduler.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dispatch.run();
|
||||
taskID = -1;
|
||||
}
|
||||
}, ticksDelay);
|
||||
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not a future task is scheduled to be executed.
|
||||
* @return TRUE if a current task has been scheduled for execution, FALSE otherwise.
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return taskID >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a future task from being executed.
|
||||
* @return TRUE if a task was cancelled, FALSE otherwise.
|
||||
*/
|
||||
public boolean cancel() {
|
||||
if (isRunning()) {
|
||||
scheduler.cancelTask(taskID);
|
||||
taskID = -1;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw task ID.
|
||||
* @return Raw task ID, or negative one if no task has been scheduled.
|
||||
*/
|
||||
public int getTaskID() {
|
||||
return taskID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the plugin this task belongs to.
|
||||
* @return The plugin scheduling the current taks.
|
||||
*/
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the current task and all future tasks scheduled by this instance.
|
||||
*/
|
||||
public synchronized void close() {
|
||||
if (!closed) {
|
||||
cancel();
|
||||
plugin = null;
|
||||
scheduler = null;
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
}
|
||||
}
|
@ -90,6 +90,13 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
NETWORK_SERVER_OBJECT;
|
||||
}
|
||||
|
||||
// The amount of time to wait until we actually unhook every player
|
||||
private static final int TICKS_PER_SECOND = 20;
|
||||
private static final int UNHOOK_DELAY = 5 * TICKS_PER_SECOND;
|
||||
|
||||
// Delayed unhook
|
||||
private DelayedSingleTask unhookTask;
|
||||
|
||||
// Create a concurrent set
|
||||
private Set<PacketListener> packetListeners =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<PacketListener, Boolean>());
|
||||
@ -129,13 +136,23 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
|
||||
/**
|
||||
* Only create instances of this class if protocol lib is disabled.
|
||||
* @param unhookTask
|
||||
*/
|
||||
public PacketFilterManager(ClassLoader classLoader, Server server, Logger logger) {
|
||||
public PacketFilterManager(ClassLoader classLoader, Server server, DelayedSingleTask unhookTask, Logger logger) {
|
||||
if (logger == null)
|
||||
throw new IllegalArgumentException("logger cannot be NULL.");
|
||||
if (classLoader == null)
|
||||
throw new IllegalArgumentException("classLoader cannot be NULL.");
|
||||
|
||||
// Just boilerplate
|
||||
final DelayedSingleTask finalUnhookTask = unhookTask;
|
||||
|
||||
// References
|
||||
this.unhookTask = unhookTask;
|
||||
this.server = server;
|
||||
this.classLoader = classLoader;
|
||||
this.logger = logger;
|
||||
|
||||
// Used to determine if injection is needed
|
||||
Predicate<GamePhase> isInjectionNecessary = new Predicate<GamePhase>() {
|
||||
@Override
|
||||
@ -144,17 +161,15 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
|
||||
if (phase.hasLogin())
|
||||
result &= getPhaseLoginCount() > 0;
|
||||
// Note that we will still hook players if the unhooking has been delayed
|
||||
if (phase.hasPlaying())
|
||||
result &= getPhasePlayingCount() > 0;
|
||||
result &= getPhasePlayingCount() > 0 || finalUnhookTask.isRunning();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// Initialize values
|
||||
this.server = server;
|
||||
this.classLoader = classLoader;
|
||||
this.logger = logger;
|
||||
// Initialize injection mangers
|
||||
this.playerInjection = new PlayerInjectionHandler(classLoader, logger, isInjectionNecessary, this, server);
|
||||
this.packetInjector = new PacketInjector(classLoader, this, playerInjection);
|
||||
this.asyncFilterManager = new AsyncFilterManager(logger, server.getScheduler(), this);
|
||||
@ -257,8 +272,12 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
// We may have to inject into every current player
|
||||
if (phase.hasPlaying()) {
|
||||
if (phasePlayingCount.incrementAndGet() == 1) {
|
||||
// Inject our hook into already existing players
|
||||
initializePlayers(server.getOnlinePlayers());
|
||||
// If we're about to uninitialize every player, cancel that instead
|
||||
if (unhookTask.isRunning())
|
||||
unhookTask.cancel();
|
||||
else
|
||||
// Inject our hook into already existing players
|
||||
initializePlayers(server.getOnlinePlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -274,8 +293,14 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
// We may have to inject into every current player
|
||||
if (phase.hasPlaying()) {
|
||||
if (phasePlayingCount.decrementAndGet() == 0) {
|
||||
// Inject our hook into already existing players
|
||||
uninitializePlayers(server.getOnlinePlayers());
|
||||
// Schedule unhooking in the future
|
||||
unhookTask.schedule(UNHOOK_DELAY, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Inject our hook into already existing players
|
||||
uninitializePlayers(server.getOnlinePlayers());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren