This commit is contained in:
Alexander Söderberg 2024-04-14 08:37:19 +00:00 committed by GitHub
commit a78287370d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1689 additions and 7 deletions

View File

@ -53,6 +53,9 @@ dependencies {
// Adventure // Adventure
implementation(libs.adventureBukkit) implementation(libs.adventureBukkit)
// Cloud
implementation(libs.cloudPaper)
} }
tasks.processResources { tasks.processResources {
@ -77,6 +80,7 @@ tasks.named<ShadowJar>("shadowJar") {
relocate("com.google.inject", "com.plotsquared.google") relocate("com.google.inject", "com.plotsquared.google")
relocate("org.aopalliance", "com.plotsquared.core.aopalliance") relocate("org.aopalliance", "com.plotsquared.core.aopalliance")
relocate("cloud.commandframework.services", "com.plotsquared.core.services") relocate("cloud.commandframework.services", "com.plotsquared.core.services")
relocate("cloud.commandframework", "com.plotsquared.commands")
relocate("io.leangen.geantyref", "com.plotsquared.core.geantyref") relocate("io.leangen.geantyref", "com.plotsquared.core.geantyref")
relocate("com.intellectualsites.arkitektonika", "com.plotsquared.core.arkitektonika") relocate("com.intellectualsites.arkitektonika", "com.plotsquared.core.arkitektonika")
relocate("com.intellectualsites.http", "com.plotsquared.core.http") relocate("com.intellectualsites.http", "com.plotsquared.core.http")

View File

@ -28,6 +28,7 @@ import com.google.inject.TypeLiteral;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator; import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.plotsquared.bukkit.inject.BackupModule; import com.plotsquared.bukkit.inject.BackupModule;
import com.plotsquared.bukkit.inject.BukkitModule; import com.plotsquared.bukkit.inject.BukkitModule;
import com.plotsquared.bukkit.inject.CloudModule;
import com.plotsquared.bukkit.inject.PermissionModule; import com.plotsquared.bukkit.inject.PermissionModule;
import com.plotsquared.bukkit.inject.WorldManagerModule; import com.plotsquared.bukkit.inject.WorldManagerModule;
import com.plotsquared.bukkit.listener.BlockEventListener; import com.plotsquared.bukkit.listener.BlockEventListener;
@ -64,6 +65,7 @@ import com.plotsquared.bukkit.uuid.SquirrelIdUUIDService;
import com.plotsquared.core.PlotPlatform; import com.plotsquared.core.PlotPlatform;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.backup.BackupManager; import com.plotsquared.core.backup.BackupManager;
import com.plotsquared.core.commands.PlotSquaredCommandManager;
import com.plotsquared.core.components.ComponentPresetManager; import com.plotsquared.core.components.ComponentPresetManager;
import com.plotsquared.core.configuration.ConfigurationNode; import com.plotsquared.core.configuration.ConfigurationNode;
import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationSection;
@ -83,6 +85,7 @@ import com.plotsquared.core.inject.annotations.DefaultGenerator;
import com.plotsquared.core.inject.annotations.ImpromptuPipeline; import com.plotsquared.core.inject.annotations.ImpromptuPipeline;
import com.plotsquared.core.inject.annotations.WorldConfig; import com.plotsquared.core.inject.annotations.WorldConfig;
import com.plotsquared.core.inject.annotations.WorldFile; import com.plotsquared.core.inject.annotations.WorldFile;
import com.plotsquared.core.inject.modules.CommandModule;
import com.plotsquared.core.inject.modules.PlotSquaredModule; import com.plotsquared.core.inject.modules.PlotSquaredModule;
import com.plotsquared.core.listener.PlotListener; import com.plotsquared.core.listener.PlotListener;
import com.plotsquared.core.listener.WESubscriber; import com.plotsquared.core.listener.WESubscriber;
@ -293,6 +296,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
new PermissionModule(), new PermissionModule(),
new WorldManagerModule(), new WorldManagerModule(),
new PlotSquaredModule(), new PlotSquaredModule(),
new CommandModule(),
new CloudModule(this),
new BukkitModule(this), new BukkitModule(this),
new BackupModule() new BackupModule()
); );
@ -388,6 +393,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
// Commands // Commands
if (Settings.Enabled_Components.COMMANDS) { if (Settings.Enabled_Components.COMMANDS) {
this.registerCommands(); this.registerCommands();
// Register the commands.
this.injector().getInstance(PlotSquaredCommandManager.class).registerDefaultCommands();
} }
// Permissions // Permissions

View File

@ -0,0 +1,50 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.commands;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.SenderMapper;
/**
* Mapper between {@link CommandSender} and {@link PlotPlayer}.
*/
public final class BukkitSenderMapper implements SenderMapper<CommandSender, PlotPlayer<?>> {
@Override
public @NonNull PlotPlayer<?> map(final @NonNull CommandSender base) {
if (base instanceof Player player) {
return BukkitUtil.adapt(player);
}
return ConsolePlayer.getConsole();
}
@Override
public @NonNull CommandSender reverse(final @NonNull PlotPlayer<?> mapped) {
if (mapped instanceof ConsolePlayer) {
return Bukkit.getConsoleSender();
}
return (Player) mapped.getPlatformPlayer();
}
}

View File

@ -0,0 +1,99 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.inject;
import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.commands.BukkitSenderMapper;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.commands.CommandRequirement;
import com.plotsquared.core.commands.PlotSquaredCaptionProvider;
import com.plotsquared.core.commands.PlotSquaredRequirementFailureHandler;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.bukkit.CloudBukkitCapabilities;
import org.incendo.cloud.execution.ExecutionCoordinator;
import org.incendo.cloud.minecraft.extras.MinecraftExceptionHandler;
import org.incendo.cloud.paper.PaperCommandManager;
import org.incendo.cloud.processors.requirements.RequirementPostprocessor;
public class CloudModule extends AbstractModule {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + CloudModule.class.getSimpleName());
private static @NonNull CommandSender convert(final @NonNull PlotPlayer<?> player) {
if (player instanceof ConsolePlayer) {
return Bukkit.getConsoleSender();
}
return (Player) player.getPlatformPlayer();
}
private static @NonNull PlotPlayer<?> convert (final @NonNull CommandSender sender) {
if (sender instanceof Player player) {
return BukkitUtil.adapt(player);
}
return ConsolePlayer.getConsole();
}
private final BukkitPlatform bukkitPlatform;
public CloudModule(final @NonNull BukkitPlatform bukkitPlatform) {
this.bukkitPlatform = bukkitPlatform;
}
@Override
protected void configure() {
final PaperCommandManager<PlotPlayer<?>> commandManager = new PaperCommandManager<PlotPlayer<?>>(
this.bukkitPlatform,
ExecutionCoordinator.asyncCoordinator(),
new BukkitSenderMapper()
);
commandManager.captionRegistry().registerProvider(new PlotSquaredCaptionProvider());
if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) {
commandManager.registerBrigadier();
} else if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) {
commandManager.registerAsynchronousCompletions();
}
final RequirementPostprocessor<PlotPlayer<?>, CommandRequirement> requirementPostprocessor =
RequirementPostprocessor.of(CommandRequirement.REQUIREMENTS_KEY, new PlotSquaredRequirementFailureHandler());
commandManager.registerCommandPostProcessor(requirementPostprocessor);
// TODO(City): Override parsing errors using MM parsing.
MinecraftExceptionHandler.<PlotPlayer<?>>create(PlotPlayer::getAudience)
.defaultHandlers()
.decorator((ctx, component) -> TranslatableCaption.of("core.prefix").
toComponent(ctx.context().sender())
.append(component))
.registerTo(commandManager);
bind(Key.get(new TypeLiteral<CommandManager<PlotPlayer<?>>>() {})).toInstance(commandManager);
}
}

View File

@ -15,6 +15,11 @@ dependencies {
api(libs.adventureApi) api(libs.adventureApi)
api(libs.adventureMiniMessage) api(libs.adventureMiniMessage)
// Cloud
api(libs.cloud)
api(libs.cloudMinecraftExtras)
api(libs.cloudRequirements)
// Guice // Guice
api(libs.guice) { api(libs.guice) {
exclude(group = "com.google.guava") exclude(group = "com.google.guava")

View File

@ -18,7 +18,6 @@
*/ */
package com.plotsquared.core; package com.plotsquared.core;
import cloud.commandframework.services.ServicePipeline;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Key; import com.google.inject.Key;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
@ -47,6 +46,7 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.incendo.cloud.services.ServicePipeline;
import java.io.File; import java.io.File;

View File

@ -18,7 +18,6 @@
*/ */
package com.plotsquared.core.command; package com.plotsquared.core.command;
import cloud.commandframework.services.ServicePipeline;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
@ -49,6 +48,7 @@ import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.incendo.cloud.services.ServicePipeline;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
@ -332,7 +332,7 @@ public class Auto extends SubCommand {
List<Plot> plots = this.servicePipeline List<Plot> plots = this.servicePipeline
.pump(new AutoQuery(player, null, sizeX, sizeZ, plotarea)) .pump(new AutoQuery(player, null, sizeX, sizeZ, plotarea))
.through(AutoService.class) .through(AutoService.class)
.getResult(); .complete();
plots = this.eventDispatcher.callAutoPlotsChosen(player, plots).getPlots(); plots = this.eventDispatcher.callAutoPlotsChosen(player, plots).getPlots();

View File

@ -0,0 +1,98 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.processors.requirements.Requirement;
import org.incendo.cloud.processors.requirements.Requirements;
import java.util.List;
/**
* Something that is required for a command to be executed.
*/
public interface CommandRequirement extends Requirement<PlotPlayer<?>, CommandRequirement> {
/**
* The key used to store the requirements in the {@link org.incendo.cloud.meta.CommandMeta}.
*/
CloudKey<Requirements<PlotPlayer<?>, CommandRequirement>> REQUIREMENTS_KEY = CloudKey.of(
"requirements",
new TypeToken<Requirements<PlotPlayer<?>, CommandRequirement>>() {
}
);
/**
* Returns the caption sent when the requirement is not met.
*
* @return the caption
*/
@NonNull TranslatableCaption failureCaption();
/**
* Returns the placeholder values.
*
* @return placeholder values
*/
default @NonNull TagResolver @NonNull[] tagResolvers() {
return new TagResolver[0];
}
/**
* Returns a requirement that evaluates to {@code true} if the sender has the given {@code permission} or if
* this requirement evaluates to {@code true}.
*
* @param permission the override permission
* @return the new requirement
*/
default @NonNull CommandRequirement withPermissionOverride(final @NonNull Permission permission) {
final CommandRequirement thisRequirement = this;
return new CommandRequirement() {
@Override
public @NonNull TranslatableCaption failureCaption() {
return TranslatableCaption.of("permission.no_permission");
}
@Override
public @NonNull TagResolver @NonNull [] tagResolvers() {
return new TagResolver[] {
TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_SET_FLAG_OTHER))
};
}
@Override
public @NonNull List<@NonNull CommandRequirement> parents() {
return thisRequirement.parents();
}
@Override
public boolean evaluateRequirement(final @NonNull CommandContext<PlotPlayer<?>> context) {
return context.sender().hasPermission(permission) || thisRequirement.evaluateRequirement(context);
}
};
}
}

View File

@ -0,0 +1,81 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.context.CommandContext;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* Common {@link CommandRequirement command requirements}.
*/
public enum CommonCommandRequirement implements CommandRequirement {
/**
* Requires that the command sender is currently in a plot.
*/
REQUIRES_PLOT(TranslatableCaption.of("errors.not_in_plot"), ctx -> ctx.sender().getCurrentPlot() != null),
/**
* Requires that the command sender is in a claimed plot.
*/
REQUIRES_OWNER(TranslatableCaption.of("working.plot_not_claimed"),
ctx -> ctx.sender().getCurrentPlot().hasOwner(),
REQUIRES_PLOT
),
/**
* Requires that the command sender is the plot owner.
*/
IS_OWNER(TranslatableCaption.of("permission.no_plot_perms"),
ctx -> ctx.sender().getCurrentPlot().isOwner(ctx.sender().getUUID()),
REQUIRES_OWNER
)
;
private final TranslatableCaption failureCaption;
private final Predicate<CommandContext<PlotPlayer<?>>> predicate;
private final List<@NonNull CommandRequirement> parents;
CommonCommandRequirement(
final @NonNull TranslatableCaption failureCaption,
final @NonNull Predicate<CommandContext<PlotPlayer<?>>> predicate,
final @NonNull CommandRequirement @NonNull... parents
) {
this.failureCaption = failureCaption;
this.predicate = predicate;
this.parents = Arrays.asList(parents);
}
public @NonNull TranslatableCaption failureCaption() {
return this.failureCaption;
}
@Override
public @NonNull List<@NonNull CommandRequirement> parents() {
return this.parents;
}
@Override
public boolean evaluateRequirement(final @NonNull CommandContext<PlotPlayer<?>> context) {
return this.predicate.test(context);
}
}

View File

@ -0,0 +1,50 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.caption.CaptionMap;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.incendo.cloud.caption.Caption;
import org.incendo.cloud.caption.CaptionProvider;
/**
* {@link CaptionProvider} that retrieves caption values from the {@link CaptionMap caption map}.
*/
public final class PlotSquaredCaptionProvider implements CaptionProvider<PlotPlayer<?>> {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlotSquaredCaptionProvider.class.getSimpleName());
@Override
public @Nullable String provide(final @NonNull Caption caption, final @NonNull PlotPlayer<?> recipient) {
try {
return PlotSquared.get()
.getCaptionMap(TranslatableCaption.DEFAULT_NAMESPACE)
.getMessage(TranslatableCaption.of(caption.key()), recipient);
} catch (final CaptionMap.NoSuchCaptionException ignored) {
LOGGER.warn("Missing caption '{}', will attempt to fall back on Cloud defaults", caption.key());
return null;
}
}
}

View File

@ -0,0 +1,78 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.plotsquared.core.command.CommandCategory;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.bean.CommandBean;
import org.incendo.cloud.bean.CommandProperties;
import org.incendo.cloud.processors.requirements.RequirementApplicable;
import org.incendo.cloud.processors.requirements.Requirements;
import java.util.List;
public abstract class PlotSquaredCommandBean extends CommandBean<PlotPlayer<?>> {
private final RequirementApplicable.RequirementApplicableFactory<PlotPlayer<?>, CommandRequirement>
requirementApplicableFactory = RequirementApplicable.factory(CommandRequirement.REQUIREMENTS_KEY);
/**
* Returns the category of the command.
*
* @return the category
*/
public abstract @NonNull CommandCategory category();
/**
* Returns the requirements for the command to be executable.
*
* @return the requirements
*/
public abstract @NonNull List<@NonNull CommandRequirement> requirements();
/**
* Prepares the given {@code builder}.
*
* <p>This should be implemented by abstract classes that extend {@link PlotSquaredCommandBean} to offer shared behavior
* for a subset of plot commands.</p>
*
* @param builder the builder
* @return the prepared builder
*/
protected Command.@NonNull Builder<PlotPlayer<?>> prepare(final Command.@NonNull Builder<PlotPlayer<?>> builder) {
return builder;
}
@Override
protected final @NonNull CommandProperties properties() {
return CommandProperties.of("platsquared", "plat");
}
@Override
protected final Command.@NonNull Builder<PlotPlayer<?>> configure(final Command.@NonNull Builder<PlotPlayer<?>> builder) {
return this.configurePlotCommand(this.prepare(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, this.category())))
.apply(this.requirementApplicableFactory.create(Requirements.of(this.requirements())));
}
protected abstract Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(
Command.@NonNull Builder<PlotPlayer<?>> builder
);
}

View File

@ -0,0 +1,74 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.plotsquared.core.commands.injection.PlotInjector;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.injection.GuiceInjectionService;
import java.util.Set;
@Singleton
public final class PlotSquaredCommandManager {
private final CommandManager<PlotPlayer<?>> commandManager;
private final Injector injector;
@Inject
public PlotSquaredCommandManager(
final @NonNull CommandManager<PlotPlayer<?>> commandManager,
final @NonNull Injector injector
) {
this.commandManager = commandManager;
this.injector = injector;
this.registerInjectors();
}
/**
* Registers the commands that are shipped with PlotSquared.
*/
public void registerDefaultCommands() {
final Set<PlotSquaredCommandBean> commands =
this.injector.getInstance(Key.get(new TypeLiteral<Set<PlotSquaredCommandBean>>() {}));
commands.forEach(command -> this.commandManager().command(command));
}
/**
* Returns the command manager.
*
* @return the command manager
*/
public @NonNull CommandManager<PlotPlayer<?>> commandManager() {
return this.commandManager;
}
private void registerInjectors() {
this.commandManager.parameterInjectorRegistry().registerInjector(Plot.class,
this.injector.getInstance(PlotInjector.class));
this.commandManager.parameterInjectorRegistry().registerInjectionService(GuiceInjectionService.create(this.injector));
}
}

View File

@ -0,0 +1,36 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.plotsquared.core.command.CommandCategory;
import org.incendo.cloud.key.CloudKey;
/**
* Shared {@link org.incendo.cloud.meta.CommandMeta command meta} keys.
*/
public final class PlotSquaredCommandMeta {
/**
* Key that determines what {@link CommandCategory category} a command belongs to.
*/
public static final CloudKey<CommandCategory> META_CATEGORY = CloudKey.of("category", CommandCategory.class);
private PlotSquaredCommandMeta() {
}
}

View File

@ -0,0 +1,35 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.processors.requirements.RequirementFailureHandler;
public final class PlotSquaredRequirementFailureHandler implements RequirementFailureHandler<PlotPlayer<?>, CommandRequirement> {
@Override
public void handleFailure(
final @NonNull CommandContext<PlotPlayer<?>> context,
final @NonNull CommandRequirement requirement
) {
context.sender().sendMessage(requirement.failureCaption(), requirement.tagResolvers());
}
}

View File

@ -0,0 +1,120 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.command.setting.flag;
import com.google.inject.Inject;
import com.plotsquared.core.commands.parser.PlotFlagParser;
import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider;
import com.plotsquared.core.configuration.caption.CaptionUtility;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.flag.FlagParseException;
import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.util.EventDispatcher;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser;
import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser;
public final class FlagAddCommand extends FlagCommandBean {
private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {});
private static final CloudKey<String> COMPONENT_VALUE = CloudKey.of("value", String.class);
private final EventDispatcher eventDispatcher;
@Inject
public FlagAddCommand(final @NonNull EventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
}
@Override
protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(
final Command.@NonNull Builder<PlotPlayer<?>> builder
) {
return builder.literal("add")
.required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL))
.required(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG));
}
@Override
public void execute(final @NonNull CommandContext<PlotPlayer<?>> commandContext) {
final PlotPlayer<?> player = commandContext.sender();
final Plot plot = commandContext.inject(Plot.class).orElseThrow();
final PlotFlag<?, ?> flag = commandContext.get(COMPONENT_FLAG);
final String flagValue = commandContext.get(COMPONENT_VALUE);
final PlotFlagAddEvent event = this.eventDispatcher.callFlagAdd(flag, plot);
if (event.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Flag set")))
);
return;
}
if (event.getEventResult() != Result.FORCE) {
final String[] split = flagValue.split(",");
for (final String entry : split) {
if (!checkPermValue(player, flag, flag.getName(), entry)) {
return;
}
}
}
final String sanitizedValue = CaptionUtility.stripClickEvents(flag, flagValue);
final PlotFlag<?, ?> parsedFlag;
try {
parsedFlag = flag.parse(flagValue);
} catch (final FlagParseException e) {
player.sendMessage(
TranslatableCaption.of("flag.flag_parse_error"),
TagResolver.builder()
.tag("flag_name", Tag.inserting(Component.text(flag.getName())))
.tag("flag_value", Tag.inserting(Component.text(e.getValue())))
.tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
.build()
);
return;
}
final boolean result = plot.setFlag(plot.getFlagContainer().getFlag(flag.getClass()).merge(parsedFlag.getValue()));
if (!result) {
player.sendMessage(TranslatableCaption.of("flag.flag_not_added"));
return;
}
player.sendMessage(
TranslatableCaption.of("flag.flag_added"),
TagResolver.builder()
.tag("flag", Tag.inserting(Component.text(flag.getName())))
.tag("value", Tag.inserting(Component.text(parsedFlag.toString())))
.build()
);
}
}

View File

@ -0,0 +1,139 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.command.setting.flag;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.CommandCategory;
import com.plotsquared.core.commands.CommandRequirement;
import com.plotsquared.core.commands.CommonCommandRequirement;
import com.plotsquared.core.commands.PlotSquaredCommandBean;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.flag.FlagParseException;
import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.plot.flag.types.IntegerFlag;
import com.plotsquared.core.plot.flag.types.ListFlag;
import com.plotsquared.core.util.MathMan;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import java.util.List;
public abstract class FlagCommandBean extends PlotSquaredCommandBean {
protected static boolean checkPermValue(
final @NonNull PlotPlayer<?> player,
final @NonNull PlotFlag<?, ?> flag, @NonNull String key, @NonNull String value
) {
key = key.toLowerCase();
value = value.toLowerCase();
String perm = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format(key.toLowerCase(), value.toLowerCase());
if (flag instanceof IntegerFlag && MathMan.isInteger(value)) {
try {
int numeric = Integer.parseInt(value);
// Getting full permission without ".<amount>" at the end
perm = perm.substring(0, perm.length() - value.length() - 1);
boolean result = false;
if (numeric >= 0) {
int checkRange = PlotSquared.get().getPlatform().equalsIgnoreCase("bukkit") ?
numeric :
Settings.Limit.MAX_PLOTS;
result = player.hasPermissionRange(perm, checkRange) >= numeric;
}
if (!result) {
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver(
"node",
Tag.inserting(Component.text(perm + "." + numeric))
)
);
}
return result;
} catch (NumberFormatException ignore) {
}
} else if (flag instanceof final ListFlag<?, ?> listFlag) {
try {
PlotFlag<? extends List<?>, ?> parsedFlag = listFlag.parse(value);
for (final Object entry : parsedFlag.getValue()) {
final String permission = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format(
key.toLowerCase(),
entry.toString().toLowerCase()
);
final boolean result = player.hasPermission(permission);
if (!result) {
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver("node", Tag.inserting(Component.text(permission)))
);
return false;
}
}
} catch (final FlagParseException e) {
player.sendMessage(
TranslatableCaption.of("flag.flag_parse_error"),
TagResolver.builder()
.tag("flag_name", Tag.inserting(Component.text(flag.getName())))
.tag("flag_value", Tag.inserting(Component.text(e.getValue())))
.tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
.build()
);
return false;
} catch (final Exception e) {
return false;
}
return true;
}
boolean result;
String basePerm = Permission.PERMISSION_SET_FLAG_KEY.format(key.toLowerCase());
if (flag.isValuedPermission()) {
result = player.hasKeyedPermission(basePerm, value);
} else {
result = player.hasPermission(basePerm);
perm = basePerm;
}
if (!result) {
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver("node", Tag.inserting(Component.text(perm)))
);
}
return result;
}
@Override
public final @NonNull CommandCategory category() {
return CommandCategory.SETTINGS;
}
@Override
public @NonNull List<@NonNull CommandRequirement> requirements() {
return List.of(CommonCommandRequirement.IS_OWNER.withPermissionOverride(Permission.PERMISSION_SET_FLAG_OTHER));
}
@Override
protected final Command.@NonNull Builder<PlotPlayer<?>> prepare(final Command.@NonNull Builder<PlotPlayer<?>> builder) {
return builder.literal("flag");
}
}

View File

@ -0,0 +1,88 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.command.setting.flag;
import com.plotsquared.core.commands.parser.PlotFlagParser;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.flag.PlotFlag;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser;
public final class FlagInfoCommand extends FlagCommandBean {
private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {});
@Override
protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(final Command.@NonNull Builder<PlotPlayer<?>> builder) {
return builder.literal("info")
.required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL));
}
@Override
public void execute(final @NonNull CommandContext<PlotPlayer<?>> commandContext) {
final PlotFlag<?, ?> plotFlag = commandContext.get(COMPONENT_FLAG);
final PlotPlayer<?> player = commandContext.sender();
player.sendMessage(TranslatableCaption.of("flag.flag_info_header"));
// Flag name
player.sendMessage(
TranslatableCaption.of("flag.flag_info_name"),
TagResolver.resolver("flag", Tag.inserting(Component.text(plotFlag.getName())))
);
// Flag category
player.sendMessage(
TranslatableCaption.of("flag.flag_info_category"),
TagResolver.resolver(
"value",
Tag.inserting(plotFlag.getFlagCategory().toComponent(player))
)
);
// Flag description
// TODO maybe merge and \n instead?
player.sendMessage(TranslatableCaption.of("flag.flag_info_description"));
player.sendMessage(plotFlag.getFlagDescription());
// Flag example
player.sendMessage(
TranslatableCaption.of("flag.flag_info_example"),
TagResolver.builder()
.tag("command", Tag.preProcessParsed("/plot flag set"))
.tag("flag", Tag.preProcessParsed(plotFlag.getName()))
.tag("value", Tag.preProcessParsed(plotFlag.getExample()))
.build()
);
// Default value
final String defaultValue = player.getLocation().getPlotArea().getFlagContainer()
.getFlagErased(plotFlag.getClass()).toString();
player.sendMessage(
TranslatableCaption.of("flag.flag_info_default_value"),
TagResolver.resolver("value", Tag.inserting(Component.text(defaultValue)))
);
// Footer. Done this way to prevent the duplicate-message-thingy from catching it
player.sendMessage(TranslatableCaption.of("flag.flag_info_footer"));
}
}

View File

@ -0,0 +1,93 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.command.setting.flag;
import com.plotsquared.core.configuration.caption.StaticCaption;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
import com.plotsquared.core.plot.flag.InternalFlag;
import com.plotsquared.core.plot.flag.PlotFlag;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.context.CommandContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public final class FlagListCommand extends FlagCommandBean {
private static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build();
@Override
protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(
final Command.@NonNull Builder<PlotPlayer<?>> builder
) {
return builder.literal("list");
}
@Override
public void execute(final @NonNull CommandContext<PlotPlayer<?>> commandContext) {
final PlotPlayer<?> player = commandContext.sender();
final Map<Component, ArrayList<String>> flags = new HashMap<>();
for (PlotFlag<?, ?> plotFlag : GlobalFlagContainer.getInstance().getRecognizedPlotFlags()) {
if (plotFlag instanceof InternalFlag) {
continue;
}
final Component category = plotFlag.getFlagCategory().toComponent(player);
final Collection<String> flagList = flags.computeIfAbsent(category, k -> new ArrayList<>());
flagList.add(plotFlag.getName());
}
for (final Map.Entry<Component, ArrayList<String>> entry : flags.entrySet()) {
Collections.sort(entry.getValue());
Component category =
MINI_MESSAGE.deserialize(
TranslatableCaption.of("flag.flag_list_categories").getComponent(player),
TagResolver.resolver("category", Tag.inserting(entry.getKey().style(Style.empty())))
);
TextComponent.Builder builder = Component.text().append(category);
final Iterator<String> flagIterator = entry.getValue().iterator();
while (flagIterator.hasNext()) {
final String flag = flagIterator.next();
builder.append(MINI_MESSAGE
.deserialize(
TranslatableCaption.of("flag.flag_list_flag").getComponent(player),
TagResolver.builder()
.tag("command", Tag.preProcessParsed("/plat flag info " + flag))
.tag("flag", Tag.inserting(Component.text(flag)))
.tag("suffix", Tag.inserting(Component.text(flagIterator.hasNext() ? ", " : "")))
.build()
));
}
player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(builder.build())));
}
}
}

View File

@ -0,0 +1,171 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.command.setting.flag;
import com.google.inject.Inject;
import com.plotsquared.core.commands.parser.PlotFlagParser;
import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.PlotFlagRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.flag.FlagParseException;
import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.plot.flag.types.ListFlag;
import com.plotsquared.core.util.EventDispatcher;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser;
import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser;
public final class FlagRemoveCommand extends FlagCommandBean {
private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {});
private static final CloudKey<String> COMPONENT_VALUE = CloudKey.of("value", String.class);
private final EventDispatcher eventDispatcher;
@Inject
public FlagRemoveCommand(final @NonNull EventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
}
@Override
protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(
final Command.@NonNull Builder<PlotPlayer<?>> builder
) {
return builder.literal("remove")
.required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.PLOT))
.optional(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG));
}
@Override
public void execute(final @NonNull CommandContext<PlotPlayer<?>> commandContext) {
final PlotPlayer<?> player = commandContext.sender();
final Plot plot = commandContext.inject(Plot.class).orElseThrow();
final PlotFlag<?, ?> flag = commandContext.get(COMPONENT_FLAG);
final String flagValue = commandContext.getOrDefault(COMPONENT_VALUE, null);
final PlotFlagRemoveEvent event = this.eventDispatcher.callFlagRemove(flag, plot);
if (event.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Flag set")))
);
return;
}
final String flagKey = flag.getName().toLowerCase(Locale.ENGLISH);
if (event.getEventResult() != Result.FORCE
&& !player.hasPermission(Permission.PERMISSION_SET_FLAG_KEY.format(flagKey))) {
if (flagValue == null) {
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver(
"node",
Tag.inserting(Component.text(Permission.PERMISSION_SET_FLAG_KEY.format(flagKey)))
)
);
return;
}
}
if (flagValue != null && flag instanceof ListFlag<?,?> listFlag) {
final List<?> list = new ArrayList<>(plot.getFlag(listFlag));
final PlotFlag parsedFlag;
try {
parsedFlag = listFlag.parse(flagValue);
} catch (final FlagParseException e) {
player.sendMessage(
TranslatableCaption.of("flag.flag_parse_error"),
TagResolver.builder()
.tag("flag_name", Tag.inserting(Component.text(flag.getName())))
.tag("flag_value", Tag.inserting(Component.text(e.getValue())))
.tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
.build()
);
return;
}
if (((List<?>) parsedFlag.getValue()).isEmpty()) {
player.sendMessage(TranslatableCaption.of("flag.flag_not_removed"));
return;
}
if (list.removeAll((List) parsedFlag.getValue())) {
if (list.isEmpty()) {
if (plot.removeFlag(flag)) {
player.sendMessage(
TranslatableCaption.of("flag.flag_removed"),
TagResolver.builder()
.tag("flag", Tag.inserting(Component.text(flagKey)))
.tag("value", Tag.inserting(Component.text(flag.toString())))
.build()
);
return;
} else {
player.sendMessage(TranslatableCaption.of("flag.flag_not_removed"));
return;
}
} else {
PlotFlag<?, ?> plotFlag = parsedFlag.createFlagInstance(list);
PlotFlagAddEvent addEvent = eventDispatcher.callFlagAdd(plotFlag, plot);
if (addEvent.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver(
"value",
Tag.inserting(Component.text("Re-addition of " + plotFlag.getName()))
)
);
return;
}
if (plot.setFlag(addEvent.getFlag())) {
player.sendMessage(TranslatableCaption.of("flag.flag_partially_removed"));
return;
} else {
player.sendMessage(TranslatableCaption.of("flag.flag_not_removed"));
return;
}
}
}
} else if (!plot.removeFlag(flag)) {
player.sendMessage(TranslatableCaption.of("flag.flag_not_removed"));
return;
}
player.sendMessage(
TranslatableCaption.of("flag.flag_removed"),
TagResolver.builder()
.tag("flag", Tag.inserting(Component.text(flagKey)))
.tag("value", Tag.inserting(Component.text(flag.toString())))
.build()
);
}
}

View File

@ -0,0 +1,110 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.command.setting.flag;
import com.google.inject.Inject;
import com.plotsquared.core.commands.parser.PlotFlagParser;
import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider;
import com.plotsquared.core.configuration.caption.CaptionUtility;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.flag.FlagParseException;
import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.util.EventDispatcher;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.key.CloudKey;
import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser;
import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser;
public final class FlagSetCommand extends FlagCommandBean {
private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {});
private static final CloudKey<String> COMPONENT_VALUE = CloudKey.of("value", String.class);
private final EventDispatcher eventDispatcher;
@Inject
public FlagSetCommand(final @NonNull EventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
}
@Override
protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(
final Command.@NonNull Builder<PlotPlayer<?>> builder
) {
return builder.literal("set")
.required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL))
.required(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG));
}
@Override
public void execute(final @NonNull CommandContext<PlotPlayer<?>> commandContext) {
final PlotPlayer<?> player = commandContext.sender();
final Plot plot = commandContext.inject(Plot.class).orElseThrow();
final PlotFlag<?, ?> flag = commandContext.get(COMPONENT_FLAG);
final String flagValue = commandContext.get(COMPONENT_VALUE);
final PlotFlagAddEvent event = this.eventDispatcher.callFlagAdd(flag, plot);
if (event.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Flag set")))
);
return;
}
if (event.getEventResult() != Result.FORCE && !checkPermValue(player, flag, flag.getName(), flagValue)) {
return;
}
final String sanitizedValue = CaptionUtility.stripClickEvents(flag, flagValue);
final PlotFlag<?, ?> parsedFlag;
try {
parsedFlag = flag.parse(flagValue);
} catch (final FlagParseException e) {
player.sendMessage(
TranslatableCaption.of("flag.flag_parse_error"),
TagResolver.builder()
.tag("flag_name", Tag.inserting(Component.text(flag.getName())))
.tag("flag_value", Tag.inserting(Component.text(e.getValue())))
.tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
.build()
);
return;
}
plot.setFlag(parsedFlag);
player.sendMessage(
TranslatableCaption.of("flag.flag_added"),
TagResolver.builder()
.tag("flag", Tag.inserting(Component.text(flag.getName())))
.tag("value", Tag.inserting(Component.text(parsedFlag.toString())))
.build()
);
}
}

View File

@ -0,0 +1,42 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.injection;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.injection.ParameterInjector;
import org.incendo.cloud.util.annotation.AnnotationAccessor;
/**
* {@link ParameterInjector} that returns the current plot of the player.
*/
public final class PlotInjector implements ParameterInjector<PlotPlayer<?>, Plot> {
@Override
public @Nullable Plot create(
final @NonNull CommandContext<PlotPlayer<?>> context,
final @NonNull AnnotationAccessor annotationAccessor
) {
// TODO: Allow for overriding for console.
return context.sender().getCurrentPlot();
}
}

View File

@ -0,0 +1,158 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.parser;
import com.plotsquared.core.configuration.caption.LocaleHolder;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.flag.FlagContainer;
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
import com.plotsquared.core.plot.flag.InternalFlag;
import com.plotsquared.core.plot.flag.PlotFlag;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.util.ComponentMessageThrowable;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.exception.parsing.ParserException;
import org.incendo.cloud.parser.ArgumentParseResult;
import org.incendo.cloud.parser.ArgumentParser;
import org.incendo.cloud.parser.ParserDescriptor;
import org.incendo.cloud.suggestion.BlockingSuggestionProvider;
import org.incendo.cloud.suggestion.Suggestion;
import java.util.Collection;
import java.util.function.Function;
/**
* Parser that parses and suggests {@link PlotFlag plot flags}.
*/
public final class PlotFlagParser implements ArgumentParser<PlotPlayer<?>, PlotFlag<?, ?>>,
BlockingSuggestionProvider<PlotPlayer<?>> {
/**
* Returns a new parser that parses {@link PlotFlag plot flags}.
*
* @param source the source of available flag values
* @return the parser
*/
public static @NonNull ParserDescriptor<PlotPlayer<?>, PlotFlag<?, ?>> plotFlagParser(final @NonNull FlagSource source) {
return ParserDescriptor.of(new PlotFlagParser(source), new TypeToken<PlotFlag<?, ?>>() {
});
}
private final FlagSource flagSource;
private PlotFlagParser(final @NonNull FlagSource flagSource) {
this.flagSource = flagSource;
}
@Override
public @NonNull ArgumentParseResult<@NonNull PlotFlag<?, ?>> parse(
final @NonNull CommandContext<@NonNull PlotPlayer<?>> commandContext,
final @NonNull CommandInput commandInput
) {
final String flagName = commandInput.readString();
final PlotFlag<?, ?> flag = GlobalFlagContainer.getInstance().getFlagFromString(flagName);
if (flag == null) {
return ArgumentParseResult.failure(new PlotFlagParseException(commandContext));
}
return ArgumentParseResult.success(flag);
}
@Override
public @NonNull Iterable<@NonNull Suggestion> suggestions(
final @NonNull CommandContext<PlotPlayer<?>> context,
final @NonNull CommandInput input
) {
return this.flagSource.flags(context.sender())
.stream()
.filter(flag -> (!(flag instanceof InternalFlag)))
.map(PlotFlag::getName)
.map(Suggestion::simple)
.toList();
}
public enum FlagSource {
/**
* All recognized flags.
*/
GLOBAL(player -> GlobalFlagContainer.getInstance(), false),
/**
* All flags that have been configured in the current plot.
*/
PLOT(player -> {
final Plot plot = player.getCurrentPlot();
if (plot == null) {
return GlobalFlagContainer.getInstance();
}
return plot.getFlagContainer();
}, true);
private final Function<PlotPlayer<?>, FlagContainer> containerFunction;
private final boolean storedOnly;
FlagSource(final @NonNull Function<PlotPlayer<?>, FlagContainer> containerFunction, final boolean storedOnly) {
this.containerFunction = containerFunction;
this.storedOnly = storedOnly;
}
/**
* Returns the flag container.
*
* @param player the player to get the container for
* @return the container
*/
public @NonNull FlagContainer flagContainer(final @NonNull PlotPlayer<?> player) {
return this.containerFunction.apply(player);
}
/**
* Returns the flags from this source.
*
* @param player the player to get the flags for
* @return the flags
*/
public @NonNull Collection<@NonNull PlotFlag<?, ?>> flags(final @NonNull PlotPlayer<?> player) {
final FlagContainer container = this.flagContainer(player);
if (this.storedOnly) {
return container.getFlagMap().values();
}
return container.getRecognizedPlotFlags();
}
}
/**
* Exception thrown when an invalid flag name is supplied.
*/
public static final class PlotFlagParseException extends ParserException implements ComponentMessageThrowable {
private PlotFlagParseException(final @NonNull CommandContext<?> context) {
super(PlotFlagParser.class, context, TranslatableCaption.of("flag.not_valid_flag"));
}
@Override
public @NonNull Component componentMessage() {
// TODO(City): This sucks...
return ((TranslatableCaption) this.errorCaption()).toComponent(LocaleHolder.console());
}
}
}

View File

@ -0,0 +1,86 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.suggestions;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.plot.flag.types.ListFlag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.key.CloudKey;
import org.incendo.cloud.suggestion.BlockingSuggestionProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Suggestion provider that provides context-aware {@link PlotFlag plot flag} value suggestions using
* {@link PlotFlag#getTabCompletions()}.
*/
public final class FlagValueSuggestionProvider implements BlockingSuggestionProvider.Strings<PlotPlayer<?>> {
private final CloudKey<PlotFlag<?, ?>> flagKey;
/**
* Creates a new suggestion provider.
*
* @param flagKey the key of the argument that contains the flag to provide value suggestions for
*/
public FlagValueSuggestionProvider(final @NonNull CloudKey<PlotFlag<?, ?>> flagKey) {
this.flagKey = Objects.requireNonNull(flagKey, "flagKey");
}
@Override
public @NonNull Iterable<@NonNull String> stringSuggestions(
@NonNull final CommandContext<PlotPlayer<?>> context,
@NonNull final CommandInput input
) {
final PlotFlag<?, ?> plotFlag = context.getOrDefault(this.flagKey, null);
if (plotFlag == null) {
return List.of();
}
final Collection<String> completions = plotFlag.getTabCompletions();
if (plotFlag instanceof ListFlag<?,?> && input.peekString().contains(",")) {
final String[] split = input.peekString().split(",");
final List<String> existingValues = new ArrayList<>(Arrays.asList(split));
final String completingValue;
if (!input.peekString().endsWith(",")) {
// In this case we want to complete the value we're currently typing.
completingValue = split[split.length - 1];
existingValues.remove(existingValues.size() - 1);
} else {
completingValue = null;
}
final String prefix = existingValues.stream().collect(Collectors.joining(",", "", ","));
return completions.stream()
.filter(value -> !existingValues.contains(value))
.filter(value -> completingValue == null || value.startsWith(completingValue))
.map(value -> prefix + value)
.toList();
}
return completions;
}
}

View File

@ -25,6 +25,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.caption.Caption;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Locale; import java.util.Locale;
@ -33,7 +34,7 @@ import java.util.regex.Pattern;
/** /**
* Caption that is user modifiable * Caption that is user modifiable
*/ */
public final class TranslatableCaption implements NamespacedCaption { public final class TranslatableCaption implements NamespacedCaption, Caption {
/** /**
* Default caption namespace * Default caption namespace
@ -72,6 +73,11 @@ public final class TranslatableCaption implements NamespacedCaption {
); );
} }
@Override
public @NonNull String key() {
return this.getKey();
}
/** /**
* Get a new {@link TranslatableCaption} instance * Get a new {@link TranslatableCaption} instance
* *

View File

@ -0,0 +1,46 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.inject.modules;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.google.inject.multibindings.Multibinder;
import com.plotsquared.core.commands.PlotSquaredCommandBean;
import com.plotsquared.core.commands.command.setting.flag.FlagAddCommand;
import com.plotsquared.core.commands.command.setting.flag.FlagInfoCommand;
import com.plotsquared.core.commands.command.setting.flag.FlagListCommand;
import com.plotsquared.core.commands.command.setting.flag.FlagRemoveCommand;
import com.plotsquared.core.commands.command.setting.flag.FlagSetCommand;
public final class CommandModule extends AbstractModule {
@Override
protected void configure() {
final Multibinder<PlotSquaredCommandBean> commands = Multibinder.newSetBinder(
this.binder(),
PlotSquaredCommandBean.class
);
commands.addBinding().to(FlagAddCommand.class).in(Scopes.SINGLETON);
commands.addBinding().to(FlagInfoCommand.class).in(Scopes.SINGLETON);
commands.addBinding().to(FlagListCommand.class).in(Scopes.SINGLETON);
commands.addBinding().to(FlagRemoveCommand.class).in(Scopes.SINGLETON);
commands.addBinding().to(FlagSetCommand.class).in(Scopes.SINGLETON);
}
}

View File

@ -18,7 +18,6 @@
*/ */
package com.plotsquared.core.inject.modules; package com.plotsquared.core.inject.modules;
import cloud.commandframework.services.ServicePipeline;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.file.YamlConfiguration; import com.plotsquared.core.configuration.file.YamlConfiguration;
@ -31,6 +30,7 @@ import com.plotsquared.core.listener.PlotListener;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.uuid.UUIDPipeline; import com.plotsquared.core.uuid.UUIDPipeline;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import org.incendo.cloud.services.ServicePipeline;
import java.io.File; import java.io.File;

View File

@ -18,7 +18,6 @@
*/ */
package com.plotsquared.core.services.plots; package com.plotsquared.core.services.plots;
import cloud.commandframework.services.types.Service;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@ -26,6 +25,7 @@ import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.incendo.cloud.services.type.Service;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View File

@ -31,6 +31,8 @@ paperlib = "1.0.8"
informative-annotations = "1.4" informative-annotations = "1.4"
vault = "1.7.1" vault = "1.7.1"
serverlib = "2.3.4" serverlib = "2.3.4"
cloud = "2.0.0-beta.1"
cloudRequirements = "1.0.0-beta.1"
# Gradle plugins # Gradle plugins
shadow = "8.1.1" shadow = "8.1.1"
@ -66,7 +68,7 @@ faweBukkit = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Bukk
# Third party # Third party
prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" } prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" }
aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" } aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" }
cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud-services" } cloudServices = { group = "org.incendo", name = "cloud-services", version.ref = "cloud-services" }
mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" }
squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" }
arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" }
@ -77,6 +79,10 @@ informativeAnnotations = { group = "com.intellectualsites.informative-annotation
paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" } paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" }
vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" }
serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" }
cloud = { group = "org.incendo", name = "cloud-core", version.ref = "cloud" }
cloudPaper = { group = "org.incendo", name = "cloud-paper", version.ref = "cloud" }
cloudMinecraftExtras = { group = "org.incendo", name = "cloud-minecraft-extras", version.ref = "cloud" }
cloudRequirements = { group = "org.incendo", name = "cloud-processors-requirements", version.ref = "cloudRequirements" }
[plugins] [plugins]
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }