Compare commits
9 Commits
main
...
dev/dialog
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e554e2643d | ||
|
|
49fb85229d | ||
|
|
ffdafd07d2 | ||
|
|
bcba3413c5 | ||
|
|
b4cca9227e | ||
|
|
f80408502b | ||
|
|
4d531ea7b5 | ||
|
|
aaebd64294 | ||
|
|
33f51eed09 |
|
|
@ -2,11 +2,12 @@ import java.io.ByteArrayOutputStream
|
|||
import java.io.FileOutputStream
|
||||
import java.net.URL
|
||||
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||
import net.minecrell.pluginyml.paper.PaperPluginDescription
|
||||
|
||||
plugins {
|
||||
id("java")
|
||||
id("java-library")
|
||||
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
|
||||
id("de.eldoria.plugin-yml.paper") version "0.8.0"
|
||||
id("xyz.jpenilla.run-paper") version "1.0.6"
|
||||
id("maven-publish")
|
||||
}
|
||||
|
|
@ -40,7 +41,7 @@ tasks {
|
|||
file.parentFile.mkdirs()
|
||||
}
|
||||
if (!file.exists()) {
|
||||
download("https://jenkins.destro.xyz/job/Cosmos/lastSuccessfulBuild/artifact/cosmos-server/build/libs/cosmos-bundler-1.21.6-R0.1-SNAPSHOT-mojmap.jar", fileName)
|
||||
download("https://jenkins.destro.xyz/job/Cosmos/lastSuccessfulBuild/artifact/cosmos-server/build/libs/cosmos-bundler-1.21.11-R0.1-SNAPSHOT-mojmap.jar", fileName)
|
||||
}
|
||||
serverJar(file)
|
||||
minecraftVersion("1.21")
|
||||
|
|
@ -61,8 +62,10 @@ publishing {
|
|||
configure<PublishingExtension> {
|
||||
repositories {
|
||||
maven {
|
||||
name = "maven"
|
||||
url = uri("https://repo.destro.xyz/snapshots/")
|
||||
name = "AlttdNexus"
|
||||
url = uri(
|
||||
"https://repo.alttd.com/repository/alttd-snapshot/"
|
||||
)
|
||||
credentials(PasswordCredentials::class)
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +73,7 @@ publishing {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("com.alttd.cosmos:cosmos-api:1.21.6-R0.1-SNAPSHOT")
|
||||
compileOnly("com.alttd.cosmos:cosmos-api:1.21.11-R0.1-SNAPSHOT")
|
||||
compileOnly("com.github.milkbowl:VaultAPI:1.7") {
|
||||
exclude("org.bukkit","bukkit")
|
||||
}
|
||||
|
|
@ -97,14 +100,23 @@ fun download(link: String, path: String) {
|
|||
}
|
||||
}
|
||||
|
||||
bukkit {
|
||||
paper {
|
||||
name = rootProject.name
|
||||
main = "$group.${rootProject.name}"
|
||||
bootstrapper = "$group.${rootProject.name}Bootstrap"
|
||||
version = "${rootProject.version}-${gitCommit()}"
|
||||
apiVersion = "1.20"
|
||||
apiVersion = "1.21"
|
||||
authors = listOf("destro174")
|
||||
depend = listOf("Vault")
|
||||
softDepend = listOf("GriefPrevention")
|
||||
serverDependencies {
|
||||
register("Vault") {
|
||||
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
|
||||
}
|
||||
|
||||
register("GriefPrevention") {
|
||||
required = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
permissions {
|
||||
register("playershops.admin") {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,14 @@ rootProject.name = "PlayerShops"
|
|||
dependencyResolutionManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
|
||||
maven {
|
||||
name = "AlttdNexus"
|
||||
url = uri(
|
||||
"https://repo.alttd.com/repository/alttd-snapshot/"
|
||||
)
|
||||
credentials(PasswordCredentials::class)
|
||||
}
|
||||
maven("https://repo.destro.xyz/snapshots")
|
||||
maven("https://jitpack.io") { // Vault
|
||||
content {
|
||||
includeGroup("com.github.milkbowl")
|
||||
|
|
|
|||
|
|
@ -1,21 +1,26 @@
|
|||
package com.alttd.playershops;
|
||||
|
||||
import com.alttd.playershops.commands.PlayerShopCommands;
|
||||
import com.alttd.playershops.commands.PlayerShopCommand;
|
||||
import com.alttd.playershops.config.Config;
|
||||
import com.alttd.playershops.config.DatabaseConfig;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.gui.GuiIcon;
|
||||
import com.alttd.playershops.handler.ShopHandler;
|
||||
import com.alttd.playershops.listener.*;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.storage.database.DatabaseManager;
|
||||
import com.alttd.playershops.storage.database.DatabaseHelper;
|
||||
import io.papermc.paper.command.brigadier.Commands;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||
import lombok.Getter;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerShops extends JavaPlugin {
|
||||
|
||||
@Getter
|
||||
|
|
@ -31,7 +36,6 @@ public class PlayerShops extends JavaPlugin {
|
|||
private ShopListener shopListener;
|
||||
private PlayerListener playerListener;
|
||||
private TransactionListener transactionListener;
|
||||
private InventoryListener inventoryListener;
|
||||
private GriefPreventionListener griefPreventionListener;
|
||||
|
||||
@Getter
|
||||
|
|
@ -40,14 +44,14 @@ public class PlayerShops extends JavaPlugin {
|
|||
public void onEnable() {
|
||||
instance = this;
|
||||
if(!setupEconomy()) {
|
||||
Bukkit.getLogger().warning("Error loading Vault and economy.\n Disabling plugin");
|
||||
getLogger().warning("Error loading Vault and economy.\n Disabling plugin");
|
||||
this.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
Bukkit.getLogger().info("Hooked into Vault economy provided by " + econ.getName());
|
||||
getLogger().info("Hooked into Vault economy provided by " + econ.getName());
|
||||
reloadConfigs();
|
||||
if(!setupDatabase()) {
|
||||
Bukkit.getLogger().warning("Error setting up database connection.\n Disabling plugin");
|
||||
getLogger().warning("Error setting up database connection.\n Disabling plugin");
|
||||
this.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
|
@ -95,7 +99,6 @@ public class PlayerShops extends JavaPlugin {
|
|||
shopListener = new ShopListener(this);
|
||||
playerListener = new PlayerListener(this);
|
||||
transactionListener = new TransactionListener(this);
|
||||
inventoryListener = new InventoryListener(this);
|
||||
griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP
|
||||
}
|
||||
|
||||
|
|
@ -103,11 +106,14 @@ public class PlayerShops extends JavaPlugin {
|
|||
shopListener.unregister();
|
||||
playerListener.unregister();
|
||||
transactionListener.unregister();
|
||||
inventoryListener.unregister();
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
PlayerShopCommands.registerCommands();
|
||||
LifecycleEventManager<Plugin> manager = this.getLifecycleManager();
|
||||
manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> {
|
||||
final Commands commands = event.registrar();
|
||||
commands.register(new PlayerShopCommand().command(), null, List.of("shop", "shops"));
|
||||
});
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
|
|
@ -119,9 +125,6 @@ public class PlayerShops extends JavaPlugin {
|
|||
for (ShopType shopType : ShopType.values()) {
|
||||
// preload ShopType to get the configs active
|
||||
}
|
||||
for (GuiIcon guiIcon : GuiIcon.values()) {
|
||||
// preload to get config values generated
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.alttd.playershops;
|
||||
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class PlayerShopsBootstrap implements PluginBootstrap {
|
||||
|
||||
@Override
|
||||
public void bootstrap(BootstrapContext context) {}
|
||||
|
||||
}
|
||||
|
|
@ -1,147 +1,95 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.commands.arguments.OfflinePlayerArgument;
|
||||
import com.alttd.playershops.commands.subcommands.CheckStockCommand;
|
||||
import com.alttd.playershops.commands.subcommands.ReloadCommand;
|
||||
import com.alttd.playershops.commands.subcommands.TransferShopsCommand;
|
||||
import com.alttd.playershops.gui.HomeGui;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import com.alttd.playershops.dialog.ShopDialog;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import io.papermc.paper.command.brigadier.Commands;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
public class PlayerShopCommand {
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
public static final String BASE_PERM = "playershops.command";
|
||||
|
||||
public class PlayerShopCommand extends Command {
|
||||
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
|
||||
final LiteralArgumentBuilder<CommandSourceStack> builder =
|
||||
Commands.literal("playershop")
|
||||
.requires(
|
||||
commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM)
|
||||
&& commandSourceStack.getSender() instanceof Player
|
||||
)
|
||||
.executes((source) -> {
|
||||
if (!(source.getSource().getSender() instanceof Player player))
|
||||
return 1;
|
||||
|
||||
public static final String BASE_PERM = "playershops.command"; // TODO load from config
|
||||
ShopDialog shopDialog = new ShopDialog(player.getUniqueId());
|
||||
shopDialog.open();
|
||||
return 1;
|
||||
})
|
||||
.then(
|
||||
Commands.literal("reload")
|
||||
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".reload"))
|
||||
.executes(source -> {
|
||||
PlayerShops.getInstance().reloadConfigs();
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
.then(
|
||||
Commands.literal("checkstock")
|
||||
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".checkstock")
|
||||
&& commandSourceStack.getSender() instanceof Player)
|
||||
.then(
|
||||
Commands.argument("range", IntegerArgumentType.integer(1, 100))
|
||||
.executes(source -> {
|
||||
if (!(source.getSource().getSender() instanceof Player player))
|
||||
return 1;
|
||||
|
||||
// subcommand label -> subcommand
|
||||
private static final Map<String, Subcommand> SUBCOMMANDS = PlayerShopCommands.make(() -> {
|
||||
final Map<Set<String>, Subcommand> commands = new HashMap<>();
|
||||
int range = source.getArgument("range", Integer.class);
|
||||
int stock = -1;
|
||||
CheckStockCommand.doStockCheck(player, range, stock);
|
||||
return 1;
|
||||
})
|
||||
.then(
|
||||
Commands.argument("stock", IntegerArgumentType.integer())
|
||||
.executes(source -> {
|
||||
if (!(source.getSource().getSender() instanceof Player player))
|
||||
return 1;
|
||||
|
||||
commands.put(Set.of("reload"), new ReloadCommand());
|
||||
commands.put(Set.of("checkstock"), new CheckStockCommand());
|
||||
commands.put(Set.of("transfershops"), new TransferShopsCommand());
|
||||
int range = source.getArgument("range", Integer.class);
|
||||
int stock = source.getArgument("stock", Integer.class);
|
||||
CheckStockCommand.doStockCheck(player, range, stock);
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(
|
||||
Commands.literal("transfershops")
|
||||
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".transfershops"))
|
||||
.then(
|
||||
Commands.argument("old", new OfflinePlayerArgument())
|
||||
.then(
|
||||
Commands.argument("new", new OfflinePlayerArgument())
|
||||
)
|
||||
.executes(
|
||||
source -> {
|
||||
OfflinePlayer oldOwner = source.getArgument("old", OfflinePlayer.class);
|
||||
OfflinePlayer newOwner = source.getArgument("new", OfflinePlayer.class);
|
||||
PlayerShops.getInstance().getShopHandler().transferShops(source.getSource().getSender(), oldOwner, newOwner);
|
||||
|
||||
return commands.entrySet().stream()
|
||||
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
});
|
||||
// alias -> subcommand label
|
||||
private static final Map<String, String> ALIASES = PlayerShopCommands.make(() -> {
|
||||
final Map<String, Set<String>> aliases = new HashMap<>();
|
||||
|
||||
aliases.put("reload", Set.of("reloadconfig"));
|
||||
|
||||
return aliases.entrySet().stream()
|
||||
.flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey())))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
});
|
||||
|
||||
public PlayerShopCommand() {
|
||||
super("playershop");
|
||||
this.description = "PlayerShop related commands";
|
||||
this.usageMessage = "/playershop [" + String.join(" | ", SUBCOMMANDS.keySet()) + "]";
|
||||
this.setAliases(List.of("shop", "shops"));
|
||||
final List<String> permissions = new ArrayList<>();
|
||||
permissions.add(BASE_PERM);
|
||||
permissions.addAll(SUBCOMMANDS.keySet().stream().map(s -> BASE_PERM + "." + s).toList());
|
||||
this.setPermission(String.join(";", permissions));
|
||||
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
for (final String perm : permissions) {
|
||||
pluginManager.addPermission(new Permission(perm, PermissionDefault.OP));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
;
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static boolean testPermission(final CommandSender sender, final String permission) {
|
||||
if (sender.hasPermission(BASE_PERM + "." + permission)) {
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(Bukkit.permissionMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> tabComplete(
|
||||
final @NotNull CommandSender sender,
|
||||
final @NotNull String alias,
|
||||
final String[] args,
|
||||
final @Nullable Location location
|
||||
) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
return PlayerShopCommands.getListMatchingLast(sender, args, SUBCOMMANDS.keySet(), BASE_PERM);
|
||||
}
|
||||
|
||||
final @Nullable Pair<String, Subcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(
|
||||
final @NotNull CommandSender sender,
|
||||
final @NotNull String commandLabel,
|
||||
final String[] args
|
||||
) {
|
||||
if (!testPermission(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(Util.parseMiniMessage("<red>Only players can use this command."));
|
||||
return false;
|
||||
}
|
||||
HomeGui gui = new HomeGui(player.getUniqueId());
|
||||
gui.open();
|
||||
return true;
|
||||
}
|
||||
final @Nullable Pair<String, Subcommand> subCommand = resolveCommand(args[0]);
|
||||
|
||||
if (subCommand == null) {
|
||||
sender.sendMessage(text("Usage: " + this.usageMessage, RED));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!testPermission(sender, subCommand.first())) {
|
||||
return true;
|
||||
}
|
||||
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
||||
}
|
||||
|
||||
private static @Nullable Pair<String, Subcommand> resolveCommand(String label) {
|
||||
label = label.toLowerCase(Locale.ENGLISH);
|
||||
@Nullable Subcommand subCommand = SUBCOMMANDS.get(label);
|
||||
if (subCommand == null) {
|
||||
final @Nullable String command = ALIASES.get(label);
|
||||
if (command != null) {
|
||||
label = command;
|
||||
subCommand = SUBCOMMANDS.get(command);
|
||||
}
|
||||
}
|
||||
|
||||
if (subCommand != null) {
|
||||
return Pair.of(label, subCommand);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class PlayerShopCommands {
|
||||
|
||||
private PlayerShopCommands() {
|
||||
}
|
||||
|
||||
private static final Map<String, Command> COMMANDS = new HashMap<>();
|
||||
static {
|
||||
COMMANDS.put("playershop", new PlayerShopCommand());
|
||||
}
|
||||
|
||||
public static void registerCommands() {
|
||||
COMMANDS.forEach((s, command) -> {
|
||||
Bukkit.getCommandMap().register(s, command.getName(), command);
|
||||
});
|
||||
}
|
||||
|
||||
// Code from Mojang - copyright them | Altered to fit our needs
|
||||
public static List<String> getListMatchingLast(final CommandSender sender, final String[] args, final String basePermission, final String... matches) {
|
||||
return getListMatchingLast(sender, args, Arrays.asList(matches), basePermission);
|
||||
}
|
||||
|
||||
public static boolean matches(final String s, final String s1) {
|
||||
return s1.regionMatches(true, 0, s, 0, s.length());
|
||||
}
|
||||
|
||||
public static List<String> getListMatchingLast(final CommandSender sender, final String[] strings, final Collection<?> collection, final String basePermission) {
|
||||
String last = strings[strings.length - 1];
|
||||
ArrayList<String> results = Lists.newArrayList();
|
||||
|
||||
if (!collection.isEmpty()) {
|
||||
|
||||
for (String s1 : collection.stream().map(Functions.toStringFunction()).toList()) {
|
||||
if (matches(last, s1) && (sender.hasPermission(basePermission + "." + s1))) {
|
||||
results.add(s1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static <T> T make(Supplier<T> factory) {
|
||||
return factory.get();
|
||||
}
|
||||
// end copy stuff
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public interface Subcommand {
|
||||
|
||||
boolean execute(CommandSender sender, String subCommand, String[] args);
|
||||
|
||||
default List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.alttd.playershops.commands.arguments;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
|
||||
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class OfflinePlayerArgument implements CustomArgumentType.Converted<OfflinePlayer, String> {
|
||||
|
||||
@Override
|
||||
public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException {
|
||||
try {
|
||||
return Bukkit.getOfflinePlayer(nativeType);
|
||||
} catch (Exception e) {
|
||||
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid PlayerName %s!".formatted(nativeType), NamedTextColor.RED));
|
||||
|
||||
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArgumentType<String> getNativeType() {
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> @NotNull CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
|
||||
Bukkit.getOnlinePlayers().stream()
|
||||
.map(Player::getName)
|
||||
.filter(name -> name.toLowerCase(Locale.ROOT).startsWith(builder.getRemainingLowerCase()))
|
||||
.forEach(builder::suggest);
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,7 @@ package com.alttd.playershops.commands.subcommands;
|
|||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.commands.PlayerShopCommand;
|
||||
import com.alttd.playershops.commands.PlayerShopCommands;
|
||||
import com.alttd.playershops.commands.Subcommand;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
|
|
@ -13,78 +12,26 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class CheckStockCommand implements Subcommand {
|
||||
public class CheckStockCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
return this.doStockCheck(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
// TODO give some default tab completions
|
||||
if (args.length == 1) {
|
||||
return PlayerShopCommands.getListMatchingLast(sender, args, PlayerShopCommand.BASE_PERM + ".checkstock", "help");
|
||||
} else if (args.length == 2) {
|
||||
// return PlayerShopCommands.getListMatchingLast(sender, args, "radius");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private int minimumStock = -1;
|
||||
|
||||
public boolean doStockCheck(final CommandSender sender, final String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendRichMessage("<red>Only players can use this command.");
|
||||
return false;
|
||||
}
|
||||
if (args.length != 1 && args.length != 2) {
|
||||
player.sendRichMessage("<red>Invalid command syntax, use /checkstock <radius> [minimum stock]");
|
||||
return false;
|
||||
}
|
||||
|
||||
int radius;
|
||||
try {
|
||||
radius = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendRichMessage("<red>radius has to be a valid number, use /checkstock <radius> [minimum stock]");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (radius > 100 || radius <= 0) {
|
||||
player.sendRichMessage("<red>Please keep the radius between 1 and 100");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length == 2) {
|
||||
try {
|
||||
minimumStock = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendRichMessage("<red>minimum stock has to be a valid number, use /checkstock <radius> [minimum stock]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
List<Stock> stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player);
|
||||
sendStockMessage(player, stockList);
|
||||
public static void doStockCheck(final Player player, int radius, int minimumStock) {
|
||||
List<Stock> stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player, minimumStock);
|
||||
sendStockMessage(player, stockList, minimumStock);
|
||||
highlightLowStock(player, stockList);
|
||||
return true;
|
||||
}
|
||||
|
||||
//Stole this code from AlttdUtility by ___Kappa___ and reworked it slightly
|
||||
private void highlightLowStock(Player player, List<Stock> stockList) {
|
||||
private static void highlightLowStock(Player player, List<Stock> stockList) {
|
||||
ParticleBuilder particleBuilder = new ParticleBuilder(Particle.DUST);
|
||||
particleBuilder.color(255, 255, 255);
|
||||
particleBuilder.receivers(player);
|
||||
|
|
@ -139,7 +86,7 @@ public class CheckStockCommand implements Subcommand {
|
|||
* @param caller Player who is checking for stock, can only see the stock from their shops unless they have base_perm.checkstock.bypass
|
||||
* @return A list of Stock that the player is allowed to see
|
||||
*/
|
||||
private List<Stock> checkStock(int x, int z, int radius, Player caller) {
|
||||
private static List<Stock> checkStock(int x, int z, int radius, Player caller, int minimumStock) {
|
||||
List<PlayerShop> shops = PlayerShops.getInstance().getShopHandler().getShopsInRadius(x, z, radius);
|
||||
Stream<PlayerShop> playerShopStream = shops.stream();
|
||||
if (minimumStock != -1)
|
||||
|
|
@ -157,8 +104,7 @@ public class CheckStockCommand implements Subcommand {
|
|||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static final String putInConfig = "<yellow><click:run_command:'/cmi tppos <x> <y> <z>'>[<aqua><item_component></aqua>] <amount> left in stock</click></yellow>";
|
||||
private void sendStockMessage(Player player, List<Stock> stockList) {
|
||||
private static void sendStockMessage(Player player, List<Stock> stockList, int minimumStock) {
|
||||
Component component = null;
|
||||
for (Stock stock : stockList) {
|
||||
TagResolver resolver = TagResolver.resolver(
|
||||
|
|
@ -169,9 +115,9 @@ public class CheckStockCommand implements Subcommand {
|
|||
Placeholder.parsed("amount", stock.stock + "")
|
||||
);
|
||||
if (component == null)
|
||||
component = Util.parseMiniMessage(putInConfig, resolver);
|
||||
component = Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver);
|
||||
else
|
||||
component = component.append(Component.newline()).append(Util.parseMiniMessage(putInConfig, resolver));
|
||||
component = component.append(Component.newline()).append(Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver));
|
||||
}
|
||||
if (component == null)
|
||||
if (minimumStock == -1)
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
package com.alttd.playershops.commands.subcommands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.commands.Subcommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class ReloadCommand implements Subcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
PlayerShops.getInstance().reloadConfigs();
|
||||
// Todo message when config is reloaded
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package com.alttd.playershops.commands.subcommands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.commands.Subcommand;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
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.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class TransferShopsCommand implements Subcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendRichMessage("<red>Only players can use this command.");
|
||||
return false;
|
||||
}
|
||||
if (args.length != 1 && args.length != 2) {
|
||||
player.sendRichMessage("<red>Invalid command syntax, use /transfershops <uuid> <newplayer>");
|
||||
return false;
|
||||
}
|
||||
OfflinePlayer oldOfflinePlayer = Bukkit.getOfflinePlayer(args[0]);
|
||||
if (!oldOfflinePlayer.hasPlayedBefore()) {
|
||||
player.sendRichMessage("<red>" + args[0] + " has not joined this server before.");
|
||||
return false;
|
||||
}
|
||||
Player newShopOwner = Bukkit.getPlayer(args[1]);
|
||||
if (newShopOwner == null) {
|
||||
player.sendRichMessage("<red>" + args[1] + " is not online and has to be online for this process.");
|
||||
return false;
|
||||
}
|
||||
UUID oldUUID = oldOfflinePlayer.getUniqueId();
|
||||
List<PlayerShop> playerShops = PlayerShops.getInstance().getShopHandler().getShops(oldUUID);
|
||||
sender.sendRichMessage("<red>Starting the transfer process now, this might lag the server.");
|
||||
for (PlayerShop playerShop : playerShops) {
|
||||
playerShop.setOwner(newShopOwner);
|
||||
}
|
||||
newShopOwner.sendRichMessage(playerShops.size() + " have been transferred to you.");
|
||||
sender.sendRichMessage(playerShops.size() + " have been transferred to " + args[1] + ".");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -143,9 +143,11 @@ public class MessageConfig {
|
|||
|
||||
public static String SHOP_INFO = "<yellow>This shop <action> <gold><amount></gold> <item> for <gold><price></gold>.</yellow>";
|
||||
public static String SHOP_STOCK_INFO = "<yellow>This <type> shop has <gold><stock></gold> stock.</yellow>";
|
||||
public static String SHOP_STOCK_CHECK = "<yellow><click:run_command:'/cmi tppos <x> <y> <z>'>[<aqua><item_component></aqua>] <amount> left in stock</click></yellow>";
|
||||
private static void otherMessages() {
|
||||
SHOP_INFO = getString("messages.shop-info", SHOP_INFO);
|
||||
SHOP_STOCK_INFO = getString("messages.shop-stock-info", SHOP_STOCK_INFO);
|
||||
SHOP_STOCK_CHECK = getString("messages.shop-stock-check", SHOP_STOCK_CHECK);
|
||||
}
|
||||
|
||||
public static String CHANGE_PRICE_PROMPT = "What should the price be? Type cancel to cancel this action.";
|
||||
|
|
|
|||
|
|
@ -1,216 +0,0 @@
|
|||
package com.alttd.playershops.conversation;
|
||||
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.gui.ShopManagementGui;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import com.google.common.base.Joiner;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.conversations.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConversationManager implements ConversationAbandonedListener {
|
||||
|
||||
PlayerShop playerShop;
|
||||
Player player;
|
||||
Conversation conversation;
|
||||
|
||||
public ConversationManager(JavaPlugin plugin, Player player, ConversationType conversationType, PlayerShop playerShop) {
|
||||
if (player.isConversing()) return;
|
||||
this.player = player;
|
||||
this.playerShop = playerShop;
|
||||
ConversationFactory conversationFactory = new ConversationFactory(plugin)
|
||||
.withModality(true)
|
||||
.withFirstPrompt(getPrompt(conversationType))
|
||||
.addConversationAbandonedListener(this)
|
||||
.withEscapeSequence("cancel");
|
||||
conversation = conversationFactory.buildConversation(player);
|
||||
conversation.setLocalEchoEnabled(false); // why is this not in the builder
|
||||
conversation.begin();
|
||||
}
|
||||
|
||||
Prompt getPrompt(ConversationType conversationType) {
|
||||
switch (conversationType) {
|
||||
case CHANGE_ITEM -> {
|
||||
return new ChangeItemPrompt();
|
||||
}
|
||||
case CHANGE_AMOUNT -> {
|
||||
return new ChangeAmountPrompt();
|
||||
}
|
||||
case CHANGE_TYPE -> {
|
||||
return new ChangeTypePrompt();
|
||||
}
|
||||
case WITHDRAW_BALANCE -> {
|
||||
return new WithdrawBalancePrompt();
|
||||
}
|
||||
case ADD_BALANCE -> {
|
||||
return new AddBalancePrompt();
|
||||
}
|
||||
case CHANGE_PRICE -> {
|
||||
return new ChangePricePrompt();
|
||||
}
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
private void openGui() {
|
||||
player.abandonConversation(conversation);
|
||||
ShopManagementGui shopManagementGui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||
shopManagementGui.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void conversationAbandoned(@NotNull ConversationAbandonedEvent abandonedEvent) {
|
||||
// abandonedEvent.getContext().getForWhom().sendRawMessage("Conversation ended.");
|
||||
}
|
||||
|
||||
private class ChangeTypePrompt extends FixedSetPrompt {
|
||||
|
||||
public ChangeTypePrompt() {
|
||||
super("buy", "sell", "none", "random");
|
||||
}
|
||||
|
||||
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||
return Util.parseMiniMessage("What shoptype would you like to use: " + Joiner.on(", ").join(fixedSet) + " Type cancel to cancel this action.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Prompt acceptValidatedInput(ConversationContext context, String input) {
|
||||
ShopType newType = ShopType.fromString(input);
|
||||
playerShop.setShopType(newType);
|
||||
openGui();
|
||||
return END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ChangePricePrompt extends NumericPrompt {
|
||||
|
||||
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||
return Util.parseMiniMessage(MessageConfig.CHANGE_PRICE_PROMPT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||
return input.doubleValue() >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||
return MessageConfig.CHANGE_PRICE_FAILED_PROMPT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||
playerShop.setPrice(number.doubleValue());
|
||||
openGui();
|
||||
return END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ChangeAmountPrompt extends NumericPrompt {
|
||||
|
||||
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||
return Util.parseMiniMessage(MessageConfig.CHANGE_AMOUNT_PROMPT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||
return input.intValue() > 0 && input.intValue() <= 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||
return MessageConfig.CHANGE_AMOUNT_FAILED_PROMPT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||
playerShop.setAmount(number.intValue());
|
||||
openGui();
|
||||
return END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class AddBalancePrompt extends NumericPrompt {
|
||||
|
||||
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||
return Util.parseMiniMessage(MessageConfig.ADD_BALANCE_PROMPT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||
if (input.doubleValue() < 0)
|
||||
return false;
|
||||
return EconomyUtils.hasSufficientFunds(player, input.doubleValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||
return MessageConfig.ADD_BALANCE_FAILED_PROMPT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||
playerShop.addBalance(number.doubleValue());
|
||||
EconomyUtils.removeFunds(player, number.doubleValue());
|
||||
openGui();
|
||||
return END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class WithdrawBalancePrompt extends NumericPrompt {
|
||||
|
||||
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||
return Util.parseMiniMessage(MessageConfig.WITHDRAW_BALANCE_PROMPT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||
if (input.doubleValue() < 0)
|
||||
return false;
|
||||
return EconomyUtils.hasSufficientFunds(playerShop, input.doubleValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||
return MessageConfig.WITHDRAW_BALANCE_FAILED_PROMPT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||
playerShop.removeBalance(number.doubleValue());
|
||||
EconomyUtils.addFunds(player, number.doubleValue());
|
||||
openGui();
|
||||
return END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ChangeItemPrompt extends FixedSetPrompt {
|
||||
|
||||
ChangeItemPrompt() {
|
||||
super("continue");
|
||||
}
|
||||
|
||||
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||
return Util.parseMiniMessage(MessageConfig.CHANGE_ITEM_PROMPT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Prompt acceptValidatedInput(ConversationContext context, String input) {
|
||||
playerShop.setItemStack(player.getInventory().getItemInMainHand().clone());
|
||||
openGui();
|
||||
return END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package com.alttd.playershops.conversation;
|
||||
|
||||
public enum ConversationType {
|
||||
CHANGE_ITEM,
|
||||
CHANGE_AMOUNT,
|
||||
CHANGE_TYPE,
|
||||
CHANGE_PRICE,
|
||||
WITHDRAW_BALANCE,
|
||||
ADD_BALANCE;
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.body.DialogBody;
|
||||
import io.papermc.paper.registry.data.dialog.input.DialogInput;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractDialog {
|
||||
|
||||
Dialog dialog;
|
||||
protected final int INV_SIZE = 54;
|
||||
UUID uuid;
|
||||
AbstractDialog lastDialog;
|
||||
List<ActionButton> actions = new ArrayList<>();
|
||||
List<DialogInput> inputs = new ArrayList<>();
|
||||
List<DialogBody> texts = new ArrayList<>();
|
||||
ActionButton closeButton;
|
||||
|
||||
AbstractDialog(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
this.lastDialog = null;
|
||||
closeButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Go back</gold>")).action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasLastGui()) {
|
||||
return;
|
||||
}
|
||||
lastDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
).build();
|
||||
}
|
||||
|
||||
abstract Dialog initDialog();
|
||||
|
||||
public void open() {
|
||||
if (dialog == null)
|
||||
return;
|
||||
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
// player.closeDialog();
|
||||
player.showDialog(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
void close() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
||||
|
||||
void initContents() {
|
||||
}
|
||||
|
||||
Player getPlayer() {
|
||||
return Bukkit.getPlayer(uuid);
|
||||
}
|
||||
|
||||
public void setLastGui(AbstractDialog lastDialog) {
|
||||
this.lastDialog = lastDialog;
|
||||
}
|
||||
|
||||
public boolean hasLastGui() {
|
||||
return this.lastDialog != null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.object.ObjectContents;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ListPlayersDialog extends AbstractDialog {
|
||||
|
||||
private final List<UUID> owners;
|
||||
|
||||
public ListPlayersDialog(UUID uuid) {
|
||||
super(uuid);
|
||||
this.owners = PlayerShops.getInstance().getShopHandler().getShopOwnersForThisServer();
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
Dialog initDialog() {
|
||||
if (getPlayer() == null) {
|
||||
return null;
|
||||
}
|
||||
initContents();
|
||||
|
||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
||||
dialogRegistryBuilderFactory.empty()
|
||||
.type(DialogType.multiAction(
|
||||
actions,
|
||||
closeButton,
|
||||
3)
|
||||
)
|
||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_PLAYERS_TITLE))
|
||||
.body(texts)
|
||||
.inputs(inputs)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initContents() {
|
||||
super.initContents();
|
||||
|
||||
for (UUID shopOwnerUUID : owners) {
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(shopOwnerUUID);
|
||||
String playerName;
|
||||
if (!offlinePlayer.hasPlayedBefore()) {
|
||||
playerName = "Unknown";
|
||||
} else {
|
||||
playerName = offlinePlayer.getName();
|
||||
}
|
||||
|
||||
actions.add(
|
||||
ActionButton.builder(
|
||||
Component.object(ObjectContents.playerHead(shopOwnerUUID)).append(Component.space().append(Component.text(playerName))))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ListShopsDialog listShopsDialog = new ListShopsDialog(uuid, shopOwnerUUID);
|
||||
listShopsDialog.setLastGui(this);
|
||||
listShopsDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
161
src/main/java/com/alttd/playershops/dialog/ListShopsDialog.java
Normal file
161
src/main/java/com/alttd/playershops/dialog/ListShopsDialog.java
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.body.DialogBody;
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ListShopsDialog extends AbstractDialog {
|
||||
|
||||
List<PlayerShop> shops;
|
||||
UUID playerToList;
|
||||
Component title;
|
||||
TagResolver placeholders;
|
||||
|
||||
public ListShopsDialog(UUID uuid, UUID playerToList) {
|
||||
super(uuid);
|
||||
this.playerToList = playerToList;
|
||||
this.shops = PlayerShops.getInstance().getShopHandler().getShops(this.playerToList);
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(this.playerToList);
|
||||
|
||||
placeholders = TagResolver.resolver(
|
||||
Placeholder.unparsed("playername", offlinePlayer.hasPlayedBefore() ? offlinePlayer.getName() : "Unknown")
|
||||
);
|
||||
title = MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_SHOPS_TITLE, placeholders);
|
||||
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
public ListShopsDialog(UUID uuid, List<PlayerShop> playerShops) {
|
||||
super(uuid);
|
||||
this.shops = playerShops;
|
||||
|
||||
placeholders = TagResolver.resolver(
|
||||
Placeholder.unparsed("material", "Unknown")
|
||||
);
|
||||
title = MiniMessage.miniMessage().deserialize("Shops per item");
|
||||
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
Dialog initDialog() {
|
||||
if (getPlayer() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
initContents();
|
||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
||||
dialogRegistryBuilderFactory.empty()
|
||||
.type(DialogType.multiAction(
|
||||
actions,
|
||||
closeButton,
|
||||
3)
|
||||
)
|
||||
.base(DialogBase.builder(title)
|
||||
.body(texts)
|
||||
.inputs(inputs)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initContents() {
|
||||
super.initContents();
|
||||
|
||||
texts.add(DialogBody.plainMessage(MiniMessage.miniMessage().deserialize("<gold>This menu will <red>not</red> display shops that are not initialized")));
|
||||
|
||||
for (PlayerShop shop : shops) {
|
||||
if (!shop.isInitialized()) {
|
||||
continue;
|
||||
}
|
||||
actions.add(
|
||||
ActionButton.builder(
|
||||
ShopUtil.spriteComponent(shop.getItemStack()))
|
||||
.tooltip(shop.getHoverComponent(getPlayer()))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ShopUtil.canManageShop(player, shop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), shop);
|
||||
manageShopDialog.setLastGui(this);
|
||||
manageShopDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
if (uuid != null && uuid.equals(playerToList) && getPlayer().hasPermission("playershops.shop.collectall")) {
|
||||
actions.add(
|
||||
ActionButton.builder(
|
||||
MiniMessage.miniMessage().deserialize("<gold>Collect sales</gold>"))
|
||||
.tooltip(MiniMessage.miniMessage().deserialize("<gold>Click to collect all balance from your shops.</gold>"))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
double d = 0;
|
||||
int count = 0;
|
||||
for (PlayerShop playerShop : shops) {
|
||||
if (!ShopUtil.canManageShop(player, playerShop))
|
||||
continue;
|
||||
|
||||
if (playerShop.getType().equals(ShopType.BUY))
|
||||
continue;
|
||||
|
||||
double balance = playerShop.getBalance();
|
||||
if (balance == 0)
|
||||
continue;
|
||||
|
||||
playerShop.removeBalance(balance);
|
||||
EconomyUtils.addFunds(player, balance);
|
||||
d += balance;
|
||||
count++;
|
||||
}
|
||||
TagResolver placeholders = TagResolver.resolver(
|
||||
Placeholder.parsed("balance", String.valueOf(d)),
|
||||
Placeholder.parsed("count", String.valueOf(count))
|
||||
);
|
||||
player.sendRichMessage(count > 0 ? "<green>You have collected <balance> from <count> shops." : "<red>No shops to be collected from.", placeholders);
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
214
src/main/java/com/alttd/playershops/dialog/ManageShopDialog.java
Normal file
214
src/main/java/com/alttd/playershops/dialog/ManageShopDialog.java
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.body.DialogBody;
|
||||
import io.papermc.paper.registry.data.dialog.input.DialogInput;
|
||||
import io.papermc.paper.registry.data.dialog.input.SingleOptionDialogInput;
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ManageShopDialog extends AbstractDialog {
|
||||
|
||||
PlayerShop shop;
|
||||
|
||||
public ManageShopDialog(UUID uuid, PlayerShop shop) {
|
||||
super(uuid);
|
||||
this.shop = shop;
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
Dialog initDialog() {
|
||||
if (getPlayer() == null) {
|
||||
return null;
|
||||
}
|
||||
initContents();
|
||||
|
||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
||||
dialogRegistryBuilderFactory.empty()
|
||||
.type(DialogType.multiAction(
|
||||
actions,
|
||||
closeButton,
|
||||
3)
|
||||
)
|
||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize("<gold>PlayerShop - <playername>", Placeholder.component("playername", getPlayer().displayName())))
|
||||
.body(texts)
|
||||
.inputs(inputs)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initContents() {
|
||||
super.initContents();
|
||||
|
||||
inputs.add(
|
||||
DialogInput.singleOption("shoptype", MiniMessage.miniMessage().deserialize("<gold>ShopType</gold>"),
|
||||
Arrays.stream(ShopType.values()).map(
|
||||
shopType -> SingleOptionDialogInput.OptionEntry.create(shopType.name(), MiniMessage.miniMessage().deserialize("<green>" + shopType.name()), shop.getType() == shopType)
|
||||
).toList())
|
||||
.build()
|
||||
);
|
||||
|
||||
inputs.add(
|
||||
DialogInput.text("balance", MiniMessage.miniMessage().deserialize("<gold>Balance</gold>"))
|
||||
.initial(String.valueOf(shop.getBalance()))
|
||||
.width(300)
|
||||
.build()
|
||||
);
|
||||
inputs.add(
|
||||
DialogInput.bool("changeitem", MiniMessage.miniMessage().deserialize("<gold>Change item?</gold>"))
|
||||
.initial(false)
|
||||
.build()
|
||||
);
|
||||
inputs.add(
|
||||
DialogInput.singleOption("item", MiniMessage.miniMessage().deserialize("<gold>Item</gold>"), itemEntries()).build()
|
||||
);
|
||||
int maxQty = (shop.isInitialized() && shop.getItemStack() != null ? shop.getItemStack().getMaxStackSize() : 64);
|
||||
int initialQty = (shop.isInitialized() ? Math.min(shop.getAmount(), maxQty) : 1);
|
||||
inputs.add(
|
||||
DialogInput.numberRange("amount", MiniMessage.miniMessage().deserialize("<gold>Change amount</gold>"), 1f, (float) maxQty)
|
||||
.step(1f)
|
||||
.initial((float) initialQty)
|
||||
.width(300)
|
||||
.build()
|
||||
);
|
||||
inputs.add(
|
||||
DialogInput.text("price", MiniMessage.miniMessage().deserialize("<gold>Change price</gold>"))
|
||||
.initial(String.valueOf(shop.getPrice()))
|
||||
.width(300)
|
||||
.build()
|
||||
);
|
||||
ActionButton saveButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Confirm</gold>")).action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ShopUtil.canManageShop(player, shop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Change type
|
||||
String shopTypeString = view.getText("shoptype");
|
||||
ShopType shopType = ShopType.fromString(shopTypeString);
|
||||
if (shop.getType() != shopType) {
|
||||
shop.setShopType(shopType);
|
||||
}
|
||||
|
||||
// Change Balance
|
||||
String balanceString = view.getText("balance");
|
||||
if (balanceString != null && !balanceString.isBlank()) {
|
||||
Double balance;
|
||||
try {
|
||||
balance = EconomyUtils.parseValue(balanceString);
|
||||
if (balance != null && balance >= 0) {
|
||||
if (balance != shop.getBalance()) {
|
||||
double difference = balance - shop.getBalance();
|
||||
if (difference >= 0) {
|
||||
if (EconomyUtils.hasSufficientFunds(player, difference)) {
|
||||
shop.addBalance(difference);
|
||||
EconomyUtils.removeFunds(player, difference);
|
||||
}
|
||||
} else if (difference <= 0) {
|
||||
double diff = -1 * difference;
|
||||
if (EconomyUtils.hasSufficientFunds(shop, diff)) {
|
||||
shop.removeBalance(diff);
|
||||
EconomyUtils.addFunds(player, diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
// Change Item
|
||||
if (Boolean.TRUE.equals(view.getBoolean("changeitem"))) {
|
||||
String selection = view.getText("item");
|
||||
if (selection != null) {
|
||||
if (selection.equalsIgnoreCase("reset")) {
|
||||
shop.setItemStack(null);
|
||||
} else {
|
||||
int slot;
|
||||
try {
|
||||
slot = Integer.parseInt(selection);
|
||||
shop.setItemStack(player.getInventory().getItem(slot));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change Amount
|
||||
int amount = view.getFloat("amount").intValue();
|
||||
if (amount != shop.getAmount()) {
|
||||
shop.setAmount(amount);
|
||||
}
|
||||
|
||||
// Change Price
|
||||
String priceString = view.getText("price");
|
||||
if (priceString != null && !priceString.isBlank()) {
|
||||
Double price = EconomyUtils.parseValue(priceString);
|
||||
if (price != null && price >= 0) {
|
||||
if (price != shop.getPrice()) {
|
||||
shop.setPrice(price);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
).build();
|
||||
actions.add(saveButton);
|
||||
}
|
||||
|
||||
List<SingleOptionDialogInput.OptionEntry> itemEntries() {
|
||||
List<SingleOptionDialogInput.OptionEntry> optionEntries = new ArrayList<>();
|
||||
|
||||
if (getPlayer() == null) {
|
||||
return optionEntries;
|
||||
}
|
||||
|
||||
optionEntries.add(
|
||||
SingleOptionDialogInput.OptionEntry.create("reset", MiniMessage.miniMessage().deserialize("<gold>Reset"), false)
|
||||
);
|
||||
|
||||
for (int i = 0; i < getPlayer().getInventory().getSize() ; i++) {
|
||||
ItemStack item = getPlayer().getInventory().getItem(i);
|
||||
if (item == null || item.getType() == Material.AIR) continue;
|
||||
ItemStack itemStack = item.clone();
|
||||
optionEntries.add(
|
||||
SingleOptionDialogInput.OptionEntry.create(String.valueOf(i), ShopUtil.spriteComponent(itemStack), shop.getItemStack() == itemStack)
|
||||
);
|
||||
}
|
||||
|
||||
return optionEntries;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SearchShopsDialog extends AbstractDialog {
|
||||
|
||||
List<PlayerShop> shops;
|
||||
|
||||
public SearchShopsDialog(UUID uuid) {
|
||||
super(uuid);
|
||||
// this.shops = PlayerShops.getInstance().getShopHandler().getShops(playerToList);
|
||||
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
Dialog initDialog() {
|
||||
if (getPlayer() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
initContents();
|
||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
||||
dialogRegistryBuilderFactory.empty()
|
||||
.type(DialogType.multiAction(
|
||||
actions,
|
||||
closeButton,
|
||||
5)
|
||||
)
|
||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_SHOPS_TITLE))
|
||||
.body(texts)
|
||||
.inputs(inputs)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initContents() {
|
||||
super.initContents();
|
||||
|
||||
for (Map.Entry<Material, List<PlayerShop>> entry : PlayerShops.getInstance().getShopHandler().shopByMaterial().entrySet()) {
|
||||
actions.add(ActionButton.builder(ShopUtil.spriteComponent(entry.getKey()))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ListShopsDialog listShopsDialog = new ListShopsDialog(uuid, entry.getValue());
|
||||
listShopsDialog.setLastGui(this);
|
||||
listShopsDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
128
src/main/java/com/alttd/playershops/dialog/ShopDialog.java
Normal file
128
src/main/java/com/alttd/playershops/dialog/ShopDialog.java
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ShopDialog extends AbstractDialog {
|
||||
|
||||
public ShopDialog(UUID uuid) {
|
||||
super(uuid);
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
Dialog initDialog() {
|
||||
if (getPlayer() == null) {
|
||||
return null;
|
||||
}
|
||||
initContents();
|
||||
|
||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
||||
dialogRegistryBuilderFactory.empty()
|
||||
.type(DialogType.multiAction(
|
||||
actions,
|
||||
closeButton,
|
||||
3)
|
||||
)
|
||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_HOME_TITLE))
|
||||
.body(texts)
|
||||
.inputs(inputs)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initContents() {
|
||||
super.initContents();
|
||||
|
||||
actions.add(
|
||||
ActionButton.builder(
|
||||
MiniMessage.miniMessage().deserialize("Your shops"))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ListShopsDialog abstractDialog = new ListShopsDialog(uuid, uuid);
|
||||
abstractDialog.setLastGui(this);
|
||||
abstractDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
actions.add(
|
||||
ActionButton.builder(
|
||||
MiniMessage.miniMessage().deserialize("All shops"))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ListPlayersDialog abstractDialog = new ListPlayersDialog(uuid);
|
||||
abstractDialog.setLastGui(this);
|
||||
abstractDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
actions.add(
|
||||
ActionButton.builder(
|
||||
MiniMessage.miniMessage().deserialize("Shops per item"))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SearchShopsDialog abstractDialog = new SearchShopsDialog(uuid);
|
||||
abstractDialog.setLastGui(this);
|
||||
abstractDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
/* actions.add(
|
||||
ActionButton.builder(
|
||||
MiniMessage.miniMessage().deserialize("Settings"))
|
||||
.action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ShopSettingsDialog abstractDialog = new ShopSettingsDialog(uuid);
|
||||
abstractDialog.setLastGui(this);
|
||||
abstractDialog.open();
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
)
|
||||
.build()
|
||||
);*/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package com.alttd.playershops.dialog;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerSettings;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
||||
import io.papermc.paper.registry.data.dialog.input.DialogInput;
|
||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ShopSettingsDialog extends AbstractDialog {
|
||||
|
||||
PlayerSettings playerSettings;
|
||||
public ShopSettingsDialog(UUID uuid) {
|
||||
super(uuid);
|
||||
playerSettings = PlayerShops.getInstance().getShopHandler().getPlayerSettings(uuid);
|
||||
dialog = initDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
Dialog initDialog() {
|
||||
if (getPlayer() == null) {
|
||||
return null;
|
||||
}
|
||||
initContents();
|
||||
|
||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
||||
dialogRegistryBuilderFactory.empty()
|
||||
.type(DialogType.multiAction(
|
||||
actions,
|
||||
closeButton,
|
||||
1)
|
||||
)
|
||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_PLAYER_SETTINGS_TITLE))
|
||||
.body(texts)
|
||||
.inputs(inputs)
|
||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initContents() {
|
||||
super.initContents();
|
||||
|
||||
for(Object2BooleanMap.Entry<PlayerSettings.Option> entry : playerSettings.optionsMap.object2BooleanEntrySet()) {
|
||||
String setting = entry.getKey().name();
|
||||
System.out.println(setting);
|
||||
inputs.add(
|
||||
DialogInput.bool(setting, MiniMessage.miniMessage().deserialize("<gold>" + entry.getKey().toString() + "</gold>"))
|
||||
.initial(playerSettings.getOption(entry.getKey()))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
actions.add(
|
||||
ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Confirm</gold>")).action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if (Boolean.TRUE.equals(view.getBoolean("changeitem"))) {
|
||||
//
|
||||
// }
|
||||
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
).build()
|
||||
);
|
||||
actions.add(
|
||||
ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Set shop default values</gold>")).action(
|
||||
DialogAction.customClick((view, audience) -> {
|
||||
if (!(audience instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
}, ClickCallback.Options.builder()
|
||||
.lifetime(Duration.ofMinutes(5))
|
||||
.uses(-1)
|
||||
.build())
|
||||
).build()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractGui implements InventoryHolder {
|
||||
|
||||
Inventory inventory;
|
||||
protected final int INV_SIZE = 54;
|
||||
int currentSlot;
|
||||
UUID uuid;
|
||||
int pageIndex;
|
||||
AbstractGui lastGui;
|
||||
|
||||
|
||||
AbstractGui(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
this.currentSlot = 0;
|
||||
this.lastGui = null;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
}
|
||||
|
||||
boolean close() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
player.closeInventory();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void scrollPageNext() {
|
||||
ItemStack nextPageIcon = inventory.getItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot());
|
||||
if (nextPageIcon != null && nextPageIcon.equals(getNextPageIcon())) {
|
||||
inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), getPrevPageIcon());
|
||||
++pageIndex;
|
||||
initInvContents();
|
||||
}
|
||||
}
|
||||
|
||||
void scrollPagePrev() {
|
||||
ItemStack prevPageIcon = inventory.getItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot());
|
||||
if (prevPageIcon != null && prevPageIcon.equals(getPrevPageIcon())) {
|
||||
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), getNextPageIcon());
|
||||
--pageIndex;
|
||||
if (pageIndex == 0) {
|
||||
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), null);
|
||||
}
|
||||
initInvContents();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean addItem(int slot, ItemStack icon) {
|
||||
currentSlot = slot;
|
||||
return addItem(icon);
|
||||
}
|
||||
|
||||
protected boolean addItem(ItemStack icon) {
|
||||
if (currentSlot == inventory.getSize() - 9)
|
||||
return false;
|
||||
|
||||
inventory.setItem(currentSlot, icon);
|
||||
currentSlot++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void initInvContents() {
|
||||
clearInvBody();
|
||||
currentSlot = 0;
|
||||
}
|
||||
|
||||
protected void clearInvBody() {
|
||||
for (int i = 0; i < inventory.getSize() - 9; ++i) {
|
||||
// inventory.setItem(i, null);
|
||||
inventory.setItem(i, getDivider());
|
||||
}
|
||||
}
|
||||
|
||||
void makeMenuBar() {
|
||||
for (int i = inventory.getSize() - 9; i < inventory.getSize(); ++i) {
|
||||
inventory.setItem(i, getDivider());
|
||||
}
|
||||
}
|
||||
|
||||
Player getPlayer() {
|
||||
return Bukkit.getPlayer(uuid);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
ItemStack getPrevPageIcon() {
|
||||
return GuiIcon.MENUBAR_PREV_PAGE.getItemStack();
|
||||
}
|
||||
|
||||
ItemStack getNextPageIcon() {
|
||||
return GuiIcon.MENUBAR_NEXT_PAGE.getItemStack();
|
||||
}
|
||||
|
||||
ItemStack getExitIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack getDivider() {
|
||||
return GuiIcon.DIVIDER.getItemStack();
|
||||
}
|
||||
|
||||
public void onClick(int slot, ItemStack item) {
|
||||
// TODO a better way to do this.
|
||||
// check all menu actions here
|
||||
if (slot == GuiIcon.MENUBAR_BACK.getSlot() && GuiIcon.MENUBAR_BACK.getItemStack().equals(item)) {
|
||||
if (hasLastGui())
|
||||
lastGui.open();
|
||||
} else if (slot == GuiIcon.MENUBAR_EXIT.getSlot() && GuiIcon.MENUBAR_EXIT.getItemStack().equals(item)) {
|
||||
getPlayer().closeInventory();
|
||||
} else if (slot == GuiIcon.MENUBAR_SEARCH.getSlot() && GuiIcon.MENUBAR_SEARCH.getItemStack().equals(item)) {
|
||||
// TODO
|
||||
} else if (slot == GuiIcon.MENUBAR_PREV_PAGE.getSlot() && GuiIcon.MENUBAR_PREV_PAGE.getItemStack().equals(item)) {
|
||||
scrollPagePrev();
|
||||
} else if (slot == GuiIcon.MENUBAR_NEXT_PAGE.getSlot() && GuiIcon.MENUBAR_NEXT_PAGE.getItemStack().equals(item)) {
|
||||
scrollPageNext();
|
||||
}
|
||||
}
|
||||
|
||||
public void setLastGui(AbstractGui lastGui) {
|
||||
this.lastGui = lastGui;
|
||||
inventory.setItem(GuiIcon.MENUBAR_BACK.getSlot(), GuiIcon.MENUBAR_BACK.getItemStack());
|
||||
}
|
||||
|
||||
public boolean hasLastGui() {
|
||||
return lastGui != null;
|
||||
}
|
||||
|
||||
void addPrevPageItem() {
|
||||
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), GuiIcon.MENUBAR_PREV_PAGE.getItemStack());
|
||||
}
|
||||
|
||||
void addNextPageItem() {
|
||||
inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), GuiIcon.MENUBAR_NEXT_PAGE.getItemStack());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.config.GuiIconConfig;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public enum GuiIcon {
|
||||
DIVIDER,
|
||||
MENUBAR_BACK,
|
||||
MENUBAR_EXIT,
|
||||
MENUBAR_SEARCH,
|
||||
MENUBAR_PREV_PAGE,
|
||||
MENUBAR_NEXT_PAGE,
|
||||
|
||||
MANAGE_SHOP,
|
||||
MANAGE_SHOP_BALANCE_ADD,
|
||||
MANAGE_SHOP_BALANCE_REMOVE,
|
||||
MANAGE_SHOP_SALES,
|
||||
MANAGE_SHOP_ITEM,
|
||||
MANAGE_SHOP_TYPE,
|
||||
MANAGE_SHOP_AMOUNT,
|
||||
MANAGE_SHOP_PRICE,
|
||||
MANAGE_SHOP_COLLECT_SALES,
|
||||
MANAGE_SHOP_COLLECT_SALE,
|
||||
|
||||
HOME_LIST_OWN_SHOPS,
|
||||
HOME_LIST_PLAYERS,
|
||||
HOME_SETTINGS,
|
||||
LIST_SHOP,
|
||||
LIST_PLAYER,
|
||||
LIST_PLAYER_ADMIN,
|
||||
EMPTY_SHOP,
|
||||
|
||||
SETTING_ON,
|
||||
SETTING_OFF;
|
||||
|
||||
@Getter
|
||||
private final int slot;
|
||||
@Getter
|
||||
private final ItemStack itemStack;
|
||||
|
||||
GuiIcon() {
|
||||
GuiIconConfig config = new GuiIconConfig(this.toString());
|
||||
this.slot = config.slot;
|
||||
this.itemStack = createItem(config.material, config.displayName, config.lore);
|
||||
}
|
||||
|
||||
private ItemStack createItem(String materialString, String displayName, List<String> itemlore) {
|
||||
Material material = Material.getMaterial(materialString);
|
||||
if (material == null)
|
||||
return null;
|
||||
|
||||
ItemStack item = new ItemStack(material);
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
|
||||
itemMeta.displayName(format(displayName));
|
||||
List<Component> lore = new ArrayList<>();
|
||||
for (String line : itemlore) {
|
||||
lore.add(format(line));
|
||||
}
|
||||
itemMeta.lore(lore);
|
||||
item.setItemMeta(itemMeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private Component format(String s) {
|
||||
return Util.parseMiniMessage(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class HomeGui extends AbstractGui {
|
||||
|
||||
public HomeGui(UUID uuid) {
|
||||
super(uuid);
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_HOME_TITLE));
|
||||
makeMenuBar();
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
super.initInvContents();
|
||||
inventory.setItem(GuiIcon.HOME_LIST_OWN_SHOPS.getSlot(), GuiIcon.HOME_LIST_OWN_SHOPS.getItemStack());
|
||||
inventory.setItem(GuiIcon.HOME_LIST_PLAYERS.getSlot(), GuiIcon.HOME_LIST_PLAYERS.getItemStack());
|
||||
inventory.setItem(GuiIcon.HOME_SETTINGS.getSlot(), GuiIcon.HOME_SETTINGS.getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(int slot, ItemStack item) {
|
||||
super.onClick(slot, item);
|
||||
|
||||
if (slot >= 45)
|
||||
return;
|
||||
|
||||
if (slot == GuiIcon.HOME_LIST_OWN_SHOPS.getSlot() && GuiIcon.HOME_LIST_OWN_SHOPS.getItemStack().equals(item)) {
|
||||
ListShopsGui listShopsGui = new ListShopsGui(uuid, uuid);
|
||||
listShopsGui.setLastGui(this);
|
||||
listShopsGui.open();
|
||||
} else if (slot == GuiIcon.HOME_LIST_PLAYERS.getSlot() && GuiIcon.HOME_LIST_PLAYERS.getItemStack().equals(item)) {
|
||||
ListPlayersGui listPlayersGui = new ListPlayersGui(uuid);
|
||||
listPlayersGui.setLastGui(this);
|
||||
listPlayersGui.open();
|
||||
}/* else if (slot == GuiIcon.HOME_SETTINGS.getSlot() && GuiIcon.HOME_SETTINGS.getItemStack().equals(item)) {
|
||||
PlayerSettingsGui playerSettingsGui = new PlayerSettingsGui(uuid);
|
||||
playerSettingsGui.setLastGui(this);
|
||||
playerSettingsGui.open();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ListPlayersGui extends AbstractGui {
|
||||
|
||||
private final List<UUID> owners;
|
||||
public ListPlayersGui(UUID uuid) {
|
||||
super(uuid);
|
||||
this.owners = PlayerShops.getInstance().getShopHandler().getShopOwnersForThisServer();
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_PLAYERS_TITLE));
|
||||
makeMenuBar();
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
super.initInvContents();
|
||||
|
||||
int startIndex = pageIndex * 45;
|
||||
ItemStack item;
|
||||
for (int i = startIndex; i < owners.size(); i++) {
|
||||
item = ShopUtil.getPlayerHead(owners.get(i));
|
||||
|
||||
if (!addItem(item)) {
|
||||
addNextPageItem();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pageIndex > 0) {
|
||||
addPrevPageItem();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(int slot, ItemStack item) {
|
||||
super.onClick(slot, item);
|
||||
|
||||
if (slot >= 45)
|
||||
return;
|
||||
|
||||
if (item.getType() != Material.PLAYER_HEAD)
|
||||
return;
|
||||
|
||||
int index = pageIndex * 45 + slot;
|
||||
if (index >= owners.size())
|
||||
return;
|
||||
UUID playerToList = owners.get(index);
|
||||
|
||||
ListShopsGui listShopGUI = new ListShopsGui(uuid, playerToList);
|
||||
listShopGUI.setLastGui(this);
|
||||
listShopGUI.open();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ListShopsGui extends AbstractGui {
|
||||
|
||||
List<PlayerShop> shops;
|
||||
UUID playerToList;
|
||||
|
||||
public ListShopsGui(UUID uuid, UUID playerToList) {
|
||||
super(uuid);
|
||||
this.playerToList = playerToList;
|
||||
this.shops = PlayerShops.getInstance().getShopHandler().getShops(playerToList);
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerToList);
|
||||
|
||||
TagResolver placeholders = TagResolver.resolver(
|
||||
Placeholder.unparsed("playername", offlinePlayer.hasPlayedBefore() ? offlinePlayer.getName() : "error")
|
||||
);
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_SHOPS_TITLE, placeholders));
|
||||
makeMenuBar();
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void makeMenuBar() {
|
||||
super.makeMenuBar();
|
||||
if (!uuid.equals(playerToList) && getPlayer().hasPermission("playershops.shop.collectall"))
|
||||
return;
|
||||
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_COLLECT_SALES.getSlot(), GuiIcon.MANAGE_SHOP_COLLECT_SALES.getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
super.initInvContents();
|
||||
|
||||
// Todo add option to sort shops?
|
||||
|
||||
int startIndex = pageIndex * 45;
|
||||
for (int i = startIndex; i < shops.size(); i++) {
|
||||
PlayerShop shop = shops.get(i);
|
||||
ItemStack item = shop.getItemStack();
|
||||
if (!shop.isInitialized() || item == null)
|
||||
item = GuiIcon.EMPTY_SHOP.getItemStack();
|
||||
|
||||
if (!addItem(item)) {
|
||||
addNextPageItem();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pageIndex > 0) {
|
||||
addPrevPageItem();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(int slot, ItemStack item) {
|
||||
super.onClick(slot, item);
|
||||
|
||||
if (slot == GuiIcon.MANAGE_SHOP_COLLECT_SALES.getSlot() && GuiIcon.MANAGE_SHOP_COLLECT_SALES.getItemStack().equals(item)) {
|
||||
Player player = getPlayer();
|
||||
double d = 0;
|
||||
int count = 0;
|
||||
for (PlayerShop playerShop : shops) {
|
||||
if (!ShopUtil.canManageShop(player, playerShop))
|
||||
continue;
|
||||
if (playerShop.getType().equals(ShopType.BUY))
|
||||
continue;
|
||||
|
||||
double balance = playerShop.getBalance();
|
||||
if (balance == 0)
|
||||
continue;
|
||||
playerShop.removeBalance(balance);
|
||||
EconomyUtils.addFunds(player, balance);
|
||||
d += balance;
|
||||
count++;
|
||||
}
|
||||
TagResolver placeholders = TagResolver.resolver(
|
||||
Placeholder.parsed("balance", String.valueOf(d)),
|
||||
Placeholder.parsed("count", String.valueOf(count))
|
||||
);
|
||||
player.sendRichMessage(count > 0 ? "<green>You have collected <balance> from <count> shops." : "<red>No shops to be collected from.", placeholders);
|
||||
return;
|
||||
}
|
||||
|
||||
if (slot >= 45)
|
||||
return;
|
||||
|
||||
Player player = getPlayer();
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
int index = pageIndex * 45 + slot;
|
||||
if (index >= shops.size())
|
||||
return;
|
||||
|
||||
PlayerShop playerShop = shops.get(index);
|
||||
if (playerShop == null) return;
|
||||
|
||||
if (!ShopUtil.canManageShop(player, playerShop))
|
||||
return;
|
||||
|
||||
ShopManagementGui shopManagementGui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||
shopManagementGui.setLastGui(this);
|
||||
shopManagementGui.open();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopTransaction;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ListTransactionsGui extends AbstractGui {
|
||||
|
||||
private final List<ShopTransaction> transactions;
|
||||
public ListTransactionsGui(UUID uuid, PlayerShop shop) {
|
||||
super(uuid);
|
||||
this.transactions = shop.getTransactions();
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_TRANSACTIONS_TITLE));
|
||||
makeMenuBar();
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
super.initInvContents();
|
||||
|
||||
int startIndex = pageIndex * 45;
|
||||
ItemStack item;
|
||||
for (int i = startIndex; i < transactions.size(); i++) {
|
||||
item = ShopUtil.getShopTransactionItem(transactions.get(i));
|
||||
|
||||
if (!addItem(item)) {
|
||||
addNextPageItem();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pageIndex > 0) {
|
||||
addPrevPageItem();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.shop.PlayerSettings;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||
import net.kyori.adventure.text.TextReplacementConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerSettingsGui extends AbstractGui {
|
||||
|
||||
public PlayerSettingsGui(UUID uuid) {
|
||||
super(uuid);
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_PLAYER_SETTINGS_TITLE));
|
||||
makeMenuBar();
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
super.initInvContents();
|
||||
int startIndex = pageIndex * 45;
|
||||
ItemStack item;
|
||||
|
||||
for(Object2BooleanMap.Entry<PlayerSettings.Option> entry : PlayerShops.getInstance().getShopHandler().getPlayerSettings(uuid).optionsMap.object2BooleanEntrySet()) {
|
||||
item = entry.getBooleanValue() ? GuiIcon.SETTING_ON.getItemStack() : GuiIcon.SETTING_OFF.getItemStack();
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
itemMeta.displayName(
|
||||
itemMeta.displayName().replaceText(
|
||||
TextReplacementConfig.builder()
|
||||
.match("<setting>")
|
||||
.replacement(entry.getKey().toString().toLowerCase().replace("_", " ")).build()));
|
||||
}
|
||||
item.setItemMeta(itemMeta);
|
||||
|
||||
if (!addItem(item)) {
|
||||
addNextPageItem();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pageIndex > 0) {
|
||||
addPrevPageItem();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(int slot, ItemStack item) {
|
||||
super.onClick(slot, item);
|
||||
|
||||
if (slot >= 45)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.conversation.ConversationManager;
|
||||
import com.alttd.playershops.conversation.ConversationType;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ShopManagementGui extends AbstractGui {
|
||||
|
||||
PlayerShop shop;
|
||||
|
||||
public ShopManagementGui(UUID uuid, PlayerShop shop) {
|
||||
super(uuid);
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_MANAGE_TITLE));
|
||||
this.shop = shop;
|
||||
makeMenuBar();
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
super.initInvContents();
|
||||
|
||||
ItemStack shopIcon = GuiIcon.MANAGE_SHOP.getItemStack();
|
||||
ItemMeta meta = shopIcon.getItemMeta();
|
||||
List<Component> lore = new ArrayList<>();
|
||||
TagResolver placeholders = TagResolver.resolver(
|
||||
Placeholder.unparsed("balance", shop.getBalance() + ""),
|
||||
Placeholder.unparsed("price", shop.getPrice() + ""),
|
||||
Placeholder.unparsed("amount", shop.getAmount() + ""),
|
||||
Placeholder.unparsed("shoptype", shop.getType().toString()),
|
||||
Placeholder.component("itemname", ShopUtil.itemNameComponent(shop.getItemStack()))
|
||||
);
|
||||
lore.add(Util.parseMiniMessage("Balance: <balance>", placeholders));
|
||||
lore.add(Util.parseMiniMessage("item: <itemname>", placeholders));
|
||||
lore.add(Util.parseMiniMessage("amount: <amount>", placeholders));
|
||||
lore.add(Util.parseMiniMessage("Type: <shoptype>", placeholders));
|
||||
lore.add(Util.parseMiniMessage("Price: <price>", placeholders));
|
||||
|
||||
meta.lore(lore);
|
||||
shopIcon.setItemMeta(meta);
|
||||
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP.getSlot(), shopIcon);
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_COLLECT_SALE.getSlot(), GuiIcon.MANAGE_SHOP_COLLECT_SALE.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_SALES.getSlot(), GuiIcon.MANAGE_SHOP_SALES.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_ITEM.getSlot(), GuiIcon.MANAGE_SHOP_ITEM.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_TYPE.getSlot(), GuiIcon.MANAGE_SHOP_TYPE.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_AMOUNT.getSlot(), GuiIcon.MANAGE_SHOP_AMOUNT.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_PRICE.getSlot(), GuiIcon.MANAGE_SHOP_PRICE.getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
void makeMenuBar() {
|
||||
super.makeMenuBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(int slot, ItemStack item) {
|
||||
super.onClick(slot, item);
|
||||
|
||||
if (slot == GuiIcon.MANAGE_SHOP_COLLECT_SALE.getSlot() && GuiIcon.MANAGE_SHOP_COLLECT_SALE.getItemStack().equals(item)) {
|
||||
Player player = getPlayer();
|
||||
double d = 0;
|
||||
int count = 0;
|
||||
if (!ShopUtil.canManageShop(player, this.shop))
|
||||
return;
|
||||
if (this.shop.getType().equals(ShopType.BUY))
|
||||
return;
|
||||
|
||||
double balance = this.shop.getBalance();
|
||||
if (balance == 0)
|
||||
return;
|
||||
|
||||
this.shop.removeBalance(balance);
|
||||
EconomyUtils.addFunds(player, balance);
|
||||
d += balance;
|
||||
count++;
|
||||
TagResolver placeholders = TagResolver.resolver(
|
||||
Placeholder.parsed("balance", String.valueOf(d)),
|
||||
Placeholder.parsed("count", String.valueOf(count))
|
||||
);
|
||||
player.sendRichMessage("<green>You have collected <balance> from <count> shops.", placeholders);
|
||||
return;
|
||||
}
|
||||
|
||||
if (slot >= 45)
|
||||
return;
|
||||
|
||||
if (slot == GuiIcon.MANAGE_SHOP.getSlot() && GuiIcon.MANAGE_SHOP.getItemStack().equals(item)) {
|
||||
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot() && GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack().equals(item)) {
|
||||
if (EconomyUtils.getFunds(getPlayer()) > 0) {
|
||||
openChangePrompt(ConversationType.ADD_BALANCE);
|
||||
} else {
|
||||
getPlayer().sendRichMessage("<red>You do not have money to add to this shop");
|
||||
}
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot() && GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack().equals(item)) {
|
||||
if (shop.getBalance() > 0) {
|
||||
openChangePrompt(ConversationType.WITHDRAW_BALANCE);
|
||||
} else {
|
||||
getPlayer().sendRichMessage("<red>You can't withdraw money from this shop");
|
||||
}
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_SALES.getSlot() && GuiIcon.MANAGE_SHOP_SALES.getItemStack().equals(item)) {
|
||||
ListTransactionsGui listTransactionsGui = new ListTransactionsGui(uuid, shop);
|
||||
listTransactionsGui.setLastGui(this);
|
||||
listTransactionsGui.open();
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_ITEM.getSlot() && GuiIcon.MANAGE_SHOP_ITEM.getItemStack().equals(item)) {
|
||||
openChangePrompt(ConversationType.CHANGE_ITEM);
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_TYPE.getSlot() && GuiIcon.MANAGE_SHOP_TYPE.getItemStack().equals(item)) {
|
||||
openChangePrompt(ConversationType.CHANGE_TYPE);
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_AMOUNT.getSlot() && GuiIcon.MANAGE_SHOP_AMOUNT.getItemStack().equals(item)) {
|
||||
openChangePrompt(ConversationType.CHANGE_AMOUNT);
|
||||
} else if (slot == GuiIcon.MANAGE_SHOP_PRICE.getSlot() && GuiIcon.MANAGE_SHOP_PRICE.getItemStack().equals(item)) {
|
||||
openChangePrompt(ConversationType.CHANGE_PRICE);
|
||||
}
|
||||
}
|
||||
|
||||
private void openChangePrompt(ConversationType conversationType) {
|
||||
Player player = getPlayer();
|
||||
player.closeInventory();
|
||||
new ConversationManager(PlayerShops.getInstance(), player, conversationType, shop);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,14 +6,18 @@ import com.alttd.playershops.shop.PlayerSettings;
|
|||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.storage.database.DatabaseHelper;
|
||||
import com.alttd.playershops.utils.Logger;
|
||||
import com.alttd.playershops.utils.Pair;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
|
|
@ -178,4 +182,47 @@ public class ShopHandler {
|
|||
return playerSettings.computeIfAbsent(uuid, PlayerSettings::loadFromFile);
|
||||
}
|
||||
|
||||
public void transferShops(CommandSender sender, OfflinePlayer oldOwner, OfflinePlayer newOwner) {
|
||||
if (!oldOwner.hasPlayedBefore()) {
|
||||
sender.sendRichMessage("<red>" + oldOwner.getName() + " has not joined this server before.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newOwner.hasPlayedBefore()) {
|
||||
sender.sendRichMessage("<red>" + newOwner.getName() + " has not joined this server before.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<PlayerShop> playerShops = PlayerShops.getInstance().getShopHandler().getShops(oldOwner.getUniqueId());
|
||||
sender.sendRichMessage("<red>Starting the transfer process now, this might lag the server.");
|
||||
for (PlayerShop playerShop : playerShops) {
|
||||
playerShop.setOwner(newOwner);
|
||||
}
|
||||
if (newOwner.isOnline() && newOwner.getPlayer() != null) {
|
||||
newOwner.getPlayer().sendRichMessage(playerShops.size() + " have been transferred to you.");
|
||||
}
|
||||
sender.sendRichMessage(playerShops.size() + " from " + oldOwner.getName() + " have been transferred to " + newOwner.getName() + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* On demand calculation of shops per material
|
||||
*
|
||||
* @return TreeMap containing a list of PlayerShops per material.
|
||||
*/
|
||||
public TreeMap<Material, List<PlayerShop>> shopByMaterial() {
|
||||
// TODO -- make this a cache. update cache on change, do not calc dynamicly
|
||||
TreeMap<Material, List<PlayerShop>> shopByMaterialTreeSet = new TreeMap<>();
|
||||
|
||||
for (PlayerShop shop : getShops()) {
|
||||
if (!shop.isInitialized()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Material material = shop.getItemStack().getType();
|
||||
List<PlayerShop> shopList = shopByMaterialTreeSet.computeIfAbsent(material, v -> new ArrayList<>());
|
||||
shopList.add(shop);
|
||||
}
|
||||
|
||||
return shopByMaterialTreeSet;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
package com.alttd.playershops.listener;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.gui.AbstractGui;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class InventoryListener extends EventListener {
|
||||
|
||||
private final PlayerShops plugin;
|
||||
public InventoryListener(PlayerShops plugin) {
|
||||
this.plugin = plugin;
|
||||
this.register(this.plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClickEvent(InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player player))
|
||||
return;
|
||||
|
||||
if (!(event.getView().getTopInventory().getHolder() instanceof AbstractGui gui))
|
||||
return;
|
||||
|
||||
if ((event.getView().getBottomInventory().equals(event.getClickedInventory())))
|
||||
return;
|
||||
|
||||
if (event.getClick() == ClickType.NUMBER_KEY) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack clicked = event.getCurrentItem();
|
||||
if (!(clicked != null && clicked.getType() != Material.AIR))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
gui.onClick(event.getRawSlot(), clicked);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package com.alttd.playershops.listener;
|
|||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
import com.alttd.playershops.gui.ShopManagementGui;
|
||||
import com.alttd.playershops.dialog.ManageShopDialog;
|
||||
import com.alttd.playershops.handler.ShopHandler;
|
||||
import com.alttd.playershops.hook.WorldGuardHook;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
|
|
@ -92,8 +92,10 @@ public class TransactionListener extends EventListener {
|
|||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||
gui.open();
|
||||
// ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||
// gui.open();
|
||||
ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), playerShop);
|
||||
manageShopDialog.open();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@ import java.util.UUID;
|
|||
public class PlayerSettings {
|
||||
public enum Option {
|
||||
SALE_OWNER_NOTIFICATIONS, SALE_USER_NOTIFICATIONS,
|
||||
STOCK_NOTIFICATIONS, DISCORD_STOCK_NOTIFICATIONS
|
||||
STOCK_NOTIFICATIONS, DISCORD_STOCK_NOTIFICATIONS;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name().toLowerCase().replace("_", " ");
|
||||
}
|
||||
}
|
||||
|
||||
private final UUID uuid;
|
||||
|
|
|
|||
|
|
@ -3,18 +3,25 @@ package com.alttd.playershops.shop;
|
|||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.events.*;
|
||||
import com.alttd.playershops.utils.*;
|
||||
import com.alttd.playershops.utils.sprite.MaterialSprites;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
|
|
@ -30,8 +37,8 @@ public class PlayerShop {
|
|||
private final Location signLocation;
|
||||
private final Location shopLocation;
|
||||
private String server;
|
||||
private double price;
|
||||
private int amount;
|
||||
private double price = 0;
|
||||
private int amount = 1;
|
||||
private double balance;
|
||||
private ItemStack itemStack;
|
||||
@Setter
|
||||
|
|
@ -109,7 +116,7 @@ public class PlayerShop {
|
|||
}
|
||||
|
||||
public boolean matches(ItemStack item) {
|
||||
return ShopUtil.matches(getItemStack(), item);
|
||||
return ItemMatcher.matches(getItemStack(), item);
|
||||
}
|
||||
|
||||
public void remove(ItemStack item, int amount) {
|
||||
|
|
@ -134,7 +141,7 @@ public class PlayerShop {
|
|||
}
|
||||
}
|
||||
|
||||
public void setOwner(Player player) {
|
||||
public void setOwner(OfflinePlayer player) {
|
||||
ownerUUID = player.getUniqueId();
|
||||
ownerName = player.getName();
|
||||
update();
|
||||
|
|
@ -171,14 +178,15 @@ public class PlayerShop {
|
|||
public void run() {
|
||||
if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return;
|
||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
Component itemComponent = getItemStack() == null ? ShopUtil.trimmedItemNameComponent(getItemStack()): MaterialSprites.get(getItemStack().getType()).append(Component.space()).append(ShopUtil.trimmedItemNameComponent(getItemStack()));
|
||||
TagResolver tagResolver = TagResolver.resolver(
|
||||
Placeholder.unparsed("ownername", getOwnerName()),
|
||||
Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))),
|
||||
Placeholder.unparsed("amount", String.valueOf(getAmount())),
|
||||
Placeholder.component("itemname", ShopUtil.trimmedItemNameComponent(getItemStack()))
|
||||
Placeholder.component("itemname", itemComponent)
|
||||
);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
signBlock.line(i, miniMessage.deserialize(signLines.get(i), tagResolver));
|
||||
signBlock.getSide(Side.FRONT).line(i, miniMessage.deserialize(signLines.get(i), tagResolver));
|
||||
}
|
||||
signBlock.update(true);
|
||||
}
|
||||
|
|
@ -360,8 +368,12 @@ public class PlayerShop {
|
|||
if (Util.callCancellableEvent(shopItemChangeEvent))
|
||||
return; // cancelled by another plugin, does this need logging?
|
||||
|
||||
this.itemStack = itemStack;
|
||||
this.itemStack.setAmount(this.amount != 0 ? this.amount : 1);
|
||||
if (itemStack == null) {
|
||||
this.itemStack = null;
|
||||
} else {
|
||||
this.itemStack = itemStack.clone();
|
||||
this.itemStack.setAmount(this.amount != 0 ? this.amount : 1);
|
||||
}
|
||||
setDirty(true);
|
||||
update();
|
||||
}
|
||||
|
|
@ -451,4 +463,25 @@ public class PlayerShop {
|
|||
+ " balance :" + this.balance
|
||||
+ " lastTransaction :" + this.lastTransaction;
|
||||
}
|
||||
|
||||
public Component getHoverComponent(Player player) {
|
||||
Component component = ShopUtil.itemNameComponent(getItemStack())
|
||||
.append(Component.newline())
|
||||
.append(Component.newline())
|
||||
.append(Component.text("ShopType: " + type))
|
||||
.append(Component.newline())
|
||||
.append(Component.text("Price: " + price))
|
||||
.append(Component.newline())
|
||||
.append(Component.text("ShopType: " + amount))
|
||||
.append(Component.newline())
|
||||
.append(Component.text("World: " + shopLocation.getWorld().getName()))
|
||||
.append(Component.newline())
|
||||
.append(Component.text("Coordinates: " + shopLocation.getBlockX() + ", " + shopLocation.getBlockY() + ", " + shopLocation.getBlockZ()))
|
||||
;
|
||||
if (getOwnerUUID().equals(player.getUniqueId())) {
|
||||
component = component.append(Component.newline()).append(Component.text("Balance: " + balance));
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,4 +65,37 @@ public class EconomyUtils {
|
|||
return bd.doubleValue();
|
||||
}
|
||||
|
||||
public static Double parseValue(String input) {
|
||||
Double value = null;
|
||||
if (input == null || input.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
value = Double.parseDouble(input);
|
||||
} catch (NumberFormatException ex) {
|
||||
Double multiplier = multiplierValue(input.substring(input.length() - 1));
|
||||
if (multiplier == null) {
|
||||
multiplier = 1.0;
|
||||
}
|
||||
try {
|
||||
value = Double.parseDouble(input.substring(0, input.length() - 1));
|
||||
} catch (NumberFormatException ignored) {}
|
||||
if (value != null) {
|
||||
value = value * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static Double multiplierValue(String input) {
|
||||
Double value = null;
|
||||
switch(input.toLowerCase()) {
|
||||
case "k" -> value = 1000.0;
|
||||
case "m" -> value = 1000000.0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class InventoryUtils {
|
|||
for (ItemStack iStack : inv.getContents()) {
|
||||
if (iStack == null)
|
||||
continue;
|
||||
if (ShopUtil.matches(item, iStack)) {
|
||||
if (ItemMatcher.matches(item, iStack)) {
|
||||
items += iStack.getAmount();
|
||||
}
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ public class InventoryUtils {
|
|||
int amount = itemStack.getAmount();
|
||||
for (ItemStack stack : contents) {
|
||||
if (stack != null) {
|
||||
if (ShopUtil.matches(stack, itemStack)) {
|
||||
if (ItemMatcher.matches(stack, itemStack)) {
|
||||
if (stack.getAmount() > amount) {
|
||||
stack.setAmount(stack.getAmount() - amount);
|
||||
inventory.setContents(contents);
|
||||
|
|
|
|||
335
src/main/java/com/alttd/playershops/utils/ItemMatcher.java
Normal file
335
src/main/java/com/alttd/playershops/utils/ItemMatcher.java
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
package com.alttd.playershops.utils;
|
||||
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.ShulkerBox;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ItemMatcher {
|
||||
|
||||
private final static List<Matcher> matcherList = new ArrayList<>();
|
||||
|
||||
static {
|
||||
// DisplayName
|
||||
matcherList.add(
|
||||
(meta1, meta2) ->
|
||||
Objects.equals(meta1.displayName(), meta2.displayName())
|
||||
);
|
||||
// Damage
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof Damageable damageable1 && meta2 instanceof Damageable damageable2) {
|
||||
return damageable1.getDamage() == damageable2.getDamage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Enchants
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1.hasEnchants() != meta2.hasEnchants()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (meta1.hasEnchants()) {
|
||||
final Map<Enchantment, Integer> enchants1 = meta1.getEnchants();
|
||||
final Map<Enchantment, Integer> enchants2 = meta2.getEnchants();
|
||||
return listMatches(enchants1.entrySet(), enchants2.entrySet());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Potions
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof PotionMeta potion1 && meta2 instanceof PotionMeta potion2) {
|
||||
if (potion1.hasColor() != potion2.hasColor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (potion1.hasColor() && !Objects.equals(potion1.getColor(), potion2.getColor())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (potion1.hasCustomEffects() != potion2.hasCustomEffects()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (potion1.hasCustomEffects() && !Arrays.deepEquals(potion1.getCustomEffects().toArray(), potion2.getCustomEffects().toArray())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (potion1.getBasePotionType() != null && potion2.getBasePotionType() != null) {
|
||||
List<PotionEffect> effects1 = new ArrayList<>();
|
||||
List<PotionEffect> effects2 = new ArrayList<>();
|
||||
|
||||
if (potion1.getBasePotionType() != null) {
|
||||
effects1.addAll(potion1.getBasePotionType().getPotionEffects());
|
||||
}
|
||||
if (potion1.hasCustomEffects()) {
|
||||
effects1.addAll(potion1.getCustomEffects());
|
||||
}
|
||||
if (potion2.getBasePotionType() != null) {
|
||||
effects2.addAll(potion2.getBasePotionType().getPotionEffects());
|
||||
}
|
||||
if (potion2.hasCustomEffects()) {
|
||||
effects2.addAll(potion2.getCustomEffects());
|
||||
}
|
||||
return listMatches(effects1, effects2);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Attributes
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1.hasAttributeModifiers() != meta2.hasAttributeModifiers()) {
|
||||
return false;
|
||||
}
|
||||
if (meta1.hasAttributeModifiers() && meta2.hasAttributeModifiers()) {
|
||||
final Set<Attribute> set1 = Objects.requireNonNull(meta1.getAttributeModifiers()).keySet();
|
||||
final Set<Attribute> set2 = Objects.requireNonNull(meta2.getAttributeModifiers()).keySet();
|
||||
for(final Attribute att : set1) {
|
||||
if(!set2.contains(att)) {
|
||||
return false;
|
||||
} else if(!meta1.getAttributeModifiers().get(att).equals(meta2.getAttributeModifiers().get(att))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Itemflags
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
return Arrays.deepEquals(meta1.getItemFlags().toArray(), meta2.getItemFlags().toArray());
|
||||
}
|
||||
);
|
||||
// Books
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof BookMeta bookMeta1 && meta2 instanceof BookMeta bookMeta2) {
|
||||
if (bookMeta1.hasTitle() != bookMeta2.hasTitle()) {
|
||||
return false;
|
||||
}
|
||||
if (bookMeta1.hasTitle() && !Objects.equals(bookMeta1.getTitle(), bookMeta2.getTitle())) {
|
||||
return false;
|
||||
}
|
||||
if (bookMeta1.hasPages() != bookMeta2.hasPages()) {
|
||||
return false;
|
||||
}
|
||||
if (bookMeta1.hasPages() && !bookMeta1.getPages().equals(bookMeta2.getPages())) {
|
||||
return false;
|
||||
}
|
||||
if (bookMeta1.hasAuthor() != bookMeta2.hasAuthor()) {
|
||||
return false;
|
||||
}
|
||||
if (bookMeta1.hasAuthor() && !Objects.equals(bookMeta1.getAuthor(), bookMeta2.getAuthor())) {
|
||||
return false;
|
||||
}
|
||||
if (bookMeta1.hasGeneration() != bookMeta2.hasGeneration()) {
|
||||
return false;
|
||||
}
|
||||
return !bookMeta1.hasGeneration() || Objects.equals(bookMeta1.getGeneration(), bookMeta2.getGeneration());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Fireworks
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof FireworkMeta fireworkMeta1 && meta2 instanceof FireworkMeta fireworkMeta2) {
|
||||
if (fireworkMeta1.hasEffects() != fireworkMeta2.hasEffects()) {
|
||||
return false;
|
||||
}
|
||||
if (!fireworkMeta1.getEffects().equals(fireworkMeta2.getEffects())) {
|
||||
return false;
|
||||
}
|
||||
return fireworkMeta1.getPower() == fireworkMeta2.getPower();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Banners
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof BannerMeta bannerMeta1 && meta2 instanceof BannerMeta bannerMeta2) {
|
||||
if (bannerMeta1.numberOfPatterns() != bannerMeta2.numberOfPatterns()) {
|
||||
return false;
|
||||
}
|
||||
return new HashSet<>(bannerMeta1.getPatterns()).containsAll(bannerMeta2.getPatterns());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Skulls/heads
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof SkullMeta skullMeta1 && meta2 instanceof SkullMeta skullMeta2) {
|
||||
return Objects.equals(skullMeta1.getOwningPlayer(), skullMeta2.getOwningPlayer());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Bundles
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof BundleMeta bundleMeta1 && meta2 instanceof BundleMeta bundleMeta2) {
|
||||
if (bundleMeta1.hasItems() != bundleMeta2.hasItems()) {
|
||||
return false;
|
||||
}
|
||||
if (bundleMeta1.hasItems()) {
|
||||
return listMatches(bundleMeta1.getItems(), bundleMeta2.getItems());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Maps
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof MapMeta mapMeta1 && meta2 instanceof MapMeta mapMeta2) {
|
||||
if (mapMeta1.hasMapView() != mapMeta2.hasMapView()) {
|
||||
return false;
|
||||
}
|
||||
// TODO -- do we need checks on color?
|
||||
// mapMeta1.getColor()
|
||||
MapView mapView1 = mapMeta1.getMapView();
|
||||
MapView mapView2 = mapMeta2.getMapView();
|
||||
if (mapView1 == null || mapView2 == null)
|
||||
return false;
|
||||
|
||||
if (mapView1.getId() == mapView2.getId())
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Leather
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof LeatherArmorMeta leatherArmorMeta1 && meta2 instanceof LeatherArmorMeta leatherArmorMeta2) {
|
||||
return leatherArmorMeta1.getColor().equals(leatherArmorMeta2.getColor());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Tropical fishes
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof TropicalFishBucketMeta tropicalFishBucketMeta1 && meta2 instanceof TropicalFishBucketMeta tropicalFishBucketMeta2) {
|
||||
if (tropicalFishBucketMeta1.hasVariant() != tropicalFishBucketMeta2.hasVariant()) {
|
||||
return false;
|
||||
}
|
||||
return !tropicalFishBucketMeta1.hasVariant()
|
||||
|| (tropicalFishBucketMeta1.getPattern() == tropicalFishBucketMeta2.getPattern()
|
||||
&& tropicalFishBucketMeta1.getBodyColor().equals(tropicalFishBucketMeta2.getBodyColor())
|
||||
&& tropicalFishBucketMeta1.getPatternColor().equals(tropicalFishBucketMeta2.getPatternColor()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Axolotls
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof AxolotlBucketMeta axolotlBucketMeta1 && meta2 instanceof AxolotlBucketMeta axolotlBucketMeta2) {
|
||||
return axolotlBucketMeta1.getVariant() == axolotlBucketMeta2.getVariant();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Shulkerboxes
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof BlockStateMeta blockStateMeta1 && meta2 instanceof BlockStateMeta blockStateMeta2) {
|
||||
// extra heavy - Banners, Shulkerboxes, beehive and more?
|
||||
BlockState blockState1 = blockStateMeta1.getBlockState();
|
||||
BlockState blockState2 = blockStateMeta2.getBlockState();
|
||||
|
||||
if (blockState1 instanceof ShulkerBox shulkerBox1 && blockState2 instanceof ShulkerBox shulkerBox2) {
|
||||
if (shulkerBox1.getColor() != shulkerBox2.getColor())
|
||||
return false; // not the same color
|
||||
|
||||
// Do we need all of the above checks inside the shulker?
|
||||
if (Arrays.equals(shulkerBox1.getInventory().getContents(), shulkerBox2.getInventory().getContents()))
|
||||
return true; // same content
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Suspicious stews
|
||||
matcherList.add(
|
||||
(meta1, meta2) -> {
|
||||
if (meta1 instanceof SuspiciousStewMeta suspiciousStewMeta1 && meta2 instanceof SuspiciousStewMeta suspiciousStewMeta2) {
|
||||
if (suspiciousStewMeta1.hasCustomEffects() != suspiciousStewMeta2.hasCustomEffects()) {
|
||||
return false;
|
||||
}
|
||||
if (suspiciousStewMeta1.hasCustomEffects()) {
|
||||
return listMatches(suspiciousStewMeta1.getCustomEffects(), suspiciousStewMeta2.getCustomEffects());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean matches(ItemStack item1, ItemStack item2) {
|
||||
if (item1 == null && item2 == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item1 == null || item2 == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!item1.getType().equals(item2.getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(item1.isSimilar(item2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item1.hasItemMeta() && item2.hasItemMeta()) {
|
||||
return metaMatches(item1, item2);
|
||||
}
|
||||
|
||||
return !item1.hasItemMeta() && !item1.hasItemMeta();
|
||||
}
|
||||
|
||||
protected static boolean metaMatches(ItemStack item1, ItemStack item2) {
|
||||
ItemMeta meta1 = item1.getItemMeta();
|
||||
ItemMeta meta2 = item2.getItemMeta();
|
||||
|
||||
if (meta1 != null && meta2 != null) {
|
||||
for (Matcher matcher : matcherList) {
|
||||
boolean result = matcher.match(meta1, meta2);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return meta1 == null && meta2 == null;
|
||||
}
|
||||
|
||||
private static boolean listMatches(Collection<?> list1, Collection<?> list2) {
|
||||
return list1.containsAll(list2) && list2.containsAll(list1);
|
||||
}
|
||||
|
||||
public static interface Matcher {
|
||||
|
||||
boolean match(ItemMeta meta1, ItemMeta meta2);
|
||||
}
|
||||
}
|
||||
5
src/main/java/com/alttd/playershops/utils/Pair.java
Normal file
5
src/main/java/com/alttd/playershops/utils/Pair.java
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
package com.alttd.playershops.utils;
|
||||
|
||||
public record Pair<X, Y>(X x, Y y) {
|
||||
|
||||
}
|
||||
|
|
@ -2,20 +2,17 @@ package com.alttd.playershops.utils;
|
|||
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.ShopTransaction;
|
||||
import com.alttd.playershops.utils.sprite.MaterialSprites;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.ShulkerBox;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.bukkit.map.MapView;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -37,167 +34,6 @@ public class ShopUtil {
|
|||
return (loc.getWorld().isChunkLoaded(x, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two items to each other. Returns true if they match.
|
||||
*
|
||||
* @param stack1
|
||||
* The first item stack
|
||||
* @param stack2
|
||||
* The second item stack
|
||||
* @return true if the itemstacks match. (Material, durability, enchants, name)
|
||||
*/
|
||||
public static boolean matches(ItemStack stack1, ItemStack stack2) {
|
||||
if (stack1 == stack2)
|
||||
return true; // Referring to the same thing, or both are null.
|
||||
if (stack1 == null || stack2 == null)
|
||||
return false; // One of them is null (Can't be both, see above)
|
||||
if (stack1.getType() != stack2.getType())
|
||||
return false; // Not the same material
|
||||
if (stack1.getDurability() != stack2.getDurability())
|
||||
return false; // Not the same durability
|
||||
if (!stack1.getEnchantments().equals(stack2.getEnchantments()))
|
||||
return false; // They have the same enchants
|
||||
if (!stack1.getItemMeta().equals(stack2.getItemMeta()))
|
||||
return false; // They have the same enchants
|
||||
if (stack1.getItemMeta().hasDisplayName() || stack2.getItemMeta().hasDisplayName()) {
|
||||
if (stack1.getItemMeta().hasDisplayName() && stack2.getItemMeta().hasDisplayName()) {
|
||||
if (!stack1.getItemMeta().getDisplayName().equals(stack2.getItemMeta().getDisplayName())) {
|
||||
return false; // items have different display name
|
||||
}
|
||||
} else {
|
||||
return false; // one of the item stacks have a display name
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class.forName("org.bukkit.inventory.meta.EnchantmentStorageMeta");
|
||||
boolean book1 = stack1.getItemMeta() instanceof EnchantmentStorageMeta;
|
||||
boolean book2 = stack2.getItemMeta() instanceof EnchantmentStorageMeta;
|
||||
if (book1 != book2)
|
||||
return false;// One has enchantment meta, the other does not.
|
||||
if (book1 == true) { // They are the same here (both true or both
|
||||
// false). So if one is true, the other is
|
||||
// true.
|
||||
Map<Enchantment, Integer> ench1 = ((EnchantmentStorageMeta) stack1.getItemMeta()).getStoredEnchants();
|
||||
Map<Enchantment, Integer> ench2 = ((EnchantmentStorageMeta) stack2.getItemMeta()).getStoredEnchants();
|
||||
if (!ench1.equals(ench2))
|
||||
return false; // Enchants aren't the same.
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
return matches2(stack1, stack2);
|
||||
}
|
||||
|
||||
public static boolean matches2(ItemStack stack1, ItemStack stack2) {
|
||||
if (stack1 == stack2)
|
||||
return true; // Referring to the same thing, or both are null.
|
||||
|
||||
if (stack1 == null || stack2 == null)
|
||||
return false; // One of them is null (Can't be both, see above)
|
||||
|
||||
if (stack1.getType() != stack2.getType())
|
||||
return false; // Not the same material
|
||||
|
||||
if ((!stack1.hasItemMeta() && !stack2.hasItemMeta()))
|
||||
return true; // Only one of the items has item meta
|
||||
|
||||
if (stack1.hasItemMeta() && stack2.hasItemMeta()) {
|
||||
ItemMeta itemMeta1 = stack1.getItemMeta();
|
||||
ItemMeta itemMeta2 = stack2.getItemMeta();
|
||||
|
||||
if ((itemMeta1.hasDisplayName() != itemMeta2.hasDisplayName()))
|
||||
return false; // Only one has a display name
|
||||
|
||||
if (!itemMeta1.getDisplayName().equals(itemMeta2.getDisplayName()))
|
||||
return false; // items have different display name
|
||||
|
||||
// This is where the heavy checks are :/
|
||||
|
||||
try {
|
||||
Class.forName("org.bukkit.inventory.meta.EnchantmentStorageMeta");
|
||||
boolean book1 = itemMeta1 instanceof EnchantmentStorageMeta;
|
||||
boolean book2 = itemMeta2 instanceof EnchantmentStorageMeta;
|
||||
if (book1 != book2)
|
||||
return false;// One has enchantment meta, the other does not.
|
||||
if (book1 == true) { // They are the same here (both true or both false). So if one is true, the other is true.
|
||||
Map<Enchantment, Integer> ench1 = ((EnchantmentStorageMeta) itemMeta1).getStoredEnchants();
|
||||
Map<Enchantment, Integer> ench2 = ((EnchantmentStorageMeta) itemMeta2).getStoredEnchants();
|
||||
if (!ench1.equals(ench2))
|
||||
return false; // Enchants aren't the same.
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
if (itemMeta1 instanceof Damageable damageable1 && itemMeta2 instanceof Damageable damageable2)
|
||||
if (damageable1.getDamage() != damageable2.getDamage())
|
||||
return false; // Not the same durability
|
||||
|
||||
// We need this check now because mapart stores data in the map NBT
|
||||
if (itemMeta1 instanceof MapMeta mapMeta1 && itemMeta2 instanceof MapMeta mapMeta2) {
|
||||
MapView mapView1 = mapMeta1.getMapView();
|
||||
MapView mapView2 = mapMeta2.getMapView();
|
||||
if (mapView1 == null || mapView2 == null)
|
||||
return false; // at least one is null
|
||||
|
||||
if (mapView1.getId() == mapView2.getId())
|
||||
return true; // ID does not match
|
||||
}
|
||||
|
||||
if (itemMeta1 instanceof TropicalFishBucketMeta tropicalFishBucketMeta1 && itemMeta2 instanceof TropicalFishBucketMeta tropicalFishBucketMeta2) {
|
||||
if (tropicalFishBucketMeta1.getBodyColor() != tropicalFishBucketMeta2.getBodyColor())
|
||||
return false;
|
||||
|
||||
if (tropicalFishBucketMeta1.getPattern() != tropicalFishBucketMeta2.getPattern())
|
||||
return false;
|
||||
|
||||
if (tropicalFishBucketMeta1.getPatternColor() != tropicalFishBucketMeta2.getPatternColor())
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (itemMeta1 instanceof AxolotlBucketMeta axolotlBucketMeta1 && itemMeta2 instanceof AxolotlBucketMeta axolotlBucketMeta2) {
|
||||
if (axolotlBucketMeta1.getVariant() != axolotlBucketMeta2.getVariant())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemMeta1 instanceof BlockStateMeta blockStateMeta1 && itemMeta2 instanceof BlockStateMeta blockStateMeta2) {
|
||||
// extra heavy - Banners, Shulkerboxes, beehive and more?
|
||||
BlockState blockState1 = blockStateMeta1.getBlockState();
|
||||
BlockState blockState2 = blockStateMeta2.getBlockState();
|
||||
|
||||
if (blockState1 instanceof ShulkerBox shulkerBox1 && blockState2 instanceof ShulkerBox shulkerBox2) {
|
||||
if (shulkerBox1.getColor() != shulkerBox2.getColor())
|
||||
return false; // not the same color
|
||||
|
||||
// Do we need all of the above checks inside the shulker?
|
||||
if (Arrays.equals(shulkerBox1.getInventory().getContents(), shulkerBox2.getInventory().getContents()))
|
||||
return true; // same content
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
/* if (itemMeta1 instanceof BannerMeta bannerMeta1 && itemMeta2 instanceof BannerMeta bannerMeta2) {
|
||||
if (bannerMeta1.numberOfPatterns() != bannerMeta2.numberOfPatterns())
|
||||
return false;
|
||||
|
||||
if (!bannerMeta1.getPatterns().equals(bannerMeta2.getPatterns()))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemMeta1 instanceof BookMeta bookMeta1 && itemMeta2 instanceof BookMeta bookMeta2) {
|
||||
// Todo Books
|
||||
}
|
||||
|
||||
if (itemMeta1 instanceof PotionMeta potionMeta1 && itemMeta2 instanceof PotionMeta potionMeta2) {
|
||||
|
||||
}*/
|
||||
}
|
||||
// if (!stack1.getEnchantments().equals(stack2.getEnchantments()))
|
||||
// return false; // They have the same enchants
|
||||
// if (!stack1.getItemMeta().equals(stack2.getItemMeta()))
|
||||
// return false; // They have the same enchants
|
||||
return Arrays.equals(stack1.serializeAsBytes(), stack2.serializeAsBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items that can be given to the inventory safely.
|
||||
*
|
||||
|
|
@ -216,7 +52,7 @@ public class ShopUtil {
|
|||
for (ItemStack iStack : contents) {
|
||||
if (iStack == null || iStack.getType() == Material.AIR) {
|
||||
space += item.getMaxStackSize();
|
||||
} else if (matches(item, iStack)) {
|
||||
} else if (ItemMatcher.matches(item, iStack)) {
|
||||
space += item.getMaxStackSize() - iStack.getAmount();
|
||||
}
|
||||
}
|
||||
|
|
@ -329,7 +165,7 @@ public class ShopUtil {
|
|||
Component component;
|
||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
if (item == null || item.getType().equals(Material.AIR))
|
||||
return miniMessage.deserialize("NONE");
|
||||
return miniMessage.deserialize("No item");
|
||||
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
|
||||
if (dname) {
|
||||
component = item.getItemMeta().displayName();
|
||||
|
|
@ -366,4 +202,18 @@ public class ShopUtil {
|
|||
public static double round(double price) {
|
||||
return (double) Math.round(price * 100) / 100;
|
||||
}
|
||||
|
||||
public static Component spriteComponent(ItemStack itemStack) {
|
||||
Component component = Component.empty();
|
||||
if (itemStack == null || itemStack.getType() == Material.AIR) return component;
|
||||
|
||||
component = MaterialSprites.get(itemStack.getType()).append(Component.space()).append(
|
||||
itemStack.displayName().hoverEvent(itemStack.asHoverEvent()));
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
public static Component spriteComponent(Material material) {
|
||||
return MaterialSprites.get(material).append(Component.space()).append(Component.text(material.key().value()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user