summaryrefslogtreecommitdiffstats
path: root/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/inventory/InventoryCheckListener.java
blob: f42a37185a528aa46534c3e93537818300e43ad1 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package com.earth2me.essentials.anticheat.checks.inventory;

import com.earth2me.essentials.anticheat.EventManager;
import com.earth2me.essentials.anticheat.NoCheat;
import com.earth2me.essentials.anticheat.NoCheatPlayer;
import com.earth2me.essentials.anticheat.checks.CheckUtil;
import com.earth2me.essentials.anticheat.config.ConfigurationCacheStore;
import com.earth2me.essentials.anticheat.config.Permissions;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;


/**
 * Central location to listen to events that are relevant for the inventory checks
 *
 */
public class InventoryCheckListener implements Listener, EventManager
{
	private final DropCheck dropCheck;
	private final InstantBowCheck instantBowCheck;
	private final InstantEatCheck instantEatCheck;
	private final NoCheat plugin;

	public InventoryCheckListener(NoCheat plugin)
	{

		this.dropCheck = new DropCheck(plugin);
		this.instantBowCheck = new InstantBowCheck(plugin);
		this.instantEatCheck = new InstantEatCheck(plugin);

		this.plugin = plugin;
	}

	/**
	 * We listen to DropItem Event for the dropCheck
	 *
	 * @param event The PlayerDropItem Event
	 */
	@EventHandler(priority = EventPriority.LOWEST)
	protected void handlePlayerDropItemEvent(final PlayerDropItemEvent event)
	{

		if (event.isCancelled() || event.getPlayer().isDead())
		{
			return;
		}

		boolean cancelled = false;

		final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
		final InventoryConfig cc = InventoryCheck.getConfig(player);
		final InventoryData data = InventoryCheck.getData(player);

		// If it should be executed, do it
		if (cc.dropCheck && !player.hasPermission(Permissions.INVENTORY_DROP))
		{
			cancelled = dropCheck.check(player, data, cc);
		}

		if (cancelled)
		{
			// Cancelling drop events is not save (in certain circumstances
			// items will disappear completely). So don't do it and kick
			// players instead by default
			// event.setCancelled(true);
		}
	}

	/**
	 * We listen to PlayerInteractEvent for the instantEat and instantBow checks
	 *
	 * @param event The PlayerInteractEvent
	 */
	@EventHandler(priority = EventPriority.LOWEST)
	public void interact(final PlayerInteractEvent event)
	{

		// Only interested in right-clicks while holding an item
		if (!event.hasItem() || !(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK))
		{
			return;
		}

		NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
		final InventoryData data = InventoryCheck.getData(player);

		if (event.getItem().getType() == Material.BOW)
		{
			// It was a bow, the player starts to pull the string
			// Remember this time
			data.lastBowInteractTime = System.currentTimeMillis();
		}
		else if (CheckUtil.isFood(event.getItem()))
		{
			// It was food, the player starts to eat some food
			// Remember this time and the type of food
			data.foodMaterial = event.getItem().getType();
			data.lastEatInteractTime = System.currentTimeMillis();
		}
		else
		{
			// Nothing that we are interested in, reset data
			data.lastBowInteractTime = 0;
			data.lastEatInteractTime = 0;
			data.foodMaterial = null;
		}
	}

	/**
	 * We listen to FoodLevelChange Event because Bukkit doesn't provide a PlayerFoodEating Event (or whatever it would
	 * be called).
	 *
	 * @param event The FoodLevelChangeEvent
	 */
	@EventHandler(priority = EventPriority.LOWEST)
	public void foodchanged(final FoodLevelChangeEvent event)
	{
		// Only if a player ate food
		if (!event.isCancelled() && event.getEntity() instanceof Player)
		{
			final NoCheatPlayer player = plugin.getPlayer((Player)event.getEntity());
			final InventoryConfig cc = InventoryCheck.getConfig(player);
			final InventoryData data = InventoryCheck.getData(player);

			// Only if he should get checked
			if (cc.eatCheck && !player.hasPermission(Permissions.INVENTORY_INSTANTEAT))
			{

				boolean cancelled = instantEatCheck.check(player, event, data, cc);

				// The check requested the foodlevelchange to get cancelled
				event.setCancelled(cancelled);
			}

			// Forget the food material, as the info is no longer needed
			data.foodMaterial = null;
		}

	}

	/**
	 * We listen to EntityShootBowEvent for the instantbow check
	 *
	 * @param event The EntityShootBowEvent
	 */
	@EventHandler(priority = EventPriority.LOWEST)
	public void bowfired(final EntityShootBowEvent event)
	{
		// Only if a player shot the arrow
		if (!event.isCancelled() && event.getEntity() instanceof Player)
		{
			final NoCheatPlayer player = plugin.getPlayer((Player)event.getEntity());
			final InventoryConfig cc = InventoryCheck.getConfig(player);

			// Only if he should get checked
			if (cc.bowCheck && !player.hasPermission(Permissions.INVENTORY_INSTANTBOW))
			{
				final InventoryData data = InventoryCheck.getData(player);
				boolean cancelled = instantBowCheck.check(player, event, data, cc);

				// The check requested the bowshooting to get cancelled
				event.setCancelled(cancelled);
			}
		}
	}

	public List<String> getActiveChecks(ConfigurationCacheStore cc)
	{
		LinkedList<String> s = new LinkedList<String>();

		InventoryConfig i = InventoryCheck.getConfig(cc);
		if (i.dropCheck)
		{
			s.add("inventory.dropCheck");
		}
		if (i.bowCheck)
		{
			s.add("inventory.instantbow");
		}
		if (i.eatCheck)
		{
			s.add("inventory.instanteat");
		}
		return s;
	}
}