From 833399e8d06b817b8227f91e8bd173ab0e40c66f Mon Sep 17 00:00:00 2001 From: Sekwah Date: Sat, 31 Aug 2024 03:47:36 +0200 Subject: [PATCH] feat: add command tags (#443) Co-authored-by: TreemanKing <67459602+TreemanKing@users.noreply.github.com> --- .github/workflows/pre-commit-check.yaml | 85 +++++----- .../core/AdvancedPortalsCore.java | 1 + .../advancedportals/core/CoreListeners.java | 2 + .../common/CreateTaggedSubCommand.java | 5 +- .../portal/CreatePortalSubCommand.java | 7 +- .../connector/containers/PlayerContainer.java | 3 + .../connector/containers/ServerContainer.java | 4 + .../core/portal/AdvancedPortal.java | 59 ++++--- .../core/repository/ConfigRepository.java | 3 + .../repository/impl/ConfigRepositoryImpl.java | 6 + .../serializeddata/ReflectiveConstructor.java | 4 +- .../config/CommandPortalConfig.java | 8 + .../core/serializeddata/config/Config.java | 2 + .../core/services/PortalServices.java | 3 +- .../core/tags/activation/CommandTag.java | 146 ++++++++++++++++++ .../core/tags/activation/CooldownTag.java | 4 +- .../core/tags/activation/PermissionTag.java | 4 +- .../core/util/FriendlyDataOutput.java | 6 +- .../core/warphandler/ActivationData.java | 6 +- lang/src/main/resources/lang/en_GB.lang | 9 +- .../container/SpigotPlayerContainer.java | 9 ++ .../container/SpigotServerContainer.java | 55 +++++++ 22 files changed, 335 insertions(+), 96 deletions(-) create mode 100644 core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/CommandPortalConfig.java create mode 100644 core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CommandTag.java diff --git a/.github/workflows/pre-commit-check.yaml b/.github/workflows/pre-commit-check.yaml index e745f3b8..58d1750c 100644 --- a/.github/workflows/pre-commit-check.yaml +++ b/.github/workflows/pre-commit-check.yaml @@ -13,53 +13,56 @@ concurrency: jobs: pre-commit-check: - permissions: - pull-requests: write if: github.event.action != 'labeled' || github.event.label.name == 'pre-commit ci run' name: Run pre-commit checks runs-on: ubuntu-20.04 steps: - - name: Checkout - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - run: gh pr edit ${{ github.event.number }} --remove-label 'pre-commit ci run' - if: github.event.action == 'labeled' && github.event.label.name == 'pre-commit ci run' - env: - GH_TOKEN: ${{ github.token }} - - uses: dorny/paths-filter@v2 - id: filter - with: - list-files: shell - filters: | - addedOrModified: - - added|modified: '**' + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - run: gh pr edit ${{ github.event.number }} --remove-label 'pre-commit ci run' + if: github.event.action == 'labeled' && github.event.label.name == 'pre-commit ci run' + env: + GH_TOKEN: ${{ github.token }} + - uses: dorny/paths-filter@v2 + id: filter + with: + list-files: shell + filters: | + addedOrModified: + - added|modified: '**' # run only if changed files were detected - - name: Run against changes - uses: pre-commit/action@v3.0.1 - if: steps.filter.outputs.addedOrModified == 'true' - with: - extra_args: --files ${{ steps.filter.outputs.addedOrModified_files }} + - name: Run against changes + uses: pre-commit/action@v3.0.1 + if: steps.filter.outputs.addedOrModified == 'true' + with: + extra_args: --files ${{ steps.filter.outputs.addedOrModified_files }} # run if no changed files were detected (e.g. workflow_dispatch on master branch) - - name: Run against all files - uses: pre-commit/action@v3.0.1 - if: steps.filter.outputs.addedOrModified != 'true' - with: - extra_args: --all-files - - uses: pre-commit-ci/lite-action@v1.0.2 - if: always() - with: - msg: apply code formatting + - name: Run against all files + uses: pre-commit/action@v3.0.1 + if: steps.filter.outputs.addedOrModified != 'true' + with: + extra_args: --all-files - - name: Commit pre-commit changes - if: always() && github.event.action != 'pull_request' && github.event.action != 'labeled' - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git add . - git commit -m "chore: pre-commit changes" || echo "No changes to commit" - git push ${{ github.head_ref }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Commit pre-commit changes + if: always() + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "chore: pre-commit changes [skip ci]" || echo "No changes to commit" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Push pre-commit changes + if: always() && github.event.action != 'pull_request' && github.event.action != 'labeled' && github.event.action != 'synchronize' + run: | + git push ${{ github.head_ref }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: pre-commit-ci/lite-action@v1.0.2 + if: always() 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 3bbd8c62..87112b52 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -128,6 +128,7 @@ public class AdvancedPortalsCore { 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/CoreListeners.java b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java index a3951bc6..16124d0a 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java @@ -31,6 +31,7 @@ public class CoreListeners { public void playerJoin(PlayerContainer player) { this.playerDataServices.setJoinCooldown(player); + this.playerDataServices.getPlayerData(player).setInPortal(true); } public void teleportEvent(PlayerContainer player) { @@ -173,6 +174,7 @@ public class CoreListeners { public void worldChange(PlayerContainer player) { this.playerDataServices.setJoinCooldown(player); + this.playerDataServices.getPlayerData(player).setInPortal(true); } public boolean preventEntityCombust(EntityContainer entity) { diff --git a/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/common/CreateTaggedSubCommand.java b/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/common/CreateTaggedSubCommand.java index 3a2378ea..566285c4 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/common/CreateTaggedSubCommand.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/common/CreateTaggedSubCommand.java @@ -75,8 +75,9 @@ public abstract class CreateTaggedSubCommand implements SubCommand { String baseString = endsWithSplit ? argData : argData.substring( - 0, - argData.lastIndexOf(multiTagSplit) + 1); + 0, + argData.lastIndexOf(multiTagSplit) + + 1); tagSuggestions = tagSuggestions diff --git a/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/CreatePortalSubCommand.java b/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/CreatePortalSubCommand.java index 762ff4f8..17ba71dd 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/CreatePortalSubCommand.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/CreatePortalSubCommand.java @@ -48,12 +48,7 @@ public class CreatePortalSubCommand extends CreateTaggedSubCommand { // Find the tag with the "name" NAME DataTag nameTag = portalTags.stream() - .filter(tag -> { - this.infoLogger.info("Tag: " + tag.NAME); - this.infoLogger.info( - "Equals: " + tag.NAME.equals(NameTag.TAG_NAME)); - return tag.NAME.equals(NameTag.TAG_NAME); - }) + .filter(tag -> tag.NAME.equals(NameTag.TAG_NAME)) .findFirst() .orElse(null); 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 f51fb6b8..b50510a5 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 @@ -1,6 +1,7 @@ package com.sekwah.advancedportals.core.connector.containers; import com.sekwah.advancedportals.core.serializeddata.BlockLocation; +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); + + ServerContainer getServer(); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/ServerContainer.java b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/ServerContainer.java index c074612d..ad73b423 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/ServerContainer.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/ServerContainer.java @@ -1,5 +1,6 @@ package com.sekwah.advancedportals.core.connector.containers; +import com.sekwah.advancedportals.core.tags.activation.CommandTag; import java.util.List; import java.util.UUID; @@ -13,4 +14,7 @@ public interface ServerContainer { List getTriggerBlocks(); PlayerContainer[] getPlayers(); + + void dispatchCommand(UUID uuid, String command, + CommandTag.CommandLevel commandLevel); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java b/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java index 02b14b63..d044ccaa 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java @@ -13,6 +13,7 @@ import com.sekwah.advancedportals.core.tags.activation.TriggerBlockTag; import com.sekwah.advancedportals.core.util.Lang; import com.sekwah.advancedportals.core.warphandler.ActivationData; import com.sekwah.advancedportals.core.warphandler.Tag; + import java.util.*; /** @@ -104,28 +105,27 @@ public class AdvancedPortal implements TagTarget { }*/ /** - * @param player The player on the server attempting to use an advanced - * portal + * @param player The player on the server attempting to use an advanced + * portal * @param moveActivated if the portal was activated by a move event (won't - * trigger knockback) + * trigger knockback) * @return */ public boolean activate(PlayerContainer player, boolean moveActivated) { var playerData = playerDataServices.getPlayerData(player); if (playerData.isInPortal()) return false; - playerData.setInPortal(true); if (playerData.hasJoinCooldown()) { var cooldown = - (int) Math.ceil(playerData.getJoinCooldownLeft() / 1000D); + (int) Math.ceil(playerData.getJoinCooldownLeft() / 1000D); player.sendMessage(Lang.translateInsertVariables( - "portal.cooldown.join", cooldown, - Lang.translate(cooldown == 1 ? "time.second" - : "time.seconds"))); + "portal.cooldown.join", cooldown, + Lang.translate(cooldown == 1 ? "time.second" + : "time.seconds"))); if (configRepository.playFailSound()) { var rand = new Random(); player.playSound("block.portal.travel", 0.05f, - rand.nextFloat() * 0.4F + 0.8F); + rand.nextFloat() * 0.4F + 0.8F); } return false; } @@ -139,36 +139,33 @@ public class AdvancedPortal implements TagTarget { for (DataTag portalTag : portalTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(portalTag.NAME); - if (activationHandler != null) { - if (!activationHandler.preActivated( - this, player, data, - this.getArgValues(portalTag.NAME))) { - return false; - } + tagRegistry.getActivationHandler(portalTag.NAME); + if (activationHandler != null && !activationHandler.preActivated( + this, player, data, + this.getArgValues(portalTag.NAME))) { + return false; } } for (DataTag portalTag : portalTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(portalTag.NAME); - if (activationHandler != null) { - if (!activationHandler.activated( - this, player, data, - this.getArgValues(portalTag.NAME))) { - return false; - } + tagRegistry.getActivationHandler(portalTag.NAME); + if (activationHandler != null && !activationHandler.activated( + this, player, data, + this.getArgValues(portalTag.NAME))) { + return false; } } for (DataTag portalTag : portalTags) { Tag.Activation activationHandler = - tagRegistry.getActivationHandler(portalTag.NAME); + tagRegistry.getActivationHandler(portalTag.NAME); if (activationHandler != null) { activationHandler.postActivated( - this, player, data, this.getArgValues(portalTag.NAME)); + this, player, data, this.getArgValues(portalTag.NAME)); } } if (data.hasActivated()) { playerData.setNetherPortalCooldown(1000); + playerData.setInPortal(true); return true; } return false; @@ -192,12 +189,12 @@ public class AdvancedPortal implements TagTarget { double playerZ = loc.getPosZ(); return Objects.equals(loc.getWorldName(), this.minLoc.getWorldName()) - && playerX >= this.minLoc.getPosX() - additionalArea - && playerX < this.maxLoc.getPosX() + 1 + additionalArea - && playerY >= this.minLoc.getPosY() - additionalArea - && playerY < this.maxLoc.getPosY() + 1 + additionalArea - && playerZ >= this.minLoc.getPosZ() - additionalArea - && playerZ < this.maxLoc.getPosZ() + 1 + additionalArea; + && playerX >= this.minLoc.getPosX() - additionalArea + && playerX < this.maxLoc.getPosX() + 1 + additionalArea + && playerY >= this.minLoc.getPosY() - additionalArea + && playerY < this.maxLoc.getPosY() + 1 + additionalArea + && playerZ >= this.minLoc.getPosZ() - additionalArea + && playerZ < this.maxLoc.getPosZ() + 1 + additionalArea; } public void setArgValues(DataTag portalTag) { diff --git a/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java b/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java index 8cf4efb3..335f0f6a 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java @@ -1,6 +1,7 @@ package com.sekwah.advancedportals.core.repository; import com.sekwah.advancedportals.core.serializeddata.DataStorage; +import com.sekwah.advancedportals.core.serializeddata.config.CommandPortalConfig; public interface ConfigRepository { boolean getUseOnlySpecialAxe(); @@ -32,4 +33,6 @@ public interface ConfigRepository { boolean playFailSound(); void storeConfig(); + + CommandPortalConfig getCommandPortals(); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java b/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java index 35ab286e..c2ffc783 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java @@ -3,6 +3,7 @@ package com.sekwah.advancedportals.core.repository.impl; import com.google.inject.Singleton; import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.serializeddata.DataStorage; +import com.sekwah.advancedportals.core.serializeddata.config.CommandPortalConfig; import com.sekwah.advancedportals.core.serializeddata.config.Config; import java.util.HashMap; @@ -95,6 +96,11 @@ public class ConfigRepositoryImpl implements ConfigRepository { return this.config.playFailSound; } + @Override + public CommandPortalConfig getCommandPortals() { + return this.config.commandPortals; + } + @Override public void storeConfig() { this.dataStorage.storeFile(this.config, "config.yaml"); diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/ReflectiveConstructor.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/ReflectiveConstructor.java index faba0051..f4c51bc6 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/ReflectiveConstructor.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/ReflectiveConstructor.java @@ -127,8 +127,8 @@ public class ReflectiveConstructor extends Constructor { } } catch (Exception e) { infoLogger.warning("Failed to set field " + field.getName() - + " in " + currentClass.getName() + ": " - + e.getMessage()); + + " in " + currentClass.getName() + + ": " + e.getMessage()); infoLogger.error(e); throw new RuntimeException("Failed to set field " + field.getName() + " in " diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/CommandPortalConfig.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/CommandPortalConfig.java new file mode 100644 index 00000000..67efae08 --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/CommandPortalConfig.java @@ -0,0 +1,8 @@ +package com.sekwah.advancedportals.core.serializeddata.config; + +public class CommandPortalConfig { + public final boolean op = true; + public final boolean console = true; + + public final boolean permsWildcard = true; +} diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java index d1216ab6..06191c47 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java @@ -33,4 +33,6 @@ public class Config { public double throwbackStrength = 0.7; public boolean playFailSound = true; + + public CommandPortalConfig commandPortals = new CommandPortalConfig(); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java index 0361127d..0fc78df6 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java @@ -95,7 +95,8 @@ public class PortalServices { } } var playerData = playerDataServices.getPlayerData(player); - if (!notInPortal) { + if (!playerData.isInPortal() && !notInPortal) { + playerData.setInPortal(true); var strength = configRepository.getThrowbackStrength(); PlayerUtils.throwPlayerBack(player, strength); } 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..3f2fc4a7 --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CommandTag.java @@ -0,0 +1,146 @@ +package com.sekwah.advancedportals.core.tags.activation; + +import com.google.inject.Inject; +import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; +import com.sekwah.advancedportals.core.registry.TagTarget; +import com.sekwah.advancedportals.core.repository.ConfigRepository; +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, Tag.Creation { + + @Inject + ConfigRepository configRepository; + + 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) { + for (String command : argData) { + char executionCommand = command.charAt(0); + String formattedCommand = + command.replaceAll("@player", player.getName()); + + switch (executionCommand) { + case '!': + player.getServer().dispatchCommand( + player.getUUID(), formattedCommand.substring(1), + CommandLevel.OP); + break; + case '#': + player.getServer().dispatchCommand( + player.getUUID(), formattedCommand.substring(1), + CommandLevel.CONSOLE); + break; + case '^': + player.getServer().dispatchCommand( + player.getUUID(), formattedCommand.substring(1), + CommandLevel.PERMISSION_WILDCARD); + break; + default: + player.getServer().dispatchCommand(player.getUUID(), + formattedCommand, + CommandLevel.PLAYER); + break; + } + } + } + + @Override + public boolean activated(TagTarget target, PlayerContainer player, + ActivationData activationData, String[] argData) { + // Will trigger in the post activation stage to make sure the command triggers after any teleportation + activationData.setWarpStatus(ActivationData.WarpedStatus.ACTIVATED); + return true; + } + + @Override + public boolean created(TagTarget target, PlayerContainer player, + String[] argData) { + if (argData != null) { + for (String command : argData) { + char executionCommand = command.charAt(0); + return switch (executionCommand) { + case '!' -> { + if (!player.hasPermission("advancedportals.createportal.commandlevel.op")) { + player.sendMessage(Lang.translateInsertVariables("tag.command.nopermission", "OP")); + yield false; + } + yield true; + } + case '#' -> { + if (!player.hasPermission("advancedportals.createportal.commandlevel.console")) { + player.sendMessage(Lang.translateInsertVariables("tag.command.nopermission","Console")); + yield false; + } + yield true; + } + case '^' -> { + if (!player.hasPermission("advancedportals.createportal.commandlevel.permswild")) { + player.sendMessage(Lang.translateInsertVariables("tag.command.nopermission", "*")); + yield false; + } + yield true; + } + default -> true; + }; + } + } + return false; + } + + @Override + public void destroyed(TagTarget target, PlayerContainer player, String[] argData) { + // Needs created but not destroyed + } + + public enum CommandLevel{ + OP, + PERMISSION_WILDCARD, + CONSOLE, + PLAYER + } +} diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java index f4897ca5..c4cf91d1 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java @@ -19,10 +19,10 @@ import javax.annotation.Nullable; public class CooldownTag implements Tag.Activation, Tag.Creation { @Inject - transient PlayerDataServices playerDataServices; + PlayerDataServices playerDataServices; @Inject - transient ConfigRepository configRepository; + ConfigRepository configRepository; @Inject private InfoLogger infoLogger; diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/PermissionTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/PermissionTag.java index 65cfa6e4..910110bf 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/PermissionTag.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/PermissionTag.java @@ -13,10 +13,10 @@ import javax.inject.Inject; public class PermissionTag implements Tag.Activation { @Inject - transient PlayerDataServices playerDataServices; + PlayerDataServices playerDataServices; @Inject - transient ConfigRepository configRepository; + ConfigRepository configRepository; @Inject private InfoLogger infoLogger; diff --git a/core/src/main/java/com/sekwah/advancedportals/core/util/FriendlyDataOutput.java b/core/src/main/java/com/sekwah/advancedportals/core/util/FriendlyDataOutput.java index b829b118..aeafe78f 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/util/FriendlyDataOutput.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/util/FriendlyDataOutput.java @@ -51,13 +51,15 @@ public class FriendlyDataOutput { public void writeUtf(String text, int maxLength) { if (text.length() > maxLength) { throw new EncoderException("String too big (was " + text.length() - + " characters, max " + maxLength + ")"); + + " characters, max " + maxLength + + ")"); } else { byte[] abyte = text.getBytes(StandardCharsets.UTF_8); int i = getMaxEncodedUtfLength(maxLength); if (abyte.length > i) { throw new EncoderException("String too big (was " + abyte.length - + " bytes encoded, max " + i + ")"); + + " bytes encoded, max " + i + + ")"); } else { this.writeVarInt(abyte.length); this.writeBytes(abyte); diff --git a/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java b/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java index f1c1b7b3..32a2d3f9 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java @@ -25,10 +25,8 @@ public class ActivationData { } public void setWarpStatus(WarpedStatus warped) { - if (this.warpStatus == WarpedStatus.WARPED) { - return; - } else if (this.warpStatus == WarpedStatus.ACTIVATED - && warped != WarpedStatus.WARPED) { + if (this.warpStatus == WarpedStatus.WARPED || (this.warpStatus == WarpedStatus.ACTIVATED + && warped != WarpedStatus.WARPED)) { return; } this.warpStatus = warped; diff --git a/lang/src/main/resources/lang/en_GB.lang b/lang/src/main/resources/lang/en_GB.lang index 32f419df..95dee468 100644 --- a/lang/src/main/resources/lang/en_GB.lang +++ b/lang/src/main/resources/lang/en_GB.lang @@ -102,8 +102,8 @@ command.destination.show.unsupported= Destination markers are not supported on t command.destination.teleport.help=Teleports to specified destination. command.destination.teleport.detailedhelp=Teleports to destination given by the name of the destination. -command.destination.teleport.error=There was an error teleporting to your destination (@destiname). -command.destination.teleport.success=You have teleported to destination (@destiname). +command.destination.teleport.error= There was an error teleporting to your destination (@destiname). +command.destination.teleport.success= You have teleported to destination (@destiname). command.destination.reload.help=Reloads the destination data from the repository. command.destination.reload.detailedhelp=This command will reload all destination data from the repository, updating the cache with the latest data. @@ -172,6 +172,9 @@ 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.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. +tag.command.nopermission= You do not have permission to create a command at %1$s command level +tag.command.notenabled= Command portals of %1$s level are not enabled on this server. 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 34bf9889..50d9d822 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 @@ -3,8 +3,10 @@ package com.sekwah.advancedportals.spigot.connector.container; import com.google.inject.Inject; import com.sekwah.advancedportals.core.AdvancedPortalsCore; import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; +import com.sekwah.advancedportals.core.connector.containers.ServerContainer; 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.spigot.AdvancedPortalsPlugin; import com.sekwah.advancedportals.spigot.reflection.MinecraftCustomPayload; import java.util.Arrays; @@ -12,9 +14,11 @@ import java.util.UUID; 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; /** * Just a temporary container for whenever advanced portals needs to get data @@ -112,4 +116,9 @@ public class SpigotPlayerContainer public void playSound(String sound, float volume, float pitch) { this.player.playSound(this.player.getLocation(), sound, volume, pitch); } + + @Override + public ServerContainer getServer() { + return new SpigotServerContainer(this.player.getServer()); + } } diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotServerContainer.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotServerContainer.java index 6b1f9161..ea73c220 100644 --- a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotServerContainer.java +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotServerContainer.java @@ -3,12 +3,15 @@ package com.sekwah.advancedportals.spigot.connector.container; import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; import com.sekwah.advancedportals.core.connector.containers.ServerContainer; import com.sekwah.advancedportals.core.connector.containers.WorldContainer; +import com.sekwah.advancedportals.core.tags.activation.CommandTag; import java.util.Arrays; import java.util.List; import java.util.UUID; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.permissions.PermissionAttachment; public class SpigotServerContainer implements ServerContainer { private final Server server; @@ -72,4 +75,56 @@ public class SpigotServerContainer implements ServerContainer { default -> false; }; } + + @Override + public void dispatchCommand(UUID uuid, String command, CommandTag.CommandLevel commandLevel) { + Player player = server.getPlayer(uuid); + switch (commandLevel) { + case CONSOLE: + server.dispatchCommand(server.getConsoleSender(), command); + break; + case PLAYER: + server.dispatchCommand(player, command); + break; + case OP, PERMISSION_WILDCARD: + executeCommandWithPermission(player, server, command, + commandLevel); + break; + } + } + + // Execute commands with elevated permissions method + private void executeCommandWithPermission( + Player player, Server server, String command, + CommandTag.CommandLevel commandLevel) { + switch (commandLevel) { + case PERMISSION_WILDCARD: + if (player.hasPermission("*")) { + server.dispatchCommand(player, command); + return; + } + PermissionAttachment permissionAttachment = + player.addAttachment( + server.getPluginManager().getPlugin("AdvancedPortals")); + try { + permissionAttachment.setPermission("*", true); + server.dispatchCommand(player, command); + } finally { + player.removeAttachment(permissionAttachment); + } + break; + case OP: + if (player.isOp()) { + server.dispatchCommand(player, command); + return; + } + try { + player.setOp(true); + server.dispatchCommand(player, command); + } finally { + player.setOp(false); + } + break; + } + } }