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.io.FileOutputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||||
|
import net.minecrell.pluginyml.paper.PaperPluginDescription
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("java-library")
|
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("xyz.jpenilla.run-paper") version "1.0.6"
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +41,7 @@ tasks {
|
||||||
file.parentFile.mkdirs()
|
file.parentFile.mkdirs()
|
||||||
}
|
}
|
||||||
if (!file.exists()) {
|
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)
|
serverJar(file)
|
||||||
minecraftVersion("1.21")
|
minecraftVersion("1.21")
|
||||||
|
|
@ -61,8 +62,10 @@ publishing {
|
||||||
configure<PublishingExtension> {
|
configure<PublishingExtension> {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
name = "maven"
|
name = "AlttdNexus"
|
||||||
url = uri("https://repo.destro.xyz/snapshots/")
|
url = uri(
|
||||||
|
"https://repo.alttd.com/repository/alttd-snapshot/"
|
||||||
|
)
|
||||||
credentials(PasswordCredentials::class)
|
credentials(PasswordCredentials::class)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +73,7 @@ publishing {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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") {
|
compileOnly("com.github.milkbowl:VaultAPI:1.7") {
|
||||||
exclude("org.bukkit","bukkit")
|
exclude("org.bukkit","bukkit")
|
||||||
}
|
}
|
||||||
|
|
@ -97,14 +100,23 @@ fun download(link: String, path: String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bukkit {
|
paper {
|
||||||
name = rootProject.name
|
name = rootProject.name
|
||||||
main = "$group.${rootProject.name}"
|
main = "$group.${rootProject.name}"
|
||||||
|
bootstrapper = "$group.${rootProject.name}Bootstrap"
|
||||||
version = "${rootProject.version}-${gitCommit()}"
|
version = "${rootProject.version}-${gitCommit()}"
|
||||||
apiVersion = "1.20"
|
apiVersion = "1.21"
|
||||||
authors = listOf("destro174")
|
authors = listOf("destro174")
|
||||||
depend = listOf("Vault")
|
serverDependencies {
|
||||||
softDepend = listOf("GriefPrevention")
|
register("Vault") {
|
||||||
|
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
|
||||||
|
}
|
||||||
|
|
||||||
|
register("GriefPrevention") {
|
||||||
|
required = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
permissions {
|
permissions {
|
||||||
register("playershops.admin") {
|
register("playershops.admin") {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,14 @@ rootProject.name = "PlayerShops"
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
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
|
maven("https://jitpack.io") { // Vault
|
||||||
content {
|
content {
|
||||||
includeGroup("com.github.milkbowl")
|
includeGroup("com.github.milkbowl")
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
package com.alttd.playershops;
|
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.Config;
|
||||||
import com.alttd.playershops.config.DatabaseConfig;
|
import com.alttd.playershops.config.DatabaseConfig;
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
import com.alttd.playershops.gui.GuiIcon;
|
|
||||||
import com.alttd.playershops.handler.ShopHandler;
|
import com.alttd.playershops.handler.ShopHandler;
|
||||||
import com.alttd.playershops.listener.*;
|
import com.alttd.playershops.listener.*;
|
||||||
import com.alttd.playershops.shop.ShopType;
|
import com.alttd.playershops.shop.ShopType;
|
||||||
import com.alttd.playershops.storage.database.DatabaseManager;
|
import com.alttd.playershops.storage.database.DatabaseManager;
|
||||||
import com.alttd.playershops.storage.database.DatabaseHelper;
|
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 lombok.Getter;
|
||||||
import net.milkbowl.vault.economy.Economy;
|
import net.milkbowl.vault.economy.Economy;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PlayerShops extends JavaPlugin {
|
public class PlayerShops extends JavaPlugin {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -31,7 +36,6 @@ public class PlayerShops extends JavaPlugin {
|
||||||
private ShopListener shopListener;
|
private ShopListener shopListener;
|
||||||
private PlayerListener playerListener;
|
private PlayerListener playerListener;
|
||||||
private TransactionListener transactionListener;
|
private TransactionListener transactionListener;
|
||||||
private InventoryListener inventoryListener;
|
|
||||||
private GriefPreventionListener griefPreventionListener;
|
private GriefPreventionListener griefPreventionListener;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -40,14 +44,14 @@ public class PlayerShops extends JavaPlugin {
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
if(!setupEconomy()) {
|
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);
|
this.setEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bukkit.getLogger().info("Hooked into Vault economy provided by " + econ.getName());
|
getLogger().info("Hooked into Vault economy provided by " + econ.getName());
|
||||||
reloadConfigs();
|
reloadConfigs();
|
||||||
if(!setupDatabase()) {
|
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);
|
this.setEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +99,6 @@ public class PlayerShops extends JavaPlugin {
|
||||||
shopListener = new ShopListener(this);
|
shopListener = new ShopListener(this);
|
||||||
playerListener = new PlayerListener(this);
|
playerListener = new PlayerListener(this);
|
||||||
transactionListener = new TransactionListener(this);
|
transactionListener = new TransactionListener(this);
|
||||||
inventoryListener = new InventoryListener(this);
|
|
||||||
griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP
|
griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,11 +106,14 @@ public class PlayerShops extends JavaPlugin {
|
||||||
shopListener.unregister();
|
shopListener.unregister();
|
||||||
playerListener.unregister();
|
playerListener.unregister();
|
||||||
transactionListener.unregister();
|
transactionListener.unregister();
|
||||||
inventoryListener.unregister();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerCommands() {
|
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() {
|
public void reloadConfigs() {
|
||||||
|
|
@ -119,9 +125,6 @@ public class PlayerShops extends JavaPlugin {
|
||||||
for (ShopType shopType : ShopType.values()) {
|
for (ShopType shopType : ShopType.values()) {
|
||||||
// preload ShopType to get the configs active
|
// 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;
|
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.CheckStockCommand;
|
||||||
import com.alttd.playershops.commands.subcommands.ReloadCommand;
|
import com.alttd.playershops.dialog.ShopDialog;
|
||||||
import com.alttd.playershops.commands.subcommands.TransferShopsCommand;
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
import com.alttd.playershops.gui.HomeGui;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.alttd.playershops.utils.Util;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
import org.bukkit.Bukkit;
|
import io.papermc.paper.command.brigadier.Commands;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
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 org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.*;
|
public class PlayerShopCommand {
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
public static final String BASE_PERM = "playershops.command";
|
||||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
|
||||||
|
|
||||||
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
|
int range = source.getArgument("range", Integer.class);
|
||||||
private static final Map<String, Subcommand> SUBCOMMANDS = PlayerShopCommands.make(() -> {
|
int stock = -1;
|
||||||
final Map<Set<String>, Subcommand> commands = new HashMap<>();
|
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());
|
int range = source.getArgument("range", Integer.class);
|
||||||
commands.put(Set.of("checkstock"), new CheckStockCommand());
|
int stock = source.getArgument("stock", Integer.class);
|
||||||
commands.put(Set.of("transfershops"), new TransferShopsCommand());
|
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()
|
return 1;
|
||||||
.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 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.PlayerShops;
|
||||||
import com.alttd.playershops.commands.PlayerShopCommand;
|
import com.alttd.playershops.commands.PlayerShopCommand;
|
||||||
import com.alttd.playershops.commands.PlayerShopCommands;
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
import com.alttd.playershops.commands.Subcommand;
|
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
import com.alttd.playershops.utils.ShopUtil;
|
import com.alttd.playershops.utils.ShopUtil;
|
||||||
import com.alttd.playershops.utils.Util;
|
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 net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@DefaultQualifier(NonNull.class)
|
@DefaultQualifier(NonNull.class)
|
||||||
public class CheckStockCommand implements Subcommand {
|
public class CheckStockCommand {
|
||||||
|
|
||||||
@Override
|
public static void doStockCheck(final Player player, int radius, int minimumStock) {
|
||||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
List<Stock> stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player, minimumStock);
|
||||||
return this.doStockCheck(sender, args);
|
sendStockMessage(player, stockList, minimumStock);
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
highlightLowStock(player, stockList);
|
highlightLowStock(player, stockList);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Stole this code from AlttdUtility by ___Kappa___ and reworked it slightly
|
//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 particleBuilder = new ParticleBuilder(Particle.DUST);
|
||||||
particleBuilder.color(255, 255, 255);
|
particleBuilder.color(255, 255, 255);
|
||||||
particleBuilder.receivers(player);
|
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
|
* @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
|
* @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);
|
List<PlayerShop> shops = PlayerShops.getInstance().getShopHandler().getShopsInRadius(x, z, radius);
|
||||||
Stream<PlayerShop> playerShopStream = shops.stream();
|
Stream<PlayerShop> playerShopStream = shops.stream();
|
||||||
if (minimumStock != -1)
|
if (minimumStock != -1)
|
||||||
|
|
@ -157,8 +104,7 @@ public class CheckStockCommand implements Subcommand {
|
||||||
}).collect(Collectors.toList());
|
}).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 static void sendStockMessage(Player player, List<Stock> stockList, int minimumStock) {
|
||||||
private void sendStockMessage(Player player, List<Stock> stockList) {
|
|
||||||
Component component = null;
|
Component component = null;
|
||||||
for (Stock stock : stockList) {
|
for (Stock stock : stockList) {
|
||||||
TagResolver resolver = TagResolver.resolver(
|
TagResolver resolver = TagResolver.resolver(
|
||||||
|
|
@ -169,9 +115,9 @@ public class CheckStockCommand implements Subcommand {
|
||||||
Placeholder.parsed("amount", stock.stock + "")
|
Placeholder.parsed("amount", stock.stock + "")
|
||||||
);
|
);
|
||||||
if (component == null)
|
if (component == null)
|
||||||
component = Util.parseMiniMessage(putInConfig, resolver);
|
component = Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver);
|
||||||
else
|
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 (component == null)
|
||||||
if (minimumStock == -1)
|
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_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_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() {
|
private static void otherMessages() {
|
||||||
SHOP_INFO = getString("messages.shop-info", SHOP_INFO);
|
SHOP_INFO = getString("messages.shop-info", SHOP_INFO);
|
||||||
SHOP_STOCK_INFO = getString("messages.shop-stock-info", SHOP_STOCK_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.";
|
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.shop.PlayerShop;
|
||||||
import com.alttd.playershops.storage.database.DatabaseHelper;
|
import com.alttd.playershops.storage.database.DatabaseHelper;
|
||||||
import com.alttd.playershops.utils.Logger;
|
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.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.DoubleChest;
|
import org.bukkit.block.DoubleChest;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
|
||||||
|
|
@ -178,4 +182,47 @@ public class ShopHandler {
|
||||||
return playerSettings.computeIfAbsent(uuid, PlayerSettings::loadFromFile);
|
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.PlayerShops;
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
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.handler.ShopHandler;
|
||||||
import com.alttd.playershops.hook.WorldGuardHook;
|
import com.alttd.playershops.hook.WorldGuardHook;
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
|
@ -92,8 +92,10 @@ public class TransactionListener extends EventListener {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
// ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||||
gui.open();
|
// gui.open();
|
||||||
|
ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), playerShop);
|
||||||
|
manageShopDialog.open();
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,12 @@ import java.util.UUID;
|
||||||
public class PlayerSettings {
|
public class PlayerSettings {
|
||||||
public enum Option {
|
public enum Option {
|
||||||
SALE_OWNER_NOTIFICATIONS, SALE_USER_NOTIFICATIONS,
|
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;
|
private final UUID uuid;
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,25 @@ package com.alttd.playershops.shop;
|
||||||
import com.alttd.playershops.PlayerShops;
|
import com.alttd.playershops.PlayerShops;
|
||||||
import com.alttd.playershops.events.*;
|
import com.alttd.playershops.events.*;
|
||||||
import com.alttd.playershops.utils.*;
|
import com.alttd.playershops.utils.*;
|
||||||
|
import com.alttd.playershops.utils.sprite.MaterialSprites;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
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.MiniMessage;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.block.Sign;
|
import org.bukkit.block.Sign;
|
||||||
|
import org.bukkit.block.sign.Side;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -30,8 +37,8 @@ public class PlayerShop {
|
||||||
private final Location signLocation;
|
private final Location signLocation;
|
||||||
private final Location shopLocation;
|
private final Location shopLocation;
|
||||||
private String server;
|
private String server;
|
||||||
private double price;
|
private double price = 0;
|
||||||
private int amount;
|
private int amount = 1;
|
||||||
private double balance;
|
private double balance;
|
||||||
private ItemStack itemStack;
|
private ItemStack itemStack;
|
||||||
@Setter
|
@Setter
|
||||||
|
|
@ -109,7 +116,7 @@ public class PlayerShop {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches(ItemStack item) {
|
public boolean matches(ItemStack item) {
|
||||||
return ShopUtil.matches(getItemStack(), item);
|
return ItemMatcher.matches(getItemStack(), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(ItemStack item, int amount) {
|
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();
|
ownerUUID = player.getUniqueId();
|
||||||
ownerName = player.getName();
|
ownerName = player.getName();
|
||||||
update();
|
update();
|
||||||
|
|
@ -171,14 +178,15 @@ public class PlayerShop {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return;
|
if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return;
|
||||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
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(
|
TagResolver tagResolver = TagResolver.resolver(
|
||||||
Placeholder.unparsed("ownername", getOwnerName()),
|
Placeholder.unparsed("ownername", getOwnerName()),
|
||||||
Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))),
|
Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))),
|
||||||
Placeholder.unparsed("amount", String.valueOf(getAmount())),
|
Placeholder.unparsed("amount", String.valueOf(getAmount())),
|
||||||
Placeholder.component("itemname", ShopUtil.trimmedItemNameComponent(getItemStack()))
|
Placeholder.component("itemname", itemComponent)
|
||||||
);
|
);
|
||||||
for (int i = 0; i < 4; i++) {
|
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);
|
signBlock.update(true);
|
||||||
}
|
}
|
||||||
|
|
@ -360,8 +368,12 @@ public class PlayerShop {
|
||||||
if (Util.callCancellableEvent(shopItemChangeEvent))
|
if (Util.callCancellableEvent(shopItemChangeEvent))
|
||||||
return; // cancelled by another plugin, does this need logging?
|
return; // cancelled by another plugin, does this need logging?
|
||||||
|
|
||||||
this.itemStack = itemStack;
|
if (itemStack == null) {
|
||||||
|
this.itemStack = null;
|
||||||
|
} else {
|
||||||
|
this.itemStack = itemStack.clone();
|
||||||
this.itemStack.setAmount(this.amount != 0 ? this.amount : 1);
|
this.itemStack.setAmount(this.amount != 0 ? this.amount : 1);
|
||||||
|
}
|
||||||
setDirty(true);
|
setDirty(true);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
@ -451,4 +463,25 @@ public class PlayerShop {
|
||||||
+ " balance :" + this.balance
|
+ " balance :" + this.balance
|
||||||
+ " lastTransaction :" + this.lastTransaction;
|
+ " 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();
|
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()) {
|
for (ItemStack iStack : inv.getContents()) {
|
||||||
if (iStack == null)
|
if (iStack == null)
|
||||||
continue;
|
continue;
|
||||||
if (ShopUtil.matches(item, iStack)) {
|
if (ItemMatcher.matches(item, iStack)) {
|
||||||
items += iStack.getAmount();
|
items += iStack.getAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ public class InventoryUtils {
|
||||||
int amount = itemStack.getAmount();
|
int amount = itemStack.getAmount();
|
||||||
for (ItemStack stack : contents) {
|
for (ItemStack stack : contents) {
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
if (ShopUtil.matches(stack, itemStack)) {
|
if (ItemMatcher.matches(stack, itemStack)) {
|
||||||
if (stack.getAmount() > amount) {
|
if (stack.getAmount() > amount) {
|
||||||
stack.setAmount(stack.getAmount() - amount);
|
stack.setAmount(stack.getAmount() - amount);
|
||||||
inventory.setContents(contents);
|
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.PlayerShop;
|
||||||
import com.alttd.playershops.shop.ShopTransaction;
|
import com.alttd.playershops.shop.ShopTransaction;
|
||||||
|
import com.alttd.playershops.utils.sprite.MaterialSprites;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.*;
|
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.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.*;
|
import org.bukkit.inventory.meta.*;
|
||||||
import org.bukkit.map.MapView;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
@ -37,167 +34,6 @@ public class ShopUtil {
|
||||||
return (loc.getWorld().isChunkLoaded(x, z));
|
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.
|
* Returns the number of items that can be given to the inventory safely.
|
||||||
*
|
*
|
||||||
|
|
@ -216,7 +52,7 @@ public class ShopUtil {
|
||||||
for (ItemStack iStack : contents) {
|
for (ItemStack iStack : contents) {
|
||||||
if (iStack == null || iStack.getType() == Material.AIR) {
|
if (iStack == null || iStack.getType() == Material.AIR) {
|
||||||
space += item.getMaxStackSize();
|
space += item.getMaxStackSize();
|
||||||
} else if (matches(item, iStack)) {
|
} else if (ItemMatcher.matches(item, iStack)) {
|
||||||
space += item.getMaxStackSize() - iStack.getAmount();
|
space += item.getMaxStackSize() - iStack.getAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -329,7 +165,7 @@ public class ShopUtil {
|
||||||
Component component;
|
Component component;
|
||||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
if (item == null || item.getType().equals(Material.AIR))
|
if (item == null || item.getType().equals(Material.AIR))
|
||||||
return miniMessage.deserialize("NONE");
|
return miniMessage.deserialize("No item");
|
||||||
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
|
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
|
||||||
if (dname) {
|
if (dname) {
|
||||||
component = item.getItemMeta().displayName();
|
component = item.getItemMeta().displayName();
|
||||||
|
|
@ -366,4 +202,18 @@ public class ShopUtil {
|
||||||
public static double round(double price) {
|
public static double round(double price) {
|
||||||
return (double) Math.round(price * 100) / 100;
|
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