mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-09-14 16:08:34 +02:00
Add TickListener component.
TickTask allows registration and calls on each tick.
This commit is contained in:
parent
6d245c62a7
commit
91420f9edf
@ -46,6 +46,7 @@ import fr.neatmonster.nocheatplus.components.NCPListener;
|
|||||||
import fr.neatmonster.nocheatplus.components.NameSetPermState;
|
import fr.neatmonster.nocheatplus.components.NameSetPermState;
|
||||||
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
|
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
|
||||||
import fr.neatmonster.nocheatplus.components.PermStateReceiver;
|
import fr.neatmonster.nocheatplus.components.PermStateReceiver;
|
||||||
|
import fr.neatmonster.nocheatplus.components.TickListener;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||||
@ -258,10 +259,15 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||||||
((INeedConfig) obj).onReload();
|
((INeedConfig) obj).onReload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (obj instanceof TickListener){
|
||||||
|
TickTask.addTickListener((TickListener) obj);
|
||||||
|
}
|
||||||
if (obj instanceof PermStateReceiver){
|
if (obj instanceof PermStateReceiver){
|
||||||
// No immediate update done.
|
// No immediate update done.
|
||||||
permStateReceivers.add((PermStateReceiver) obj);
|
permStateReceivers.add((PermStateReceiver) obj);
|
||||||
}
|
}
|
||||||
|
// Also add to DataManager, which will pick what it needs.
|
||||||
|
// TODO: This is fishy in principle, something more concise?
|
||||||
dataMan.addComponent(obj);
|
dataMan.addComponent(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +311,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||||||
if (obj instanceof PermStateReceiver){
|
if (obj instanceof PermStateReceiver){
|
||||||
permStateReceivers.remove((PermStateReceiver) obj);
|
permStateReceivers.remove((PermStateReceiver) obj);
|
||||||
}
|
}
|
||||||
|
if (obj instanceof TickListener){
|
||||||
|
TickTask.removeTickListener((TickListener) obj);
|
||||||
|
}
|
||||||
if (obj instanceof INotifyReload) {
|
if (obj instanceof INotifyReload) {
|
||||||
notifyReload.remove(obj);
|
notifyReload.remove(obj);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.components;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be registered with the TickTask.
|
||||||
|
* @author mc_dev
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface TickListener {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tick Current tick count. This might start over at 0 if reset in onEnable.
|
||||||
|
* @param timeLast Last time after processing loop. Allows to check how long the tick already took (roughly). No "system time ran backwards" check for this value.
|
||||||
|
*/
|
||||||
|
public void onTick(int tick, long timeLast);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package fr.neatmonster.nocheatplus.utilities;
|
package fr.neatmonster.nocheatplus.utilities;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -13,6 +14,7 @@ import fr.neatmonster.nocheatplus.NoCheatPlus;
|
|||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||||
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
|
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
|
||||||
|
import fr.neatmonster.nocheatplus.components.TickListener;
|
||||||
import fr.neatmonster.nocheatplus.players.DataManager;
|
import fr.neatmonster.nocheatplus.players.DataManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,6 +56,9 @@ public class TickTask implements Runnable {
|
|||||||
/** Actions to execute. */
|
/** Actions to execute. */
|
||||||
private static final List<ViolationData> delayedActions = new LinkedList<ViolationData>();
|
private static final List<ViolationData> delayedActions = new LinkedList<ViolationData>();
|
||||||
|
|
||||||
|
/** Tick listeners to call every tick. */
|
||||||
|
private static final List<TickListener> tickListeners = new ArrayList<TickListener>();
|
||||||
|
|
||||||
/** Last n tick durations, measured from run to run.*/
|
/** Last n tick durations, measured from run to run.*/
|
||||||
private static final long[] tickDurations = new long[lagMaxTicks];
|
private static final long[] tickDurations = new long[lagMaxTicks];
|
||||||
|
|
||||||
@ -93,7 +98,7 @@ public class TickTask implements Runnable {
|
|||||||
* Force executing actions.<br>
|
* Force executing actions.<br>
|
||||||
* Note: Only call from the main thread!
|
* Note: Only call from the main thread!
|
||||||
*/
|
*/
|
||||||
public void executeActions() {
|
public static void executeActions() {
|
||||||
final List<ViolationData> copyActions = new LinkedList<ViolationData>();
|
final List<ViolationData> copyActions = new LinkedList<ViolationData>();
|
||||||
synchronized (delayedActions) {
|
synchronized (delayedActions) {
|
||||||
if (delayedActions.isEmpty()) return;
|
if (delayedActions.isEmpty()) return;
|
||||||
@ -158,6 +163,28 @@ public class TickTask implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a tick listener. Should be thread safe, though... why?
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public static void addTickListener(TickListener listener){
|
||||||
|
synchronized (tickListeners) {
|
||||||
|
if (locked) return;
|
||||||
|
tickListeners.add(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a tick listener. Should be thread safe, though... why?
|
||||||
|
* @param listener
|
||||||
|
* @return If previously contained.
|
||||||
|
*/
|
||||||
|
public static boolean removeTickListener(TickListener listener){
|
||||||
|
synchronized (tickListeners) {
|
||||||
|
return tickListeners.remove(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tasks tick count. It is increased with every server tick.<br>
|
* Get the tasks tick count. It is increased with every server tick.<br>
|
||||||
* NOTE: Can be called from other threads.
|
* NOTE: Can be called from other threads.
|
||||||
@ -318,7 +345,7 @@ public class TickTask implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty queues (call after setLocked(true)
|
* Empty queues (better call after setLocked(true)) and tickListeners.
|
||||||
*/
|
*/
|
||||||
public static void purge(){
|
public static void purge(){
|
||||||
synchronized (permissionUpdates) {
|
synchronized (permissionUpdates) {
|
||||||
@ -327,6 +354,9 @@ public class TickTask implements Runnable {
|
|||||||
synchronized (delayedActions) {
|
synchronized (delayedActions) {
|
||||||
delayedActions.clear();
|
delayedActions.clear();
|
||||||
}
|
}
|
||||||
|
synchronized (tickListeners) {
|
||||||
|
tickListeners.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -345,16 +375,42 @@ public class TickTask implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// Instance methods
|
// Instance methods (meant private).
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Notify all listeners.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private final void notifyListeners() {
|
||||||
|
final List<TickListener> copyListeners = new ArrayList<TickListener>();
|
||||||
|
synchronized (tickListeners) {
|
||||||
|
// Synchronized to allow concurrent adding (!? why ?!).
|
||||||
|
// (Ignores the locked state while still running.)
|
||||||
|
copyListeners.addAll(tickListeners);
|
||||||
|
}
|
||||||
|
for (final TickListener listener : copyListeners){
|
||||||
|
try{
|
||||||
|
listener.onTick(tick, timeLast);
|
||||||
|
}
|
||||||
|
catch(Throwable t){
|
||||||
|
LogUtil.logSevere("[NoCheatPlus] (TickTask) TickListener generated an exception:");
|
||||||
|
LogUtil.logSevere(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
tick ++;
|
tick ++;
|
||||||
|
|
||||||
// Now sync is forced, for the ability to lock.
|
// Actions.
|
||||||
executeActions();
|
executeActions();
|
||||||
|
// Permissions.
|
||||||
updatePermissions();
|
updatePermissions();
|
||||||
|
// Listeners.
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
// Measure time after heavy stuff.
|
// Measure time after heavy stuff.
|
||||||
final long time = System.currentTimeMillis();
|
final long time = System.currentTimeMillis();
|
||||||
|
Loading…
Reference in New Issue
Block a user