diff --git a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java index 1b0afded..bc77c1d8 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -119,6 +119,7 @@ private void registerTags() { this.tagRegistry.registerTag(new CooldownTag()); this.tagRegistry.registerTag(new TriggerBlockTag()); this.tagRegistry.registerTag(new PermissionTag()); + this.tagRegistry.registerTag(new CommandTag()); } /** diff --git a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java index f6db6e96..0f7571fb 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java @@ -2,6 +2,7 @@ import com.sekwah.advancedportals.core.serializeddata.BlockLocation; import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; +import com.sekwah.advancedportals.core.tags.activation.CommandTag; import java.util.UUID; @@ -37,4 +38,6 @@ public interface PlayerContainer extends EntityContainer { boolean sendPacket(String channel, byte[] bytes); void playSound(String sound, float volume, float pitch); + + void performCommand(String string, CommandTag.CommandLevel commandLevel); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CommandTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CommandTag.java new file mode 100644 index 00000000..f3ea0350 --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CommandTag.java @@ -0,0 +1,88 @@ +package com.sekwah.advancedportals.core.tags.activation; + +import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; +import com.sekwah.advancedportals.core.registry.TagTarget; +import com.sekwah.advancedportals.core.util.Lang; +import com.sekwah.advancedportals.core.warphandler.ActivationData; +import com.sekwah.advancedportals.core.warphandler.Tag; +import javax.annotation.Nullable; + +public class CommandTag implements Tag.Activation, Tag.Split{ + + public static String TAG_NAME = "command"; + + private final TagType[] tagTypes = new TagType[]{ TagType.PORTAL }; + + @Override + public TagType[] getTagTypes() { + return tagTypes; + } + + @Override + public String getName() { + return TAG_NAME; + } + + @Nullable + @Override + public String[] getAliases() { + return null; + } + + @Override + public String description() { + return Lang.translate("tag.command.description"); + } + + @Nullable + @Override + public String splitString() { + return ","; + } + + @Override + public boolean preActivated(TagTarget target, PlayerContainer player, ActivationData activeData, String[] argData) { + return true; + } + //TODO: Check if its worth autocompleting an existing command in the command tag by + // grabbing all commands in the server + + //TODO: Add a warning in console if op/* command is used and tell them to use console instead + @Override + public void postActivated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + if(activationData.hasActivated()) { + for (String command : argData) { + + String formattedCommand = command.replaceAll("@player", player.getName()); + char executionCommand = formattedCommand.charAt(0); + + switch (executionCommand) { + case '!': + player.performCommand(formattedCommand.substring(1),CommandLevel.OP); + break; + case '#': + player.performCommand(formattedCommand.substring(1), CommandLevel.CONSOLE); + break; + case '^': + player.performCommand(formattedCommand.substring(1), CommandLevel.STAR); + break; + default: + player.performCommand(formattedCommand, CommandLevel.PLAYER); + break; + } + } + } + } + + @Override + public boolean activated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + return true; + } + + public enum CommandLevel{ + OP, + STAR, + CONSOLE, + PLAYER + } +} diff --git a/lang/src/main/resources/lang/en_GB.lang b/lang/src/main/resources/lang/en_GB.lang index 125f5e48..9f356252 100644 --- a/lang/src/main/resources/lang/en_GB.lang +++ b/lang/src/main/resources/lang/en_GB.lang @@ -162,7 +162,7 @@ items.interact.right=Right Click tag.permission.description=Sets the permission of a portal tag.desti.description=Sets the destination of the portal tag.name.error.nospaces= The name cannot contain spaces. -tag.triggerblock.description=Sets the trigger block/s of the portal. Comma seperated or multi tag. - -tag.cooldown.fail= The cooldown must be a number. +tag.triggerblock.description=Sets the trigger block/s of the portal. Comma separated or multi tag. +tag.command.description=Sets a command on the post activation of the portal. Comma separated or multi tag. +tag.cooldown.fail= The cooldown must be a number. \ No newline at end of file diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java index 3c5034d0..b6f07c23 100644 --- a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java @@ -6,16 +6,24 @@ import com.sekwah.advancedportals.core.connector.containers.WorldContainer; import com.sekwah.advancedportals.core.serializeddata.BlockLocation; import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; +import com.sekwah.advancedportals.core.tags.activation.CommandTag; +import com.sekwah.advancedportals.core.util.InfoLogger; +import com.sekwah.advancedportals.core.util.Lang; import com.sekwah.advancedportals.spigot.AdvancedPortalsPlugin; import com.sekwah.advancedportals.spigot.reflection.MinecraftCustomPayload; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.ServerOperator; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; /** @@ -23,6 +31,9 @@ */ public class SpigotPlayerContainer extends SpigotEntityContainer implements PlayerContainer { + @Inject + private InfoLogger infoLogger; + @Inject private AdvancedPortalsCore portalsCore; @@ -106,4 +117,42 @@ public Player getPlayer() { public void playSound(String sound, float volume, float pitch) { this.player.playSound(this.player.getLocation(), sound, volume, pitch); } + + @Override + public void performCommand(String command, CommandTag.CommandLevel commandLevel) { + Server server = this.player.getServer(); + switch (commandLevel) { + case CONSOLE: + server.dispatchCommand(server.getConsoleSender(), command); + break; + case PLAYER: + server.dispatchCommand(this.getPlayer(), command); + break; + case OP, STAR: + executeCommandWithPermission(server, command, commandLevel); + break; + } + } + + private void executeCommandWithPermission (Server server, String command, CommandTag.CommandLevel commandLevel) { + switch (commandLevel) { + case STAR: + PermissionAttachment permissionAttachment = player.addAttachment(server.getPluginManager().getPlugin("AdvancedPortals")); + try { + permissionAttachment.setPermission("*", true); + server.dispatchCommand(player, command); + } finally { + player.removeAttachment(permissionAttachment); + } + break; + case OP: + try { + player.setOp(true); + server.dispatchCommand(player, command); + } finally { + player.setOp(false); + } + break; + } + } }