-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommands.java
More file actions
324 lines (297 loc) · 11.9 KB
/
Commands.java
File metadata and controls
324 lines (297 loc) · 11.9 KB
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
/*
Class for responding to received messages and executing appropriate commands.
@Author: Jacob Gnatz
@Creation Date: 2019-11-22
@Last Update: 2020-7-4
*/
public class Commands extends ListenerAdapter {
//Instance Variables
private final String ID = "638867894431907850";
private final String PREFIX = "/";
private final String HELP = "help";
private final String HEAD = "head";
private final String[] COMMANDS = new String[] {HELP, HEAD};
private User prevAuth;
//Constructor
public Commands()
{
//Other instance variables are preset and final
prevAuth = null;
}
//Methods
/*
Main function for determining response to received messages.
@param event: The event contents of the received message.
*/
@Override
public void onMessageReceived(MessageReceivedEvent event)
{
//If prevAuth is null, no previous messages
if (prevAuth == null)
prevAuth = event.getAuthor();
//Prevent bot loops
if (event.getAuthor().isBot())
return;
//Store common event variables
Message msg = event.getMessage();
String content = event.getMessage().getContentRaw();
//Print to System
System.out.println("Message from " + event.getAuthor().getName()
+ ". Contents: " + event.getMessage().getContentRaw());
/*Message decoding*/
//Check for mention, call mention function
if (!msg.getMentionedUsers().isEmpty())
{
for (User user: msg.getMentionedUsers())
{
if (user.getId().equals(ID)) {
//Bot is mentioned
onMention(event);
break;
}
}
}
//Check for prefix, execute valid commands
else if(content.startsWith(PREFIX))
{
/*ADD MORE KEYWORDS HERE*/
if(content.startsWith(HELP, 1))
onHelp(event);
else if (content.startsWith(HEAD, 1))
onHead(event);
else
//No valid command entered
System.out.println("Invalid command received!");
}
else
//No mention or prefix found
System.out.println("No instructions received!");
//Update prevAuth to this author for next event
prevAuth = event.getAuthor();
}
/*
Method for helping users utilize CraftCrab on first use.
*/
public void onMention(MessageReceivedEvent event)
{
String prepend = "Hello fellow \uD83E\uDD80!\n" +
"To use my commands, type `/` proceeded by a command.";
String sendStr = commandBuilder(event, prepend);
event.getChannel().sendMessage(sendStr).queue();
}
/*
Method for helping users remember commands and explain their usage (if provided).
*/
public void onHelp(MessageReceivedEvent event)
{
//Split message into args
String[] args = splitIntoArgs(event);
//Check if user has provided any arguments
if (args.length > 1)
{
//Check for command keywords, print associated messages
/*ADD MORE KEYWORDS HERE*/
if (args[1].equals(HELP))
event.getChannel().sendMessage(explainHelp()).queue();
else if (args[1].equals(HEAD))
event.getChannel().sendMessage(explainHead()).queue();
else
//No valid keyword entered
event.getChannel().sendMessage(":x: `" + args[1] + "` is not a valid command!").queue();
}
//User has provided no arguments, print help message
else
{
String sendStr;
String prepend = "If you want help on a specific command, " +
"type `/help` proceeded by the command.";
sendStr = commandBuilder(event, prepend);
event.getChannel().sendMessage(sendStr).queue();
}
}
/*
Internal method for documenting the help function.
@return: String that doesn't really explain the help function.
*/
private String explainHelp()
{
return "Are you a scheming \uD83E\uDD9E? No infinite loops for you!";
}
/*
Method for splitting a give command from https://minecraft-heads.com/ into usable NBT
data for an in-game data parser. Prints a message with instructions and extracted
data components.
*/
public void onHead(MessageReceivedEvent event)
{
//Split message into args
String[] args = splitIntoArgs(event);
//Check if user has provided any args
if (args.length > 1)
{
//Check if arguments match a give playerhead command
if (checkHeadArguments(event))
{
//All arguments and keywords present, print decoupled message
event.getChannel().sendMessage(sendHeadMessage(event)).queue();
}
//Arguments do not match a give playerhead command, print help message
else
{
event.getChannel().sendMessage(":x: Incorrect command given!\nType `/help head` for usage.").queue();
}
}
//User has provided no arguments, print help message
else
{
event.getChannel().sendMessage(":x: No command given!\nType `/help head` for usage.").queue();
}
}
/*
Internal method for checking user's provided arguments for the head command.
Note: This method will break if Mojang changes their give command formatting or NBT data formatting.
@return: Boolean validating this commands arguments.
*/
private boolean checkHeadArguments(MessageReceivedEvent event)
{
//Validation info
String give = "/give";
String atP = "@p";
String playerhead = "minecraft:player_head";
String display = "display";
String name = "Name";
String skullowner = "SkullOwner";
String id = "Id";
String properties = "Properties";
String textures = "textures";
String value = "Value";
String[] keywords = new String[] {display, name, skullowner, id, properties, textures, value};
//Split message into args, message
String[] args = splitIntoArgs(event);
String msg = event.getMessage().getContentRaw();
//Validate initial args
if (args[1].equals(give) &&
args[2].equals(atP) &&
args[3].startsWith(playerhead))
{
//Validate message contains keywords
for (String keyword : keywords)
{
if (!(msg.contains(keyword)))
{
//Failed to find essential keyword
System.out.println("checkHeadArguments: Did not find keyword: " + keyword);
return false;
}
}
//All keywords found, return true
return true;
}
//Invalid initial args
else
{
System.out.println("checkHeadArguments: Invalid initial args!");
return false;
}
}
/*
Internal method for extracting key values from a give command for formatting later.
Assumes checkHeadArguments() returned true.
Note: This method will break if Mojang changes their give command formatting or NBT data formatting.
@return: String array with key values.
*/
private String[] decoupleHeadArguments(MessageReceivedEvent event)
{
//Extract and modify give command message
String cmd = event.getMessage().getContentRaw();
cmd = cmd.substring(cmd.indexOf("minecraft:"));
String[] keyValues = cmd.split(",");
//Extract and modify display name
keyValues[0] = keyValues[0].substring(keyValues[0].indexOf("display:{Name:\"")+15, keyValues[0].indexOf("}") + 1);
keyValues[0] = keyValues[0].replaceAll("\\\\", "");
//Extract and modify the 4 skullowner ID values
for (int i = 1; i < 5; i++) {
keyValues[i] = keyValues[i].replaceAll("[^\\d-]", "");
}
//Extract and modify texture value
keyValues[5] = keyValues[5].substring(keyValues[5].indexOf("Value:\"")+7, keyValues[5].indexOf("}"));
keyValues[5] = keyValues[5].replaceAll("\"", "");
//Return keyValues
return keyValues;
}
/*
Internal method for formatting a message for player usage from key values.
Note: This method was changed for 1.16, and uses an unorganized keyValues array.
@return: String of the formatted keyvalues and basic instructions.
*/
private String sendHeadMessage(String[] keyValues, MessageReceivedEvent event)
{
int chatCount = 0, pageCount = 0;
String sendStr = "Hello <@" + event.getAuthor().getId() + ">! Here are your head values:\n" +
"**Chat Menu Values:**\n" +
"UUID " + ++chatCount + ": " + keyValues[1] + "\n" +
"UUID " + ++chatCount + ": " + keyValues[2] + "\n" +
"UUID " + ++chatCount + ": " + keyValues[3] + "\n" +
"UUID " + ++chatCount + ": " + keyValues[4] + "\n" +
"**Lectern Values:**\n" +
"Page " + ++pageCount + ": " + keyValues[0] + "\n" +
"Page " + ++pageCount + ": " + keyValues[5] + "\n";
return sendStr;
}
/*
Public method for returning the formatted head message.
@return: String of the formatted keyvalues and basic instructions.
*/
public String sendHeadMessage(MessageReceivedEvent event)
{
return sendHeadMessage(decoupleHeadArguments(event), event);
}
/*
Internal method for documenting the head function.
@return: String that explains to the user the head function.
*/
private String explainHead()
{
return "`/head (give command)`\n" +
"**Description:** Returns a message with the values necessary to generate a playerhead based on the given playerhead command.\n\n" +
"**How to use:**\n" +
"1) Go to https://minecraft-heads.com/custom-heads and browse for a head decoration you would like to use.\n" +
"2) Copy the `Give-Code` field on the head's page (Note: you must copy the entire code within the field.)\n" +
"3) Type `/head` and paste your give code.\n\n" +
"A message will be then be returned that contains the values necessary for using the head generator shrine.\n" +
"Questions? See #player-heads for more info.";
}
private String[] splitIntoArgs(MessageReceivedEvent event)
{
return event.getMessage().getContentRaw().split(" ");
}
/*
Internal method for building the list of commands this class currently implements.
@return: String representing a list of current commands.
*/
private String commandBuilder(MessageReceivedEvent event)
{
StringBuilder reStrB = new StringBuilder();
reStrB.append("Current commands are: ");
for (String cmd : COMMANDS)
{
reStrB.append("`" + cmd + "`, ");
}
reStrB.replace(reStrB.length()-2, reStrB.length(), ".");
String reStr = reStrB.toString();
return reStr;
}
/*
Internal method for building a list of commands this class currently implements.
Includes a prepended message to the list in a previous line.
@return: String of current commands with a prepended message.
*/
private String commandBuilder(MessageReceivedEvent event, String prepend)
{
return prepend + "\n" + (commandBuilder(event));
}
}