+ [Angle] Added a new check to prevent players from attacking multiple

entities at the same time (using a forcefield for example);
+ [BedFlying] Added a new check to prevent players from flying (and also
canceling fall damages) by sending fake bed leaving packets;
+ [NoPwnage] Added new options in the configuration to change all the
displayed messages (message displayed when asking for the completion of
a captcha, etc.);
= [FastBreak] Added the type of the broken block in the message
displayed in the chat/console to reduce the number of false positives;
+ [WaterWalk] Check completely rewritten to be more accurate;
= [General] Fixed configuration not be reloaded correctly;
= [NoPwnage] Fixed kicks not being executed properly;
= [NoPwnage] Fixed captcha disabling the check forever for a player when
he successfully enters it;
= [Running] Fixed an issue happening when players where standing on a
fence into water (was also happening with the WaterWalk check);
= [Running] Fixed an issue happening when players where trying to jump
out of a cobweb while still being in the air (false flying warnings).
This commit is contained in:
NeatMonster 2012-05-14 21:06:22 +02:00
parent 2bca6481b1
commit 2feceae9b0
27 changed files with 1023 additions and 491 deletions

View File

@ -171,70 +171,6 @@
stop it.
------------------------ MOVING Permissions for CHECKS -------------------------
- nocheatplus.checks.moving.runfly
Allows the player to move freely. It also treats the player as if he has the
".flying", ".swimming", ".sneaking" and ".nofall" permission too.
- nocheatplus.checks.moving.flying
Allows the player to fly, independent of if he is in "creative mode" or not.
He will be limited in speed by the config settings "flyingspeedvertical" and
"flyingspeedhorizontal". It also treats the player as if he has the
".nofall" permission too.
- nocheatplus.checks.moving.swimming
Allows the player to swim as fast as he is allowed to walk. Normally a
player swims slower than he walks and NoCheatPlus prevents faster movement
in water.
- nocheatplus.checks.moving.sneaking
Allows the player to sneak faster than he is allowed to walk. Normally a
player sneaks a lot slower than he walks and NoCheatPlus prevents faster
movement while sneaking.
- nocheatplus.checks.moving.blocking
Allows the player to move faster than he is allowed while blocking. Normally
a player move a lot slower while blocking than when he walks and NoCheatPlus
prevent faster movement while blocking. Please note this will also allow the
player to attack an entity while blocking (which is not possible with an un-
modified client).
- nocheatplus.checks.moving.cobweb
Allows the player to move fast than he is allowed while being into cobweb.
Normally a player more a lot slower than when he wallks and NoCheatPlus will
try to prevent that kind of behavior.
- nocheatplus.checks.moving.nofall
Allows the player to avoid fall damage by using hacks. Normally NoCheatPlus
will keep track of a players movement and try to rectify the fall-damage
calculations of Minecraft in case they seem to be wrong because of players
tricking the server.
- nocheatplus.checks.moving.morepackets
Allows players to make a lot more movements than normally possible. Doing
more movements will result in faster overall movement speed and causes the
server to spend a lot of additional time for processing these movements.
- nocheatplus.checks.moving.morepacketsvehicle
Allows players to make a lot more movements (while being in a vehicule) than
normally possible. Doing more movements will result in faster overall
movement speed and causes the server to spent a lot of additional time for
processing these movements.
- nocheatplus.checks.moving.waterwalk
Allows players to walk on water (by using a griefing client). This
functionality is also called Jesus mode.
- nocheatplus.checks.moving.boatonground
Allows players to place boats on the ground (and not only on the water).
- nocheatplus.checks.moving.respawntrick
Allows player to respawn on top if they are blocked by a gravel or a sand
block (instead of removing the blocks blocking them). This is usually used
by players to go quickly to the surface when they are in their mines).
-------------------- BLOCKBREAK Permissions for CHECKS -------------------------
- nocheatplus.checks.blockbreak.fastbreak
@ -272,20 +208,6 @@
signature.
--------------------- INVENTORY Permissions for CHECKS -------------------------
- nocheatplus.checks.inventory.drop
Don't limit the number of items that a player may drop within a short time.
- nocheatplus.checks.inventory.instantbow
Don't prevent players from shooting their bows instantly without taking the
usual time to pull the string back.
- nocheatplus.checks.inventory.instanteat
Don't prevent players from eating their food instantly without taking the
usual time to munch on it.
----------------------- CHAT Permissions for CHECKS ----------------------------
- nocheatplus.checks.chat.nopwnage
@ -333,19 +255,93 @@
possible (if he hasn't really jumped/fallen [if he has just sent a packet
before attacking the entity]).
- nocheatplus.checks.fight.angle
Don't prevent the player from attacking multiple entities at the time (this
check is mostly triggered when a player is using a forcefield).
--------------------- INVENTORY Permissions for CHECKS -------------------------
- nocheatplus.checks.inventory.drop
Don't limit the number of items that a player may drop within a short time.
- nocheatplus.checks.inventory.instantbow
Don't prevent players from shooting their bows instantly without taking the
usual time to pull the string back.
- nocheatplus.checks.inventory.instanteat
Don't prevent players from eating their food instantly without taking the
usual time to munch on it.
------------------------ MOVING Permissions for CHECKS -------------------------
- nocheatplus.checks.moving.runfly
Allows the player to move freely. It also treats the player as if he has the
".flying", ".swimming", ".sneaking" and ".nofall" permission too.
- nocheatplus.checks.moving.flying
Allows the player to fly, independent of if he is in "creative mode" or not.
He will be limited in speed by the config settings "flyingspeedvertical" and
"flyingspeedhorizontal". It also treats the player as if he has the
".nofall" permission too.
- nocheatplus.checks.moving.nofall
Allows the player to avoid fall damage by using hacks. Normally NoCheatPlus
will keep track of a players movement and try to rectify the fall-damage
calculations of Minecraft in case they seem to be wrong because of players
tricking the server.
- nocheatplus.checks.moving.swimming
Allows the player to swim as fast as he is allowed to walk. Normally a
player swims slower than he walks and NoCheatPlus prevents faster movement
in water.
- nocheatplus.checks.moving.sneaking
Allows the player to sneak faster than he is allowed to walk. Normally a
player sneaks a lot slower than he walks and NoCheatPlus prevents faster
movement while sneaking.
- nocheatplus.checks.moving.blocking
Allows the player to move faster than he is allowed while blocking. Normally
a player move a lot slower while blocking than when he walks and NoCheatPlus
prevent faster movement while blocking. Please note this will also allow the
player to attack an entity while blocking (which is not possible with an un-
modified client).
- nocheatplus.checks.moving.cobweb
Allows the player to move fast than he is allowed while being into cobweb.
Normally a player more a lot slower than when he wallks and NoCheatPlus will
try to prevent that kind of behavior.
- nocheatplus.checks.moving.morepackets
Allows players to make a lot more movements than normally possible. Doing
more movements will result in faster overall movement speed and causes the
server to spend a lot of additional time for processing these movements.
- nocheatplus.checks.moving.morepacketsvehicle
Allows players to make a lot more movements (while being in a vehicule) than
normally possible. Doing more movements will result in faster overall
movement speed and causes the server to spent a lot of additional time for
processing these movements.
- nocheatplus.checks.moving.waterwalk
Allows players to walk on water (by using a griefing client). This
functionality is also called Jesus mode.
- nocheatplus.checks.moving.respawntrick
Allows player to respawn on top if they are blocked by a gravel or a sand
block (instead of removing the blocks blocking them). This is usually used
by players to go quickly to the surface when they are in their mines).
- nocheatplus.checks.moving.boatonground
Allows players to place boats on the ground (and not only on the water).
--------------------------------------------------------------------------------
---------------------------- Permissions for MODS ------------------------------
--------------------------------------------------------------------------------
- nocheatplus.mods.zombe.fly
Don't prevent the player from using Zombe's fly mod.
- nocheatplus.mods.zombe.xray
Don't prevent the player from using Zombe's noclip.
- nocheatplus.mods.zombe.cheat
Don't prevent the player from using Zombe's cheat.
- nocheatplus.mods.cjb.fly
Don't prevent the player from using CJB's fly mod.
@ -356,12 +352,6 @@
- nocheatplus.mods.cjb.radar
Don't prevent the player from using CJB's radar.
- nocheatplus.mods.rei.cave
Don't prevent the player from using Rei's Minimap's cave mode.
- nocheatplus.mods.rei.radar
Don't prevent the player from using Rei's Minimap's radar.
- nocheatplus.mods.minecraftautomap.ores
Don't prevent the player from using Minecraft AutoMap's ores detector.
@ -371,6 +361,12 @@
- nocheatplus.mods.minecraftautomap.radar
Don't prevent the player from using Minecraft AutoMap's radar.
- nocheatplus.mods.rei.cave
Don't prevent the player from using Rei's Minimap's cave mode.
- nocheatplus.mods.rei.radar
Don't prevent the player from using Rei's Minimap's radar.
- nocheatplus.mods.smartmoving.climbing
Don't prevent the player from using Smart Moving's climb.
@ -389,6 +385,15 @@
- nocheatplus.mods.smartmoving.flying
Don't prevent the player from using Smart Moving's fly.
- nocheatplus.mods.zombe.fly
Don't prevent the player from using Zombe's fly mod.
- nocheatplus.mods.zombe.xray
Don't prevent the player from using Zombe's noclip.
- nocheatplus.mods.zombe.cheat
Don't prevent the player from using Zombe's cheat.
--------------------------------------------------------------------------------
---------------------- Things to know about Permissions ------------------------
@ -400,18 +405,18 @@
- nocheatplus
- nocheatplus.admin
- nocheatplus.checks
- nocheatplus.checks.moving
- nocheatplus.checks.blockbreak
- nocheatplus.checks.blockplace
- nocheatplus.checks.inventory
- nocheatplus.checks.chat
- nocheatplus.checks.inventory
- nocheatplus.checks.moving
- nocheatplus.checks.fight
- nocheatplus.mods
- nocheatplus.mods.zombe
- nocheatplus.mods.cjb
- nocheatplus.mods.rei
- nocheatplus.mods.minecraftautomap
- nocheatplus.mods.rei
- nocheatplus.mods.smartmoving
- nocheatplus.mods.zombe
To give a player all the permissions that start with that permission node.
@ -533,6 +538,14 @@
active:
Should players be checked for this behaviour.
intervalsurvival:
The regular interval between each block breaks if the player is in
survival mode.
intervalcreative:
The regular interval between each block breaks if the player is in
creative mode.
actions:
What should happen if the player is considered to cheat this way. The
default is to prevent him from breaking the block ("cancel" breaking)
@ -621,6 +634,10 @@
active:
Should players be checked for this behaviour.
interval:
The regular interval between two block places (doesn't depend on the
player's gamemode).
actions:
What should happen if the player is considered to cheat this way. The
default is to prevent him from placing the block ("cancel" placing)
@ -696,12 +713,15 @@
for this check is the interval elapsed subtracted to the interval
defined in the configuration's file; It increases with every failure and
decreases with every successfully thrown projectile.
5) FASTSIGN
Players using custom clients are able to spam the server with signs
containing the text they have chosen.
active:
Should players get checked for this type of hack.
exclusions:
If the first line of the sign is included into this list, the sign won't
be checked.
@ -711,37 +731,49 @@
Checks that at least technically have to do with chat or commands.
hideCommands:
Enable this if you don't want NoCheat+'s commands to reply to the player if
he doesn't have the permissions to use them.
1) NOPWNAGE:
The instructions for this check comes directly from NoPwnage's instructions
file. You can find the project at http://dev.bukkit.org/server-mods/
nopwnage/.
warnPlayers:
active:
Should messages be check to see if players are spamming the server?
warnplayers:
Should a player that reaches the "warnLevel" get a text message telling
him that he is under suspicion of being a bot.
warnOthers:
warnothers:
Should all players get warned when a player gets banned for spambot-like
activity?
warnLevel:
warnlevel:
How much suspicion must a message earn to issue a warning for the
player?
warnTimeout:
warntimeout:
After what time (in ms) should a player be considered "unwarned" again.
banLevel:
banlevel:
How much suspicion must a message earn to execute the "commands"
(usually ban the player). If warnings for players are enabled and the
player hasn't been warned yet, he'll get warned instead.
move.enabled:
otheractions:
NoPwnage allows you to decide what should happen when a player reaches
"banLevel" or relogged too fast. The default is to kick him and ban IP
and name. You'll also get a log message to console stating how exactly
he reached the "banLevel" (how much suspicion was added by each check).
"[player]" and "[ip]" wildcards will be replaced by the actual data
during execution.
IMPORTANT: Please notice that cancelling the check will not cancel the
actual message but kick the player (and the kick message defined in the
configuration will displayed on the player's screen).
move.active:
move.weightbonus:
move.weightmalus:
move.timeout:
@ -749,57 +781,57 @@
he did move, the suspicion will be reduced by the "weightbonus" value.
If he did not move, the suspicion will be increased by "weightmalus"
value.
Only used if "enabled".
Only used if "actived".
messageRepeat.enabled:
messageRepeat.weight:
messageRepeat.timeout:
repeat.active:
repeat.weight:
repeat.timeout:
NoPwnage will check if a player repeats his messages within the
"timeout" timeframe. Even if the message is a bit different, it will be
counted as being a repetition. The suspicion is increased by "weight"
and for each additional repetition by "weight/2". This means that
multiple repetitions will increase suspicion, but not as much as the
first repetition.
Only used if "enabled".
Only used if "actived".
messageSpeed.enabled:
messageSpeed.weight:
messageSpeed.timeout:
speed.active:
speed.weight:
speed.timeout:
NoPwnage will check if a player sends messages too fast. If a message is
sent within "timout" ms after the previous message, increase suspicion
by "weight". For each additional message that is sent within "timeout",
the suspicion is increased by "weight/2". This means that multiple
too fast sent messages in a row will increase suspicion, but not as much
as the first.
Only used if "enabled".
Only used if "actived".
messageFirst.enabled:
messageFirst.weight:
messageFirst.timeout:
first.active:
first.weight:
first.timeout:
NoPwnage will check if a player sends his first message within "timeout"
ms after his login. If he does, increase supspicion by "weight".
Only used if "enabled".
Only used if "actived".
globalMessageRepeat.enabled:
globalMessageRepeat.weight:
globalMessageRepeat.timeout:
global.active:
global.weight:
global.timeout:
NoPwnage will check if a player repeats a message that has been sent by
another player just before, within "timeout". If he does, suspicion will
be increased by "weight" and for each additional repetition by
"weight/2", independent of by which player. This means that multiple
repetitions will increase suspicion, but not as much as the first
repetition.
Only used if "enabled".
Only used if "actived".
bannedMessageRepeat.enabled:
bannedMessageRepeat.weight:
bannedMessageRepeat.timeout:
banned.active:
banned.weight:
banned.timeout:
NoPwnage will remember the last message that caused someone to get
banned. If a player repeats that message within "timeout" ms, the
suspicion will be increased by "weight".
Only used if "enabled".
Only used if "actived".
relog.enabled:
relog.active:
relog.time:
relog.warnings:
relog.timeout:
@ -808,44 +840,34 @@
"warnings" times already, the "commands" will be executed for him.
Warnings get removed if the time of the last warning was more than
"timeout" ms ago.
kickmessage:
The message that will be displayed to the player is he is kicked by the
NoPwnage check.
Only used if "actived".
actions:
NoPwnage allows you to decide what should happen when a player reaches
"banLevel" or relogged too fast. The default is to kick him and ban IP
and name. You'll also get a log message to console stating how exactly
he reached the "banLevel" (how much suspicion was added by each check).
"[player]" and "[ip]" wildcards will be replaced by the actual data
during execution.
IMPORTANT: Please notice that cancelling the check will not cancel the
actual message but kick the player (and the kick message defined in the
configuration will displayed on the player's screen).
captcha.enabled:
captcha.active:
Should players that get to "banlevel" be presented with a captcha first
instead of running the commands immediatly?
captcha.question:
How should the question be worded. Use & to create colors. The text
[captcha] will be replaced with the actual captcha.
tries:
captcha.tries:
How many attempts will a player have to give the correct answer. A
failed attempt will display the question again. Be generous here, as
players may not be fast enough to read the question the first few times
or be otherwise distracted.
length:
captcha.length:
How many characters should the captcha have.
characters:
captcha.characters:
The characters for the captcha are randomly drawn from this string
messages.kick
messages.captchaquestion
messages.captchasuccess
messages.warnplayer
messages.warnothers
messages.warnrelog
You can customize here all the message which are going to be displayed
by the NoPwnage check (the kick message displayed when a spambot is
kicked, the message asking for a captcha, the warning messages, etc.).
2) ARRIVALSLIMIT:
This check limits the number of new players joining every X seconds to
@ -862,10 +884,14 @@
The interval in milliseconds during which the number of new players
defined in the configuration are allowed to join.
cooldown:
cooldowndelay:
The number of milliseconds during which new players won't be allowed
to join if too many new players have been detected.
kickmessage:
The message that will be displayed when a player is kicked by this
check.
newtime:
The time elsaped since the player's first join to be considered as
an old/regular player.
@ -1069,6 +1095,28 @@
the event. The Violation Level (VL) for this check is the difference
between the real values and the values defined in the configuration.
9) ANGLE
Players may be able to attack accurately multiple entities at the same time
using a forcefield. This check will try to stop that kind of cheat by check
for the time, the angle delta and the location of the player between each
hit. This check has been introduced recently so it's still experimental.
active:
Should players be checked for this behavior.
threshold:
This is the minimum value (percentage) to trigger a violation. This
percentage is calculated by doing a weighted average of the percentage
of the time, angle and location checks. I recommand to use a value close
to 50.
actions:
What should happen if the player fails this check. Default is to not
allow the player to attack the entity ("cancel" the attack) and log
the event. The Violation Level (VL) for this check is the difference
between the real values and the values defined in the configuration.
----------------------------- INVENTORY Subsection -----------------------------
@ -1187,7 +1235,7 @@
swimming speed of players at all (NoCheatPlus knows when players sprint,
use Swiftness potions etc and will already adapt the speed based on
that data).
verticalswimspped:
How fast should the player be allowed to swim (but on the vertical
axis). Default is "100", meaning 100% of normal swimming speed. You will
@ -1228,12 +1276,12 @@
how severe the cheating is) and teleport the player to the last known
legitimate location on ground that NoCheatPlus can remember for that
player ("cancel" the movement).
NOFALL:
This is an entire subsection dedicated to the "moving.nofall" check.
It will be used to check if the player has tried to avoid fall
damages.
active:
Should players be checked for a common type of "nofall" hack, that
allows them to avoid taking damage when falling. If you don't care
@ -1292,6 +1340,24 @@
him. The VL increases with every failed check and slowly decreases for
every passed check.
BEDFLYING:
This is an entire subsection dedicated to the "moving.bedflying" check.
It will be used instead as a complements of the running check to make
sure that the player isn't try to fly by sending bed leaving packets.
This technique can also be used to avoid fall damages.
active:
Should players get checked for this type of movement related hacks at
all. If deactivated, player may be able to fly (but really slowly).
actions:
What should happen if a player flies but isn't allowed to do so?
Default is to log messages and to prevent the player from moving
("cancel" his last movement). The Violation Level (VL) of this check
is the distance that the player went beyond what NoCheatPlus allowed
him. The VL increases with every failed check and slowly decreases for
every passed check.
2) MOREPACKETS:
The morepackets check is complementary to the "runfly" check. While the
@ -1340,9 +1406,8 @@
Firstly, it'll check if the player's move is valid (not only moving the X
and Z axes but also on the Y axis and, of course, if the player is near the
surface (most of the griefing client set the player 0.3 blocks under the
water surface). Secondly, it'll make sure the player is using the borders
of the block to climb outside the water (it prevents players using griefing
clients to simply jump multiple times over the water).
water surface). Secondly, it'll make sure the player is jumping on the
surface of the water by checking his velocity.
active:
Should players be checked for this kind of cheating. If you are not
@ -1351,13 +1416,12 @@
easily the oceans.
actions:
What should happen if a player is considered to be cheating by walking
What should happen if a player is considered to be cheating by walking
on water. Default is to log messages and to prevent the player from
moving ("cancel" his last movement). The Violation Level (VL) of this
check is the distance between the player and the surface or how far away
he is from the normal position if a player climbing a block. The VL
increases with every failed check and slowly decreases for every passed
check.
is his velocity from a regular value. The VL increases with every failed
check and slowly decreases for every passed check.
--------------------------------------------------------------------------------

View File

@ -36,33 +36,6 @@ permissions:
nocheatplus.checks:
description: Allow the player to bypass all checks
children:
nocheatplus.checks.moving:
description: Allow the player to bypass all moving related checks
children:
nocheatplus.checks.moving.runfly:
description: Allow a player to move as free and as fast as he wants (ignores flying, swimming and sneaking settings)
nocheatplus.checks.moving.flying:
description: Allow a player to fly, but only within given speed limits (ignores swimming and sneaking settings)
nocheatplus.checks.moving.swimming:
description: Allow a player to move through water without slowdown
nocheatplus.checks.moving.sneaking:
description: Allow a player to sneak without slowdown
nocheatplus.checks.moving.blocking:
description: Allow a player to block without slowdown
nocheatplus.checks.moving.cobweb:
description: Allow a player to move without slowdown while being into cobweb
nocheatplus.checks.moving.nofall:
description: Allow a player to cheat and not take fall damage at all
nocheatplus.checks.moving.morepackets:
description: Allow a player to send more move-event-packets than normal, causing him to move faster than normal
nocheatplus.checks.moving.morepacketsvehicle:
description: Allow a player to send more vehicule-move-event-packets than normal, causing him to move faster than normal
nocheatplus.checks.moving.waterwalk:
description: Allow a player to walk on the water
nocheatplus.checks.moving.boatonground:
description: Allow a player to place a boat on the ground (not only on the water)
nocheatplus.checks.moving.respawntrick:
description: Allow a player to respawn on top if blocked by gravel or sand (instead of removing the blocks)
nocheatplus.checks.blockbreak:
description: Allow the player to bypass all blockbreak checks
children:
@ -115,6 +88,8 @@ permissions:
description: Allow a player to do knockbacks when it's not technically possible
nocheatplus.checks.fight.critical:
description: Allow a player to do criticals when it's not technically possible
nocheatplus.checks.fight.angle:
description: Allow a player to attack multiple entities at the same time (using a forcefield)
nocheatplus.checks.inventory:
description: Allow the player to bypass all inventory checks
children:
@ -124,18 +99,38 @@ permissions:
description: Allow a player to eat food faster than normally possible
nocheatplus.checks.inventory.instantbow:
description: Allow a player to charge his bow faster than usual
nocheatplus.checks.moving:
description: Allow the player to bypass all moving related checks
children:
nocheatplus.checks.moving.runfly:
description: Allow a player to move as free and as fast as he wants (ignores flying, swimming and sneaking settings)
nocheatplus.checks.moving.flying:
description: Allow a player to fly, but only within given speed limits (ignores swimming and sneaking settings)
nocheatplus.checks.moving.bedflying:
description: Allow a player to fly by sending fake bed leaving packets (and only cancelling his fall damages)
nocheatplus.checks.moving.nofall:
description: Allow a player to cheat and not take fall damage at all
nocheatplus.checks.moving.swimming:
description: Allow a player to move through water without slowdown
nocheatplus.checks.moving.sneaking:
description: Allow a player to sneak without slowdown
nocheatplus.checks.moving.blocking:
description: Allow a player to block without slowdown
nocheatplus.checks.moving.cobweb:
description: Allow a player to move without slowdown while being into cobweb
nocheatplus.checks.moving.morepackets:
description: Allow a player to send more move-event-packets than normal, causing him to move faster than normal
nocheatplus.checks.moving.morepacketsvehicle:
description: Allow a player to send more vehicule-move-event-packets than normal, causing him to move faster than normal
nocheatplus.checks.moving.waterwalk:
description: Allow a player to walk on the water
nocheatplus.checks.moving.respawntrick:
description: Allow a player to respawn on top if blocked by gravel or sand (instead of removing the blocks)
nocheatplus.checks.moving.boatonground:
description: Allow a player to place a boat on the ground (not only on the water)
nocheatplus.mods:
description: Allow the player to use all the client mods
children:
nocheatplus.mods.zombe:
description: Allow the player to use all Zombe's cheats
children:
nocheatplus.mods.zombe.fly:
description: Allow the player to use Zombe's fly mod
nocheatplus.mods.zombe.noclip:
description: Allow the player to use Zombe's noclip
nocheatplus.mods.zombe.cheat:
description: Allow the player to use Zombe's cheat
nocheatplus.mods.cjb:
description: Allow the player to use all CJB's cheats
children:
@ -145,13 +140,6 @@ permissions:
description: Allow the player to use CJB's xray
nocheatplus.mods.cjb.radar:
description: Allow the player to use CJB's radar
nocheatplus.mods.rei:
description: Allow the player to use all Rei's Minimap's cheats
children:
nocheatplus.mods.rei.cave:
description: Allow the player to use Rei's cave mode
nocheatplus.mods.rei.radar:
description: Allow the player to use Rei's radar
nocheatplus.mods.minecraftautomap:
description: Allow the player to use all Minecraft AutoMap's cheats
children:
@ -161,6 +149,13 @@ permissions:
description: Allow the player to use Minecraft AutoMap's cave mode
nocheatplus.mods.minecraftautomap.radar:
description: Allow the player to use Minecraft AutoMap's radar
nocheatplus.mods.rei:
description: Allow the player to use all Rei's Minimap's cheats
children:
nocheatplus.mods.rei.cave:
description: Allow the player to use Rei's cave mode
nocheatplus.mods.rei.radar:
description: Allow the player to use Rei's radar
nocheatplus.mods.smartmoving:
description: Allow the player to use all Smart Moving's moves
children:
@ -175,4 +170,13 @@ permissions:
nocheatplus.mods.smartmoving.jumping:
description: Allow the player to use Smart Moving's jump
nocheatplus.mods.smartmoving.flying:
description: Allow the player to use Smart Moving's fly
description: Allow the player to use Smart Moving's fly
nocheatplus.mods.zombe:
description: Allow the player to use all Zombe's cheats
children:
nocheatplus.mods.zombe.fly:
description: Allow the player to use Zombe's fly mod
nocheatplus.mods.zombe.noclip:
description: Allow the player to use Zombe's noclip
nocheatplus.mods.zombe.cheat:
description: Allow the player to use Zombe's cheat

View File

@ -4,7 +4,7 @@
<!-- Informations -->
<name>NoCheatPlus</name>
<version>3.6_1</version>
<version>3.6.1</version>
<description>Detect and fight the exploitation of various flaws/bugs in Minecraft.</description>
<url>http://dev.bukkit.org/server-mods/nocheatplus</url>

View File

@ -101,6 +101,7 @@ public class CommandHandler implements CommandExecutor {
sender.sendMessage("[NoCheatPlus] Reloading configuration");
ConfigManager.cleanup();
ConfigManager.init();
NCPPlayer.reloadConfig();
sender.sendMessage("[NoCheatPlus] Configuration reloaded");
} else
sender.sendMessage("You lack the " + Permissions.ADMIN_RELOAD + " permission to use 'reload'");
@ -121,7 +122,7 @@ public class CommandHandler implements CommandExecutor {
ConfPaths.MISCELLANEOUS_PROTECTPLUGINS);
// Hide NoCheatPlus's commands if the player doesn't have the required permission
if (protectPlugins && !NCPPlayer.hasPermission(sender, "nocheatplus.admin.commands")) {
if (protectPlugins && !NCPPlayer.hasPermission(sender, Permissions.ADMIN_COMMANDS)) {
sender.sendMessage("Unknown command. Type \"help\" for help.");
return true;
}

View File

@ -20,7 +20,6 @@ public enum ParameterName {
BLOCK_TYPE("blocktype"),
LIMIT("limit"),
FOOD("food"),
SERVERS("servers"),
REASON("reason"),
IP("ip");

View File

@ -2,12 +2,14 @@ package fr.neatmonster.nocheatplus.checks.blockbreak;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.players.NCPPlayer;
import fr.neatmonster.nocheatplus.players.informations.Statistics.Id;
import fr.neatmonster.nocheatplus.utilities.locations.SimpleLocation;
/**
* A check used to verify if the player isn't placing his blocks too quickly
@ -80,7 +82,14 @@ public class FastBreakCheck extends BlockBreakCheck {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(getData(player).fastBreakVL));
else
else if (wildcard == ParameterName.BLOCK_TYPE) {
final SimpleLocation location = getData(player).lastDamagedBlock;
if (location.isSet())
return new Location(player.getWorld(), location.x, location.y, location.z).getBlock().getType().name()
.toLowerCase().replace("_", " ");
else
return "UNKNOWN";
} else
return super.getParameter(wildcard, player);
}
}

View File

@ -23,7 +23,6 @@ public class ChatConfig extends CheckConfig {
public final int noPwnageWarnLevel;
public final long noPwnageWarnTimeout;
public final int noPwnageBanLevel;
public final String noPwnageKickMessage;
public final ActionList noPwnageActions;
public final boolean noPwnageMoveCheck;
@ -61,6 +60,13 @@ public class ChatConfig extends CheckConfig {
public final String noPwnageCaptchaCharacters;
public final int noPwnageCaptchaTries;
public final String noPwnageMessagesKick;
public final String noPwnageMessagesCaptchaQuestion;
public final String noPwnageMessagesCaptchaSuccess;
public final String noPwnageMessagesWarnPlayer;
public final String noPwnageMessagesWarnOthers;
public final String noPwnageMessagesWarnRelog;
public final boolean arrivalsLimitCheck;
public final int arrivalsLimitPlayersLimit;
public final long arrivalsLimitTimeframe;
@ -83,7 +89,6 @@ public class ChatConfig extends CheckConfig {
noPwnageWarnLevel = data.getInt(ConfPaths.CHAT_NOPWNAGE_WARNLEVEL);
noPwnageWarnTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_WARNTIMEOUT);
noPwnageBanLevel = data.getInt(ConfPaths.CHAT_NOPWNAGE_BANLEVEL);
noPwnageKickMessage = data.getString(ConfPaths.CHAT_NOPWNAGE_KICKMESSAGE);
noPwnageActions = data.getActionList(ConfPaths.CHAT_NOPWNAGE_ACTIONS, Permissions.CHAT_NOPWNAGE);
noPwnageMoveCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_MOVE_CHECK);
@ -121,6 +126,13 @@ public class ChatConfig extends CheckConfig {
noPwnageCaptchaCharacters = data.getString(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS);
noPwnageCaptchaTries = data.getInt(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES);
noPwnageMessagesKick = data.getString(ConfPaths.CHAT_NOPWNAGE_MESSAGES_KICK);
noPwnageMessagesCaptchaQuestion = data.getString(ConfPaths.CHAT_NOPWNAGE_MESSAGES_CAPTCHAQUESTION);
noPwnageMessagesCaptchaSuccess = data.getString(ConfPaths.CHAT_NOPWNAGE_MESSAGES_CAPTCHASUCCESS);
noPwnageMessagesWarnPlayer = data.getString(ConfPaths.CHAT_NOPWNAGE_MESSAGES_WARNPLAYER);
noPwnageMessagesWarnOthers = data.getString(ConfPaths.CHAT_NOPWNAGE_MESSAGES_WARNOTHERS);
noPwnageMessagesWarnRelog = data.getString(ConfPaths.CHAT_NOPWNAGE_MESSAGES_WARNRELOG);
arrivalsLimitCheck = data.getBoolean(ConfPaths.CHAT_ARRIVALSLIMIT_CHECK);
arrivalsLimitPlayersLimit = data.getInt(ConfPaths.CHAT_ARRIVALSLIMIT_PLAYERSLIMIT);
arrivalsLimitTimeframe = data.getLong(ConfPaths.CHAT_ARRIVALSLIMIT_TIMEFRAME);

View File

@ -40,7 +40,6 @@ public class ChatData extends CheckData {
// Remember some data about captcha
public String captchaAnswer = "";
public String captchaQuestion = "";
public boolean captchaDone = false;
public boolean captchaStarted = false;
public int captchaTries;
@ -51,6 +50,14 @@ public class ChatData extends CheckData {
public String reason = "";
public String ip = "";
public void clear() {
location.reset();
lastMessage = captchaAnswer = captchaQuestion = "";
lastMessageTime = joinTime = leaveTime = lastWarningTime = lastRelogWarningTime = lastMovedTime = 0L;
messageRepeated = relogWarnings = speedRepeated = captchaTries = 0;
captchaStarted = false;
}
public boolean compareLocation(final SimpleLocation l) {
return location != null && location.x == l.x && location.y == l.y && location.z == l.z;
}

View File

@ -10,6 +10,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckListener;
import fr.neatmonster.nocheatplus.players.NCPPlayer;
import fr.neatmonster.nocheatplus.players.informations.Permissions;
@ -64,7 +65,7 @@ public class ChatListener extends CheckListener {
// First the nopwnage check
if (cc.noPwnageCheck && !player.hasPermission(Permissions.CHAT_NOPWNAGE))
if (noPwnageCheck.check(player, event)) {
player.getBukkitPlayer().kickPlayer(cc.noPwnageKickMessage);
player.getBukkitPlayer().kickPlayer(Check.removeColors(cc.noPwnageMessagesKick));
return;
} else
cancelled = event.isCancelled();
@ -141,7 +142,7 @@ public class ChatListener extends CheckListener {
// Check if the join is legit
if (cc.noPwnageCheck && !player.hasPermission(Permissions.CHAT_NOPWNAGE))
if (noPwnageCheck.handleJoin(player, data, cc))
event.disallow(Result.KICK_OTHER, cc.noPwnageKickMessage);
event.disallow(Result.KICK_OTHER, Check.removeColors(cc.noPwnageMessagesKick));
/*** ARRIVALSLIMIT CHECK ***/
// Do not check the players if the event is already cancelled,

View File

@ -3,7 +3,6 @@ package fr.neatmonster.nocheatplus.checks.chat;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerChatEvent;
@ -55,16 +54,15 @@ public class NoPwnageCheck extends ChatCheck {
boolean cancel = false;
// If the player has filled out the captcha, return
if (data.commandsHaveBeenRun || !player.getBukkitPlayer().isOnline() || cc.noPwnageCaptchaCheck
&& data.captchaDone)
// His reply was valid, he isn't a spambot
if (data.commandsHaveBeenRun || !player.getBukkitPlayer().isOnline())
return cancel;
if (cc.noPwnageCaptchaCheck && data.captchaStarted) {
// Correct answer?
if (data.message.equals(data.captchaAnswer)) {
data.captchaDone = true;
player.sendMessage(ChatColor.GREEN + "OK, it sounds like you're not a spambot.");
// His reply was valid, he isn't a spambot
data.clear();
player.sendMessage(replaceColors(cc.noPwnageMessagesCaptchaSuccess));
} else {
// Display the question again
player.sendMessage(data.captchaQuestion);
@ -158,8 +156,7 @@ public class NoPwnageCheck extends ChatCheck {
data.captchaStarted = true;
final String captcha = generateCaptcha(cc);
data.captchaAnswer = captcha;
data.captchaQuestion = ChatColor.RED + "Please type '" + ChatColor.GOLD + captcha + ChatColor.RED
+ "' to continue sending messages/commands.";
data.captchaQuestion = replaceColors(cc.noPwnageMessagesCaptchaQuestion).replace("[captcha]", captcha);
event.setCancelled(true);
player.sendMessage(data.captchaQuestion);
} else if (player.getBukkitPlayer().isOnline()) {
@ -235,9 +232,8 @@ public class NoPwnageCheck extends ChatCheck {
data.relogWarnings = 0;
if (data.relogWarnings < cc.noPwnageRelogWarnings) {
player.sendMessage(replaceColors(ConfigManager.getConfigFile().getString(ConfPaths.LOGGING_PREFIX))
+ ChatColor.DARK_RED
+ "You relogged really fast! If you keep doing that, you're going to be banned.");
player.sendMessage(replaceColors(ConfigManager.getConfigFile().getString(ConfPaths.LOGGING_PREFIX)
+ cc.noPwnageMessagesWarnRelog));
data.lastRelogWarningTime = now;
data.relogWarnings++;
} else if (now - data.lastRelogWarningTime < cc.noPwnageRelogTimeout) {
@ -347,9 +343,7 @@ public class NoPwnageCheck extends ChatCheck {
*/
private void warnOthers(final NCPPlayer player) {
Bukkit.getServer().broadcastMessage(
ChatColor.YELLOW + player.getName() + ChatColor.DARK_RED + " has set off the autoban!");
Bukkit.getServer().broadcastMessage(
ChatColor.DARK_RED + " Please do not say anything similar to what the user said!");
replaceColors(getConfig(player).noPwnageMessagesWarnOthers).replace("[player]", player.getName()));
}
/**
@ -359,8 +353,7 @@ public class NoPwnageCheck extends ChatCheck {
* The Player
*/
private void warnPlayer(final NCPPlayer player) {
player.sendMessage(replaceColors(ConfigManager.getConfigFile().getString(ConfPaths.LOGGING_PREFIX))
+ ChatColor.DARK_RED
+ "Our system has detected unusual bot activities coming from you. Please be careful with what you say. DON'T repeat what you just said either, unless you want to be banned.");
player.sendMessage(replaceColors(ConfigManager.getConfigFile().getString(ConfPaths.LOGGING_PREFIX)
+ getConfig(player).noPwnageMessagesWarnPlayer));
}
}

View File

@ -0,0 +1,206 @@
package fr.neatmonster.nocheatplus.checks.fight;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.players.NCPPlayer;
import fr.neatmonster.nocheatplus.players.informations.Permissions;
import fr.neatmonster.nocheatplus.players.informations.Statistics.Id;
/**
* A check used to verify if the player isn't using a forcefield in order to attack multiple entities at the same time
*
* Thanks asofold for the original idea!
*/
public class AngleCheck extends FightCheck {
public class AngleCheckEvent extends FightEvent {
public AngleCheckEvent(final AngleCheck check, final NCPPlayer player, final ActionList actions, final double vL) {
super(check, player, actions, vL);
}
}
public class AngleData implements Comparable<AngleData> {
public final long time;
public final double x;
public final double y;
public final double z;
public final float yaw;
public AngleData(final Location location) {
time = System.currentTimeMillis();
x = location.getX();
y = location.getY();
z = location.getZ();
yaw = location.getYaw();
}
@Override
public int compareTo(final AngleData otherData) {
if (otherData.time < time)
return 1;
else if (otherData.time == time)
return 0;
else
return -1;
}
public boolean shouldBeRemoved() {
return System.currentTimeMillis() - time > 1000L;
}
}
public AngleCheck() {
super("angle", Permissions.FIGHT_ANGLE);
}
@Override
public boolean check(final NCPPlayer player, final Object... args) {
final FightConfig cc = getConfig(player);
final FightData data = getData(player);
boolean cancel = false;
// Add the current attack to the list
data.attacks.add(new AngleData(player.getLocation()));
// Sort the list of the attacks for the oldest to the newest
Collections.sort(data.attacks, Collections.reverseOrder());
// Declare 3 list which will contain the times, yaws and pitches
final List<Long> dTime = new ArrayList<Long>();
final List<Float> dYaw = new ArrayList<Float>();
final List<Double> dMove = new ArrayList<Double>();
AngleData previousAngleData = null;
for (final AngleData angleData : new ArrayList<AngleData>(data.attacks))
// If the data is older than a second...
if (angleData.shouldBeRemoved())
// ...remove it from the list
data.attacks.remove(angleData);
else {
// If we have a previous data (to calculate deltas)...
if (previousAngleData != null) {
// ...calculate the time delta...
dTime.add(Math.abs(previousAngleData.time - angleData.time));
// ...the yaw delta...
dYaw.add(Math.abs(previousAngleData.yaw - angleData.yaw) % 360F);
// ...the move delta
dMove.add(Math.sqrt(Math.pow(previousAngleData.x - angleData.x, 2)
+ Math.pow(previousAngleData.y - angleData.y, 2)
+ Math.pow(previousAngleData.z - angleData.z, 2)));
}
// Remember this data to calculate the next deltas
previousAngleData = angleData;
}
/**
* TIME
**/
// First we calculate the average time between each attack
double mTime = 0D;
for (final long time : dTime)
mTime += time;
if (dTime.size() != 0D)
mTime /= dTime.size();
// Then if the time is superior to 150 ms, we set the violation to 0...
if (mTime == 0D || mTime > 150D)
mTime = 0D;
// ...but otherwise we calculate a percentage of violation
else
mTime = 100D * (150D - mTime) / 150D;
/**
* YAW
**/
// First we calculate the average yaw change between each attack
double mYaw = 0D;
for (final double yaw : dYaw)
mYaw += yaw;
if (dYaw.size() != 0D)
mYaw /= dYaw.size();
// Then if the yaw is inferior to 50°, we set the violation to 0...
if (mYaw == 0D || mYaw < 50D)
mYaw = 0D;
// ...but otherwise we calculate a percentage of violation
else
mYaw = 100D * (360D - mYaw) / 360D;
/**
* MOVE
**/
// First we calculate the average move between each attack
double mMove = 0D;
for (final double move : dMove)
mMove += move;
if (dMove.size() != 0)
mMove /= dMove.size();
// Then, if the move is bigger than 0.2 block(s), we set the violation to 0...
if (mMove == 0D || mMove > 0.2D)
mMove = 0D;
// ...but otherwise we calculate a percentage of violation
else
mMove = 100D * (0.2D - mMove) / 0.2D;
// Now we are ready to make the average of the three "checks" violation level
// Each "check" has his coefficient: 5 for the time, 3 for the yaw, 2 for the move
final double mTotal = (5D * mTime + 3D * mYaw + 2D * mMove) / 10D;
// If the total is superior the value defined in the configuration file...
if (mTotal > cc.angleThreshold) {
// If there was lag, don't count it towards statistics and vl...
if (!NoCheatPlus.skipCheck()) {
// ...otherwise increment the violation level...
data.angleVL += mTotal;
// ...and the statistics
incrementStatistics(player, Id.FI_ANGLE, mTotal);
}
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, cc.angleActions, data.angleVL);
} else
// Otherwise reward the player by lowering his violation level
data.angleVL *= 0.98;
return cancel;
}
@Override
protected boolean executeActions(final NCPPlayer player, final ActionList actionList, final double violationLevel) {
final AngleCheckEvent event = new AngleCheckEvent(this, player, actionList, violationLevel);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled())
return super.executeActions(player, event.getActions(), event.getVL());
return false;
}
@Override
public String getParameter(final ParameterName wildcard, final NCPPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(getData(player).angleVL));
else
return super.getParameter(wildcard, player);
}
@Override
public boolean isEnabled(final FightConfig cc) {
return cc.angleCheck;
}
}

View File

@ -46,6 +46,10 @@ public class FightConfig extends CheckConfig {
public final double criticalVelocity;
public final ActionList criticalActions;
public final boolean angleCheck;
public final double angleThreshold;
public final ActionList angleActions;
public FightConfig(final ConfigFile data) {
directionCheck = data.getBoolean(ConfPaths.FIGHT_DIRECTION_CHECK);
@ -79,5 +83,9 @@ public class FightConfig extends CheckConfig {
criticalFallDistance = data.getDouble(ConfPaths.FIGHT_CRITICAL_FALLDISTANCE);
criticalVelocity = data.getDouble(ConfPaths.FIGHT_CRITICAL_VELOCITY);
criticalActions = data.getActionList(ConfPaths.FIGHT_CRITICAL_ACTIONS, Permissions.FIGHT_CRITICAL);
angleCheck = data.getBoolean(ConfPaths.FIGHT_ANGLE_CHECK);
angleThreshold = data.getDouble(ConfPaths.FIGHT_ANGLE_THRESHOLD);
angleActions = data.getActionList(ConfPaths.FIGHT_ANGLE_ACTIONS, Permissions.FIGHT_ANGLE);
}
}

View File

@ -1,10 +1,14 @@
package fr.neatmonster.nocheatplus.checks.fight;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.Entity;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckData;
import fr.neatmonster.nocheatplus.checks.fight.AngleCheck.AngleData;
/**
* Player specific data for the fight checks
@ -13,47 +17,50 @@ import fr.neatmonster.nocheatplus.checks.CheckData;
public class FightData extends CheckData {
// Keep track of the violation levels of the checks
public double directionVL;
public double noswingVL;
public double reachVL;
public int speedVL;
public double godmodeVL;
public double instanthealVL;
public double knockbackVL;
public double criticalVL;
public double directionVL;
public double noswingVL;
public double reachVL;
public int speedVL;
public double godmodeVL;
public double instanthealVL;
public double knockbackVL;
public double criticalVL;
public double angleVL;
// For checks that have penalty time
public long directionLastViolationTime;
public long reachLastViolationTime;
public long directionLastViolationTime;
public long reachLastViolationTime;
// godmode check needs to know these
public long godmodeLastDamageTime;
public int godmodeLastAge;
public int godmodeBuffer = 40;
// Godmode check needs to know these
public long godmodeLastDamageTime;
public int godmodeLastAge;
public int godmodeBuffer = 40;
// last time player regenerated health by satiation
public long instanthealLastRegenTime;
// Last time player regenerated health by satiation
public long instanthealLastRegenTime;
// three seconds buffer to smooth out lag
public long instanthealBuffer = 3000;
// Three seconds buffer to smooth out lag
public long instanthealBuffer = 3000;
// While handling an event, use this to keep the attacked entity
public Entity damagee;
public Entity damagee;
// Remember the player who attacked the entity
public Player damager;
public Player damager;
// The player swung his arm
public boolean armswung = true;
public boolean armswung = true;
// For some reason the next event should be ignored
public boolean skipNext = false;
public boolean skipNext = false;
// Keep track of time and amount of attacks
public long speedTime;
public int speedAttackCount;
public long speedTime;
public int speedAttackCount;
// Remember when the player has toggled his sprint mode
public long sprint = 0L;
public long sprint = 0L;
// Store the player's attacks
public final List<AngleData> attacks = new ArrayList<AngleData>();
}

View File

@ -46,6 +46,7 @@ public class FightListener extends CheckListener {
checks.add(new ReachCheck());
checks.add(new KnockbackCheck());
checks.add(new CriticalCheck());
checks.add(new AngleCheck());
godmodeCheck = new GodmodeCheck();
instanthealCheck = new InstanthealCheck();

View File

@ -0,0 +1,67 @@
package fr.neatmonster.nocheatplus.checks.moving;
import org.bukkit.Bukkit;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.players.NCPPlayer;
import fr.neatmonster.nocheatplus.players.informations.Statistics.Id;
/**
* A check preventing players from flying by sending bed leaving packets
*/
public class BedFlyingCheck extends MovingCheck {
public class BedFlyingCheckEvent extends MovingEvent {
public BedFlyingCheckEvent(final BedFlyingCheck check, final NCPPlayer player, final ActionList actions,
final double vL) {
super(check, player, actions, vL);
}
}
public BedFlyingCheck() {
super("bedflying");
}
public boolean check(final NCPPlayer player, final Object... args) {
final MovingData data = getData(player);
// If the player wasn't sleeping but is only sending packets, he is cheating!
if (!data.wasSleeping) {
final MovingConfig cc = getConfig(player);
// Increment violation counter
data.bedFlyVL++;
// Increment player's statistics
incrementStatistics(player, Id.MOV_BEDFLYING, 1);
// Execute the actions
return executeActions(player, cc.bedFlyActions, data.bedFlyVL);
}
// Otherwise reward the player for his legit bed leave
else
data.bedFlyVL = Math.max(0D, data.bedFlyVL - 1);
return false;
}
@Override
protected boolean executeActions(final NCPPlayer player, final ActionList actionList, final double violationLevel) {
final BedFlyingCheckEvent event = new BedFlyingCheckEvent(this, player, actionList, violationLevel);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled())
return super.executeActions(player, event.getActions(), event.getVL());
return false;
}
@Override
public String getParameter(final ParameterName wildcard, final NCPPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(getData(player).bedFlyVL));
else
return super.getParameter(wildcard, player);
}
}

View File

@ -34,6 +34,9 @@ public class MovingConfig extends CheckConfig {
public final double flyingSpeedLimitHorizontal;
public final ActionList flyingActions;
public final boolean bedFlyCheck;
public final ActionList bedFlyActions;
public final boolean nofallCheck;
public final boolean nofallAggressive;
public final float nofallMultiplier;
@ -83,6 +86,9 @@ public class MovingConfig extends CheckConfig {
flyingHeightLimit = data.getInt(ConfPaths.MOVING_RUNFLY_FLYING_HEIGHTLIMIT);
flyingActions = data.getActionList(ConfPaths.MOVING_RUNFLY_FLYING_ACTIONS, Permissions.MOVING_FLYING);
bedFlyCheck = data.getBoolean(ConfPaths.MOVING_RUNFLY_BEDFLYING_CHECK);
bedFlyActions = data.getActionList(ConfPaths.MOVING_RUNFLY_BEDFLYING_ACTIONS, Permissions.MOVING_BEDFLYING);
nofallCheck = data.getBoolean(ConfPaths.MOVING_RUNFLY_NOFALL_CHECK);
nofallMultiplier = 200 / 100F;
nofallAggressive = data.getBoolean(ConfPaths.MOVING_RUNFLY_NOFALL_AGGRESSIVE);

View File

@ -17,6 +17,7 @@ public class MovingData extends CheckData {
public double morePacketsVL;
public double morePacketsVehicleVL;
public double waterWalkVL;
public double bedFlyVL;
// Count how long a player is in the air
public int jumpPhase;
@ -29,7 +30,7 @@ public class MovingData extends CheckData {
public int onIce;
// Where should a player be teleported back to when failing the check
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
// Some values for estimating movement freedom
public double vertFreedom;
@ -44,46 +45,43 @@ public class MovingData extends CheckData {
public float fallDistance;
public float lastAddedFallDistance;
// Remember if the player has already been on the ground
public boolean hasAlreadyBeenOnTheGround = false;
// Keep in mind the player's last safe position
public Location[] lastSafeLocations = new Location[] {null, null};
public Location[] lastSafeLocations = new Location[] {null, null};
// Keep track of when "morePackets" last time checked and how much packets
// a player sent and may send before failing the check
public long morePacketsLastTime;
public int packets;
public int morePacketsBuffer = 50;
public int morePacketsBuffer = 50;
// Where to teleport the player that fails the "morepackets" check
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
// Keep track of when "morePacketsVehicle" last time checked an how much
// packets a vehicle sent and may send before failing the check
public long morePacketsVehicleLastTime;
public int packetsVehicle;
public int morePacketsVehicleBuffer = 50;
public int morePacketsVehicleBuffer = 50;
// When NoCheatPlus does teleport the player, remember the target location to
// be able to distinguish "our" teleports from teleports of others
public final PreciseLocation teleportTo = new PreciseLocation();
public final PreciseLocation teleportTo = new PreciseLocation();
// For logging and convenience, make copies of the events locations
public final PreciseLocation from = new PreciseLocation();
public final PreciseLocation fromVehicle = new PreciseLocation();
public final PreciseLocation to = new PreciseLocation();
public final PreciseLocation toVehicle = new PreciseLocation();
public final PreciseLocation from = new PreciseLocation();
public final PreciseLocation fromVehicle = new PreciseLocation();
public final PreciseLocation to = new PreciseLocation();
public final PreciseLocation toVehicle = new PreciseLocation();
// For convenience, remember if the locations are considered "on ground"
// by NoCheatPlus
public boolean fromOnOrInGround;
public boolean toOnOrInGround;
// Store if the player had blocks above his head when he moved previously
public boolean[] hadBlocksAbove = new boolean[5];
// Remember if the player was previously sleeping
public boolean wasSleeping = false;
public Id statisticCategory = Id.MOV_RUNNING;
public Id statisticCategory = Id.MOV_RUNNING;
public void clearMorePacketsData() {
morePacketsSetbackPoint.reset();
@ -96,10 +94,4 @@ public class MovingData extends CheckData {
lastAddedFallDistance = 0;
bunnyhopdelay = 0;
}
public void rotateWaterWalkData(final boolean aboveSolid) {
for (int i = 0; i < hadBlocksAbove.length - 1; i++)
hadBlocksAbove[i] = hadBlocksAbove[i + 1];
hadBlocksAbove[hadBlocksAbove.length - 1] = aboveSolid;
}
}

View File

@ -10,6 +10,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBedLeaveEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
@ -39,6 +41,7 @@ public class MovingListener extends CheckListener {
private final MorePacketsCheck morePacketsCheck;
private final MorePacketsVehicleCheck morePacketsVehicleCheck;
private final FlyingCheck flyingCheck;
private final BedFlyingCheck bedFlyingCheck;
private final RunningCheck runningCheck;
private final WaterWalkCheck waterWalkCheck;
@ -46,12 +49,56 @@ public class MovingListener extends CheckListener {
super("moving");
flyingCheck = new FlyingCheck();
bedFlyingCheck = new BedFlyingCheck();
runningCheck = new RunningCheck();
morePacketsCheck = new MorePacketsCheck();
morePacketsVehicleCheck = new MorePacketsVehicleCheck();
waterWalkCheck = new WaterWalkCheck();
}
/**
* We listen to this event to prevent player from flying by sending
* bed leaving packets.
*
* @param event
*
*/
@EventHandler(
priority = EventPriority.MONITOR)
public void bedEntering(final PlayerBedEnterEvent event) {
final NCPPlayer player = NCPPlayer.getPlayer(event.getPlayer());
final MovingConfig cc = (MovingConfig) getConfig(player);
if (cc.bedFlyCheck && !player.hasPermission(Permissions.MOVING_BEDFLYING)) {
final MovingData data = (MovingData) getData(player);
data.wasSleeping = true;
}
}
/**
* We listen to this event to prevent player from flying by sending
* bed leaving packets.
*
* @param event
*
*/
@EventHandler(
priority = EventPriority.MONITOR)
public void bedLeaving(final PlayerBedLeaveEvent event) {
final NCPPlayer player = NCPPlayer.getPlayer(event.getPlayer());
final MovingConfig cc = (MovingConfig) getConfig(player);
if (cc.bedFlyCheck && !player.hasPermission(Permissions.MOVING_BEDFLYING)) {
final MovingData data = (MovingData) getData(player);
if (bedFlyingCheck.check(player))
// To cancel the event, simply teleport him to his last safe location
event.getPlayer().teleport(data.lastSafeLocations[1]);
data.wasSleeping = false;
}
}
/**
* A workaround for players placing blocks below them getting pushed
* off the block by NoCheatPlus.

View File

@ -1,9 +1,14 @@
package fr.neatmonster.nocheatplus.checks.moving;
import net.minecraft.server.AxisAlignedBB;
import net.minecraft.server.EntityPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
@ -249,13 +254,25 @@ public class RunningCheck extends MovingCheck {
limit -= (data.jumpPhase - jumpingLimit) * 0.15D;
// Handle the calculation differently if the player is in water
if (isSwimming && data.to.y - data.from.y > 0D)
distanceAboveLimit = data.to.y - data.from.y - cc.verticalSwimmingSpeedLimit;
if (isSwimming && data.to.y - data.from.y > 0D) {
// We need to make sure the player isn't a special block
// We get the bounding box of the player
final EntityPlayer entity = ((CraftPlayer) player.getBukkitPlayer()).getHandle();
final AxisAlignedBB aabb = entity.boundingBox.clone();
// Grow it of the minimum value (to collide with blocks)
aabb.grow(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
final double xValue = (aabb.d - aabb.a) / 2D;
final double zValue = (aabb.f - aabb.c) / 2D;
if (!isSpecial(player.getWorld(), data.to.x - xValue, data.to.y, data.to.z - zValue)
&& !isSpecial(player.getWorld(), data.to.x + xValue, data.to.y, data.to.z - zValue)
&& !isSpecial(player.getWorld(), data.to.x - xValue, data.to.y, data.to.z + zValue)
&& !isSpecial(player.getWorld(), data.to.x + xValue, data.to.y, data.to.z + zValue))
distanceAboveLimit = data.to.y - data.from.y - cc.verticalSwimmingSpeedLimit;
}
// Handle the calculation differently if the player is in cobweb
final World world = player.getWorld();
if (distanceAboveLimit <= 0D && CheckUtils.isWeb(CheckUtils.evaluateLocation(world, data.from))
&& CheckUtils.isWeb(CheckUtils.evaluateLocation(world, data.to)))
if (distanceAboveLimit <= 0D
&& new Location(player.getWorld(), data.to.x, data.to.y, data.to.z).getBlock().getType() == Material.WEB)
distanceAboveLimit = Math.abs(data.to.y - data.from.y) - cc.cobWebVertSpeedLimit;
if (distanceAboveLimit <= 0D)
@ -267,6 +284,8 @@ public class RunningCheck extends MovingCheck {
if (toOnGround || fromOnGround)
data.lastJumpAmplifier = 0;
// Bukkit.broadcastMessage("d = " + distanceAboveLimit);
return distanceAboveLimit;
}
@ -290,4 +309,26 @@ public class RunningCheck extends MovingCheck {
else
return super.getParameter(wildcard, player);
}
/**
* Checks if a block special (checks if the block is stairs/fence or not)
*
* @param world
* @param x
* @param y
* @param z
* @param above
* @return is the block special?
*/
private boolean isSpecial(final World world, final double x, final double y, final double z) {
Material material = new Location(world, x, y, z).getBlock().getType();
if (material == Material.BRICK_STAIRS || material == Material.COBBLESTONE_STAIRS
|| material == Material.NETHER_BRICK_STAIRS || material == Material.SMOOTH_STAIRS
|| material == Material.STEP || material == Material.WOOD_STAIRS)
return true;
material = new Location(world, x, y - 1, z).getBlock().getType();
if (material == Material.FENCE || material == Material.IRON_FENCE || material == Material.NETHER_FENCE)
return true;
return false;
}
}

View File

@ -1,15 +1,19 @@
package fr.neatmonster.nocheatplus.checks.moving;
import net.minecraft.server.AxisAlignedBB;
import net.minecraft.server.EntityPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.World;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckUtils;
import fr.neatmonster.nocheatplus.players.NCPPlayer;
import fr.neatmonster.nocheatplus.players.informations.Statistics.Id;
import fr.neatmonster.nocheatplus.utilities.locations.PreciseLocation;
/**
@ -31,107 +35,87 @@ public class WaterWalkCheck extends MovingCheck {
}
public PreciseLocation check(final NCPPlayer player, final Object... args) {
// Get the configuration and data of the player
final MovingConfig cc = getConfig(player);
final MovingData data = getData(player);
// Some shortcuts:
final PreciseLocation to = data.to;
// Check if the player comes from a liquid
final PreciseLocation from = data.from;
final PreciseLocation up = new PreciseLocation();
up.x = to.x;
up.y = to.y + 1;
up.z = to.z;
final PreciseLocation toAbove = new PreciseLocation();
toAbove.x = to.x;
toAbove.y = to.y + 2;
toAbove.z = to.z;
final PreciseLocation fromAbove = new PreciseLocation();
fromAbove.x = from.x;
fromAbove.y = from.y + 2;
fromAbove.z = from.z;
// To know if a player "is in water" is useful
final int fromType = CheckUtils.evaluateLocation(player.getWorld(), from);
final int toType = CheckUtils.evaluateLocation(player.getWorld(), to);
final int upType = CheckUtils.evaluateLocation(player.getWorld(), up);
final boolean fromLiquid = CheckUtils.isLiquid(fromType);
// If he is not, return
if (!fromLiquid)
return null;
// Check if the player is going into a liquid
final PreciseLocation to = data.to;
final int toType = CheckUtils.evaluateLocation(player.getWorld(), to);
final boolean toLiquid = CheckUtils.isLiquid(toType);
final boolean upLiquid = CheckUtils.isLiquid(upType);
final boolean toAboveSolid = CheckUtils.isSolid(CheckUtils.getType(new Location(player.getWorld(), toAbove.x,
toAbove.y, toAbove.z).getBlock().getTypeId()));
final boolean fromAboveSolid = CheckUtils.isSolid(CheckUtils.getType(new Location(player.getWorld(),
fromAbove.x, fromAbove.y, fromAbove.z).getBlock().getTypeId()));
boolean aboveSolid = toAboveSolid || fromAboveSolid;
final boolean save = aboveSolid;
for (final boolean hadBlocksAbove : data.hadBlocksAbove)
if (hadBlocksAbove)
aboveSolid = true;
data.rotateWaterWalkData(save);
final Block fromBlock = new Location(player.getWorld(), from.x, from.y, from.z).getBlock();
// Handle the issue with water streams
boolean waterStreamsFix = false;
if (fromBlock.getType() == Material.STATIONARY_WATER || fromBlock.getType() == Material.STATIONARY_LAVA
|| (fromBlock.getType() == Material.WATER || fromBlock.getType() == Material.LAVA)
&& fromBlock.getData() == 0x0)
waterStreamsFix = true;
// Handle the issue with slabs/stairs/soul sand
boolean othersFix = false;
for (final BlockFace blockFace : BlockFace.values()) {
final Material material = fromBlock.getRelative(blockFace).getType();
if (material == Material.STEP || material == Material.WOOD_STAIRS
|| material == Material.COBBLESTONE_STAIRS || material == Material.BRICK_STAIRS
|| material == Material.SMOOTH_STAIRS || material == Material.NETHER_BRICK_STAIRS
|| material == Material.SOUL_SAND)
othersFix = true;
boolean upLiquid = false;
// If he is, check if the block containing his head is liquid too
if (toLiquid) {
final PreciseLocation upFrom = new PreciseLocation();
upFrom.set(from);
upFrom.y++;
final int upFromType = CheckUtils.evaluateLocation(player.getWorld(), upFrom);
final PreciseLocation upTo = new PreciseLocation();
upTo.set(to);
upTo.y++;
final int upToType = CheckUtils.evaluateLocation(player.getWorld(), upTo);
upLiquid = CheckUtils.isLiquid(upFromType) || CheckUtils.isLiquid(upToType);
}
// Calculate some distances
final double deltaX = Math.abs(Math.round(to.x) - to.x);
final double deltaY = Math.abs(from.y - to.y);
final double deltaZ = Math.abs(Math.round(to.z) - to.z);
final double deltaWithSurface = Math.abs(to.y - Math.ceil(to.y)) + (to.y - Math.ceil(to.y) == 0 ? 1 : 0);
final double resultXZ = (Math.abs(deltaX - 0.30D) + Math.abs(deltaZ - 0.30D)) * 100;
final double resultY = deltaWithSurface * 100;
// Here is the interesting part, we get the bounding box of the player
final EntityPlayer entity = ((CraftPlayer) player.getBukkitPlayer()).getHandle();
final AxisAlignedBB aabb = entity.boundingBox.clone();
// Grow it of the minimum value (to collide with blocks)
aabb.grow(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
// Now check if the player is forced to walk horizontally
// If he has a block above his head or if he his walking on stairs
final boolean isForced = isSpecial(player.getWorld(), aabb.a, aabb.e, aabb.c, true)
|| isSpecial(player.getWorld(), aabb.d, aabb.e, aabb.c, true)
|| isSpecial(player.getWorld(), aabb.a, aabb.e, aabb.f, true)
|| isSpecial(player.getWorld(), aabb.d, aabb.e, aabb.f, true)
|| isSpecial(player.getWorld(), aabb.a, aabb.b, aabb.c, false)
|| isSpecial(player.getWorld(), aabb.d, aabb.b, aabb.c, false)
|| isSpecial(player.getWorld(), aabb.a, aabb.b, aabb.f, false)
|| isSpecial(player.getWorld(), aabb.d, aabb.b, aabb.f, false);
PreciseLocation newToLocation = null;
// Calculate the delta with the surface
final double dSurface = Math.abs(to.y - Math.ceil(to.y)) + (to.y - Math.ceil(to.y) == 0 ? 1 : 0);
// Calculate the velocity of the player
final double velocity = player.getBukkitPlayer().getVelocity().lengthSquared();
// Slowly reduce the level with each event
// If the player his walking straight (and not force to do so)
if (fromLiquid && toLiquid && !upLiquid && !isForced && to.y == from.y && dSurface < 0.8D) {
// Increment the violation counter
data.waterWalkVL += 100D * dSurface;
// Increment the statistics
incrementStatistics(player, Id.MOV_WATERWALK, 100D * dSurface);
// Execute the actions
if (executeActions(player, cc.actions, data.waterWalkVL))
// Cancel the move if required
return from;
}
// If the player is trying to jump above the water
else if (fromLiquid && !toLiquid && !isForced && velocity > 0.09D) {
// Increment the violation counter
data.waterWalkVL += 100D * (velocity - 0.09D);
// Increment the statistics
incrementStatistics(player, Id.MOV_WATERWALK, 100D * (velocity - 0.09D));
// Execute the actions
if (executeActions(player, cc.actions, data.waterWalkVL))
// Cancel the move if required
return from;
}
// Slowly reduce the level with each event to reward the player
data.waterWalkVL *= 0.95;
if (!othersFix && fromLiquid && toLiquid && !upLiquid && !aboveSolid && deltaY == 0D && deltaWithSurface < 0.8D) {
// If the player is trying to move while being in water
// Increment violation counter
data.waterWalkVL += resultY;
incrementStatistics(player, data.statisticCategory, resultY);
final boolean cancel = executeActions(player, cc.actions, data.waterWalkVL);
// Was one of the actions a cancel? Then do it
if (cancel)
newToLocation = from;
} else if (waterStreamsFix && fromLiquid && !toLiquid && !aboveSolid && (deltaX < 0.28D || deltaX > 0.31D)
&& (deltaZ < 0.28D || deltaZ > 0.31D)) {
// If the player is trying to jump while being in water
// Increment violation counter
data.waterWalkVL += resultXZ;
incrementStatistics(player, data.statisticCategory, resultXZ);
final boolean cancel = executeActions(player, cc.actions, data.waterWalkVL);
// Was one of the actions a cancel? Then do it
if (cancel)
newToLocation = from;
}
return newToLocation;
return null;
}
@Override
@ -145,10 +129,36 @@ public class WaterWalkCheck extends MovingCheck {
@Override
public String getParameter(final ParameterName wildcard, final NCPPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(getData(player).waterWalkVL));
else
return super.getParameter(wildcard, player);
}
/**
* Checks if a block special (if above is true, it checks if the block's type isn't air, otherwise it checks if the
* block is stairs/fence or not)
*
* @param world
* @param x
* @param y
* @param z
* @param above
* @return is the block special?
*/
private boolean isSpecial(final World world, final double x, final double y, final double z, final boolean above) {
Material material = new Location(world, x, y, z).getBlock().getType();
if (above)
return material != Material.AIR;
else {
if (material == Material.BRICK_STAIRS || material == Material.COBBLESTONE_STAIRS
|| material == Material.NETHER_BRICK_STAIRS || material == Material.SMOOTH_STAIRS
|| material == Material.STEP || material == Material.WOOD_STAIRS)
return true;
material = new Location(world, x, y - 1, z).getBlock().getType();
if (material == Material.FENCE || material == Material.IRON_FENCE || material == Material.NETHER_FENCE)
return true;
return false;
}
}
}

View File

@ -24,68 +24,6 @@ public abstract class ConfPaths {
private static final String CHECKS = "checks.";
private static final String INVENTORY = CHECKS + "inventory.";
private static final String INVENTORY_DROP = INVENTORY + "drop.";
public static final String INVENTORY_DROP_CHECK = INVENTORY_DROP + "active";
public static final String INVENTORY_DROP_TIMEFRAME = INVENTORY_DROP + "time";
public static final String INVENTORY_DROP_LIMIT = INVENTORY_DROP + "limit";
public static final String INVENTORY_DROP_ACTIONS = INVENTORY_DROP + "actions";
private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
public static final String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";
public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions";
private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";
public static final String INVENTORY_INSTANTEAT_CHECK = INVENTORY_INSTANTEAT + "active";
public static final String INVENTORY_INSTANTEAT_ACTIONS = INVENTORY_INSTANTEAT + "actions";
private static final String MOVING = CHECKS + "moving.";
private static final String MOVING_RUNFLY = MOVING + "runfly.";
public static final String MOVING_RUNFLY_CHECK = MOVING_RUNFLY + "active";
// These seventh aren't automatically shown in the config
public static final String MOVING_RUNFLY_WALKSPEED = MOVING_RUNFLY + "walkspeed";
public static final String MOVING_RUNFLY_SNEAKSPEED = MOVING_RUNFLY + "sneakspeed";
public static final String MOVING_RUNFLY_BLOCKSPEED = MOVING_RUNFLY + "blockspeed";
public static final String MOVING_RUNFLY_SWIMSPEED = MOVING_RUNFLY + "swimspeed";
public static final String MOVING_RUNFLY_VERTICALSWIMSPEED = MOVING_RUNFLY + "vertswimspeed";
public static final String MOVING_RUNFLY_SPRINTSPEED = MOVING_RUNFLY + "sprintspeed";
public static final String MOVING_RUNFLY_COBWEBSPEED = MOVING_RUNFLY + "cobwebspeed";
public static final String MOVING_RUNFLY_ALLOWFASTSNEAKING = MOVING_RUNFLY + "allowfastsneaking";
public static final String MOVING_RUNFLY_ALLOWFASTBLOCKING = MOVING_RUNFLY + "allowfastblocking";
public static final String MOVING_RUNFLY_ACTIONS = MOVING_RUNFLY + "actions";
private static final String MOVING_RUNFLY_NOFALL = MOVING_RUNFLY + "nofall.";
public static final String MOVING_RUNFLY_NOFALL_CHECK = MOVING_RUNFLY_NOFALL + "active";
public static final String MOVING_RUNFLY_NOFALL_AGGRESSIVE = MOVING_RUNFLY_NOFALL + "aggressivemode";
public static final String MOVING_RUNFLY_NOFALL_ACTIONS = MOVING_RUNFLY_NOFALL + "actions";
private static final String MOVING_RUNFLY_FLYING = MOVING_RUNFLY + "flying.";
public static final String MOVING_RUNFLY_FLYING_ALLOWALWAYS = MOVING_RUNFLY_FLYING + "allowflyingalways";
public static final String MOVING_RUNFLY_FLYING_ALLOWINCREATIVE = MOVING_RUNFLY_FLYING
+ "allowflyingincreative";
public static final String MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL = MOVING_RUNFLY_FLYING
+ "flyingspeedlimitvertical";
public static final String MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL = MOVING_RUNFLY_FLYING
+ "flyingspeedlimithorizontal";
public static final String MOVING_RUNFLY_FLYING_HEIGHTLIMIT = MOVING_RUNFLY_FLYING + "flyingheightlimit";
public static final String MOVING_RUNFLY_FLYING_ACTIONS = MOVING_RUNFLY_FLYING + "actions";
private static final String MOVING_MOREPACKETS = MOVING + "morepackets.";
public static final String MOVING_MOREPACKETS_CHECK = MOVING_MOREPACKETS + "active";
public static final String MOVING_MOREPACKETS_ACTIONS = MOVING_MOREPACKETS + "actions";
private static final String MOVING_MOREPACKETSVEHICLE = MOVING + "morepacketsvehicle.";
public static final String MOVING_MOREPACKETSVEHICLE_CHECK = MOVING_MOREPACKETSVEHICLE + "active";
public static final String MOVING_MOREPACKETSVEHICLE_ACTIONS = MOVING_MOREPACKETSVEHICLE + "actions";
private static final String MOVING_WATERWALK = MOVING + "waterwalk.";
public static final String MOVING_WATERWALK_CHECK = MOVING_WATERWALK + "active";
public static final String MOVING_WATERWALK_ACTIONS = MOVING_WATERWALK + "actions";
private static final String BLOCKBREAK = CHECKS + "blockbreak.";
private static final String BLOCKBREAK_FASTBREAK = BLOCKBREAK + "fastbreak.";
@ -143,7 +81,6 @@ public abstract class ConfPaths {
public static final String CHAT_NOPWNAGE_WARNLEVEL = CHAT_NOPWNAGE + "warnlevel";
public static final String CHAT_NOPWNAGE_WARNTIMEOUT = CHAT_NOPWNAGE + "warntimeout";
public static final String CHAT_NOPWNAGE_BANLEVEL = CHAT_NOPWNAGE + "banlevel";
public static final String CHAT_NOPWNAGE_KICKMESSAGE = CHAT_NOPWNAGE + "kickmessage";
public static final String CHAT_NOPWNAGE_ACTIONS = CHAT_NOPWNAGE + "otheractions";
private static final String CHAT_NOPWNAGE_MOVE = CHAT_NOPWNAGE + "move.";
@ -189,6 +126,14 @@ public abstract class ConfPaths {
public static final String CHAT_NOPWNAGE_CAPTCHA_LENGTH = CHAT_NOPWNAGE_CAPTCHA + "length";
public static final String CHAT_NOPWNAGE_CAPTCHA_CHARACTERS = CHAT_NOPWNAGE_CAPTCHA + "characters";
private static final String CHAT_NOPWNAGE_MESSAGES = CHAT_NOPWNAGE + "messages.";
public static final String CHAT_NOPWNAGE_MESSAGES_KICK = CHAT_NOPWNAGE_MESSAGES + "kick";
public static final String CHAT_NOPWNAGE_MESSAGES_CAPTCHAQUESTION = CHAT_NOPWNAGE_MESSAGES + "captchaquestion";
public static final String CHAT_NOPWNAGE_MESSAGES_CAPTCHASUCCESS = CHAT_NOPWNAGE_MESSAGES + "captchasuccess";
public static final String CHAT_NOPWNAGE_MESSAGES_WARNPLAYER = CHAT_NOPWNAGE_MESSAGES + "warnplayer";
public static final String CHAT_NOPWNAGE_MESSAGES_WARNOTHERS = CHAT_NOPWNAGE_MESSAGES + "warnothers";
public static final String CHAT_NOPWNAGE_MESSAGES_WARNRELOG = CHAT_NOPWNAGE_MESSAGES + "warnrelog";
private static final String CHAT_ARRIVALSLIMIT = CHAT + "arrivalslimit.";
public static final String CHAT_ARRIVALSLIMIT_CHECK = CHAT_ARRIVALSLIMIT + "active";
public static final String CHAT_ARRIVALSLIMIT_PLAYERSLIMIT = CHAT_ARRIVALSLIMIT + "playerslimit";
@ -244,6 +189,76 @@ public abstract class ConfPaths {
public static final String FIGHT_CRITICAL_VELOCITY = FIGHT_CRITICAL + "velocity";
public static final String FIGHT_CRITICAL_ACTIONS = FIGHT_CRITICAL + "actions";
public static final String STRINGS = "strings";
private static final String FIGHT_ANGLE = FIGHT + "angle.";
public static final String FIGHT_ANGLE_CHECK = FIGHT_ANGLE + "active";
public static final String FIGHT_ANGLE_THRESHOLD = FIGHT_ANGLE + "threshold";
public static final String FIGHT_ANGLE_ACTIONS = FIGHT_ANGLE + "actions";
private static final String INVENTORY = CHECKS + "inventory.";
private static final String INVENTORY_DROP = INVENTORY + "drop.";
public static final String INVENTORY_DROP_CHECK = INVENTORY_DROP + "active";
public static final String INVENTORY_DROP_TIMEFRAME = INVENTORY_DROP + "time";
public static final String INVENTORY_DROP_LIMIT = INVENTORY_DROP + "limit";
public static final String INVENTORY_DROP_ACTIONS = INVENTORY_DROP + "actions";
private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
public static final String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";
public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions";
private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";
public static final String INVENTORY_INSTANTEAT_CHECK = INVENTORY_INSTANTEAT + "active";
public static final String INVENTORY_INSTANTEAT_ACTIONS = INVENTORY_INSTANTEAT + "actions";
private static final String MOVING = CHECKS + "moving.";
private static final String MOVING_RUNFLY = MOVING + "runfly.";
public static final String MOVING_RUNFLY_CHECK = MOVING_RUNFLY + "active";
// These seventh aren't automatically shown in the config
public static final String MOVING_RUNFLY_WALKSPEED = MOVING_RUNFLY + "walkspeed";
public static final String MOVING_RUNFLY_SNEAKSPEED = MOVING_RUNFLY + "sneakspeed";
public static final String MOVING_RUNFLY_BLOCKSPEED = MOVING_RUNFLY + "blockspeed";
public static final String MOVING_RUNFLY_SWIMSPEED = MOVING_RUNFLY + "swimspeed";
public static final String MOVING_RUNFLY_VERTICALSWIMSPEED = MOVING_RUNFLY + "vertswimspeed";
public static final String MOVING_RUNFLY_SPRINTSPEED = MOVING_RUNFLY + "sprintspeed";
public static final String MOVING_RUNFLY_COBWEBSPEED = MOVING_RUNFLY + "cobwebspeed";
public static final String MOVING_RUNFLY_ALLOWFASTSNEAKING = MOVING_RUNFLY + "allowfastsneaking";
public static final String MOVING_RUNFLY_ALLOWFASTBLOCKING = MOVING_RUNFLY + "allowfastblocking";
public static final String MOVING_RUNFLY_ACTIONS = MOVING_RUNFLY + "actions";
private static final String MOVING_RUNFLY_NOFALL = MOVING_RUNFLY + "nofall.";
public static final String MOVING_RUNFLY_NOFALL_CHECK = MOVING_RUNFLY_NOFALL + "active";
public static final String MOVING_RUNFLY_NOFALL_AGGRESSIVE = MOVING_RUNFLY_NOFALL + "aggressivemode";
public static final String MOVING_RUNFLY_NOFALL_ACTIONS = MOVING_RUNFLY_NOFALL + "actions";
private static final String MOVING_RUNFLY_FLYING = MOVING_RUNFLY + "flying.";
public static final String MOVING_RUNFLY_FLYING_ALLOWALWAYS = MOVING_RUNFLY_FLYING + "allowflyingalways";
public static final String MOVING_RUNFLY_FLYING_ALLOWINCREATIVE = MOVING_RUNFLY_FLYING
+ "allowflyingincreative";
public static final String MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL = MOVING_RUNFLY_FLYING
+ "flyingspeedlimitvertical";
public static final String MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL = MOVING_RUNFLY_FLYING
+ "flyingspeedlimithorizontal";
public static final String MOVING_RUNFLY_FLYING_HEIGHTLIMIT = MOVING_RUNFLY_FLYING + "flyingheightlimit";
public static final String MOVING_RUNFLY_FLYING_ACTIONS = MOVING_RUNFLY_FLYING + "actions";
private static final String MOVING_RUNFLY_BEDFLYING = MOVING_RUNFLY + "bedflying.";
public static final String MOVING_RUNFLY_BEDFLYING_CHECK = MOVING_RUNFLY_BEDFLYING + "active";
public static final String MOVING_RUNFLY_BEDFLYING_ACTIONS = MOVING_RUNFLY_BEDFLYING + "actions";
private static final String MOVING_MOREPACKETS = MOVING + "morepackets.";
public static final String MOVING_MOREPACKETS_CHECK = MOVING_MOREPACKETS + "active";
public static final String MOVING_MOREPACKETS_ACTIONS = MOVING_MOREPACKETS + "actions";
private static final String MOVING_MOREPACKETSVEHICLE = MOVING + "morepacketsvehicle.";
public static final String MOVING_MOREPACKETSVEHICLE_CHECK = MOVING_MOREPACKETSVEHICLE + "active";
public static final String MOVING_MOREPACKETSVEHICLE_ACTIONS = MOVING_MOREPACKETSVEHICLE + "actions";
private static final String MOVING_WATERWALK = MOVING + "waterwalk.";
public static final String MOVING_WATERWALK_CHECK = MOVING_WATERWALK + "active";
public static final String MOVING_WATERWALK_ACTIONS = MOVING_WATERWALK + "actions";
public static final String STRINGS = "strings";
}

View File

@ -32,49 +32,6 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MISCELLANEOUS_OPBYCONSOLEONLY, true);
set(ConfPaths.MISCELLANEOUS_PROTECTPLUGINS, true);
/*** INVENTORY ***/
set(ConfPaths.INVENTORY_DROP_CHECK, true);
set(ConfPaths.INVENTORY_DROP_TIMEFRAME, 20);
set(ConfPaths.INVENTORY_DROP_LIMIT, 100);
set(ConfPaths.INVENTORY_DROP_ACTIONS, "log:drop:0:1:cif cmd:kick");
set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "log:ibow:2:5:if cancel");
set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:ieat:2:5:if cancel");
/*** MOVING ***/
set(ConfPaths.MOVING_RUNFLY_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING, false);
set(ConfPaths.MOVING_RUNFLY_ALLOWFASTBLOCKING, false);
set(ConfPaths.MOVING_RUNFLY_ACTIONS,
"log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");
set(ConfPaths.MOVING_RUNFLY_NOFALL_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_NOFALL_AGGRESSIVE, true);
set(ConfPaths.MOVING_RUNFLY_NOFALL_ACTIONS, "log:nofall:0:5:cif cancel");
set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWALWAYS, false);
set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWINCREATIVE, true);
set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL, 100);
set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL, 60);
set(ConfPaths.MOVING_RUNFLY_FLYING_HEIGHTLIMIT, 128);
set(ConfPaths.MOVING_RUNFLY_FLYING_ACTIONS,
"log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");
set(ConfPaths.MOVING_MOREPACKETS_CHECK, true);
set(ConfPaths.MOVING_MOREPACKETS_ACTIONS, "log:morepackets:3:2:if cancel vl>20 log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_MOREPACKETSVEHICLE_CHECK, true);
set(ConfPaths.MOVING_MOREPACKETSVEHICLE_ACTIONS, "log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_WATERWALK_CHECK, true);
set(ConfPaths.MOVING_WATERWALK_ACTIONS,
"log:waterwalk:3:5:f cancel vl>100 log:waterwalk:0:5:if cancel vl>400 log:waterwalk:0:5:cif cancel");
/*** BLOCKBREAK ***/
set(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK, true);
@ -128,7 +85,6 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.CHAT_NOPWNAGE_WARNLEVEL, 400);
set(ConfPaths.CHAT_NOPWNAGE_WARNTIMEOUT, 30000);
set(ConfPaths.CHAT_NOPWNAGE_BANLEVEL, 800);
set(ConfPaths.CHAT_NOPWNAGE_KICKMESSAGE, "Kicked by the NoPwnage check of NoCheat+!");
set(ConfPaths.CHAT_NOPWNAGE_ACTIONS, "cancel log:nopwnage:2:5:cf cmd:ban cmd:ban-ip");
set(ConfPaths.CHAT_NOPWNAGE_MOVE_CHECK, true);
@ -167,6 +123,16 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
set(ConfPaths.CHAT_NOPWNAGE_MESSAGES_KICK, "You're not allowed to spam this server!");
set(ConfPaths.CHAT_NOPWNAGE_MESSAGES_CAPTCHAQUESTION,
"&cPlease type '&6[captcha]&c' to continue sending messages/commands.");
set(ConfPaths.CHAT_NOPWNAGE_MESSAGES_CAPTCHASUCCESS, "&aOK, it sounds like you're not a spambot.");
set(ConfPaths.CHAT_NOPWNAGE_MESSAGES_WARNPLAYER,
"&cOur system has detected unusual bot activities coming from you. Please be careful with what you say. DON'T repeat what you just said either, unless you want to be banned.");
set(ConfPaths.CHAT_NOPWNAGE_MESSAGES_WARNOTHERS, "&cPlease do not say anything similar to what [player] said!");
set(ConfPaths.CHAT_NOPWNAGE_MESSAGES_WARNRELOG,
"&cYou relogged really fast! If you keep doing that, you're going to be banned.");
set(ConfPaths.CHAT_ARRIVALSLIMIT_CHECK, false);
set(ConfPaths.CHAT_ARRIVALSLIMIT_PLAYERSLIMIT, 3);
set(ConfPaths.CHAT_ARRIVALSLIMIT_TIMEFRAME, 5000);
@ -213,11 +179,66 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.FIGHT_CRITICAL_VELOCITY, 0.1D);
set(ConfPaths.FIGHT_CRITICAL_ACTIONS, "cancel vl>50 log:fcritical:0:5:cif cancel");
set(ConfPaths.FIGHT_ANGLE_CHECK, true);
set(ConfPaths.FIGHT_ANGLE_THRESHOLD, 50D);
set(ConfPaths.FIGHT_ANGLE_ACTIONS, "cancel vl>100 log:fangle:3:5:f cancel vl>250 log:fangle:0:5:cif cancel");
/*** INVENTORY ***/
set(ConfPaths.INVENTORY_DROP_CHECK, true);
set(ConfPaths.INVENTORY_DROP_TIMEFRAME, 20);
set(ConfPaths.INVENTORY_DROP_LIMIT, 100);
set(ConfPaths.INVENTORY_DROP_ACTIONS, "log:drop:0:1:cif cmd:kick");
set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "log:ibow:2:5:if cancel");
set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:ieat:2:5:if cancel");
/*** MOVING ***/
set(ConfPaths.MOVING_RUNFLY_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING, false);
set(ConfPaths.MOVING_RUNFLY_ALLOWFASTBLOCKING, false);
set(ConfPaths.MOVING_RUNFLY_ACTIONS,
"log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");
set(ConfPaths.MOVING_RUNFLY_NOFALL_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_NOFALL_AGGRESSIVE, true);
set(ConfPaths.MOVING_RUNFLY_NOFALL_ACTIONS, "log:nofall:0:5:cif cancel");
set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWALWAYS, false);
set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWINCREATIVE, true);
set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL, 100);
set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL, 60);
set(ConfPaths.MOVING_RUNFLY_FLYING_HEIGHTLIMIT, 128);
set(ConfPaths.MOVING_RUNFLY_FLYING_ACTIONS,
"log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");
set(ConfPaths.MOVING_RUNFLY_BEDFLYING_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_BEDFLYING_ACTIONS,
"log:bedfly:3:5:f cancel vl>1 log:bedfly:0:5:if cancel vl>4 log:bedfly:0:5:cif cancel");
set(ConfPaths.MOVING_MOREPACKETS_CHECK, true);
set(ConfPaths.MOVING_MOREPACKETS_ACTIONS, "log:morepackets:3:2:if cancel vl>20 log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_MOREPACKETSVEHICLE_CHECK, true);
set(ConfPaths.MOVING_MOREPACKETSVEHICLE_ACTIONS, "log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_WATERWALK_CHECK, true);
set(ConfPaths.MOVING_WATERWALK_ACTIONS,
"log:waterwalk:3:5:f vl>100 log:waterwalk:0:5:if cancel vl>400 log:waterwalk:0:5:cif cancel");
/*** STRINGS ***/
set(ConfPaths.STRINGS + ".drop",
"[player] failed [check]: tried to drop more items than allowed. VL [violations].");
set(ConfPaths.STRINGS + ".moveshort", "[player] failed [check]. VL [violations].");
set(ConfPaths.STRINGS + ".movelong",
"[player] in [world] at [location] moving to [locationto] over distance [movedistance] failed check [check]. Total violation level so far [violations].");
set(ConfPaths.STRINGS + ".bedfly",
"[player] failed [check]: tried to fly by sending bed leaving packets. VL [violations].");
set(ConfPaths.STRINGS + ".nofall",
"[player] failed [check]: tried to avoid fall damage for ~[falldistance] blocks. VL [violations].");
set(ConfPaths.STRINGS + ".morepackets",
@ -225,7 +246,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".waterwalk",
"[player] failed [check]: tried to walk on water. Total violation level [violations].");
set(ConfPaths.STRINGS + ".bbfastbreak",
"[player] failed [check]: tried to break too much blocks. Total violation level [violations].");
"[player] failed [check]: tried to break too much [blocktype]. Total violation level [violations].");
set(ConfPaths.STRINGS + ".bbreach",
"[player] failed [check]: tried to interact with a block over distance [reachdistance]. VL [violations].");
set(ConfPaths.STRINGS + ".bbdirection",
@ -256,6 +277,8 @@ public class DefaultConfig extends ConfigFile {
"[player] failed [check]: tried to do a knockback but wasn't technically sprinting. VL [violations].");
set(ConfPaths.STRINGS + ".fcritical",
"[player] failed [check]: tried to do a critical hit but wasn't technically jumping. VL [violations].");
set(ConfPaths.STRINGS + ".fangle",
"[player] failed [check]: tried to fight multiple entities at the same time. VL [violations].");
set(ConfPaths.STRINGS + ".ibow", "[player] failed [check]: fires bow to fast. VL [violations].");
set(ConfPaths.STRINGS + ".ieat", "[player] failed [check]: eats food [food] too fast. VL [violations].");
set(ConfPaths.STRINGS + ".kick", "kick [player]");

View File

@ -59,6 +59,11 @@ public class NCPPlayer {
return false;
}
public static void reloadConfig() {
for (final String playerName : players.keySet())
players.get(playerName).configMap.clear();
}
private final String name;
private Player bukkitPlayer;

View File

@ -45,6 +45,7 @@ public class Permissions {
public static final String FIGHT_INSTANTHEAL = FIGHT + ".instantheal";
public static final String FIGHT_KNOCKBACK = FIGHT + ".knockback";
public static final String FIGHT_CRITICAL = FIGHT + ".critical";
public static final String FIGHT_ANGLE = FIGHT + ".angle";
private static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
@ -53,12 +54,13 @@ public class Permissions {
private static final String MOVING = CHECKS + ".moving";
public static final String MOVING_RUNFLY = MOVING + ".runfly";
public static final String MOVING_FLYING = MOVING + ".flying";
public static final String MOVING_BEDFLYING = MOVING + ".bedflying";
public static final String MOVING_NOFALL = MOVING + ".nofall";
public static final String MOVING_SWIMMING = MOVING + ".swimming";
public static final String MOVING_SNEAKING = MOVING + ".sneaking";
public static final String MOVING_BLOCKING = MOVING + ".blocking";
public static final String MOVING_FLYING = MOVING + ".flying";
public static final String MOVING_COBWEB = MOVING + ".cobweb";
public static final String MOVING_NOFALL = MOVING + ".nofall";
public static final String MOVING_MOREPACKETS = MOVING + ".morepackets";
public static final String MOVING_MOREPACKETSVEHICLE = MOVING + ".morepacketsvehicle";
public static final String MOVING_WATERWALK = MOVING + ".waterwalk";

View File

@ -24,11 +24,13 @@ public class Statistics {
FI_SPEED("fight.speed"),
FI_KNOCKBACK("fight.knockback"),
FI_CRITICAL("fight.critical"),
FI_ANGLE("fight.angle"),
INV_DROP("inventory.drop"),
INV_BOW("inventory.instantbow"),
INV_EAT("inventory.instanteat"),
MOV_RUNNING("moving.running"),
MOV_FLYING("moving.flying"),
MOV_BEDFLYING("moving.bedflying"),
MOV_MOREPACKETS("moving.morepackets"),
MOV_MOREPACKETSVEHICLE("moving.morepacketsvehicle"),
MOV_NOFALL("moving.nofall"),
@ -36,6 +38,7 @@ public class Statistics {
MOV_BLOCKING("moving.blocking"),
MOV_SWIMMING("moving.swimming"),
MOV_COBWEB("moving.cobweb"),
MOV_WATERWALK("moving.waterwalk"),
FI_GODMODE("fight.godmode"),
FI_INSTANTHEAL("fight.instantheal");

View File

@ -42,4 +42,9 @@ public final class PreciseLocation {
y = location.y;
z = location.z;
}
@Override
public String toString() {
return "PreciseLocation {x=" + x + ", y=" + y + ", z=" + z + "}";
}
}

View File

@ -61,4 +61,8 @@ public final class SimpleLocation {
z = location.getBlockZ();
}
@Override
public String toString() {
return "SimpleLocation {x=" + x + ", y=" + y + ", z=" + z + "}";
}
}