summaryrefslogtreecommitdiffstats
path: root/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/fight/GodmodeCheck.java
blob: cd0fd6aaa09a67824066db0e8eac50c4797bf6f0 (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
package com.earth2me.essentials.anticheat.checks.fight;

import com.earth2me.essentials.anticheat.NoCheat;
import com.earth2me.essentials.anticheat.NoCheatPlayer;
import com.earth2me.essentials.anticheat.actions.ParameterName;
import com.earth2me.essentials.anticheat.config.Permissions;
import com.earth2me.essentials.anticheat.data.Statistics;
import java.util.Locale;
import net.minecraft.server.EntityPlayer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.entity.CraftPlayer;


/**
 * The Godmode Check will find out if a player tried to stay invulnerable after being hit or after dying
 *
 */
public class GodmodeCheck extends FightCheck
{
	public GodmodeCheck(NoCheat plugin)
	{
		super(plugin, "fight.godmode", Permissions.FIGHT_GODMODE);
	}

	@Override
	public boolean check(NoCheatPlayer player, FightData data, FightConfig cc)
	{

		boolean cancelled = false;

		long time = System.currentTimeMillis();

		// Check at most once a second
		if (data.godmodeLastDamageTime + 1000L < time)
		{
			data.godmodeLastDamageTime = time;

			// How old is the player now?
			int age = player.getTicksLived();
			// How much older did he get?
			int ageDiff = Math.max(0, age - data.godmodeLastAge);
			// Is he invulnerable?
			int nodamageTicks = player.getPlayer().getNoDamageTicks();

			if (nodamageTicks > 0 && ageDiff < 15)
			{
				// He is invulnerable and didn't age fast enough, that costs
				// some points
				data.godmodeBuffer -= (15 - ageDiff);

				// Still points left?
				if (data.godmodeBuffer <= 0)
				{
					// No, that means VL and statistics increased
					data.godmodeVL -= data.godmodeBuffer;
					incrementStatistics(player, Statistics.Id.FI_GODMODE, -data.godmodeBuffer);

					// Execute whatever actions are associated with this check and the
					// violation level and find out if we should cancel the event
					cancelled = executeActions(player, cc.godmodeActions, data.godmodeVL);
				}
			}
			else
			{
				// Give some new points, once a second
				data.godmodeBuffer += 15;
				data.godmodeVL *= 0.95;
			}

			if (data.godmodeBuffer < 0)
			{
				// Can't have less than 0
				data.godmodeBuffer = 0;
			}
			else if (data.godmodeBuffer > 30)
			{
				// And 30 is enough for simple lag situations
				data.godmodeBuffer = 30;
			}

			// Start age counting from a new time
			data.godmodeLastAge = age;
		}

		return cancelled;
	}

	@Override
	public boolean isEnabled(FightConfig cc)
	{
		return cc.godmodeCheck;
	}

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

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

	/**
	 * If a player apparently died, make sure he really dies after some time if he didn't already, by setting up a
	 * Bukkit task
	 *
	 * @param player The player
	 */
	public void death(CraftPlayer player)
	{
		// First check if the player is really dead (e.g. another plugin could
		// have just fired an artificial event)
		if (player.getHealth() <= 0 && player.isDead())
		{
			try
			{
				final EntityPlayer entity = player.getHandle();

				// Schedule a task to be executed in roughly 1.5 seconds
				Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
				{
					public void run()
					{
						try
						{
							// Check again if the player should be dead, and
							// if the game didn't mark him as dead
							if (entity.getHealth() <= 0 && !entity.dead)
							{
								// Artifically "kill" him
								entity.deathTicks = 19;
								entity.a(true);
							}
						}
						catch (Exception e)
						{
						}
					}
				}, 30);
			}
			catch (Exception e)
			{
			}
		}
	}
}