feat: add command tags (#443)

Co-authored-by: TreemanKing <67459602+TreemanKing@users.noreply.github.com>
This commit is contained in:
Sekwah 2024-08-31 03:47:36 +02:00
parent ab92ff1046
commit 833399e8d0
22 changed files with 335 additions and 96 deletions

View File

@ -13,53 +13,56 @@ concurrency:
jobs: jobs:
pre-commit-check: pre-commit-check:
permissions:
pull-requests: write
if: github.event.action != 'labeled' || github.event.label.name == 'pre-commit ci run' if: github.event.action != 'labeled' || github.event.label.name == 'pre-commit ci run'
name: Run pre-commit checks name: Run pre-commit checks
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
- run: gh pr edit ${{ github.event.number }} --remove-label 'pre-commit ci run' - 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' if: github.event.action == 'labeled' && github.event.label.name == 'pre-commit ci run'
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
- uses: dorny/paths-filter@v2 - uses: dorny/paths-filter@v2
id: filter id: filter
with: with:
list-files: shell list-files: shell
filters: | filters: |
addedOrModified: addedOrModified:
- added|modified: '**' - added|modified: '**'
# run only if changed files were detected # run only if changed files were detected
- name: Run against changes - name: Run against changes
uses: pre-commit/action@v3.0.1 uses: pre-commit/action@v3.0.1
if: steps.filter.outputs.addedOrModified == 'true' if: steps.filter.outputs.addedOrModified == 'true'
with: with:
extra_args: --files ${{ steps.filter.outputs.addedOrModified_files }} extra_args: --files ${{ steps.filter.outputs.addedOrModified_files }}
# run if no changed files were detected (e.g. workflow_dispatch on master branch) # run if no changed files were detected (e.g. workflow_dispatch on master branch)
- name: Run against all files - name: Run against all files
uses: pre-commit/action@v3.0.1 uses: pre-commit/action@v3.0.1
if: steps.filter.outputs.addedOrModified != 'true' if: steps.filter.outputs.addedOrModified != 'true'
with: with:
extra_args: --all-files extra_args: --all-files
- uses: pre-commit-ci/lite-action@v1.0.2
if: always()
with:
msg: apply code formatting
- name: Commit pre-commit changes - name: Commit pre-commit changes
if: always() && github.event.action != 'pull_request' && github.event.action != 'labeled' if: always()
run: | run: |
git config --global user.name "github-actions[bot]" git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com" git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add . git add .
git commit -m "chore: pre-commit changes" || echo "No changes to commit" git commit -m "chore: pre-commit changes [skip ci]" || echo "No changes to commit"
git push ${{ github.head_ref }} env:
env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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()

View File

@ -128,6 +128,7 @@ public class AdvancedPortalsCore {
this.tagRegistry.registerTag(new CooldownTag()); this.tagRegistry.registerTag(new CooldownTag());
this.tagRegistry.registerTag(new TriggerBlockTag()); this.tagRegistry.registerTag(new TriggerBlockTag());
this.tagRegistry.registerTag(new PermissionTag()); this.tagRegistry.registerTag(new PermissionTag());
this.tagRegistry.registerTag(new CommandTag());
} }
/** /**

View File

@ -31,6 +31,7 @@ public class CoreListeners {
public void playerJoin(PlayerContainer player) { public void playerJoin(PlayerContainer player) {
this.playerDataServices.setJoinCooldown(player); this.playerDataServices.setJoinCooldown(player);
this.playerDataServices.getPlayerData(player).setInPortal(true);
} }
public void teleportEvent(PlayerContainer player) { public void teleportEvent(PlayerContainer player) {
@ -173,6 +174,7 @@ public class CoreListeners {
public void worldChange(PlayerContainer player) { public void worldChange(PlayerContainer player) {
this.playerDataServices.setJoinCooldown(player); this.playerDataServices.setJoinCooldown(player);
this.playerDataServices.getPlayerData(player).setInPortal(true);
} }
public boolean preventEntityCombust(EntityContainer entity) { public boolean preventEntityCombust(EntityContainer entity) {

View File

@ -75,8 +75,9 @@ public abstract class CreateTaggedSubCommand implements SubCommand {
String baseString = endsWithSplit String baseString = endsWithSplit
? argData ? argData
: argData.substring( : argData.substring(
0, 0,
argData.lastIndexOf(multiTagSplit) + 1); argData.lastIndexOf(multiTagSplit)
+ 1);
tagSuggestions = tagSuggestions =
tagSuggestions tagSuggestions

View File

@ -48,12 +48,7 @@ public class CreatePortalSubCommand extends CreateTaggedSubCommand {
// Find the tag with the "name" NAME // Find the tag with the "name" NAME
DataTag nameTag = DataTag nameTag =
portalTags.stream() portalTags.stream()
.filter(tag -> { .filter(tag -> tag.NAME.equals(NameTag.TAG_NAME))
this.infoLogger.info("Tag: " + tag.NAME);
this.infoLogger.info(
"Equals: " + tag.NAME.equals(NameTag.TAG_NAME));
return tag.NAME.equals(NameTag.TAG_NAME);
})
.findFirst() .findFirst()
.orElse(null); .orElse(null);

View File

@ -1,6 +1,7 @@
package com.sekwah.advancedportals.core.connector.containers; package com.sekwah.advancedportals.core.connector.containers;
import com.sekwah.advancedportals.core.serializeddata.BlockLocation; import com.sekwah.advancedportals.core.serializeddata.BlockLocation;
import com.sekwah.advancedportals.core.tags.activation.CommandTag;
import java.util.UUID; import java.util.UUID;
/** /**
@ -37,4 +38,6 @@ public interface PlayerContainer extends EntityContainer {
boolean sendPacket(String channel, byte[] bytes); boolean sendPacket(String channel, byte[] bytes);
void playSound(String sound, float volume, float pitch); void playSound(String sound, float volume, float pitch);
ServerContainer getServer();
} }

View File

@ -1,5 +1,6 @@
package com.sekwah.advancedportals.core.connector.containers; package com.sekwah.advancedportals.core.connector.containers;
import com.sekwah.advancedportals.core.tags.activation.CommandTag;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -13,4 +14,7 @@ public interface ServerContainer {
List<String> getTriggerBlocks(); List<String> getTriggerBlocks();
PlayerContainer[] getPlayers(); PlayerContainer[] getPlayers();
void dispatchCommand(UUID uuid, String command,
CommandTag.CommandLevel commandLevel);
} }

View File

@ -13,6 +13,7 @@ import com.sekwah.advancedportals.core.tags.activation.TriggerBlockTag;
import com.sekwah.advancedportals.core.util.Lang; import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.warphandler.ActivationData; import com.sekwah.advancedportals.core.warphandler.ActivationData;
import com.sekwah.advancedportals.core.warphandler.Tag; import com.sekwah.advancedportals.core.warphandler.Tag;
import java.util.*; import java.util.*;
/** /**
@ -104,28 +105,27 @@ public class AdvancedPortal implements TagTarget {
}*/ }*/
/** /**
* @param player The player on the server attempting to use an advanced * @param player The player on the server attempting to use an advanced
* portal * portal
* @param moveActivated if the portal was activated by a move event (won't * @param moveActivated if the portal was activated by a move event (won't
* trigger knockback) * trigger knockback)
* @return * @return
*/ */
public boolean activate(PlayerContainer player, boolean moveActivated) { public boolean activate(PlayerContainer player, boolean moveActivated) {
var playerData = playerDataServices.getPlayerData(player); var playerData = playerDataServices.getPlayerData(player);
if (playerData.isInPortal()) if (playerData.isInPortal())
return false; return false;
playerData.setInPortal(true);
if (playerData.hasJoinCooldown()) { if (playerData.hasJoinCooldown()) {
var cooldown = var cooldown =
(int) Math.ceil(playerData.getJoinCooldownLeft() / 1000D); (int) Math.ceil(playerData.getJoinCooldownLeft() / 1000D);
player.sendMessage(Lang.translateInsertVariables( player.sendMessage(Lang.translateInsertVariables(
"portal.cooldown.join", cooldown, "portal.cooldown.join", cooldown,
Lang.translate(cooldown == 1 ? "time.second" Lang.translate(cooldown == 1 ? "time.second"
: "time.seconds"))); : "time.seconds")));
if (configRepository.playFailSound()) { if (configRepository.playFailSound()) {
var rand = new Random(); var rand = new Random();
player.playSound("block.portal.travel", 0.05f, player.playSound("block.portal.travel", 0.05f,
rand.nextFloat() * 0.4F + 0.8F); rand.nextFloat() * 0.4F + 0.8F);
} }
return false; return false;
} }
@ -139,36 +139,33 @@ public class AdvancedPortal implements TagTarget {
for (DataTag portalTag : portalTags) { for (DataTag portalTag : portalTags) {
Tag.Activation activationHandler = Tag.Activation activationHandler =
tagRegistry.getActivationHandler(portalTag.NAME); tagRegistry.getActivationHandler(portalTag.NAME);
if (activationHandler != null) { if (activationHandler != null && !activationHandler.preActivated(
if (!activationHandler.preActivated( this, player, data,
this, player, data, this.getArgValues(portalTag.NAME))) {
this.getArgValues(portalTag.NAME))) { return false;
return false;
}
} }
} }
for (DataTag portalTag : portalTags) { for (DataTag portalTag : portalTags) {
Tag.Activation activationHandler = Tag.Activation activationHandler =
tagRegistry.getActivationHandler(portalTag.NAME); tagRegistry.getActivationHandler(portalTag.NAME);
if (activationHandler != null) { if (activationHandler != null && !activationHandler.activated(
if (!activationHandler.activated( this, player, data,
this, player, data, this.getArgValues(portalTag.NAME))) {
this.getArgValues(portalTag.NAME))) { return false;
return false;
}
} }
} }
for (DataTag portalTag : portalTags) { for (DataTag portalTag : portalTags) {
Tag.Activation activationHandler = Tag.Activation activationHandler =
tagRegistry.getActivationHandler(portalTag.NAME); tagRegistry.getActivationHandler(portalTag.NAME);
if (activationHandler != null) { if (activationHandler != null) {
activationHandler.postActivated( activationHandler.postActivated(
this, player, data, this.getArgValues(portalTag.NAME)); this, player, data, this.getArgValues(portalTag.NAME));
} }
} }
if (data.hasActivated()) { if (data.hasActivated()) {
playerData.setNetherPortalCooldown(1000); playerData.setNetherPortalCooldown(1000);
playerData.setInPortal(true);
return true; return true;
} }
return false; return false;
@ -192,12 +189,12 @@ public class AdvancedPortal implements TagTarget {
double playerZ = loc.getPosZ(); double playerZ = loc.getPosZ();
return Objects.equals(loc.getWorldName(), this.minLoc.getWorldName()) return Objects.equals(loc.getWorldName(), this.minLoc.getWorldName())
&& playerX >= this.minLoc.getPosX() - additionalArea && playerX >= this.minLoc.getPosX() - additionalArea
&& playerX < this.maxLoc.getPosX() + 1 + additionalArea && playerX < this.maxLoc.getPosX() + 1 + additionalArea
&& playerY >= this.minLoc.getPosY() - additionalArea && playerY >= this.minLoc.getPosY() - additionalArea
&& playerY < this.maxLoc.getPosY() + 1 + additionalArea && playerY < this.maxLoc.getPosY() + 1 + additionalArea
&& playerZ >= this.minLoc.getPosZ() - additionalArea && playerZ >= this.minLoc.getPosZ() - additionalArea
&& playerZ < this.maxLoc.getPosZ() + 1 + additionalArea; && playerZ < this.maxLoc.getPosZ() + 1 + additionalArea;
} }
public void setArgValues(DataTag portalTag) { public void setArgValues(DataTag portalTag) {

View File

@ -1,6 +1,7 @@
package com.sekwah.advancedportals.core.repository; package com.sekwah.advancedportals.core.repository;
import com.sekwah.advancedportals.core.serializeddata.DataStorage; import com.sekwah.advancedportals.core.serializeddata.DataStorage;
import com.sekwah.advancedportals.core.serializeddata.config.CommandPortalConfig;
public interface ConfigRepository { public interface ConfigRepository {
boolean getUseOnlySpecialAxe(); boolean getUseOnlySpecialAxe();
@ -32,4 +33,6 @@ public interface ConfigRepository {
boolean playFailSound(); boolean playFailSound();
void storeConfig(); void storeConfig();
CommandPortalConfig getCommandPortals();
} }

View File

@ -3,6 +3,7 @@ package com.sekwah.advancedportals.core.repository.impl;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.repository.ConfigRepository;
import com.sekwah.advancedportals.core.serializeddata.DataStorage; import com.sekwah.advancedportals.core.serializeddata.DataStorage;
import com.sekwah.advancedportals.core.serializeddata.config.CommandPortalConfig;
import com.sekwah.advancedportals.core.serializeddata.config.Config; import com.sekwah.advancedportals.core.serializeddata.config.Config;
import java.util.HashMap; import java.util.HashMap;
@ -95,6 +96,11 @@ public class ConfigRepositoryImpl implements ConfigRepository {
return this.config.playFailSound; return this.config.playFailSound;
} }
@Override
public CommandPortalConfig getCommandPortals() {
return this.config.commandPortals;
}
@Override @Override
public void storeConfig() { public void storeConfig() {
this.dataStorage.storeFile(this.config, "config.yaml"); this.dataStorage.storeFile(this.config, "config.yaml");

View File

@ -127,8 +127,8 @@ public class ReflectiveConstructor<T> extends Constructor {
} }
} catch (Exception e) { } catch (Exception e) {
infoLogger.warning("Failed to set field " + field.getName() infoLogger.warning("Failed to set field " + field.getName()
+ " in " + currentClass.getName() + ": " + " in " + currentClass.getName()
+ e.getMessage()); + ": " + e.getMessage());
infoLogger.error(e); infoLogger.error(e);
throw new RuntimeException("Failed to set field " throw new RuntimeException("Failed to set field "
+ field.getName() + " in " + field.getName() + " in "

View File

@ -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;
}

View File

@ -33,4 +33,6 @@ public class Config {
public double throwbackStrength = 0.7; public double throwbackStrength = 0.7;
public boolean playFailSound = true; public boolean playFailSound = true;
public CommandPortalConfig commandPortals = new CommandPortalConfig();
} }

View File

@ -95,7 +95,8 @@ public class PortalServices {
} }
} }
var playerData = playerDataServices.getPlayerData(player); var playerData = playerDataServices.getPlayerData(player);
if (!notInPortal) { if (!playerData.isInPortal() && !notInPortal) {
playerData.setInPortal(true);
var strength = configRepository.getThrowbackStrength(); var strength = configRepository.getThrowbackStrength();
PlayerUtils.throwPlayerBack(player, strength); PlayerUtils.throwPlayerBack(player, strength);
} }

View File

@ -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
}
}

View File

@ -19,10 +19,10 @@ import javax.annotation.Nullable;
public class CooldownTag implements Tag.Activation, Tag.Creation { public class CooldownTag implements Tag.Activation, Tag.Creation {
@Inject @Inject
transient PlayerDataServices playerDataServices; PlayerDataServices playerDataServices;
@Inject @Inject
transient ConfigRepository configRepository; ConfigRepository configRepository;
@Inject @Inject
private InfoLogger infoLogger; private InfoLogger infoLogger;

View File

@ -13,10 +13,10 @@ import javax.inject.Inject;
public class PermissionTag implements Tag.Activation { public class PermissionTag implements Tag.Activation {
@Inject @Inject
transient PlayerDataServices playerDataServices; PlayerDataServices playerDataServices;
@Inject @Inject
transient ConfigRepository configRepository; ConfigRepository configRepository;
@Inject @Inject
private InfoLogger infoLogger; private InfoLogger infoLogger;

View File

@ -51,13 +51,15 @@ public class FriendlyDataOutput {
public void writeUtf(String text, int maxLength) { public void writeUtf(String text, int maxLength) {
if (text.length() > maxLength) { if (text.length() > maxLength) {
throw new EncoderException("String too big (was " + text.length() throw new EncoderException("String too big (was " + text.length()
+ " characters, max " + maxLength + ")"); + " characters, max " + maxLength
+ ")");
} else { } else {
byte[] abyte = text.getBytes(StandardCharsets.UTF_8); byte[] abyte = text.getBytes(StandardCharsets.UTF_8);
int i = getMaxEncodedUtfLength(maxLength); int i = getMaxEncodedUtfLength(maxLength);
if (abyte.length > i) { if (abyte.length > i) {
throw new EncoderException("String too big (was " + abyte.length throw new EncoderException("String too big (was " + abyte.length
+ " bytes encoded, max " + i + ")"); + " bytes encoded, max " + i
+ ")");
} else { } else {
this.writeVarInt(abyte.length); this.writeVarInt(abyte.length);
this.writeBytes(abyte); this.writeBytes(abyte);

View File

@ -25,10 +25,8 @@ public class ActivationData {
} }
public void setWarpStatus(WarpedStatus warped) { public void setWarpStatus(WarpedStatus warped) {
if (this.warpStatus == WarpedStatus.WARPED) { if (this.warpStatus == WarpedStatus.WARPED || (this.warpStatus == WarpedStatus.ACTIVATED
return; && warped != WarpedStatus.WARPED)) {
} else if (this.warpStatus == WarpedStatus.ACTIVATED
&& warped != WarpedStatus.WARPED) {
return; return;
} }
this.warpStatus = warped; this.warpStatus = warped;

View File

@ -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.help=Teleports to specified destination.
command.destination.teleport.detailedhelp=Teleports to destination given by the name of the 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.error= There was an error teleporting to your destination (@destiname).
command.destination.teleport.success=You have teleported to 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.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. 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.permission.description=Sets the permission of a portal
tag.desti.description=Sets the destination of the portal tag.desti.description=Sets the destination of the portal
tag.name.error.nospaces= The name cannot contain spaces. 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.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.

View File

@ -3,8 +3,10 @@ package com.sekwah.advancedportals.spigot.connector.container;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore; import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; 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.BlockLocation;
import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; 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.AdvancedPortalsPlugin;
import com.sekwah.advancedportals.spigot.reflection.MinecraftCustomPayload; import com.sekwah.advancedportals.spigot.reflection.MinecraftCustomPayload;
import java.util.Arrays; import java.util.Arrays;
@ -12,9 +14,11 @@ import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.permissions.PermissionAttachment;
/** /**
* Just a temporary container for whenever advanced portals needs to get data * 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) { public void playSound(String sound, float volume, float pitch) {
this.player.playSound(this.player.getLocation(), sound, volume, pitch); this.player.playSound(this.player.getLocation(), sound, volume, pitch);
} }
@Override
public ServerContainer getServer() {
return new SpigotServerContainer(this.player.getServer());
}
} }

View File

@ -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.PlayerContainer;
import com.sekwah.advancedportals.core.connector.containers.ServerContainer; import com.sekwah.advancedportals.core.connector.containers.ServerContainer;
import com.sekwah.advancedportals.core.connector.containers.WorldContainer; import com.sekwah.advancedportals.core.connector.containers.WorldContainer;
import com.sekwah.advancedportals.core.tags.activation.CommandTag;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionAttachment;
public class SpigotServerContainer implements ServerContainer { public class SpigotServerContainer implements ServerContainer {
private final Server server; private final Server server;
@ -72,4 +75,56 @@ public class SpigotServerContainer implements ServerContainer {
default -> false; 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;
}
}
} }