Add CommandAction

This commit is contained in:
fullwall 2022-12-10 13:42:07 +08:00
parent 46b18eee49
commit 2034ca6bf0
4 changed files with 200 additions and 44 deletions

View File

@ -30,8 +30,6 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.BaseEncoding;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
@ -48,7 +46,6 @@ import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Placeholders;
import net.citizensnpcs.api.util.Translator;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.StringHelper;
@ -526,45 +523,7 @@ public class CommandTrait extends Trait {
}
public void run(NPC npc, Player clicker) {
String cmd = command;
if (command.startsWith("say")) {
cmd = "npc speak " + command.replaceFirst("say", "").trim() + " --target <p>";
}
if ((cmd.startsWith("npc ") || cmd.startsWith("waypoints ") || cmd.startsWith("wp "))
&& !cmd.contains("--id ")) {
cmd += " --id <id>";
}
String interpolatedCommand = Placeholders.replace(cmd, clicker, npc);
if (Messaging.isDebugging()) {
Messaging.debug(
"Running command " + interpolatedCommand + " on NPC " + npc.getId() + " clicker " + clicker);
}
if (!player) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), interpolatedCommand);
return;
}
boolean wasOp = clicker.isOp();
if (op) {
clicker.setOp(true);
}
if (bungeeServer != null) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(bungeeServer);
clicker.sendPluginMessage(CitizensAPI.getPlugin(), "BungeeCord", out.toByteArray());
} else {
try {
clicker.chat("/" + interpolatedCommand);
} catch (Throwable t) {
t.printStackTrace();
}
}
if (op) {
clicker.setOp(wasOp);
}
Util.runCommand(npc, clicker, command, op, player);
}
}

View File

@ -40,6 +40,7 @@ import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.Colorizer;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Placeholders;
import net.citizensnpcs.trait.shop.CommandAction.CommandActionGUI;
import net.citizensnpcs.trait.shop.ItemAction;
import net.citizensnpcs.trait.shop.ItemAction.ItemActionGUI;
import net.citizensnpcs.trait.shop.MoneyAction;
@ -327,8 +328,6 @@ public class ShopTrait extends Trait {
}
public void onClick(NPCShop shop, CitizensInventoryClickEvent event) {
if (shop.type == ShopType.COMMAND)
return;
List<Transaction> take = execute(cost, action -> action.take(event.getWhoClicked()));
if (take == null)
return;
@ -658,5 +657,6 @@ public class ShopTrait extends Trait {
NPCShopAction.register(ItemAction.class, "items", new ItemActionGUI());
NPCShopAction.register(PermissionAction.class, "permissions", new PermissionActionGUI());
NPCShopAction.register(MoneyAction.class, "money", new MoneyActionGUI());
NPCShopAction.register(MoneyAction.class, "command", new CommandActionGUI());
}
}

View File

@ -0,0 +1,147 @@
package net.citizensnpcs.trait.shop;
import java.util.List;
import java.util.function.Consumer;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.google.common.collect.Lists;
import net.citizensnpcs.api.gui.InputMenus;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.gui.Menu;
import net.citizensnpcs.api.gui.MenuContext;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.util.Util;
public class CommandAction extends NPCShopAction {
@Persist
public List<String> commands = Lists.newArrayList();
public CommandAction() {
}
public CommandAction(List<String> commands) {
this.commands = commands;
}
@Override
public String describe() {
String description = commands.size() + " command";
for (int i = 0; i < commands.size(); i++) {
description += "\n" + commands.get(i);
if (i == 3) {
description += "...";
break;
}
}
return description;
}
@Override
public Transaction grant(Entity entity) {
if (!(entity instanceof Player))
return Transaction.fail();
Player player = (Player) entity;
return Transaction.create(() -> true, () -> {
for (String command : commands) {
Util.runCommand(null, player, command, false, true);
}
}, () -> {
});
}
@Override
public Transaction take(Entity entity) {
if (!(entity instanceof Player))
return Transaction.fail();
Player player = (Player) entity;
return Transaction.create(() -> true, () -> {
for (String command : commands) {
Util.runCommand(null, player, command, false, true);
}
}, () -> {
});
}
@Menu(title = "Command editor", dimensions = { 3, 9 })
public static class CommandActionEditor extends InventoryMenuPage {
private CommandAction base;
private Consumer<NPCShopAction> callback;
public CommandActionEditor() {
}
public CommandActionEditor(CommandAction base, Consumer<NPCShopAction> callback) {
this.base = base;
this.callback = callback;
}
@Override
public void initialise(MenuContext ctx) {
for (int i = 0; i < 3 * 9; i++) {
final int idx = i;
ctx.getSlot(i).clear();
if (i < base.commands.size()) {
ctx.getSlot(i).setItemStack(new ItemStack(Material.FEATHER), "<f>Set command",
"Right click to remove\nCurrently: " + base.commands.get(i));
}
ctx.getSlot(i).setClickHandler(event -> {
if (event.isRightClick()) {
event.setCancelled(true);
if (idx < base.commands.size()) {
base.commands.remove(idx);
ctx.getSlot(idx).setItemStack(null);
}
return;
}
ctx.getMenu().transition(InputMenus
.stringSetter(() -> idx < base.commands.size() ? base.commands.get(idx) : "", (res) -> {
if (res == null) {
if (idx < base.commands.size()) {
base.commands.remove(idx);
}
return;
}
if (idx < base.commands.size()) {
base.commands.set(idx, res);
} else {
base.commands.add(res);
}
}));
});
}
}
@Override
public void onClose(HumanEntity player) {
callback.accept(base.commands.isEmpty() ? null : base);
}
}
public static class CommandActionGUI implements GUI {
@Override
public InventoryMenuPage createEditor(NPCShopAction previous, Consumer<NPCShopAction> callback) {
return new CommandActionEditor(previous == null ? new CommandAction() : (CommandAction) previous, callback);
}
@Override
public ItemStack createMenuItem(NPCShopAction previous) {
String description = null;
if (previous != null) {
CommandAction old = (CommandAction) previous;
description = old.describe();
}
return Util.createItem(Material.BOOK, "Command", description);
}
@Override
public boolean manages(NPCShopAction action) {
return action instanceof CommandAction;
}
}
}

View File

@ -3,6 +3,7 @@ package net.citizensnpcs.util;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
@ -28,13 +29,18 @@ import org.bukkit.util.Vector;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import io.netty.util.Version;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCCollisionEvent;
import net.citizensnpcs.api.event.NPCPushEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.BoundingBox;
import net.citizensnpcs.api.util.Colorizer;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Placeholders;
import net.citizensnpcs.api.util.SpigotUtil;
import net.md_5.bungee.api.ChatColor;
@ -366,6 +372,50 @@ public class Util {
}
}
public static void runCommand(NPC npc, Player clicker, String command, boolean op, boolean player) {
List<String> split = Splitter.on(' ').omitEmptyStrings().trimResults().limit(2).splitToList(command);
String bungeeServer = split.size() == 2 && split.get(0).equalsIgnoreCase("server") ? split.get(1) : null;
String cmd = command;
if (command.startsWith("say")) {
cmd = "npc speak " + command.replaceFirst("say", "").trim() + " --target <p>";
}
if ((cmd.startsWith("npc ") || cmd.startsWith("waypoints ") || cmd.startsWith("wp "))
&& !cmd.contains("--id ")) {
cmd += " --id <id>";
}
String interpolatedCommand = Placeholders.replace(cmd, clicker, npc);
if (Messaging.isDebugging()) {
Messaging.debug("Running command " + interpolatedCommand + " on NPC " + (npc == null ? -1 : npc.getId())
+ " clicker " + clicker);
}
if (!player) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), interpolatedCommand);
return;
}
boolean wasOp = clicker.isOp();
if (op) {
clicker.setOp(true);
}
if (bungeeServer != null) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(bungeeServer);
clicker.sendPluginMessage(CitizensAPI.getPlugin(), "BungeeCord", out.toByteArray());
} else {
try {
clicker.chat("/" + interpolatedCommand);
} catch (Throwable t) {
t.printStackTrace();
}
}
if (op) {
clicker.setOp(wasOp);
}
}
/**
* Sets the entity's yaw and pitch directly including head yaw.
*/