mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-12-30 20:37:52 +01:00
new check "timed.godmode" with config etc.
This commit is contained in:
parent
67b5505d04
commit
d31525ba3a
@ -31,6 +31,7 @@ import cc.co.evenprime.bukkit.nocheat.events.EventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerChatEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerMoveEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerTeleportEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.TimedEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogManager;
|
||||
|
||||
@ -101,6 +102,7 @@ public class NoCheat extends JavaPlugin {
|
||||
eventManagers.add(new BlockBreakEventManager(this));
|
||||
eventManagers.add(new BlockPlaceEventManager(this));
|
||||
eventManagers.add(new EntityDamageEventManager(this));
|
||||
eventManagers.add(new TimedEventManager(this));
|
||||
|
||||
// Then set up a task to monitor server lag
|
||||
if(lagMeasureTask == null) {
|
||||
@ -188,11 +190,12 @@ public class NoCheat extends JavaPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this periodically to walk over the stored data map and remove old/unused entries
|
||||
* Call this periodically to walk over the stored data map and remove
|
||||
* old/unused entries
|
||||
*
|
||||
*/
|
||||
public void cleanDataMap() {
|
||||
data.cleanDataMap();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.timed;
|
||||
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BaseData;
|
||||
|
||||
public class TimedCheck {
|
||||
|
||||
private final NoCheat plugin;
|
||||
|
||||
public TimedCheck(NoCheat plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void check(Player player, int tickTime, ConfigurationCache cc) {
|
||||
|
||||
// server lag(ged), skip this
|
||||
if(plugin.skipCheck())
|
||||
return;
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
BaseData data = plugin.getData(player.getName());
|
||||
|
||||
EntityPlayer p = ((CraftPlayer) player).getHandle();
|
||||
|
||||
// Compare ingame record of players ticks to our last observed value
|
||||
int difference = p.ticksLived - data.timed.ticksLived;
|
||||
|
||||
// difference should be >= tickTime for perfect synchronization
|
||||
if(difference > tickTime) {
|
||||
// player was faster than expected, give him credit for the
|
||||
// difference
|
||||
data.timed.ticksBehind -= (difference - tickTime);
|
||||
// Reduce violation level over time
|
||||
data.timed.godmodeVL *= 0.90D;
|
||||
|
||||
} else if(difference >= tickTime / 2) {
|
||||
// close enough, let it pass
|
||||
|
||||
// Reduce violation level over time
|
||||
data.timed.godmodeVL *= 0.95D;
|
||||
} else {
|
||||
// That's a bit suspicious, why is the player more than half the
|
||||
// ticktime behind? Keep that in mind
|
||||
data.timed.ticksBehind += tickTime - difference;
|
||||
|
||||
// Is he way too far behind, then correct that
|
||||
if(data.timed.ticksBehind > cc.timed.godmodeTicksLimit) {
|
||||
|
||||
data.timed.godmodeVL += tickTime - difference;
|
||||
|
||||
// Enough is enough
|
||||
data.log.check = "timed.godmode";
|
||||
data.log.godmodeTicksBehind = data.timed.ticksBehind;
|
||||
|
||||
cancel = plugin.execute(player, cc.timed.godmodeActions, (int) data.timed.godmodeVL, data.timed.history, cc);
|
||||
|
||||
// Reduce the time the player is behind accordingly
|
||||
data.timed.ticksBehind -= tickTime;
|
||||
}
|
||||
}
|
||||
|
||||
if(data.timed.ticksBehind < 0) {
|
||||
data.timed.ticksBehind = 0;
|
||||
}
|
||||
|
||||
if(cancel) {
|
||||
// Catch up for at least some of the ticks
|
||||
for(int i = 0; i < tickTime; i++) {
|
||||
p.b(true); // Catch up with the server, one tick at a time
|
||||
}
|
||||
}
|
||||
|
||||
// setup data for next time
|
||||
data.timed.ticksLived = p.ticksLived;
|
||||
}
|
||||
}
|
@ -107,6 +107,14 @@ public abstract class Configuration {
|
||||
public static final OptionNode FIGHT_SELFHIT_CHECK = new OptionNode("check", FIGHT_SELFHIT, DataType.BOOLEAN);
|
||||
public final static OptionNode FIGHT_SELFHIT_ACTIONS = new OptionNode("actions", FIGHT_SELFHIT, DataType.ACTIONLIST);
|
||||
|
||||
private static final OptionNode TIMED = new OptionNode("timed", ROOT, DataType.PARENT);
|
||||
public static final OptionNode TIMED_CHECK = new OptionNode("check", TIMED, DataType.BOOLEAN);
|
||||
|
||||
private static final OptionNode TIMED_GODMODE = new OptionNode("godmode", TIMED, DataType.PARENT);
|
||||
public static final OptionNode TIMED_GODMODE_CHECK = new OptionNode("check", TIMED_GODMODE, DataType.BOOLEAN);
|
||||
public static final OptionNode TIMED_GODMODE_TICKSLIMIT = new OptionNode("tickslimit", TIMED_GODMODE, DataType.INTEGER);
|
||||
public static final OptionNode TIMED_GODMODE_ACTIONS = new OptionNode("actions", TIMED_GODMODE, DataType.ACTIONLIST);
|
||||
|
||||
private final Map<OptionNode, Object> values;
|
||||
private final Configuration defaults;
|
||||
|
||||
|
@ -158,12 +158,25 @@ public class DefaultConfiguration extends Configuration {
|
||||
directionActionList.setActions(20, action.getActions("fightDirectionLog fightCancel".split(" ")));
|
||||
directionActionList.setActions(50, action.getActions("fightDirectionLogHigh fightCancel".split(" ")));
|
||||
setValue(FIGHT_DIRECTION_ACTIONS, directionActionList);
|
||||
|
||||
|
||||
setValue(FIGHT_SELFHIT_CHECK, true);
|
||||
ActionList selfhitActionList = new ActionList();
|
||||
selfhitActionList.setActions(0, action.getActions("fightSelfhitLog fightCancel".split(" ")));
|
||||
setValue(FIGHT_SELFHIT_ACTIONS, selfhitActionList);
|
||||
}
|
||||
|
||||
/*** TIMED ***/
|
||||
{
|
||||
setValue(TIMED_CHECK, true);
|
||||
|
||||
setValue(TIMED_GODMODE_CHECK, true);
|
||||
setValue(TIMED_GODMODE_TICKSLIMIT, 50);
|
||||
|
||||
ActionList directionActionList = new ActionList();
|
||||
directionActionList.setActions(0, action.getActions("godmodeCancel".split(" ")));
|
||||
directionActionList.setActions(100, action.getActions("godmodeLog godmodeCancel".split(" ")));
|
||||
setValue(TIMED_GODMODE_ACTIONS, directionActionList);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeActionFile(File file) {
|
||||
@ -242,6 +255,7 @@ public class DefaultConfiguration extends Configuration {
|
||||
w(w, "log onliquidLog 2 5 med [player] failed [check]: tried to place a [blocktype] block at [placelocation] against block at [placeagainst]. VL [violations]");
|
||||
w(w, "log spamLog 0 5 med [player] failed [check]: Last sent message \"[text]\". VL [violations]");
|
||||
w(w, "log nofallLog 0 5 med [player] failed [check]: tried to avoid fall damage for ~[falldistance] blocks. VL [violations]");
|
||||
w(w, "log godmodeLog 0 5 med [player] failed [check]: lagging or using godmode. VL [violations]");
|
||||
w(w, "");
|
||||
w(w, "");
|
||||
w(w, "# Some log messages related to fighting, displaying the same text, but with different level (Info, Warning, Severe)");
|
||||
@ -265,6 +279,7 @@ public class DefaultConfiguration extends Configuration {
|
||||
w(w, "special spamCancel 0 0");
|
||||
w(w, "special nofallDamage 0 0");
|
||||
w(w, "special fightCancel 0 0");
|
||||
w(w, "special godmodeCancel 0 0");
|
||||
w(w, "");
|
||||
w(w, "# CONSOLECOMMAND Actions: They will execute a command as if it were typed into the console.");
|
||||
w(w, "# - They start with the word 'consolecommand'");
|
||||
|
@ -33,6 +33,9 @@ public class Permissions {
|
||||
public static final String FIGHT_DIRECTION = FIGHT + ".direction";
|
||||
public static final String FIGHT_SELFHIT = FIGHT + ".selfhit";
|
||||
|
||||
public static final String TIMED = CHECKS + ".timed";
|
||||
public static final String TIMED_GODMODE = TIMED + ".godmode";
|
||||
|
||||
public final static String ADMIN_CHATLOG = ADMIN + ".chatlog";
|
||||
public static final String ADMIN_PERMLIST = ADMIN + ".permlist";
|
||||
public static final String ADMIN_RELOAD = ADMIN + ".reload";
|
||||
|
20
src/cc/co/evenprime/bukkit/nocheat/config/cache/CCTimed.java
vendored
Normal file
20
src/cc/co/evenprime/bukkit/nocheat/config/cache/CCTimed.java
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.util.ActionList;
|
||||
|
||||
public class CCTimed {
|
||||
|
||||
public final boolean check;
|
||||
public final boolean godmodeCheck;
|
||||
public final double godmodeTicksLimit;
|
||||
public final ActionList godmodeActions;
|
||||
|
||||
public CCTimed(Configuration data) {
|
||||
|
||||
check = data.getBoolean(Configuration.TIMED_CHECK);
|
||||
godmodeCheck = data.getBoolean(Configuration.TIMED_GODMODE_CHECK);
|
||||
godmodeTicksLimit = data.getInteger(Configuration.TIMED_GODMODE_TICKSLIMIT);
|
||||
godmodeActions = data.getActionList(Configuration.TIMED_GODMODE_ACTIONS);
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
* a world, everything unmodifiable for security/performance
|
||||
*
|
||||
*/
|
||||
public class ConfigurationCache {
|
||||
public class ConfigurationCache {
|
||||
|
||||
public final CCMoving moving;
|
||||
public final CCLogging logging;
|
||||
@ -18,6 +18,7 @@ public class ConfigurationCache {
|
||||
public final CCChat chat;
|
||||
public final CCDebug debug;
|
||||
public final CCFight fight;
|
||||
public final CCTimed timed;
|
||||
|
||||
/**
|
||||
* Instantiate a config cache and populate it with the data of a
|
||||
@ -34,6 +35,7 @@ public class ConfigurationCache {
|
||||
logging = new CCLogging(data, worldSpecificFileLogger);
|
||||
debug = new CCDebug(data);
|
||||
fight = new CCFight(data);
|
||||
timed = new CCTimed(data);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ public class BaseData extends Data {
|
||||
public final LogData log;
|
||||
public final MovingData moving;
|
||||
public final FightData fight;
|
||||
public final TimedData timed;
|
||||
|
||||
private final Data[] data; // for convenience
|
||||
|
||||
public long lastUsedTime;
|
||||
public long lastUsedTime;
|
||||
|
||||
public BaseData() {
|
||||
this.blockbreak = new BlockBreakData();
|
||||
@ -20,9 +21,10 @@ public class BaseData extends Data {
|
||||
this.log = new LogData();
|
||||
this.moving = new MovingData();
|
||||
this.fight = new FightData();
|
||||
this.timed = new TimedData();
|
||||
|
||||
data = new Data[] {this.blockbreak, this.blockplace, this.chat,
|
||||
this.log, this.moving, this.fight};
|
||||
this.log, this.moving, this.fight, this.timed};
|
||||
}
|
||||
|
||||
public void clearCriticalData() {
|
||||
@ -30,7 +32,7 @@ public class BaseData extends Data {
|
||||
d.clearCriticalData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean shouldBeRemoved(long currentTimeInMilliseconds) {
|
||||
return lastUsedTime + 60000L < currentTimeInMilliseconds;
|
||||
}
|
||||
|
@ -18,5 +18,6 @@ public class LogData extends Data {
|
||||
public double reachdistance;
|
||||
public float falldistance;
|
||||
public String playerName;
|
||||
public int godmodeTicksBehind;
|
||||
|
||||
}
|
||||
|
17
src/cc/co/evenprime/bukkit/nocheat/data/TimedData.java
Normal file
17
src/cc/co/evenprime/bukkit/nocheat/data/TimedData.java
Normal file
@ -0,0 +1,17 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.data;
|
||||
|
||||
public class TimedData extends Data {
|
||||
|
||||
public int ticksLived;
|
||||
public int ticksBehind;
|
||||
public double godmodeVL;
|
||||
public final ExecutionHistory history = new ExecutionHistory(); ;
|
||||
|
||||
public TimedData() {}
|
||||
|
||||
@Override
|
||||
public void clearCriticalData() {
|
||||
ticksBehind = 0;
|
||||
ticksLived = 0;
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import java.util.Map;
|
||||
public class PerformanceManager {
|
||||
|
||||
public enum Type {
|
||||
BLOCKBREAK, BLOCKDAMAGE, BLOCKPLACE, CHAT, MOVING, VELOCITY, FIGHT
|
||||
BLOCKBREAK, BLOCKDAMAGE, BLOCKPLACE, CHAT, MOVING, VELOCITY, FIGHT, TIMED
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,81 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.events;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.timed.TimedCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.debug.Performance;
|
||||
import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.Type;
|
||||
|
||||
public class TimedEventManager implements EventManager {
|
||||
|
||||
private final NoCheat plugin;
|
||||
|
||||
private final TimedCheck check;
|
||||
|
||||
private final Performance timedPerformance;
|
||||
|
||||
public TimedEventManager(final NoCheat plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
check = new TimedCheck(plugin);
|
||||
|
||||
this.timedPerformance = plugin.getPerformance(Type.TIMED);
|
||||
|
||||
// "register a listener" for passed time
|
||||
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
|
||||
|
||||
private int executions = 0;
|
||||
private int loopsize = 10;
|
||||
|
||||
public void run() {
|
||||
|
||||
executions++;
|
||||
|
||||
if(executions >= loopsize) {
|
||||
executions = 0;
|
||||
}
|
||||
|
||||
for(Player p : plugin.getServer().getOnlinePlayers()) {
|
||||
if((p.hashCode() & 0x7FFFFFFF) % loopsize == executions) {
|
||||
onTimedEvent(p, loopsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, 1);
|
||||
}
|
||||
|
||||
public void onTimedEvent(Player player, int elapsedTicks) {
|
||||
|
||||
// Performance counter setup
|
||||
long nanoTimeStart = 0;
|
||||
final boolean performanceCheck = timedPerformance.isEnabled();
|
||||
|
||||
if(performanceCheck)
|
||||
nanoTimeStart = System.nanoTime();
|
||||
|
||||
ConfigurationCache cc = plugin.getConfig(player);
|
||||
|
||||
if(cc.timed.check && !player.hasPermission(Permissions.TIMED)) {
|
||||
check.check(player, elapsedTicks, cc);
|
||||
}
|
||||
|
||||
// store performance time
|
||||
if(performanceCheck)
|
||||
timedPerformance.addTime(System.nanoTime() - nanoTimeStart);
|
||||
}
|
||||
|
||||
public List<String> getActiveChecks(ConfigurationCache cc) {
|
||||
LinkedList<String> s = new LinkedList<String>();
|
||||
|
||||
if(cc.timed.check && cc.timed.godmodeCheck)
|
||||
s.add("timed.godmode");
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user