summaryrefslogtreecommitdiffstats
path: root/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/blockplace/DirectionCheck.java
blob: 8aa782d195eff30042608145c4c2bd077b4b8014 (plain)
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
package com.earth2me.essentials.anticheat.checks.blockplace;

import com.earth2me.essentials.anticheat.NoCheat;
import com.earth2me.essentials.anticheat.NoCheatPlayer;
import com.earth2me.essentials.anticheat.actions.ParameterName;
import com.earth2me.essentials.anticheat.checks.CheckUtil;
import com.earth2me.essentials.anticheat.data.SimpleLocation;
import com.earth2me.essentials.anticheat.data.Statistics.Id;
import java.util.Locale;
import org.bukkit.Location;


/**
 * The DirectionCheck will find out if a player tried to interact with something that's not in his field of view.
 *
 */
public class DirectionCheck extends BlockPlaceCheck
{
	public DirectionCheck(NoCheat plugin)
	{
		super(plugin, "blockplace.direction");
	}

	public boolean check(NoCheatPlayer player, BlockPlaceData data, BlockPlaceConfig cc)
	{

		boolean cancel = false;

		final SimpleLocation blockPlaced = data.blockPlaced;
		final SimpleLocation blockPlacedAgainst = data.blockPlacedAgainst;

		// How far "off" is the player with his aim. We calculate from the
		// players eye location and view direction to the center of the target
		// block. If the line of sight is more too far off, "off" will be
		// bigger than 0
		double off = CheckUtil.directionCheck(player, blockPlacedAgainst.x + 0.5D, blockPlacedAgainst.y + 0.5D, blockPlacedAgainst.z + 0.5D, 1D, 1D, cc.directionPrecision);

		// now check if the player is looking at the block from the correct side
		double off2 = 0.0D;

		// Find out against which face the player tried to build, and if he
		// stood on the correct side of it
		Location eyes = player.getPlayer().getEyeLocation();
		if (blockPlaced.x > blockPlacedAgainst.x)
		{
			off2 = blockPlacedAgainst.x + 0.5D - eyes.getX();
		}
		else if (blockPlaced.x < blockPlacedAgainst.x)
		{
			off2 = -(blockPlacedAgainst.x + 0.5D - eyes.getX());
		}
		else if (blockPlaced.y > blockPlacedAgainst.y)
		{
			off2 = blockPlacedAgainst.y + 0.5D - eyes.getY();
		}
		else if (blockPlaced.y < blockPlacedAgainst.y)
		{
			off2 = -(blockPlacedAgainst.y + 0.5D - eyes.getY());
		}
		else if (blockPlaced.z > blockPlacedAgainst.z)
		{
			off2 = blockPlacedAgainst.z + 0.5D - eyes.getZ();
		}
		else if (blockPlaced.z < blockPlacedAgainst.z)
		{
			off2 = -(blockPlacedAgainst.z + 0.5D - eyes.getZ());
		}

		// If he wasn't on the correct side, add that to the "off" value
		if (off2 > 0.0D)
		{
			off += off2;
		}

		final long time = System.currentTimeMillis();

		if (off < 0.1D)
		{
			// Player did nothing wrong
			// reduce violation counter to reward him
			data.directionVL *= 0.9D;
		}
		else
		{
			// Player failed the check
			// Increment violation counter and statistics
			data.directionVL += off;
			incrementStatistics(player, Id.BP_DIRECTION, off);

			// 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.directionActions, data.directionVL);

			if (cancel)
			{
				// if we should cancel, remember the current time too
				data.directionLastViolationTime = time;
			}
		}

		// If the player is still in penalty time, cancel the event anyway
		if (data.directionLastViolationTime + cc.directionPenaltyTime > time)
		{
			// A safeguard to avoid people getting stuck in penalty time
			// indefinitely in case the system time of the server gets changed
			if (data.directionLastViolationTime > time)
			{
				data.directionLastViolationTime = 0;
			}

			// He is in penalty time, therefore request cancelling of the event
			return true;
		}

		return cancel;
	}

	@Override
	public String getParameter(ParameterName wildcard, NoCheatPlayer player)
	{

		if (wildcard == ParameterName.VIOLATIONS)
		{
			return String.format(Locale.US, "%d", (int)getData(player).directionVL);
		}
		else
		{
			return super.getParameter(wildcard, player);
		}
	}
}