|
|
@ -1,9 +1,10 @@ |
|
|
|
package de.yannicpunktdee.yoshibot.command; |
|
|
|
|
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
import de.yannicpunktdee.yoshibot.command.YoshiCommandDistributor.Action; |
|
|
|
import de.yannicpunktdee.yoshibot.command.commands.SauceCommand; |
|
|
|
import de.yannicpunktdee.yoshibot.main.SauceProvider; |
|
|
|
import de.yannicpunktdee.yoshibot.main.YoshiBot; |
|
|
|
import net.dv8tion.jda.api.entities.Guild; |
|
|
|
import net.dv8tion.jda.api.entities.TextChannel; |
|
|
@ -12,21 +13,22 @@ import net.dv8tion.jda.api.entities.VoiceChannel; |
|
|
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;; |
|
|
|
|
|
|
|
/** |
|
|
|
* Parst einen Eingabestring, entscheidet ob er ein Kommando ist und zerlegt ihn in seine Bestandteile. |
|
|
|
* Kommandos besitzen einen Status, der Auskunft gibt, ob Fehler beim Parsen des Eingabestrings aufgetreten |
|
|
|
* sind oder der String gar kein Kommando war. Außerdem wird bei erfolgreich geparsten Kommandos eine Aktion |
|
|
|
* festgelegt, die das Kommando ausführen soll, sowie die Argumente mit welcher das Kommando ausgeführt wird. |
|
|
|
* Außerdem enthalten ist eine Referenz auf Ursprungs-User und -TextChannel. |
|
|
|
* Parst einen Eingabestring, entscheidet ob er ein Kommando ist und zerlegt ihn in seine Bestandteile. Kommandos |
|
|
|
* besitzen einen Status, der Auskunft gibt, ob Fehler beim Parsen des Eingabestrings aufgetreten sind oder der String |
|
|
|
* gar kein Kommando war. Außerdem wird bei erfolgreich geparsten Kommandos eine Aktion festgelegt, die das Kommando |
|
|
|
* ausführen soll, sowie die Argumente mit welcher das Kommando ausgeführt wird. Außerdem enthalten ist eine Referenz |
|
|
|
* auf Ursprungs-User und -TextChannel. |
|
|
|
* |
|
|
|
* @author Yannic Link |
|
|
|
*/ |
|
|
|
public class YoshiCommandContext { |
|
|
|
|
|
|
|
/** |
|
|
|
* Repräsentiert einen Status, den eine YoshiCommand-Instanz hat, nachdem der Eingabestring eingelesen |
|
|
|
* und geparst wurde. Sofern der Status nicht OK ist, ist diese Instanz entweder kein Kommando oder |
|
|
|
* besitzt eine fehlerhafte Syntax. |
|
|
|
* Repräsentiert einen Status, den eine YoshiCommand-Instanz hat, nachdem der Eingabestring eingelesen und geparst |
|
|
|
* wurde. Sofern der Status nicht OK ist, ist diese Instanz entweder kein Kommando oder besitzt eine fehlerhafte |
|
|
|
* Syntax. |
|
|
|
*/ |
|
|
|
public static enum State { |
|
|
|
public enum State { |
|
|
|
/** |
|
|
|
* Das Kommando wurde erfolgreich geparst und besitzt keine Syntaxfehler. |
|
|
|
*/ |
|
|
@ -48,10 +50,11 @@ public class YoshiCommandContext { |
|
|
|
*/ |
|
|
|
BAD_SYNTAX |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Hilfskonstrukt. Beschreibt den Zustand vom Parser. |
|
|
|
*/ |
|
|
|
private static enum ReadingState{ |
|
|
|
private enum ReadingState { |
|
|
|
/** |
|
|
|
* Der Parser ist dabei festzustellen, ob es sich um ein Kommando handelt. |
|
|
|
*/ |
|
|
@ -84,7 +87,9 @@ public class YoshiCommandContext { |
|
|
|
* Der Parser liest gerade einen zusammenhängenden Argumentenwert ein. |
|
|
|
*/ |
|
|
|
READING_STRING |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
@ -105,43 +110,48 @@ public class YoshiCommandContext { |
|
|
|
*/ |
|
|
|
private Map<String, String> arguments; |
|
|
|
|
|
|
|
private List<String> argumentList; |
|
|
|
|
|
|
|
private MessageReceivedEvent event; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Erzeugt aus einem unbearbeiteten Eingabestring ein Kommando. Nach dem parsen enthält die state-Variable |
|
|
|
* den Endzustand des Parsers. |
|
|
|
* Erzeugt aus einem unbearbeiteten Eingabestring ein Kommando. Nach dem parsen enthält die state-Variable den |
|
|
|
* Endzustand des Parsers. |
|
|
|
* |
|
|
|
* @param argumentsString Ein unbearbeiteter Eingabestring |
|
|
|
* @param user Der Benutzer, der das Kommando geschickt hat. |
|
|
|
* @param channel Der Textchannel in den das Kommando geschickt wurde. |
|
|
|
*/ |
|
|
|
public YoshiCommandContext(String argumentsString, MessageReceivedEvent event) { |
|
|
|
this.event = event; |
|
|
|
|
|
|
|
argumentsString = argumentsString.trim(); |
|
|
|
|
|
|
|
arguments = new HashMap<String, String>(); |
|
|
|
argumentList = new ArrayList<>(); |
|
|
|
argumentList.addAll(Arrays.asList(argumentsString.split(" "))); |
|
|
|
argumentList.remove(0); |
|
|
|
|
|
|
|
arguments = new HashMap<>(); |
|
|
|
|
|
|
|
ReadingState readingState = ReadingState.VERIFYING; |
|
|
|
String currentKey = null; |
|
|
|
int startPos = 0; |
|
|
|
int length = argumentsString.length(); |
|
|
|
|
|
|
|
for(int position = 0; position < length; position++) { |
|
|
|
for (int position = 0; position < length; position++) { |
|
|
|
char currentChar = argumentsString.charAt(position); |
|
|
|
|
|
|
|
switch(readingState) { |
|
|
|
switch (readingState) { |
|
|
|
case VERIFYING: |
|
|
|
if(!Character.isWhitespace(currentChar)) continue; |
|
|
|
if(!argumentsString.substring(0, position).equals(PREFIX)) { |
|
|
|
if (!Character.isWhitespace(currentChar)) continue; |
|
|
|
if (!argumentsString.substring(0, position).equals(PREFIX)) { |
|
|
|
state = State.NO_COMMAND; |
|
|
|
return; |
|
|
|
} |
|
|
|
readingState = ReadingState.AFTER_VERIFY; |
|
|
|
continue; |
|
|
|
case AFTER_VERIFY: |
|
|
|
if(Character.isWhitespace(currentChar)) continue; |
|
|
|
if(currentChar == '-'){ |
|
|
|
if (Character.isWhitespace(currentChar)) continue; |
|
|
|
if (currentChar == '-') { |
|
|
|
state = State.NO_ACTION; |
|
|
|
return; |
|
|
|
} |
|
|
@ -149,18 +159,18 @@ public class YoshiCommandContext { |
|
|
|
readingState = ReadingState.READING_ACTION; |
|
|
|
continue; |
|
|
|
case READING_ACTION: |
|
|
|
if(!Character.isWhitespace(currentChar)) continue; |
|
|
|
try{ |
|
|
|
if (!Character.isWhitespace(currentChar)) continue; |
|
|
|
try { |
|
|
|
action = Action.valueOf(argumentsString.substring(startPos, position).toUpperCase()); |
|
|
|
readingState = ReadingState.INTERMEDIATE; |
|
|
|
} catch(IllegalArgumentException e) { |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
state = State.UNKNOWN_ACTION; |
|
|
|
return; |
|
|
|
} |
|
|
|
continue; |
|
|
|
case INTERMEDIATE: |
|
|
|
if(Character.isWhitespace(currentChar)) continue; |
|
|
|
if(currentChar != '-' || currentChar == '"') { |
|
|
|
if (Character.isWhitespace(currentChar)) continue; |
|
|
|
if ((currentChar != '-' || currentChar == '"') && action != Action.SAUCE) { |
|
|
|
state = State.BAD_SYNTAX; |
|
|
|
return; |
|
|
|
} |
|
|
@ -168,17 +178,17 @@ public class YoshiCommandContext { |
|
|
|
readingState = ReadingState.READING_KEY; |
|
|
|
continue; |
|
|
|
case READING_KEY: |
|
|
|
if(!Character.isWhitespace(currentChar)) continue; |
|
|
|
if (!Character.isWhitespace(currentChar)) continue; |
|
|
|
currentKey = argumentsString.substring(startPos, position); |
|
|
|
readingState = ReadingState.AFTER_KEY; |
|
|
|
continue; |
|
|
|
case AFTER_KEY: |
|
|
|
if(Character.isWhitespace(currentChar)) continue; |
|
|
|
if(currentChar == '-') { |
|
|
|
if (Character.isWhitespace(currentChar)) continue; |
|
|
|
if (currentChar == '-') { |
|
|
|
arguments.put(currentKey, null); |
|
|
|
startPos = position + 1; |
|
|
|
readingState = ReadingState.READING_KEY; |
|
|
|
} else if(currentChar == '"'){ |
|
|
|
} else if (currentChar == '"') { |
|
|
|
startPos = position + 1; |
|
|
|
readingState = ReadingState.READING_STRING; |
|
|
|
} else { |
|
|
@ -187,36 +197,36 @@ public class YoshiCommandContext { |
|
|
|
} |
|
|
|
continue; |
|
|
|
case READING_VALUE: |
|
|
|
if(!Character.isWhitespace(currentChar)) continue; |
|
|
|
if (!Character.isWhitespace(currentChar)) continue; |
|
|
|
arguments.put(currentKey, argumentsString.substring(startPos, position)); |
|
|
|
readingState = ReadingState.INTERMEDIATE; |
|
|
|
continue; |
|
|
|
case READING_STRING: |
|
|
|
if(currentChar != '"') continue; |
|
|
|
if(argumentsString.charAt(position - 1) == '\\') continue; |
|
|
|
if (currentChar != '"') continue; |
|
|
|
if (argumentsString.charAt(position - 1) == '\\') continue; |
|
|
|
arguments.put(currentKey, argumentsString.substring(startPos, position)); |
|
|
|
readingState = ReadingState.INTERMEDIATE; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
switch(readingState) { |
|
|
|
switch (readingState) { |
|
|
|
case INTERMEDIATE: |
|
|
|
state = State.OK; |
|
|
|
return; |
|
|
|
case VERIFYING: |
|
|
|
if(argumentsString.equals(PREFIX)) { |
|
|
|
if (argumentsString.equals(PREFIX)) { |
|
|
|
action = Action.HELP; |
|
|
|
state = State.OK; |
|
|
|
}else { |
|
|
|
} else { |
|
|
|
state = State.NO_COMMAND; |
|
|
|
} |
|
|
|
return; |
|
|
|
case READING_ACTION: |
|
|
|
try{ |
|
|
|
try { |
|
|
|
action = Action.valueOf(argumentsString.substring(startPos).toUpperCase()); |
|
|
|
readingState = ReadingState.INTERMEDIATE; |
|
|
|
} catch(IllegalArgumentException e) { |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
state = State.UNKNOWN_ACTION; |
|
|
|
return; |
|
|
|
} |
|
|
@ -248,36 +258,42 @@ public class YoshiCommandContext { |
|
|
|
public State getState() { |
|
|
|
return state; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Gibt die im Kommando spezifizierte Aktion zurück. null, wenn status fehlerhaft oder kein Kommando. |
|
|
|
*/ |
|
|
|
public Action getAction() { |
|
|
|
return action; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Prüft, ob das Kommando mit Argumenten aufgerufen wurde. |
|
|
|
*/ |
|
|
|
public boolean hasArguments() { |
|
|
|
return !arguments.isEmpty(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Prüft, ob alle Key-Werte in der Argumentenliste vorhanden sind. |
|
|
|
* |
|
|
|
* @param args Liste von den auf Existenz zu überprüfenden Argumenten. |
|
|
|
*/ |
|
|
|
public boolean containsArguments(String[] args) { |
|
|
|
for(String arg : args) { |
|
|
|
if(!arguments.containsKey(arg)) { |
|
|
|
for (String arg : args) { |
|
|
|
if (!arguments.containsKey(arg)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Gibt den Wert eines Arguments zurück. |
|
|
|
* |
|
|
|
* @param arg Name des Arguments. |
|
|
|
*/ |
|
|
|
public String getArgument(String arg) { |
|
|
|
if(!arguments.containsKey(arg)) return null; |
|
|
|
if (!arguments.containsKey(arg)) return null; |
|
|
|
return arguments.get(arg); |
|
|
|
} |
|
|
|
|
|
|
@ -285,4 +301,8 @@ public class YoshiCommandContext { |
|
|
|
return event; |
|
|
|
} |
|
|
|
|
|
|
|
public List<String> getArguments() { |
|
|
|
return this.argumentList; |
|
|
|
} |
|
|
|
|
|
|
|
} |