Add tab completion to the jail command #77

Tried to make the tab complete pretty smart, there probably are several
issues with it but first round of testing should be good to go!
This commit is contained in:
graywolf336 2015-06-29 22:46:36 -05:00
parent a602bf77fe
commit c22f1ec22d
6 changed files with 114 additions and 18 deletions

View File

@ -78,7 +78,7 @@ public class JailIO {
try {
Lang.getFile().save(new File(pl.getDataFolder(), "en.yml"));
} catch (IOException e) {
pl.getLogger().severe("Unable to save the language file: " + e.getMessage());
pl.getLogger().severe("Unable to save the language file: " + e.getMessage() + " (" + e.getClass().getSimpleName() + ")");
}
}
}
@ -1271,7 +1271,7 @@ public class JailIO {
ResultSet set = ps.executeQuery();
while(set.next()) {
entries.add(Lang.RECORDENTRY.get(new String[] { set.getString("date"), set.getString("username"), set.getString("jailer"), String.valueOf(set.getLong("time")), set.getString("reason") }));
entries.add(Lang.RECORDENTRY.get(new String[] { set.getString("date"), set.getString("username"), set.getString("jailer"), String.valueOf(set.getLong("time")), set.getString("reason"), set.getString("uuid") }));
}
set.close();

View File

@ -211,6 +211,10 @@ public class JailMain extends JavaPlugin {
return cmdHand.parseTabComplete(jm, sender, command.getName().toLowerCase(), args);
}
}catch(Exception e) {
if(this.debug)
e.printStackTrace();
debug(e.getClass().getSimpleName() + " occured while providing tab complete: " + e.getMessage());
return Collections.emptyList();
}
}

View File

@ -8,7 +8,6 @@ import java.util.Map.Entry;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.graywolf336.jail.JailMain;
import com.graywolf336.jail.JailManager;
@ -87,19 +86,29 @@ public class JailHandler {
//Sort the results before adding the player names
Collections.sort(results);
//Don't send out all the players if they don't have jail permission
if(hasJailPermission)
for(Player p : jm.getPlugin().getServer().getOnlinePlayers())
if(arg0.isEmpty() || StringUtil.startsWithIgnoreCase(p.getName(), arg0))
results.add(p.getName());
return results;
//If the results doesn't contain anything and they have permission to jail someone
//then send let the jail command provide the tab completion
if(results.isEmpty() && hasJailPermission)
return getMatches("jail").get(0).provideTabCompletions(jm, sender, args);
else
return results;
}else {
String arg0 = args[0].toLowerCase();
boolean hasJailPermission = false;
for(Command c : commands.values()) {
CommandInfo i = c.getClass().getAnnotation(CommandInfo.class);
//since the pattern won't ever match the jail plugin
//we can skip it but first we need to see if they have
//permission to do the jailing
if(i.pattern().equalsIgnoreCase("jail|j")) {
hasJailPermission = sender.hasPermission(i.permission());
continue;
}
if(!arg0.toLowerCase().matches(i.pattern())) continue;
//Sender provided too many arguments which means there
//is nothing to tab complete
if(i.maxArgs() != -1 && i.maxArgs() < args.length - 1) continue;
@ -110,10 +119,14 @@ public class JailHandler {
//If the sender doesn't have permission, we won't send them further
if(!sender.hasPermission(i.permission())) continue;
if(arg0.toLowerCase().matches(i.pattern())) {
return c.provideTabCompletions(jm, sender, args);
}
return c.provideTabCompletions(jm, sender, args);
}
//By the time it has reached here no other command matched
//which means they are probably jailing someone, or trying to
//so let's check permission first and go from there.
if(hasJailPermission)
return getMatches("jail").get(0).provideTabCompletions(jm, sender, args);
}
return Collections.emptyList();

View File

@ -1,14 +1,18 @@
package com.graywolf336.jail.command.subcommands;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.graywolf336.jail.JailManager;
import com.graywolf336.jail.Util;
@ -34,6 +38,8 @@ import com.lexicalscope.jewel.cli.CliFactory;
usage = "/jail [name] (-t time) (-j JailName) (-c CellName) (-a AnyCell) (-m Muted) (-r A reason for jailing)"
)
public class JailCommand implements Command {
private static final String noJailPermission = "jail.cantbejailed";
private List<String> commands = Arrays.asList(new String[] { "p", "t", "i", "j", "c", "a", "m", "r" });
/*
* Executes the command. Checks the following:
@ -47,7 +53,6 @@ public class JailCommand implements Command {
* - If the prisoner is online or not.
*/
public boolean execute(JailManager jm, CommandSender sender, String... args) {
if(jm.getJails().isEmpty()) {
sender.sendMessage(Lang.NOJAILS.get());
return true;
@ -86,7 +91,7 @@ public class JailCommand implements Command {
//If the player instance is not null and the player has the permission
//'jail.cantbejailed' then don't allow this to happen
if(p != null && p.hasPermission("jail.cantbejailed")) {
if(p != null && p.hasPermission(noJailPermission)) {
sender.sendMessage(Lang.CANTBEJAILED.get());
return true;
}
@ -256,7 +261,81 @@ public class JailCommand implements Command {
}
public List<String> provideTabCompletions(JailManager jm, CommandSender sender, String... args) throws Exception {
//TODO implement (this'll take a while)
//by the time it gets to this command it'll have at least two arguments
String last = args[args.length - 1];
if(last.isEmpty() || !commands.contains(last.replace("-", ""))) {
//the current part is empty. Need to look at their previous
//item and if it is a valid option, then provide them a valid tab complete option
if(args.length - 2 > -1) {
String previous = args[args.length - 2];
jm.getPlugin().debug("args[args.length - 2]: " + previous);
if(previous.equalsIgnoreCase("-p")) return getPlayers(jm, "");
else if(previous.equalsIgnoreCase("-j")) return jm.getJailsByPrefix("");
else if(previous.equalsIgnoreCase("-c")) {
//Since we need to give them a list of the cells in a jail
//we need to get the jail they're giving
int jailIndex = ArrayUtils.indexOf(args, "-j");
if(jailIndex != -1) {
String jail = args[jailIndex + 1];
jm.getPlugin().debug("The jail is: " + jail);
if(jm.isValidJail(jail)) return getCells(jm, jail, "");
}
}else if(previous.endsWith("r")) return Collections.emptyList();
else if(!commands.contains(args[args.length - 2].replace("-", ""))) return getUnusedCommands(args);
}
}else if(last.equalsIgnoreCase("-")) {
//add some smart checking so that it only returns a list of what isn't already
//in the command :)
return getUnusedCommands(args);
}else {
return getPlayers(jm, last);
}
return Collections.emptyList();
}
private List<String> getPlayers(JailManager jm, String first) {
List<String> results = new ArrayList<String>();
for(Player p : jm.getPlugin().getServer().getOnlinePlayers())
if(first.isEmpty() || StringUtil.startsWithIgnoreCase(p.getName(), first))
if(!jm.isPlayerJailed(p.getUniqueId()) && !p.hasPermission(noJailPermission)) //don't send back them if they're already jailed or can't be jailed
results.add(p.getName());
Collections.sort(results);
return results;
}
private List<String> getCells(JailManager jm, String jail, String cell) {
List<String> results = new ArrayList<String>();
for(Cell c : jm.getJail(jail).getCells())
if(!c.hasPrisoner())
if(cell.isEmpty() || StringUtil.startsWithIgnoreCase(c.getName(), cell))
results.add(c.getName());
Collections.sort(results);
return results;
}
private List<String> getUnusedCommands(String[] args) {
List<String> used = new ArrayList<String>();
for(String s : args)
if(s.contains("-"))
used.add(s.replace("-", ""));
List<String> unused = new ArrayList<String>();
for(String t : commands)
if(!used.contains(t) //don't add it if it is already used
&& !t.equalsIgnoreCase("p"))//don't add -p
unused.add("-" + t);
Collections.sort(unused);
return unused;
}
}

View File

@ -60,7 +60,7 @@ language:
jailed: '&cYou have been jailed!'
jailedwithreason: '&cYou have been jailed for: %0%'
muted: '&cStop talking, you are in jail.'
noemptycells: '&cNo empty cells were found for %0%, all them appear to be full.'
noemptycells: '&cNo empty cells were found for %0%, all of them appear to be full.'
noprisoners: '&9%0% is empty and contains no prisoners.'
notjailed: '&c%0% is not jailed.'
nowmuted: '&9%0% is now muted.'

View File

@ -104,7 +104,7 @@ public class TestJailLanguage {
assertEquals(colorize("&cYou have been jailed!"), Lang.JAILED.get());
assertEquals(colorize("&cYou have been jailed for: terrible coding"), Lang.JAILEDWITHREASON.get("terrible coding"));
assertEquals(colorize("&cStop talking, you are in jail."), Lang.MUTED.get());
assertEquals(colorize("&cNo empty cells were found for cloud, all them appear to be full."), Lang.NOEMPTYCELLS.get("cloud"));
assertEquals(colorize("&cNo empty cells were found for cloud, all of them appear to be full."), Lang.NOEMPTYCELLS.get("cloud"));
assertEquals(colorize("&9cloud is empty and contains no prisoners."), Lang.NOPRISONERS.get("cloud"));
assertEquals(colorize("&cgraywolf336 is not jailed."), Lang.NOTJAILED.get("graywolf336"));
assertEquals(colorize("&9graywolf336 is now muted."), Lang.NOWMUTED.get("graywolf336"));