Skip to content

Commit

Permalink
Deduplicate triggered actions for blocks and entities (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
rymiel authored Feb 12, 2024
1 parent 1bf6100 commit 3528ff5
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 393 deletions.
205 changes: 3 additions & 202 deletions bukkit/src/main/java/org/popcraft/bolt/listeners/BlockListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.bukkit.util.Vector;
import org.popcraft.bolt.BoltPlugin;
import org.popcraft.bolt.access.Access;
import org.popcraft.bolt.event.LockBlockEvent;
import org.popcraft.bolt.lang.Translation;
import org.popcraft.bolt.matcher.Match;
import org.popcraft.bolt.protection.BlockProtection;
Expand All @@ -54,7 +53,6 @@
import org.popcraft.bolt.source.SourceResolver;
import org.popcraft.bolt.source.SourceTypeResolver;
import org.popcraft.bolt.source.SourceTypes;
import org.popcraft.bolt.util.Action;
import org.popcraft.bolt.util.BoltComponents;
import org.popcraft.bolt.util.BoltPlayer;
import org.popcraft.bolt.util.Doors;
Expand All @@ -66,28 +64,22 @@
import org.popcraft.bolt.util.ProtectableConfig;
import org.popcraft.bolt.util.Protections;
import org.popcraft.bolt.util.SchedulerUtil;
import org.popcraft.bolt.util.Time;

import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static org.popcraft.bolt.util.BoltComponents.resolveTranslation;
import static org.popcraft.bolt.util.BoltComponents.translateRaw;
import static org.popcraft.bolt.util.Profiles.NIL_UUID;

public final class BlockListener implements Listener {
public final class BlockListener extends InteractionListener implements Listener {
private static final SourceResolver REDSTONE_SOURCE_RESOLVER = new SourceTypeResolver(Source.of(SourceTypes.REDSTONE));
private static final EnumSet<Material> DYES = EnumSet.of(Material.WHITE_DYE, Material.ORANGE_DYE, Material.MAGENTA_DYE, Material.LIGHT_BLUE_DYE, Material.YELLOW_DYE, Material.LIME_DYE, Material.PINK_DYE, Material.GRAY_DYE, Material.LIGHT_GRAY_DYE, Material.CYAN_DYE, Material.PURPLE_DYE, Material.BLUE_DYE, Material.BROWN_DYE, Material.GREEN_DYE, Material.RED_DYE, Material.BLACK_DYE);
private static final Material CHISELED_BOOKSHELF = EnumUtil.valueOf(Material.class, "CHISELED_BOOKSHELF").orElse(null);
private static final Material SCULK_SENSOR = EnumUtil.valueOf(Material.class, "SCULK_SENSOR").orElse(null);
private static final Material CALIBRATED_SCULK_SENSOR = EnumUtil.valueOf(Material.class, "CALIBRATED_SCULK_SENSOR").orElse(null);
private static final Material DECORATED_POT = EnumUtil.valueOf(Material.class, "DECORATED_POT").orElse(null);
private final BoltPlugin plugin;

public BlockListener(final BoltPlugin plugin) {
this.plugin = plugin;
super(plugin);
}

@EventHandler
Expand All @@ -109,7 +101,7 @@ public void onPlayerInteract(final PlayerInteractEvent e) {
}
final Protection protection = plugin.findProtection(clicked);
boolean shouldCancel = false;
if (triggerActions(player, protection, clicked)) {
if (triggerAction(player, protection, clicked)) {
boltPlayer.setInteracted(true);
SchedulerUtil.schedule(plugin, player, boltPlayer::clearInteraction);
shouldCancel = true;
Expand Down Expand Up @@ -207,197 +199,6 @@ public void onPlayerInteract(final PlayerInteractEvent e) {
}
}

private boolean triggerActions(final Player player, final Protection protection, final Block block) {
final BoltPlayer boltPlayer = plugin.player(player);
final Action action = boltPlayer.getAction();
if (action == null) {
return false;
}
if (!player.hasPermission(action.getPermission())) {
BoltComponents.sendMessage(player, Translation.COMMAND_NO_PERMISSION);
return false;
}
final Action.Type actionType = action.getType();
switch (actionType) {
case LOCK -> {
final LockBlockEvent event = new LockBlockEvent(player, block);
plugin.getEventBus().post(event);
if (event.isCancelled()) {
BoltComponents.sendMessage(
player,
Translation.CLICK_LOCKED_CANCELLED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
break;
}

final String protectionType = Optional.ofNullable(action.getData())
.flatMap(type -> plugin.getBolt().getAccessRegistry().getProtectionByType(type))
.map(Access::type)
.orElse(plugin.getDefaultProtectionType());
final ProtectableConfig protectableConfig = plugin.getProtectableConfig(block);
final boolean lockPermission = protectableConfig != null && protectableConfig.lockPermission();
if (protection != null) {
if (!protection.getType().equals(protectionType) && plugin.canAccess(protection, player, Permission.EDIT)) {
protection.setType(protectionType);
plugin.saveProtection(protection);
BoltComponents.sendMessage(
player,
Translation.CLICK_LOCKED_CHANGED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION_TYPE, Protections.protectionType(protection, player))
);
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_LOCKED_ALREADY,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(protection, player))
);
}
} else if (plugin.isProtectable(block) && (!lockPermission || player.hasPermission("bolt.protection.lock.%s".formatted(block.getType().name().toLowerCase())))) {
final BlockProtection newProtection = plugin.createProtection(block, boltPlayer.isLockNil() ? NIL_UUID : player.getUniqueId(), protectionType);
plugin.saveProtection(newProtection);
boltPlayer.setLockNil(false);
BoltComponents.sendMessage(
player,
Translation.CLICK_LOCKED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION_TYPE, Protections.protectionType(newProtection, player)),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_NOT_LOCKABLE,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
}
}
case UNLOCK -> {
if (protection != null) {
if (plugin.canAccess(protection, player, Permission.DESTROY)) {
plugin.removeProtection(protection);
BoltComponents.sendMessage(
player,
Translation.CLICK_UNLOCKED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION_TYPE, Protections.protectionType(protection, player)),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(protection, player))
);
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_UNLOCKED_NO_PERMISSION,
plugin.isUseActionBar()
);
}
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_NOT_LOCKED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
}
}
case INFO -> {
if (protection != null) {
final boolean showFull = protection.getOwner().equals(player.getUniqueId()) || player.hasPermission("bolt.command.info.full");
final boolean showAccessList = !protection.getAccess().isEmpty();
Profiles.findOrLookupProfileByUniqueId(protection.getOwner())
.thenAccept(profile -> SchedulerUtil.schedule(plugin, player, () -> BoltComponents.sendMessage(
player,
showFull ? (showAccessList ? Translation.INFO_FULL_ACCESS : Translation.INFO_FULL_NO_ACCESS) : Translation.INFO,
Placeholder.component(Translation.Placeholder.PROTECTION_TYPE, Protections.protectionType(protection, player)),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(protection, player)),
Placeholder.component(Translation.Placeholder.PLAYER, Optional.ofNullable(profile.name()).<Component>map(Component::text).orElse(resolveTranslation(Translation.UNKNOWN, player))),
Placeholder.component(Translation.Placeholder.ACCESS_LIST_SIZE, Component.text(protection.getAccess().size())),
Placeholder.component(Translation.Placeholder.ACCESS_LIST, Protections.accessList(protection.getAccess(), player)),
Placeholder.component(Translation.Placeholder.CREATED_TIME, Time.relativeTimestamp(protection.getCreated(), player)),
Placeholder.component(Translation.Placeholder.ACCESSED_TIME, Time.relativeTimestamp(protection.getAccessed(), player))
)));
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_NOT_LOCKED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
}
}
case EDIT -> {
if (protection != null) {
if (plugin.canAccess(protection, player, Permission.EDIT)) {
boltPlayer.consumeModifications().forEach((source, type) -> {
if (Boolean.parseBoolean(action.getData())) {
protection.getAccess().put(source.toString(), type);
} else {
protection.getAccess().remove(source.toString());
}
});
plugin.saveProtection(protection);
BoltComponents.sendMessage(
player,
Translation.CLICK_EDITED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION_TYPE, Protections.protectionType(protection, player)),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(protection, player))
);
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_EDITED_NO_PERMISSION,
plugin.isUseActionBar()
);
}
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_NOT_LOCKED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
}
}
case DEBUG -> BoltComponents.sendMessage(
player,
Optional.ofNullable(protection).map(Protection::toString).toString()
);
case TRANSFER -> {
if (protection != null) {
if (player.getUniqueId().equals(protection.getOwner()) || action.isAdmin()) {
final UUID uuid = UUID.fromString(action.getData());
protection.setOwner(uuid);
plugin.saveProtection(protection);
Profiles.findOrLookupProfileByUniqueId(uuid)
.thenAccept(profile -> SchedulerUtil.schedule(plugin, player, () -> BoltComponents.sendMessage(
player,
Translation.CLICK_TRANSFER_CONFIRM,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION_TYPE, Protections.protectionType(protection, player)),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(protection, player)),
Placeholder.component(Translation.Placeholder.PLAYER, Optional.ofNullable(profile.name()).<Component>map(Component::text).orElse(resolveTranslation(Translation.UNKNOWN, player)))
)));
} else {
BoltComponents.sendMessage(player, Translation.CLICK_EDITED_NO_OWNER, plugin.isUseActionBar());
}
} else {
BoltComponents.sendMessage(
player,
Translation.CLICK_NOT_LOCKED,
plugin.isUseActionBar(),
Placeholder.component(Translation.Placeholder.PROTECTION, Protections.displayType(block, player))
);
}
}
}
boltPlayer.clearAction();
return true;
}

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onBlockPlace(final BlockPlaceEvent e) {
final Player player = e.getPlayer();
Expand Down
Loading

0 comments on commit 3528ff5

Please sign in to comment.