diff --git a/README.md b/README.md
index 3e21536..1cdc552 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# AdvancementCommand
Runs a command, optionally as console or permission elevated when receiving advancements
+
## Downloads
See [Releases](https://github.com/aikar/AdvancementCommand/releases)
@@ -8,7 +9,7 @@ See examples below for format
Each entry must define:
- advancement
- - command OR alias
+ - command OR commands OR alias
An advancement can be defined multiple times in the list to perform multiple commands.
@@ -17,8 +18,9 @@ If no other configuration is provided, it will be ran as the player without op o
Alias will alias one advancement to run the same commands as another, so you don't have to duplicate it.
### Keys
- - **advancement**: the advancement key such as `minecraft:brewed_potion` to trigger on
+ - **advancement**: the advancement key such as `minecraft:husbandry/root` to trigger on
- **command**: what command to run, see variables below for template variables
+ - **commands**: Alternatively, a list of what command to run, see variables below for template variables
- **run_as**: `player` or `console` - who receives the command feedback
- **op**: Should player be given temporary op for this command. Unnecessary for `run_as: console`
- **permission**: Permission node to give temporarily for this command. Example:
@@ -38,7 +40,7 @@ Inside of a command, you may use the following variables
- **%PLAYER**: The name of the player earning the advancement.
- **%UUID**: The UUID of the player earning the advancement.
- **%PLAYERDISPLAYNAME**: The display name of the player earning the advancement. (might be the same as player)
- - **%ADVANCEMENT**: The advancement key (eg `minecraft:brewed_potion`) being earned.
+ - **%ADVANCEMENT**: The advancement key (eg `minecraft:adventure/root`) being earned.
## Examples
```yaml
@@ -51,7 +53,9 @@ on_advancement:
# run a standard command with no permissions
- advancement: minecraft:example
run_as: player
- command: say Hey I just got an advancement!
+ commands:
+ - say Hey I just got an advancement!
+ - me Dances!
op: false
# run a command as the console (command feedback to console instead of the player, ideal for rank changes)
- advancement: myplugin:gainrank1
@@ -63,15 +67,27 @@ on_advancement:
run_as: player
command: teleport %player some secret coords
permission: minecraft.command.teleport
- - advancement: minecraft:brew_potion
+ - advancement: minecraft:husbandry/tame_an_animal
alias: myplugin:teleport_to_secret
- - advancement: minecraft:bred_animals
+ - advancement: minecraft:husbandry/plant_seed
alias: myplugin:teleport_to_secret
```
## Tricks
You may define fake advancement keys, to define a list of actions, and then use them
-inside of your alias targets
+inside of your alias targets.
+
+## Contributing
+See Issues section.
+
+Join [#aikar on Spigot IRC - irc.spi.gt](https://aikarchat.emc.gs) to discuss.
+
+Or [Code With Aikar](https://aikardiscord.emc.gs) Discord.
+
+## Other projects by Aikar / Empire Minecraft
+ - [ACF - Annotation Command Framework](https://acf.emc.gs) - The most powerful command framework for Bukkit, Sponge, BungeeCoord, JDA and any other platform. Build rich command definitions powered by annotations.
+ - [TaskChain](https://taskchain.emc.gs) - Powerful context control to dispatch tasks Async, then access the result sync for API usage. Concurrency controls too.
+ - [Minecraft Timings](https://github.com/aikar/minecraft-timings/) - Add Timings to your plugin in a safe way that works on all Bukkit platforms (CraftBukkit - no timings, Spigot - Timings v1, Paper and Paper forks - Timings v2)
## License
As with all my other public projects
diff --git a/pom.xml b/pom.xml
index d928510..edc1848 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
co.aikar
advancementcommand
- 1.0.0
+ 1.1.0
jar
AdvancementCommand
diff --git a/src/main/java/co/aikar/advancementcommand/AdvancementCommand.java b/src/main/java/co/aikar/advancementcommand/AdvancementCommand.java
index da4c2cb..db7fc9f 100644
--- a/src/main/java/co/aikar/advancementcommand/AdvancementCommand.java
+++ b/src/main/java/co/aikar/advancementcommand/AdvancementCommand.java
@@ -1,6 +1,7 @@
package co.aikar.advancementcommand;
import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -23,11 +24,12 @@
@SuppressWarnings("unused")
public final class AdvancementCommand extends JavaPlugin implements Listener {
- private final ArrayListMultimap commandMap = ArrayListMultimap.create();
+ private final ListMultimap commandMap = ArrayListMultimap.create();
private static final Pattern PLAYER = Pattern.compile("%player\b", Pattern.CASE_INSENSITIVE);
private static final Pattern PLAYER_DISPLAY = Pattern.compile("%playerdisplayname\b", Pattern.CASE_INSENSITIVE);
private static final Pattern UUID = Pattern.compile("%uuid\b", Pattern.CASE_INSENSITIVE);
private static final Pattern ADVANCEMENT = Pattern.compile("%advancement\b", Pattern.CASE_INSENSITIVE);
+
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
@@ -67,39 +69,37 @@ public void reloadConfig() {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerAdvancementDone(PlayerAdvancementDoneEvent event) {
String key = event.getAdvancement().getKey().toString();
- runCommands(event, key);
+ processAdvancement(event, key);
}
- private void runCommands(PlayerAdvancementDoneEvent event, String key) {
+ private void processAdvancement(PlayerAdvancementDoneEvent event, String key) {
List commands = this.commandMap.get(key.toLowerCase());
if (commands == null || commands.isEmpty()) {
return;
}
+ Player player = event.getPlayer();
for (CommandInfo info : commands) {
if (info.alias != null) {
- doWithPermissions(info, event.getPlayer(), () -> runCommands(event, info.alias));
+ doWithPermissions(info, player, () -> processAdvancement(event, info.alias));
} else {
- runCommand(event, key, info);
+ doWithPermissions(info, player, () -> dispatchCommands(event, key, info));
}
}
}
- private void runCommand(PlayerAdvancementDoneEvent event, String key, CommandInfo info) {
+ private Player dispatchCommands(PlayerAdvancementDoneEvent event, String key, CommandInfo info) {
Player player = event.getPlayer();
+ CommandSender sender = info.asPlayer ? player : Bukkit.getConsoleSender();
String name = player.getName();
String displayName = player.getDisplayName();
- String command = PLAYER.matcher(info.command).replaceAll(name);
- command = PLAYER_DISPLAY.matcher(command).replaceAll(displayName);
- command = ADVANCEMENT.matcher(command).replaceAll(key);
- command = UUID.matcher(command).replaceAll(player.getUniqueId().toString());
-
- if (!(info.asPlayer)) {
- Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
- return;
+ for (String command : info.commands) {
+ command = PLAYER.matcher(command).replaceAll(name);
+ command = PLAYER_DISPLAY.matcher(command).replaceAll(displayName);
+ command = ADVANCEMENT.matcher(command).replaceAll(key);
+ command = UUID.matcher(command).replaceAll(player.getUniqueId().toString());
+ Bukkit.getServer().dispatchCommand(sender, command);
}
-
- String finalCommand = command;
- doWithPermissions(info, player, () -> Bukkit.getServer().dispatchCommand(player, finalCommand));
+ return player;
}
private void doWithPermissions(CommandInfo info, Player player, Runnable run) {
@@ -132,22 +132,26 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
return true;
}
- private class CommandInfo {
+ private static class CommandInfo {
final boolean asPlayer;
- final String command;
+ final List commands = new ArrayList<>();
final String alias;
final boolean op;
final List permissions = new ArrayList<>();
CommandInfo(ConfigurationSection section) {
- this.asPlayer = !section.getString("run_as", "player").equals("console");
- this.command = section.getString("command");
+ this.asPlayer = !section.getString("run_as", "player").trim().equalsIgnoreCase("console");
+ String command = section.getString("command");
+ if (command != null) {
+ this.commands.add(command);
+ }
+ this.commands.addAll(section.getStringList("commands"));
this.alias = section.getString("alias");
- boolean commandEmpty = this.command == null || this.command.isEmpty();
+ boolean commandEmpty = this.commands.isEmpty();
if (this.alias != null && commandEmpty) {
- throw new Error("command can not be empty");
+ throw new IllegalArgumentException("Commands can not be empty");
}
if (!commandEmpty && this.alias != null) {
- throw new Error("You can not have both a command and alias configuration");
+ throw new IllegalArgumentException("You can not have both a command and alias configuration");
}
this.op = section.getBoolean("op", false);
String permission = section.getString("permission");
@@ -155,9 +159,7 @@ private class CommandInfo {
this.permissions.add(permission);
}
List permissions = section.getStringList("permissions");
- if (permissions != null) {
- this.permissions.addAll(permissions);
- }
+ this.permissions.addAll(permissions);
}
}
}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index cab06d3..bccf1cd 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -2,5 +2,16 @@ name: AdvancementCommand
version: ${project.version}
main: co.aikar.advancementcommand.AdvancementCommand
authors: [Aikar]
-description: When an advancement is ran, run a command at potentially elevated permissions
-website: https://aikar.co
+description: When an advancement is ran, run commands at potentially elevated permissions
+website: https://github.com/aikar/AdvancementCommand
+
+comands:
+ advancementcommand:
+ description: Reloads AdvancementCommand config
+ aliases: [advcom]
+ permission: advancementcommand
+
+permissions:
+ advancementcommand:
+ description: Lets you reload AdvancementCommand config
+ default: op