/
CommandScriptEvent.java
181 lines (165 loc) · 6.99 KB
/
CommandScriptEvent.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
package com.denizenscript.denizen.events.server;
import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizen.objects.EntityTag;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
import com.denizenscript.denizencore.objects.ArgumentHelper;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.scripts.ScriptEntryData;
import com.denizenscript.denizencore.tags.core.EscapeTagBase;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import org.bukkit.Location;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
import java.util.Arrays;
public class CommandScriptEvent extends BukkitScriptEvent implements Listener {
// <--[event]
// @Events
// command
// <command_name> command
//
// @Regex ^on( [^\s]+)? command$
//
// @Group Server
//
// @Switch in:<area> to only process the event if it occurred within a specified area.
//
// @Triggers when a player, console, or command block/minecart runs a Bukkit command. This happens before
// any code of established commands, allowing scripts to 'override' existing commands.
// Note that for the sake of the event line, escaping is used, so 'bukkit:plugins' becomes 'bukkit&coplugins'
// @Context
// <context.command> returns the command name as an Element.
// <context.raw_args> returns any args used as an Element.
// <context.args> returns a ListTag of the arguments.
// <context.source_type> returns the source of the command. Can be: PLAYER, SERVER, COMMAND_BLOCK, or COMMAND_MINECART.
// <context.command_block_location> returns the command block's location (if the command was run from one).
// <context.command_minecart> returns the EntityTag of the command minecart (if the command was run from one).
//
// @Determine
// "FULFILLED" to tell Bukkit the command was handled.
//
// @Player when source_type is player.
//
// -->
public CommandScriptEvent() {
instance = this;
}
public static CommandScriptEvent instance;
public String commandName;
public String fullMessage;
public String sourceType;
public Location location;
public PlayerCommandPreprocessEvent playerEvent;
public ServerCommandEvent serverEvent;
@Override
public String getName() {
return "Command";
}
@Override
public boolean couldMatch(ScriptPath path) {
if (!path.eventArgLowerAt(1).equals("command") &&
(!path.eventArgLowerAt(0).equals("command") || path.eventArgLowerAt(1).equals("unknown"))) {
return false;
}
return true;
}
@Override
public boolean matches(ScriptPath path) {
if (!runInCheck(path, playerEvent == null ? null : playerEvent.getPlayer().getLocation())) {
return false;
}
if (!path.eventArgLowerAt(0).equals("command") && !runGenericCheck(path.eventArgLowerAt(0), EscapeTagBase.escape(commandName))) {
return false;
}
return super.matches(path);
}
@Override
public ScriptEntryData getScriptEntryData() {
return new BukkitScriptEntryData(playerEvent == null ? null : new PlayerTag(playerEvent.getPlayer()), null);
}
public String cleanMessageArgs() {
return fullMessage.split(" ").length > 1 ? fullMessage.split(" ", 2)[1] : "";
}
@Override
public boolean applyDetermination(ScriptPath path, ObjectTag determinationObj) {
if (determinationObj instanceof ElementTag) {
String determination = determinationObj.toString();
String lower = CoreUtilities.toLowerCase(determination);
if (lower.equals("fulfilled")) {
cancelled = true;
cancellationChanged();
return true;
}
}
return super.applyDetermination(path, determinationObj);
}
@Override
public ObjectTag getContext(String name) {
if (name.equals("command")) {
return new ElementTag(commandName);
}
else if (name.equals("raw_args")) {
return new ElementTag(cleanMessageArgs());
}
else if (name.equals("args")) {
return new ListTag(Arrays.asList(ArgumentHelper.buildArgs(cleanMessageArgs())));
}
else if (name.equals("server")) {
return new ElementTag(sourceType.equals("server"));
}
else if (name.equals("source_type")) {
return new ElementTag(sourceType);
}
else if (name.equals("command_block_location") && serverEvent != null && serverEvent.getSender() instanceof BlockCommandSender) {
return new LocationTag(((BlockCommandSender) serverEvent.getSender()).getBlock().getLocation());
}
else if (name.equals("command_minecart") && serverEvent != null && serverEvent.getSender() instanceof CommandMinecart) {
return new EntityTag((CommandMinecart) serverEvent.getSender());
}
return super.getContext(name);
}
@EventHandler
public void onPlayerEvent(PlayerCommandPreprocessEvent event) {
this.playerEvent = event;
this.serverEvent = null;
this.fullMessage = event.getMessage();
this.commandName = fullMessage.split(" ")[0].substring(1);
this.location = event.getPlayer().getLocation();
this.sourceType = "player";
fire(event);
}
@Override
public void cancellationChanged() {
if (cancelled && serverEvent != null) {
serverEvent.setCommand("denizen do_nothing");
}
super.cancellationChanged();
}
@EventHandler
public void onServerEvent(ServerCommandEvent event) {
this.playerEvent = null;
this.serverEvent = event;
this.fullMessage = event.getCommand();
this.commandName = fullMessage.split(" ")[0];
if (event.getSender() instanceof BlockCommandSender) {
this.location = ((BlockCommandSender) event.getSender()).getBlock().getLocation();
this.sourceType = "command_block";
}
else if (event.getSender() instanceof CommandMinecart) {
this.location = ((CommandMinecart) event.getSender()).getLocation();
this.sourceType = "command_minecart";
}
else {
this.location = null;
this.sourceType = "server";
}
fire(event);
}
}