/
CommandExecuter.java
182 lines (139 loc) · 7.7 KB
/
CommandExecuter.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
173
174
175
176
177
178
179
180
181
182
package net.aufdemrand.denizen.scripts.commands;
import net.aufdemrand.denizen.Denizen;
import net.aufdemrand.denizen.events.ScriptEntryExecuteEvent;
import net.aufdemrand.denizen.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.dNPC;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.objects.aH;
import net.aufdemrand.denizen.tags.TagManager;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.debugging.dB.DebugElement;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CommandExecuter {
private Denizen plugin;
final Pattern definition_pattern = Pattern.compile("%(.+?)%");
public CommandExecuter(Denizen denizen) {
plugin = denizen;
}
/*
* Executes a command defined in scriptEntry
*/
public boolean execute(ScriptEntry scriptEntry) {
Matcher m = definition_pattern.matcher(scriptEntry.getCommandName());
StringBuffer sb = new StringBuffer();
while (m.find()) {
if (scriptEntry.getResidingQueue().hasContext(m.group(1).toLowerCase()))
m.appendReplacement(sb,
scriptEntry.getResidingQueue().getContext(m.group(1).toLowerCase()));
else m.appendReplacement(sb, "null");
}
m.appendTail(sb);
scriptEntry.setCommandName(sb.toString());
if (plugin.getCommandRegistry().get(scriptEntry.getCommandName()) == null) {
dB.echoDebug(DebugElement.Header, "Executing command: " + scriptEntry.getCommandName());
dB.echoError(scriptEntry.getCommandName() + " is an invalid dCommand! Are you sure it loaded?");
dB.echoDebug(DebugElement.Footer);
return false;
}
// Get the command instance ready for the execution of the scriptEntry
AbstractCommand command = plugin.getCommandRegistry().get(scriptEntry.getCommandName());
// Debugger information
if (scriptEntry.getPlayer() != null)
dB.echoDebug(DebugElement.Header, "Executing dCommand: " + scriptEntry.getCommandName() + "/" + scriptEntry.getPlayer().getName());
else dB.echoDebug(DebugElement.Header, "Executing dCommand: " + scriptEntry.getCommandName() + (scriptEntry.getNPC() != null ? "/" + scriptEntry.getNPC().getName() : ""));
// Don't execute() if problems arise in parseArgs()
boolean keepGoing = true;
try {
// Throw exception if arguments are required for this command, but not supplied.
if (command.getOptions().REQUIRED_ARGS > scriptEntry.getArguments().size()) throw new InvalidArgumentsException("");
if (scriptEntry.has_tags)
scriptEntry.setArguments(TagManager.fillArguments(scriptEntry.getArguments(), scriptEntry, true)); // Replace tags
/* If using NPCID:# or PLAYER:Name arguments, these need to be changed out immediately because...
* 1) Denizen/Player flags need the desired NPC/PLAYER before parseArgs's getFilledArguments() so that
* the Player/Denizen flags will read from the correct Object. If using PLAYER or NPCID arguments,
* the desired Objects are obviously not the same objects that were sent with the ScriptEntry.
* 2) These arguments should be valid for EVERY ScriptCommand, so why not just take care of it
* here, instead of requiring each command to take care of the argument.
*/
List<String> newArgs = new ArrayList<String>();
int nested_depth = 0;
for (String arg : scriptEntry.getArguments()) {
if (arg.equals("{")) nested_depth++;
if (arg.equals("}")) nested_depth--;
if (nested_depth > 0) {
newArgs.add(arg);
continue;
}
m = definition_pattern.matcher(arg);
sb = new StringBuffer();
while (m.find()) {
if (scriptEntry.getResidingQueue().hasContext(m.group(1).toLowerCase()))
m.appendReplacement(sb,
scriptEntry.getResidingQueue()
.getContext(m.group(1).toLowerCase()));
else m.appendReplacement(sb, "null");
}
m.appendTail(sb);
arg = sb.toString();
// Fill player/off-line player
if (aH.matchesValueArg("player", arg, aH.ArgumentType.String)) {
arg = TagManager.tag(scriptEntry.getPlayer(), scriptEntry.getNPC(), arg, false);
scriptEntry.setPlayer(dPlayer.valueOf(aH.getStringFrom(arg)));
}
// Fill NPCID/NPC argument
else if (aH.matchesValueArg("npcid, npc", arg, aH.ArgumentType.String)) {
dB.echoDebug("...replacing the linked NPC.");
arg = TagManager.tag(scriptEntry.getPlayer(), scriptEntry.getNPC(), arg, false);
if (dNPC.matches(aH.getStringFrom(arg)))
scriptEntry.setNPC(dNPC.valueOf(aH.getStringFrom(arg)));
}
else newArgs.add(arg);
}
// Add the arguments back to the scriptEntry.
scriptEntry.setArguments(newArgs);
// Now process non-instant tags.
if (scriptEntry.has_tags)
scriptEntry.setArguments(TagManager.fillArguments(scriptEntry.getArguments(), scriptEntry, false));
// Parse the rest of the arguments for execution.
command.parseArgs(scriptEntry);
} catch (InvalidArgumentsException e) {
keepGoing = false;
// Give usage hint if InvalidArgumentsException was called.
dB.echoError("Woah! Invalid arguments were specified!");
dB.echoDebug(ChatColor.YELLOW + "+> MESSAGE follows: " + ChatColor.WHITE + "'" + e.getMessage() + "'");
dB.echoDebug("Usage: " + command.getUsageHint());
dB.echoDebug(DebugElement.Footer);
} catch (Exception e) {
keepGoing = false;
dB.echoError("Woah! An exception has been called with this command!");
if (!dB.showStackTraces)
dB.echoError("Enable '/denizen stacktrace' for the nitty-gritty.");
else e.printStackTrace();
dB.echoDebug(DebugElement.Footer);
} finally {
if (keepGoing)
try {
// Fire event for last minute cancellation/alterations
ScriptEntryExecuteEvent event = new ScriptEntryExecuteEvent(scriptEntry);
Bukkit.getServer().getPluginManager().callEvent(event);
// If event is altered, update the scriptEntry.
if (event.isAltered()) scriptEntry = event.getScriptEntry();
// Run the execute method in the command
if (!event.isCancelled()) command.execute(scriptEntry);
else dB.echoDebug("ScriptEntry has been cancelled.");
} catch (Exception e) {
dB.echoError("Woah!! An exception has been called with this command!");
if (!dB.showStackTraces)
dB.echoError("Enable '/denizen stacktrace' for the nitty-gritty.");
else e.printStackTrace();
}
}
return true;
}
}