Skip to content

Commit

Permalink
v1.1.0: Multiple improvements
Browse files Browse the repository at this point in the history
Add multiple commands per advancement with a list, clean up some code
  • Loading branch information
aikar committed Feb 24, 2018
1 parent 5911fb0 commit 4858a09
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 37 deletions.
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)

Expand All @@ -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.

Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>co.aikar</groupId>
<artifactId>advancementcommand</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
<packaging>jar</packaging>

<name>AdvancementCommand</name>
Expand Down
56 changes: 29 additions & 27 deletions src/main/java/co/aikar/advancementcommand/AdvancementCommand.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -23,11 +24,12 @@
@SuppressWarnings("unused")
public final class AdvancementCommand extends JavaPlugin implements Listener {

private final ArrayListMultimap<String, CommandInfo> commandMap = ArrayListMultimap.create();
private final ListMultimap<String, CommandInfo> 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);
Expand Down Expand Up @@ -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<CommandInfo> 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) {
Expand Down Expand Up @@ -132,32 +132,34 @@ 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<String> commands = new ArrayList<>();
final String alias;
final boolean op;
final List<String> 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");
if (permission != null) {
this.permissions.add(permission);
}
List<String> permissions = section.getStringList("permissions");
if (permissions != null) {
this.permissions.addAll(permissions);
}
this.permissions.addAll(permissions);
}
}
}
15 changes: 13 additions & 2 deletions src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 4858a09

Please sign in to comment.