Compare commits

..
41 Commits
Author SHA1 Message Date
Andrew Wong d7907498c9 fix typo 2026-08-09 20:29:11 +10:00
Andrew Wong afbdc6c009 Update README with maintenance notice and alternative link
Update README to indicate project is no longer maintained and provide alternative link.
2026-08-09 20:28:47 +10:00
mesemi cc3a0b32a4 Add SetMaxExtends 2025-09-20 16:54:49 +10:00
Andrew Wong aca6103b1c Refactor the CacheManager to defensive copy and use a binary format 2025-08-10 01:26:39 +10:00
Solo 02c02dad8d Added a cache layer for the names to avoid having to fetch the offline player everytime 2025-08-10 01:26:39 +10:00
Andrew Wong 822f300e65 Fix group info command
Fixes #36
2025-02-25 00:12:18 +08:00
Andrew Wong 1671dc8c26 Update cloud, move exception handlers around to prevent recursion 2025-02-08 21:30:40 +08:00
Andrew Wong 72c4a76c6c Save regions async 2025-01-12 14:00:31 +08:00
Andrew Wong c9e7e3cdbb Bump gradle verstion to 8.11.1 2025-01-12 10:17:48 +08:00
Andrew Wong 4ceff1b80e Update mockbukkit 2024-10-07 16:31:55 +11:00
Andrew Wong 8e88dc7b6b Update gradle wrapper 2024-10-07 16:23:41 +11:00
Andrew Wong 2762ebae1d Supplement OfflinePlayer#hasPlayedBefore checks with #isOnline checks 2024-08-08 20:34:49 +10:00
Andrew Wong 5742dd623e Fix as me command to have the player arg be properly optional 2024-08-04 21:51:44 +10:00
Andrew Wong e5d190d81e Revert "Remove argument from me command"
This reverts commit b631cfc89d.
2024-08-04 21:50:39 +10:00
Andrew Wong b631cfc89d Remove argument from me command 2024-08-04 21:10:04 +10:00
Andrew Wong 399b166339 Sync back to main after looking up offline player async 2024-08-03 18:10:17 +10:00
Andrew Wong b556cb1bce Refactor commands to avoid main thread offline player lookup 2024-08-01 11:12:19 +10:00
Andrew Wong 105274b633 Snapshot 2.9.2 2024-08-01 11:11:54 +10:00
Andrew Wong 9b036dad93 Release 2.9.1 2024-07-24 14:47:35 +10:00
Andrew Wong 628aa83089 Update cloud to beta.9 2024-07-24 14:45:59 +10:00
Andrew Wong 11da15454d Enforce min version to 1.21 2024-07-24 14:45:59 +10:00
Andrew Wong ff2e4e235d Compile against 1.21, bump version to 2.9.1-SNAPSHOT 2024-07-24 14:45:59 +10:00
Andrew Wong 88c7b7a4bd Release 2.9.0 2024-07-24 14:04:44 +10:00
Andrew Wong cd3a7e97a7 Remove extra listener for SignChangeEvent in SignListener 2024-07-24 14:04:13 +10:00
Andrew Wong d33739491a Revert "Release 2.9.0"
This reverts commit ff59fa7f70.
2024-07-24 13:35:27 +10:00
Andrew Wong 5488deb0d7 Fix message sending errors in the ArgumentParseHandler, fix issue with quickbuy and quickrent where newly joined playes are treated as invalid 2024-07-24 13:35:09 +10:00
Andrew Wong ff59fa7f70 Release 2.9.0 2024-07-24 13:21:03 +10:00
Andrew Wong 219ba0335e Remove paperweight userdev, update cloud to 2.0.0-beta.8 2024-07-24 13:15:08 +10:00
Andrew Wong 724439da7d Remove BukkitInterface 2024-06-30 17:43:23 +10:00
Andrew Wong 7bebca5dca Inline BlockBehaviourHelper, remove areashop-nms and areashop-platform-modern 2024-06-30 17:37:45 +10:00
Andrew Wong 5989ecbcbc Handle new SignChangeEvent in the sign listener 2024-06-28 21:39:15 +10:00
Andrew Wong a6a38be0a5 Set version to 2.9.0-SNAPSHOT 2024-06-22 01:26:21 +10:00
Andrew Wong 5034aa358a Fix version util parsing for versions without trailing zeros 2024-06-22 01:22:55 +10:00
Andrew Wong 4f7982f5b2 Update min required version to 1.20.6 2024-06-22 01:16:47 +10:00
Andrew Wong 92c8eea23a Code cleanup, migrate to java 21 2024-06-22 01:10:28 +10:00
Andrew Wong 4ff5852a9d Update the worldguard, worldedit and fastasyncworldedit dependency and adapters 2024-06-22 00:52:07 +10:00
Andrew Wong b30a292398 Bump version to 2.9.0 2024-06-22 00:39:28 +10:00
Andrew Wong 5640a55d73 Update cloud-paper to 2.0.0-SNAPSHOT. Refactor commands to accomodate the new CommandSourceStack 2024-06-22 00:39:05 +10:00
Andrew Wong cd79e071a4 Bump java version in workflows and jitpack 2024-06-22 00:39:03 +10:00
Andrew Wong 49a4b1420d Initial work on compiling against 1.20.6 2024-06-22 00:39:01 +10:00
Andrew Wong 7ef50fbcba Update gradle wrapper to 8.7 2024-06-22 00:38:59 +10:00
118 changed files with 1529 additions and 881 deletions

No files matched your search

+5 -5
View File
@@ -11,12 +11,12 @@ jobs:
os: ["ubuntu-latest", "windows-latest"]
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1.0.4
- name: Set up JDK 17
uses: actions/setup-java@v2
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: 'zulu'
cache: 'gradle'
- name: Build with Gradle
+11 -13
View File
@@ -1,6 +1,6 @@
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("xyz.jpenilla.run-paper") version "2.2.3"
id("io.github.goooler.shadow") version "8.1.7"
id("xyz.jpenilla.run-paper") version "2.3.0"
}
idea {
@@ -31,10 +31,10 @@ dependencies {
api("com.google.inject.extensions:guice-assistedinject:7.0.0") {
exclude("com.google.guava")
}
implementation("org.incendo:cloud-paper:2.0.0-beta.5") {
implementation("org.incendo:cloud-paper:2.0.0-beta.10") {
exclude("com.google.guava")
}
implementation("org.incendo:cloud-processors-confirmation:1.0.0-beta.2") {
implementation("org.incendo:cloud-processors-confirmation:1.0.0-beta.3") {
exclude("com.google.guava")
}
implementation("net.kyori:adventure-text-minimessage:4.16.0")
@@ -43,7 +43,6 @@ dependencies {
// Project submodules
api(projects.areashopInterface)
api(projects.areashopNms)
api(projects.adapters.platform.platformInterface)
api(projects.adapters.platform.paper)
@@ -53,10 +52,9 @@ dependencies {
runtimeOnly(projects.adapters.plugins.worldguard)
runtimeOnly(projects.adapters.plugins.fastasyncworldedit)
runtimeOnly(projects.adapters.plugins.essentials)
runtimeOnly(projects.adapters.platform.bukkitModern)
}
testImplementation("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.86.1")
testImplementation("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT")
testImplementation("com.github.seeseemelk:MockBukkit-v1.21:3.131.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.1")
}
@@ -132,15 +130,15 @@ tasks {
// Configure the Minecraft version for our task.
// This is the only required configuration besides applying the plugin.
// Your plugin's jar (or shadowJar if present) will be used automatically.
minecraftVersion("1.18.2")
minecraftVersion("1.21.1")
downloadPlugins {
github("EssentialsX", "essentials", "2.20.1", "EssentialsX-2.20.1.jar")
github("MilkBowl", "Vault", "1.7.3", "Vault.jar")
// WorldEdit 7.2.19
url("https://mediafilez.forgecdn.net/files/5077/477/worldedit-bukkit-7.2.19.jar")
// WorldGuard 7.0.7
url("https://mediafilez.forgecdn.net/files/3677/516/worldguard-bukkit-7.0.7-dist.jar")
// WorldEdit 7.3.9
url("https://mediafilez.forgecdn.net/files/5935/693/worldedit-bukkit-7.3.9.jar")
// WorldGuard 7.0.12
url("https://mediafilez.forgecdn.net/files/5719/698/worldguard-bukkit-7.0.12-dist.jar")
}
}
}
@@ -100,7 +100,7 @@ public class ASLanguageManager extends LanguageManager {
Log.error("Failed to find location of jar file:", ExceptionUtils.getStackTrace(e));
return;
}
try (ZipFile jar = new ZipFile(jarPath);) {
try (ZipFile jar = new ZipFile(jarPath)) {
Enumeration<? extends ZipEntry> entries = jar.entries();
// Each entry is a file or directory
@@ -16,9 +16,10 @@ import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.listeners.PlayerLoginLogoutListener;
import me.wiefferink.areashop.managers.CacheManager;
import me.wiefferink.areashop.managers.FeatureManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.Manager;
import me.wiefferink.areashop.managers.SignErrorLogger;
import me.wiefferink.areashop.managers.SignLinkerManager;
@@ -26,7 +27,6 @@ import me.wiefferink.areashop.modules.AreaShopModule;
import me.wiefferink.areashop.modules.BukkitModule;
import me.wiefferink.areashop.modules.DependencyModule;
import me.wiefferink.areashop.modules.PlatformModule;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
import me.wiefferink.areashop.services.ServiceManager;
import me.wiefferink.areashop.tools.GithubUpdateCheck;
import me.wiefferink.areashop.tools.LanguageConverter;
@@ -57,6 +57,7 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@@ -79,10 +80,10 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
private WorldGuardInterface worldGuardInterface = null;
private WorldEditPlugin worldEdit = null;
private WorldEditInterface worldEditInterface = null;
private PlatformAdapter platformAdapter;
private MessageBridge messageBridge;
private IFileManager fileManager = null;
private LanguageManager languageManager = null;
private CacheManager cacheManager = null;
private SignLinkerManager signLinkerManager = null;
private FeatureManager featureManager = null;
private SignManager signManager;
@@ -183,18 +184,8 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
// Setup NMS Impl
Version currentServerVersion = VersionUtil.parseMinecraftVersion(Bukkit.getBukkitVersion());
if (currentServerVersion.versionData().isOlderThan(VersionUtil.MC_1_18_2)) {
error("Unsupported minecraft version: " + currentServerVersion + "! Minimum is 1.18.2");
shutdownOnError();
return;
}
try {
Class<?> adapterImpl = Class.forName("me.wiefferink.areashop.adapters.platform.modern.ModernPlatformAdapter");
this.platformAdapter = adapterImpl.asSubclass(PlatformAdapter.class).getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
error("Failed to initialize modern PlatformAdapter implementation!");
if (currentServerVersion.versionData().isOlderThan(VersionUtil.MC_1_21)) {
error("Unsupported minecraft version: " + currentServerVersion + "! Minimum is 1.21");
shutdownOnError();
return;
}
@@ -207,7 +198,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
platform = new SpigotPlatform(this);
info("Detected Spigot; using the SpigotPlatform impl");
}
final PlatformModule platformModule = new PlatformModule(platform, this.platformAdapter);
final PlatformModule platformModule = new PlatformModule(platform);
// Check if Vault is present
if(getServer().getPluginManager().getPlugin("Vault") == null) {
@@ -271,7 +262,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
AreaShopModule asModule = new AreaShopModule(this,
this.messageBridge,
this.platformAdapter,
this.worldEditInterface,
this.worldGuardInterface,
this.signErrorLogger,
@@ -298,11 +288,17 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
managers.add(featureManager);
signManager = injector.getInstance(SignManager.class);
managers.add(signManager);
cacheManager = injector.getInstance(CacheManager.class);
String rawExpiryDuration = fileManager.getConfig().getString("cacheExpiryDuration", "7d");
long millis = Utils.durationStringToLong(rawExpiryDuration);
cacheManager.initialize(new File(getDataFolder(), "uuid-cache.bin"), Duration.ofMillis(millis));
cacheManager.loadCache();
managers.add(cacheManager);
loadExtensions();
// Register the event listeners
getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this, messageBridge), this);
getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this, messageBridge, this.cacheManager), this);
setupTasks();
@@ -397,6 +393,10 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
return version;
}
public CacheManager getCacheManager() {
return cacheManager;
}
/**
* Called on shutdown or reload of the server.
*/
@@ -454,7 +454,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
List<String> chatPrefix = getConfig().getStringList("chatPrefix");
List<String> convertedChatPrefix = LanguageConverter.convertRawList(chatPrefix);
if (convertedChatPrefix.size() == 1) {
getConfig().set("mmChatPrefix", convertedChatPrefix.get(0));
getConfig().set("mmChatPrefix", convertedChatPrefix.getFirst());
} else {
getConfig().set("mmChatPrefix", convertedChatPrefix);
}
@@ -503,10 +503,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
this.chatprefix = chatprefix;
}
public PlatformAdapter getPlatformAdapter() {
return platformAdapter;
}
public SignErrorLogger getSignErrorLogger() {
return signErrorLogger;
}
@@ -605,7 +601,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
* Function to get the Vault plugin.
* @return Economy
*/
@Deprecated
private Economy getEconomy() {
RegisteredServiceProvider<Economy> economy = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if(economy == null) {
@@ -619,7 +614,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopApi {
* Get the Vault permissions provider.
* @return Vault permissions provider
*/
@Deprecated
private net.milkbowl.vault.permission.Permission getPermissionProvider() {
RegisteredServiceProvider<net.milkbowl.vault.permission.Permission> permissionProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
if (permissionProvider == null) {
@@ -10,6 +10,8 @@ import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.WorldFlagUtil;
import me.wiefferink.areashop.commands.util.WorldGuardRegionParser;
import me.wiefferink.areashop.commands.util.WorldSelection;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
@@ -28,13 +30,11 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.parser.standard.EnumParser;
import org.jetbrains.annotations.NotNull;
@@ -92,31 +92,29 @@ public class AddCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
// /as add <rent|buy> [region] [world]
ParserDescriptor<Entity, ProtectedRegion> wgRegionParser = ParserDescriptor.of(new WorldGuardRegionParser<>(
WorldFlagUtil.DEFAULT_WORLD_FLAG,
this.worldGuardInterface), ProtectedRegion.class);
var wgRegionParser = WorldGuardRegionParser.worldGuardRegionParser(WorldFlagUtil.DEFAULT_WORLD_FLAG, this.worldGuardInterface);
return builder
.literal("add")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_REGION_TYPE, EnumParser.enumParser(GeneralRegion.RegionType.class))
.optional(KEY_REGION, wgRegionParser)
.flag(WorldFlagUtil.DEFAULT_WORLD_FLAG)
.handler(this::handleCommand);
}
private void handleCommand(CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
final GeneralRegion.RegionType regionType = context.get(KEY_REGION_TYPE);
World world = WorldFlagUtil.parseOrDetectWorld(context);
World world = WorldFlagUtil.parseOrDetectWorld(context, player);
Map<String, ProtectedRegion> regions;
Optional<ProtectedRegion> inputRegion = context.optional(KEY_REGION);
if (inputRegion.isPresent()) {
regions = new HashMap<>();
regions.put(inputRegion.get().getId(), inputRegion.get());
} else {
WorldSelection selection = WorldSelection.fromPlayer(context.sender(), this.worldEditInterface);
WorldSelection selection = WorldSelection.fromPlayer(player, this.worldEditInterface);
regions = Utils.getWorldEditRegionsInSelection(selection.selection()).stream()
.collect(Collectors.toMap(ProtectedRegion::getId, region -> region));
}
@@ -318,7 +316,7 @@ public class AddCommand extends AreashopCommandBean {
// Add existing owners/members if any
if (!landlord && !existing.isEmpty()) {
UUID rentBy = existing.remove(0);
UUID rentBy = existing.removeFirst();
OfflinePlayer rentByPlayer = Bukkit.getOfflinePlayer(rentBy);
RentingRegionEvent rentingRegionEvent = new RentingRegionEvent(rent,
@@ -378,7 +376,7 @@ public class AddCommand extends AreashopCommandBean {
// Add existing owners/members if any
if (!landlord && !existing.isEmpty()) {
UUID buyBy = existing.remove(0);
UUID buyBy = existing.removeFirst();
OfflinePlayer buyByPlayer = Bukkit.getOfflinePlayer(buyBy);
BuyingRegionEvent buyingRegionEvent = new BuyingRegionEvent(buy,
@@ -3,13 +3,17 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -19,26 +23,33 @@ import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
@Singleton
public class AddFriendCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_FRIEND = CloudKey.of("friend", OfflinePlayer.class);
private static final CloudKey<String> KEY_FRIEND = CloudKey.of("friend", String.class);
private final CommandFlag<GeneralRegion> regionFlag;
private final MessageBridge messageBridge;
private final Plugin plugin;
private final BukkitSchedulerExecutor executor;
private final OfflinePlayerHelper offlinePlayerHelper;
@Inject
public AddFriendCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager,
@Nonnull Plugin plugin
@Nonnull Plugin plugin,
@Nonnull BukkitSchedulerExecutor executor,
@Nonnull OfflinePlayerHelper offlinePlayerHelper
) {
this.messageBridge = messageBridge;
this.plugin = plugin;
this.regionFlag = RegionParseUtil.createDefault(fileManager);
this.executor = executor;
this.offlinePlayerHelper = offlinePlayerHelper;
}
@Override
@@ -47,7 +58,7 @@ public class AddFriendCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.addfriendall") || target.hasPermission("areashop.addfriend")) {
return "help-addFriend";
}
@@ -55,46 +66,64 @@ public class AddFriendCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("addfriend")
.senderType(Player.class)
.required(KEY_FRIEND, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.senderType(PlayerCommandSource.class)
.required(KEY_FRIEND, OfflinePlayerParser.parser())
.flag(this.regionFlag)
.handler(this::handleCommand);
}
private void handleCommand(CommandContext<Player> context) {
Player sender = context.sender();
private void handleCommand(CommandContext<PlayerCommandSource> context) {
Player sender = context.sender().sender();
if (!sender.hasPermission("areashop.addfriend") && !sender.hasPermission("areashop.addfriendall")) {
this.messageBridge.message(sender, "addfriend-noPermission");
return;
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
OfflinePlayer friend = context.get(KEY_FRIEND);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_FRIEND))
.whenCompleteAsync((offlinePlayer, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", offlinePlayer.getName());
return;
}
processWithFriend(sender, region, offlinePlayer);
}, this.executor);
}
private void processWithFriend(@Nonnull Player sender,
@Nonnull GeneralRegion region,
@Nonnull OfflinePlayer friend
) {
if (sender.hasPermission("areashop.addfriendall") && ((region instanceof RentRegion rentRegion && !rentRegion.isRented())
|| (region instanceof BuyRegion buyRegion && !buyRegion.isSold()))) {
this.messageBridge.message(sender, "addfriend-noOwner", region);
this.messageBridge.message(sender, "addfriend-noOwner", region);
return;
}
if (!sender.hasPermission("areashop.addfriend")) {
this.messageBridge.message(sender, "addfriend-noPermission", region);
this.messageBridge.message(sender, "addfriend-noPermission", region);
return;
}
if (!region.isOwner(sender)) {
this.messageBridge.message(sender, "addfriend-noPermissionOther", region);
this.messageBridge.message(sender, "addfriend-noPermissionOther", region);
return;
}
if (!friend.hasPlayedBefore() && !friend.isOnline() && !plugin.getConfig()
.getBoolean("addFriendNotExistingPlayers")) {
this.messageBridge.message(sender, "addfriend-notVisited", friend.getName(), region);
this.messageBridge.message(sender, "addfriend-notVisited", friend.getName(), region);
} else if (region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
this.messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
this.messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
} else if (region.isOwner(friend.getUniqueId())) {
this.messageBridge.message(sender, "addfriend-self", friend.getName(), region);
this.messageBridge.message(sender, "addfriend-self", friend.getName(), region);
} else if (region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
region.update();
this.messageBridge.message(sender, "addfriend-success", friend.getName(), region);
this.messageBridge.message(sender, "addfriend-success", friend.getName(), region);
}
}
@@ -8,6 +8,8 @@ import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.SignProfileUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.managers.IFileManager;
@@ -24,6 +26,7 @@ import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Optional;
@@ -58,7 +61,7 @@ public class AddSignCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.addsign")) {
return "help-addsign";
}
@@ -66,16 +69,16 @@ public class AddSignCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("addsign")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.optional(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
.flag(SignProfileUtil.DEFAULT_FLAG)
.handler(this::handleCommand);
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player sender = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player sender = context.sender().sender();
if (!sender.hasPermission("areashop.addsign")) {
throw new AreaShopCommandException("addsign-noPermission");
}
@@ -93,7 +96,7 @@ public class AddSignCommand extends AreashopCommandBean {
return;
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, KEY_REGION);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, KEY_REGION);
String profile = SignProfileUtil.getOrParseProfile(context, this.plugin);
Optional<RegionSign> optionalRegionSign = this.signManager.signFromLocation(block.getLocation());
if(optionalRegionSign.isPresent()) {
@@ -5,6 +5,8 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import org.bukkit.command.CommandSender;
@@ -13,6 +15,7 @@ import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
@@ -27,7 +30,7 @@ public class BuyCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.buy")) {
return "help-buy";
}
@@ -46,20 +49,21 @@ public class BuyCommand extends AreashopCommandBean {
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder
.literal("buy")
.flag(this.buyRegionFlag)
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.handler(this::handleCommand);
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
if (!context.hasPermission("areashop.buy")) {
throw new AreaShopCommandException("buy-noPermission");
}
BuyRegion region = RegionParseUtil.getOrParseBuyRegion(context, this.buyRegionFlag);
region.buy(context.sender());
Player sender = context.sender().sender();
BuyRegion region = RegionParseUtil.getOrParseBuyRegion(context, sender, this.buyRegionFlag);
region.buy(sender);
}
}
@@ -8,6 +8,7 @@ import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.WorldSelection;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.managers.IFileManager;
@@ -21,7 +22,7 @@ import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.ParserDescriptor;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.ArrayList;
@@ -56,7 +57,7 @@ public class DelCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.destroyrent") || target.hasPermission("areashop.destroybuy") || target.hasPermission(
"areashop.destroyrent.landlord") || target.hasPermission("areashop.destroybuy.landlord")) {
return "help-del";
@@ -70,18 +71,14 @@ public class DelCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
ParserDescriptor<CommandSender, GeneralRegion> regionParser = ParserDescriptor.of(
new GeneralRegionParser<>(this.fileManager),
GeneralRegion.class
);
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("del", "delete")
.optional(KEY_REGION, regionParser)
.optional(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
.handler(this::handleCommand);
}
public void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
public void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.destroybuy")
&& !sender.hasPermission("areashop.destroybuy.landlord")
&& !sender.hasPermission("areashop.destroyrent")
@@ -179,12 +176,9 @@ public class DelCommand extends AreashopCommandBean {
return true;
}
if (region instanceof BuyRegion
return region instanceof BuyRegion
&& (!sender.hasPermission("areashop.destroybuy") && !(isLandlord && sender.hasPermission(
"areashop.destroybuy.landlord")))) {
return true;
}
return false;
"areashop.destroybuy.landlord")));
}
}
@@ -3,15 +3,18 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.features.FriendsFeature;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -22,6 +25,7 @@ import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.suggestion.Suggestion;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Collection;
@@ -32,17 +36,23 @@ import java.util.concurrent.CompletableFuture;
public class DelFriendCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
private static final CloudKey<String> KEY_PLAYER = CloudKey.of("player", String.class);
private final MessageBridge messageBridge;
private final CommandFlag<GeneralRegion> regionFlag;
private final OfflinePlayerHelper offlinePlayerHelper;
private final BukkitSchedulerExecutor executor;
@Inject
public DelFriendCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
@Nonnull IFileManager fileManager,
@Nonnull OfflinePlayerHelper offlinePlayerHelper,
@Nonnull BukkitSchedulerExecutor executor
) {
this.messageBridge = messageBridge;
this.regionFlag = RegionParseUtil.createDefault(fileManager);
this.offlinePlayerHelper = offlinePlayerHelper;
this.executor = executor;
}
/**
@@ -63,7 +73,7 @@ public class DelFriendCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.delfriendall") || target.hasPermission("areashop.delfriend")) {
return "help-delFriend";
}
@@ -81,20 +91,37 @@ public class DelFriendCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("delfriend", "deletefriend")
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser(), this::suggestFriends)
.required(KEY_PLAYER, OfflinePlayerParser.parser(), this::suggestFriends)
.flag(this.regionFlag)
.handler(this::handleCommand);
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
throw new AreaShopCommandException("delfriend-noPermission");
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
OfflinePlayer friend = context.get(KEY_PLAYER);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_PLAYER))
.whenCompleteAsync((offlinePlayer, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", offlinePlayer.getName());
return;
}
processWithSender(sender, region, offlinePlayer);
}, this.executor);
}
private void processWithSender(@Nonnull CommandSender sender,
@Nonnull GeneralRegion region,
@Nonnull OfflinePlayer friend) {
FriendsFeature friendsFeature = region.getFriendsFeature();
if (sender.hasPermission("areashop.delfriendall")) {
if ((region instanceof RentRegion rentRegion && !rentRegion.isRented())
@@ -128,16 +155,16 @@ public class DelFriendCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestFriends(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
CommandSender sender = context.sender();
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.delfriend")) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
GeneralRegion region;
try {
region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
} catch (AreaShopCommandException ignored) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
@@ -5,6 +5,8 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.tools.Materials;
@@ -16,6 +18,7 @@ import org.bukkit.util.BlockIterator;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Optional;
@@ -44,22 +47,22 @@ public class DelSignCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("delsign", "deletesign")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.handler(this::handleCommand);
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.delsign")) {
return "help-delsign";
}
return null;
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player sender = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player sender = context.sender().sender();
if (!sender.hasPermission("areashop.delsign")) {
throw new AreaShopCommandException("delsign-noPermission");
}
@@ -6,6 +6,8 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionGroupParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -24,6 +26,7 @@ import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.parser.standard.DoubleParser;
import org.incendo.cloud.parser.standard.EnumParser;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Collection;
@@ -65,7 +68,7 @@ public class FindCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.find")) {
return "help-find";
}
@@ -73,9 +76,9 @@ public class FindCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("find")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_REGION_TYPE, EnumParser.enumParser(GeneralRegion.RegionType.class))
.optional(KEY_PRICE, DoubleParser.doubleParser(0))
.flag(this.regionGroupFlag)
@@ -87,8 +90,8 @@ public class FindCommand extends AreashopCommandBean {
return CommandProperties.of("find");
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player sender = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player sender = context.sender().sender();
if (!sender.hasPermission("areashop.find")) {
throw new AreaShopCommandException("find-noPermission");
}
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
@@ -20,6 +21,7 @@ import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.parser.standard.StringParser;
import org.incendo.cloud.suggestion.Suggestion;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Collection;
@@ -57,7 +59,7 @@ public class GroupAddCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.groupadd")) {
return "help-groupadd";
}
@@ -65,7 +67,7 @@ public class GroupAddCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("groupadd")
.required(KEY_GROUP, StringParser.stringParser(), this::suggestGroupNames)
.flag(this.regionFlag)
@@ -77,8 +79,8 @@ public class GroupAddCommand extends AreashopCommandBean {
return CommandProperties.of("groupadd");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.groupadd")) {
throw new AreaShopCommandException("groupadd-noPermission");
}
@@ -102,7 +104,7 @@ public class GroupAddCommand extends AreashopCommandBean {
return;
}
Collection<GeneralRegion> regions = RegionParseUtil.getOrParseRegionsInSel(context, this.regionFlag);
Collection<GeneralRegion> regions = RegionParseUtil.getOrParseRegionsInSel(context, sender, this.regionFlag);
Set<GeneralRegion> regionsSuccess = new TreeSet<>();
Set<GeneralRegion> regionsFailed = new TreeSet<>();
for (GeneralRegion region : regions) {
@@ -129,7 +131,7 @@ public class GroupAddCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestGroupNames(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
@@ -20,6 +21,7 @@ import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.parser.standard.StringParser;
import org.incendo.cloud.suggestion.Suggestion;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Collection;
@@ -57,7 +59,7 @@ public class GroupDelCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.groupdel")) {
return "help-groupdel";
}
@@ -65,7 +67,7 @@ public class GroupDelCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("groupdel")
.required(KEY_GROUP, StringParser.stringParser(), this::suggestGroupNames)
.flag(this.regionFlag)
@@ -77,8 +79,8 @@ public class GroupDelCommand extends AreashopCommandBean {
return CommandProperties.of("groupdel");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("groupdel")) {
throw new AreaShopCommandException("groupdel-noPermission");
}
@@ -101,7 +103,7 @@ public class GroupDelCommand extends AreashopCommandBean {
return;
}
Collection<GeneralRegion> regions = RegionParseUtil.getOrParseRegionsInSel(context, this.regionFlag);
Collection<GeneralRegion> regions = RegionParseUtil.getOrParseRegionsInSel(context, sender, this.regionFlag);
Set<GeneralRegion> regionsSuccess = new TreeSet<>();
Set<GeneralRegion> regionsFailed = new TreeSet<>();
for (GeneralRegion region : regions) {
@@ -129,7 +131,7 @@ public class GroupDelCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestGroupNames(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionGroupParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RegionGroup;
import me.wiefferink.areashop.tools.Utils;
@@ -15,6 +16,7 @@ import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.ParserDescriptor;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.Set;
@@ -39,7 +41,7 @@ public class GroupInfoCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.groupinfo")) {
return "help-groupinfo";
}
@@ -47,8 +49,8 @@ public class GroupInfoCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
ParserDescriptor<CommandSender, RegionGroup> regionGroupParser = ParserDescriptor.of(
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
ParserDescriptor<CommandSource<?>, RegionGroup> regionGroupParser = ParserDescriptor.of(
new RegionGroupParser<>(this.fileManager, "groupinfo-noGroup"),
RegionGroup.class);
return builder
@@ -63,7 +65,7 @@ public class GroupInfoCommand extends AreashopCommandBean {
return CommandProperties.of("groupinfo");
}
public void handleCommand(@Nonnull CommandContext<CommandSender> context) {
public void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
if (!context.hasPermission("groupinfo")) {
throw new AreaShopCommandException("groupinfo-noPermission");
}
@@ -73,7 +75,7 @@ public class GroupInfoCommand extends AreashopCommandBean {
throw new AreaShopCommandException("groupinfo-noMembers", group.getName());
}
String seperatedMembers = Utils.createCommaSeparatedList(members);
this.messageBridge.message(context.sender(), "groupinfo-members", group.getName(), seperatedMembers);
this.messageBridge.message(context.sender().sender(), "groupinfo-members", group.getName(), seperatedMembers);
}
}
@@ -5,6 +5,7 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
@@ -41,7 +42,7 @@ public class GroupListCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("grouplist", "groups")
.handler(this::handleCommand);
}
@@ -51,12 +52,12 @@ public class GroupListCommand extends AreashopCommandBean {
return CommandProperties.of("grouplist", "groups");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
if (!context.hasPermission("areashop.grouplist")) {
throw new AreaShopCommandException("grouplist-noPermission");
}
List<String> groups = this.fileManager.getGroupNames();
CommandSender sender = context.sender();
CommandSender sender = context.sender().sender();
if(groups.isEmpty()) {
messageBridge.message(sender, "grouplist-noGroups");
} else {
@@ -5,6 +5,7 @@ import com.google.inject.Singleton;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.AreashopCommands;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
@@ -24,7 +25,7 @@ public class HelpCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.help")) {
return "help-help";
}
@@ -36,9 +37,8 @@ public class HelpCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("help")
.handler(this::handleCommand);
}
@@ -48,8 +48,8 @@ public class HelpCommand extends AreashopCommandBean {
return CommandProperties.of("help");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.help")) {
throw new AreaShopCommandException("help-noPermission");
}
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AcceptedValuesParser;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.regions.ImportJobFactory;
import org.bukkit.command.CommandSender;
import org.incendo.cloud.Command;
@@ -13,6 +14,7 @@ import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.ParserDescriptor;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.List;
@@ -42,7 +44,7 @@ public class ImportCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.import")) {
return "help-import";
}
@@ -50,7 +52,7 @@ public class ImportCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
withConfirmation();
var sourceParser = AcceptedValuesParser.ofConstant(List.of("RegionForSale"), "import-wrongSource", true);
return builder.literal("import")
@@ -69,8 +71,8 @@ public class ImportCommand extends AreashopCommandBean {
// - Region flags?
// - Settings from the 'permissions' section in RegionForSale/config.yml?
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.import")) {
this.messageBridge.message(sender, "import-noPermission");
return;
@@ -4,10 +4,12 @@ import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import org.bukkit.command.CommandSender;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
@@ -29,7 +31,7 @@ public class InfoBaseCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.info")) {
return "help-info";
}
@@ -37,7 +39,7 @@ public class InfoBaseCommand extends AreashopCommandBean {
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("info").handler(this::handleCommand);
}
@@ -46,8 +48,8 @@ public class InfoBaseCommand extends AreashopCommandBean {
return CommandProperties.of("info");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.info")) {
messageBridge.message(sender, "info-noPermission");
return;
@@ -5,6 +5,7 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionGroupParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -21,6 +22,7 @@ import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.parser.standard.EnumParser;
import org.incendo.cloud.parser.standard.IntegerParser;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.LinkedList;
@@ -59,15 +61,12 @@ public class InfoCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
if(target.hasPermission("areashop.info")) {
return "help-info";
}
public String getHelpKey(@NotNull CommandSender target) {
return null;
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("info")
.required(KEY_TYPE, EnumParser.enumParser(RegionStateFilterType.class))
.flag(FLAG_PAGE)
@@ -80,8 +79,8 @@ public class InfoCommand extends AreashopCommandBean {
return CommandProperties.of("info");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.info")) {
messageBridge.message(sender, "info-noPermission");
return;
@@ -90,7 +89,7 @@ public class InfoCommand extends AreashopCommandBean {
processOtherFilters(context, filterType);
}
private void processOtherFilters(@Nonnull CommandContext<CommandSender> context,
private void processOtherFilters(@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull RegionStateFilterType filterType) {
RegionGroup filterGroup = context.flags().get(this.filterGroupFlag);
int page = context.flags().getValue(FLAG_PAGE).orElse(1);
@@ -127,7 +126,7 @@ public class InfoCommand extends AreashopCommandBean {
case RESELLING -> "info reselling";
case NOGROUP -> "info nogroup";
};
showSortedPagedList(context.sender(), toShow, filterGroup, header, page, baseCommand);
showSortedPagedList(context.sender().sender(), toShow, filterGroup, header, page, baseCommand);
}
@@ -3,11 +3,13 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionInfoUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import org.bukkit.OfflinePlayer;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.command.CommandSender;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
@@ -19,18 +21,24 @@ import javax.annotation.Nonnull;
@Singleton
public class InfoPlayerCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
private static final CloudKey<String> KEY_PLAYER = CloudKey.of("player", String.class);
private final MessageBridge messageBridge;
private final IFileManager fileManager;
private final OfflinePlayerHelper offlinePlayerHelper;
private final BukkitSchedulerExecutor executor;
@Inject
public InfoPlayerCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
@Nonnull IFileManager fileManager,
@Nonnull OfflinePlayerHelper offlinePlayerHelper,
@Nonnull BukkitSchedulerExecutor executor
) {
this.messageBridge = messageBridge;
this.fileManager = fileManager;
this.offlinePlayerHelper = offlinePlayerHelper;
this.executor = executor;
}
@Override
@@ -40,16 +48,13 @@ public class InfoPlayerCommand extends AreashopCommandBean {
@Override
public String getHelpKey(CommandSender target) {
if (target.hasPermission("areashop.info")) {
return "help-info";
}
return null;
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("info").literal("player")
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.required(KEY_PLAYER, OfflinePlayerParser.parser())
.handler(this::handleCommand);
}
@@ -58,14 +63,25 @@ public class InfoPlayerCommand extends AreashopCommandBean {
return CommandProperties.of("info region");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.info")) {
messageBridge.message(sender, "info-noPermission");
return;
}
OfflinePlayer offlinePlayer = context.get(KEY_PLAYER);
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, offlinePlayer);
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_PLAYER))
.whenCompleteAsync((offlinePlayer, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", offlinePlayer.getName());
return;
}
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, offlinePlayer);
}, this.executor);
}
}
@@ -6,6 +6,7 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -18,6 +19,7 @@ import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.ArrayList;
@@ -45,15 +47,12 @@ public class InfoRegionCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
if (target.hasPermission("areashop.info")) {
return "help-info";
}
public String getHelpKey(@NotNull CommandSender target) {
return null;
}
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("info").literal("region")
.flag(this.regionFlag)
.handler(this::handleCommand);
@@ -64,14 +63,14 @@ public class InfoRegionCommand extends AreashopCommandBean {
return CommandProperties.of("info region");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.info")) {
messageBridge.message(sender, "info-noPermission");
return;
}
// Region info
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
if (region instanceof RentRegion rent) {
handleRent(sender, rent);
} else if (region instanceof BuyRegion buy) {
@@ -7,6 +7,8 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.SignProfileUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.SignLinkerManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -22,7 +24,6 @@ import javax.annotation.Nonnull;
@Singleton
public class LinkSignsCommand extends AreashopCommandBean {
private final MessageBridge messageBridge;
private final SignLinkerManager signLinkerManager;
private final AreaShop plugin;
@@ -34,7 +35,6 @@ public class LinkSignsCommand extends AreashopCommandBean {
@Nonnull SignLinkerManager signLinkerManager,
@Nonnull AreaShop plugin
) {
this.messageBridge = messageBridge;
this.signLinkerManager = signLinkerManager;
this.plugin = plugin;
this.profileFlag = SignProfileUtil.createDefault(plugin);
@@ -46,11 +46,10 @@ public class LinkSignsCommand extends AreashopCommandBean {
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("linksign")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.flag(this.profileFlag)
.handler(this::handleCommand);
}
@@ -68,8 +67,8 @@ public class LinkSignsCommand extends AreashopCommandBean {
return null;
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
if (!player.hasPermission("linksigns")) {
throw new AreaShopCommandException("linksigns-noPermission");
}
@@ -3,12 +3,15 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionInfoUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import org.bukkit.OfflinePlayer;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -23,17 +26,23 @@ import javax.annotation.Nonnull;
@Singleton
public class MeCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
private static final CloudKey<String> KEY_PLAYER = CloudKey.of("player", String.class);
private final IFileManager fileManager;
private final MessageBridge messageBridge;
private final OfflinePlayerHelper offlinePlayerHelper;
private final BukkitSchedulerExecutor executor;
@Inject
public MeCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
@Nonnull IFileManager fileManager,
@Nonnull OfflinePlayerHelper offlinePlayerHelper,
@Nonnull BukkitSchedulerExecutor executor
) {
this.messageBridge = messageBridge;
this.fileManager = fileManager;
this.offlinePlayerHelper = offlinePlayerHelper;
this.executor = executor;
}
@Override
@@ -41,12 +50,11 @@ public class MeCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("me")
.senderType(Player.class)
.optional(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.senderType(PlayerCommandSource.class)
.optional(KEY_PLAYER, OfflinePlayerParser.parser())
.handler(this::handleCommand);
}
@@ -56,20 +64,35 @@ public class MeCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.me")) {
return "help-me";
}
return null;
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player sender = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player sender = context.sender().sender();
if (!sender.hasPermission("areashop.me")) {
throw new AreaShopCommandException("me-noPermission");
}
OfflinePlayer player = context.getOrDefault(KEY_PLAYER, sender);
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, player);
if (!context.contains(KEY_PLAYER)) {
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, sender);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_PLAYER))
.whenCompleteAsync((offlinePlayer, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", offlinePlayer.getName());
return;
}
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, offlinePlayer);
}, this.executor);
}
}
@@ -1,10 +1,9 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.tools.SimpleMessageBridge;
import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.command.CommandSender;
@@ -26,14 +25,7 @@ public class MessageCommand extends AreashopCommandBean {
private static final CloudKey<Player> KEY_PLAYER = CloudKey.of("player", Player.class);
private static final CloudKey<String> KEY_MESSAGE = CloudKey.of("message", String.class);
private final MessageBridge messageBridge;
@Inject
public MessageCommand(@Nonnull MessageBridge messageBridge) {
this.messageBridge = messageBridge;
}
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
// Internal command, no need to show in the help list
return null;
}
@@ -43,9 +35,8 @@ public class MessageCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("message")
.required(KEY_PLAYER, PlayerParser.playerParser())
.required(KEY_MESSAGE, StringParser.greedyStringParser())
@@ -57,8 +48,8 @@ public class MessageCommand extends AreashopCommandBean {
return CommandProperties.of("message");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if(!sender.hasPermission("areashop.message")) {
throw new AreaShopCommandException("message-noPermission");
}
@@ -3,16 +3,18 @@ package me.wiefferink.areashop.commands;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.ArgumentParseExceptionHandler;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionCreationUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -32,12 +34,13 @@ public class QuickBuyCommand extends AreashopCommandBean {
private static final CloudKey<String> KEY_REGION = CloudKey.of("region", String.class);
private static final CloudKey<Double> KEY_PRICE = CloudKey.of("price", Double.class);
private static final CloudKey<OfflinePlayer> KEY_LANDLORD = CloudKey.of("landlord", OfflinePlayer.class);
private static final CloudKey<String> KEY_LANDLORD = CloudKey.of("landlord", String.class);
private final RegionFactory regionFactory;
private final IFileManager fileManager;
private final MessageBridge messageBridge;
private final RegionCreationUtil regionCreationUtil;
private final BukkitSchedulerExecutor executor;
private final OfflinePlayerHelper offlinePlayerHelper;
@Inject
public QuickBuyCommand(
@@ -45,13 +48,15 @@ public class QuickBuyCommand extends AreashopCommandBean {
@Nonnull RegionFactory regionFactory,
@Nonnull IFileManager fileManager,
@Nonnull RegionCreationUtil regionCreationUtil,
@Nonnull BukkitSchedulerExecutor executor
@Nonnull BukkitSchedulerExecutor executor,
@Nonnull OfflinePlayerHelper offlinePlayerHelper
) {
this.messageBridge = messageBridge;
this.regionFactory = regionFactory;
this.fileManager = fileManager;
this.regionCreationUtil = regionCreationUtil;
this.executor = executor;
this.offlinePlayerHelper = offlinePlayerHelper;
}
@Override
@@ -61,28 +66,28 @@ public class QuickBuyCommand extends AreashopCommandBean {
@Nonnull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("quickbuy")
.permission("permission")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_REGION, StringParser.stringParser())
.required(KEY_PRICE, DoubleParser.doubleParser(0))
.required(KEY_LANDLORD, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.required(KEY_LANDLORD, OfflinePlayerParser.parser())
.handler(this::handleCommand);
}
// /as quickbuy <name> <price> <duration> <landlord>
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
if (!player.hasPermission("areashop.quickbuy")) {
player.sendMessage("Insufficient permission");
return;
}
this.regionCreationUtil.createRegion(context, KEY_REGION)
this.regionCreationUtil.createRegion(context, player, KEY_REGION)
.exceptionally(throwable -> {
if (throwable instanceof AreaShopCommandException exception) {
ArgumentParseExceptionHandler.handleException(this.messageBridge, player, exception);
ArgumentParseExceptionHandler.handleException(this.messageBridge, context.sender(), exception);
} else {
throw new CommandExecutionException(throwable, context);
}
@@ -94,20 +99,26 @@ public class QuickBuyCommand extends AreashopCommandBean {
return;
}
double price = context.get(KEY_PRICE);
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_LANDLORD))
.whenCompleteAsync((landlord, exception) -> {
if (exception != null) {
player.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!landlord.isOnline() && !landlord.hasPlayedBefore()) {
this.messageBridge.message(player, "me-noPlayer", landlord.getName());
return;
}
String regionName = region.getId();
World world = player.getWorld();
OfflinePlayer landlord = context.get(KEY_LANDLORD);
if (!landlord.hasPlayedBefore()) {
this.messageBridge.message(player, "me-noPlayer");
return;
}
String regionName = region.getId();
World world = player.getWorld();
BuyRegion buyRegion = this.regionFactory.createBuyRegion(regionName, world);
buyRegion.setPrice(price);
buyRegion.setLandlord(landlord.getUniqueId(), landlord.getName());
this.fileManager.addRegion(buyRegion);
this.messageBridge.message(player, "add-success", "buy", regionName);
BuyRegion buyRegion = this.regionFactory.createBuyRegion(regionName, world);
buyRegion.setPrice(price);
buyRegion.setLandlord(landlord.getUniqueId(), landlord.getName());
this.fileManager.addRegion(buyRegion);
this.messageBridge.message(player, "add-success", "buy", regionName);
}, this.executor);
}, this.executor);
}
@@ -124,4 +135,4 @@ public class QuickBuyCommand extends AreashopCommandBean {
protected @Nonnull CommandProperties properties() {
return CommandProperties.of("quickbuy");
}
}
}
@@ -7,6 +7,8 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.IFileManager;
@@ -56,16 +58,16 @@ public class QuickDeleteCommand extends AreashopCommandBean {
@Nonnull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("quickdelete", "quickdel")
.permission("areashop.quickdelete")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
.handler(this::handleCommand);
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
GeneralRegion region = context.get(KEY_REGION);
boolean giveMoneyBack = context.flags().isPresent(FLAG_RETURN_MONEY);
DeletingRegionEvent event = this.fileManager.deleteRegion(region, giveMoneyBack);
@@ -3,18 +3,20 @@ package me.wiefferink.areashop.commands;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.ArgumentParseExceptionHandler;
import me.wiefferink.areashop.commands.util.DurationInputParser;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionCreationUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RegionFactory;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import me.wiefferink.areashop.tools.DurationInput;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -36,12 +38,13 @@ public class QuickRentCommand extends AreashopCommandBean {
private static final CloudKey<Double> KEY_PRICE = CloudKey.of("price", Double.class);
private static final CloudKey<DurationInput> KEY_DURATION = CloudKey.of("duration", DurationInput.class);
private static final CloudKey<OfflinePlayer> KEY_LANDLORD = CloudKey.of("landlord", OfflinePlayer.class);
private static final CloudKey<String> KEY_LANDLORD = CloudKey.of("landlord", String.class);
private final RegionFactory regionFactory;
private final IFileManager fileManager;
private final MessageBridge messageBridge;
private final RegionCreationUtil regionCreationUtil;
private final BukkitSchedulerExecutor executor;
private final OfflinePlayerHelper offlinePlayerHelper;
@Inject
public QuickRentCommand(
@@ -49,13 +52,15 @@ public class QuickRentCommand extends AreashopCommandBean {
@Nonnull RegionFactory regionFactory,
@Nonnull IFileManager fileManager,
@Nonnull RegionCreationUtil regionCreationUtil,
@Nonnull BukkitSchedulerExecutor executor
@Nonnull BukkitSchedulerExecutor executor,
@Nonnull OfflinePlayerHelper offlinePlayerHelper
) {
this.messageBridge = messageBridge;
this.regionFactory = regionFactory;
this.fileManager = fileManager;
this.regionCreationUtil = regionCreationUtil;
this.executor = executor;
this.offlinePlayerHelper = offlinePlayerHelper;
}
@Override
@@ -65,29 +70,29 @@ public class QuickRentCommand extends AreashopCommandBean {
@Nonnull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("quickrent")
.permission("permission")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_REGION, StringParser.stringParser())
.required(KEY_PRICE, DoubleParser.doubleParser(0))
.required(KEY_DURATION, DurationInputParser.durationInputParser())
.required(KEY_LANDLORD, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.required(KEY_LANDLORD, OfflinePlayerParser.parser())
.handler(this::handleCommand);
}
// /as quickrent <name> <price> <duration> <landlord>
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
if (!player.hasPermission("areashop.quickrent")) {
player.sendMessage("Insufficient permission");
return;
}
this.regionCreationUtil.createRegion(context, KEY_REGION)
this.regionCreationUtil.createRegion(context, player, KEY_REGION)
.exceptionally(throwable -> {
if (throwable instanceof AreaShopCommandException exception) {
ArgumentParseExceptionHandler.handleException(this.messageBridge, player, exception);
ArgumentParseExceptionHandler.handleException(this.messageBridge, context.sender(), exception);
} else {
throw new CommandExecutionException(throwable, context);
}
@@ -101,20 +106,27 @@ public class QuickRentCommand extends AreashopCommandBean {
double price = context.get(KEY_PRICE);
DurationInput duration = context.get(KEY_DURATION);
OfflinePlayer landlord = context.get(KEY_LANDLORD);
if (!landlord.hasPlayedBefore()) {
this.messageBridge.message(player, "me-noPlayer");
return;
}
String regionName = region.getId();
World world = player.getWorld();
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_LANDLORD))
.whenCompleteAsync((landlord, exception) -> {
if (exception != null) {
player.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!landlord.hasPlayedBefore() && !landlord.isOnline()) {
this.messageBridge.message(player, "cmd-invalidPlayer", landlord.getName());
return;
}
String regionName = region.getId();
World world = player.getWorld();
RentRegion rentRegion = this.regionFactory.createRentRegion(regionName, world);
rentRegion.setPrice(price);
rentRegion.setLandlord(landlord.getUniqueId(), landlord.getName());
rentRegion.setDuration(duration.toTinySpacedString());
this.fileManager.addRegion(rentRegion);
this.messageBridge.message(player, "add-success", "rent", regionName);
RentRegion rentRegion = this.regionFactory.createRentRegion(regionName, world);
rentRegion.setPrice(price);
rentRegion.setLandlord(landlord.getUniqueId(), landlord.getName());
rentRegion.setDuration(duration.toTinySpacedString());
this.fileManager.addRegion(rentRegion);
this.messageBridge.message(player, "add-success", "rent", regionName);
}, this.executor);
}, this.executor);
}
@@ -131,4 +143,4 @@ public class QuickRentCommand extends AreashopCommandBean {
protected @Nonnull CommandProperties properties() {
return CommandProperties.of("quickrent");
}
}
}
@@ -5,6 +5,7 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
@@ -30,7 +31,7 @@ public class ReloadCommand extends AreashopCommandBean {
@Nonnull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("reload")
.handler(this::handleCommand);
}
@@ -49,10 +50,10 @@ public class ReloadCommand extends AreashopCommandBean {
return null;
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
if (!context.hasPermission("areashop.reload")) {
throw new AreaShopCommandException("reload-noPermission");
}
this.plugin.reload(context.sender());
this.plugin.reload(context.sender().sender());
}
}
@@ -5,6 +5,8 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
@@ -13,6 +15,7 @@ import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
@@ -32,7 +35,7 @@ public class RentCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if(target.hasPermission("areashop.rent")) {
return "help-rent";
}
@@ -46,20 +49,21 @@ public class RentCommand extends AreashopCommandBean {
@Override
protected @Nonnull Command.Builder<? extends CommandSender> configureCommand(@Nonnull Command.Builder<CommandSender> builder) {
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder
.literal("rent")
.flag(this.rentRegionFlag)
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.handler(this::handleCommand);
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
if (!context.hasPermission("areashop.rent")) {
throw new AreaShopCommandException("rent-noPermission");
}
RentRegion region = RegionParseUtil.getOrParseRentRegion(context, this.rentRegionFlag);
region.rent(context.sender());
Player sender = context.sender().sender();
RentRegion region = RegionParseUtil.getOrParseRentRegion(context, sender, this.rentRegionFlag);
region.rent(sender);
}
}
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.BuyRegionParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -39,11 +40,11 @@ public class ResellCommand extends AreashopCommandBean {
public ResellCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
this.messageBridge = messageBridge;
this.fileManager = fileManager;
ParserDescriptor<CommandSender, BuyRegion> regionParser = ParserDescriptor.of(
ParserDescriptor<CommandSource<?>, BuyRegion> regionParser = ParserDescriptor.of(
new BuyRegionParser<>(fileManager, this::suggestBuyRegions),
BuyRegion.class
);
this.regionFlag = CommandFlag.builder("region").withComponent(regionParser).build();
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region").withComponent(regionParser).build();
}
@Override
@@ -51,9 +52,9 @@ public class ResellCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
@Nonnull
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
return builder.literal("resell")
.required(KEY_PRICE, DoubleParser.doubleParser(0))
.flag(this.regionFlag)
@@ -67,7 +68,7 @@ public class ResellCommand extends AreashopCommandBean {
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.resellall") || target.hasPermission("areashop.resell")) {
return "help-resell";
}
@@ -75,14 +76,14 @@ public class ResellCommand extends AreashopCommandBean {
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.resell") && !sender.hasPermission("areashop.resellall")) {
messageBridge.message(sender, "resell-noPermissionOther");
return;
}
double price = context.get(KEY_PRICE);
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, this.regionFlag);
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, sender, this.regionFlag);
if (!buy.isSold()) {
messageBridge.message(sender, "resell-notBought", buy);
return;
@@ -111,7 +112,7 @@ public class ResellCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestBuyRegions(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
@@ -39,9 +40,8 @@ public class SchematicEventCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("schemevent")
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
.required(KEY_EVENT_TYPE, EnumParser.enumParser(GeneralRegion.RegionEvent.class))
@@ -54,15 +54,15 @@ public class SchematicEventCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.schematicevents")) {
return "help-schemevent";
}
return null;
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.schematicevents")) {
throw new AreaShopCommandException("schemevent-noPermission");
}
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.BuyRegionParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -34,11 +35,11 @@ public class SellCommand extends AreashopCommandBean {
@Inject
public SellCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
ParserDescriptor<CommandSender, BuyRegion> regionParser =
ParserDescriptor<CommandSource<?>, BuyRegion> regionParser =
ParserDescriptor.of(new BuyRegionParser<>(fileManager, this::suggestBuyRegions), BuyRegion.class);
this.messageBridge = messageBridge;
this.fileManager = fileManager;
this.buyRegionFlag = CommandFlag.builder("region").withComponent(regionParser).build();
this.buyRegionFlag = CommandFlag.<CommandSource<?>>builder("region").withComponent(regionParser).build();
}
/**
@@ -63,9 +64,8 @@ public class SellCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("sell")
.flag(this.buyRegionFlag)
.handler(this::handleCommand);
@@ -84,13 +84,13 @@ public class SellCommand extends AreashopCommandBean {
return null;
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
this.messageBridge.message(sender, "sell-noPermission");
return;
}
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, this.buyRegionFlag);
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, sender, this.buyRegionFlag);
if (!buy.isSold()) {
messageBridge.message(sender, "sell-notBought", buy);
return;
@@ -99,7 +99,7 @@ public class SellCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestBuyRegions(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.DurationInput;
@@ -40,7 +41,7 @@ public class SetDurationCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.setduration")) {
return "help-setduration";
}
@@ -52,9 +53,8 @@ public class SetDurationCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("setduration")
.required(KEY_DURATION, StringParser.stringParser())
.flag(this.regionFlag)
@@ -66,13 +66,13 @@ public class SetDurationCommand extends AreashopCommandBean {
return CommandProperties.of("setduration");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.setduration") && (!sender.hasPermission("areashop.setduration.landlord") && sender instanceof Player)) {
this.messageBridge.message(sender, "setduration-noPermission");
return;
}
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, this.regionFlag);
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, sender, this.regionFlag);
if (!sender.hasPermission("areashop.setduration")
&& !(sender instanceof Player player
&& rent.isLandlord(player.getUniqueId()))
@@ -3,13 +3,15 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.OfflinePlayer;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
@@ -24,23 +26,29 @@ import javax.annotation.Nonnull;
@Singleton
public class SetLandlordCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
private static final CloudKey<String> KEY_PLAYER = CloudKey.of("player", String.class);
private final MessageBridge messageBridge;
private final CommandFlag<GeneralRegion> regionFlag;
private final OfflinePlayerHelper offlinePlayerHelper;
private final BukkitSchedulerExecutor executor;
@Inject
public SetLandlordCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
@Nonnull IFileManager fileManager,
@Nonnull OfflinePlayerHelper offlinePlayerHelper,
@Nonnull BukkitSchedulerExecutor executor
) {
this.messageBridge = messageBridge;
this.regionFlag = RegionParseUtil.createDefault(fileManager);
this.offlinePlayerHelper = offlinePlayerHelper;
this.executor = executor;
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.setlandlord")) {
return "help-setlandlord";
}
@@ -52,11 +60,10 @@ public class SetLandlordCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("setlandlord")
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.required(KEY_PLAYER, OfflinePlayerParser.parser())
.flag(this.regionFlag)
.handler(this::handleCommand);
}
@@ -66,17 +73,28 @@ public class SetLandlordCommand extends AreashopCommandBean {
return CommandProperties.of("setlandlord");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.setlandlord")) {
throw new AreaShopCommandException("setlandlord-noPermission");
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
OfflinePlayer player = context.get(KEY_PLAYER);
String playerName = player.getName();
region.setLandlord(player.getUniqueId(), playerName);
region.update();
this.messageBridge.message(sender, "setlandlord-success", playerName, region);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_PLAYER))
.whenCompleteAsync((landlord, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!landlord.hasPlayedBefore() && !landlord.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", landlord.getName());
return;
}
String playerName = landlord.getName();
region.setLandlord(landlord.getUniqueId(), playerName);
region.update();
this.messageBridge.message(sender, "setlandlord-success", playerName, region);
}, this.executor);
}
}
@@ -0,0 +1,88 @@
package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.RentRegion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.parser.standard.IntegerParser;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
@Singleton
public class SetMaxExtends extends AreashopCommandBean {
private static final CloudKey<Integer> KEY_EXTENDS = CloudKey.of("extends", Integer.class);
private final MessageBridge messageBridge;
private final CommandFlag<RentRegion> regionFlag;
@Inject
public SetMaxExtends(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
) {
this.messageBridge = messageBridge;
this.regionFlag = RegionParseUtil.createDefaultRent(fileManager);
}
@Override
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.setmaxextends")) {
return "help-setmaxextends";
}
return null;
}
@Override
public String stringDescription() {
return null;
}
@Override
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("setmaxextends")
.required(KEY_EXTENDS, IntegerParser.integerParser(0))
.flag(this.regionFlag)
.handler(this::handleCommand);
}
@Override
protected @NonNull CommandProperties properties() {
return CommandProperties.of("setmaxextends");
}
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.setmaxextends") && (!sender.hasPermission("areashop.setmaxextends.landlord") && sender instanceof Player)) {
this.messageBridge.message(sender, "setmaxextends-noPermission");
return;
}
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, sender, this.regionFlag);
if (!sender.hasPermission("areashop.setmaxextends")
&& !(sender instanceof Player player
&& rent.isLandlord(player.getUniqueId()))
) {
this.messageBridge.message(sender, "setmaxextends-noLandlord", rent);
return;
}
int extend = context.get(KEY_EXTENDS);
sender.sendMessage();
rent.setMaxExtends(extend);
rent.update();
this.messageBridge.message(sender, "setmaxextends-success", rent);
}
}
@@ -3,13 +3,16 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -27,22 +30,28 @@ import java.util.UUID;
@Singleton
public class SetOwnerCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
private static final CloudKey<String> KEY_PLAYER = CloudKey.of("player", String.class);
private final CommandFlag<GeneralRegion> regionFlag;
private final MessageBridge messageBridge;
private final OfflinePlayerHelper offlinePlayerHelper;
private final BukkitSchedulerExecutor executor;
@Inject
public SetOwnerCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
) {
@Nonnull IFileManager fileManager,
@Nonnull OfflinePlayerHelper offlinePlayerHelper,
@Nonnull BukkitSchedulerExecutor executor
) {
this.messageBridge = messageBridge;
this.regionFlag = RegionParseUtil.createDefault(fileManager);
this.offlinePlayerHelper = offlinePlayerHelper;
this.executor = executor;
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
return "help-setowner";
}
@@ -54,11 +63,10 @@ public class SetOwnerCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("setowner")
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.required(KEY_PLAYER, OfflinePlayerParser.parser())
.flag(this.regionFlag)
.handler(this::handleCommand);
}
@@ -68,13 +76,13 @@ public class SetOwnerCommand extends AreashopCommandBean {
return CommandProperties.of("setowner");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
this.messageBridge.message(sender, "setowner-noPermission");
return;
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
if (region instanceof RentRegion && !sender.hasPermission("areashop.setownerrent")) {
this.messageBridge.message(sender, "setowner-noPermissionRent", region);
return;
@@ -83,11 +91,22 @@ public class SetOwnerCommand extends AreashopCommandBean {
this.messageBridge.message(sender, "setowner-noPermissionBuy", region);
return;
}
OfflinePlayer player = context.get(KEY_PLAYER);
if (!player.hasPlayedBefore()) {
this.messageBridge.message(sender, "setowner-noPlayer", player.getName(), region);
return;
}
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_PLAYER))
.whenCompleteAsync((offlinePlayer, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", offlinePlayer.getName());
return;
}
setOwner(sender, offlinePlayer, region);
}, this.executor);
}
private void setOwner(@Nonnull CommandSender sender, @Nonnull OfflinePlayer player, GeneralRegion region) {
final UUID uuid = player.getUniqueId();
if (region instanceof RentRegion rent) {
if (rent.isRenter(uuid)) {
@@ -5,6 +5,7 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -49,9 +50,8 @@ public class SetPriceCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("setprice")
.required(KEY_PRICE, StringParser.stringParser())
.flag(this.regionFlag)
@@ -63,13 +63,13 @@ public class SetPriceCommand extends AreashopCommandBean {
return CommandProperties.of("setprice");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.setprice") && (!sender.hasPermission("areashop.setprice.landlord") && sender instanceof Player)) {
this.messageBridge.message(sender, "setprice-noPermission");
return;
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
if (!sender.hasPermission("areashop.setprice")
&& !(sender instanceof Player player && region.isLandlord(player.getUniqueId()))) {
this.messageBridge.message(sender, "setprice-noLandlord", region);
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
@@ -44,7 +45,7 @@ public class SetRestoreCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.setrestore")) {
return "help-setrestore";
}
@@ -56,9 +57,8 @@ public class SetRestoreCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("setrestore")
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
.required(KEY_RESTORE, StringParser.stringParser(), this::suggestRestoreType)
@@ -71,8 +71,8 @@ public class SetRestoreCommand extends AreashopCommandBean {
return CommandProperties.of("setrestore");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.setrestore")) {
throw new AreaShopCommandException("setrestore-noPermission");
}
@@ -101,7 +101,7 @@ public class SetRestoreCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestRestoreType(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -113,7 +113,7 @@ public class SetRestoreCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestSchematicProfiles(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
ConfigurationSection schemProfiles = fileManager.getConfig().getConfigurationSection("schematicProfiles");
@@ -7,6 +7,8 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -53,7 +55,7 @@ public class SetTeleportCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.setteleportall") || target.hasPermission("areashop.setteleport")) {
return "help-setteleport";
}
@@ -65,11 +67,10 @@ public class SetTeleportCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("settp")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.flag(this.regionFlag)
.handler(this::handleCommand);
}
@@ -79,13 +80,13 @@ public class SetTeleportCommand extends AreashopCommandBean {
return CommandProperties.of("settp");
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
if (!player.hasPermission("areashop.setteleport") && !player.hasPermission("areashop.setteleportall")) {
this.messageBridge.message(player, "setteleport-noPermission");
return;
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, player, this.regionFlag);
boolean owner;
if (region instanceof RentRegion rentRegion) {
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
@@ -49,9 +50,8 @@ public class SetTransferCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("settransfer")
.required(KEY_ENABLED, BooleanParser.booleanParser(true))
.flag(this.regionFlag)
@@ -63,12 +63,12 @@ public class SetTransferCommand extends AreashopCommandBean {
return CommandProperties.of("settransfer");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.settransfer")) {
throw new AreaShopCommandException("settransfer-noPermission");
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
boolean enabled = context.get(KEY_ENABLED);
region.setTransferEnabled(enabled);
messageBridge.message(sender, "settransfer-success", enabled, region);
@@ -7,6 +7,8 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
@@ -96,7 +98,7 @@ public class StackCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.stack")) {
return "help-stack";
}
@@ -108,11 +110,10 @@ public class StackCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("stack")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_AMOUNT, IntegerParser.integerParser(0))
.required(KEY_GAP, IntegerParser.integerParser(0))
.required(KEY_NAME, StringParser.stringParser())
@@ -127,8 +128,8 @@ public class StackCommand extends AreashopCommandBean {
return CommandProperties.of("stack");
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
if (!player.hasPermission("areashop.stack")) {
throw new AreaShopCommandException("stack-noPermission");
}
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.BuyRegionParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -35,11 +36,11 @@ public class StopResellCommand extends AreashopCommandBean {
@Inject
public StopResellCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
ParserDescriptor<CommandSender, BuyRegion> regionParser =
ParserDescriptor<CommandSource<?>, BuyRegion> regionParser =
ParserDescriptor.of(new BuyRegionParser<>(fileManager, this::suggestBuyRegions), BuyRegion.class);
this.messageBridge = messageBridge;
this.fileManager = fileManager;
this.regionFlag = CommandFlag.builder("region")
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region")
.withComponent(regionParser)
.build();
}
@@ -57,9 +58,8 @@ public class StopResellCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("stopresell")
.flag(this.regionFlag)
.handler(this::handleCommand);
@@ -70,14 +70,14 @@ public class StopResellCommand extends AreashopCommandBean {
return CommandProperties.of("stopresell");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.stopresell") && !sender.hasPermission("areashop.stopresellall")) {
this.messageBridge.message(sender, "stopresell-noPermissionOther");
return;
}
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, this.regionFlag);
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, sender, this.regionFlag);
if (!buy.isInResellingMode()) {
this.messageBridge.message(sender, "stopresell-notResell", buy);
return;
@@ -100,7 +100,7 @@ public class StopResellCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestBuyRegions(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -5,6 +5,8 @@ import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.command.CommandSender;
@@ -53,7 +55,7 @@ public class TeleportCommand extends AreashopCommandBean {
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
return "help-teleport";
}
@@ -65,11 +67,10 @@ public class TeleportCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("tp", "teleport")
.senderType(Player.class)
.senderType(PlayerCommandSource.class)
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
.handler(this::handleCommand);
}
@@ -79,8 +80,8 @@ public class TeleportCommand extends AreashopCommandBean {
return CommandProperties.of("teleport", "tp");
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player player = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player player = context.sender().sender();
if (!player.hasPermission("areashop.teleport") && !player.hasPermission("areashop.teleportall") && !player.hasPermission(
"areashop.teleportavailable") && !player.hasPermission("areashop.teleportavailablesign") && !player.hasPermission(
"areashop.teleportsign") && !player.hasPermission("areashop.teleportsignall") && !player.hasPermission(
@@ -7,6 +7,7 @@ import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.features.homeaccess.HomeAccessFeature;
import me.wiefferink.areashop.features.homeaccess.HomeAccessType;
import me.wiefferink.areashop.managers.IFileManager;
@@ -43,9 +44,9 @@ public final class ToggleHomeCommand extends AreashopCommandBean {
public ToggleHomeCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
this.messageBridge = messageBridge;
this.fileManager = fileManager;
this.regionFlag = CommandFlag.builder("region")
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region")
.withComponent(
new CommandComponent.Builder<CommandSender, GeneralRegion>()
CommandComponent.<CommandSource<?>, GeneralRegion>builder()
.name("region")
.description(Description.EMPTY)
.valueType(GeneralRegion.class)
@@ -57,7 +58,7 @@ public final class ToggleHomeCommand extends AreashopCommandBean {
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (!target.hasPermission("sethomecontrol.control")) {
return null;
}
@@ -69,9 +70,8 @@ public final class ToggleHomeCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("togglehome")
.required(KEY_ACCESS_TYPE, EnumParser.enumParser(HomeAccessType.class))
.flag(this.regionFlag)
@@ -83,13 +83,13 @@ public final class ToggleHomeCommand extends AreashopCommandBean {
return CommandProperties.of("togglehome");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.togglehome")) {
throw new AreaShopCommandException("togglehome-noPermission");
}
final HomeAccessType accessType = context.get(KEY_ACCESS_TYPE);
final GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
final GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
if (!(sender instanceof Player) && !sender.hasPermission("sethome.control.other")) {
return;
}
@@ -101,11 +101,11 @@ public final class ToggleHomeCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestRegions(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
CommandSender sender = context.sender();
CommandSender sender = context.sender().sender();
Stream<GeneralRegion> regions;
if (sender.hasPermission("sethome.control.other")) {
regions = this.fileManager.getRegionsRef().stream();
@@ -3,11 +3,14 @@ package me.wiefferink.areashop.commands;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
import me.wiefferink.areashop.commands.util.OfflinePlayerParser;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.OfflinePlayer;
@@ -33,27 +36,30 @@ import java.util.concurrent.CompletableFuture;
@Singleton
public class TransferCommand extends AreashopCommandBean {
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
private static final CloudKey<String> KEY_PLAYER = CloudKey.of("player", String.class);
private final MessageBridge messageBridge;
private final IFileManager fileManager;
private final CommandFlag<GeneralRegion> regionFlag;
private final OfflinePlayerHelper offlinePlayerHelper;
@Inject
public TransferCommand(
@Nonnull MessageBridge messageBridge,
@Nonnull IFileManager fileManager
@Nonnull IFileManager fileManager,
@Nonnull OfflinePlayerHelper offlinePlayerHelper
) {
ParserDescriptor<Player, GeneralRegion> regionParser =
ParserDescriptor<PlayerCommandSource, GeneralRegion> regionParser =
ParserDescriptor.of(new GeneralRegionParser<>(fileManager, this::suggestRegions), GeneralRegion.class);
this.messageBridge = messageBridge;
this.fileManager = fileManager;
this.regionFlag = CommandFlag.builder("region")
this.regionFlag = CommandFlag.<PlayerCommandSource>builder("region")
.withComponent(regionParser)
.build();
this.offlinePlayerHelper = offlinePlayerHelper;
}
@Override
public String getHelpKey(CommandSender target) {
public String getHelpKey(@NotNull CommandSender target) {
if (!target.hasPermission("areashop.transfer")) {
return null;
}
@@ -65,12 +71,11 @@ public class TransferCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("transfer")
.senderType(Player.class)
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
.senderType(PlayerCommandSource.class)
.required(KEY_PLAYER, OfflinePlayerParser.parser())
.flag(this.regionFlag)
.handler(this::handleCommand);
}
@@ -80,21 +85,41 @@ public class TransferCommand extends AreashopCommandBean {
return CommandProperties.of("transfer");
}
private void handleCommand(@Nonnull CommandContext<Player> context) {
Player sender = context.sender();
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
Player sender = context.sender().sender();
if (!sender.hasPermission("areashop.transfer")) {
throw new AreaShopCommandException("transfer-noPermission");
}
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, this.regionFlag);
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
if (!region.isTransferEnabled()) {
throw new AreaShopCommandException("transfer-disabled");
}
OfflinePlayer targetPlayer = context.get(KEY_PLAYER);
this.offlinePlayerHelper.lookupOfflinePlayerAsync(context.get(KEY_PLAYER))
.whenComplete((offlinePlayer, exception) -> {
if (exception != null) {
sender.sendMessage("failed to lookup offline player!");
exception.printStackTrace();
return;
}
if (!offlinePlayer.hasPlayedBefore() &&!offlinePlayer.isOnline()) {
this.messageBridge.message(sender, "cmd-invalidPlayer", offlinePlayer.getName());
return;
}
performTransfer(sender, offlinePlayer, region);
});
}
private void performTransfer(
@Nonnull Player sender,
@Nonnull OfflinePlayer targetPlayer,
@Nonnull GeneralRegion region
) {
String targetPlayerName = targetPlayer.getName();
if (Objects.equals(sender, targetPlayer)) {
throw new AreaShopCommandException("transfer-transferSelf");
}
if (!targetPlayer.hasPlayedBefore()) {
if (!targetPlayer.hasPlayedBefore() && !targetPlayer.isOnline()) {
// Unknown player
throw new AreaShopCommandException("transfer-noPlayer", targetPlayerName);
}
@@ -124,11 +149,11 @@ public class TransferCommand extends AreashopCommandBean {
}
private CompletableFuture<Iterable<Suggestion>> suggestRegions(
@Nonnull CommandContext<Player> context,
@Nonnull CommandContext<PlayerCommandSource> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
UUID uuid = context.sender().getUniqueId();
UUID uuid = context.sender().sender().getUniqueId();
List<Suggestion> suggestions = this.fileManager.getRegions()
.stream()
.filter(region -> region.isOwner(uuid) || region.isLandlord(uuid))
@@ -6,6 +6,7 @@ import me.wiefferink.areashop.commands.util.AreaShopCommandException;
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
import me.wiefferink.areashop.commands.util.RegionParseUtil;
import me.wiefferink.areashop.commands.util.RentRegionParser;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
@@ -32,10 +33,10 @@ public class UnrentCommand extends AreashopCommandBean {
@Inject
public UnrentCommand(@Nonnull IFileManager fileManager) {
ParserDescriptor<CommandSender, RentRegion> regionParser =
ParserDescriptor<CommandSource<?>, RentRegion> regionParser =
ParserDescriptor.of(new RentRegionParser<>(fileManager, this::suggestRegions), RentRegion.class);
this.fileManager = fileManager;
this.regionFlag = CommandFlag.builder("region")
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region")
.withComponent(regionParser)
.build();
}
@@ -70,9 +71,8 @@ public class UnrentCommand extends AreashopCommandBean {
return null;
}
@NotNull
@Override
protected Command.Builder<? extends CommandSender> configureCommand(@NotNull Command.Builder<CommandSender> builder) {
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
return builder.literal("unrent")
.flag(this.regionFlag)
.handler(this::handleCommand);
@@ -83,12 +83,12 @@ public class UnrentCommand extends AreashopCommandBean {
return CommandProperties.of("unrent");
}
private void handleCommand(@Nonnull CommandContext<CommandSender> context) {
CommandSender sender = context.sender();
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
CommandSender sender = context.sender().sender();
if (!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
throw new AreaShopCommandException("unrent-noPermission");
}
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, this.regionFlag);
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, sender, this.regionFlag);
if (!rent.isRented()) {
throw new AreaShopCommandException("unrent-notRented", rent);
}
@@ -97,7 +97,7 @@ public class UnrentCommand extends AreashopCommandBean {
@Nonnull
private CompletableFuture<Iterable<Suggestion>> suggestRegions(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<CommandSource<?>> context,
@Nonnull CommandInput input
) {
String text = input.peekString();
@@ -1,6 +1,6 @@
package me.wiefferink.areashop.commands.util;
import org.bukkit.command.CommandSender;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandBean;
import org.incendo.cloud.key.CloudKey;
@@ -12,7 +12,7 @@ import javax.annotation.Nonnull;
* An extension of {@link CommandBean} which does extra pre-processing of the commands.
* Adapted from <a href="https://github.com/Incendo/kitchensink">KitchenSink</a>
*/
public abstract class AreashopCommandBean extends CommandBean<CommandSender> implements HelpProvider {
public abstract class AreashopCommandBean extends CommandBean<CommandSource<?>> implements HelpProvider {
private boolean requireConfirmation;
@@ -21,8 +21,8 @@ public abstract class AreashopCommandBean extends CommandBean<CommandSender> imp
}
@Override
protected final @Nonnull Command.Builder<? extends CommandSender> configure(
final @Nonnull Command.Builder<CommandSender> builder
protected final @Nonnull Command.Builder<? extends CommandSource<?>> configure(
final @Nonnull Command.Builder<CommandSource<?>> builder
) {
return this.configureCommand(builder)
.meta(CloudKey.of("bukkit_description", String.class), this.stringDescription())
@@ -44,7 +44,7 @@ public abstract class AreashopCommandBean extends CommandBean<CommandSender> imp
* @param builder builder to configure
* @return the updated builder
*/
protected abstract @Nonnull Command.Builder<? extends CommandSender> configureCommand(
@Nonnull Command.Builder<CommandSender> builder
protected abstract @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(
@Nonnull Command.Builder<CommandSource<?>> builder
);
}
@@ -46,10 +46,11 @@ import me.wiefferink.areashop.commands.TeleportCommand;
import me.wiefferink.areashop.commands.ToggleHomeCommand;
import me.wiefferink.areashop.commands.TransferCommand;
import me.wiefferink.areashop.commands.UnrentCommand;
import me.wiefferink.areashop.commands.SetMaxExtends;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.CommandSourceMapper;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.incendo.cloud.SenderMapper;
import org.incendo.cloud.bukkit.CloudBukkitCapabilities;
import org.incendo.cloud.exception.ArgumentParseException;
import org.incendo.cloud.exception.CommandExecutionException;
import org.incendo.cloud.exception.InvalidCommandSenderException;
@@ -109,13 +110,14 @@ public class AreashopCommands {
TeleportCommand.class,
ToggleHomeCommand.class,
TransferCommand.class,
UnrentCommand.class
UnrentCommand.class,
SetMaxExtends.class
);
private final MessageBridge messageBridge;
private final Injector injector;
private final PaperCommandManager<CommandSender> commandManager;
private final PaperCommandManager<CommandSource<?>> commandManager;
private final List<AreashopCommandBean> commands = new ArrayList<>();
private HelpRenderer helpRenderer;
@@ -123,11 +125,9 @@ public class AreashopCommands {
@Inject
AreashopCommands(@Nonnull Injector injector, @Nonnull Plugin plugin, @Nonnull MessageBridge messageBridge) {
this.injector = injector;
this.commandManager = new PaperCommandManager<>(
plugin,
ExecutionCoordinator.simpleCoordinator(),
SenderMapper.identity()
);
this.commandManager = PaperCommandManager.builder(new CommandSourceMapper())
.executionCoordinator(ExecutionCoordinator.simpleCoordinator())
.buildOnEnable(plugin);
this.messageBridge = messageBridge;
}
@@ -142,25 +142,22 @@ public class AreashopCommands {
this.commandManager.command(configuredBuilder);
}
// Show help by default
this.commandManager.command(builder.handler(context -> showHelp(context.sender())));
this.commandManager.command(builder.handler(context -> showHelp(context.sender().sender())));
this.helpRenderer = new HelpRenderer(this.messageBridge, this.commands);
}
private void initCommandManager() {
if (this.commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) {
this.commandManager.registerBrigadier();
}
ExceptionController<CommandSender> exceptionController = this.commandManager.exceptionController();
ExceptionController<CommandSource<?>> exceptionController = this.commandManager.exceptionController();
// We need to unwrap ArgumentParseException because they wrap the custom exception messages
exceptionController.registerHandler(ArgumentParseException.class,
ExceptionHandler.unwrappingHandler(AreaShopCommandException.class));
exceptionController.registerHandler(CommandExecutionException.class,
ExceptionHandler.unwrappingHandler(AreaShopCommandException.class));
exceptionController.registerHandler(InvalidCommandSenderException.class,
new InvalidCommandSenderHandler(this.messageBridge));
exceptionController.registerHandler(AreaShopCommandException.class,
new ArgumentParseExceptionHandler<>(this.messageBridge));
var confirmationConfiguration = ConfirmationConfiguration.<CommandSender>builder()
exceptionController.registerHandler(ArgumentParseException.class,
ExceptionHandler.unwrappingHandler(AreaShopCommandException.class));
exceptionController.registerHandler(CommandExecutionException.class,
ExceptionHandler.unwrappingHandler(AreaShopCommandException.class));
var confirmationConfiguration = ConfirmationConfiguration.<CommandSource<?>>builder()
.cache(GuavaCache.of(CacheBuilder.newBuilder().build()))
.noPendingCommandNotifier(x -> {
})
@@ -1,13 +1,13 @@
package me.wiefferink.areashop.commands.util;
import me.wiefferink.areashop.MessageBridge;
import org.bukkit.command.CommandSender;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import org.incendo.cloud.exception.handling.ExceptionContext;
import org.incendo.cloud.exception.handling.ExceptionHandler;
import javax.annotation.Nonnull;
public class ArgumentParseExceptionHandler<C extends CommandSender> implements ExceptionHandler<C, AreaShopCommandException> {
public class ArgumentParseExceptionHandler<C extends CommandSource<?>> implements ExceptionHandler<C, AreaShopCommandException> {
private final MessageBridge messageBridge;
@@ -17,17 +17,17 @@ public class ArgumentParseExceptionHandler<C extends CommandSender> implements E
public static void handleException(
@Nonnull MessageBridge messageBridge,
@Nonnull CommandSender sender,
@Nonnull CommandSource<?> sender,
@Nonnull AreaShopCommandException exception
) {
String key = exception.messageKey();
Object[] replacements = exception.replacements();
if (replacements.length == 0) {
messageBridge.message(sender, key);
messageBridge.message(sender.sender(), key);
return;
}
// Pass the values as a var-args and not as a string[]
messageBridge.message(sender, key, replacements);
messageBridge.message(sender.sender(), key, replacements);
}
@Override
@@ -1,8 +1,8 @@
package me.wiefferink.areashop.commands.util;
import me.wiefferink.areashop.MessageBridge;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.exception.InvalidCommandSenderException;
import org.incendo.cloud.exception.handling.ExceptionContext;
@@ -10,7 +10,7 @@ import org.incendo.cloud.exception.handling.ExceptionHandler;
import javax.annotation.Nonnull;
public class InvalidCommandSenderHandler implements ExceptionHandler<CommandSender, InvalidCommandSenderException> {
public class InvalidCommandSenderHandler implements ExceptionHandler<CommandSource<?>, InvalidCommandSenderException> {
private final MessageBridge messageBridge;
@@ -19,9 +19,9 @@ public class InvalidCommandSenderHandler implements ExceptionHandler<CommandSend
}
@Override
public void handle(@NonNull ExceptionContext<CommandSender, InvalidCommandSenderException> context) throws Throwable {
public void handle(@NonNull ExceptionContext<CommandSource<?>, InvalidCommandSenderException> context) throws Throwable {
InvalidCommandSenderException exception = context.exception();
if (exception.requiredSender().equals(Player.class)) {
if (exception.requiredSenderTypes().contains(PlayerCommandSource.class)) {
this.messageBridge.message(exception.commandSender(), "cmd-onlyByPlayer");
return;
}
@@ -0,0 +1,38 @@
package me.wiefferink.areashop.commands.util;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.parser.ArgumentParseResult;
import org.incendo.cloud.parser.ArgumentParser;
import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.suggestion.BlockingSuggestionProvider;
public class OfflinePlayerParser<C> implements ArgumentParser<C, String>, BlockingSuggestionProvider.Strings<C> {
public static <C> ParserDescriptor<C, String> parser() {
return ParserDescriptor.of(new OfflinePlayerParser<>(), String.class);
}
@Override
public @NonNull ArgumentParseResult<@NonNull String> parse(@NonNull CommandContext<@NonNull C> commandContext,
@NonNull CommandInput commandInput) {
final String input = commandInput.readString();
if (input.length() > 16) {
return ArgumentParseResult.failure(new AreaShopCommandException("cmd-invalidPlayer", input));
}
return ArgumentParseResult.success(input);
}
@Override
public @NonNull Iterable<@NonNull String> stringSuggestions(@NonNull CommandContext<C> commandContext,
@NonNull CommandInput input) {
return Bukkit.getServer().getOnlinePlayers().stream()
.map(Player::getName)
.toList();
}
}
@@ -38,16 +38,16 @@ public class RegionCreationUtil {
}
public CompletableFuture<ProtectedRegion> createRegion(
@Nonnull CommandContext<Player> context,
@Nonnull CommandContext<?> context,
@Nonnull Player sender,
@Nonnull CloudKey<String> regionKey
) {
Player player = context.sender();
World world = player.getWorld();
World world = sender.getWorld();
String regionName = context.get(regionKey);
if (this.fileManager.getRegion(regionName) != null) {
return CompletableFuture.failedFuture(new AreaShopCommandException("add-failed", regionName));
}
this.server.dispatchCommand(player, String.format("rg define %s", regionName));
this.server.dispatchCommand(sender, String.format("rg define %s", regionName));
CompletableFuture<ProtectedRegion> future = new CompletableFuture<>();
this.server.getScheduler().runTaskLater(this.plugin, () -> {
ProtectedRegion region = this.worldGuardInterface.getRegionManager(world).getRegion(regionName);
@@ -33,10 +33,10 @@ public final class RegionParseUtil {
@Nonnull
public static Collection<GeneralRegion> getOrParseRegionsInSel(
@Nonnull CommandContext<CommandSender> context,
@Nonnull CommandContext<?> context,
@Nonnull CommandSender sender,
@Nonnull CommandFlag<GeneralRegion> regionFlag
) {
CommandSender sender = context.sender();
if (!(sender instanceof Player player)) {
throw new AreaShopCommandException("cmd-weOnlyByPlayer");
}
@@ -54,15 +54,15 @@ public final class RegionParseUtil {
}
@Nonnull
public static <C> GeneralRegion getOrParseRegion(
@Nonnull CommandContext<C> context,
public static GeneralRegion getOrParseRegion(
@Nonnull CommandContext<?> context,
@Nonnull CommandSender sender,
@Nonnull CommandFlag<GeneralRegion> flag
) throws AreaShopCommandException {
GeneralRegion region = context.flags().get(flag);
if (region != null) {
return region;
}
C sender = context.sender();
if (!(sender instanceof Entity entity)) {
throw new AreaShopCommandException("cmd-automaticRegionOnlyByPlayer");
}
@@ -74,21 +74,21 @@ public final class RegionParseUtil {
} else if (regions.size() > 1) {
errorMessageKey = "cmd-moreRegionsAtLocation";
} else {
return regions.get(0);
return regions.getFirst();
}
throw new AreaShopCommandException(errorMessageKey);
}
@Nonnull
public static <C> GeneralRegion getOrParseRegion(
@Nonnull CommandContext<C> context,
public static GeneralRegion getOrParseRegion(
@Nonnull CommandContext<?> context,
@Nonnull CommandSender sender,
@Nonnull CloudKey<GeneralRegion> key
) throws AreaShopCommandException {
GeneralRegion region = context.getOrDefault(key, null);
if (region != null) {
return region;
}
C sender = context.sender();
if (!(sender instanceof Entity entity)) {
throw new AreaShopCommandException("cmd-automaticRegionOnlyByPlayer");
}
@@ -100,7 +100,7 @@ public final class RegionParseUtil {
} else if (regions.size() > 1) {
errorMessageKey = "cmd-moreRegionsAtLocation";
} else {
return regions.get(0);
return regions.getFirst();
}
throw new AreaShopCommandException(errorMessageKey);
}
@@ -121,12 +121,14 @@ public final class RegionParseUtil {
}
@Nonnull
public static BuyRegion getOrParseBuyRegion(@Nonnull CommandContext<? extends CommandSender> context, CommandFlag<BuyRegion> flag) {
public static BuyRegion getOrParseBuyRegion(
@Nonnull CommandContext<?> context,
@Nonnull CommandSender sender,
@Nonnull CommandFlag<BuyRegion> flag) {
BuyRegion buyRegion = context.flags().get(flag);
if (buyRegion != null) {
return buyRegion;
}
CommandSender sender = context.sender();
if (!(sender instanceof Player player)) {
throw new AreaShopCommandException("cmd-automaticRegionOnlyByPlayer");
}
@@ -136,16 +138,18 @@ public final class RegionParseUtil {
} else if (regions.size() != 1) {
throw new AreaShopCommandException("cmd-moreRegionsAtLocation");
}
return regions.get(0);
return regions.getFirst();
}
@Nonnull
public static RentRegion getOrParseRentRegion(@Nonnull CommandContext<? extends CommandSender> context, CommandFlag<RentRegion> flag) {
public static RentRegion getOrParseRentRegion(
@Nonnull CommandContext<?> context,
@Nonnull CommandSender sender,
@Nonnull CommandFlag<RentRegion> flag) {
RentRegion rentRegion = context.flags().get(flag);
if (rentRegion != null) {
return rentRegion;
}
CommandSender sender = context.sender();
if (!(sender instanceof Player player)) {
throw new AreaShopCommandException("cmd-automaticRegionOnlyByPlayer");
}
@@ -155,7 +159,7 @@ public final class RegionParseUtil {
} else if (regions.size() != 1) {
throw new AreaShopCommandException("cmd-moreRegionsAtLocation");
}
return regions.get(0);
return regions.getFirst();
}
}
@@ -1,6 +1,5 @@
package me.wiefferink.areashop.commands.util;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -45,14 +44,14 @@ public final class SignProfileUtil {
}
@Nullable
public static String getOrParseProfile(@Nonnull CommandContext<? extends CommandSender> context,
public static String getOrParseProfile(@Nonnull CommandContext<?> context,
@Nonnull Plugin plugin) {
return getOrParseProfile(context, DEFAULT_FLAG, plugin);
}
@Nullable
public static String getOrParseProfile(
@Nonnull CommandContext<? extends CommandSender> context,
@Nonnull CommandContext<?> context,
@Nonnull CommandFlag<String> flag,
@Nonnull Plugin plugin
) throws AreaShopCommandException {
@@ -1,59 +0,0 @@
package me.wiefferink.areashop.commands.util;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.bukkit.BukkitCommandContextKeys;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.parser.ArgumentParseResult;
import org.incendo.cloud.parser.ArgumentParser;
import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.suggestion.BlockingSuggestionProvider;
public class ValidatedOfflinePlayerParser<C> implements ArgumentParser<C, OfflinePlayer>, BlockingSuggestionProvider.Strings<C> {
public static <C> ParserDescriptor<C, OfflinePlayer> validatedOfflinePlayerParser() {
return ParserDescriptor.of(new ValidatedOfflinePlayerParser<>(), OfflinePlayer.class);
}
@Override
@SuppressWarnings("deprecation")
public @NonNull ArgumentParseResult<OfflinePlayer> parse(
final @NonNull CommandContext<C> commandContext,
final @NonNull CommandInput commandInput
) {
final String input = commandInput.readString();
if (input.length() > 16) {
return ArgumentParseResult.failure(new AreaShopCommandException("cmd-invalidPlayer", input));
}
final Player onlinePlayer = Bukkit.getPlayerExact(input);
if (onlinePlayer != null) {
return ArgumentParseResult.success(onlinePlayer);
}
final OfflinePlayer player;
try {
player = Bukkit.getOfflinePlayer(input);
} catch (final Exception e) {
return ArgumentParseResult.failure(new AreaShopCommandException("cmd-invalidPlayer", input));
}
if (!player.hasPlayedBefore()) {
return ArgumentParseResult.failure(new AreaShopCommandException("cmd-invalidPlayer", input));
}
return ArgumentParseResult.success(player);
}
@Override
public @NonNull Iterable<@NonNull String> stringSuggestions(
final @NonNull CommandContext<C> commandContext,
final @NonNull CommandInput input
) {
final CommandSender sender = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
return Bukkit.getOnlinePlayers().stream()
.filter(onlinePlayer -> !(sender instanceof Player player && !((Player) sender).canSee(player)))
.map(Player::getName)
.toList();
}
}
@@ -19,20 +19,21 @@ public final class WorldFlagUtil {
}
@Nonnull
public static <C extends Entity> World parseOrDetectWorld(@Nonnull CommandContext<C> context) {
return parseOrDetectWorld(context, DEFAULT_WORLD_FLAG);
public static World parseOrDetectWorld(@Nonnull CommandContext<?> context, @Nonnull Entity sender) {
return parseOrDetectWorld(context, sender, DEFAULT_WORLD_FLAG);
}
@Nonnull
public static <C extends Entity> World parseOrDetectWorld(
@Nonnull CommandContext<C> context,
public static World parseOrDetectWorld(
@Nonnull CommandContext<?> context,
@Nonnull Entity sender,
@Nonnull CommandFlag<World> flag
) {
World world = context.flags().get(flag);
if (world != null) {
return world;
}
return context.sender().getWorld();
return sender.getWorld();
}
}
@@ -2,6 +2,7 @@ package me.wiefferink.areashop.commands.util;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.commands.util.commandsource.EntityCommandSource;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@@ -17,7 +18,7 @@ import org.incendo.cloud.suggestion.SuggestionProvider;
import javax.annotation.Nonnull;
import java.util.Collections;
public class WorldGuardRegionParser<C extends Entity> implements ArgumentParser<C, ProtectedRegion> {
public class WorldGuardRegionParser<C extends EntityCommandSource> implements ArgumentParser<C, ProtectedRegion> {
private final WorldGuardInterface worldGuardInterface;
private final CommandFlag<World> worldFlag;
@@ -29,7 +30,7 @@ public class WorldGuardRegionParser<C extends Entity> implements ArgumentParser<
this.worldGuardInterface = worldGuardInterface;
}
public static <C extends Entity> ParserDescriptor<C, ProtectedRegion> worldGuardRegionParser(
public static <C extends EntityCommandSource> ParserDescriptor<C, ProtectedRegion> worldGuardRegionParser(
@Nonnull CommandFlag<World> worldFlag,
@Nonnull WorldGuardInterface worldGuardInterface
) {
@@ -39,7 +40,8 @@ public class WorldGuardRegionParser<C extends Entity> implements ArgumentParser<
@Override
public @Nonnull ArgumentParseResult<ProtectedRegion> parse(@Nonnull CommandContext<C> commandContext,
@Nonnull CommandInput commandInput) {
World world = WorldFlagUtil.parseOrDetectWorld(commandContext, worldFlag);
Entity sender = commandContext.sender().sender();
World world = WorldFlagUtil.parseOrDetectWorld(commandContext, sender, worldFlag);
String regionName = commandInput.peekString();
RegionManager regionManager = this.worldGuardInterface.getRegionManager(world);
if (regionManager == null) {
@@ -57,7 +59,7 @@ public class WorldGuardRegionParser<C extends Entity> implements ArgumentParser<
@Override
public @Nonnull SuggestionProvider<C> suggestionProvider() {
return SuggestionProvider.blockingStrings((commandContext, input) -> {
C sender = commandContext.sender();
Entity sender = commandContext.sender().sender();
if (!(sender instanceof Player player)) {
return Collections.emptyList();
}
@@ -0,0 +1,16 @@
package me.wiefferink.areashop.commands.util.commandsource;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.command.CommandSender;
import javax.annotation.Nonnull;
public interface CommandSource<C extends CommandSender> {
@Nonnull
CommandSourceStack sourceStack();
@Nonnull
C sender();
}
@@ -0,0 +1,27 @@
package me.wiefferink.areashop.commands.util.commandsource;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.SenderMapper;
public class CommandSourceMapper implements SenderMapper<CommandSourceStack, CommandSource<?>> {
@Override
public @NonNull CommandSource<?> map(@NonNull CommandSourceStack base) {
CommandSender sender = base.getSender();
if (sender instanceof Player) {
return new PlayerCommandSource(base);
} else if (sender instanceof Entity) {
return new EntityCommandSource(base);
}
return new GenericCommandSource(base);
}
@Override
public @NonNull CommandSourceStack reverse(@NonNull CommandSource<?> mapped) {
return mapped.sourceStack();
}
}
@@ -0,0 +1,15 @@
package me.wiefferink.areashop.commands.util.commandsource;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.command.CommandSender;
import javax.annotation.Nonnull;
public record CommandSourceWrapper(@Nonnull CommandSourceStack commandSourceStack) {
@Nonnull
public CommandSender sender() {
return commandSourceStack().getSender();
}
}
@@ -0,0 +1,23 @@
package me.wiefferink.areashop.commands.util.commandsource;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
public sealed class EntityCommandSource extends GenericCommandSource permits PlayerCommandSource {
public EntityCommandSource(@Nonnull CommandSourceStack sourceStack) {
super(sourceStack);
if (!(sourceStack.getSender() instanceof Entity)) {
throw new IllegalArgumentException("Source stack sender is not an entity!");
}
}
@NotNull
@Override
public Entity sender() {
return (Entity) super.sender();
}
}
@@ -0,0 +1,31 @@
package me.wiefferink.areashop.commands.util.commandsource;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
public class GenericCommandSource implements CommandSource<CommandSender> {
private final CommandSourceStack sourceStack;
private final CommandSender sender;
public GenericCommandSource(@Nonnull CommandSourceStack sourceStack) {
this.sourceStack = sourceStack;
this.sender = sourceStack.getSender();
}
@NotNull
@Override
public final CommandSourceStack sourceStack() {
return this.sourceStack;
}
@NotNull
@Override
public CommandSender sender() {
return this.sender;
}
}
@@ -0,0 +1,22 @@
package me.wiefferink.areashop.commands.util.commandsource;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
public final class PlayerCommandSource extends EntityCommandSource {
public PlayerCommandSource(@Nonnull CommandSourceStack sourceStack) {
super(sourceStack);
if (!(sourceStack.getSender() instanceof Player)) {
throw new IllegalArgumentException("Source stack sender is not a player!");
}
}
@Override
public @NotNull Player sender() {
return (Player) super.sender();
}
}
@@ -103,7 +103,7 @@ public class FriendsFeature extends RegionFeature {
HashSet<String> result = new HashSet<>();
for(UUID friend : getFriends()) {
OfflinePlayer player = Bukkit.getOfflinePlayer(friend);
if(player != null && player.getName() != null) {
if(player.getName() != null) {
result.add(player.getName());
}
}
@@ -133,7 +133,7 @@ public class WorldGuardRegionFlagsFeature extends RegionFeature {
}
} else {
// Parse all other normal flags (groups are also handled)
String flagSetting = null;
StringBuilder flagSetting = null;
com.sk89q.worldguard.protection.flags.RegionGroup groupValue = null;
Flag<?> foundFlag = worldGuardInterface.fuzzyMatchFlag(flagName);
@@ -152,7 +152,7 @@ public class WorldGuardRegionFlagsFeature extends RegionFeature {
//AreaShop.debug(" Flag " + flagName + " reset (+ possible group of flag)");
} else {
if(groupFlag == null) {
flagSetting = value;
flagSetting = new StringBuilder(value);
} else {
for(String part : value.split(" ")) {
if(part.startsWith("g:")) {
@@ -165,16 +165,16 @@ public class WorldGuardRegionFlagsFeature extends RegionFeature {
}
} else {
if(flagSetting == null) {
flagSetting = part;
flagSetting = new StringBuilder(part);
} else {
flagSetting += " " + part;
flagSetting.append(" ").append(part);
}
}
}
}
if(flagSetting != null) {
try {
setFlag(worldguardRegion, foundFlag, flagSetting);
setFlag(worldguardRegion, foundFlag, flagSetting.toString());
//AreaShop.debug(" Flag " + flagName + " set: " + flagSetting);
} catch(InvalidFlagFormat e) {
AreaShop.warn("Found wrong value for flag " + flagName);
@@ -7,7 +7,6 @@ import io.github.bakedlibs.dough.blocks.BlockPosition;
import io.papermc.lib.PaperLib;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.managers.SignErrorLogger;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.SignUtils;
@@ -16,6 +15,7 @@ import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
@@ -35,8 +35,8 @@ import java.util.List;
*/
public class RegionSign {
private final BlockBehaviourHelper blockHelper;
private final SignErrorLogger errorLogger;
private final Server server;
private final SignsFeature signsFeature;
private final String key;
@@ -44,13 +44,13 @@ public class RegionSign {
@AssistedInject
RegionSign(
@Nonnull BlockBehaviourHelper blockBehaviourHelper,
@Nonnull SignErrorLogger signErrorLogger,
@Nonnull Server server,
@Assisted @Nonnull SignsFeature signsFeature,
@Assisted @Nonnull String key
) {
this.blockHelper = blockBehaviourHelper;
this.errorLogger = signErrorLogger;
this.server = server;
this.signsFeature = signsFeature;
this.key = key;
}
@@ -176,7 +176,7 @@ public class RegionSign {
// Place the sign back (with proper rotation and type) after it has been hidden or (indirectly) destroyed
if(!Materials.isSign(block.getType())) {
Material signType = getMaterial();
if (!blockHelper.canPlace(block.getLocation(), Bukkit.createBlockData(signType))) {
if (!block.canPlace(this.server.createBlockData(signType))) {
errorLogger.submitWarning("Setting sign" + key + "of region" + getRegion().getName() + "failed, could not set sign block back");
this.remove();
return false;
@@ -278,7 +278,7 @@ public class RegionSign {
for(String command : stateConfig.getStringList(clickType.getValue() + "Console")) {
consoleCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
}
getRegion().runCommands(Bukkit.getConsoleSender(), consoleCommands);
getRegion().runCommands(this.server.getConsoleSender(), consoleCommands);
return !playerCommands.isEmpty() || !consoleCommands.isEmpty();
}
@@ -10,7 +10,6 @@ import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RegionFactory;
@@ -42,7 +41,6 @@ import java.util.Set;
public class SignListener implements Listener {
private final BlockBehaviourHelper behaviourHelper;
private final AreaShop plugin;
private final MessageBridge messageBridge;
private final SignManager signManager;
@@ -53,7 +51,6 @@ public class SignListener implements Listener {
public SignListener(
@Nonnull AreaShop plugin,
@Nonnull BlockBehaviourHelper behaviourHelper,
@Nonnull RegionFactory regionFactory,
@Nonnull MessageBridge messageBridge,
@Nonnull SignLinkerManager signLinkerManager,
@@ -64,7 +61,6 @@ public class SignListener implements Listener {
this.signManager = signManager;
this.signLinkerManager = signLinkerManager;
this.regionFactory = regionFactory;
this.behaviourHelper = behaviourHelper;
this.plugin = plugin;
this.worldGuardInterface = worldGuardInterface;
this.messageBridge = messageBridge;
@@ -96,8 +92,9 @@ public class SignListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onIndirectSignBreak(BlockPhysicsEvent event) {
Block block = event.getBlock();
// Check if the block is a sign
if(!Materials.isSign(event.getBlock().getType()) || behaviourHelper.isBlockValid(event.getBlock())) {
if(!Materials.isSign(block.getType()) || block.canPlace(block.getBlockData())) {
return;
}
@@ -152,24 +149,13 @@ public class SignListener implements Listener {
if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)) {
return;
}
// Only care about clicking blocks
if(!Materials.isSign(block.getType())) {
Optional<RegionSign> optionalRegionSign = getRegionSign(block, event.getPlayer());
if (optionalRegionSign.isEmpty()) {
return;
}
RegionSign regionSign = optionalRegionSign.get();
// Check if this sign belongs to a region
Optional<RegionSign> optional = signManager.signFromLocation(block.getLocation());
if(optional.isEmpty()) {
return;
}
RegionSign regionSign = optional.get();
// Ignore players that are in sign link mode (which will handle the event itself)
Player player = event.getPlayer();
if(signLinkerManager.isInSignLinkMode(player)) {
return;
}
// Get the clicktype
GeneralRegion.ClickType clickType = null;
@@ -189,6 +175,21 @@ public class SignListener implements Listener {
event.setCancelled(ran);
}
private Optional<RegionSign> getRegionSign(@Nonnull Block block, @Nonnull Player player) {
// Only care about clicking blocks
if(!Materials.isSign(block.getType())) {
return Optional.empty();
}
// Ignore players that are in sign link mode (which will handle the event itself)
if(signLinkerManager.isInSignLinkMode(player)) {
return Optional.empty();
}
// Check if this sign belongs to a region
return signManager.signFromLocation(block.getLocation());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onSignChange(SignChangeEvent event) {
Player player = event.getPlayer();
@@ -9,7 +9,6 @@ import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.regions.RegionFactory;
import javax.annotation.Nonnull;
@@ -25,7 +24,6 @@ public class SignsModule extends AbstractModule {
@Provides
@Singleton
public SignListener provideSignListener(@Nonnull AreaShop plugin,
@Nonnull BlockBehaviourHelper behaviourHelper,
@Nonnull RegionFactory regionFactory,
@Nonnull MessageBridge messageBridge,
@Nonnull SignLinkerManager signLinkerManager,
@@ -35,7 +33,6 @@ public class SignsModule extends AbstractModule {
) {
final SignListener signListener = new SignListener(
plugin,
behaviourHelper,
regionFactory,
messageBridge,
signLinkerManager,
@@ -2,10 +2,12 @@ package me.wiefferink.areashop.listeners;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.managers.CacheManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.areashop.tools.CacheWrapper;
import me.wiefferink.bukkitdo.Do;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -27,14 +29,20 @@ public final class PlayerLoginLogoutListener implements Listener {
private final AreaShop plugin;
private final MessageBridge messageBridge;
private final CacheManager cacheManager;
/**
* Constructor.
* @param plugin The AreaShop plugin
*/
public PlayerLoginLogoutListener(@Nonnull AreaShop plugin, @Nonnull MessageBridge messageBridge) {
public PlayerLoginLogoutListener(
@Nonnull AreaShop plugin,
@Nonnull MessageBridge messageBridge,
@Nonnull CacheManager cacheManager
) {
this.plugin = plugin;
this.messageBridge = messageBridge;
this.cacheManager = cacheManager;
}
/**
@@ -48,6 +56,8 @@ public final class PlayerLoginLogoutListener implements Listener {
}
final Player player = event.getPlayer();
this.cacheManager.computeIfAbsent(player.getUniqueId(), uuid -> new CacheWrapper(uuid, player.getName()));
// Schedule task to check for notifications, prevents a lag spike at login
Do.syncTimerLater(25, 25, () -> {
// Delay until all regions are loaded
@@ -0,0 +1,247 @@
package me.wiefferink.areashop.managers;
import jakarta.inject.Inject;
import me.wiefferink.areashop.tools.CacheWrapper;
import org.bukkit.plugin.Plugin;
import javax.annotation.Nonnull;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.logging.Level;
public class CacheManager extends Manager {
private final Plugin plugin;
private final Map<UUID, CacheWrapper> cache;
private File cacheFile;
private Duration expiryDuration;
@Inject
CacheManager(@Nonnull Plugin plugin) {
this.plugin = plugin;
this.cache = new HashMap<>();
}
@Override
public void shutdown() {
if (this.expiryDuration != null) {
trimCache(expiryDuration);
}
if (this.cacheFile != null) {
saveCache(cacheFile);
}
}
public void initialize(@Nonnull File cacheFile, @Nonnull Duration expiryDuration) {
this.cacheFile = cacheFile;
this.expiryDuration = expiryDuration;
}
public void loadCache() {
if (this.cacheFile != null) {
loadCache(this.cacheFile);
}
}
/**
* Load the cache from the file
*/
public void loadCache(@Nonnull File cacheFile) {
if (Files.notExists(cacheFile.toPath())) {
this.plugin.getLogger().info("uuid cache file does not exist, loaded 0 entries");
return;
}
this.cache.clear();
try (FileInputStream input = new FileInputStream(cacheFile)) {
byte[] bytes = input.readAllBytes();
ByteBuffer buffer = ByteBuffer.wrap(bytes).asReadOnlyBuffer();
while (buffer.hasRemaining()) {
long lastUsed = buffer.getLong();
long lsb = buffer.getLong();
long msb = buffer.getLong();
int stringLen = buffer.getInt();
byte[] stringBytes = new byte[stringLen];
buffer.get(stringBytes);
String name = new String(stringBytes, StandardCharsets.UTF_8);
UUID uuid = new UUID(msb, lsb);
CacheWrapper wrapper = new CacheWrapper(uuid, name, lastUsed);
this.cache.put(wrapper.getUuid(), wrapper);
}
this.plugin.getLogger()
.info(String.format("Loaded %d cached uuid name entries", this.cache.size()));
} catch (IOException ex) {
ex.printStackTrace();
this.plugin.getLogger().warning("Failed to load the uuid cache!");
}
}
public void saveCache() {
if (this.cacheFile != null) {
saveCache(this.cacheFile);
}
}
public void saveCacheAsync() {
if (this.cacheFile != null) {
saveCacheAsync(this.cacheFile);
}
}
/**
* Save the cache to the file
*/
public void saveCache(@Nonnull File cacheFile) {
List<CacheWrapper> copy = this.cache.values().stream().map(CacheWrapper::new).toList();
try {
// Ensure parent directory exists
Path parentDir = cacheFile.toPath().getParent();
if (parentDir != null) { // parent might be null if cacheFile is relative with no parent
Files.createDirectories(parentDir);
}
byte[] bytes = serialize(copy);
try (FileOutputStream fos = new FileOutputStream(cacheFile)) {
fos.write(bytes);
}
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Failed to save cache.json", e);
}
}
public void saveCacheAsync(@Nonnull File cacheFile) {
List<CacheWrapper> copy = this.cache.values().stream().map(CacheWrapper::new).toList();
CompletableFuture.runAsync(() -> {
try {
// Ensure parent directory exists
Path parentDir = cacheFile.toPath().getParent();
if (parentDir != null) { // parent might be null if cacheFile is relative with no parent
Files.createDirectories(parentDir);
}
byte[] bytes = serialize(copy);
try (FileOutputStream fos = new FileOutputStream(cacheFile)) {
fos.write(bytes);
}
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Failed to save cache.json", e);
}
});
}
private byte[] serialize(List<CacheWrapper> wrappers) {
ByteArrayOutputStream bos = new ByteArrayOutputStream(256 * wrappers.size());
for (CacheWrapper wrapper : wrappers) {
ByteBuffer buffer = ByteBuffer.allocate(256);
byte[] stringBytes = wrapper.getName().getBytes(StandardCharsets.UTF_8);
int stringLen = stringBytes.length;
long lsb = wrapper.getUuid().getLeastSignificantBits();
long msb = wrapper.getUuid().getMostSignificantBits();
long lastUsed = wrapper.getLastUsed();
buffer.putLong(lastUsed);
buffer.putLong(lsb);
buffer.putLong(msb);
buffer.putInt(stringLen);
buffer.put(stringBytes);
buffer.flip();
bos.write(buffer.array(), buffer.position(), buffer.remaining());
}
return bos.toByteArray();
}
/**
* Get a cache entry
*/
public CacheWrapper get(UUID uuid) {
return cache.get(uuid);
}
public CacheWrapper computeIfAbsent(@Nonnull UUID uuid, Function<UUID, CacheWrapper> function) {
return this.cache.computeIfAbsent(uuid, function);
}
/**
* Put a cache entry
*/
public void put(UUID uuid, CacheWrapper wrapper) {
cache.put(uuid, wrapper);
}
/**
* Remove a cache entry
*/
public CacheWrapper remove(UUID uuid) {
return cache.remove(uuid);
}
/**
* Check if cache contains a UUID
*/
public boolean contains(UUID uuid) {
return cache.containsKey(uuid);
}
/**
* Get all cache entries
*/
public Map<UUID, CacheWrapper> getAllEntries() {
return new HashMap<>(cache);
}
/**
* Clear all cache entries
*/
public void clear() {
cache.clear();
}
/**
* Get the size of the cache
*/
public int size() {
return cache.size();
}
public void trimCache() {
if (this.expiryDuration != null) {
trimCache(this.expiryDuration);
}
}
/**
* Trim the cache by removing entries older than 1 week
*/
public void trimCache(@Nonnull Duration expiryDuration) {
long expiryMillis = expiryDuration.toMillis();
long currentTime = System.currentTimeMillis();
Iterator<Map.Entry<UUID, CacheWrapper>> iterator = cache.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<UUID, CacheWrapper> entry = iterator.next();
CacheWrapper wrapper = entry.getValue();
if (wrapper.getLastUsed() != -1 && (currentTime - wrapper.getLastUsed()) >= expiryMillis) {
iterator.remove();
}
}
}
}
@@ -651,7 +651,7 @@ public class FileManager extends Manager implements IFileManager {
getRegionsRef(),
region -> {
if(region.isSaveRequired()) {
region.saveNow();
region.saveNowAsync();
}
}
);
@@ -1052,8 +1052,8 @@ public class FileManager extends Manager implements IFileManager {
boolean noWorldRegions = !noWorld.isEmpty();
while(!noWorld.isEmpty()) {
List<GeneralRegion> toDisplay = new ArrayList<>();
String missingWorld = noWorld.get(0).getWorldName();
toDisplay.add(noWorld.get(0));
String missingWorld = noWorld.getFirst().getWorldName();
toDisplay.add(noWorld.getFirst());
for(int i = 1; i < noWorld.size(); i++) {
if(noWorld.get(i).getWorldName().equalsIgnoreCase(missingWorld)) {
toDisplay.add(noWorld.get(i));
@@ -379,7 +379,7 @@ public interface IFileManager {
void setGroupSetting(RegionGroup group, String path, Object setting);
// Enum for region types
public enum AddResult {
enum AddResult {
BLACKLISTED("blacklisted"),
NOPERMISSION("nopermission"),
ALREADYADDED("alreadyadded"),
@@ -111,7 +111,7 @@ public class SignLinkerManager extends Manager implements Listener {
Block next = blockIterator.next();
List<GeneralRegion> regions = Utils.getRegions(next.getLocation());
if(regions.size() == 1) {
linker.setRegion(regions.get(0));
linker.setRegion(regions.getFirst());
return;
} else if(regions.size() > 1) {
Set<String> names = new HashSet<>();
@@ -16,7 +16,6 @@ import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.managers.SignErrorLogger;
import me.wiefferink.areashop.managers.SignLinkerManager;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
import me.wiefferink.areashop.regions.ImportJobFactory;
import me.wiefferink.areashop.regions.RegionModule;
import me.wiefferink.areashop.services.ServiceManager;
@@ -32,7 +31,6 @@ public class AreaShopModule extends AbstractModule {
private final AreaShop instance;
private final WorldGuardInterface worldGuardInterface;
private final WorldEditInterface worldEditInterface;
private final PlatformAdapter platformAdapter;
private final MessageBridge messageBridge;
private final SignErrorLogger signErrorLogger;
private final AbstractModule[] extras;
@@ -41,7 +39,6 @@ public class AreaShopModule extends AbstractModule {
public AreaShopModule(@Nonnull AreaShop instance,
@Nonnull MessageBridge messageBridge,
@Nonnull PlatformAdapter platformAdapter,
@Nonnull WorldEditInterface worldEditInterface,
@Nonnull WorldGuardInterface worldGuardInterface,
@Nonnull SignErrorLogger signErrorLogger,
@@ -50,7 +47,6 @@ public class AreaShopModule extends AbstractModule {
) {
this.instance = instance;
this.messageBridge = messageBridge;
this.platformAdapter = platformAdapter;
this.signErrorLogger = signErrorLogger;
this.worldEditInterface = worldEditInterface;
this.worldGuardInterface = worldGuardInterface;
@@ -3,27 +3,20 @@ package me.wiefferink.areashop.modules;
import com.google.inject.AbstractModule;
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
import me.wiefferink.areashop.adapters.platform.OfflinePlayerHelper;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
import org.jetbrains.annotations.NotNull;
public class PlatformModule extends AbstractModule {
private final MinecraftPlatform minecraftPlatform;
private final PlatformAdapter platformAdapter;
public PlatformModule(@NotNull MinecraftPlatform platform,
@NotNull PlatformAdapter platformAdapter) {
public PlatformModule(@NotNull MinecraftPlatform platform) {
this.minecraftPlatform = platform;
this.platformAdapter = platformAdapter;
}
@Override
protected void configure() {
bind(MinecraftPlatform.class).toInstance(this.minecraftPlatform);
bind(OfflinePlayerHelper.class).toInstance(this.minecraftPlatform.offlinePlayerHelper());
bind(PlatformAdapter.class).toInstance(this.platformAdapter);
bind(BlockBehaviourHelper.class).toInstance(this.platformAdapter.blockBehaviourHelper());
bind(BukkitSchedulerExecutor.class).asEagerSingleton();
}
}
@@ -31,7 +31,7 @@ import java.util.UUID;
public class BuyRegion extends GeneralRegion {
private final Economy economy;
@AssistedInject
BuyRegion(
@Nonnull AreaShop plugin,
@@ -147,7 +147,7 @@ public class BuyRegion extends GeneralRegion {
*/
public String getPlayerName() {
String result = Utils.toName(getBuyer());
if(result == null || result.isEmpty()) {
if(result.isEmpty()) {
result = getStringSetting("buy.buyerName");
if(result == null || result.isEmpty()) {
result = "<UNKNOWN>";
@@ -402,7 +402,7 @@ public class BuyRegion extends GeneralRegion {
r = null;
OfflinePlayer oldOwnerPlayer = Bukkit.getOfflinePlayer(oldOwner);
String oldOwnerName = getPlayerName();
if(oldOwnerPlayer != null && oldOwnerPlayer.getName() != null) {
if(oldOwnerPlayer.getName() != null) {
r = economy.depositPlayer(oldOwnerPlayer, getWorldName(), getResellPrice());
oldOwnerName = oldOwnerPlayer.getName();
} else if(oldOwnerName != null) {
@@ -424,7 +424,7 @@ public class BuyRegion extends GeneralRegion {
// Resell is done, disable that now
disableReselling();
// Send message to the player
message(offlinePlayer, "buy-successResale", oldOwnerName);
Player seller = Bukkit.getPlayer(oldOwner);
@@ -542,7 +542,7 @@ public class BuyRegion extends GeneralRegion {
// Give back the money
OfflinePlayer player = Bukkit.getOfflinePlayer(getBuyer());
if(player.hasPlayedBefore() && !noPayBack) {
if((player.hasPlayedBefore() || player.isOnline()) && !noPayBack) {
EconomyResponse response = null;
boolean error = false;
try {
@@ -1,5 +1,6 @@
package me.wiefferink.areashop.regions;
import com.google.common.base.Charsets;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.AreaShop;
@@ -29,11 +30,15 @@ import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.util.Vector;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@@ -472,7 +477,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
if(landlordName != null && !landlordName.isEmpty()) {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(landlordName);
if(offlinePlayer.hasPlayedBefore()) {
if(offlinePlayer.hasPlayedBefore() || offlinePlayer.isOnline()) {
return offlinePlayer.getUniqueId();
}
}
@@ -958,6 +963,27 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
}
}
@Nonnull
public CompletableFuture<Boolean> saveNowAsync() {
if(isDeleted()) {
return CompletableFuture.completedFuture(false);
}
String data = config.saveToString();
saveRequired = false;
File file = new File(plugin.getFileManager().getRegionFolder() + File.separator + getName().toLowerCase() + ".yml");
BukkitScheduler scheduler = this.plugin.getServer().getScheduler();
CompletableFuture<Boolean> future = new CompletableFuture<>();
scheduler.runTaskAsynchronously(this.plugin, () -> {
try(Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);){
writer.write(data);
future.complete(true);
} catch (IOException ex) {
future.complete(false);
}
});
return future;
}
// CONFIG
@@ -1307,7 +1333,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
// Check all limitgroups the player has
List<String> groups = new ArrayList<>(plugin.getConfig().getConfigurationSection("limitGroups").getKeys(false));
while(!groups.isEmpty()) {
String group = groups.get(0);
String group = groups.getFirst();
if(plugin.hasPermission(offlinePlayer, "areashop.limits." + group) && this.matchesLimitGroup(group)) {
String pathPrefix = "limitGroups." + group + ".";
if(!plugin.getConfig().isInt(pathPrefix + "total")) {
@@ -1386,7 +1412,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
/**
* Class to store the result of a limits check.
*/
public class LimitResult {
public static class LimitResult {
private final boolean actionAllowed;
private final LimitType limitingFactor;
private final int maximum;
@@ -1464,12 +1490,12 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
private boolean limitGroupsOfSameCategory(String firstGroup, String secondGroup) {
List<String> firstGroups = plugin.getConfig().getStringList("limitGroups." + firstGroup + ".groups");
List<String> secondGroups = plugin.getConfig().getStringList("limitGroups." + secondGroup + ".groups");
if(!firstGroups.containsAll(secondGroups) || !secondGroups.containsAll(firstGroups)) {
if(!new HashSet<>(firstGroups).containsAll(secondGroups) || !new HashSet<>(secondGroups).containsAll(firstGroups)) {
return false;
}
List<String> firstWorlds = plugin.getConfig().getStringList("limitGroups." + firstGroup + ".worlds");
List<String> secondWorlds = plugin.getConfig().getStringList("limitGroups." + secondGroup + ".worlds");
return !(!firstWorlds.containsAll(secondWorlds) || !secondWorlds.containsAll(firstWorlds));
return !(!new HashSet<>(firstWorlds).containsAll(secondWorlds) || !new HashSet<>(secondWorlds).containsAll(firstWorlds));
}
/**
@@ -1675,8 +1701,8 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
x1 = points.get(numPoints - 1).getBlockX();
z1 = points.get(numPoints - 1).getBlockZ();
x2 = points.get(0).getBlockX();
z2 = points.get(0).getBlockZ();
x2 = points.getFirst().getBlockX();
z2 = points.getFirst().getBlockZ();
area += ((z1 + z2) * (x1 - x2));
area = Math.ceil(Math.abs(area) / 2);
@@ -279,7 +279,7 @@ public class ImportJob {
if(owner != null) {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(owner);
if(offlinePlayer.hasPlayedBefore()) {
if(offlinePlayer.hasPlayedBefore() || offlinePlayer.isOnline()) {
existing.add(offlinePlayer.getUniqueId());
}
}
@@ -296,7 +296,7 @@ public class ImportJob {
// First owner (or if none, the first member) will be the renter/buyer
if(!existing.isEmpty()) {
region.setOwner(existing.remove(0));
region.setOwner(existing.removeFirst());
}
// Add others as friends
for(UUID friend : existing) {
@@ -15,8 +15,7 @@ import java.util.Set;
// TODO consider switching to saving lowercase regions
public class RegionGroup {
private final Plugin plugin;
private final IFileManager fileManager;
private final IFileManager fileManager;
private final String name;
private final Set<String> regions;
private Set<String> autoRegions;
@@ -30,8 +29,7 @@ public class RegionGroup {
*/
@AssistedInject
RegionGroup(@Nonnull Plugin plugin, @Nonnull IFileManager fileManager, @Assisted String name) {
this.plugin = plugin;
this.fileManager = fileManager;
this.fileManager = fileManager;
this.name = name;
this.autoDirty = true;
setSetting("name", name);
@@ -190,6 +190,9 @@ public class RentRegion extends GeneralRegion {
}
}
public void setMaxExtends(int times) {
setSetting("rent.maxExtends", times); }
@Override
public Object provideReplacement(String variable) {
return switch (variable) {
@@ -230,7 +233,7 @@ public class RentRegion extends GeneralRegion {
*/
public String getPlayerName() {
String result = Utils.toName(getRenter());
if(result == null || result.isEmpty()) {
if(result.isEmpty()) {
result = config.getString("rent.renterName");
if(result == null || result.isEmpty()) {
result = "<UNKNOWN>";
@@ -252,11 +255,7 @@ public class RentRegion extends GeneralRegion {
* @param rentedUntil The time until the region is rented
*/
public void setRentedUntil(Long rentedUntil) {
if(rentedUntil == null) {
setSetting("rent.rentedUntil", null);
} else {
setSetting("rent.rentedUntil", rentedUntil);
}
setSetting("rent.rentedUntil", rentedUntil);
}
/**
@@ -420,7 +419,7 @@ public class RentRegion extends GeneralRegion {
// Check if a warning needs to be send for each defined point in time
Player player = Bukkit.getPlayer(getRenter());
long sendUntil = Calendar.getInstance().getTimeInMillis() + (plugin.getConfig().getInt("expireWarning.delay") * 60 * 1000);
long sendUntil = Calendar.getInstance().getTimeInMillis() + (plugin.getConfig().getInt("expireWarning.delay") * 60 * 1000L);
for(String timeBefore : profileSection.getKeys(false)) {
long timeBeforeParsed = Utils.durationStringToLong(timeBefore);
if(timeBeforeParsed <= 0) {
@@ -489,12 +488,9 @@ public class RentRegion extends GeneralRegion {
message(offlinePlayer, "general-noRegion");
return false;
}
boolean extend = false;
if(getRenter() != null && offlinePlayer.getUniqueId().equals(getRenter())) {
extend = true;
}
boolean extend = getRenter() != null && offlinePlayer.getUniqueId().equals(getRenter());
// Check if available or extending
// Check if available or extending
if (isRented() && !extend) {
message(offlinePlayer, "rent-someoneElse");
return false;
@@ -714,7 +710,7 @@ public class RentRegion extends GeneralRegion {
// Give back the money
OfflinePlayer player = Bukkit.getOfflinePlayer(getRenter());
if(player != null && !noPayBack) {
if(!noPayBack) {
r = null;
boolean error = false;
try {
@@ -0,0 +1,67 @@
package me.wiefferink.areashop.tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import java.util.Objects;
import java.util.UUID;
public class CacheWrapper {
private static final Logger log = LoggerFactory.getLogger(CacheWrapper.class);
private final UUID uuid;
private final String name;
private long lastUsed;
public CacheWrapper(CacheWrapper other) {
this.uuid = other.uuid;
this.name = other.name;
this.lastUsed = other.lastUsed;
}
public CacheWrapper(@Nonnull UUID uuid, @Nonnull String name) {
this(uuid, name, -1);
}
public CacheWrapper(@Nonnull UUID uuid, @Nonnull String name, long lastUsed) {
this.uuid = uuid;
this.name = name;
this.lastUsed = lastUsed;
}
public UUID getUuid() {
return this.uuid;
}
public String getName() {
this.lastUsed = System.currentTimeMillis();
return name;
}
public long getLastUsed() {
return lastUsed;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
CacheWrapper that = (CacheWrapper) o;
return lastUsed == that.lastUsed && Objects.equals(uuid,
that.uuid) && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(uuid, name, lastUsed);
}
@Override
public String toString() {
return "CacheWrapper{" +
"uuid=" + uuid +
", name='" + name + '\'' +
", lastUsed=" + lastUsed +
'}';
}
}
@@ -11,6 +11,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
@@ -89,7 +90,7 @@ public class GithubUpdateCheck {
try {
try {
String rawUrl = API_HOST + "/" + author + "/" + repository + "/" + API_LATEST_RELEASE;
url = new URL(rawUrl);
url = URI.create(rawUrl).toURL();
} catch(MalformedURLException e) {
logger.severe("Invalid url: '" + url + "', are the author '" + author + "' and repository '" + repository + "' correct?");
error = true;
@@ -79,7 +79,7 @@ public class LanguageConverter {
}
List<String> converted = convertRawList(messages);
if (converted.size() == 1) {
node.set(String.class, converted.get(0));
node.set(String.class, converted.getFirst());
} else {
node.setList(String.class, converted);
}
@@ -3,7 +3,7 @@ package me.wiefferink.areashop.tools;
/**
* Parse math from a string
* Adapted from:
* https://stackoverflow.com/questions/3422673/how-to-evaluate-a-math-expression-given-in-string-form
* <a href="https://stackoverflow.com/questions/3422673/how-to-evaluate-a-math-expression-given-in-string-form">...</a>
*/
public final class OperandParser {
@@ -38,7 +38,7 @@ public class SimpleMessageBridge implements MessageBridge {
}
if (message.get() == null || message.get().isEmpty() || (message.get().size() == 1 && message.get()
.get(0)
.getFirst()
.isEmpty())) {
return;
}
@@ -21,7 +21,7 @@ public class SpigotOfflinePlayerHelper implements OfflinePlayerHelper {
@Override
public CompletableFuture<Optional<UUID>> lookupUuidAsync(String username) {
return lookupOfflinePlayerAsync(username).thenApply(player -> {
if (player.hasPlayedBefore()) {
if (player.hasPlayedBefore() || player.isOnline()) {
return Optional.of(player.getUniqueId());
}
return Optional.empty();
@@ -31,6 +31,11 @@ public class SpigotOfflinePlayerHelper implements OfflinePlayerHelper {
@Override
public CompletableFuture<OfflinePlayer> lookupOfflinePlayerAsync(String username) {
final CompletableFuture<OfflinePlayer> future = new CompletableFuture<>();
OfflinePlayer onlinePlayer = this.plugin.getServer().getPlayerExact(username);
if (onlinePlayer != null) {
future.complete(onlinePlayer);
return future;
}
final Server server = this.plugin.getServer();
server.getScheduler().runTaskAsynchronously(this.plugin, () -> {
@SuppressWarnings("deprecation")
@@ -6,6 +6,7 @@ import jakarta.inject.Inject;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import me.wiefferink.areashop.managers.CacheManager;
import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
@@ -396,10 +397,10 @@ public class Utils {
result.add(pr);
first = false;
} else {
if(pr.getPriority() > result.get(0).getPriority()) {
if(pr.getPriority() > result.getFirst().getPriority()) {
result.clear();
result.add(pr);
} else if(pr.getParent() != null && pr.getParent().equals(result.get(0))) {
} else if(pr.getParent() != null && pr.getParent().equals(result.getFirst())) {
result.clear();
result.add(pr);
} else {
@@ -480,10 +481,10 @@ public class Utils {
result.add(region);
first = false;
} else {
if(region.getRegion().getPriority() > result.get(0).getRegion().getPriority()) {
if(region.getRegion().getPriority() > result.getFirst().getRegion().getPriority()) {
result.clear();
result.add(region);
} else if(region.getRegion().getParent() != null && region.getRegion().getParent().equals(result.get(0).getRegion())) {
} else if(region.getRegion().getParent() != null && region.getRegion().getParent().equals(result.getFirst().getRegion())) {
result.clear();
result.add(region);
} else {
@@ -523,7 +524,7 @@ public class Utils {
String result;
// Check for infinite and NaN
if(Double.isInfinite(amount)) {
result = "\u221E"; // Infinite symbol
result = "∞"; // Infinite symbol
} else if(Double.isNaN(amount)) {
result = "NaN";
} else {
@@ -802,16 +803,25 @@ public class Utils {
* @return the name of the player
*/
public static String toName(UUID uuid) {
if(uuid == null) {
return "";
} else {
String name = Bukkit.getOfflinePlayer(uuid).getName();
if(name != null) {
return name;
}
return "";
}
}
if (uuid == null) {
return "";
}
final CacheManager cacheManager = plugin.getCacheManager();
if (cacheManager.contains(uuid))
return cacheManager.get(uuid).getName();
final String name = Bukkit.getOfflinePlayer(uuid).getName();
if (name != null) {
cacheManager.put(uuid, new CacheWrapper(uuid, name, System.currentTimeMillis()));
return name;
}
return "";
}
/**
* Conversion from name to uuid.
@@ -7,7 +7,7 @@ public record Version(String original, VersionData versionData) {
/**
* Semver pattern, cg1 = major, cg2 = minor, cg3 = patch, cg4 = prerelease and cg5 = buildmetadata
* Taken from https://semver.org/ and https://regex101.com/r/vkijKf/1/
* Taken from <a href="https://semver.<a href="org/">...</a>">and https://regex1</a>01.com/r/vkijKf/1/
*/
public static final Pattern SEMVER_PATTERN = Pattern.compile(
"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
@@ -1,10 +1,29 @@
package me.wiefferink.areashop.tools.version;
import javax.annotation.Nonnull;
import java.util.StringJoiner;
public class VersionUtil {
public static VersionData MC_1_18_2 = new VersionData(1, 18, 2);
public static final VersionData MC_1_21 = new VersionData(1, 21);
public static Version parseMinecraftVersion(String minecraftVersion) {
@Nonnull
public static String padTrailingZero(@Nonnull String minecraftVersion) {
int dotCount = 0;
for (char c : minecraftVersion.toCharArray()) {
if (c == '.') {
dotCount += 1;
}
}
StringJoiner joiner = new StringJoiner("");
for (int i = 0; i < 2 - dotCount; i++) {
joiner.add(".0");
}
return minecraftVersion + joiner;
}
@Nonnull
public static Version parseMinecraftVersion(@Nonnull String minecraftVersion) {
// Expecting 1.X.X-R0.1-SNAPSHOT
int stripLength = "-R0.1-SNAPSHOT".length();
int length = minecraftVersion.length();
@@ -13,7 +32,7 @@ public class VersionUtil {
}
String strippedVersion = minecraftVersion.substring(0, length - stripLength);
try {
return Version.parse(strippedVersion);
return Version.parse(padTrailingZero(strippedVersion));
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Invalid minecraft version: " + minecraftVersion, ex);
}
+1
View File
@@ -150,6 +150,7 @@ forceClearEntities: false
# Maximum number of locations the teleport function should check to find a safe spot.
maximumTries: 50000
cacheExpiryDuration: '7d'
# ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
# │ VARIABLES: Variables that can be used in messages and settings where a region is available. │
@@ -374,6 +374,11 @@ setduration-noLandlord: You don't have permission to change the duration because
setduration-successRemoved: 'Duration of %lang:region% has been removed, it will now
use the duration from a group or the default.yml file, new duration: %duration%.'
setmaxextends-noPermission: You don't have permission to change the amount of times a region can have rent extended.
setmaxextends-help: /as setmaxextends \<amount> [region], the region you stand in will be used if not specified.
setmaxextends-noLandlord: You don't have permission to change the duration because you are not the landlord of %lang:region%.
setmaxextends-success: Max extensions of %lang:region% changed to %maxextends%
setup-noRegion: You did not specify a region on the second line.
setup-alreadyRentSign: The region you specified is already added to AreaShop as a
rent region, add signs with [as] on the first line or '/as addsign'.
+6
View File
@@ -81,6 +81,7 @@ help-reload: "%lang:helpCommand|/as reload|% Reload all files and update the reg
help-setrestore: "%lang:helpCommand|/as setrestore|% Set restoring on/off and choose profile."
help-setprice: "%lang:helpCommand|/as setprice|% Change the price of a region."
help-setduration: "%lang:helpCommand|/as setduration|% Change the duration of a rent region."
help-setmaxextends: "%lang:helpCommand|/as setmaxextends|% Change the amount of times a renter can extend their rent by."
help-settransfer: "%lang:helpCommand|/as settransfer|% Set transfer on/off."
help-teleport: "%lang:helpCommand|/as tp|% Teleport to a rent/buy region."
help-setteleport: "%lang:helpCommand|/as settp|% Set teleport position for a region."
@@ -350,6 +351,11 @@ setduration-success: "Duration of region %lang:region% changed to '%duration%'."
setduration-noLandlord: "You don't have permission to change the duration because you are not the landlord of %lang:region%."
setduration-successRemoved: "Duration of %lang:region% has been removed, it will now use the duration from a group or the default.yml file, new duration: %duration%."
setmaxextends-noPermission: "You don't have permission to change the amount of times a region can have rent extended."
setmaxextends-help: "/as setmaxextends <amount> [region], the region you stand in will be used if not specified."
setmaxextends-noLandlord: "You don't have permission to change the duration because you are not the landlord of %lang:region%."
setmaxextends-success: "Max extensions of %lang:region% changed to %maxextends%"
setup-noRegion: "You did not specify a region on the second line."
setup-alreadyRentSign: "The region you specified is already added to AreaShop as a rent region, add signs with [as] on the first line or '/as addsign'."
setup-alreadyOtherWorld: "The region you specified is already added to AreaShop in another world, regions from different worlds still need different names."
+6 -1
View File
@@ -1,3 +1,8 @@
<h1>
The project is no longer maintained. See this alternative <a href="https://github.com/MCCitiesNetwork/realty">realty</a>
</h1>
<br>
![AreaShop logo](https://cloud.githubusercontent.com/assets/6951068/9471294/f016d8ee-4b4f-11e5-9bda-d61b1c423ebb.png)<br/>
[![](https://jitpack.io/v/md5sha256/AreaShop.svg)](https://jitpack.io/#md5sha256/AreaShop)
<br>
@@ -74,4 +79,4 @@ For a preview join 'mc.go-craft.com' and go to the Survival server, the shops ar
**Made by [PerkulatorTime](https://www.youtube.com/user/PerkulatorTime)**<br/>
[![Tutorial Video](https://cloud.githubusercontent.com/assets/6951068/9532788/147526cc-4d0e-11e5-9672-1274faae280a.png)](https://www.youtube.com/watch?v=OQOsOG-EdNc)
Old video for AreaShop v1.0: [Tutorial by VariationVault](https://www.youtube.com/watch?v=k2HMCxCCOYo)
Old video for AreaShop v1.0: [Tutorial by VariationVault](https://www.youtube.com/watch?v=k2HMCxCCOYo)
@@ -1,11 +0,0 @@
dependencies {
compileOnly("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
compileOnly(projects.areashopInterface)
compileOnly(projects.areashopNms)
}
description = "AreaShop NMS Helper 1-18"
tasks {
}
@@ -1,28 +0,0 @@
package me.wiefferink.areashop.adapters.platform.modern;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import java.util.Objects;
public class BlockBehaviourImpl implements BlockBehaviourHelper {
@Override
public boolean canPlace(Location location, BlockData blockData) {
Objects.requireNonNull(location.getWorld(), "Null World!");
return location.getBlock().canPlace(blockData);
}
@Override
public boolean isBlockValid(Block block) {
return block.canPlace(block.getBlockData());
}
@Override
public boolean isBlockStateValid(BlockState blockState) {
return blockState.getBlock().canPlace(blockState.getBlockData());
}
}
@@ -1,15 +0,0 @@
package me.wiefferink.areashop.adapters.platform.modern;
import me.wiefferink.areashop.platform.adapter.BlockBehaviourHelper;
import me.wiefferink.areashop.platform.adapter.PlatformAdapter;
public class ModernPlatformAdapter implements PlatformAdapter {
private final BlockBehaviourImpl blockBehaviourHelper = new BlockBehaviourImpl();
@Override
public BlockBehaviourHelper blockBehaviourHelper() {
return this.blockBehaviourHelper;
}
}
@@ -23,19 +23,22 @@ public class PaperOfflinePlayerHelper implements OfflinePlayerHelper {
@Override
public CompletableFuture<Optional<UUID>> lookupUuidAsync(String username) {
final PlayerProfile profile = this.server.createProfile(username);
final CompletableFuture<Optional<UUID>> future = new CompletableFuture<>();
this.server.getScheduler().runTaskAsynchronously(this.plugin, () -> {
profile.complete(false);
future.complete(Optional.ofNullable(profile.getId()));
});
return future;
return profile.update().thenApply(PlayerProfile::getId).thenApply(Optional::ofNullable);
}
@Override
public CompletableFuture<OfflinePlayer> lookupOfflinePlayerAsync(String username) {
final CompletableFuture<OfflinePlayer> future = new CompletableFuture<>();
OfflinePlayer onlinePlayer = this.server.getPlayerExact(username);
if (onlinePlayer != null) {
future.complete(onlinePlayer);
return future;
}
OfflinePlayer cachedPlayer = this.server.getOfflinePlayerIfCached(username);
if (cachedPlayer != null) {
return CompletableFuture.completedFuture(cachedPlayer);
}
this.server.getScheduler().runTaskAsynchronously(this.plugin, () -> {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = plugin.getServer().getOfflinePlayer(username);
future.complete(offlinePlayer);
});
@@ -1,7 +1,6 @@
package me.wiefferink.areashop.adapters.plugins.essentials;
import me.wiefferink.areashop.features.homeaccess.AccessControlValidator;
import org.checkerframework.checker.nullness.qual.NonNull;
import javax.annotation.Nonnull;
@@ -23,7 +23,6 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.checkerframework.checker.nullness.qual.NonNull;
import javax.annotation.Nonnull;
import java.util.Optional;
Loaded 100 of 118 files, more files were not shown because too many files have changed in this diff. Show more