/
EngraveCommand.java
172 lines (144 loc) · 7.39 KB
/
EngraveCommand.java
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
package net.aufdemrand.denizen.scripts.commands.core;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemDespawnEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import net.aufdemrand.denizen.exceptions.CommandExecutionException;
import net.aufdemrand.denizen.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.commands.AbstractCommand;
import net.aufdemrand.denizen.utilities.arguments.aH;
import net.aufdemrand.denizen.utilities.arguments.aH.ArgumentType;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.debugging.dB.Messages;
import net.aufdemrand.denizen.utilities.nbt.NBTItem;
/*
* Denizen dScript ENGRAVE command:
*
* Engraves an item in the player's hand. Engraved items are bound to their engraver and cannot be picked
* up by other Players.
*
*/
public class EngraveCommand extends AbstractCommand implements Listener {
/* ENGRAVE (REMOVE|ADD) (TARGET:target_name)
/* Arguments: [] - Required, () - Optional
*
* Example Usage:
*/
private enum Action { ADD, REMOVE }
@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
// Initialize fields
Action action = Action.ADD;
String target = scriptEntry.getPlayer().getName();
ItemStack item = scriptEntry.getPlayer().getItemInHand() != null ? scriptEntry.getPlayer().getItemInHand(): null;
for (String arg : scriptEntry.getArguments()) {
if (aH.matchesArg("ADD, REMOVE, REMOVEALL", arg)) {
action = Action.valueOf(aH.getStringFrom(arg).toUpperCase());
} else if (aH.matchesValueArg("TARGET", arg, ArgumentType.String)) {
target = aH.getStringFrom(arg);
} else if (aH.matchesItem(arg)) {
item = aH.getItemFrom(arg);
} else throw new InvalidArgumentsException(Messages.ERROR_UNKNOWN_ARGUMENT, arg);
}
if (item == null) throw new InvalidArgumentsException(Messages.ERROR_MISSING_OTHER, "ITEM");
if (target == null) throw new InvalidArgumentsException(Messages.ERROR_NO_PLAYER);
// Add objects that need to be passed to execute() to the scriptEntry
scriptEntry.addObject("action", action)
.addObject("target", target)
.addObject("item", item);
}
@Override
public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
// Fetch objects
Action action = (Action) scriptEntry.getObject("action");
String target = String.valueOf(scriptEntry.getObject("target"));
ItemStack item = (ItemStack) scriptEntry.getObject("item");
// Report to dB
dB.report(getName(),
aH.debugObj("Action", action.toString())
+ aH.debugObj("Target", target)
+ aH.debugObj("Item", item.getType().toString()));
switch (action) {
case ADD:
dB.echoDebug("Engraving '" + item.getType() + "' with an inscription of '" + target + "'.");
NBTItem.addCustomNBT(item, "owner", target);
dB.echoDebug(NBTItem.getCustomNBT(item, "owner"));
return;
case REMOVE:
dB.echoDebug("Removing engraving on '" + item.getType() + "'.");
NBTItem.removeCustomNBT(item, "owner");
return;
}
}
// Map to keep track of notification cooldowns (String playerName, Long timeout)
Map<String, Long> notifyCooldown = new HashMap<String, Long>();
/*
* Checks the owner of the picked up item, if any. Will not let the Player pick up
* the item if they are not the owner of the engraved item.
*
* If sneaking, a message will let the Player know that it is engraved.
*
*/
@EventHandler
public void checkOwner(PlayerPickupItemEvent event) {
ItemStack item = event.getItem().getItemStack();
if (NBTItem.hasCustomNBT(item, "owner")
&& !NBTItem.getCustomNBT(item, "owner").equalsIgnoreCase(event.getPlayer().getName())) {
dB.echoDebug(NBTItem.getCustomNBT(item, "owner"));
// See why item isn't being picked up if sneaking.
if (event.getPlayer().isSneaking()) {
// Check cooldown to avoid spam from multiple items/event firings
if (!notifyCooldown.containsKey(event.getPlayer().getName())) {
// If not cooled down, set cool-down and alert Player they cannot pick it up.
notifyCooldown.put(event.getPlayer().getName(), System.currentTimeMillis() + 10000);
event.getPlayer().sendMessage("That " + event.getItem().getItemStack().getType() + " does not belong to you!");
} else {
// If cooled down, remove the cooldown.
if (notifyCooldown.get(event.getPlayer().getName()) < System.currentTimeMillis())
notifyCooldown.remove(event.getPlayer().getName());
}
}
// If engraved, and not the engraved Player, cancel the pickup event.
event.setCancelled(true);
}
// Otherwise, don't interfere.
}
// Map to keep track of despawn delays. (Integer entityID, Long timeout)
Map<Integer, Long> despawnDelay = new HashMap<Integer, Long>();
/*
* An engraved item will take longer to despawn in the world, allowing a little bit of extra time
* for the player to retrieve it.
*
*/
@EventHandler
public void stopDespawn(ItemDespawnEvent event) {
ItemStack item = event.getEntity().getItemStack();
// Check if the item has an engraving, otherwise carry on.
if (NBTItem.hasCustomNBT(item, "owner")) {
dB.echoDebug(NBTItem.getCustomNBT(item, "owner"));
// If in the delay map
if (despawnDelay.containsKey(event.getEntity().getEntityId())) {
// If not cooled, cancel despawn.
if (despawnDelay.get(event.getEntity().getEntityId()) < System.currentTimeMillis())
event.setCancelled(true);
else
// If cooled, remove from map.
dB.echoDebug("Removed an ENGRAVED '" + item.getType().name() + "' which belonged to '" + NBTItem.getCustomNBT(item, "owner") + "'.");
despawnDelay.remove(event.getEntity().getEntityId());
} else {
// If not in delay map, add to delay map and cancel despawn.
event.setCancelled(true);
dB.echoDebug("Stopped despawn of an ENGRAVED '" + item + "' which belonged to '" + NBTItem.getCustomNBT(item, "owner") + "'. Will remove from world in 10 minutes.");
despawnDelay.put(event.getEntity().getEntityId(), System.currentTimeMillis() + (1000 * 60 * 10));
}
}
}
@Override
public void onEnable() {
denizen.getServer().getPluginManager().registerEvents(this, denizen);
}
}