Skip to content

Instantly share code, notes, and snippets.

@aikar
Last active November 2, 2024 00:54
Empire Command SystemFramework licensed MIT - WORK TO MAKE THIS A LIBRARY: https://github.com/aikar/commands
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandAlias {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandCompletion {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermission {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Default {
String value() default "";
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Flags {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Optional {
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Don't join remaining arguments
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Single {}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Split {
String value() default ",";
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Subcommand {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Syntax {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Values {
String value();
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands;
import com.empireminecraft.config.EmpireServer;
import com.empireminecraft.config.PlayerSettingKey;
import com.empireminecraft.data.EmpireUser;
import com.empireminecraft.features.friends.Friend;
import com.empireminecraft.features.items.CustomItems;
import com.empireminecraft.features.survival.mobs.CustomMob;
import com.empireminecraft.systems.db.DbRow;
import com.empireminecraft.systems.db.EmpireDb;
import com.empireminecraft.systems.residence.TagManager;
import com.empireminecraft.systems.residence.protection.Residence;
import com.empireminecraft.systems.residence.protection.ResidenceFlag;
import com.empireminecraft.systems.residence.protection.ResidenceFlags;
import com.empireminecraft.systems.residence.protection.ResidenceStore;
import com.empireminecraft.util.NumUtil;
import com.empireminecraft.util.Patterns;
import com.empireminecraft.util.UserUtil;
import com.empireminecraft.util.Util;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public final class CommandCompletions {
private CommandCompletions() {}
private static final List<String> EMPTY = ImmutableList.of();
public static List<String> of(CommandSender sender, String completion, String input) {
if (completion == null) {
return ImmutableList.of();
}
String[] complete = Patterns.COLON.split(completion, 2);
switch (complete[0]) {
case "@promos":
try {
final List<DbRow> rows = EmpireDb.getResults("SELECT name, enabled FROM promos");
final List<String> promos = new ArrayList<>();
rows.stream()
.filter(row -> (
complete.length == 2 && "all".equals(complete[1]))
|| ((Integer) 1).equals(row.get("enabled")))
.forEach(row -> promos.add(row.get("name")));
return promos;
} catch (SQLException e) {
Util.sendMsg(sender, "&cError getting promotions");
Util.printException("Exception in getting promos", e);
}
break;
case "@friends": {
if ((sender instanceof Player)) {
final Player player = (Player) sender;
final EmpireUser user = player.getUser();
return user.getFriendsList()
.getFriends()
.valueCollection()
.stream()
.map(Friend::getFriendName)
.collect(Collectors.toList());
}
break;
}
case "@bannedplayers":
if (!(sender instanceof Player) || UserUtil.isModerator((Player) sender)) {
try {
return EmpireDb.getFirstColumnResults(
"SELECT u.name FROM user_ban b JOIN user u ON b.user_id = u.user_id WHERE " +
"u.name LIKE ?", input + "%");
} catch (SQLException e) {
e.printStackTrace();
}
return ImmutableList.of();
}
break;
case "@flags":
final Collection<ResidenceFlag> allFlags = ResidenceFlags.getFlags();
List<String> flags = Lists.newArrayListWithExpectedSize(allFlags.size() * 2);
allFlags.forEach(flag -> {
if (flag.subFlags.isEmpty()) {
if (flag.parent == null) { // ignore subflags since they are in allFlags map
flags.add(flag.name);
}
} else {
flags.addAll(flag.subFlags.stream()
.map(sflag -> flag.name + ":" + sflag.name)
.collect(Collectors.toList()));
}
});
return flags;
case "@biomes":
return Residence.getAllowedBiomes(false);
case "@flagstates":
return ImmutableList.of("true","t","false","f","remove","r");
case "@residences":
List<String> list = Lists.newArrayList();
list.addAll(ResidenceStore.nameMap.keySet());
if (!input.isEmpty()) {
String first = input.substring(0, 1);
if (NumUtil.isNumber(first)) {
list.addAll(ResidenceStore.addrMap.keySet().stream().map(String::valueOf).collect(Collectors.toList()));
} else if ("+".equals(first)) {
list.addAll(TagManager.tagMap.keySet().stream().map((tag) -> "+" + tag).collect(Collectors.toList()));
}
}
return list;
case "@range":
if (complete.length == 1) {
return ImmutableList.of();
}
final String[] ranges = Patterns.DASH.split(complete[1]);
int start;
int end;
if (ranges.length != 2) {
start = 0;
end = Util.parseInt(ranges[0], 0);
} else {
start = Util.parseInt(ranges[0], 0);
end = Util.parseInt(ranges[1], 0);
}
return IntStream.rangeClosed(start, end).mapToObj(Integer::toString).collect(Collectors.toList());
case "@timeunits":
return ImmutableList.of("hours", "days", "weeks", "months", "minutes");
case "@allplayers":
return EmpireUser.lookupNames(input,
complete.length > 1 ? Util.parseInt(complete[1]) : null);
case "@rareitems":
return Lists.newArrayList(CustomItems.customItems.keySet());
case "@mobs":
final Stream<String> normal = Stream.of(EntityType.values())
.map(entityType -> Util.simplifyString(entityType.getName()));
final Stream<String> custom = CustomMob.allTypes.values().stream()
.map(customMob -> Util.simplifyString(customMob.customType));
return Stream.concat(normal, custom).collect(Collectors.toList());
case "@psetting":
return Stream.of(PlayerSettingKey.values()).map((key) -> key.key).collect(Collectors.toList());
case "@staffplayers":
return Util.nullDefault(EmpireUser.lookupStaff(input), EMPTY);
case "@servers":
return Util.enumNames(EmpireServer.values());
default:
return Lists.newArrayList(Patterns.PIPE.split(completion));
}
return EMPTY;
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands;
import com.empireminecraft.commands.features.*;
import com.empireminecraft.commands.misc.*;
import com.empireminecraft.commands.staff.*;
import org.bukkit.Bukkit;
public final class Commands {
private Commands() {}
public static void initialize() {
new ForumPassCommand();
new ChatCommand();
new VoteCommand();
new WasteCommand();
new FrontierCommand();
new WasteNetherCommand();
new FrontierNetherCommand();
new PlayerSettingCommand();
new AssistantCommand();
new MapCommand();
new CurrencyCommand();
new ReportCommand();
new ResidenceCommand();
new VaultCommand();
new FriendsCommand();
// Staff Commands
new GoToCommand();
new ModCommands();
new EMCBotCommands();
new SrStaffCommands();
new ModeCommand();
new GriefLogCommand();
// Misc
new OtherPluginsCommands();
new PlayerInfoCommand();
new PlayerNoteCommand();
new StaffCommand();
new MiscCommands();
new ServerCommand();
new HelpCommand();
new CompassCommand();
// RCON / CommandQueue
new BackendCommands();
Bukkit.getServer().getCommandMap().register("empire", new EnchantCommand());
EnchantCommand.buildEnchantments();
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.misc;
import com.empireminecraft.commands.EmpireCommand;
import com.empireminecraft.commands.annotation.CommandAlias;
import com.empireminecraft.commands.annotation.Default;
import com.empireminecraft.commands.annotation.Subcommand;
import com.empireminecraft.config.EmpireServer;
import com.empireminecraft.data.Worlds;
import com.empireminecraft.systems.Formatting;
import com.empireminecraft.systems.db.DbRow;
import com.empireminecraft.systems.db.EmpireDb;
import com.empireminecraft.systems.outposts.Frontier;
import com.empireminecraft.systems.outposts.Wastelands;
import com.empireminecraft.systems.residence.protection.Residence;
import com.empireminecraft.systems.residence.protection.ResidenceStore;
import com.empireminecraft.util.*;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.sql.SQLException;
import java.util.List;
import static com.empireminecraft.systems.Formatting.*;
import static com.empireminecraft.util.Util.printException;
@CommandAlias("comp|location|loc")
public class CompassCommand extends EmpireCommand {
public CompassCommand() {
super("compass");
}
@Subcommand("set")
public static void setCompass(Player player, Integer x, Integer z) {
final World world = player.getWorld();
if (!Worlds.isWilderness(world)) {
Util.sendMsg(player, COL_ERR + "Compass targets may only be set in the overworld.");
}
player.setCompassTarget(new Location(player.getWorld(), x, 64, z));
Util.sendMsg(player, COL_PRI + "Set compass target to " + COL_SEC + x + "," + z);
}
@Subcommand("bed")
public static void bedCompass(Player player) {
World world = player.getWorld();
Location bedLoc = player.getBedSpawnLocation();
if (bedLoc == null) {
Util.sendMsg(player, COL_ERR + "You do not have a valid bed spawn set");
return;
}
if (world != bedLoc.getWorld()) {
Util.sendMsg(player, COL_ERR + "Wrong World. Bed is in world &f" + bedLoc.getWorld().getName());
return;
}
if (!Worlds.isWilderness(world)) {
Util.sendMsg(player, COL_ERR + "Compass targets may only be set in the overworld.");
}
player.setCompassTarget(bedLoc);
Util.sendMsg(player, COL_PRI + "&aSet compass target to " + COL_SEC + Util.formatLocation(bedLoc));
}
@Subcommand("spawn|outpost")
public static void spawnCompass(Player player) {
Location loc = setSpawnCompass(player);
if (loc != null) {
Util.sendMsg(player, COL_PRI + "&aSet compass target to " + COL_SEC + Util.formatLocation(loc));
}
}
public static Location setSpawnCompass(Player player) {
final World world = player.getWorld();
if (!Worlds.isWilderness(world)) {
Util.sendMsg(player, COL_ERR + "Compass targets may only be set in the overworld.");
return null;
}
Location loc = world.getSpawnLocation();
if (Worlds.isWastelands(world)) {
loc = Wastelands.getCurrentRegion(player.getLocation()).getSpawnLocation(world);
} else if (Worlds.isFrontier(world) && Worlds.isPrimaryWorld(world)) {
loc = Frontier.getNearestOutpost(player.getLocation()).center;
} else if (world == Worlds.TOWN) {
List<Residence> resList = ResidenceStore.getByOwner(player.getUserId());
if (!resList.isEmpty()) {
loc = resList.get(0).getTPLoc();
}
}
player.setCompassTarget(loc);
return loc;
}
@Subcommand("distance|dis")
public static void onDistance(Player player) {
double distance = Util.distance2d(player.getLocation(), player.getCompassTarget());
Util.sendMsg(player, COL_PRI + "Distance to compass target is " + COL_SEC + Util.round(distance, 2));
}
@Subcommand("death")
public static void deathCompass(final Player player) {
final Long userId = player.getUserId();
final Integer serverId = EmpireServer.getServerId();
BukkitUtil.runTaskAsync( () -> {
try {
DbRow row = EmpireDb.getFirstRow("SELECT * FROM log_death WHERE user_id=? AND server_id=? ORDER BY time DESC LIMIT 1", userId, serverId);
if (row == null) {
Util.sendMsg(player, "&cYou have not died on this server... yet!");
return;
}
String[] msg = Patterns.SPACE_DASH_SPACE.split(row.get("death_message"));
Location deathLoc = Util.stringToLocation(msg[0]);
World world = player.getWorld();
if (world != deathLoc.getWorld()) {
Util.sendMsg(player, COL_ERR + "Wrong World. Last death is in world &f" + deathLoc.getWorld().getName());
return;
}
if (!Worlds.isWilderness(world)) {
Util.sendMsg(player, COL_ERR + "Compass targets may only be set in the overworld.");
}
player.setCompassTarget(deathLoc);
Util.sendMsg(player, COL_PRI + "&aSet compass target to " + COL_SEC + Util.formatLocation(deathLoc));
} catch (SQLException e) {
printException("Exception in deathCompass: " + player.getName(), e);
Util.sendMsg(player, "&cUnknown error.");
}
});
}
@CommandAlias("direction|dir")
public static void onDirection(Player player) {
String direction;
float yaw = player.getLocation().getYaw();
if (yaw < 0) { yaw += 360; }
if (NumUtil.isBetween(yaw, 0, 22.5)) { direction = "South"; }
else if (NumUtil.isBetween(yaw, 22.5, 67.5)) { direction = "South West"; }
else if (NumUtil.isBetween(yaw, 67.5, 117.5)) { direction = "West"; }
else if (NumUtil.isBetween(yaw, 117.5, 157.5)) { direction = "North West"; }
else if (NumUtil.isBetween(yaw, 157.5, 202.5)) { direction = "North"; }
else if (NumUtil.isBetween(yaw, 202.5, 247.5)) { direction = "North East"; }
else if (NumUtil.isBetween(yaw, 247.5, 292.5)) { direction = "East"; }
else if (NumUtil.isBetween(yaw, 292.5, 337.5)) { direction = "South East"; }
else if (NumUtil.isBetween(yaw, 337.5, 360)) {direction = "South";}
else { direction = "Unknown"; }
Util.sendMsg(player, COL_PRI + "You are facing: " + COL_SEC + direction);
}
@Default
@Subcommand("default")
public static void onLocation(Player player, @Default("false") Boolean showDebug) {
Util.sendMsg(player, Formatting.heading("Your Location"));
Location loc = player.getLocation();
ChatAPI.newMessage()
.msgColor(COL_PRI + "You are on " + COL_SEC + EmpireServer.getServer().name())
.msgColor(COL_PRI + " @ " + COL_SEC + Util.formatLocation(loc))
.msgColor(COL_TERT + " [LIVEMAP]")
.tooltip("Click to go to Live Map")
.link(MapCommand.getMapLink(loc))
.send(player);
onDirection(player);
if (Worlds.isWastelands(player.getWorld())) {
Util.sendMsg(player, COL_PRI + "You are in the &cWastelands " + COL_SEC + Wastelands.getCurrentRegion(loc).name + COL_PRI + " region.");
}
if (loc.getWorld() == Worlds.FRONTIER_WILD) {
Util.sendMsg(player, COL_PRI + "You are in the &9Frontier " + COL_SEC + Frontier.getNearestOutpost(loc).name + COL_PRI + " region.");
}
Util.sendMsg(player, COL_PRI + "Compass target: " + COL_SEC + Util.formatLocation(player.getCompassTarget()));
onDistance(player);
if (showDebug) {
Util.sendMsg(player, COL_PRI + "Chunk: " + COL_TERT +
(loc.getBlockX() >> 4) + "," +
(loc.getBlockZ() >> 4));
Util.sendMsg(player, COL_PRI + "Region File: " + COL_TERT +
(loc.getBlockX() >> 9) + "," +
(loc.getBlockZ() >> 9));
}
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.contexts;
import com.empireminecraft.commands.InvalidCommandArgument;
import com.empireminecraft.data.EmpireUser;
import lombok.Data;
import org.bukkit.entity.Player;
@Data public class AnyPlayer {
final EmpireUser user;
public Player getPlayer() {
return user.player;
}
public static ContextResolver<AnyPlayer> getResolver() {
return (c) -> {
String who = c.popFirstArg();
EmpireUser user = EmpireUser.getUserLoosely(who);
if (user == null) {
throw new InvalidCommandArgument("Could not find a player with the username " + who);
}
return new AnyPlayer(user);
};
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.contexts;
import com.empireminecraft.commands.InvalidCommandArgument;
import com.empireminecraft.commands.annotation.Single;
import com.empireminecraft.commands.annotation.Split;
import com.empireminecraft.commands.annotation.Values;
import com.empireminecraft.config.language.MiscLang;
import com.empireminecraft.data.EmpireUser;
import com.empireminecraft.data.Worlds;
import com.empireminecraft.features.EmpireMobArena;
import com.empireminecraft.features.friends.Friend;
import com.empireminecraft.systems.residence.protection.Residence;
import com.empireminecraft.systems.residence.protection.ResidenceFlagGroup;
import com.empireminecraft.systems.residence.selection.SelectionManager;
import com.empireminecraft.util.Patterns;
import com.empireminecraft.util.UserUtil;
import com.empireminecraft.util.Util;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.spigotmc.SneakyThrow;
import java.util.List;
import java.util.Map;
public final class CommandContexts {
static final Map<Class<?>, ContextResolver<?>> contextMap = Maps.newHashMap();
private CommandContexts() {}
public static void initialize() {
registerSenderAwareContext(Residence.class, Residence.getResolver());
registerContext(Integer.class, (c) -> {
try {
return Integer.parseInt(c.popFirstArg());
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Long.class, (c) -> {
try {
return Long.parseLong(c.popFirstArg());
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Float.class, (c) -> {
try {
return Float.parseFloat(c.popFirstArg());
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Double.class, (c) -> {
try {
return Double.parseDouble(c.popFirstArg());
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Boolean.class, (c) -> {
switch (c.popFirstArg()) {
case "t":
case "true":
case "on":
case "y":
case "yes":
case "1":
return true;
}
return false;
});
registerContext(String.class, (c) -> {
final Values values = c.getParam().getAnnotation(Values.class);
if (values != null) {
return c.popFirstArg();
}
if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) {
return Util.join(c.getArgs());
}
return c.popFirstArg();
});
registerContext(String[].class, (c) -> {
String val;
if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) {
val = Util.join(c.getArgs());
} else {
val = c.popFirstArg();
}
Split split = c.getParam().getAnnotation(Split.class);
if (split != null) {
if (val.isEmpty()) {
throw new InvalidCommandArgument();
}
return Patterns.getPattern(split.value()).split(val);
} else if (!c.isLastArg()) {
SneakyThrow.sneaky(new InvalidConfigurationException("Weird Command signature... String[] should be last or @Split"));
}
String[] result = c.getArgs().toArray(new String[c.getArgs().size()]);
c.getArgs().clear();
return result;
});
registerContext(EmpireUser.class, (c) -> {
String who = c.popFirstArg();
if (!UserUtil.isValidName(who)) {
throw new InvalidCommandArgument("Invalid Minecraft Name Format. 3-16 characters");
}
EmpireUser user = c.hasFlag("loose") ? EmpireUser.getUserLoosely(who) : EmpireUser.getUser(who);
if (user == null) {
throw new InvalidCommandArgument("Could not find user " + who);
}
return user;
});
registerContext(EmpireUser[].class, (c) -> {
String who;
if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) {
who = Util.join(c.getArgs());
} else {
who = c.popFirstArg();
}
final Integer days = c.getFlagValue("days", 30);
final List<EmpireUser> users = EmpireUser.getUsers((Player) c.getSender(), who, days);
if (users.isEmpty()) {
throw new InvalidCommandArgument("Could not find any of the specified users");
}
return users.toArray(new EmpireUser[users.size()]);
});
registerContext(OnlinePlayer.class, (c) -> {
final String playercheck = c.popFirstArg();
Player player = UserUtil.findPlayerSmart(c.getSender(), playercheck);
if (player == null) {
Util.sendMsg(c.getSender(), "&cCould not find a player by the name " + playercheck);
throw new InvalidCommandArgument(false);
}
return new OnlinePlayer(player);
});
registerSenderAwareContext(World.class, (c) -> {
String firstArg = c.getFirstArg();
World world = firstArg != null ? Bukkit.getWorld(Worlds.getWorldByAlias(firstArg)) : null;
if (world != null) {
c.popFirstArg();
}
if (world == null && c.getSender() instanceof Player) {
world = ((Entity) c.getSender()).getWorld();
}
if (world == null) {
throw new InvalidCommandArgument("Invalid World");
}
return world;
});
registerContext(AnyPlayer.class, AnyPlayer.getResolver());
registerSenderAwareContext(CommandSender.class, CommandExecutionContext::getSender);
registerSenderAwareContext(Player.class, (c) -> c.getSender() instanceof Player ? (Player) c.getSender() : null);
registerSenderAwareContext(EmpireMobArena.class, c -> {
Residence residence = Residence.getResidence((Entity) c.getSender());
if (residence == null || !"mobarena".equals(residence.getTopParent().getName())) {
Util.sendMsg(c.getSender(), MiscLang.NOT_IN_MBA);
throw new InvalidCommandArgument(false);
}
// TODO: Remove static ref and be a res feature
return EmpireMobArena.instance;
});
registerContext(ResidenceFlagGroup.class, ResidenceFlagGroup.getContextResolver());
registerContext(Friend.class, (c) -> {
if (!(c.getSender() instanceof Player)) {
throw new InvalidCommandArgument("Only players can run this.");
}
Player player = (Player) c.getSender();
EmpireUser user = player.getUser();
final String firstArg = c.popFirstArg();
if (firstArg == null) {
throw new InvalidCommandArgument("Please specify a friends name.");
}
EmpireUser lookup = EmpireUser.getUserLoosely(firstArg, 90);
if (lookup == null) {
throw new InvalidCommandArgument("Could not find a player by that name who has played recently.", false);
}
Friend friend = user.getFriendsList().getFriend(lookup);
if (friend == null) {
throw new InvalidCommandArgument("That player is not your friend.", false);
}
return friend;
});
registerSenderAwareContext(CuboidSelection.class, (c) -> {
if (!(c.getSender() instanceof Player)) {
throw new InvalidCommandArgument("Only players can run this.");
}
CuboidSelection selection = SelectionManager.getSelection((Player) c.getSender());
if (selection == null) {
throw new InvalidCommandArgument("You must first make a Cuboid Selection.");
}
return selection;
});
}
public static <T> void registerSenderAwareContext(Class<T> context, SenderAwareContextResolver<T> supplier) {
contextMap.put(context, supplier);
}
public static <T> void registerContext(Class<T> context, ContextResolver<T> supplier) {
contextMap.put(context, supplier);
}
public static ContextResolver<?> getResolver(Class<?> type) {
Class<?> rootType = type;
do {
if (type == Object.class) {
break;
}
final ContextResolver<?> resolver = contextMap.get(type);
if (resolver != null) {
return resolver;
}
} while ((type = type.getSuperclass()) != null);
Util.printException(new InvalidConfigurationException("No context resolver defined for " + rootType.getName()));
return null;
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.contexts;
import com.empireminecraft.commands.RegisteredCommand;
import com.empireminecraft.commands.annotation.Default;
import com.empireminecraft.commands.annotation.Flags;
import com.empireminecraft.commands.annotation.Optional;
import com.empireminecraft.util.Patterns;
import com.empireminecraft.util.Util;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.Data;
import org.bukkit.command.CommandSender;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;
@Data public class CommandExecutionContext {
private final RegisteredCommand cmd;
private final Parameter param;
private final CommandSender sender;
private final List<String> args;
private final int index;
private final List<Object> passedArgs;
private final Map<String, String> flags;
public CommandExecutionContext(RegisteredCommand cmd, Parameter param, CommandSender sender, List<String> args,
int index, List<Object> passedArgs) {
this.cmd = cmd;
this.param = param;
this.sender = sender;
this.args = args;
this.index = index;
this.passedArgs = passedArgs;
Flags flags = param.getAnnotation(Flags.class);
if (flags != null) {
this.flags = Maps.newHashMap();
for (String s : Patterns.COMMA.split(flags.value())) {
String[] v = Patterns.EQUALS.split(s, 2);
this.flags.put(v[0], v.length > 1 ? v[1] : null);
}
} else {
this.flags = ImmutableMap.of();
}
}
public String popFirstArg() {
return !args.isEmpty() ? args.remove(0) : null;
}
public String getFirstArg() {
return !args.isEmpty() ? args.get(0) : null;
}
public boolean isLastArg() {
return cmd.parameters.length -1 == index;
}
public int getNumParams() {
return cmd.parameters.length;
}
public boolean canOverridePlayerContext() {
int numRequired = getNumParams();
for (int i = 0; i < cmd.resolvers.length; i++) {
Parameter parameter = cmd.parameters[i];
ContextResolver<?> resolver = cmd.resolvers[i];
if (parameter.getAnnotation(Optional.class) != null || parameter.getAnnotation(Default.class) != null) {
numRequired--;
} else if (resolver instanceof SenderAwareContextResolver) {
numRequired--;
}
}
return numRequired >= args.size();
}
public <T> T getOtherArgContext(Class<?> clazz) {
for (Object passedArg : passedArgs) {
if (clazz.isInstance(passedArg)) {
return (T) passedArg;
}
}
return null;
}
public boolean isOptional() {
return param.getAnnotation(Optional.class) != null;
}
public boolean hasFlag(String flag) {
return flags.containsKey(flag);
}
public String getFlagValue(String flag, String def) {
return flags.containsKey(flag) ? flags.get(flag) : def;
}
public Integer getFlagValue(String flag, Integer def) {
return Util.parseInt(this.flags.get(flag), def);
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.contexts;
import com.empireminecraft.commands.InvalidCommandArgument;
@FunctionalInterface
public interface ContextResolver <C> {
C getContext(CommandExecutionContext c) throws InvalidCommandArgument;
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.contexts;
import com.empireminecraft.data.EmpireUser;
import lombok.Data;
import org.bukkit.entity.Player;
@Data public class OnlinePlayer {
public final Player player;
public EmpireUser getUser() {
return EmpireUser.getUser(player);
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands.contexts;
public interface SenderAwareContextResolver<C> extends ContextResolver <C> {}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands;
import com.empireminecraft.commands.annotation.CommandAlias;
import com.empireminecraft.commands.annotation.CommandPermission;
import com.empireminecraft.commands.annotation.Default;
import com.empireminecraft.commands.annotation.Subcommand;
import com.empireminecraft.config.language.MiscLang;
import com.empireminecraft.util.Patterns;
import com.empireminecraft.util.Util;
import com.google.common.collect.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.util.StringUtil;
import org.spigotmc.SneakyThrow;
import co.aikar.timings.Timing;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
public abstract class EmpireCommand extends Command {
private final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create();
protected String execLabel;
protected String execSubcommand;
protected String[] origArgs;
public EmpireCommand() {
this(null);
}
public EmpireCommand(String cmd) {
super(cmd);
final Class<? extends EmpireCommand> self = this.getClass();
CommandAlias rootCmdAlias = self.getAnnotation(CommandAlias.class);
if (cmd == null) {
if (rootCmdAlias == null) {
cmd = "__" + self.getSimpleName();
} else {
cmd = Patterns.PIPE.split(rootCmdAlias.value())[0];
}
cmd = cmd.toLowerCase();
setName(cmd);
setLabel(cmd);
}
this.description = cmd + " commands";
this.usageMessage = "/" + cmd;
final CommandPermission perm = self.getAnnotation(CommandPermission.class);
if (perm != null) {
this.setPermission(perm.value());
}
boolean foundDefault = false;
for (Method method : self.getDeclaredMethods()) {
method.setAccessible(true);
String sublist = null;
final Subcommand sub = method.getAnnotation(Subcommand.class);
final Default def = method.getAnnotation(Default.class);
final CommandAlias commandAliases = method.getAnnotation(CommandAlias.class);
if (def != null) {
if (!foundDefault) {
registerSubcommand(method, "__default");
foundDefault = true;
} else {
SneakyThrow.sneaky(new InvalidConfigurationException("Multiple @Default commands"));
}
}
if (sub != null) {
sublist = sub.value();
} else if (commandAliases != null) {
sublist = commandAliases.value();
}
if (sublist != null) {
registerSubcommand(method, sublist);
}
}
try {
Method unknown = self.getMethod("onUnknown", CommandSender.class, String.class, String[].class);
unknown.setAccessible(true);
registerSubcommand(unknown, "__unknown");
} catch (NoSuchMethodException ignored) {}
if (rootCmdAlias != null) {
List<String> cmdList = new ArrayList<>();
Collections.addAll(cmdList, Patterns.PIPE.split(rootCmdAlias.value().toLowerCase()));
cmdList.remove(cmd);
for (String cmdAlias : cmdList) {
register(cmdAlias, new ForwardingCommand(this));
}
}
register(getName(), this);
}
private boolean register(String name, Command cmd) {
return Bukkit.getServer().getCommandMap().register(name.toLowerCase(), "empire", cmd);
}
private void registerSubcommand(Method method, String subCommand) {
subCommand = subCommand.toLowerCase();
final String[] subCommandParts = Patterns.SPACE.split(subCommand);
// Must run getSubcommandPossibility BEFORE we rewrite it just after this.
List<String> cmdList = getSubCommandPossibilityList(subCommandParts);
// Strip pipes off for auto complete addition
for (int i = 0; i < subCommandParts.length; i++) {
subCommandParts[i] = Patterns.PIPE.split(subCommandParts[i])[0];
}
String prefSubCommand = StringUtils.join(subCommandParts, " ");
final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class);
final String[] aliasNames = cmdAlias != null ? Patterns.PIPE.split(cmdAlias.value().toLowerCase()) : null;
String cmdName = aliasNames != null ? aliasNames[0] : getLabel() + " ";
RegisteredCommand cmd = new RegisteredCommand(this, cmdName, method, prefSubCommand);
for (String subcmd : cmdList) {
subCommands.put(subcmd, cmd);
}
if (aliasNames != null) {
for (String name : aliasNames) {
register(name, new ForwardingCommand(this, subCommandParts));
}
}
}
/**
* Takes a string like "foo|bar baz|qux" and generates a list of
* - foo baz
* - foo qux
* - bar baz
* - bar qux
*
* For every possible sub command combination
*
* @param subCommandParts
* @return List of all sub command possibilities
*/
private static List<String> getSubCommandPossibilityList(String[] subCommandParts) {
int i = 0;
ArrayList<String> current = null;
while (true) {
ArrayList<String> newList = new ArrayList<>();
if (i < subCommandParts.length) {
for (String s1 : Patterns.PIPE.split(subCommandParts[i])) {
if (current != null) {
newList.addAll(current.stream().map(s -> s + " " + s1).collect(Collectors.toList()));
} else {
newList.add(s1);
}
}
}
if (i + 1 < subCommandParts.length) {
current = newList;
i = i + 1;
continue;
}
return newList;
}
}
@Override
public final boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!testPermission(sender)) {
return true;
}
commandLabel = commandLabel.toLowerCase();
if (preCommand(sender, commandLabel, args)) {
return true;
}
execSubcommand = null;
execLabel = commandLabel;
origArgs = args;
if (args.length == 0) {
onDefault(sender, commandLabel);
return true;
}
CommandSearch cmd = findSubCommand(args);
if (cmd != null) {
execSubcommand = cmd.getCheckSub();
final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length);
executeCommand(sender, execargs, cmd.cmd);
return true;
}
if (!onUnknown(sender, commandLabel, args)) {
help(sender, args);
}
return true;
}
private CommandSearch findSubCommand(String[] args) {
return findSubCommand(args, false);
}
private CommandSearch findSubCommand(String[] args, boolean completion) {
for (int i = args.length; i >= 0; i--) {
String checkSub = StringUtils.join(args, " ", 0, i).toLowerCase();
Set<RegisteredCommand> cmds = subCommands.get(checkSub);
final int extraArgs = args.length - i;
if (!cmds.isEmpty()) {
RegisteredCommand cmd = null;
if (cmds.size() == 1) {
cmd = Iterables.getOnlyElement(cmds);
} else {
Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> {
int nonSender = c.nonSenderAwareResolvers;
int partialSender = c.optionalResolvers;
return extraArgs <= nonSender + partialSender && (completion || extraArgs >= nonSender);
}).sorted((c1, c2) -> {
int a = c1.nonSenderAwareResolvers + c1.optionalResolvers;
int b = c2.nonSenderAwareResolvers + c2.optionalResolvers;
if (a == b) {
return 0;
}
return a < b ? 1 : -1;
}).findFirst();
if (optCmd.isPresent()) {
cmd = optCmd.get();
}
}
if (cmd != null) {
return new CommandSearch(cmd, i, checkSub);
}
}
}
return null;
}
private static void executeCommand(CommandSender sender, String[] args, RegisteredCommand cmd) {
if (cmd.hasPermission(sender)) {
List<String> sargs = Lists.newArrayList(args);
try (Timing subTiming = Util.startTiming("Command: " + cmd.command)) {
cmd.invoke(sender, sargs);
}
} else {
Util.sendMsg(sender, MiscLang.COMMAND_PERM_ERROR);
}
}
public boolean canExecute(CommandSender sender, RegisteredCommand cmd) {
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String commandLabel, String[] args)
throws IllegalArgumentException {
commandLabel = commandLabel.toLowerCase();
final CommandSearch search = findSubCommand(args, true);
if (search != null) {
args = Arrays.copyOfRange(args, search.argIndex, args.length);
return completeCommand(sender, search.cmd, args, commandLabel);
}
String argString = StringUtils.join(args, " ").toLowerCase();
final List<String> cmds = new ArrayList<>();
for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) {
final String key = entry.getKey();
if (key.startsWith(argString) && !"__unknown".equals(key)) {
final RegisteredCommand value = entry.getValue();
if (!value.hasPermission(sender)) {
continue;
}
String prefCommand = value.prefSubCommand;
final String[] psplit = Patterns.SPACE.split(prefCommand);
cmds.add(psplit[args.length - 1]);
}
}
final Set<RegisteredCommand> unknownCmds = subCommands.get("__unknown");
if (cmds.isEmpty() && !unknownCmds.isEmpty()) {
RegisteredCommand unknownCommand = null;
if (unknownCmds.size() == 1) {
unknownCommand = Iterables.getOnlyElement(unknownCmds);
}
if (unknownCommand != null) {
return completeCommand(sender, unknownCommand, args, commandLabel);
}
}
return filterTabComplete(args[args.length-1], cmds);
}
private List<String> completeCommand(CommandSender sender, RegisteredCommand cmd, String[] args, String commandLabel) {
if (args.length > cmd.nonSenderAwareResolvers + cmd.optionalResolvers) {
return ImmutableList.of();
}
if (args.length == 0 || cmd.complete == null) {
return args.length < 2 ? super.tabComplete(sender, commandLabel, args) : ImmutableList.of();
}
String[] completions = Patterns.SPACE.split(cmd.complete.value());
final int argIndex = args.length - 1;
String input = args[argIndex];
final String completion = argIndex < completions.length ? completions[argIndex] : null;
if ("@players".equals(completion)) {
return super.tabComplete(sender, commandLabel, args);
}
List<String> cmds = CommandCompletions.of(sender, completion, input);
if (cmds.isEmpty()) {
cmds = ImmutableList.of(input);
}
return filterTabComplete(args[(argIndex)], cmds);
}
private static List<String> filterTabComplete(String arg, List<String> cmds) {
return cmds.stream()
.distinct()
.filter(cmd -> cmd != null && (arg.isEmpty() || StringUtil.startsWithIgnoreCase(cmd, arg)))
.collect(Collectors.toList());
}
public void help(CommandSender sender, String[] args) {
Util.sendMsg(sender, "&cUnknown Command, please type &f/help");
}
public void onDefault(CommandSender sender, String commandLabel) {
executeDefault(sender);
}
public boolean onUnknown(CommandSender sender, String commandLabel, String[] args) {
help(sender, args);
return true;
}
public boolean executeDefault(CommandSender sender, String... args) {
final Set<RegisteredCommand> defs = subCommands.get("__default");
RegisteredCommand def = null;
if (!defs.isEmpty()) {
if (defs.size() == 1) {
def = Iterables.getOnlyElement(defs);
}
if (def != null) {
executeCommand(sender, args, def);
return true;
}
}
return false;
}
public boolean preCommand(CommandSender sender, String commandLabel, String[] args) {
return false;
}
public void doHelp(CommandSender sender, String... args) {
help(sender, args);
}
public void showSyntax(CommandSender sender, RegisteredCommand cmd) {
Util.sendMsg(sender, "&cUsage: /" + cmd.command + " " + cmd.syntax);
}
@Data @AllArgsConstructor
public static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; }
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
public class ForwardingCommand extends Command {
private final Command command;
private final String[] baseArgs;
private static final String[] NO_ARGS = new String[0];
public ForwardingCommand(Command command) {
this(command, NO_ARGS);
}
public ForwardingCommand(Command command, String[] baseArgs) {
super(command.getName());
this.command = command;
this.baseArgs = baseArgs;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
return command.tabComplete(sender, alias, (String[]) ArrayUtils.addAll(baseArgs, args));
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
return command.execute(sender, commandLabel, (String[]) ArrayUtils.addAll(baseArgs, args));
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands;
public class InvalidCommandArgument extends Exception {
public boolean showSyntax = true;
public InvalidCommandArgument() {
this(null);
}
public InvalidCommandArgument(boolean showSyntax) {
this(null, showSyntax);
}
public InvalidCommandArgument(String message) {
this(message, true);
}
public InvalidCommandArgument(String message, boolean showSyntax) {
super(message, null, false, false);
this.showSyntax = showSyntax;
}
}
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package com.empireminecraft.commands;
import com.empireminecraft.commands.annotation.*;
import com.empireminecraft.commands.contexts.CommandContexts;
import com.empireminecraft.commands.contexts.CommandExecutionContext;
import com.empireminecraft.commands.contexts.ContextResolver;
import com.empireminecraft.commands.contexts.SenderAwareContextResolver;
import com.empireminecraft.systems.residence.protection.Residence;
import com.empireminecraft.util.Patterns;
import com.empireminecraft.util.Util;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.entity.Player;
import org.spigotmc.SneakyThrow;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class RegisteredCommand {
public final EmpireCommand scope;
public final String command;
public final Method method;
public final String prefSubCommand;
public final Parameter[] parameters;
public final ContextResolver<?>[] resolvers;
public final String syntax;
public final CommandPermission perm;
public final CommandCompletion complete;
public final int nonSenderAwareResolvers;
public final int optionalResolvers;
RegisteredCommand(EmpireCommand scope, String command, Method method, String prefSubCommand) {
this.scope = scope;
if ("__unknown".equals(prefSubCommand)) {
prefSubCommand = "";
}
this.command = command + (method.getAnnotation(CommandAlias.class) == null && !prefSubCommand.isEmpty() ? prefSubCommand : "");
this.method = method;
this.prefSubCommand = prefSubCommand;
this.perm = method.getAnnotation(CommandPermission.class);
this.complete = method.getAnnotation(CommandCompletion.class);
this.parameters = method.getParameters();
this.resolvers = new ContextResolver[this.parameters.length];
final Syntax syntaxStr = method.getAnnotation(Syntax.class);
int nonSenderAwareResolvers = 0;
int optionalResolvers = 0;
StringBuilder syntaxB = new StringBuilder(64);
for (int i = 0; i < parameters.length; i++) {
final Parameter parameter = parameters[i];
final Class<?> type = parameter.getType();
final ContextResolver<?> resolver = CommandContexts.getResolver(type);
if (resolver != null) {
resolvers[i] = resolver;
if (type == World.class || type == Residence.class || parameter.getAnnotation(Optional.class) != null
|| parameter.getAnnotation(Default.class) != null) {
optionalResolvers++;
} else if (!(resolver instanceof SenderAwareContextResolver)) {
nonSenderAwareResolvers++;
}
if (!CommandSender.class.isAssignableFrom(parameter.getType())) {
if (parameter.getAnnotation(Default.class) != null ||
parameter.getAnnotation(Optional.class) != null ||
resolver instanceof SenderAwareContextResolver) {
syntaxB.append('[').append(parameter.getName()).append("] ");
} else {
syntaxB.append('<').append(parameter.getName()).append("> ");
}
}
} else {
SneakyThrow.sneaky(new InvalidConfigurationException(
"Parameter " + type.getSimpleName() + " of " + this.command + " has no resolver"
));
}
}
if (syntaxStr != null) {
this.syntax = syntaxStr.value();
} else {
this.syntax = syntaxB.toString();
}
this.nonSenderAwareResolvers = nonSenderAwareResolvers;
this.optionalResolvers = optionalResolvers;
}
public void invoke(CommandSender sender, List<String> args) {
if (!scope.canExecute(sender, this)) {
return;
}
try {
List<Object> passedArgs = Lists.newArrayList();
for (int i = 0; i < parameters.length; i++) {
boolean isLast = i == parameters.length - 1;
final Parameter parameter = parameters[i];
final Class<?> type = parameter.getType();
final ContextResolver<?> resolver = resolvers[i];
if (resolver != null) {
CommandExecutionContext context = new CommandExecutionContext(this, parameter, sender, args, i, passedArgs);
if (args.isEmpty() && !(isLast && type == String[].class)) {
Default def = parameter.getAnnotation(Default.class);
Optional opt = parameter.getAnnotation(Optional.class);
if (isLast && def != null) {
args.add(def.value());
} else if (isLast && opt != null) {
passedArgs.add(null);
continue;
} else if (!(resolver instanceof SenderAwareContextResolver)) {
scope.showSyntax(sender, this);
return;
}
} else {
final Values values = parameter.getAnnotation(Values.class);
if (values != null) {
String arg = args.get(0);
final String[] split = Patterns.PIPE.split(values.value());
Set<String> possible = Sets.newHashSet();
for (String s : split) {
List<String> check = CommandCompletions.of(sender, s, arg);
if (!check.isEmpty()) {
possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList()));
} else {
possible.add(s.toLowerCase());
}
}
if (!possible.contains(arg.toLowerCase())) {
throw new InvalidCommandArgument("Must be one of: " + Util.join(possible, ", "));
}
}
}
passedArgs.add(resolver.getContext(context));
} else {
Util.sendMsg(sender, "&cUnexpected Error. Staff have been notified of the bug.");
return;
}
}
method.invoke(scope, passedArgs.toArray());
} catch (Exception e) {
if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) {
e = (Exception) e.getCause();
}
if (e instanceof InvalidCommandArgument) {
if (e.getMessage() != null && !e.getMessage().isEmpty()) {
Util.sendMsg(sender, "&cInvalid Argument: " + e.getMessage());
}
if (((InvalidCommandArgument) e).showSyntax) {
scope.showSyntax(sender, this);
}
} else {
Util.sendMsg(sender, "&cI'm sorry, but there was an error performing this command.");
Util.printException("Exception in command: " + command + " " + Util.join(args), e.getCause());
}
}
}
public boolean hasPermission(CommandSender check) {
return perm == null || !(check instanceof Player) || check.hasPermission(perm.value());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment