1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
package com.earth2me.essentials.anticheat.checks.moving;
import com.earth2me.essentials.anticheat.NoCheat;
import com.earth2me.essentials.anticheat.NoCheatPlayer;
import com.earth2me.essentials.anticheat.actions.ParameterName;
import com.earth2me.essentials.anticheat.data.PreciseLocation;
import com.earth2me.essentials.anticheat.data.Statistics.Id;
import java.util.Locale;
/**
* The morePacketsCheck (previously called SpeedhackCheck) will try to identify players that send more than the usual
* amount of move-packets to the server to be able to move faster than normal, without getting caught by the other
* checks (flying/running).
*
* It monitors the number of packets sent to the server within 1 second and compares it to the "legal" number of packets
* for that timeframe (22).
*
*/
public class MorePacketsCheck extends MovingCheck
{
// 20 would be for perfect internet connections, 22 is good enough
private final static int packetsPerTimeframe = 22;
public MorePacketsCheck(NoCheat plugin)
{
super(plugin, "moving.morepackets");
}
/**
* 1. Players get assigned a certain amount of "free" packets as a limit initially 2. Every move packet reduces that
* limit by 1 3. If more than 1 second of time passed, the limit gets increased by 22 * time in seconds, up to 50
* and he gets a new "setback" location 4. If the player reaches limit = 0 -> teleport him back to "setback" 5. If
* there was a long pause (maybe lag), limit may be up to 100
*
*/
public PreciseLocation check(NoCheatPlayer player, MovingData data, MovingConfig cc)
{
PreciseLocation newToLocation = null;
if (!data.morePacketsSetbackPoint.isSet())
{
data.morePacketsSetbackPoint.set(data.from);
}
long time = System.currentTimeMillis();
// Take a packet from the buffer
data.morePacketsBuffer--;
// Player used up buffer, he fails the check
if (data.morePacketsBuffer < 0)
{
data.morePacketsVL = -data.morePacketsBuffer;
incrementStatistics(player, Id.MOV_MOREPACKETS, 1);
data.packets = -data.morePacketsBuffer;
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
final boolean cancel = executeActions(player, cc.morePacketsActions, data.morePacketsVL);
if (cancel)
{
newToLocation = data.morePacketsSetbackPoint;
}
}
if (data.morePacketsLastTime + 1000 < time)
{
// More than 1 second elapsed, but how many?
double seconds = ((double)(time - data.morePacketsLastTime)) / 1000D;
// For each second, fill the buffer
data.morePacketsBuffer += packetsPerTimeframe * seconds;
// If there was a long pause (maybe server lag?)
// Allow buffer to grow up to 100
if (seconds > 2)
{
if (data.morePacketsBuffer > 100)
{
data.morePacketsBuffer = 100;
}
// Else only allow growth up to 50
}
else
{
if (data.morePacketsBuffer > 50)
{
data.morePacketsBuffer = 50;
}
}
// Set the new "last" time
data.morePacketsLastTime = time;
// Set the new "setback" location
if (newToLocation == null)
{
data.morePacketsSetbackPoint.set(data.from);
}
}
else if (data.morePacketsLastTime > time)
{
// Security check, maybe system time changed
data.morePacketsLastTime = time;
}
return newToLocation;
}
@Override
public String getParameter(ParameterName wildcard, NoCheatPlayer player)
{
if (wildcard == ParameterName.VIOLATIONS)
{
return String.format(Locale.US, "%d", (int)getData(player).morePacketsVL);
}
else if (wildcard == ParameterName.PACKETS)
{
return String.format(Locale.US, "%d", getData(player).packets);
}
else
{
return super.getParameter(wildcard, player);
}
}
}
|