From 5e96f67674f0a6c5b06db563df7b512e5a9591ca Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:33:16 +0200 Subject: [PATCH 01/51] begin refactor --- build.gradle.kts | 3 - .../parcellockers/ParcelLockers.java | 49 +++-- .../command/debug/DebugCommand.java | 15 +- .../repository/ParcelContentRepository.java | 4 +- .../ParcelContentRepositoryOrmLite.java | 4 +- .../repository/DeliveryRepository.java | 3 +- .../repository/DeliveryRepositoryOrmLite.java | 2 +- .../implementation/locker/LockerMainGui.java | 24 +-- .../locker/ParcelCollectionGui.java | 20 +- .../locker/ParcelItemStorageGui.java | 19 +- .../locker/ParcelSendingGui.java | 18 +- .../gui/implementation/remote/MainGui.java | 16 +- .../implementation/remote/ParcelListGui.java | 17 +- .../implementation/remote/SentParcelsGui.java | 15 +- .../repository/ItemStorageRepository.java | 5 +- .../ItemStorageRepositoryOrmLite.java | 4 +- .../controller/LockerBreakController.java | 2 +- .../locker/repository/LockerCache.java | 46 +++-- .../locker/repository/LockerRepository.java | 8 +- .../repository/LockerRepositoryOrmLite.java | 26 +-- ...{ParcelManager.java => ParcelService.java} | 106 ++++++----- .../parcel/command/ParcelCommand.java | 24 +-- .../parcel/repository/ParcelCache.java | 32 +++- .../parcel/repository/ParcelPageResult.java | 4 +- .../parcel/repository/ParcelTable.java | 36 +++- .../parcel/task/ParcelSendTask.java | 2 +- .../parcel/util/ParcelPlaceholderUtil.java | 12 +- .../{UserManager.java => UserService.java} | 10 +- .../user/controller/LoadUserController.java | 10 +- .../controller/PrepareUserController.java | 10 +- .../user/repository/UserPageResult.java | 3 +- .../LockerRepositoryIntegrationTest.java | 2 +- .../locker/repository/LockerCacheTest.java | 140 ++++++++++++++ .../parcel/repository/ParcelCacheTest.java | 175 ++++++++++++++++++ 34 files changed, 611 insertions(+), 255 deletions(-) rename src/main/java/com/eternalcode/parcellockers/parcel/{ParcelManager.java => ParcelService.java} (51%) rename src/main/java/com/eternalcode/parcellockers/user/{UserManager.java => UserService.java} (87%) create mode 100644 src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java create mode 100644 src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java diff --git a/build.gradle.kts b/build.gradle.kts index 7b1aefebc..d5a23f18d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -169,6 +169,3 @@ tasks { ).forEach { relocate(it, "$relocationPrefix.$it") } } } - - - diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 33a6277f2..4e96704ee 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -27,7 +27,7 @@ import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelManager; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.command.ParcelCommand; import com.eternalcode.parcellockers.parcel.command.argument.ParcelArgument; @@ -35,7 +35,7 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepositoryOrmLite; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.updater.UpdaterService; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import com.eternalcode.parcellockers.user.controller.LoadUserController; import com.eternalcode.parcellockers.user.controller.PrepareUserController; import com.eternalcode.parcellockers.user.repository.UserRepository; @@ -53,14 +53,6 @@ import io.papermc.lib.PaperLib; import io.papermc.lib.environments.Environment; import io.sentry.Sentry; -import net.kyori.adventure.platform.bukkit.BukkitAudiences; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bstats.bukkit.Metrics; -import org.bukkit.Server; -import org.bukkit.command.CommandSender; -import org.bukkit.plugin.java.JavaPlugin; -import org.slf4j.helpers.NOPLogger; - import java.sql.SQLException; import java.time.Duration; import java.util.ArrayList; @@ -70,6 +62,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bstats.bukkit.Metrics; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.java.JavaPlugin; +import org.slf4j.helpers.NOPLogger; public final class ParcelLockers extends JavaPlugin { @@ -147,15 +146,17 @@ public void onEnable() { DeliveryRepositoryOrmLite deliveryRepository = new DeliveryRepositoryOrmLite(databaseManager, scheduler); ParcelContentRepository parcelContentRepository = new ParcelContentRepositoryOrmLite(databaseManager, scheduler); - ParcelManager parcelManager = new ParcelManager(config, announcer, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); + ParcelService parcelService = new ParcelService(config, announcer, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); ItemStorageRepository itemStorageRepository = new ItemStorageRepositoryOrmLite(databaseManager, scheduler); UserRepository userRepository = new UserRepositoryOrmLite(databaseManager, scheduler); - UserManager userManager = new UserManager(userRepository); + UserService userService = new UserService(userRepository); - MainGui mainGUI = new MainGui(this, server, miniMessage, config, parcelRepository, lockerRepository, userManager); - ParcelListGui parcelListGUI = new ParcelListGui(this, server, miniMessage, config, parcelRepository, lockerRepository, userManager, mainGUI); + MainGui mainGUI = new MainGui(this, server, miniMessage, config, parcelRepository, lockerRepository, + userService); + ParcelListGui parcelListGUI = new ParcelListGui(this, server, miniMessage, config, parcelRepository, lockerRepository, + userService, mainGUI); this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .argument(Parcel.class, new ParcelArgument(parcelCache)) @@ -164,7 +165,8 @@ public void onEnable() { .message(LiteBukkitMessages.PLAYER_ONLY, config.messages.onlyForPlayers) .message(LiteBukkitMessages.PLAYER_NOT_FOUND, config.messages.cantFindPlayer) .commands(LiteCommandsAnnotations.of( - new ParcelCommand(lockerRepository, announcer, config, mainGUI, parcelListGUI, parcelManager, userManager), + new ParcelCommand(lockerRepository, announcer, config, mainGUI, parcelListGUI, + parcelService, userService), new ParcelLockersCommand(configManager, config, announcer), new DebugCommand(parcelRepository, lockerRepository, itemStorageRepository, parcelContentRepository, announcer) )) @@ -172,14 +174,15 @@ public void onEnable() { .missingPermission(new PermissionMessage(announcer, config)) .build(); - LockerMainGui lockerMainGUI = new LockerMainGui(this, miniMessage, config, itemStorageRepository, parcelRepository, lockerRepository, announcer, parcelContentRepository, userRepository, this.skullAPI, parcelManager); + LockerMainGui lockerMainGUI = new LockerMainGui(this, miniMessage, config, itemStorageRepository, parcelRepository, lockerRepository, announcer, parcelContentRepository, userRepository, this.skullAPI, + parcelService); Stream.of( new LockerInteractionController(lockerCache, lockerMainGUI), new LockerPlaceController(config, this, lockerRepository, announcer), new LockerBreakController(lockerRepository, lockerCache, announcer, config.messages), - new PrepareUserController(userManager), - new LoadUserController(userManager, server) + new PrepareUserController(userService), + new LoadUserController(userService, server) ).forEach(controller -> server.getPluginManager().registerEvents(controller, this)); new Metrics(this, 17677); @@ -231,17 +234,7 @@ private void softwareCheck() { if (!environment.isPaper()) { logger.warning("Your server running on unsupported software, please use Paper or its forks"); logger.warning("You can easily download Paper from https://papermc.io/downloads"); - logger.warning("WARNING: Supported MC versions are 1.17.x-1.21.x"); - return; - } - - if (!environment.isVersion(17)) { - logger.warning("ParcelLockers no longer supports your version, be aware that there may be bugs!"); - return; } - - logger.info("Your server is running on supported software, congratulations!"); - logger.info("Server version: " + this.getServer().getVersion()); } } diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index 6d9953699..fb1f3a1e7 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -10,15 +10,14 @@ import dev.rollczi.litecommands.annotations.context.Context; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; @Command(name = "parcel debug") @Permission("parcellockers.debug") @@ -54,7 +53,7 @@ void deleteParcels(@Context CommandSender sender) { @Execute(name = "delete lockers") void deleteLockers(@Context CommandSender sender) { - this.lockerRepository.removeAll().exceptionally(throwable -> { + this.lockerRepository.deleteAll().exceptionally(throwable -> { this.announcer.sendMessage(sender, "&4Failed to delete lockers"); return null; }).thenRun(() -> this.announcer.sendMessage(sender, "&cLockers deleted")); @@ -62,7 +61,7 @@ void deleteLockers(@Context CommandSender sender) { @Execute(name = "delete itemstorages") void deleteItemStorages(@Context CommandSender sender) { - this.itemStorageRepository.removeAll().exceptionally(throwable -> { + this.itemStorageRepository.deleteAll().exceptionally(throwable -> { this.announcer.sendMessage(sender, "&4Failed to delete item storages"); return null; }).thenRun(() -> this.announcer.sendMessage(sender, "&cItem storages deleted")); @@ -70,7 +69,7 @@ void deleteItemStorages(@Context CommandSender sender) { @Execute(name = "delete parcelcontents") void deleteParcelContents(@Context CommandSender sender) { - this.contentRepository.removeAll().exceptionally(throwable -> { + this.contentRepository.deleteAll().exceptionally(throwable -> { this.announcer.sendMessage(sender, "&4Failed to delete parcel contents"); return null; }).thenRun(() -> this.announcer.sendMessage(sender, "&cParcel contents deleted")); diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java index f6c2cab41..d71292620 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java @@ -11,8 +11,8 @@ public interface ParcelContentRepository { CompletableFuture> find(UUID uniqueId); - CompletableFuture remove(UUID uniqueId); + CompletableFuture delete(UUID uniqueId); - CompletableFuture removeAll(); + CompletableFuture deleteAll(); } diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java index b83bc3e47..982388a22 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java @@ -30,12 +30,12 @@ public CompletableFuture save(ParcelContent parcelContent) { } @Override - public CompletableFuture remove(UUID uniqueId) { + public CompletableFuture delete(UUID uniqueId) { return this.deleteById(ParcelContentTable.class, uniqueId); } @Override - public CompletableFuture removeAll() { + public CompletableFuture deleteAll() { return this.deleteAll(ParcelContentTable.class); } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java index b31284fd2..67e720b9e 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java @@ -1,7 +1,6 @@ package com.eternalcode.parcellockers.delivery.repository; import com.eternalcode.parcellockers.delivery.Delivery; - import java.util.List; import java.util.Optional; import java.util.UUID; @@ -13,7 +12,7 @@ public interface DeliveryRepository { CompletableFuture> find(UUID parcel); - CompletableFuture remove(UUID parcel); + CompletableFuture delete(UUID parcel); CompletableFuture>> findAll(); } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java index d4be00c68..8864b109b 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java @@ -42,7 +42,7 @@ public CompletableFuture>> findAll() { } @Override - public CompletableFuture remove(UUID parcel) { + public CompletableFuture delete(UUID parcel) { return this.deleteById(DeliveryTable.class, parcel); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index 66a6b4a31..fc2316f75 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -1,14 +1,16 @@ package com.eternalcode.parcellockers.gui.implementation.locker; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; -import com.eternalcode.parcellockers.parcel.ParcelManager; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import com.eternalcode.parcellockers.user.repository.UserRepository; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; @@ -18,8 +20,6 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; - public class LockerMainGui implements GuiView { private final Plugin plugin; @@ -32,9 +32,9 @@ public class LockerMainGui implements GuiView { private final ParcelContentRepository parcelContentRepository; private final UserRepository userRepository; private final SkullAPI skullAPI; - private final ParcelManager parcelManager; + private final ParcelService parcelService; - private final UserManager userManager; + private final UserService userService; public LockerMainGui( Plugin plugin, @@ -47,7 +47,7 @@ public LockerMainGui( ParcelContentRepository parcelContentRepository, UserRepository userRepository, SkullAPI skullAPI, - ParcelManager parcelManager + ParcelService parcelService ) { this.plugin = plugin; this.miniMessage = miniMessage; @@ -59,9 +59,9 @@ public LockerMainGui( this.parcelContentRepository = parcelContentRepository; this.userRepository = userRepository; this.skullAPI = skullAPI; - this.parcelManager = parcelManager; + this.parcelService = parcelService; - this.userManager = new UserManager(this.userRepository); + this.userService = new UserService(this.userRepository); } @Override @@ -94,8 +94,8 @@ public void show(Player player) { this.plugin.getServer().getScheduler(), this.parcelRepository, this.miniMessage, - this.parcelManager, - this.userManager, + this.parcelService, + this.userService, this.lockerRepository ); @@ -110,7 +110,7 @@ public void show(Player player) { this.parcelContentRepository, this.userRepository, this.skullAPI, - this.parcelManager, + this.parcelService, new ParcelSendingGuiState() ).show(player))); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java index 73d5fa887..4dcbcccfb 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java @@ -5,13 +5,13 @@ import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelManager; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import com.eternalcode.parcellockers.util.InventoryUtil; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -33,8 +33,8 @@ public class ParcelCollectionGui implements GuiView { private final BukkitScheduler scheduler; private final ParcelRepository parcelRepository; private final MiniMessage miniMessage; - private final ParcelManager parcelManager; - private final UserManager userManager; + private final ParcelService parcelService; + private final UserService userService; private final LockerRepository lockerRepository; public ParcelCollectionGui( @@ -43,8 +43,8 @@ public ParcelCollectionGui( BukkitScheduler scheduler, ParcelRepository parcelRepository, MiniMessage miniMessage, - ParcelManager parcelManager, - UserManager userManager, + ParcelService parcelService, + UserService userService, LockerRepository lockerRepository ) { this.plugin = plugin; @@ -52,8 +52,8 @@ public ParcelCollectionGui( this.scheduler = scheduler; this.parcelRepository = parcelRepository; this.miniMessage = miniMessage; - this.parcelManager = parcelManager; - this.userManager = userManager; + this.parcelService = parcelService; + this.userService = userService; this.lockerRepository = lockerRepository; } @@ -118,12 +118,12 @@ private void show(Player player, Page page) { ConfigItem item = parcelItem.clone(); item.name = item.name.replace("{NAME}", parcel.name()); - item.lore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userManager, this.lockerRepository); + item.lore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userService, this.lockerRepository); item.setGlow(true); gui.addItem(item.toGuiItem(event -> { - this.parcelManager.collectParcel(player, parcel); + this.parcelService.collect(player, parcel); gui.removeItem(event.getSlot()); InventoryUtil.shiftItems(event.getSlot(), gui, item.type); gui.update(); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java index 941bd1bc7..5503bb598 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java @@ -7,7 +7,7 @@ import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; -import com.eternalcode.parcellockers.parcel.ParcelManager; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; @@ -16,6 +16,9 @@ import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.StorageGui; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Material; import org.bukkit.Sound; @@ -23,10 +26,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.IntStream; - public class ParcelItemStorageGui { private final Plugin plugin; @@ -40,7 +39,7 @@ public class ParcelItemStorageGui { private final UserRepository userRepository; private final SkullAPI skullAPI; private final ParcelSendingGuiState state; - private final ParcelManager parcelManager; + private final ParcelService parcelService; public ParcelItemStorageGui( Plugin plugin, @@ -53,7 +52,7 @@ public ParcelItemStorageGui( ParcelContentRepository parcelContentRepository, UserRepository userRepository, SkullAPI skullAPI, - ParcelSendingGuiState state, ParcelManager parcelManager + ParcelSendingGuiState state, ParcelService parcelService ) { this.plugin = plugin; this.config = config; @@ -66,7 +65,7 @@ public ParcelItemStorageGui( this.userRepository = userRepository; this.skullAPI = skullAPI; this.state = state; - this.parcelManager = parcelManager; + this.parcelService = parcelService; } void show(Player player, ParcelSize size) { @@ -86,7 +85,7 @@ void show(Player player, ParcelSize size) { this.parcelContentRepository, this.userRepository, this.skullAPI, - this.parcelManager, + this.parcelService, this.state ).show(player)); @@ -134,7 +133,7 @@ void show(Player player, ParcelSize size) { items.add(item); } - this.itemStorageRepository.remove(player.getUniqueId()).thenAccept(unused -> { + this.itemStorageRepository.delete(player.getUniqueId()).thenAccept(unused -> { this.itemStorageRepository.save(new ItemStorage(player.getUniqueId(), items)); }).whenComplete(SentryExceptionHandler.handler()); }); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java index 54a195684..987fa2204 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java @@ -9,7 +9,7 @@ import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelManager; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.user.repository.UserRepository; @@ -59,7 +59,7 @@ public class ParcelSendingGui implements GuiView { private final ParcelContentRepository parcelContentRepository; private final UserRepository userRepository; private final SkullAPI skullAPI; - private final ParcelManager parcelManager; + private final ParcelService parcelService; private final ParcelSendingGuiState state; @@ -76,7 +76,7 @@ public ParcelSendingGui( ParcelContentRepository parcelContentRepository, UserRepository userRepository, SkullAPI skullAPI, - ParcelManager parcelManager, + ParcelService parcelService, ParcelSendingGuiState state ) { this.plugin = plugin; @@ -89,7 +89,7 @@ public ParcelSendingGui( this.parcelContentRepository = parcelContentRepository; this.userRepository = userRepository; this.skullAPI = skullAPI; - this.parcelManager = parcelManager; + this.parcelService = parcelService; this.state = state; this.scheduler = this.plugin.getServer().getScheduler(); } @@ -194,7 +194,7 @@ public void show(Player player) { this.userRepository, this.skullAPI, this.state, - this.parcelManager + this.parcelService ); this.itemStorageRepository.find(player.getUniqueId()).thenAccept(result -> { if (result.isPresent()) { @@ -230,8 +230,10 @@ public void show(Player player) { this.state.getParcelDescription(), this.state.isPriority(), this.state.getReceiver(), this.state.getSize(), this.state.getEntryLocker(), this.state.getDestinationLocker(), this.state.getStatus()); - this.parcelManager.sendParcel(player, parcel, result.get().items()) - .thenRun(() -> this.itemStorageRepository.remove(player.getUniqueId())); + if (this.parcelService.send(player, parcel, result.get().items())) { + this.itemStorageRepository.delete(player.getUniqueId()); + } + this.gui.close(player); }).orTimeout(5, TimeUnit.SECONDS)); @@ -246,7 +248,7 @@ public void show(Player player) { this.parcelContentRepository, this.userRepository, this.skullAPI, - this.parcelManager + this.parcelService ).show(player)); ConfigItem smallButton = guiSettings.smallParcelSizeItem; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index b181fe465..64b9f689c 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -1,10 +1,12 @@ package com.eternalcode.parcellockers.gui.implementation.remote; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -12,8 +14,6 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; - public class MainGui implements GuiView { private final Plugin plugin; @@ -22,7 +22,7 @@ public class MainGui implements GuiView { private final PluginConfiguration config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final UserManager userManager; + private final UserService userService; public MainGui( Plugin plugin, @@ -31,7 +31,7 @@ public MainGui( PluginConfiguration config, ParcelRepository parcelRepository, LockerRepository lockerRepository, - UserManager userManager + UserService userService ) { this.plugin = plugin; this.server = server; @@ -39,7 +39,7 @@ public MainGui( this.config = config; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.userManager = userManager; + this.userService = userService; } @Override @@ -73,8 +73,8 @@ public void show(Player player) { gui.setItem(24, parcelArchiveItem); gui.setItem(40, closeItem); - gui.addSlotAction(20, event -> new ParcelListGui(this.plugin, this.server, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userManager, this).show(player)); - gui.addSlotAction(22, event -> new SentParcelsGui(this.plugin, this.server, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userManager).show(player)); + gui.addSlotAction(20, event -> new ParcelListGui(this.plugin, this.server, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userService, this).show(player)); + gui.addSlotAction(22, event -> new SentParcelsGui(this.plugin, this.server, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userService).show(player)); gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.open(player); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 18fd5c568..45d13e18f 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -1,5 +1,7 @@ package com.eternalcode.parcellockers.gui.implementation.remote; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.parcellockers.configuration.implementation.ConfigItem; import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; import com.eternalcode.parcellockers.gui.GuiView; @@ -9,21 +11,18 @@ import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; +import java.util.List; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import java.util.List; - -import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; - public class ParcelListGui implements GuiView { private static final int WIDTH = 7; @@ -35,7 +34,7 @@ public class ParcelListGui implements GuiView { private final PluginConfiguration config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final UserManager userManager; + private final UserService userService; private final MainGui mainGUI; public ParcelListGui( @@ -45,7 +44,7 @@ public ParcelListGui( PluginConfiguration config, ParcelRepository parcelRepository, LockerRepository lockerRepository, - UserManager userManager, + UserService userService, MainGui mainGUI ) { this.plugin = plugin; @@ -54,7 +53,7 @@ public ParcelListGui( this.config = config; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.userManager = userManager; + this.userService = userService; this.mainGUI = mainGUI; } @@ -94,7 +93,7 @@ private void show(Player player, Page page) { for (Parcel parcel : result.parcels()) { ItemBuilder parcelItem = item.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userManager, this.lockerRepository).stream() + List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userService, this.lockerRepository).stream() .map(line -> resetItalic(this.miniMessage.deserialize(line))) .toList(); parcelItem.lore(newLore); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 7b377f367..9d279ef71 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -8,20 +8,19 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; +import java.util.Collections; +import java.util.List; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import java.util.Collections; -import java.util.List; - public class SentParcelsGui implements GuiView { private final Plugin plugin; @@ -31,7 +30,7 @@ public class SentParcelsGui implements GuiView { private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; private final MainGui mainGUI; - private final UserManager userManager; + private final UserService userService; public SentParcelsGui( Plugin plugin, @@ -41,7 +40,7 @@ public SentParcelsGui( ParcelRepository parcelRepository, LockerRepository lockerRepository, MainGui mainGUI, - UserManager userManager + UserService userService ) { this.plugin = plugin; this.server = server; @@ -50,7 +49,7 @@ public SentParcelsGui( this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; this.mainGUI = mainGUI; - this.userManager = userManager; + this.userService = userService; } @Override @@ -83,7 +82,7 @@ public void show(Player player) { for (Parcel parcel : parcels) { ItemBuilder item = parcelItem.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore, this.userManager, this.lockerRepository) + List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore, this.userService, this.lockerRepository) .stream() .map(line -> this.miniMessage.deserialize(line)) .toList(); diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java index 4db6df69a..22b09f516 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java @@ -1,7 +1,6 @@ package com.eternalcode.parcellockers.itemstorage.repository; import com.eternalcode.parcellockers.itemstorage.ItemStorage; - import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -12,7 +11,7 @@ public interface ItemStorageRepository { CompletableFuture> find(UUID uuid); - CompletableFuture remove(UUID uuid); + CompletableFuture delete(UUID uuid); - CompletableFuture removeAll(); + CompletableFuture deleteAll(); } diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java index 6914286c9..a0e693ef5 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java @@ -35,12 +35,12 @@ public CompletableFuture> find(UUID uuid) { } @Override - public CompletableFuture remove(UUID uuid) { + public CompletableFuture delete(UUID uuid) { return this.deleteById(ItemStorageTable.class, uuid); } @Override - public CompletableFuture removeAll() { + public CompletableFuture deleteAll() { return this.deleteAll(ItemStorageTable.class); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java index 9b76d54fb..c007b36da 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java @@ -63,7 +63,7 @@ public void onBlockBreak(BlockBreakEvent event) { } UUID toRemove = this.cache.get(position).get().uuid(); - this.lockerRepository.remove(toRemove); + this.lockerRepository.delete(toRemove); this.announcer.sendMessage(player, this.messages.parcelLockerSuccessfullyDeleted); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java index 3bd439848..7230ee4f8 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java @@ -2,17 +2,30 @@ import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.shared.Position; - +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.time.Duration; import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; public class LockerCache { - private final Map cache = new ConcurrentHashMap<>(); - private final Map positionCache = new ConcurrentHashMap<>(); + private final Cache cache; + private final Cache positionCache; + + public LockerCache() { + this.cache = Caffeine.newBuilder() + .maximumSize(10_000) + .expireAfterAccess(Duration.ofHours(2)) + .build(); + + this.positionCache = Caffeine.newBuilder() + .maximumSize(10_000) + .expireAfterAccess(Duration.ofHours(2)) + .build(); + } public void put(Locker locker) { this.cache.put(locker.uuid(), locker); @@ -25,33 +38,38 @@ public void putAll(Map lockers) { } public Locker remove(UUID uuid) { - this.positionCache.remove(this.cache.get(uuid).position()); - return this.cache.remove(uuid); + Locker locker = this.cache.getIfPresent(uuid); + if (locker != null) { + this.positionCache.invalidate(locker.position()); + this.cache.invalidate(uuid); + } + return locker; } public Locker remove(Locker locker) { - this.positionCache.remove(locker.position()); - return this.cache.remove(locker.uuid()); + this.positionCache.invalidate(locker.position()); + this.cache.invalidate(locker.uuid()); + return locker; } public Map cache() { - return Collections.unmodifiableMap(this.cache); + return Collections.unmodifiableMap(this.cache.asMap()); } public Map positionCache() { - return Collections.unmodifiableMap(this.positionCache); + return Collections.unmodifiableMap(this.positionCache.asMap()); } public Optional get(UUID uuid) { - return Optional.ofNullable(this.cache.get(uuid)); + return Optional.ofNullable(this.cache.getIfPresent(uuid)); } public Optional get(Position position) { - return Optional.ofNullable(this.positionCache.get(position)); + return Optional.ofNullable(this.positionCache.getIfPresent(position)); } public void clear() { - this.cache.clear(); - this.positionCache.clear(); + this.cache.invalidateAll(); + this.positionCache.invalidateAll(); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java index 0e5e1f5ef..8f12ab2f3 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java @@ -12,17 +12,17 @@ public interface LockerRepository { CompletableFuture save(Locker locker); - CompletableFuture> findAll(); + CompletableFuture>> findAll(); CompletableFuture> find(UUID uuid); CompletableFuture> find(Position position); - CompletableFuture remove(UUID uuid); + CompletableFuture delete(UUID uuid); - CompletableFuture remove(Locker locker); + CompletableFuture delete(Locker locker); - CompletableFuture removeAll(); + CompletableFuture deleteAll(); CompletableFuture findPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index 8746d3b7d..48c365ae5 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -9,12 +9,12 @@ import com.j256.ormlite.table.TableUtils; import io.sentry.Sentry; import java.sql.SQLException; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; public class LockerRepositoryOrmLite extends AbstractRepositoryOrmLite implements LockerRepository { @@ -43,10 +43,10 @@ public CompletableFuture save(Locker locker) { } @Override - public CompletableFuture> findAll() { - return this.selectAll(LockerTable.class).thenApply(lockers -> lockers.stream() + public CompletableFuture>> findAll() { + return this.selectAll(LockerTable.class).thenApply(lockers -> Optional.of(lockers.stream() .map(LockerTable::toLocker) - .collect(Collectors.toList())); + .collect(Collectors.toList()))); } @Override @@ -65,7 +65,7 @@ public CompletableFuture> find(Position position) { } @Override - public CompletableFuture remove(UUID uuid) { + public CompletableFuture delete(UUID uuid) { return this.deleteById(LockerTable.class, uuid) .thenApply(result -> { if (result > 0) { @@ -76,8 +76,8 @@ public CompletableFuture remove(UUID uuid) { } @Override - public CompletableFuture remove(Locker locker) { - return this.remove(locker.uuid()); + public CompletableFuture delete(Locker locker) { + return this.delete(locker.uuid()); } @Override @@ -101,16 +101,18 @@ public CompletableFuture findPage(Page page) { } @Override - public CompletableFuture removeAll() { + public CompletableFuture deleteAll() { return this.deleteAll(LockerTable.class); } public void updateCaches() { this.findAll().thenAccept(lockers -> { - Map newCache = new ConcurrentHashMap<>(); - lockers.forEach(locker -> newCache.put(locker.uuid(), locker)); - this.cache.clear(); - this.cache.putAll(newCache); + Map newCache = new HashMap<>(); + if (lockers.isPresent()) { + lockers.get().forEach(locker -> newCache.put(locker.uuid(), locker)); + this.cache.clear(); + this.cache.putAll(newCache); + } }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelManager.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java similarity index 51% rename from src/main/java/com/eternalcode/parcellockers/parcel/ParcelManager.java rename to src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index e4e29c0cd..b46b017f4 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelManager.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -12,19 +12,17 @@ import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; +import com.eternalcode.parcellockers.shared.ParcelLockersException; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import java.time.Duration; import java.time.Instant; import java.util.List; -import java.util.concurrent.CompletableFuture; import org.bukkit.Sound; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import panda.std.Blank; -import panda.std.Result; -public class ParcelManager { +public class ParcelService { private final PluginConfiguration config; private final NotificationAnnouncer announcer; @@ -33,13 +31,13 @@ public class ParcelManager { private final ParcelContentRepository parcelContentRepository; private final Scheduler scheduler; - public ParcelManager( - PluginConfiguration config, - NotificationAnnouncer announcer, - ParcelRepository parcelRepository, - DeliveryRepository deliveryRepository, - ParcelContentRepository parcelContentRepository, - Scheduler scheduler + public ParcelService( + PluginConfiguration config, + NotificationAnnouncer announcer, + ParcelRepository parcelRepository, + DeliveryRepository deliveryRepository, + ParcelContentRepository parcelContentRepository, + Scheduler scheduler ) { this.config = config; this.announcer = announcer; @@ -49,78 +47,78 @@ public ParcelManager( this.scheduler = scheduler; } - public CompletableFuture> sendParcel(CommandSender sender, Parcel parcel, List items) { + public boolean send(Player sender, Parcel parcel, List items) { Duration delay = parcel.priority() ? config.settings.priorityParcelSendDuration : config.settings.parcelSendDuration; - parcelRepository.save(parcel); + this.parcelRepository.save(parcel); - return parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)) - .handle((content, throwable) -> { - if (throwable != null) { - announcer.sendMessage(sender, config.messages.parcelFailedToSend); - return Result.error(throwable); - } - - announcer.sendMessage(sender, config.messages.parcelSent); - - scheduler.runLaterAsync( - new ParcelSendTask( - parcel, - new Delivery(parcel.uuid(), Instant.now().plus(delay)), - parcelRepository, - deliveryRepository, - config - ), - delay - ); + parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { + if (throwable != null) { + announcer.sendMessage(sender, config.messages.parcelFailedToSend); + throw new ParcelLockersException("Failed to save parcel content", throwable); + } + announcer.sendMessage(sender, config.messages.parcelSent); - return Result.ok(); - }); + Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); + ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); + scheduler.runLaterAsync(task, delay); + return true; + }); + return true; } - public void deleteParcel(CommandSender sender, Parcel parcel) { - this.parcelRepository.remove(parcel).thenAccept(v -> - this.announcer.sendMessage(sender, this.config.messages.parcelSuccessfullyDeleted) - ).whenComplete(SentryExceptionHandler.handler().andThen((v, throwable) -> { + public void remove(CommandSender sender, Parcel parcel) { + this.parcelRepository.remove(parcel) + .thenAccept(v -> announcer.sendMessage(sender, config.messages.parcelSuccessfullyDeleted)) + .whenComplete((v, throwable) -> { if (throwable != null) { - this.announcer.sendMessage(sender, this.config.messages.failedToDeleteParcel); + announcer.sendMessage(sender, config.messages.failedToDeleteParcel); } - } - )); + }); } - public void collectParcel(Player player, Parcel parcel) { + public void collect(Player player, Parcel parcel) { this.parcelContentRepository.find(parcel.uuid()).thenAccept(optional -> { if (optional.isEmpty()) { - player.playSound(player.getLocation(), this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); + playErrorSound(player); this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); return; } List items = optional.get().items(); if (items.size() > freeSlotsInInventory(player)) { - player.playSound(player.getLocation(), this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); + playErrorSound(player); this.announcer.sendMessage(player, this.config.messages.notEnoughInventorySpace); return; } - for (ItemStack item : items) { - this.scheduler.run(() -> ItemUtil.giveItem(player, item)); - } + items.forEach(item -> this.scheduler.run(() -> ItemUtil.giveItem(player, item))); this.parcelRepository.remove(parcel) - .thenCompose(v -> this.parcelContentRepository.remove(optional.get().uniqueId())) + .thenCompose(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) .whenComplete(SentryExceptionHandler.handler().andThen((v, throwable) -> { - if (throwable != null) { - this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); - return; - } - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5F, 1); + if (throwable != null) { + this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); + } else { + playSuccessSound(player); this.announcer.sendMessage(player, this.config.messages.parcelSuccessfullyCollected); } - )); + })); }); } + + private void playErrorSound(Player player) { + player.playSound( + player.getLocation(), + this.config.settings.errorSound, + this.config.settings.errorSoundVolume, + this.config.settings.errorSoundPitch + ); + } + + private void playSuccessSound(Player player) { + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5F, 1); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java index e27f1cf44..b1092ef38 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java @@ -6,19 +6,19 @@ import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelManager; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import dev.rollczi.litecommands.annotations.argument.Arg; import dev.rollczi.litecommands.annotations.async.Async; import dev.rollczi.litecommands.annotations.command.Command; import dev.rollczi.litecommands.annotations.context.Context; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; -import org.bukkit.entity.Player; - import java.util.List; +import org.bukkit.entity.Player; +@SuppressWarnings({"unused", "ClassCanBeRecord"}) @Command(name = "parcel") @Permission("parcellockers.command.parcel") public class ParcelCommand { @@ -28,8 +28,8 @@ public class ParcelCommand { private final PluginConfiguration config; private final MainGui mainGUI; private final ParcelListGui parcelListGUI; - private final ParcelManager parcelManager; - private final UserManager userManager; + private final ParcelService parcelService; + private final UserService userService; public ParcelCommand( LockerRepository lockerRepository, @@ -37,16 +37,16 @@ public ParcelCommand( PluginConfiguration config, MainGui mainGUI, ParcelListGui parcelListGUI, - ParcelManager parcelManager, - UserManager userManager + ParcelService parcelService, + UserService userService ) { this.lockerRepository = lockerRepository; this.announcer = announcer; this.config = config; this.mainGUI = mainGUI; this.parcelListGUI = parcelListGUI; - this.parcelManager = parcelManager; - this.userManager = userManager; + this.parcelService = parcelService; + this.userService = userService; } @Execute(name = "list") @@ -57,13 +57,13 @@ void list(@Context Player player) { @Async @Execute(name = "info") void info(@Context Player player, @Arg Parcel parcel) { - List messagesToSend = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, this.config.messages.parcelInfoMessages, this.userManager, this.lockerRepository); + List messagesToSend = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, this.config.messages.parcelInfoMessages, this.userService, this.lockerRepository); messagesToSend.forEach(message -> this.announcer.sendMessage(player, message)); } @Execute(name = "delete") void delete(@Context Player player, @Arg Parcel parcel) { - this.parcelManager.deleteParcel(player, parcel); + this.parcelService.remove(player, parcel); } @Execute(name = "gui") diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java index dffcd833a..47247215d 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java @@ -1,38 +1,50 @@ package com.eternalcode.parcellockers.parcel.repository; import com.eternalcode.parcellockers.parcel.Parcel; - +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.time.Duration; import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; public class ParcelCache { - private final Map cache = new ConcurrentHashMap<>(); + private final Cache cache; + + public ParcelCache() { + this.cache = Caffeine.newBuilder() + .maximumSize(10_000) + .expireAfterAccess(Duration.ofHours(2)) + .build(); + } public void put(Parcel parcel) { - cache.put(parcel.uuid(), parcel); + this.cache.put(parcel.uuid(), parcel); } public void putAll(Map parcels) { - cache.putAll(parcels); + this.cache.putAll(parcels); } public Optional get(UUID uuid) { - return Optional.ofNullable(cache.get(uuid)); + return Optional.ofNullable(this.cache.getIfPresent(uuid)); } - public void remove(UUID uuid) { - cache.remove(uuid); + public Parcel remove(UUID uuid) { + Parcel parcel = this.cache.getIfPresent(uuid); + if (parcel != null) { + this.cache.invalidate(uuid); + } + return parcel; } public void clear() { - cache.clear(); + this.cache.invalidateAll(); } public Map cache() { - return Collections.unmodifiableMap(cache); + return Collections.unmodifiableMap(this.cache.asMap()); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java index 4818fdf54..409e97884 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java @@ -1,9 +1,11 @@ package com.eternalcode.parcellockers.parcel.repository; import com.eternalcode.parcellockers.parcel.Parcel; - import java.util.List; public record ParcelPageResult(List parcels, boolean hasNextPage) { + public static ParcelPageResult empty() { + return new ParcelPageResult(List.of(), false); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelTable.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelTable.java index f7abcfb77..005922116 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelTable.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelTable.java @@ -43,7 +43,17 @@ class ParcelTable { ParcelTable() { } - ParcelTable(UUID uuid, UUID sender, String name, String description, boolean priority, UUID receiver, ParcelSize size, UUID entryLocker, UUID destinationLocker, ParcelStatus status) { + ParcelTable( + UUID uuid, + UUID sender, + String name, + String description, + boolean priority, + UUID receiver, + ParcelSize size, + UUID entryLocker, + UUID destinationLocker, + ParcelStatus status) { this.uuid = uuid; this.sender = sender; this.name = name; @@ -57,10 +67,30 @@ class ParcelTable { } static ParcelTable from(Parcel parcel) { - return new ParcelTable(parcel.uuid(), parcel.sender(), parcel.name(), parcel.description(), parcel.priority(), parcel.receiver(), parcel.size(), parcel.entryLocker(), parcel.destinationLocker(), parcel.status()); + return new ParcelTable( + parcel.uuid(), + parcel.sender(), + parcel.name(), + parcel.description(), + parcel.priority(), + parcel.receiver(), + parcel.size(), + parcel.entryLocker(), + parcel.destinationLocker(), + parcel.status()); } Parcel toParcel() { - return new Parcel(this.uuid, this.sender, this.name, this.description, this.priority, this.receiver, this.size, this.entryLocker, this.destinationLocker, this.status); + return new Parcel( + this.uuid, + this.sender, + this.name, + this.description, + this.priority, + this.receiver, + this.size, + this.entryLocker, + this.destinationLocker, + this.status); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java index 6e758a62f..86816684d 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java @@ -46,7 +46,7 @@ public void run() { this.parcelRepository.update(updated); - this.deliveryRepository.remove(updated.uuid()); + this.deliveryRepository.delete(updated.uuid()); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java index f5b13b070..2c76e6b5d 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java @@ -3,7 +3,7 @@ import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -17,13 +17,13 @@ public class ParcelPlaceholderUtil { @Blocking - public static List replaceParcelPlaceholders(Parcel parcel, List lore, UserManager userManager, LockerRepository lockerRepository) { + public static List replaceParcelPlaceholders(Parcel parcel, List lore, UserService userService, LockerRepository lockerRepository) { if (lore == null || lore.isEmpty()) { return Collections.emptyList(); } - String senderName = getName(parcel.sender(), userManager).join(); - String receiver = getName(parcel.receiver(), userManager).join(); + String senderName = getName(parcel.sender(), userService).join(); + String receiver = getName(parcel.receiver(), userService).join(); Formatter formatter = new Formatter() .register("{UUID}", parcel.uuid().toString()) @@ -58,8 +58,8 @@ public static List replaceParcelPlaceholders(Parcel parcel, List return newLore; } - private static CompletableFuture getName(UUID userUuid, UserManager userManager) { - return userManager.get(userUuid).thenApply(userOptional -> userOptional + private static CompletableFuture getName(UUID userUuid, UserService userService) { + return userService.get(userUuid).thenApply(userOptional -> userOptional .map(user -> user.name()) .orElse("Unknown") ); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java b/src/main/java/com/eternalcode/parcellockers/user/UserService.java similarity index 87% rename from src/main/java/com/eternalcode/parcellockers/user/UserManager.java rename to src/main/java/com/eternalcode/parcellockers/user/UserService.java index 29c08de8c..24dcad51c 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserService.java @@ -1,22 +1,20 @@ package com.eternalcode.parcellockers.user; import com.eternalcode.parcellockers.user.repository.UserRepository; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public class UserManager { +public class UserService { private final UserRepository userRepository; private final Map usersByUUID = new HashMap<>(); private final Map usersByName = new HashMap<>(); - public UserManager(UserRepository userRepository) { + public UserService(UserRepository userRepository) { this.userRepository = userRepository; } @@ -68,8 +66,4 @@ public User create(UUID uuid, String name) { return user; } - - public Collection getUsers() { - return Collections.unmodifiableCollection(this.usersByUUID.values()); - } } diff --git a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java index adec0e29d..2c20e17c0 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java +++ b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.user.controller; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -9,18 +9,18 @@ public class LoadUserController implements Listener { - private final UserManager userManager; + private final UserService userService; private final Server server; - public LoadUserController(UserManager userManager, Server server) { - this.userManager = userManager; + public LoadUserController(UserService userService, Server server) { + this.userService = userService; this.server = server; } @EventHandler void onLoad(ServerLoadEvent event) { for (Player player : this.server.getOnlinePlayers()) { - this.userManager.create(player.getUniqueId(), player.getName()); + this.userService.create(player.getUniqueId(), player.getName()); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java b/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java index b144ca629..93dd8e66e 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java +++ b/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.user.controller; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserService; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -8,16 +8,16 @@ public class PrepareUserController implements Listener { - private final UserManager userManager; + private final UserService userService; - public PrepareUserController(UserManager userManager) { - this.userManager = userManager; + public PrepareUserController(UserService userService) { + this.userService = userService; } @EventHandler void onJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - this.userManager.getOrCreate(player.getUniqueId(), player.getName()); + this.userService.getOrCreate(player.getUniqueId(), player.getName()); } } diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java index 38a9bf151..c375f0603 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java @@ -1,9 +1,8 @@ package com.eternalcode.parcellockers.user.repository; import com.eternalcode.parcellockers.user.User; - import java.util.List; -public record UserPageResult(List users, boolean hasNextPage) { +record UserPageResult(List users, boolean hasNextPage) { } diff --git a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java index 2b2a35750..68e6ecdb1 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java @@ -66,7 +66,7 @@ void test() { assertEquals(1, pageResult.lockers().size()); assertEquals(uuid, pageResult.lockers().getFirst().uuid()); - await(parcelLockerRepository.remove(uuid)); + await(parcelLockerRepository.delete(uuid)); Optional removed = await(parcelLockerRepository.find(uuid)); assertTrue(removed.isEmpty()); } diff --git a/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java b/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java new file mode 100644 index 000000000..6f5bf581c --- /dev/null +++ b/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java @@ -0,0 +1,140 @@ +package com.eternalcode.parcellockers.locker.repository; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.eternalcode.parcellockers.locker.Locker; +import com.eternalcode.parcellockers.shared.Position; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class LockerCacheTest { + + private LockerCache lockerCache; + private Locker testLocker; + private Position testPosition; + + @BeforeEach + void setUp() { + lockerCache = new LockerCache(); + testPosition = new Position(10, 20, 30, "world"); + testLocker = new Locker(UUID.randomUUID(), "Test locker", testPosition); + } + + @Test + void shouldPutAndGetLockerByUuid() { + // given + lockerCache.put(testLocker); + + // when + Optional result = lockerCache.get(testLocker.uuid()); + + // then + assertTrue(result.isPresent()); + assertEquals(testLocker, result.get()); + } + + @Test + void shouldPutAndGetLockerByPosition() { + // given + lockerCache.put(testLocker); + + // when + Optional result = lockerCache.get(testPosition); + + // then + assertTrue(result.isPresent()); + assertEquals(testLocker, result.get()); + } + + @Test + void shouldRemoveLockerByUuid() { + // given + lockerCache.put(testLocker); + + // when + Locker removed = lockerCache.remove(testLocker.uuid()); + + // then + assertEquals(testLocker, removed); + assertFalse(lockerCache.get(testLocker.uuid()).isPresent()); + assertFalse(lockerCache.get(testPosition).isPresent()); + } + + @Test + void shouldRemoveLockerByObject() { + // given + lockerCache.put(testLocker); + + // when + Locker removed = lockerCache.remove(testLocker); + + // then + assertEquals(testLocker, removed); + assertFalse(lockerCache.get(testLocker.uuid()).isPresent()); + assertFalse(lockerCache.get(testPosition).isPresent()); + } + + @Test + void shouldPutAllLockers() { + // given + Locker locker1 = new Locker(UUID.randomUUID(), "Locker 1", new Position(1, 2, 3, "world")); + Locker locker2 = new Locker(UUID.randomUUID(), "Locker 2", new Position(4, 5, 6, "world")); + Map lockers = Map.of( + locker1.uuid(), locker1, + locker2.uuid(), locker2 + ); + + // when + lockerCache.putAll(lockers); + + // then + assertTrue(lockerCache.get(locker1.uuid()).isPresent()); + assertTrue(lockerCache.get(locker2.uuid()).isPresent()); + assertTrue(lockerCache.get(locker1.position()).isPresent()); + assertTrue(lockerCache.get(locker2.position()).isPresent()); + } + + @Test + void shouldClearCache() { + // given + lockerCache.put(testLocker); + + // when + lockerCache.clear(); + + // then + assertFalse(lockerCache.get(testLocker.uuid()).isPresent()); + assertFalse(lockerCache.get(testPosition).isPresent()); + assertEquals(0, lockerCache.cache().size()); + } + + @Test + void shouldReturnCorrectSize() { + // given + lockerCache.put(testLocker); + + // when & then + assertEquals(1, lockerCache.cache().size()); + assertEquals(1, lockerCache.positionCache().size()); + } + + @Test + void shouldReturnUnmodifiableMaps() { + // given + lockerCache.put(testLocker); + + // when + Map cache = lockerCache.cache(); + Map positionCache = lockerCache.positionCache(); + + // then + assertThrows(UnsupportedOperationException.class, () -> cache.clear()); + assertThrows(UnsupportedOperationException.class, () -> positionCache.clear()); + } +} diff --git a/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java b/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java new file mode 100644 index 000000000..b08b59f86 --- /dev/null +++ b/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java @@ -0,0 +1,175 @@ +package com.eternalcode.parcellockers.parcel.repository; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.eternalcode.parcellockers.parcel.Parcel; +import com.eternalcode.parcellockers.parcel.ParcelSize; +import com.eternalcode.parcellockers.parcel.ParcelStatus; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ParcelCacheTest { + + private ParcelCache parcelCache; + private Parcel testParcel; + + @BeforeEach + void setUp() { + parcelCache = new ParcelCache(); + testParcel = new Parcel( + UUID.randomUUID(), + UUID.randomUUID(), + "Test Package", + "Test package description", + false, + UUID.randomUUID(), + ParcelSize.MEDIUM, + UUID.randomUUID(), + UUID.randomUUID(), + ParcelStatus.PENDING + ); + } + + @Test + void shouldPutAndGetParcel() { + // given + parcelCache.put(testParcel); + + // when + Optional result = parcelCache.get(testParcel.uuid()); + + // then + assertTrue(result.isPresent()); + assertEquals(testParcel, result.get()); + } + + @Test + void shouldReturnEmptyWhenParcelNotFound() { + // when + Optional result = parcelCache.get(UUID.randomUUID()); + + // then + assertFalse(result.isPresent()); + } + + @Test + void shouldRemoveParcel() { + // given + parcelCache.put(testParcel); + + // when + Parcel removed = parcelCache.remove(testParcel.uuid()); + + // then + assertEquals(testParcel, removed); + assertFalse(parcelCache.get(testParcel.uuid()).isPresent()); + } + + @Test + void shouldReturnNullWhenRemovingNonExistentParcel() { + // when + Parcel removed = parcelCache.remove(UUID.randomUUID()); + + // then + assertNull(removed); + } + + @Test + void shouldPutAllParcels() { + // given + Parcel parcel1 = new Parcel( + UUID.randomUUID(), + UUID.randomUUID(), + "Package 1", + "Description 1", + true, + UUID.randomUUID(), + ParcelSize.SMALL, + UUID.randomUUID(), + UUID.randomUUID(), + ParcelStatus.PENDING + ); + + Parcel parcel2 = new Parcel( + UUID.randomUUID(), + UUID.randomUUID(), + "Package 2", + "Description 2", + false, + UUID.randomUUID(), + ParcelSize.LARGE, + UUID.randomUUID(), + UUID.randomUUID(), + ParcelStatus.DELIVERED + ); + + Map parcels = Map.of( + parcel1.uuid(), parcel1, + parcel2.uuid(), parcel2 + ); + + // when + parcelCache.putAll(parcels); + + // then + assertTrue(parcelCache.get(parcel1.uuid()).isPresent()); + assertTrue(parcelCache.get(parcel2.uuid()).isPresent()); + assertEquals(2, parcelCache.cache().size()); + } + + @Test + void shouldClearCache() { + // given + parcelCache.put(testParcel); + + // when + parcelCache.clear(); + + // then + assertFalse(parcelCache.get(testParcel.uuid()).isPresent()); + assertEquals(0, parcelCache.cache().size()); + } + + @Test + void shouldReturnCorrectSize() { + // given + parcelCache.put(testParcel); + + // when & then + assertEquals(1, parcelCache.cache().size()); + } + + @Test + void shouldReturnUnmodifiableMap() { + // given + parcelCache.put(testParcel); + + // when + Map cache = parcelCache.cache(); + + // then + assertThrows(UnsupportedOperationException.class, () -> cache.clear()); + assertEquals(1, cache.size()); + assertTrue(cache.containsKey(testParcel.uuid())); + } + + @Test + void shouldWorkWithCustomConfiguration() { + // given + ParcelCache cache = new ParcelCache(); + + // when + cache.put(testParcel); + + // then + assertTrue(cache.get(testParcel.uuid()).isPresent()); + assertEquals(1, cache.cache().size()); + } +} From cfe5ecad7f84705fae49429049e558245c5fdb68 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:36:50 +0200 Subject: [PATCH 02/51] extract interfaces --- .../parcellockers/ParcelLockers.java | 6 +- .../implementation/locker/LockerMainGui.java | 3 +- .../parcellockers/parcel/ParcelService.java | 117 +--------------- .../parcel/ParcelServiceImpl.java | 127 ++++++++++++++++++ .../parcellockers/user/UserService.java | 64 +-------- .../parcellockers/user/UserServiceImpl.java | 73 ++++++++++ .../user/repository/UserPageResult.java | 2 +- 7 files changed, 216 insertions(+), 176 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java create mode 100644 src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 4e96704ee..22b6e064c 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -28,6 +28,7 @@ import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; +import com.eternalcode.parcellockers.parcel.ParcelServiceImpl; import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.command.ParcelCommand; import com.eternalcode.parcellockers.parcel.command.argument.ParcelArgument; @@ -36,6 +37,7 @@ import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.updater.UpdaterService; import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserServiceImpl; import com.eternalcode.parcellockers.user.controller.LoadUserController; import com.eternalcode.parcellockers.user.controller.PrepareUserController; import com.eternalcode.parcellockers.user.repository.UserRepository; @@ -146,12 +148,12 @@ public void onEnable() { DeliveryRepositoryOrmLite deliveryRepository = new DeliveryRepositoryOrmLite(databaseManager, scheduler); ParcelContentRepository parcelContentRepository = new ParcelContentRepositoryOrmLite(databaseManager, scheduler); - ParcelService parcelService = new ParcelService(config, announcer, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); + ParcelService parcelService = new ParcelServiceImpl(config, announcer, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); ItemStorageRepository itemStorageRepository = new ItemStorageRepositoryOrmLite(databaseManager, scheduler); UserRepository userRepository = new UserRepositoryOrmLite(databaseManager, scheduler); - UserService userService = new UserService(userRepository); + UserService userService = new UserServiceImpl(userRepository); MainGui mainGUI = new MainGui(this, server, miniMessage, config, parcelRepository, lockerRepository, userService); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index fc2316f75..3993215ae 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -11,6 +11,7 @@ import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserServiceImpl; import com.eternalcode.parcellockers.user.repository.UserRepository; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; @@ -61,7 +62,7 @@ public LockerMainGui( this.skullAPI = skullAPI; this.parcelService = parcelService; - this.userService = new UserService(this.userRepository); + this.userService = new UserServiceImpl(this.userRepository); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index b46b017f4..a4eed1fa8 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -1,124 +1,15 @@ package com.eternalcode.parcellockers.parcel; -import static com.eternalcode.parcellockers.util.InventoryUtil.freeSlotsInInventory; - -import com.eternalcode.commons.bukkit.ItemUtil; -import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; -import com.eternalcode.parcellockers.content.ParcelContent; -import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; -import com.eternalcode.parcellockers.delivery.Delivery; -import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; -import com.eternalcode.parcellockers.shared.ParcelLockersException; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import java.time.Duration; -import java.time.Instant; import java.util.List; -import org.bukkit.Sound; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class ParcelService { - - private final PluginConfiguration config; - private final NotificationAnnouncer announcer; - private final ParcelRepository parcelRepository; - private final DeliveryRepository deliveryRepository; - private final ParcelContentRepository parcelContentRepository; - private final Scheduler scheduler; - - public ParcelService( - PluginConfiguration config, - NotificationAnnouncer announcer, - ParcelRepository parcelRepository, - DeliveryRepository deliveryRepository, - ParcelContentRepository parcelContentRepository, - Scheduler scheduler - ) { - this.config = config; - this.announcer = announcer; - this.parcelRepository = parcelRepository; - this.deliveryRepository = deliveryRepository; - this.parcelContentRepository = parcelContentRepository; - this.scheduler = scheduler; - } - - public boolean send(Player sender, Parcel parcel, List items) { - Duration delay = parcel.priority() - ? config.settings.priorityParcelSendDuration - : config.settings.parcelSendDuration; - - this.parcelRepository.save(parcel); - - parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { - if (throwable != null) { - announcer.sendMessage(sender, config.messages.parcelFailedToSend); - throw new ParcelLockersException("Failed to save parcel content", throwable); - } - announcer.sendMessage(sender, config.messages.parcelSent); - - Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); - ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); - scheduler.runLaterAsync(task, delay); - return true; - }); - return true; - } - - public void remove(CommandSender sender, Parcel parcel) { - this.parcelRepository.remove(parcel) - .thenAccept(v -> announcer.sendMessage(sender, config.messages.parcelSuccessfullyDeleted)) - .whenComplete((v, throwable) -> { - if (throwable != null) { - announcer.sendMessage(sender, config.messages.failedToDeleteParcel); - } - }); - } - - public void collect(Player player, Parcel parcel) { - this.parcelContentRepository.find(parcel.uuid()).thenAccept(optional -> { - if (optional.isEmpty()) { - playErrorSound(player); - this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); - return; - } - - List items = optional.get().items(); - if (items.size() > freeSlotsInInventory(player)) { - playErrorSound(player); - this.announcer.sendMessage(player, this.config.messages.notEnoughInventorySpace); - return; - } - - items.forEach(item -> this.scheduler.run(() -> ItemUtil.giveItem(player, item))); +public interface ParcelService { - this.parcelRepository.remove(parcel) - .thenCompose(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) - .whenComplete(SentryExceptionHandler.handler().andThen((v, throwable) -> { - if (throwable != null) { - this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); - } else { - playSuccessSound(player); - this.announcer.sendMessage(player, this.config.messages.parcelSuccessfullyCollected); - } - })); - }); - } + void collect(Player player, Parcel parcel); - private void playErrorSound(Player player) { - player.playSound( - player.getLocation(), - this.config.settings.errorSound, - this.config.settings.errorSoundVolume, - this.config.settings.errorSoundPitch - ); - } + void remove(CommandSender sender, Parcel parcel); - private void playSuccessSound(Player player) { - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5F, 1); - } + boolean send(Player sender, Parcel parcel, List items); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java new file mode 100644 index 000000000..bf0a8fc40 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -0,0 +1,127 @@ +package com.eternalcode.parcellockers.parcel; + +import static com.eternalcode.parcellockers.util.InventoryUtil.freeSlotsInInventory; + +import com.eternalcode.commons.bukkit.ItemUtil; +import com.eternalcode.commons.scheduler.Scheduler; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.content.ParcelContent; +import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; +import com.eternalcode.parcellockers.delivery.Delivery; +import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; +import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; +import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; +import com.eternalcode.parcellockers.shared.ParcelLockersException; +import com.eternalcode.parcellockers.shared.SentryExceptionHandler; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import org.bukkit.Sound; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class ParcelServiceImpl implements ParcelService { + + private final PluginConfiguration config; + private final NotificationAnnouncer announcer; + private final ParcelRepository parcelRepository; + private final DeliveryRepository deliveryRepository; + private final ParcelContentRepository parcelContentRepository; + private final Scheduler scheduler; + + public ParcelServiceImpl( + PluginConfiguration config, + NotificationAnnouncer announcer, + ParcelRepository parcelRepository, + DeliveryRepository deliveryRepository, + ParcelContentRepository parcelContentRepository, + Scheduler scheduler + ) { + this.config = config; + this.announcer = announcer; + this.parcelRepository = parcelRepository; + this.deliveryRepository = deliveryRepository; + this.parcelContentRepository = parcelContentRepository; + this.scheduler = scheduler; + } + + @Override + public boolean send(Player sender, Parcel parcel, List items) { + Duration delay = parcel.priority() + ? config.settings.priorityParcelSendDuration + : config.settings.parcelSendDuration; + + this.parcelRepository.save(parcel); + + parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { + if (throwable != null) { + announcer.sendMessage(sender, config.messages.parcelFailedToSend); + throw new ParcelLockersException("Failed to save parcel content", throwable); + } + announcer.sendMessage(sender, config.messages.parcelSent); + + Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); + ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); + scheduler.runLaterAsync(task, delay); + return true; + }); + return true; + } + + @Override + public void remove(CommandSender sender, Parcel parcel) { + this.parcelRepository.remove(parcel) + .thenAccept(v -> announcer.sendMessage(sender, config.messages.parcelSuccessfullyDeleted)) + .whenComplete((v, throwable) -> { + if (throwable != null) { + announcer.sendMessage(sender, config.messages.failedToDeleteParcel); + } + }); + } + + @Override + public void collect(Player player, Parcel parcel) { + this.parcelContentRepository.find(parcel.uuid()).thenAccept(optional -> { + if (optional.isEmpty()) { + playErrorSound(player); + this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); + return; + } + + List items = optional.get().items(); + if (items.size() > freeSlotsInInventory(player)) { + playErrorSound(player); + this.announcer.sendMessage(player, this.config.messages.notEnoughInventorySpace); + return; + } + + items.forEach(item -> this.scheduler.run(() -> ItemUtil.giveItem(player, item))); + + this.parcelRepository.remove(parcel) + .thenCompose(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) + .whenComplete(SentryExceptionHandler.handler().andThen((v, throwable) -> { + if (throwable != null) { + this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); + } else { + playSuccessSound(player); + this.announcer.sendMessage(player, this.config.messages.parcelSuccessfullyCollected); + } + })); + }); + } + + private void playErrorSound(Player player) { + player.playSound( + player.getLocation(), + this.config.settings.errorSound, + this.config.settings.errorSoundVolume, + this.config.settings.errorSoundPitch + ); + } + + private void playSuccessSound(Player player) { + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5F, 1); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserService.java b/src/main/java/com/eternalcode/parcellockers/user/UserService.java index 24dcad51c..78942e342 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserService.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserService.java @@ -1,69 +1,15 @@ package com.eternalcode.parcellockers.user; -import com.eternalcode.parcellockers.user.repository.UserRepository; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public class UserService { +public interface UserService { + User create(UUID uuid, String name); - private final UserRepository userRepository; + User getOrCreate(UUID uuid, String name); - private final Map usersByUUID = new HashMap<>(); - private final Map usersByName = new HashMap<>(); + CompletableFuture> get(String username); - public UserService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - public CompletableFuture> get(UUID uniqueId) { - User user = this.usersByUUID.get(uniqueId); - - if (user != null) { - return CompletableFuture.completedFuture(Optional.of(user)); - } - - return this.userRepository.find(uniqueId); - } - - public CompletableFuture> get(String username) { - User user = this.usersByName.get(username); - - if (user != null) { - return CompletableFuture.completedFuture(Optional.of(user)); - } - - return this.userRepository.find(username); - } - - public User getOrCreate(UUID uuid, String name) { - User userByUUID = this.usersByUUID.get(uuid); - - if (userByUUID != null) { - return userByUUID; - } - - User userByName = this.usersByName.get(name); - - if (userByName != null) { - return userByName; - } - - return this.create(uuid, name); - } - - public User create(UUID uuid, String name) { - if (this.usersByUUID.containsKey(uuid) || this.usersByName.containsKey(name)) { - throw new IllegalStateException("User already exists"); - } - - User user = new User(uuid, name); - this.usersByUUID.put(uuid, user); - this.usersByName.put(name, user); - this.userRepository.save(user); - - return user; - } + CompletableFuture> get(UUID uniqueId); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java new file mode 100644 index 000000000..ab87e4238 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java @@ -0,0 +1,73 @@ +package com.eternalcode.parcellockers.user; + +import com.eternalcode.parcellockers.user.repository.UserRepository; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + + private final Map usersByUUID = new HashMap<>(); + private final Map usersByName = new HashMap<>(); + + public UserServiceImpl(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public CompletableFuture> get(UUID uniqueId) { + User user = this.usersByUUID.get(uniqueId); + + if (user != null) { + return CompletableFuture.completedFuture(Optional.of(user)); + } + + return this.userRepository.find(uniqueId); + } + + @Override + public CompletableFuture> get(String username) { + User user = this.usersByName.get(username); + + if (user != null) { + return CompletableFuture.completedFuture(Optional.of(user)); + } + + return this.userRepository.find(username); + } + + @Override + public User getOrCreate(UUID uuid, String name) { + User userByUUID = this.usersByUUID.get(uuid); + + if (userByUUID != null) { + return userByUUID; + } + + User userByName = this.usersByName.get(name); + + if (userByName != null) { + return userByName; + } + + return this.create(uuid, name); + } + + @Override + public User create(UUID uuid, String name) { + if (this.usersByUUID.containsKey(uuid) || this.usersByName.containsKey(name)) { + throw new IllegalStateException("User already exists"); + } + + User user = new User(uuid, name); + this.usersByUUID.put(uuid, user); + this.usersByName.put(name, user); + this.userRepository.save(user); + + return user; + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java index c375f0603..333d99ccd 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java @@ -3,6 +3,6 @@ import com.eternalcode.parcellockers.user.User; import java.util.List; -record UserPageResult(List users, boolean hasNextPage) { +public record UserPageResult(List users, boolean hasNextPage) { } From 32a3d514f102627aeca9effe3ae52f5e40fe42db Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:30:29 +0200 Subject: [PATCH 03/51] Update SentParcelsGui.java --- .../gui/implementation/remote/SentParcelsGui.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 9d279ef71..52adfc034 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -17,14 +17,12 @@ import java.util.List; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; public class SentParcelsGui implements GuiView { private final Plugin plugin; - private final Server server; private final MiniMessage miniMessage; private final PluginConfiguration config; private final ParcelRepository parcelRepository; @@ -34,7 +32,6 @@ public class SentParcelsGui implements GuiView { public SentParcelsGui( Plugin plugin, - Server server, MiniMessage miniMessage, PluginConfiguration config, ParcelRepository parcelRepository, @@ -43,7 +40,6 @@ public SentParcelsGui( UserService userService ) { this.plugin = plugin; - this.server = server; this.miniMessage = miniMessage; this.config = config; this.parcelRepository = parcelRepository; @@ -91,7 +87,7 @@ public void show(Player player) { gui.addItem(item.asGuiItem()); } - this.server.getScheduler().runTask(this.plugin, () -> gui.open(player)); + this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); }).whenComplete(SentryExceptionHandler.handler()); } } From 6d9c449cab241812e7b3d620a3c9db3987cdfb9d Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 14:37:03 +0200 Subject: [PATCH 04/51] Rename UserService back to UserManager --- .../parcellockers/ParcelLockers.java | 18 +++++++++--------- .../implementation/locker/LockerMainGui.java | 10 +++++----- .../locker/ParcelCollectionGui.java | 10 +++++----- .../gui/implementation/remote/MainGui.java | 12 ++++++------ .../implementation/remote/ParcelListGui.java | 16 ++++++---------- .../implementation/remote/SentParcelsGui.java | 10 +++++----- .../parcel/command/ParcelCommand.java | 10 +++++----- .../parcel/util/ParcelPlaceholderUtil.java | 12 ++++++------ .../{UserService.java => UserManager.java} | 3 ++- ...erServiceImpl.java => UserManagerImpl.java} | 4 ++-- .../user/controller/LoadUserController.java | 10 +++++----- .../user/controller/PrepareUserController.java | 10 +++++----- 12 files changed, 61 insertions(+), 64 deletions(-) rename src/main/java/com/eternalcode/parcellockers/user/{UserService.java => UserManager.java} (91%) rename src/main/java/com/eternalcode/parcellockers/user/{UserServiceImpl.java => UserManagerImpl.java} (94%) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 22b6e064c..69fd39219 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -36,8 +36,8 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepositoryOrmLite; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.updater.UpdaterService; -import com.eternalcode.parcellockers.user.UserService; -import com.eternalcode.parcellockers.user.UserServiceImpl; +import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserManagerImpl; import com.eternalcode.parcellockers.user.controller.LoadUserController; import com.eternalcode.parcellockers.user.controller.PrepareUserController; import com.eternalcode.parcellockers.user.repository.UserRepository; @@ -153,12 +153,12 @@ public void onEnable() { ItemStorageRepository itemStorageRepository = new ItemStorageRepositoryOrmLite(databaseManager, scheduler); UserRepository userRepository = new UserRepositoryOrmLite(databaseManager, scheduler); - UserService userService = new UserServiceImpl(userRepository); + UserManager userManager = new UserManagerImpl(userRepository); MainGui mainGUI = new MainGui(this, server, miniMessage, config, parcelRepository, lockerRepository, - userService); - ParcelListGui parcelListGUI = new ParcelListGui(this, server, miniMessage, config, parcelRepository, lockerRepository, - userService, mainGUI); + userManager); + ParcelListGui parcelListGUI = new ParcelListGui(this, miniMessage, config, parcelRepository, lockerRepository, + userManager, mainGUI); this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .argument(Parcel.class, new ParcelArgument(parcelCache)) @@ -168,7 +168,7 @@ public void onEnable() { .message(LiteBukkitMessages.PLAYER_NOT_FOUND, config.messages.cantFindPlayer) .commands(LiteCommandsAnnotations.of( new ParcelCommand(lockerRepository, announcer, config, mainGUI, parcelListGUI, - parcelService, userService), + parcelService, userManager), new ParcelLockersCommand(configManager, config, announcer), new DebugCommand(parcelRepository, lockerRepository, itemStorageRepository, parcelContentRepository, announcer) )) @@ -183,8 +183,8 @@ public void onEnable() { new LockerInteractionController(lockerCache, lockerMainGUI), new LockerPlaceController(config, this, lockerRepository, announcer), new LockerBreakController(lockerRepository, lockerCache, announcer, config.messages), - new PrepareUserController(userService), - new LoadUserController(userService, server) + new PrepareUserController(userManager), + new LoadUserController(userManager, server) ).forEach(controller -> server.getPluginManager().registerEvents(controller, this)); new Metrics(this, 17677); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index 3993215ae..c4bb31ec1 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -10,8 +10,8 @@ import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.UserService; -import com.eternalcode.parcellockers.user.UserServiceImpl; +import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.UserManagerImpl; import com.eternalcode.parcellockers.user.repository.UserRepository; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; @@ -35,7 +35,7 @@ public class LockerMainGui implements GuiView { private final SkullAPI skullAPI; private final ParcelService parcelService; - private final UserService userService; + private final UserManager userManager; public LockerMainGui( Plugin plugin, @@ -62,7 +62,7 @@ public LockerMainGui( this.skullAPI = skullAPI; this.parcelService = parcelService; - this.userService = new UserServiceImpl(this.userRepository); + this.userManager = new UserManagerImpl(this.userRepository); } @Override @@ -96,7 +96,7 @@ public void show(Player player) { this.parcelRepository, this.miniMessage, this.parcelService, - this.userService, + this.userManager, this.lockerRepository ); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java index 4dcbcccfb..023dd241f 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java @@ -11,7 +11,7 @@ import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import com.eternalcode.parcellockers.util.InventoryUtil; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -34,7 +34,7 @@ public class ParcelCollectionGui implements GuiView { private final ParcelRepository parcelRepository; private final MiniMessage miniMessage; private final ParcelService parcelService; - private final UserService userService; + private final UserManager userManager; private final LockerRepository lockerRepository; public ParcelCollectionGui( @@ -44,7 +44,7 @@ public ParcelCollectionGui( ParcelRepository parcelRepository, MiniMessage miniMessage, ParcelService parcelService, - UserService userService, + UserManager userManager, LockerRepository lockerRepository ) { this.plugin = plugin; @@ -53,7 +53,7 @@ public ParcelCollectionGui( this.parcelRepository = parcelRepository; this.miniMessage = miniMessage; this.parcelService = parcelService; - this.userService = userService; + this.userManager = userManager; this.lockerRepository = lockerRepository; } @@ -118,7 +118,7 @@ private void show(Player player, Page page) { ConfigItem item = parcelItem.clone(); item.name = item.name.replace("{NAME}", parcel.name()); - item.lore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userService, this.lockerRepository); + item.lore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userManager, this.lockerRepository); item.setGlow(true); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index 64b9f689c..81b03aa9b 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -6,7 +6,7 @@ import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -22,7 +22,7 @@ public class MainGui implements GuiView { private final PluginConfiguration config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final UserService userService; + private final UserManager userManager; public MainGui( Plugin plugin, @@ -31,7 +31,7 @@ public MainGui( PluginConfiguration config, ParcelRepository parcelRepository, LockerRepository lockerRepository, - UserService userService + UserManager userManager ) { this.plugin = plugin; this.server = server; @@ -39,7 +39,7 @@ public MainGui( this.config = config; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.userService = userService; + this.userManager = userManager; } @Override @@ -73,8 +73,8 @@ public void show(Player player) { gui.setItem(24, parcelArchiveItem); gui.setItem(40, closeItem); - gui.addSlotAction(20, event -> new ParcelListGui(this.plugin, this.server, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userService, this).show(player)); - gui.addSlotAction(22, event -> new SentParcelsGui(this.plugin, this.server, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userService).show(player)); + gui.addSlotAction(20, event -> new ParcelListGui(this.plugin, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userManager, this).show(player)); + gui.addSlotAction(22, event -> new SentParcelsGui(this.plugin, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userManager).show(player)); gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.open(player); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 45d13e18f..002f48148 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -11,7 +11,7 @@ import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -19,7 +19,6 @@ import java.util.List; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -29,31 +28,28 @@ public class ParcelListGui implements GuiView { private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); private final Plugin plugin; - private final Server server; private final MiniMessage miniMessage; private final PluginConfiguration config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final UserService userService; + private final UserManager userManager; private final MainGui mainGUI; public ParcelListGui( Plugin plugin, - Server server, MiniMessage miniMessage, PluginConfiguration config, ParcelRepository parcelRepository, LockerRepository lockerRepository, - UserService userService, + UserManager userManager, MainGui mainGUI ) { this.plugin = plugin; - this.server = server; this.miniMessage = miniMessage; this.config = config; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.userService = userService; + this.userManager = userManager; this.mainGUI = mainGUI; } @@ -93,7 +89,7 @@ private void show(Player player, Page page) { for (Parcel parcel : result.parcels()) { ItemBuilder parcelItem = item.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userService, this.lockerRepository).stream() + List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userManager, this.lockerRepository).stream() .map(line -> resetItalic(this.miniMessage.deserialize(line))) .toList(); parcelItem.lore(newLore); @@ -112,7 +108,7 @@ private void show(Player player, Page page) { gui.setItem(47, previousPageItem); } - this.server.getScheduler().runTask(this.plugin, () -> gui.open(player)); + this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); }).whenComplete(SentryExceptionHandler.handler()); } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 52adfc034..efbfd0c92 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -8,7 +8,7 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.SentryExceptionHandler; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -28,7 +28,7 @@ public class SentParcelsGui implements GuiView { private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; private final MainGui mainGUI; - private final UserService userService; + private final UserManager userManager; public SentParcelsGui( Plugin plugin, @@ -37,7 +37,7 @@ public SentParcelsGui( ParcelRepository parcelRepository, LockerRepository lockerRepository, MainGui mainGUI, - UserService userService + UserManager userManager ) { this.plugin = plugin; this.miniMessage = miniMessage; @@ -45,7 +45,7 @@ public SentParcelsGui( this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; this.mainGUI = mainGUI; - this.userService = userService; + this.userManager = userManager; } @Override @@ -78,7 +78,7 @@ public void show(Player player) { for (Parcel parcel : parcels) { ItemBuilder item = parcelItem.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore, this.userService, this.lockerRepository) + List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore, this.userManager, this.lockerRepository) .stream() .map(line -> this.miniMessage.deserialize(line)) .toList(); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java index b1092ef38..0d3ea23d6 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java @@ -8,7 +8,7 @@ import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import dev.rollczi.litecommands.annotations.argument.Arg; import dev.rollczi.litecommands.annotations.async.Async; import dev.rollczi.litecommands.annotations.command.Command; @@ -29,7 +29,7 @@ public class ParcelCommand { private final MainGui mainGUI; private final ParcelListGui parcelListGUI; private final ParcelService parcelService; - private final UserService userService; + private final UserManager userManager; public ParcelCommand( LockerRepository lockerRepository, @@ -38,7 +38,7 @@ public ParcelCommand( MainGui mainGUI, ParcelListGui parcelListGUI, ParcelService parcelService, - UserService userService + UserManager userManager ) { this.lockerRepository = lockerRepository; this.announcer = announcer; @@ -46,7 +46,7 @@ public ParcelCommand( this.mainGUI = mainGUI; this.parcelListGUI = parcelListGUI; this.parcelService = parcelService; - this.userService = userService; + this.userManager = userManager; } @Execute(name = "list") @@ -57,7 +57,7 @@ void list(@Context Player player) { @Async @Execute(name = "info") void info(@Context Player player, @Arg Parcel parcel) { - List messagesToSend = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, this.config.messages.parcelInfoMessages, this.userService, this.lockerRepository); + List messagesToSend = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, this.config.messages.parcelInfoMessages, this.userManager, this.lockerRepository); messagesToSend.forEach(message -> this.announcer.sendMessage(player, message)); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java index 2c76e6b5d..f5b13b070 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java @@ -3,7 +3,7 @@ import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -17,13 +17,13 @@ public class ParcelPlaceholderUtil { @Blocking - public static List replaceParcelPlaceholders(Parcel parcel, List lore, UserService userService, LockerRepository lockerRepository) { + public static List replaceParcelPlaceholders(Parcel parcel, List lore, UserManager userManager, LockerRepository lockerRepository) { if (lore == null || lore.isEmpty()) { return Collections.emptyList(); } - String senderName = getName(parcel.sender(), userService).join(); - String receiver = getName(parcel.receiver(), userService).join(); + String senderName = getName(parcel.sender(), userManager).join(); + String receiver = getName(parcel.receiver(), userManager).join(); Formatter formatter = new Formatter() .register("{UUID}", parcel.uuid().toString()) @@ -58,8 +58,8 @@ public static List replaceParcelPlaceholders(Parcel parcel, List return newLore; } - private static CompletableFuture getName(UUID userUuid, UserService userService) { - return userService.get(userUuid).thenApply(userOptional -> userOptional + private static CompletableFuture getName(UUID userUuid, UserManager userManager) { + return userManager.get(userUuid).thenApply(userOptional -> userOptional .map(user -> user.name()) .orElse("Unknown") ); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserService.java b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java similarity index 91% rename from src/main/java/com/eternalcode/parcellockers/user/UserService.java rename to src/main/java/com/eternalcode/parcellockers/user/UserManager.java index 78942e342..f48a069d5 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserService.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java @@ -4,7 +4,8 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; -public interface UserService { +public interface UserManager { + User create(UUID uuid, String name); User getOrCreate(UUID uuid, String name); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java similarity index 94% rename from src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java rename to src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index ab87e4238..412361f8f 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -7,14 +7,14 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; -public class UserServiceImpl implements UserService { +public class UserManagerImpl implements UserManager { private final UserRepository userRepository; private final Map usersByUUID = new HashMap<>(); private final Map usersByName = new HashMap<>(); - public UserServiceImpl(UserRepository userRepository) { + public UserManagerImpl(UserRepository userRepository) { this.userRepository = userRepository; } diff --git a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java index 2c20e17c0..adec0e29d 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java +++ b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.user.controller; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -9,18 +9,18 @@ public class LoadUserController implements Listener { - private final UserService userService; + private final UserManager userManager; private final Server server; - public LoadUserController(UserService userService, Server server) { - this.userService = userService; + public LoadUserController(UserManager userManager, Server server) { + this.userManager = userManager; this.server = server; } @EventHandler void onLoad(ServerLoadEvent event) { for (Player player : this.server.getOnlinePlayers()) { - this.userService.create(player.getUniqueId(), player.getName()); + this.userManager.create(player.getUniqueId(), player.getName()); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java b/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java index 93dd8e66e..b144ca629 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java +++ b/src/main/java/com/eternalcode/parcellockers/user/controller/PrepareUserController.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.user.controller; -import com.eternalcode.parcellockers.user.UserService; +import com.eternalcode.parcellockers.user.UserManager; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -8,16 +8,16 @@ public class PrepareUserController implements Listener { - private final UserService userService; + private final UserManager userManager; - public PrepareUserController(UserService userService) { - this.userService = userService; + public PrepareUserController(UserManager userManager) { + this.userManager = userManager; } @EventHandler void onJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - this.userService.getOrCreate(player.getUniqueId(), player.getName()); + this.userManager.getOrCreate(player.getUniqueId(), player.getName()); } } From 6ea38f4078d2bad93a1a0e0f1b9541fa27ba06c5 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 14:45:18 +0200 Subject: [PATCH 05/51] add new lines --- .../com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index bf0a8fc40..502b941ab 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -64,7 +64,9 @@ public boolean send(Player sender, Parcel parcel, List items) { Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); + scheduler.runLaterAsync(task, delay); + return true; }); return true; From bcb7a091ef9e0329955523feb251db9b0958ca3f Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 15:36:42 +0200 Subject: [PATCH 06/51] Change config library from CDN to Okaeri configs, remove Sentry --- build.gradle.kts | 14 +- .../parcellockers/ParcelLockers.java | 42 +- .../parcellockers/ParcelLockersCommand.java | 16 +- .../command/handler/InvalidUsageImpl.java | 9 +- .../command/handler/PermissionMessage.java | 6 +- .../configuration/ConfigService.java | 58 +++ .../configuration/ConfigurationManager.java | 50 --- .../configuration/ReloadableConfig.java | 10 - .../composer/DurationComposer.java | 96 ----- .../composer/OldEnumComposer.java | 55 --- .../composer/PositionComposer.java | 18 - .../composer/PositionTransformer.java | 25 ++ .../composer/SimpleComposer.java | 9 - .../implementation/MessagesConfig.java | 6 + .../implementation/PluginConfig.java | 384 +++++++++++++++++ .../implementation/PluginConfiguration.java | 407 ------------------ .../ConfigItem.java | 82 +--- .../ParcelContentRepositoryOrmLite.java | 5 +- .../conversation/ParcelLockerPlacePrompt.java | 6 +- .../database/DatabaseManager.java | 7 +- .../persister/ItemStackPersister.java | 3 - .../locker/DestinationSelectionGui.java | 29 +- .../implementation/locker/LockerMainGui.java | 6 +- .../locker/ParcelCollectionGui.java | 21 +- .../locker/ParcelItemStorageGui.java | 13 +- .../locker/ParcelSendingGui.java | 20 +- .../locker/ParcelSendingGuiState.java | 70 +-- .../locker/ReceiverSelectionGui.java | 11 +- .../gui/implementation/remote/MainGui.java | 8 +- .../implementation/remote/ParcelListGui.java | 11 +- .../implementation/remote/SentParcelsGui.java | 11 +- .../ItemStorageRepositoryOrmLite.java | 2 - .../controller/LockerBreakController.java | 6 +- .../controller/LockerPlaceController.java | 15 +- .../repository/LockerRepositoryOrmLite.java | 5 +- .../notification/NoticeService.java | 47 ++ .../notification/NotificationAnnouncer.java | 6 +- .../notification/NotificationType.java | 1 + .../parcel/ParcelServiceImpl.java | 11 +- .../parcel/command/ParcelCommand.java | 6 +- .../repository/ParcelRepositoryOrmLite.java | 2 - .../parcel/task/ParcelSendTask.java | 6 +- .../shared/SentryExceptionHandler.java | 26 -- .../UpdaterNotificationController.java | 13 +- .../repository/UserRepositoryOrmLite.java | 2 - .../parcellockers/util/ItemSerdesUtil.java | 5 - .../composer/DurationComposerTest.java | 92 ---- .../composer/PositionComposerTest.java | 69 --- .../LockerRepositoryIntegrationTest.java | 6 +- .../ParcelRepositoryIntegrationTest.java | 6 +- 50 files changed, 683 insertions(+), 1151 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/ConfigurationManager.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/ReloadableConfig.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/composer/DurationComposer.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/composer/OldEnumComposer.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionComposer.java create mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/composer/SimpleComposer.java create mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java create mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfiguration.java rename src/main/java/com/eternalcode/parcellockers/configuration/{implementation => serializable}/ConfigItem.java (64%) create mode 100644 src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/shared/SentryExceptionHandler.java delete mode 100644 src/test/java/com/eternalcode/parcellockers/configuration/composer/DurationComposerTest.java delete mode 100644 src/test/java/com/eternalcode/parcellockers/configuration/composer/PositionComposerTest.java diff --git a/build.gradle.kts b/build.gradle.kts index d5a23f18d..357dd8080 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,6 +19,7 @@ repositories { maven { url = uri("https://oss.sonatype.org/content/repositories/central") } maven { url = uri("https://repo.papermc.io/repository/maven-public/") } maven { url = uri("https://repo.eternalcode.pl/releases") } + maven { url = uri("https://storehouse.okaeri.eu/repository/maven-public/") } } dependencies { @@ -36,8 +37,10 @@ dependencies { implementation("dev.triumphteam:triumph-gui:3.1.12") implementation("de.rapha149.signgui:signgui:2.5.4") - // CDN - implementation("net.dzikoysk:cdn:1.14.9") + // configs + implementation("eu.okaeri:okaeri-configs-serdes-commons:5.0.9") + implementation("eu.okaeri:okaeri-configs-serdes-bukkit:5.0.9") + implementation("eu.okaeri:okaeri-configs-yaml-bukkit:5.0.9") // expressible implementation("org.panda-lang:expressible:1.3.6") @@ -47,7 +50,6 @@ dependencies { // metrics and sentry implementation("org.bstats:bstats-bukkit:3.1.0") - implementation("io.sentry:sentry:8.19.1") // database implementation("com.zaxxer:HikariCP:7.0.1") @@ -78,6 +80,10 @@ dependencies { implementation("com.eternalcode:eternalcode-commons-adventure:1.3.0") implementation("com.eternalcode:eternalcode-commons-bukkit:1.3.0") + // notification library + implementation("com.eternalcode:multification-bukkit:1.2.2") + implementation("com.eternalcode:multification-okaeri:1.1.4") + // caffeine implementation("com.github.ben-manes.caffeine:caffeine:3.2.2") @@ -152,7 +158,7 @@ tasks { "org.bstats", "org.json", "org.postgresql", - "net.dzikoysk", + "eu.okaeri", "net.kyori", "io.papermc", "io.sentry", diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 69fd39219..65c241f5c 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -7,8 +7,9 @@ import com.eternalcode.parcellockers.command.debug.DebugCommand; import com.eternalcode.parcellockers.command.handler.InvalidUsageImpl; import com.eternalcode.parcellockers.command.handler.PermissionMessage; -import com.eternalcode.parcellockers.configuration.ConfigurationManager; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.ConfigService; +import com.eternalcode.parcellockers.configuration.implementation.MessagesConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.content.repository.ParcelContentRepositoryOrmLite; import com.eternalcode.parcellockers.database.DatabaseManager; @@ -25,7 +26,7 @@ import com.eternalcode.parcellockers.locker.controller.LockerPlaceController; import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelServiceImpl; @@ -43,8 +44,6 @@ import com.eternalcode.parcellockers.user.repository.UserRepository; import com.eternalcode.parcellockers.user.repository.UserRepositoryOrmLite; import com.google.common.base.Stopwatch; -import com.j256.ormlite.logger.LoggerFactory; -import com.j256.ormlite.logger.NullLogBackend; import dev.rollczi.litecommands.LiteCommands; import dev.rollczi.litecommands.adventure.LiteAdventureExtension; import dev.rollczi.litecommands.annotations.LiteCommandsAnnotations; @@ -54,11 +53,10 @@ import dev.rollczi.liteskullapi.SkullAPI; import io.papermc.lib.PaperLib; import io.papermc.lib.environments.Environment; -import io.sentry.Sentry; +import java.io.File; import java.sql.SQLException; import java.time.Duration; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -70,12 +68,9 @@ import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; -import org.slf4j.helpers.NOPLogger; public final class ParcelLockers extends JavaPlugin { - public static org.slf4j.Logger DEBUG_LOGGER = NOPLogger.NOP_LOGGER; - private LiteCommands liteCommands; private BukkitAudiences audiences; private SkullAPI skullAPI; @@ -93,33 +88,14 @@ public void onEnable() { .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) .build(); - NotificationAnnouncer announcer = new NotificationAnnouncer(this.audiences, miniMessage); - ConfigurationManager configManager = new ConfigurationManager(this.getDataFolder()); - PluginConfiguration config = configManager.load(new PluginConfiguration()); + ConfigService configManager = new ConfigService(); + PluginConfig config = configManager.create(PluginConfig.class, new File(this.getDataFolder(), "config.yml")); + MessagesConfig messagesConfig = configManager.create(MessagesConfig.class, new File(this.getDataFolder(), "messages.yml")); Server server = this.getServer(); + NoticeService noticeService = new NoticeService(messagesConfig, miniMessage, this.audiences); Scheduler scheduler = new BukkitSchedulerImpl(this); - if (config.settings.enableSentry) { - Sentry.init(options -> { - this.getLogger().info("Initializing Sentry..."); - options.setDsn("https://1dffb5bec4484aaaaca5fcb4c3157a99@o4505014505177088.ingest.sentry.io/4505019784888320"); - options.setTracesSampleRate(1.0); - options.setRelease(this.getDescription().getVersion()); - options.setTag("serverVersion", this.getServer().getVersion()); - options.setTag("serverSoftware", PaperLib.getEnvironment().getName()); - options.setTag("plugins", Arrays.stream(server.getPluginManager().getPlugins()).toList().toString()); - options.setEnabled(false); - this.getLogger().info("Sentry initialized successfully!"); - }); - } - - if (config.settings.debug) { - DEBUG_LOGGER = org.slf4j.LoggerFactory.getLogger("ParcelLockers] [DEBUG"); - } - - LoggerFactory.setLogBackendFactory(new NullLogBackend.NullLogBackendFactory()); - DatabaseManager databaseManager = new DatabaseManager(config, this.getLogger(), this.getDataFolder()); this.databaseManager = databaseManager; diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java index a6fd4b0aa..4ce303fd8 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java @@ -1,10 +1,10 @@ package com.eternalcode.parcellockers; -import com.eternalcode.parcellockers.configuration.ConfigurationManager; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.ConfigService; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import dev.rollczi.litecommands.annotations.command.Command; -import dev.rollczi.litecommands.annotations.context.Context; +import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; import org.bukkit.command.CommandSender; @@ -15,24 +15,24 @@ @Permission("parcellockers.admin") public class ParcelLockersCommand { - private final ConfigurationManager configManager; - private final PluginConfiguration config; + private final ConfigService configManager; + private final PluginConfig config; private final NotificationAnnouncer announcer; - public ParcelLockersCommand(ConfigurationManager configManager, PluginConfiguration config, NotificationAnnouncer announcer) { + public ParcelLockersCommand(ConfigService configManager, PluginConfig config, NotificationAnnouncer announcer) { this.configManager = configManager; this.config = config; this.announcer = announcer; } @Execute(name = "reload") - void reload(@Context CommandSender sender) { + void reload(@Sender CommandSender sender) { this.configManager.reload(); this.announcer.sendMessage(sender, this.config.messages.reload); } @Execute(name = "give") - void give(@Context Player player) { + void give(@Sender Player player) { ItemStack parcelItem = this.config.settings.parcelLockerItem.toGuiItem().getItemStack(); player.getInventory().addItem(parcelItem); } diff --git a/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java b/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java index aab236c47..88face257 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java @@ -1,23 +1,22 @@ package com.eternalcode.parcellockers.command.handler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import dev.rollczi.litecommands.handler.result.ResultHandlerChain; import dev.rollczi.litecommands.invalidusage.InvalidUsage; import dev.rollczi.litecommands.invalidusage.InvalidUsageHandler; import dev.rollczi.litecommands.invocation.Invocation; import dev.rollczi.litecommands.schematic.Schematic; +import java.util.List; import org.bukkit.command.CommandSender; import panda.utilities.text.Formatter; -import java.util.List; - public class InvalidUsageImpl implements InvalidUsageHandler { private final NotificationAnnouncer announcer; - private final PluginConfiguration config; + private final PluginConfig config; - public InvalidUsageImpl(NotificationAnnouncer announcer, PluginConfiguration config) { + public InvalidUsageImpl(NotificationAnnouncer announcer, PluginConfig config) { this.announcer = announcer; this.config = config; } diff --git a/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java b/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java index ac654dbd6..699f492ba 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java +++ b/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.command.handler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import dev.rollczi.litecommands.handler.result.ResultHandlerChain; import dev.rollczi.litecommands.invocation.Invocation; @@ -12,9 +12,9 @@ public class PermissionMessage implements MissingPermissionsHandler { private final NotificationAnnouncer announcer; - private final PluginConfiguration config; + private final PluginConfig config; - public PermissionMessage(NotificationAnnouncer announcer, PluginConfiguration config) { + public PermissionMessage(NotificationAnnouncer announcer, PluginConfig config) { this.announcer = announcer; this.config = config; } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java new file mode 100644 index 000000000..fc5135b67 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java @@ -0,0 +1,58 @@ +package com.eternalcode.parcellockers.configuration; + +import com.eternalcode.multification.bukkit.notice.resolver.sound.SoundBukkitResolver; +import com.eternalcode.multification.notice.resolver.NoticeResolverDefaults; +import com.eternalcode.multification.notice.resolver.NoticeResolverRegistry; +import com.eternalcode.multification.okaeri.MultificationSerdesPack; +import eu.okaeri.configs.ConfigManager; +import eu.okaeri.configs.OkaeriConfig; +import eu.okaeri.configs.serdes.OkaeriSerdesPack; +import eu.okaeri.configs.serdes.SerdesRegistry; +import eu.okaeri.configs.serdes.commons.SerdesCommons; +import eu.okaeri.configs.yaml.bukkit.YamlBukkitConfigurer; +import eu.okaeri.configs.yaml.bukkit.serdes.SerdesBukkit; +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +public class ConfigService { + + private final Set configs = new HashSet<>(); + + public T create(Class config, File file) { + T configFile = ConfigManager.create(config); + + YamlBukkitConfigurer configurer = new YamlBukkitConfigurer(); + NoticeResolverRegistry noticeRegistry = NoticeResolverDefaults.createRegistry() + .registerResolver(new SoundBukkitResolver()); + + configFile.withConfigurer(configurer, + new SerdesCommons(), + new SerdesBukkit(), + new MultificationSerdesPack(noticeRegistry), + new DefaultSerdesPack() + ); + + configFile.withBindFile(file); + configFile.withRemoveOrphans(true); + configFile.saveDefaults(); + configFile.load(true); + + this.configs.add(configFile); + + return configFile; + } + + public void reload() { + for (OkaeriConfig config : this.configs) { + config.load(); + } + } + + private static class DefaultSerdesPack implements OkaeriSerdesPack { + @Override + public void register(SerdesRegistry config) { + + } + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigurationManager.java b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigurationManager.java deleted file mode 100644 index 554d031d2..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigurationManager.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.eternalcode.parcellockers.configuration; - -import com.eternalcode.parcellockers.configuration.composer.DurationComposer; -import com.eternalcode.parcellockers.configuration.composer.OldEnumComposer; -import com.eternalcode.parcellockers.configuration.composer.PositionComposer; -import com.eternalcode.parcellockers.shared.Position; -import net.dzikoysk.cdn.Cdn; -import net.dzikoysk.cdn.CdnFactory; -import org.bukkit.Sound; - -import java.io.File; -import java.time.Duration; -import java.util.HashSet; -import java.util.Set; - -public class ConfigurationManager { - - private static final Cdn CDN = CdnFactory - .createYamlLike() - .getSettings() - .withComposer(Position.class, new PositionComposer()) - .withComposer(Duration.class, new DurationComposer()) - .withComposer(Sound.class, new OldEnumComposer()) - .build(); - - private final Set configs = new HashSet<>(); - private final File dataFolder; - - public ConfigurationManager(File dataFolder) { - this.dataFolder = dataFolder; - } - - public T load(T config) { - CDN.load(config.resource(this.dataFolder), config) - .orThrow(RuntimeException::new); - - CDN.render(config, config.resource(this.dataFolder)) - .orThrow(RuntimeException::new); - - this.configs.add(config); - - return config; - } - - public void reload() { - for (ReloadableConfig config : this.configs) { - this.load(config); - } - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/ReloadableConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/ReloadableConfig.java deleted file mode 100644 index 5b2431f21..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/ReloadableConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.eternalcode.parcellockers.configuration; - -import net.dzikoysk.cdn.source.Resource; - -import java.io.File; - -public interface ReloadableConfig { - - Resource resource(File folder); -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/composer/DurationComposer.java b/src/main/java/com/eternalcode/parcellockers/configuration/composer/DurationComposer.java deleted file mode 100644 index 80eeec2d2..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/composer/DurationComposer.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.eternalcode.parcellockers.configuration.composer; - -import panda.std.Result; - -import java.time.Duration; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class DurationComposer implements SimpleComposer { - - // Regex to match each time component individually - private static final Pattern TIME_PATTERN = Pattern.compile("(?:(\\d+)d)?\\s*(?:(\\d+)h)?\\s*(?:(\\d+)m)?\\s*(?:(\\d+)s)?", Pattern.CASE_INSENSITIVE); - - @Override - public Result serialize(Duration duration) { - if (duration == null) { - return Result.error(new IllegalArgumentException("Duration cannot be null")); - } - - long days = duration.toDays(); - long hours = duration.toHours() % 24; - long minutes = duration.toMinutes() % 60; - long seconds = duration.getSeconds() % 60; - - StringBuilder result = new StringBuilder(); - if (days > 0) { - result.append(days).append("d "); - } - if (hours > 0) { - result.append(hours).append("h "); - } - if (minutes > 0) { - result.append(minutes).append("m "); - } - if (seconds > 0 || result.isEmpty()) { // Always include seconds if no other components - result.append(seconds).append("s"); - } - - return Result.ok(result.toString().trim()); - } - - @Override - public Result deserialize(String input) { - try { - if (input == null || input.isBlank()) { - return Result.error(new IllegalArgumentException("Input cannot be null or blank")); - } - - // If input is already in ISO-8601 format - if (input.toUpperCase().startsWith("P")) { - return Result.ok(Duration.parse(input)); - } - - // For simple case: just a number (assume seconds) - if (input.matches("\\d+(\\.\\d+)?")) { - if (input.contains(".")) { - double seconds = Double.parseDouble(input); - return Result.ok(Duration.ofMillis((long) (seconds * 1000))); - } else { - return Result.ok(Duration.ofSeconds(Long.parseLong(input))); - } - } - - // Parse custom format (e.g., "1d 2h 30m 15s") - Duration duration = Duration.ZERO; - Matcher matcher = TIME_PATTERN.matcher(input); - - if (matcher.matches()) { - String days = matcher.group(1); - String hours = matcher.group(2); - String minutes = matcher.group(3); - String seconds = matcher.group(4); - - if (days != null) { - duration = duration.plusDays(Long.parseLong(days)); - } - if (hours != null) { - duration = duration.plusHours(Long.parseLong(hours)); - } - if (minutes != null) { - duration = duration.plusMinutes(Long.parseLong(minutes)); - } - if (seconds != null) { - duration = duration.plusSeconds(Long.parseLong(seconds)); - } - - return Result.ok(duration); - } - - return Result.error(new IllegalArgumentException( - "Invalid duration format. Expected format like '1d 2h 3m 4s' or ISO-8601 duration.")); - } catch (Exception e) { - return Result.error(new IllegalArgumentException("Invalid duration format. Expected format like '1d 2h 3m 4s' or ISO-8601 duration.")); - } - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/composer/OldEnumComposer.java b/src/main/java/com/eternalcode/parcellockers/configuration/composer/OldEnumComposer.java deleted file mode 100644 index 088357a42..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/composer/OldEnumComposer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.eternalcode.parcellockers.configuration.composer; - -import dev.rollczi.litecommands.reflect.ReflectUtil; -import net.dzikoysk.cdn.CdnSettings; -import net.dzikoysk.cdn.model.Element; -import net.dzikoysk.cdn.model.Entry; -import net.dzikoysk.cdn.model.Piece; -import net.dzikoysk.cdn.reflect.TargetType; -import net.dzikoysk.cdn.serdes.Composer; -import net.dzikoysk.cdn.serdes.SimpleDeserializer; -import org.bukkit.util.OldEnum; -import panda.std.Result; - -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; - -public class OldEnumComposer implements Composer>, SimpleDeserializer> { - - public static final Predicate> IS_OLD_ENUM = type -> OldEnum.class.isAssignableFrom(type); - - private static final Map, Method> VALUE_OF_METHODS = new HashMap<>(); - - @Override - public Result, Exception> deserialize(String source) { - throw new UnsupportedOperationException("Enum deserializer requires enum class"); - } - - @Override - public Result, Exception> deserialize(TargetType type, String source) { - try { - Method valueOfMethod = VALUE_OF_METHODS.computeIfAbsent(type.getType(), key -> findValueOfMethod(key)); - OldEnum oldEnum = ReflectUtil.invokeStaticMethod(valueOfMethod, source); - - return Result.ok(oldEnum); - } - catch (IllegalArgumentException argumentException) { - return Result.error(argumentException); - } - } - - private Method findValueOfMethod(Class type) { - Method valueOfMethod = ReflectUtil.getMethod(type, "valueOf", String.class); - valueOfMethod.setAccessible(true); - return valueOfMethod; - } - - @Override - public Result, ? extends Exception> serialize(CdnSettings settings, List description, String key, TargetType type, OldEnum oldEnum) { - return Result.ok(key.isEmpty() ? new Piece(oldEnum.name()) : new Entry(description, key, oldEnum.name())); - } - -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionComposer.java b/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionComposer.java deleted file mode 100644 index 7e8c0f286..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionComposer.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.eternalcode.parcellockers.configuration.composer; - -import com.eternalcode.parcellockers.shared.Position; -import panda.std.Result; - -public class PositionComposer implements SimpleComposer { - - @Override - public Result deserialize(String source) { - return Result.supplyThrowing(IllegalArgumentException.class, () -> Position.parse(source)); - } - - @Override - public Result serialize(Position entity) { - return Result.ok(entity.toString()); - } - -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java b/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java new file mode 100644 index 000000000..0c45d16c5 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java @@ -0,0 +1,25 @@ +package com.eternalcode.parcellockers.configuration.composer; + +import com.eternalcode.parcellockers.shared.Position; +import eu.okaeri.configs.schema.GenericsPair; +import eu.okaeri.configs.serdes.BidirectionalTransformer; +import eu.okaeri.configs.serdes.SerdesContext; +import org.jetbrains.annotations.NotNull; + +public class PositionTransformer extends BidirectionalTransformer { + + @Override + public GenericsPair getPair() { + return this.genericsPair(Position.class, String.class); + } + + @Override + public String leftToRight(@NotNull Position position, @NotNull SerdesContext context) { + return position.toString(); + } + + @Override + public Position rightToLeft(@NotNull String data, @NotNull SerdesContext context) { + return Position.parse(data); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/composer/SimpleComposer.java b/src/main/java/com/eternalcode/parcellockers/configuration/composer/SimpleComposer.java deleted file mode 100644 index 7450708e6..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/composer/SimpleComposer.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.eternalcode.parcellockers.configuration.composer; - -import net.dzikoysk.cdn.serdes.Composer; -import net.dzikoysk.cdn.serdes.SimpleDeserializer; -import net.dzikoysk.cdn.serdes.SimpleSerializer; - -public interface SimpleComposer extends Composer, SimpleDeserializer, SimpleSerializer { - -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java new file mode 100644 index 000000000..7bef38fb7 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java @@ -0,0 +1,6 @@ +package com.eternalcode.parcellockers.configuration.implementation; + +import eu.okaeri.configs.OkaeriConfig; + +public class MessagesConfig extends OkaeriConfig { +} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java new file mode 100644 index 000000000..767a3fbfa --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -0,0 +1,384 @@ +package com.eternalcode.parcellockers.configuration.implementation; + +import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; +import com.eternalcode.parcellockers.database.DatabaseType; +import eu.okaeri.configs.OkaeriConfig; +import eu.okaeri.configs.annotation.Comment; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import org.bukkit.Material; +import org.bukkit.Sound; + +public class PluginConfig extends OkaeriConfig { + + @Comment({" ", "# Parcel Lockers plugin configuration file." }) + public Settings settings = new Settings(); + + @Comment({ " ", "# The plugin messages." }) + public Messages messages = new Messages(); + + @Comment({ " ", "# The plugin GUI settings." }) + public GuiSettings guiSettings = new GuiSettings(); + + public static class Settings extends OkaeriConfig { + + @Comment({ " ", "# Whether the player after entering the server should receive information about the new version of the plugin?" }) + public boolean receiveUpdates = true; + + @Comment({ " ", "# The database type. (MYSQL, SQLITE)" }) + public DatabaseType databaseType = DatabaseType.SQLITE; + + @Comment({ " ", "# The URL to the database." }) + public String host = "localhost"; + + @Comment({ " ", "# The database name." }) + public String databaseName = "parcellockers"; + + @Comment({ " ", "# The database user." }) + public String user = "root"; + + @Comment({ " ", "# The database port." }) + public String port = "3306"; + + @Comment({ " ", "# The database password." }) + public String password = ""; + + @Comment({ " ", "# The parcel locker item." }) + public ConfigItem parcelLockerItem = new ConfigItem() + .name("&3Parcel locker") + .type(Material.CHEST) + .lore(List.of("&bPlace to create a parcel locker.")); + + @Comment({" ", "# Standard parcel sending duration"}) + public Duration parcelSendDuration = Duration.ofSeconds(10); + + @Comment({" ", "# Parcel sending duration for priority parcels"}) + public Duration priorityParcelSendDuration = Duration.ofSeconds(5); + + @Comment({" ", "# Error sound used in the plugin."}) + public Sound errorSound = Sound.ENTITY_ENDERMAN_AMBIENT; + + @Comment({ " ", "# The sound volume for the error sound." }) + public float errorSoundVolume = 1.0F; + + @Comment({ " ", "# The sound pitch for the error sound." }) + public float errorSoundPitch = 1.0F; + + + } + + public static class Messages extends OkaeriConfig { + + public String onlyForPlayers = "&4โœ˜ &cThis command is only available to players!"; + public String noPermission = "&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"; + public String cantFindPlayer = "&4โœ˜ &cThe specified player could not be found!"; + public String invalidUsage = "&4โฃ &cCorrect usage: &6{USAGE}"; + public String reload = "&3โฃ &bConfiguration has been successfully reloaded!"; + public String parcelCommandUsage = "&9โ“˜ Correct usage: &3/parcel &b &3[parcel]"; + public String parcelSuccessfullyDeleted = "&2โœ” &aParcel deleted successfully."; + public String failedToDeleteParcel = "&4โœ˜ &cAn error occurred while deleting the parcel."; + public String failedToCreateParcelLocker = "&4โœ˜ &cCould not create the parcel locker."; + public String parcelLockerSuccessfullyCreated = "&7ยป &aParcel locker created successfully."; + public String enterDescriptionPrompt = "&6โ†ต &eEnter a description for the parcel locker:"; + public String cannotBreakParcelLocker = "&4โœ˜ &cYou have no permission to break the parcel locker."; + public String parcelLockerSuccessfullyDeleted = "&2โœ” &aParcel locker deleted successfully."; + public String broadcastParcelLockerRemoved = "&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"; + public String parcelSent = "&2โœ” &aParcel sent successfully."; + public String parcelFailedToSend = "&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."; + public String illegalItemFailedToSend = "&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"; + public String parcelCannotBeEmpty = "&4โœ˜ &cThe parcel cannot be empty!"; + public String parcelNameCannotBeEmpty = "&4โœ˜ &cThe parcel name cannot be empty!"; + public String parcelNameSet = "&2โœ” &aParcel name set successfully."; + public String parcelDescriptionSet = "&2โœ” &aParcel description set successfully."; + public String parcelReceiverSet = "&2โœ” &aParcel receiver set successfully."; + public String parcelDestinationSet = "&2โœ” &aParcel destination locker set successfully."; + public String alreadyCreatingLocker = "&4โœ˜ &cYou are already creating a parcel locker!"; + public String receiverNotSet = "&4โœ˜ &cThe parcel receiver is not set!"; + public String parcelSuccessfullyCollected = "&2โœ” &aParcel collected successfully."; + public String failedToCollectParcel = "&4โœ˜ &cAn error occurred while collecting the parcel."; + public String notEnoughInventorySpace = "&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"; + + @Comment({ " ", "# The parcel info message." }) + public List parcelInfoMessages = List.of( + "&7ยป &6Parcel info:", + "&fโ€ข &6UUID: &e{UUID}", + "&fโ€ข &6Sender: &e{SENDER}", + "&fโ€ข &6Receiver: &e{RECEIVER}", + "&fโ€ข &6Size: &e{SIZE}", + "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", + "&fโ€ข &6Priority: &e{PRIORITY}", + "&fโ€ข &6Description: &e{DESCRIPTION}" + ); + } + + public static class GuiSettings extends OkaeriConfig { + + @Comment({ " ", "# The title of the main GUI" }) + public String mainGuiTitle = "&3Main menu"; + + @Comment({ " ", "# The title of the parcel list GUI" }) + public String parcelListGuiTitle = "&aMy parcels"; + + @Comment({ " ", "# The item of the sent parcels GUI" }) + public String sentParcelsTitle = "&6Sent parcels"; + + @Comment({ " ", "# The item of the parcel locker sending GUI" }) + public String parcelLockerSendingGuiTitle = "&3Parcel sending"; + + @Comment({ " ", "# The item of the parcel recipient pick GUI" }) + public String parcelReceiverSelectionGuiTitle = "&5Select recipient"; + + @Comment({ " ", "# The item of the parcel collection GUI" }) + public String parcelCollectionGuiTitle = "&aCollect parcels"; + + @Comment({ " ", "# The item of the small parcel size button" }) + public ConfigItem smallParcelSizeItem = new ConfigItem() + .name("&aโžป Small") + .lore(List.of("&aClick to select the small parcel size.")) + .type(Material.LIME_WOOL); + + @Comment({ " ", "# The item of the medium parcel size button" }) + public ConfigItem mediumParcelSizeItem = new ConfigItem() + .name("&eโžผ Medium") + .lore(List.of("&eClick to select the medium parcel size.")) + .type(Material.YELLOW_WOOL); + + @Comment({ " ", "# The item of the large parcel size button" }) + public ConfigItem largeParcelSizeItem = new ConfigItem() + .name("&cโžฝ Large") + .lore(List.of("&cClick to select the large parcel size.")) + .type(Material.RED_WOOL); + + @Comment({ " ", "# The item represents selected small parcel size." }) + public ConfigItem selectedSmallParcelSizeItem = new ConfigItem() + .name("&aโžป Small") + .lore(List.of("&aโœง Currently selected!")) + .glow(true) + .type(Material.OAK_CHEST_BOAT); + + @Comment({ " ", "# The item represents selected medium parcel size." }) + public ConfigItem selectedMediumParcelSizeItem = new ConfigItem() + .name("&eโžผ Medium") + .lore(List.of("&aCurrently selected!")) + .glow(true) + .type(Material.CHEST_MINECART); + + @Comment({ " ", "# The item represents selected large parcel size." }) + public ConfigItem selectedLargeParcelSizeItem = new ConfigItem() + .name("&cโžฝ Large") + .lore(List.of("&aCurrently selected!")) + .glow(true) + .type(Material.TNT_MINECART); + + @Comment({ " ", "# The item of the priority button" }) + public ConfigItem priorityItem = new ConfigItem() + .name("&c\uD83D\uDE80 Priority") + .lore(List.of("&cClick to select the priority.")) + .type(Material.FIREWORK_ROCKET); + + @Comment({ " ", "# The item of the selected priority button" }) + public ConfigItem selectedPriorityItem = new ConfigItem() + .name("&c\uD83D\uDE80 Priority") + .lore(List.of("&4Currently selected!", "&7&oClick to unselect.")) + .type(Material.FIREWORK_ROCKET) + .glow(true); + + @Comment({ " ", "# The close button item" }) + public ConfigItem closeItem = new ConfigItem() + .name("&cโ˜“ Close") + .lore(List.of("&cClick to close the GUI.")) + .type(Material.BARRIER); + + @Comment({ " ", "# The item of the main GUI" }) + public ConfigItem mainGuiBackgroundItem = new ConfigItem() + .name("") + .lore(Collections.emptyList()) + .type(Material.GRAY_STAINED_GLASS_PANE); + + @Comment({ " ", "# The item of the corner GUI item.", "# Purely for decoration purposes." }) + public ConfigItem cornerItem = new ConfigItem() + .name("") + .lore(Collections.emptyList()) + .type(Material.BLUE_STAINED_GLASS_PANE); + + @Comment({ " ", "# The item of the parcel submit button" }) + public ConfigItem submitParcelItem = new ConfigItem() + .name("&aโœ” Submit") + .lore(List.of("Click to submit the parcel.", "Proceed with caution! This action is final and cannot be undone.")) + .type(Material.ENDER_PEARL) + .glow(true); + + @Comment({ " ", "# The item of the parcel list button" }) + public ConfigItem myParcelsItem = new ConfigItem() + .name("&3โ›ƒ My parcels") + .lore(List.of("&bClick to open your parcels.")) + .type(Material.ENDER_CHEST); + + @Comment({ " ", "# The item of the sent parcels button" }) + public ConfigItem sentParcelsItem = new ConfigItem() + .name("&6\uD83D\uDCE6 Sent parcels") + .lore(List.of("&eClick to show parcels, which you sent.", "&eYou can also cancel them here, if you want to.")) + .type(Material.YELLOW_SHULKER_BOX) + .glow(true); + + @Comment({ " ", "# The parcel archive item button." }) + public ConfigItem parcelArchiveItem = new ConfigItem() + .name("&5\uD83D\uDCDA Parcel archive") + .lore(List.of("&eClick to show all parcels, which you sent or received in the past.", "&c&oNot implemented yet")) + .type(Material.BOOKSHELF); + + @Comment({ " ", "# The item of the parcel locker collect button" }) + public ConfigItem parcelLockerCollectItem = new ConfigItem() + .name("&2โฌ‡ Collect parcels") + .lore(List.of("&2Click to collect your parcels.")) + .type(Material.CHEST) + .glow(true); + + @Comment({ " ", "# The item of the parcel locker send button" }) + public ConfigItem parcelLockerSendItem = new ConfigItem() + .name("&6โฌ† Send parcels") + .lore(List.of("&6Click to send parcels.")) + .type(Material.CHEST_MINECART) + .glow(true); + + @Comment({ " ", "# The item of the parcel" }) + public ConfigItem parcelItem = new ConfigItem() + .name("&6{NAME}") + .lore(List.of( + "&6UUID: &e{UUID}", + "&6Sender: &e{SENDER}", + "&6Receiver: &e{RECEIVER}", + "&6Size: &e{SIZE}", + "&6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", + "&6Priority: &e{PRIORITY}", + "&6Description: &e{DESCRIPTION}" + ) + ) + .type(Material.CHEST_MINECART); + + @Comment({ " ", "# The item of the parcel item storage button" }) + public ConfigItem parcelStorageItem = new ConfigItem() + .name("&6\uD83D\uDCE4 Parcel storage") + .lore(List.of("&eClick to edit the parcel content.")) + .type(Material.CHEST); + + @Comment({ " ", "# The item of the parcel name button" }) + public ConfigItem parcelNameItem = new ConfigItem() + .name("&4โœŽ &cParcel name") + .lore(List.of("&cClick to edit the parcel name.")) + .type(Material.NAME_TAG); + + @Comment({ " ", "# The value of the GUI line, when parcel name is set" }) + public String parcelNameSetLine = "&6> Current parcel name: &e{NAME}"; + + @Comment({ " ", "# The item of the parcel description button" }) + public ConfigItem parcelDescriptionItem = new ConfigItem() + .name("&2โ˜ฐ &aParcel description") + .lore(List.of("&aClick to edit the parcel description.")) + .type(Material.PAPER); + + public String parcelDescriptionSetLine = "&2> &aCurrent parcel description: &2{DESCRIPTION}"; + + @Comment({ " ", "# The item of the parcel receiver button" }) + public ConfigItem parcelReceiverItem = new ConfigItem() + .name("&5\uD83E\uDDCD &dParcel receiver") + .lore(List.of("&dClick to edit the parcel receiver.")) + .type(Material.PLAYER_HEAD); + + @Comment({ " ", "# The value of the GUI line, when parcel name is set" }) + public String parcelReceiverGuiSetLine = "&5ยป &dCurrent parcel receiver: &5{RECEIVER}"; + + @Comment({ " ", "# The value of the player itemlore line, when parcel receiver is not set" }) + public String parcelReceiverNotSetLine = "&9โ€บ &bClick to select."; + + @Comment({ " ", "# The value of the player item lore line, when parcel receiver is set" }) + public String parcelReceiverSetLine = "&2โœ” &aSelected!"; + + @Comment({ " ", "# The item of the parcel destination locker button" }) + public ConfigItem parcelDestinationLockerItem = new ConfigItem() + .name("&3\uD83D\uDCCD Destination locker") + .lore(List.of("&3Click to edit the parcel destination locker.")) + .type(Material.COMPASS); + + @Comment({ " ", "# The item of the previous page button" }) + public ConfigItem previousPageItem = new ConfigItem() + .name("&bโ† Previous page") + .lore(List.of("&bClick to go to the previous page.")) + .type(Material.ARROW); + + @Comment({ " ", "# The item of the next page button" }) + public ConfigItem nextPageItem = new ConfigItem() + .name("&bโ†’ Next page") + .lore(List.of("&bClick to go to the next page.")) + .type(Material.ARROW); + + @Comment({ " ", "# The item of the confirm items button" }) + public ConfigItem confirmItemsItem = new ConfigItem() + .name("&aโœ” Confirm items") + .lore(List.of("&aClick to confirm the items.")) + .type(Material.LIME_WOOL); + + @Comment({ " ", "# The name of the parcel small content GUI" }) + public String parcelSmallContentGuiTitle = "&2Small parcel content"; + + @Comment({ " ", "# The name of the parcel medium content GUI" }) + public String parcelMediumContentGuiTitle = "&6Medium parcel content"; + + @Comment({ " ", "# The name of the parcel large content GUI" }) + public String parcelLargeContentGuiTitle = "&4Large parcel content"; + + @Comment({ " ", "# The title of the parcel destination locker selection GUI" }) + public String parcelDestinationLockerSelectionGuiTitle = "&3Select destination locker"; + + @Comment({ " ", "# The item of the parcel in destination selection GUI" }) + public ConfigItem destinationLockerItem = new ConfigItem() + .name("&3{DESCRIPTION}") + .lore(List.of("&bClick to select this locker.")) + .type(Material.CHEST); + + @Comment({ " ", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) + public String parcelDestinationLockerSetLine = "&6โ€บ &eCurrent destination locker: &6{DESCRIPTION}"; + + @Comment({ " ", "# The destination GUI locker button lore in case the destination locker is set." }) + public String parcelDestinationSetLine = "&2โœ” &aSelected!"; + + @Comment({ " ", "# The destination GUI locker button lore in case the destination locker is not set." }) + public String parcelDestinationNotSetLine = "&9โ€บ &bClick to select."; + + @Comment({ " ", "# Illegal items list, that cannot be stored in the parcel." }) + public List illegalItems = List.of( + Material.BARRIER, + Material.COMMAND_BLOCK, + Material.COMMAND_BLOCK_MINECART, + Material.CHAIN_COMMAND_BLOCK, + Material.REPEATING_COMMAND_BLOCK, + Material.STRUCTURE_BLOCK, + Material.STRUCTURE_VOID, + Material.JIGSAW, + Material.DEBUG_STICK, + Material.SPAWNER, + Material.BEDROCK, + Material.VAULT, + Material.END_PORTAL_FRAME + ); + + @Comment({ " ", "# The item of the parcel item in the collection GUI" }) + public ConfigItem parcelCollectionItem = new ConfigItem() + .name("&a{NAME}") + .lore(List.of( + "&6UUID: &e{UUID}", + "&6Sender: &e{SENDER}", + "&6Size: &e{SIZE}", + "&6Description: &e{DESCRIPTION}" + ) + ) + .type(Material.CHEST_MINECART); + + @Comment({ " ", "# The item that is displayed in the collection GUI when no parcels are found" }) + public ConfigItem noParcelsItem = new ConfigItem() + .name("&cNo parcels found") + .lore(List.of("&cYou don't have any parcels to collect.")) + .type(Material.BARRIER); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfiguration.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfiguration.java deleted file mode 100644 index 4055b0261..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfiguration.java +++ /dev/null @@ -1,407 +0,0 @@ -package com.eternalcode.parcellockers.configuration.implementation; - -import com.eternalcode.parcellockers.configuration.ReloadableConfig; -import com.eternalcode.parcellockers.database.DatabaseType; -import net.dzikoysk.cdn.entity.Contextual; -import net.dzikoysk.cdn.entity.Description; -import net.dzikoysk.cdn.source.Resource; -import net.dzikoysk.cdn.source.Source; -import org.bukkit.Material; -import org.bukkit.Sound; - -import java.io.File; -import java.time.Duration; -import java.util.Collections; -import java.util.List; - -public class PluginConfiguration implements ReloadableConfig { - - @Description({ " ", "# Parcel Lockers plugin configuration file." }) - public Settings settings = new Settings(); - - @Description({ " ", "# The plugin messages." }) - public Messages messages = new Messages(); - - @Description({ " ", "# The plugin GUI settings." }) - public GuiSettings guiSettings = new GuiSettings(); - - @Override - public Resource resource(File folder) { - return Source.of(folder, "config.yml"); - } - - @Contextual - public static class Settings { - - @Description({ " ", - "# Should we enable Sentry integration?", - "# Sentry is a service that collects errors and other information about the plugin.", - "# It is used to improve the plugin and fix bugs.", - "# It is also strongly recommended to enable this option.", - "# You can learn more about Sentry here: https://sentry.io/" }) - public boolean enableSentry = true; - - @Description({ " ", "# Set to enable debug mode and receive more detailed information in the console." }) - public boolean debug = false; - - @Description({ " ", "# Whether the player after entering the server should receive information about the new version of the plugin?" }) - public boolean receiveUpdates = true; - - @Description({ " ", "# The database type. (MYSQL, SQLITE)" }) - public DatabaseType databaseType = DatabaseType.SQLITE; - - @Description({ " ", "# The URL to the database." }) - public String host = "localhost"; - - @Description({ " ", "# The database name." }) - public String databaseName = "parcellockers"; - - @Description({ " ", "# The database user." }) - public String user = "root"; - - @Description({ " ", "# The database port." }) - public String port = "3306"; - - @Description({ " ", "# The database password." }) - public String password = ""; - - @Description({ " ", "# The parcel locker item." }) - public ConfigItem parcelLockerItem = new ConfigItem() - .setName("&3Parcel locker") - .setType(Material.CHEST) - .setLore(List.of("&bPlace to create a parcel locker.")); - - @Description({" ", "# Standard parcel sending duration"}) - public Duration parcelSendDuration = Duration.ofSeconds(10); - - @Description({" ", "# Parcel sending duration for priority parcels"}) - public Duration priorityParcelSendDuration = Duration.ofSeconds(5); - - @Description({" ", "# Error sound used in the plugin."}) - public Sound errorSound = Sound.ENTITY_ENDERMAN_AMBIENT; - - @Description({ " ", "# The sound volume for the error sound." }) - public float errorSoundVolume = 1.0F; - - @Description({ " ", "# The sound pitch for the error sound." }) - public float errorSoundPitch = 1.0F; - - - } - - @Contextual - public static class Messages { - - public String onlyForPlayers = "&4โœ˜ &cThis command is only available to players!"; - public String noPermission = "&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"; - public String cantFindPlayer = "&4โœ˜ &cThe specified player could not be found!"; - public String invalidUsage = "&4โฃ &cCorrect usage: &6{USAGE}"; - public String reload = "&3โฃ &bConfiguration has been successfully reloaded!"; - public String parcelCommandUsage = "&9โ“˜ Correct usage: &3/parcel &b &3[parcel]"; - public String parcelSuccessfullyDeleted = "&2โœ” &aParcel deleted successfully."; - public String failedToDeleteParcel = "&4โœ˜ &cAn error occurred while deleting the parcel."; - public String failedToCreateParcelLocker = "&4โœ˜ &cCould not create the parcel locker."; - public String parcelLockerSuccessfullyCreated = "&7ยป &aParcel locker created successfully."; - public String enterDescriptionPrompt = "&6โ†ต &eEnter a description for the parcel locker:"; - public String cannotBreakParcelLocker = "&4โœ˜ &cYou have no permission to break the parcel locker."; - public String parcelLockerSuccessfullyDeleted = "&2โœ” &aParcel locker deleted successfully."; - public String broadcastParcelLockerRemoved = "&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"; - public String parcelSent = "&2โœ” &aParcel sent successfully."; - public String parcelFailedToSend = "&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."; - public String illegalItemFailedToSend = "&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"; - public String parcelCannotBeEmpty = "&4โœ˜ &cThe parcel cannot be empty!"; - public String parcelNameCannotBeEmpty = "&4โœ˜ &cThe parcel name cannot be empty!"; - public String parcelNameSet = "&2โœ” &aParcel name set successfully."; - public String parcelDescriptionSet = "&2โœ” &aParcel description set successfully."; - public String parcelReceiverSet = "&2โœ” &aParcel receiver set successfully."; - public String parcelDestinationSet = "&2โœ” &aParcel destination locker set successfully."; - public String alreadyCreatingLocker = "&4โœ˜ &cYou are already creating a parcel locker!"; - public String receiverNotSet = "&4โœ˜ &cThe parcel receiver is not set!"; - public String parcelSuccessfullyCollected = "&2โœ” &aParcel collected successfully."; - public String failedToCollectParcel = "&4โœ˜ &cAn error occurred while collecting the parcel."; - public String notEnoughInventorySpace = "&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"; - - @Description({ " ", "# The parcel info message." }) - public List parcelInfoMessages = List.of( - "&7ยป &6Parcel info:", - "&fโ€ข &6UUID: &e{UUID}", - "&fโ€ข &6Sender: &e{SENDER}", - "&fโ€ข &6Receiver: &e{RECEIVER}", - "&fโ€ข &6Size: &e{SIZE}", - "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", - "&fโ€ข &6Priority: &e{PRIORITY}", - "&fโ€ข &6Description: &e{DESCRIPTION}" - ); - } - - @Contextual - public static class GuiSettings { - - @Description({ " ", "# The title of the main GUI" }) - public String mainGuiTitle = "&3Main menu"; - - @Description({ " ", "# The title of the parcel list GUI" }) - public String parcelListGuiTitle = "&aMy parcels"; - - @Description({ " ", "# The item of the sent parcels GUI" }) - public String sentParcelsTitle = "&6Sent parcels"; - - @Description({ " ", "# The item of the parcel locker sending GUI" }) - public String parcelLockerSendingGuiTitle = "&3Parcel sending"; - - @Description({ " ", "# The item of the parcel recipient pick GUI" }) - public String parcelReceiverSelectionGuiTitle = "&5Select recipient"; - - @Description({ " ", "# The item of the parcel collection GUI" }) - public String parcelCollectionGuiTitle = "&aCollect parcels"; - - @Description({ " ", "# The item of the small parcel size button" }) - public ConfigItem smallParcelSizeItem = new ConfigItem() - .setName("&aโžป Small") - .setLore(List.of("&aClick to select the small parcel size.")) - .setType(Material.LIME_WOOL); - - @Description({ " ", "# The item of the medium parcel size button" }) - public ConfigItem mediumParcelSizeItem = new ConfigItem() - .setName("&eโžผ Medium") - .setLore(List.of("&eClick to select the medium parcel size.")) - .setType(Material.YELLOW_WOOL); - - @Description({ " ", "# The item of the large parcel size button" }) - public ConfigItem largeParcelSizeItem = new ConfigItem() - .setName("&cโžฝ Large") - .setLore(List.of("&cClick to select the large parcel size.")) - .setType(Material.RED_WOOL); - - @Description({ " ", "# The item represents selected small parcel size." }) - public ConfigItem selectedSmallParcelSizeItem = new ConfigItem() - .setName("&aโžป Small") - .setLore(List.of("&aโœง Currently selected!")) - .setGlow(true) - .setType(Material.OAK_CHEST_BOAT); - - @Description({ " ", "# The item represents selected medium parcel size." }) - public ConfigItem selectedMediumParcelSizeItem = new ConfigItem() - .setName("&eโžผ Medium") - .setLore(List.of("&aCurrently selected!")) - .setGlow(true) - .setType(Material.CHEST_MINECART); - - @Description({ " ", "# The item represents selected large parcel size." }) - public ConfigItem selectedLargeParcelSizeItem = new ConfigItem() - .setName("&cโžฝ Large") - .setLore(List.of("&aCurrently selected!")) - .setGlow(true) - .setType(Material.TNT_MINECART); - - @Description({ " ", "# The item of the priority button" }) - public ConfigItem priorityItem = new ConfigItem() - .setName("&c\uD83D\uDE80 Priority") - .setLore(List.of("&cClick to select the priority.")) - .setType(Material.FIREWORK_ROCKET); - - @Description({ " ", "# The item of the selected priority button" }) - public ConfigItem selectedPriorityItem = new ConfigItem() - .setName("&c\uD83D\uDE80 Priority") - .setLore(List.of("&4Currently selected!", "&7&oClick to unselect.")) - .setType(Material.FIREWORK_ROCKET) - .setGlow(true); - - @Description({ " ", "# The close button item" }) - public ConfigItem closeItem = new ConfigItem() - .setName("&cโ˜“ Close") - .setLore(List.of("&cClick to close the GUI.")) - .setType(Material.BARRIER); - - @Description({ " ", "# The item of the main GUI" }) - public ConfigItem mainGuiBackgroundItem = new ConfigItem() - .setName("") - .setLore(Collections.emptyList()) - .setType(Material.GRAY_STAINED_GLASS_PANE); - - @Description({ " ", "# The item of the corner GUI item.", "# Purely for decoration purposes." }) - public ConfigItem cornerItem = new ConfigItem() - .setName("") - .setLore(Collections.emptyList()) - .setType(Material.BLUE_STAINED_GLASS_PANE); - - @Description({ " ", "# The item of the parcel submit button" }) - public ConfigItem submitParcelItem = new ConfigItem() - .setName("&aโœ” Submit") - .setLore(List.of("Click to submit the parcel.", "Proceed with caution! This action is final and cannot be undone.")) - .setType(Material.ENDER_PEARL) - .setGlow(true); - - @Description({ " ", "# The item of the parcel list button" }) - public ConfigItem myParcelsItem = new ConfigItem() - .setName("&3โ›ƒ My parcels") - .setLore(List.of("&bClick to open your parcels.")) - .setType(Material.ENDER_CHEST); - - @Description({ " ", "# The item of the sent parcels button" }) - public ConfigItem sentParcelsItem = new ConfigItem() - .setName("&6\uD83D\uDCE6 Sent parcels") - .setLore(List.of("&eClick to show parcels, which you sent.", "&eYou can also cancel them here, if you want to.")) - .setType(Material.YELLOW_SHULKER_BOX) - .setGlow(true); - - @Description({ " ", "# The parcel archive item button." }) - public ConfigItem parcelArchiveItem = new ConfigItem() - .setName("&5\uD83D\uDCDA Parcel archive") - .setLore(List.of("&eClick to show all parcels, which you sent or received in the past.", "&c&oNot implemented yet")) - .setType(Material.BOOKSHELF); - - @Description({ " ", "# The item of the parcel locker collect button" }) - public ConfigItem parcelLockerCollectItem = new ConfigItem() - .setName("&2โฌ‡ Collect parcels") - .setLore(List.of("&2Click to collect your parcels.")) - .setType(Material.CHEST) - .setGlow(true); - - @Description({ " ", "# The item of the parcel locker send button" }) - public ConfigItem parcelLockerSendItem = new ConfigItem() - .setName("&6โฌ† Send parcels") - .setLore(List.of("&6Click to send parcels.")) - .setType(Material.CHEST_MINECART) - .setGlow(true); - - @Description({ " ", "# The item of the parcel" }) - public ConfigItem parcelItem = new ConfigItem() - .setName("&6{NAME}") - .setLore(List.of( - "&6UUID: &e{UUID}", - "&6Sender: &e{SENDER}", - "&6Receiver: &e{RECEIVER}", - "&6Size: &e{SIZE}", - "&6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", - "&6Priority: &e{PRIORITY}", - "&6Description: &e{DESCRIPTION}" - ) - ) - .setType(Material.CHEST_MINECART); - - @Description({ " ", "# The item of the parcel item storage button" }) - public ConfigItem parcelStorageItem = new ConfigItem() - .setName("&6\uD83D\uDCE4 Parcel storage") - .setLore(List.of("&eClick to edit the parcel content.")) - .setType(Material.CHEST); - - @Description({ " ", "# The item of the parcel name button" }) - public ConfigItem parcelNameItem = new ConfigItem() - .setName("&4โœŽ &cParcel name") - .setLore(List.of("&cClick to edit the parcel name.")) - .setType(Material.NAME_TAG); - - @Description({ " ", "# The value of the GUI line, when parcel name is set" }) - public String parcelNameSetLine = "&6> Current parcel name: &e{NAME}"; - - @Description({ " ", "# The item of the parcel description button" }) - public ConfigItem parcelDescriptionItem = new ConfigItem() - .setName("&2โ˜ฐ &aParcel description") - .setLore(List.of("&aClick to edit the parcel description.")) - .setType(Material.PAPER); - - public String parcelDescriptionSetLine = "&2> &aCurrent parcel description: &2{DESCRIPTION}"; - - @Description({ " ", "# The item of the parcel receiver button" }) - public ConfigItem parcelReceiverItem = new ConfigItem() - .setName("&5\uD83E\uDDCD &dParcel receiver") - .setLore(List.of("&dClick to edit the parcel receiver.")) - .setType(Material.PLAYER_HEAD); - - @Description({ " ", "# The value of the GUI line, when parcel name is set" }) - public String parcelReceiverGuiSetLine = "&5ยป &dCurrent parcel receiver: &5{RECEIVER}"; - - @Description({ " ", "# The value of the player itemlore line, when parcel receiver is not set" }) - public String parcelReceiverNotSetLine = "&9โ€บ &bClick to select."; - - @Description({ " ", "# The value of the player item lore line, when parcel receiver is set" }) - public String parcelReceiverSetLine = "&2โœ” &aSelected!"; - - @Description({ " ", "# The item of the parcel destination locker button" }) - public ConfigItem parcelDestinationLockerItem = new ConfigItem() - .setName("&3\uD83D\uDCCD Destination locker") - .setLore(List.of("&3Click to edit the parcel destination locker.")) - .setType(Material.COMPASS); - - @Description({ " ", "# The item of the previous page button" }) - public ConfigItem previousPageItem = new ConfigItem() - .setName("&bโ† Previous page") - .setLore(List.of("&bClick to go to the previous page.")) - .setType(Material.ARROW); - - @Description({ " ", "# The item of the next page button" }) - public ConfigItem nextPageItem = new ConfigItem() - .setName("&bโ†’ Next page") - .setLore(List.of("&bClick to go to the next page.")) - .setType(Material.ARROW); - - @Description({ " ", "# The item of the confirm items button" }) - public ConfigItem confirmItemsItem = new ConfigItem() - .setName("&aโœ” Confirm items") - .setLore(List.of("&aClick to confirm the items.")) - .setType(Material.LIME_WOOL); - - @Description({ " ", "# The name of the parcel small content GUI" }) - public String parcelSmallContentGuiTitle = "&2Small parcel content"; - - @Description({ " ", "# The name of the parcel medium content GUI" }) - public String parcelMediumContentGuiTitle = "&6Medium parcel content"; - - @Description({ " ", "# The name of the parcel large content GUI" }) - public String parcelLargeContentGuiTitle = "&4Large parcel content"; - - @Description({ " ", "# The title of the parcel destination locker selection GUI" }) - public String parcelDestinationLockerSelectionGuiTitle = "&3Select destination locker"; - - @Description({ " ", "# The item of the parcel in destination selection GUI" }) - public ConfigItem destinationLockerItem = new ConfigItem() - .setName("&3{DESCRIPTION}") - .setLore(List.of("&bClick to select this locker.")) - .setType(Material.CHEST); - - @Description({ " ", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) - public String parcelDestinationLockerSetLine = "&6โ€บ &eCurrent destination locker: &6{DESCRIPTION}"; - - @Description({ " ", "# The destination GUI locker button lore in case the destination locker is set." }) - public String parcelDestinationSetLine = "&2โœ” &aSelected!"; - - @Description({ " ", "# The destination GUI locker button lore in case the destination locker is not set." }) - public String parcelDestinationNotSetLine = "&9โ€บ &bClick to select."; - - @Description({ " ", "# Illegal items list, that cannot be stored in the parcel." }) - public List illegalItems = List.of( - Material.BARRIER, - Material.COMMAND_BLOCK, - Material.COMMAND_BLOCK_MINECART, - Material.CHAIN_COMMAND_BLOCK, - Material.REPEATING_COMMAND_BLOCK, - Material.STRUCTURE_BLOCK, - Material.STRUCTURE_VOID, - Material.JIGSAW, - Material.DEBUG_STICK, - Material.SPAWNER, - Material.BEDROCK, - Material.VAULT, - Material.END_PORTAL_FRAME - ); - - @Description({ " ", "# The item of the parcel item in the collection GUI" }) - public ConfigItem parcelCollectionItem = new ConfigItem() - .setName("&a{NAME}") - .setLore(List.of( - "&6UUID: &e{UUID}", - "&6Sender: &e{SENDER}", - "&6Size: &e{SIZE}", - "&6Description: &e{DESCRIPTION}" - ) - ) - .setType(Material.CHEST_MINECART); - - @Description({ " ", "# The item that is displayed in the collection GUI when no parcels are found" }) - public ConfigItem noParcelsItem = new ConfigItem() - .setName("&cNo parcels found") - .setLore(List.of("&cYou don't have any parcels to collect.")) - .setType(Material.BARRIER); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java similarity index 64% rename from src/main/java/com/eternalcode/parcellockers/configuration/implementation/ConfigItem.java rename to src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index 40285909b..c802c8a95 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -1,5 +1,4 @@ -package com.eternalcode.parcellockers.configuration.implementation; - +package com.eternalcode.parcellockers.configuration.serializable; import com.eternalcode.commons.adventure.AdventureLegacyColorPostProcessor; import com.eternalcode.commons.adventure.AdventureLegacyColorPreProcessor; @@ -7,8 +6,12 @@ import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.components.GuiAction; import dev.triumphteam.gui.guis.GuiItem; -import net.dzikoysk.cdn.entity.Contextual; -import net.dzikoysk.cdn.entity.Exclude; +import eu.okaeri.configs.OkaeriConfig; +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Material; import org.bukkit.event.inventory.InventoryClickEvent; @@ -16,22 +19,20 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; - -@Contextual -public class ConfigItem implements Cloneable { +@Getter +@Setter +@Accessors(fluent = true) +public class ConfigItem extends OkaeriConfig implements Cloneable { - @Exclude private static final MiniMessage MINI_MESSAGE = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) .build(); - public Material type = Material.STONE; - public String name = "&fItem name"; - public List lore = List.of("&fFirst line of lore", "&9Second line of lore"); - public boolean glow = false; + private Material type = Material.STONE; + private String name = ""; + private List lore = List.of(); + private boolean glow = false; public GuiItem toGuiItem(GuiAction action) { return ItemBuilder.from(this.type) @@ -54,67 +55,14 @@ public GuiItem toGuiItem(GuiAction action) { .glow(this.glow); } - @Exclude public GuiItem toGuiItem() { return this.toBuilder().asGuiItem(); } - @Exclude public ItemStack toItemStack() { return this.toBuilder().build(); } - @Exclude - public Material getType() { - return this.type; - } - - @Exclude - public String getName() { - return this.name; - } - - @Exclude - public List getLore() { - return this.lore; - } - - @Exclude - public boolean isGlow() { - return this.glow; - } - - @Exclude - public ConfigItem setType(Material type) { - this.type = type; - return this; - } - - @Exclude - public ConfigItem setName(String name) { - this.name = name; - return this; - } - - @Exclude - public ConfigItem setLore(List lore) { - this.lore = lore; - return this; - } - - @Exclude - public ConfigItem addLore(String lore) { - this.lore.add(lore); - return this; - } - - @Exclude - public ConfigItem setGlow(boolean glow) { - this.glow = glow; - return this; - } - - @Exclude @Override public ConfigItem clone() { try { diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java index 982388a22..ca71befca 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java @@ -4,8 +4,8 @@ import com.eternalcode.parcellockers.content.ParcelContent; import com.eternalcode.parcellockers.database.DatabaseManager; import com.eternalcode.parcellockers.database.wrapper.AbstractRepositoryOrmLite; +import com.eternalcode.parcellockers.shared.ParcelLockersException; import com.j256.ormlite.table.TableUtils; -import io.sentry.Sentry; import java.sql.SQLException; import java.util.Optional; import java.util.UUID; @@ -19,8 +19,7 @@ public ParcelContentRepositoryOrmLite(DatabaseManager databaseManager, Scheduler try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), ParcelContentTable.class); } catch (SQLException exception) { - Sentry.captureException(exception); - throw new RuntimeException("Failed to create ParcelContent table", exception); + throw new ParcelLockersException("Failed to create ParcelContent table", exception); } } diff --git a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java b/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java index 495661d30..192c8a1ba 100644 --- a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java +++ b/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.conversation; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import org.bukkit.ChatColor; import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.Prompt; @@ -9,9 +9,9 @@ public class ParcelLockerPlacePrompt implements Prompt { - private final PluginConfiguration config; + private final PluginConfig config; - public ParcelLockerPlacePrompt(PluginConfiguration config) { + public ParcelLockerPlacePrompt(PluginConfig config) { this.config = config; } diff --git a/src/main/java/com/eternalcode/parcellockers/database/DatabaseManager.java b/src/main/java/com/eternalcode/parcellockers/database/DatabaseManager.java index 3e1098391..e622e0012 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/DatabaseManager.java +++ b/src/main/java/com/eternalcode/parcellockers/database/DatabaseManager.java @@ -1,13 +1,12 @@ package com.eternalcode.parcellockers.database; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.google.common.base.Stopwatch; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.dao.DaoManager; import com.j256.ormlite.jdbc.DataSourceConnectionSource; import com.j256.ormlite.support.ConnectionSource; import com.zaxxer.hikari.HikariDataSource; - import java.io.File; import java.sql.SQLException; import java.util.Map; @@ -17,7 +16,7 @@ public class DatabaseManager { - private final PluginConfiguration config; + private final PluginConfig config; private final Logger logger; private final File dataFolder; @@ -26,7 +25,7 @@ public class DatabaseManager { private HikariDataSource dataSource; private ConnectionSource connectionSource; - public DatabaseManager(PluginConfiguration config, Logger logger, File dataFolder) { + public DatabaseManager(PluginConfig config, Logger logger, File dataFolder) { this.config = config; this.logger = logger; this.dataFolder = dataFolder; diff --git a/src/main/java/com/eternalcode/parcellockers/database/persister/ItemStackPersister.java b/src/main/java/com/eternalcode/parcellockers/database/persister/ItemStackPersister.java index eb908acfb..b463de680 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/persister/ItemStackPersister.java +++ b/src/main/java/com/eternalcode/parcellockers/database/persister/ItemStackPersister.java @@ -9,7 +9,6 @@ import com.j256.ormlite.field.types.BaseDataType; import com.j256.ormlite.support.DatabaseResults; import de.eldoria.jacksonbukkit.JacksonPaper; -import io.sentry.Sentry; import java.sql.SQLException; import java.util.List; import org.bukkit.inventory.ItemStack; @@ -40,7 +39,6 @@ public Object javaToSqlArg(FieldType fieldType, Object javaObject) { try { return JSON.writeValueAsString(stacks); } catch (JsonProcessingException e) { - Sentry.captureException(e); throw new ParcelLockersException("Failed to serialize itemstacks", e); } } @@ -62,7 +60,6 @@ public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) { try { return JSON.readValue(string, JSON.getTypeFactory().constructCollectionType(List.class, ItemStack.class)); } catch (JsonProcessingException exception) { - Sentry.captureException(exception); throw new ParcelLockersException("Failed to deserialize itemstacks", exception); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java index 0547ad5e2..e022492f8 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java @@ -1,26 +1,24 @@ package com.eternalcode.parcellockers.gui.implementation.locker; -import com.eternalcode.parcellockers.configuration.implementation.ConfigItem; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerPageResult; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; - import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitScheduler; public class DestinationSelectionGui implements GuiView { @@ -30,7 +28,7 @@ public class DestinationSelectionGui implements GuiView { private final Plugin plugin; private final BukkitScheduler scheduler; - private final PluginConfiguration config; + private final PluginConfig config; private final MiniMessage miniMessage; private final LockerRepository lockerRepository; private final ParcelSendingGui sendingGUI; @@ -39,7 +37,7 @@ public class DestinationSelectionGui implements GuiView { public DestinationSelectionGui( Plugin plugin, BukkitScheduler scheduler, - PluginConfiguration config, + PluginConfig config, MiniMessage miniMessage, LockerRepository lockerRepository, ParcelSendingGui sendingGUI, @@ -94,8 +92,7 @@ private void show(Player player, Page page) { this.loadLockers(player, result, refresher).forEach(refresher::addItem); this.scheduler.runTask(this.plugin, () -> gui.open(player)); - }).whenComplete(SentryExceptionHandler.handler()) - .orTimeout(5, TimeUnit.SECONDS); + }).orTimeout(5, TimeUnit.SECONDS); } private List> loadLockers(Player player, LockerPageResult result, PaginatedGuiRefresher refresh) { @@ -109,16 +106,16 @@ private Supplier toItem(Player player, Locker locker, PaginatedGuiRefre ConfigItem parcelItem = this.config.guiSettings.destinationLockerItem.clone(); return () -> { - String name = parcelItem.getName().replace("{DESCRIPTION}", locker.description()); + String name = parcelItem.name().replace("{DESCRIPTION}", locker.description()); boolean isLockerSelected = uuid.equals(this.state.getDestinationLocker()); String oneLineLore = isLockerSelected ? this.config.guiSettings.parcelDestinationSetLine : this.config.guiSettings.parcelDestinationNotSetLine; return parcelItem - .setName(name) - .setGlow(isLockerSelected) - .setLore(List.of(oneLineLore)) + .name(name) + .glow(isLockerSelected) + .lore(List.of(oneLineLore)) .toGuiItem(event -> { if (isLockerSelected) { this.state.setDestinationLocker(null); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index c4bb31ec1..a57ad00b5 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -2,7 +2,7 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; @@ -25,7 +25,7 @@ public class LockerMainGui implements GuiView { private final Plugin plugin; private final MiniMessage miniMessage; - private final PluginConfiguration config; + private final PluginConfig config; private final ItemStorageRepository itemStorageRepository; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; @@ -40,7 +40,7 @@ public class LockerMainGui implements GuiView { public LockerMainGui( Plugin plugin, MiniMessage miniMessage, - PluginConfiguration config, + PluginConfig config, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, LockerRepository lockerRepository, diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java index 023dd241f..b9e223cb6 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java @@ -1,7 +1,7 @@ package com.eternalcode.parcellockers.gui.implementation.locker; -import com.eternalcode.parcellockers.configuration.implementation.ConfigItem; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; @@ -10,7 +10,6 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import com.eternalcode.parcellockers.user.UserManager; import com.eternalcode.parcellockers.util.InventoryUtil; import dev.triumphteam.gui.guis.Gui; @@ -29,7 +28,7 @@ public class ParcelCollectionGui implements GuiView { private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); private final Plugin plugin; - private final PluginConfiguration config; + private final PluginConfig config; private final BukkitScheduler scheduler; private final ParcelRepository parcelRepository; private final MiniMessage miniMessage; @@ -39,7 +38,7 @@ public class ParcelCollectionGui implements GuiView { public ParcelCollectionGui( Plugin plugin, - PluginConfiguration config, + PluginConfig config, BukkitScheduler scheduler, ParcelRepository parcelRepository, MiniMessage miniMessage, @@ -63,7 +62,7 @@ public void show(Player player) { } private void show(Player player, Page page) { - PluginConfiguration.GuiSettings guiSettings = this.config.guiSettings; + PluginConfig.GuiSettings guiSettings = this.config.guiSettings; Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelCollectionGuiTitle); @@ -117,20 +116,20 @@ private void show(Player player, Page page) { } ConfigItem item = parcelItem.clone(); - item.name = item.name.replace("{NAME}", parcel.name()); - item.lore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userManager, this.lockerRepository); + item.name(item.name().replace("{NAME}", parcel.name())); + item.lore(ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.userManager, this.lockerRepository)); - item.setGlow(true); + item.glow(true); gui.addItem(item.toGuiItem(event -> { this.parcelService.collect(player, parcel); gui.removeItem(event.getSlot()); - InventoryUtil.shiftItems(event.getSlot(), gui, item.type); + InventoryUtil.shiftItems(event.getSlot(), gui, item.type()); gui.update(); })); } this.scheduler.runTask(this.plugin, () -> gui.open(player)); - }).whenComplete(SentryExceptionHandler.handler()); + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java index 5503bb598..ea0048e27 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java @@ -1,7 +1,7 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.bukkit.ItemUtil; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.itemstorage.ItemStorage; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; @@ -10,7 +10,6 @@ import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import com.eternalcode.parcellockers.user.repository.UserRepository; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; @@ -29,7 +28,7 @@ public class ParcelItemStorageGui { private final Plugin plugin; - private final PluginConfiguration config; + private final PluginConfig config; private final MiniMessage miniMessage; private final ItemStorageRepository itemStorageRepository; private final ParcelRepository parcelRepository; @@ -43,7 +42,7 @@ public class ParcelItemStorageGui { public ParcelItemStorageGui( Plugin plugin, - PluginConfiguration config, + PluginConfig config, MiniMessage miniMessage, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, @@ -70,7 +69,7 @@ public ParcelItemStorageGui( void show(Player player, ParcelSize size) { StorageGui gui; - PluginConfiguration.GuiSettings guiSettings = this.config.guiSettings; + PluginConfig.GuiSettings guiSettings = this.config.guiSettings; GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); @@ -135,7 +134,7 @@ void show(Player player, ParcelSize size) { this.itemStorageRepository.delete(player.getUniqueId()).thenAccept(unused -> { this.itemStorageRepository.save(new ItemStorage(player.getUniqueId(), items)); - }).whenComplete(SentryExceptionHandler.handler()); + }); }); this.itemStorageRepository.find(player.getUniqueId()).thenAccept(optional -> { @@ -148,6 +147,6 @@ void show(Player player, ParcelSize size) { } this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); - }).whenComplete(SentryExceptionHandler.handler()); + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java index 987fa2204..034fb4da2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java @@ -1,8 +1,8 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.adventure.AdventureUtil; -import com.eternalcode.parcellockers.configuration.implementation.ConfigItem; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; @@ -50,7 +50,7 @@ public class ParcelSendingGui implements GuiView { private static final int CLOSE_ITEM_SLOT = 49; private final Plugin plugin; private final BukkitScheduler scheduler; - private final PluginConfiguration config; + private final PluginConfig config; private final MiniMessage miniMessage; private final ItemStorageRepository itemStorageRepository; private final ParcelRepository parcelRepository; @@ -67,7 +67,7 @@ public class ParcelSendingGui implements GuiView { public ParcelSendingGui( Plugin plugin, - PluginConfiguration config, + PluginConfig config, MiniMessage miniMessage, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, @@ -96,8 +96,8 @@ public ParcelSendingGui( @Override public void show(Player player) { - PluginConfiguration settings = this.config; - PluginConfiguration.GuiSettings guiSettings = settings.guiSettings; + PluginConfig settings = this.config; + PluginConfig.GuiSettings guiSettings = settings.guiSettings; Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelLockerSendingGuiTitle); @@ -136,7 +136,7 @@ public void show(Player player) { ? "None" : this.state.getParcelName())); this.gui.updateItem(NAME_ITEM_SLOT, nameItem - .setLore(lore) + .lore(lore) .toItemStack()); return List.of(SignGUIAction.runSync((JavaPlugin) this.plugin, () -> this.gui.open(player))); }) @@ -170,7 +170,7 @@ public void show(Player player) { lore.add(this.config.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", description)); this.gui.updateItem(DESCRIPTION_ITEM_SLOT, descriptionItem - .setLore(lore) + .lore(lore) .toItemStack()); return List.of(SignGUIAction.runSync((JavaPlugin) this.plugin, () -> this.gui.open(player))); }) @@ -312,7 +312,7 @@ public void show(Player player) { } private void setSelected(Gui gui, ParcelSize size) { - PluginConfiguration.GuiSettings settings = this.config.guiSettings; + PluginConfig.GuiSettings settings = this.config.guiSettings; this.state.setSize(size); ConfigItem smallButton = size == ParcelSize.SMALL ? settings.selectedSmallParcelSizeItem : settings.smallParcelSizeItem; @@ -327,7 +327,7 @@ private void setSelected(Gui gui, ParcelSize size) { } private void setSelected(Gui gui, boolean priority) { - PluginConfiguration.GuiSettings settings = this.config.guiSettings; + PluginConfig.GuiSettings settings = this.config.guiSettings; this.state.setPriority(priority); ConfigItem priorityButton = priority ? settings.selectedPriorityItem : settings.priorityItem; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java index eec9471c8..27372ad5e 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java @@ -2,9 +2,14 @@ import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.ParcelStatus; - import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; +@Getter +@Setter +@Accessors(fluent = true) public class ParcelSendingGuiState { private String parcelName; @@ -27,67 +32,4 @@ public ParcelSendingGuiState() { this.status = ParcelStatus.PENDING; } - public String getParcelName() { - return this.parcelName; - } - - public void setParcelName(String parcelName) { - this.parcelName = parcelName; - } - - public String getParcelDescription() { - return this.parcelDescription; - } - - public void setParcelDescription(String parcelDescription) { - this.parcelDescription = parcelDescription; - } - - public ParcelSize getSize() { - return this.size; - } - - public void setSize(ParcelSize size) { - this.size = size; - } - - public UUID getReceiver() { - return this.receiver; - } - - public void setReceiver(UUID receiver) { - this.receiver = receiver; - } - - public boolean isPriority() { - return this.priority; - } - - public void setPriority(boolean priority) { - this.priority = priority; - } - - public UUID getDestinationLocker() { - return this.destinationLocker; - } - - public void setDestinationLocker(UUID destinationLocker) { - this.destinationLocker = destinationLocker; - } - - public UUID getEntryLocker() { - return this.entryLocker; - } - - public void setEntryLocker(UUID entryLocker) { - this.entryLocker = entryLocker; - } - - public ParcelStatus getStatus() { - return this.status; - } - - public void setStatus(ParcelStatus status) { - this.status = status; - } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java index 8b22239e7..a3a74762c 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java @@ -1,10 +1,9 @@ package com.eternalcode.parcellockers.gui.implementation.locker; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import com.eternalcode.parcellockers.user.User; import com.eternalcode.parcellockers.user.repository.UserPageResult; import com.eternalcode.parcellockers.user.repository.UserRepository; @@ -33,7 +32,7 @@ public class ReceiverSelectionGui implements GuiView { private final Plugin plugin; private final BukkitScheduler scheduler; - private final PluginConfiguration config; + private final PluginConfig config; private final MiniMessage miniMessage; private final UserRepository userRepository; private final ParcelSendingGui sendingGUI; @@ -44,7 +43,7 @@ public class ReceiverSelectionGui implements GuiView { public ReceiverSelectionGui( Plugin plugin, BukkitScheduler scheduler, - PluginConfiguration config, + PluginConfig config, MiniMessage miniMessage, UserRepository userRepository, ParcelSendingGui sendingGUI, @@ -105,8 +104,8 @@ private void show(Player player, Page page) { } this.scheduler.runTask(this.plugin, () -> gui.open(player)); - }).whenComplete(SentryExceptionHandler.handler()); - }).whenComplete(SentryExceptionHandler.handler()); + }); + }); } private CompletableFuture>> loadSkulls(Player player, UserPageResult result, PaginatedGuiRefresher refresh) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index 81b03aa9b..36d6cdef8 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -2,7 +2,7 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; @@ -19,7 +19,7 @@ public class MainGui implements GuiView { private final Plugin plugin; private final Server server; private final MiniMessage miniMessage; - private final PluginConfiguration config; + private final PluginConfig config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; private final UserManager userManager; @@ -28,7 +28,7 @@ public MainGui( Plugin plugin, Server server, MiniMessage miniMessage, - PluginConfiguration config, + PluginConfig config, ParcelRepository parcelRepository, LockerRepository lockerRepository, UserManager userManager @@ -44,7 +44,7 @@ public MainGui( @Override public void show(Player player) { - PluginConfiguration.GuiSettings guiSettings = this.config.guiSettings; + PluginConfig.GuiSettings guiSettings = this.config.guiSettings; Gui gui = Gui.gui() .title(resetItalic(this.miniMessage.deserialize(guiSettings.mainGuiTitle))) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 002f48148..8ea5457c9 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -2,15 +2,14 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; -import com.eternalcode.parcellockers.configuration.implementation.ConfigItem; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; @@ -29,7 +28,7 @@ public class ParcelListGui implements GuiView { private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); private final Plugin plugin; private final MiniMessage miniMessage; - private final PluginConfiguration config; + private final PluginConfig config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; private final UserManager userManager; @@ -38,7 +37,7 @@ public class ParcelListGui implements GuiView { public ParcelListGui( Plugin plugin, MiniMessage miniMessage, - PluginConfiguration config, + PluginConfig config, ParcelRepository parcelRepository, LockerRepository lockerRepository, UserManager userManager, @@ -109,7 +108,7 @@ private void show(Player player, Page page) { } this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); - }).whenComplete(SentryExceptionHandler.handler()); + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index efbfd0c92..0b1d89682 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -1,13 +1,12 @@ package com.eternalcode.parcellockers.gui.implementation.remote; -import com.eternalcode.parcellockers.configuration.implementation.ConfigItem; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; @@ -24,7 +23,7 @@ public class SentParcelsGui implements GuiView { private final Plugin plugin; private final MiniMessage miniMessage; - private final PluginConfiguration config; + private final PluginConfig config; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; private final MainGui mainGUI; @@ -33,7 +32,7 @@ public class SentParcelsGui implements GuiView { public SentParcelsGui( Plugin plugin, MiniMessage miniMessage, - PluginConfiguration config, + PluginConfig config, ParcelRepository parcelRepository, LockerRepository lockerRepository, MainGui mainGUI, @@ -88,6 +87,6 @@ public void show(Player player) { gui.addItem(item.asGuiItem()); } this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); - }).whenComplete(SentryExceptionHandler.handler()); + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java index a0e693ef5..ddbe86191 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java @@ -5,7 +5,6 @@ import com.eternalcode.parcellockers.database.wrapper.AbstractRepositoryOrmLite; import com.eternalcode.parcellockers.itemstorage.ItemStorage; import com.j256.ormlite.table.TableUtils; -import io.sentry.Sentry; import java.sql.SQLException; import java.util.Optional; import java.util.UUID; @@ -19,7 +18,6 @@ public ItemStorageRepositoryOrmLite(DatabaseManager databaseManager, Scheduler s try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), ItemStorageTable.class); } catch (SQLException ex) { - Sentry.captureException(ex); ex.printStackTrace(); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java index c007b36da..84271f020 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.locker.controller; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; @@ -26,13 +26,13 @@ public class LockerBreakController implements Listener { private final LockerRepository lockerRepository; private final LockerCache cache; private final NotificationAnnouncer announcer; - private final PluginConfiguration.Messages messages; + private final PluginConfig.Messages messages; public LockerBreakController( LockerRepository lockerRepository, LockerCache cache, NotificationAnnouncer announcer, - PluginConfiguration.Messages messages + PluginConfig.Messages messages ) { this.lockerRepository = lockerRepository; this.cache = cache; diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java index 6e2fcd4e3..72b30259f 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java @@ -1,11 +1,15 @@ package com.eternalcode.parcellockers.locker.controller; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.conversation.ParcelLockerPlacePrompt; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.shared.PositionAdapter; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.UUID; import org.bukkit.Location; import org.bukkit.conversations.ConversationFactory; import org.bukkit.conversations.NullConversationPrefix; @@ -18,21 +22,16 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.Plugin; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.UUID; - public class LockerPlaceController implements Listener { - private final PluginConfiguration config; + private final PluginConfig config; private final Plugin plugin; private final LockerRepository databaseService; private final NotificationAnnouncer announcer; private final Map lockerCreators = new HashMap<>(); public LockerPlaceController( - PluginConfiguration config, + PluginConfig config, Plugin plugin, LockerRepository databaseService, NotificationAnnouncer announcer diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index 48c365ae5..87cc9df60 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -5,9 +5,9 @@ import com.eternalcode.parcellockers.database.wrapper.AbstractRepositoryOrmLite; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.ParcelLockersException; import com.eternalcode.parcellockers.shared.Position; import com.j256.ormlite.table.TableUtils; -import io.sentry.Sentry; import java.sql.SQLException; import java.util.HashMap; import java.util.List; @@ -28,9 +28,8 @@ public LockerRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), LockerTable.class); } catch (SQLException ex) { - Sentry.captureException(ex); ex.printStackTrace(); - throw new RuntimeException("Failed to initialize locker table", ex); + throw new ParcelLockersException("Failed to initialize locker table", ex); } } diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java b/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java new file mode 100644 index 000000000..b84bfd2a3 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java @@ -0,0 +1,47 @@ +package com.eternalcode.parcellockers.notification; + +import com.eternalcode.multification.adventure.AudienceConverter; +import com.eternalcode.multification.bukkit.BukkitMultification; +import com.eternalcode.multification.translation.TranslationProvider; +import com.eternalcode.parcellockers.configuration.implementation.MessagesConfig; +import net.kyori.adventure.platform.AudienceProvider; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.ComponentSerializer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class NoticeService extends BukkitMultification { + + private final MessagesConfig messages; + private final MiniMessage miniMessage; + private final AudienceProvider audienceProvider; + + public NoticeService(MessagesConfig messages, MiniMessage miniMessage, AudienceProvider audienceProvider) { + this.messages = messages; + this.miniMessage = miniMessage; + this.audienceProvider = audienceProvider; + } + + @Override + protected @NotNull TranslationProvider translationProvider() { + return locale -> this.messages; + } + + @Override + protected @NotNull AudienceConverter audienceConverter() { + return commandSender -> { + if (commandSender instanceof Player player) { + return this.audienceProvider.player(player.getUniqueId()); + } + + return this.audienceProvider.console(); + }; + } + + @Override + protected @NotNull ComponentSerializer serializer() { + return this.miniMessage; + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java b/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java index 314b53649..796ae317e 100644 --- a/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java +++ b/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java @@ -1,5 +1,7 @@ package com.eternalcode.parcellockers.notification; +import java.util.Map; +import java.util.function.BiConsumer; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.platform.AudienceProvider; import net.kyori.adventure.text.Component; @@ -8,9 +10,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.util.Map; -import java.util.function.BiConsumer; - +@Deprecated public class NotificationAnnouncer { private static final Map> NOTIFICATION_HANDLERS = Map.of( diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java b/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java index bb100784b..9b58e9b0d 100644 --- a/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java +++ b/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.notification; +@Deprecated public enum NotificationType { ACTION_BAR, diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 502b941ab..692bc439e 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -4,7 +4,7 @@ import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.ParcelContent; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.delivery.Delivery; @@ -13,7 +13,6 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.shared.ParcelLockersException; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; import java.time.Duration; import java.time.Instant; import java.util.List; @@ -24,7 +23,7 @@ public class ParcelServiceImpl implements ParcelService { - private final PluginConfiguration config; + private final PluginConfig config; private final NotificationAnnouncer announcer; private final ParcelRepository parcelRepository; private final DeliveryRepository deliveryRepository; @@ -32,7 +31,7 @@ public class ParcelServiceImpl implements ParcelService { private final Scheduler scheduler; public ParcelServiceImpl( - PluginConfiguration config, + PluginConfig config, NotificationAnnouncer announcer, ParcelRepository parcelRepository, DeliveryRepository deliveryRepository, @@ -103,14 +102,14 @@ public void collect(Player player, Parcel parcel) { this.parcelRepository.remove(parcel) .thenCompose(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) - .whenComplete(SentryExceptionHandler.handler().andThen((v, throwable) -> { + .whenComplete((v, throwable) -> { if (throwable != null) { this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); } else { playSuccessSound(player); this.announcer.sendMessage(player, this.config.messages.parcelSuccessfullyCollected); } - })); + }); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java index 0d3ea23d6..1854c2bed 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.parcel.command; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.gui.implementation.remote.MainGui; import com.eternalcode.parcellockers.gui.implementation.remote.ParcelListGui; import com.eternalcode.parcellockers.locker.repository.LockerRepository; @@ -25,7 +25,7 @@ public class ParcelCommand { private final LockerRepository lockerRepository; private final NotificationAnnouncer announcer; - private final PluginConfiguration config; + private final PluginConfig config; private final MainGui mainGUI; private final ParcelListGui parcelListGUI; private final ParcelService parcelService; @@ -34,7 +34,7 @@ public class ParcelCommand { public ParcelCommand( LockerRepository lockerRepository, NotificationAnnouncer announcer, - PluginConfiguration config, + PluginConfig config, MainGui mainGUI, ParcelListGui parcelListGUI, ParcelService parcelService, diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java index 70f2800b5..c48312f73 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java @@ -6,7 +6,6 @@ import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.shared.Page; import com.j256.ormlite.table.TableUtils; -import io.sentry.Sentry; import java.sql.SQLException; import java.util.List; import java.util.Map; @@ -30,7 +29,6 @@ public ParcelRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), ParcelTable.class); } catch (SQLException ex) { - Sentry.captureException(ex); throw new RuntimeException("Failed to initialize parcel table", ex); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java index 86816684d..17959aa7f 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.parcel.task; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.delivery.Delivery; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; import com.eternalcode.parcellockers.parcel.Parcel; @@ -14,14 +14,14 @@ public class ParcelSendTask extends BukkitRunnable { private final Delivery delivery; private final ParcelRepository parcelRepository; private final DeliveryRepository deliveryRepository; - private final PluginConfiguration config; + private final PluginConfig config; public ParcelSendTask( Parcel parcel, Delivery delivery, ParcelRepository parcelRepository, DeliveryRepository deliveryRepository, - PluginConfiguration config + PluginConfig config ) { this.parcel = parcel; this.delivery = delivery; diff --git a/src/main/java/com/eternalcode/parcellockers/shared/SentryExceptionHandler.java b/src/main/java/com/eternalcode/parcellockers/shared/SentryExceptionHandler.java deleted file mode 100644 index 14df200c2..000000000 --- a/src/main/java/com/eternalcode/parcellockers/shared/SentryExceptionHandler.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.eternalcode.parcellockers.shared; - -import io.sentry.Sentry; - -import java.util.function.BiConsumer; - -public class SentryExceptionHandler implements BiConsumer { - - private static final SentryExceptionHandler INSTANCE = new SentryExceptionHandler<>(); - - private SentryExceptionHandler() { - } - - @SuppressWarnings("unchecked") - public static SentryExceptionHandler handler() { - return (SentryExceptionHandler) INSTANCE; - } - - @Override - public void accept(T result, Throwable throwable) { - if (throwable != null) { - throwable.printStackTrace(); - Sentry.captureException(throwable); - } - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java index c94a7193b..92f9fadee 100644 --- a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java +++ b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java @@ -1,7 +1,8 @@ package com.eternalcode.parcellockers.updater; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; -import com.eternalcode.parcellockers.shared.SentryExceptionHandler; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.platform.AudienceProvider; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -10,20 +11,18 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import java.util.concurrent.CompletableFuture; - public class UpdaterNotificationController implements Listener { private static final String NEW_VERSION_AVAILABLE = "ParcelLockers: New version of ParcelLockers is available, please update!"; private final UpdaterService updaterService; - private final PluginConfiguration pluginConfig; + private final PluginConfig pluginConfig; private final AudienceProvider audienceProvider; private final MiniMessage miniMessage; public UpdaterNotificationController( UpdaterService updaterService, - PluginConfiguration pluginConfig, + PluginConfig pluginConfig, AudienceProvider audienceProvider, MiniMessage miniMessage ) { @@ -48,6 +47,6 @@ void onJoin(PlayerJoinEvent event) { if (!isUpToDate) { audience.sendMessage(this.miniMessage.deserialize(NEW_VERSION_AVAILABLE)); } - }).whenComplete(SentryExceptionHandler.handler()); + }).orTimeout(5, TimeUnit.SECONDS); } } diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index bde3f892c..c2da22206 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -6,7 +6,6 @@ import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.user.User; import com.j256.ormlite.table.TableUtils; -import io.sentry.Sentry; import java.sql.SQLException; import java.util.List; import java.util.Optional; @@ -22,7 +21,6 @@ public UserRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedule try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), UserTable.class); } catch (SQLException exception) { - Sentry.captureException(exception); exception.printStackTrace(); } } diff --git a/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java b/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java index 0d436abba..ef1eb5f29 100644 --- a/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import de.eldoria.jacksonbukkit.JacksonPaper; -import io.sentry.Sentry; import java.util.List; import org.bukkit.inventory.ItemStack; @@ -26,7 +25,6 @@ public static String serialize(ItemStack stack) { try { return JSON.writeValueAsString(stack); } catch (JsonProcessingException e) { - Sentry.captureException(e); throw new ParcelLockersException("Failed to serialize itemstack", e); } } @@ -35,7 +33,6 @@ public static String serializeItems(List stack) { try { return JSON.writeValueAsString(stack); } catch (JsonProcessingException e) { - Sentry.captureException(e); throw new ParcelLockersException("Failed to serialize itemstack", e); } } @@ -44,7 +41,6 @@ public static ItemStack deserialize(String string) { try { return JSON.readValue(string, ItemStack.class); } catch (JsonProcessingException e) { - Sentry.captureException(e); throw new ParcelLockersException("Failed to deserialize itemstack", e); } } @@ -53,7 +49,6 @@ public static List deserializeItems(String string) { try { return JSON.readValue(string, JSON.getTypeFactory().constructCollectionType(List.class, ItemStack.class)); } catch (JsonProcessingException exception) { - Sentry.captureException(exception); throw new ParcelLockersException("Failed to deserialize itemstack", exception); } } diff --git a/src/test/java/com/eternalcode/parcellockers/configuration/composer/DurationComposerTest.java b/src/test/java/com/eternalcode/parcellockers/configuration/composer/DurationComposerTest.java deleted file mode 100644 index 6e16bb429..000000000 --- a/src/test/java/com/eternalcode/parcellockers/configuration/composer/DurationComposerTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.eternalcode.parcellockers.configuration.composer; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import panda.std.Result; - -import java.time.Duration; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class DurationComposerTest { - - private final DurationComposer composer = new DurationComposer(); - - @Test - @DisplayName("Serialize valid ISO-8601 duration") - void testSerializeValidDuration() { - Duration duration = Duration.ofDays(1).plusHours(2).plusMinutes(30).plusSeconds(15); - Result result = composer.serialize(duration); - - assertTrue(result.isOk()); - assertEquals("1d 2h 30m 15s", result.get()); - } - - @Test - @DisplayName("Serialize invalid (null) duration") - void testSerializeNullDuration() { - Result result = composer.serialize(null); - - assertTrue(result.isErr()); - assertEquals("Duration cannot be null", result.getError().getMessage()); - } - - @Test - @DisplayName("Deserialize valid ISO-8601 format") - void testDeserializeValidIso8601Format() { - String input = "PT1H30M"; - Result result = composer.deserialize(input); - - assertTrue(result.isOk()); - assertEquals(Duration.ofHours(1).plusMinutes(30), result.get()); - } - - @Test - @DisplayName("Deserialize valid custom format") - void testDeserializeValidCustomFormat() { - String input = "1d 2h 30m 15s"; - Result result = composer.deserialize(input); - - assertTrue(result.isOk()); - assertEquals(Duration.ofDays(1).plusHours(2).plusMinutes(30).plusSeconds(15), result.get()); - } - - @Test - @DisplayName("Deserialize valid simple number format") - void testDeserializeSimpleNumber() { - String input = "3600"; - Result result = composer.deserialize(input); - - assertTrue(result.isOk()); - assertEquals(Duration.ofSeconds(3600), result.get()); - } - - @Test - @DisplayName("Deserialize invalid format") - void testDeserializeInvalidFormat() { - String input = "invalid format"; - Result result = composer.deserialize(input); - - assertTrue(result.isErr()); - assertEquals("Invalid duration format. Expected format like '1d 2h 3m 4s' or ISO-8601 duration.", result.getError().getMessage()); - } - - @Test - @DisplayName("Deserialize empty input") - void testDeserializeNullInput() { - Result result = composer.deserialize(null); - - assertTrue(result.isErr()); - assertEquals("Input cannot be null or blank", result.getError().getMessage()); - } - - @Test - @DisplayName("Deserialize blank input") - void testDeserializeBlankInput() { - Result result = composer.deserialize(" "); - - assertTrue(result.isErr()); - assertEquals("Input cannot be null or blank", result.getError().getMessage()); - } -} diff --git a/src/test/java/com/eternalcode/parcellockers/configuration/composer/PositionComposerTest.java b/src/test/java/com/eternalcode/parcellockers/configuration/composer/PositionComposerTest.java deleted file mode 100644 index 6f900d2e2..000000000 --- a/src/test/java/com/eternalcode/parcellockers/configuration/composer/PositionComposerTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.eternalcode.parcellockers.configuration.composer; - -import com.eternalcode.parcellockers.shared.Position; -import org.junit.jupiter.api.Test; -import panda.std.AttemptFailedException; -import panda.std.Result; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class PositionComposerTest { - - private final PositionComposer positionComposer = new PositionComposer(); - - @Test - void testSerialize() { - // Given - Position position = new Position(10, 20, 30, "world"); - String expected = "Position{x=10, y=20, z=30, world='world'}"; - - // When - Result result = this.positionComposer.serialize(position); - - // Then - assertTrue(result.isOk()); - assertEquals(expected, result.get()); - } - - @Test - void testDeserialize() { - // Given - String positionString = "Position{x=-50, y=64, z=120, world='world_nether'}"; - Position expected = new Position(-50, 64, 120, "world_nether"); - - // When - Result result = this.positionComposer.deserialize(positionString); - - // Then - assertTrue(result.isOk()); - assertEquals(expected, result.get()); - } - - @Test - void testDeserializeInvalidFormat() { - // Given - String invalidString = "world,-50,64,120"; - - // When - Result result = this.positionComposer.deserialize(invalidString); - - // Then - assertTrue(result.isErr()); - assertInstanceOf(IllegalArgumentException.class, result.getError()); - } - - @Test - void testSerializeNull() { - // When & Then - assertThrows(NullPointerException.class, () -> this.positionComposer.serialize(null)); - } - - @Test - void testDeserializeNull() { - // When & Then - assertThrows(AttemptFailedException.class, () -> this.positionComposer.deserialize(null)); - } -} diff --git a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java index 68e6ecdb1..63ccd4385 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java @@ -4,8 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.eternalcode.parcellockers.TestScheduler; -import com.eternalcode.parcellockers.configuration.ConfigurationManager; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.ConfigService; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.locker.repository.LockerPageResult; @@ -40,7 +40,7 @@ class LockerRepositoryIntegrationTest extends IntegrationTestSpec { @Test void test() { File dataFolder = tempDir.resolve("ParcelLockers").toFile(); - PluginConfiguration config = new ConfigurationManager(dataFolder).load(new PluginConfiguration()); + PluginConfig config = new ConfigService(dataFolder).load(new PluginConfig()); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; LockerCache cache = new LockerCache(); diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index b5b467ecf..0225ee61d 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -4,8 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.eternalcode.parcellockers.TestScheduler; -import com.eternalcode.parcellockers.configuration.ConfigurationManager; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfiguration; +import com.eternalcode.parcellockers.configuration.ConfigService; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.ParcelStatus; @@ -43,7 +43,7 @@ class ParcelRepositoryIntegrationTest extends IntegrationTestSpec { @Test void test() { File dataFolder = tempDir.resolve("ParcelLockers").toFile(); - PluginConfiguration config = new ConfigurationManager(dataFolder).load(new PluginConfiguration()); + PluginConfig config = new ConfigService(dataFolder).load(new PluginConfig()); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; ParcelCache cache = new ParcelCache(); From 837a0472a7e13fc6d346815fb014f3c5f09142d7 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 15:38:33 +0200 Subject: [PATCH 07/51] Remove debug mode --- .../com/eternalcode/parcellockers/ParcelLockers.java | 4 ++-- .../database/wrapper/AbstractRepositoryOrmLite.java | 12 +----------- ...ParcelLockerArgument.java => LockerArgument.java} | 4 ++-- 3 files changed, 5 insertions(+), 15 deletions(-) rename src/main/java/com/eternalcode/parcellockers/locker/argument/{ParcelLockerArgument.java => LockerArgument.java} (91%) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 65c241f5c..ae273edd3 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -20,7 +20,7 @@ import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepositoryOrmLite; import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.argument.ParcelLockerArgument; +import com.eternalcode.parcellockers.locker.argument.LockerArgument; import com.eternalcode.parcellockers.locker.controller.LockerBreakController; import com.eternalcode.parcellockers.locker.controller.LockerInteractionController; import com.eternalcode.parcellockers.locker.controller.LockerPlaceController; @@ -138,7 +138,7 @@ public void onEnable() { this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .argument(Parcel.class, new ParcelArgument(parcelCache)) - .argument(Locker.class, new ParcelLockerArgument(lockerCache)) + .argument(Locker.class, new LockerArgument(lockerCache)) .extension(new LiteAdventureExtension<>()) .message(LiteBukkitMessages.PLAYER_ONLY, config.messages.onlyForPlayers) .message(LiteBukkitMessages.PLAYER_NOT_FOUND, config.messages.cantFindPlayer) diff --git a/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java index dc6a49ad6..9d99bed4a 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java @@ -1,15 +1,13 @@ package com.eternalcode.parcellockers.database.wrapper; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.ParcelLockers; import com.eternalcode.parcellockers.database.DatabaseManager; import com.j256.ormlite.dao.Dao; -import panda.std.function.ThrowingFunction; - import java.sql.SQLException; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import panda.std.function.ThrowingFunction; public abstract class AbstractRepositoryOrmLite { @@ -23,55 +21,47 @@ protected AbstractRepositoryOrmLite(DatabaseManager databaseManager, Scheduler s protected CompletableFuture save(Class type, T entity) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Saving entity: {}", entity); return dao.createOrUpdate(entity); }); } protected CompletableFuture saveIfNotExist(Class type, T entity) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Saving entity (IF NOT EXIST mode): {}", entity); return dao.createIfNotExists(entity); }); } protected CompletableFuture select(Class type, ID id) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Selecting: {}", id); return dao.queryForId(id); }); } protected CompletableFuture> selectSafe(Class type, ID id) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Selecting (safe mode): {}", id); return Optional.ofNullable(dao.queryForId(id)); }); } protected CompletableFuture delete(Class type, T entity) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Deleting: {}", entity); return dao.delete(entity); }); } protected CompletableFuture deleteAll(Class type) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Deleting all entities of type: {}", type.getSimpleName()); return dao.deleteBuilder().delete(); }); } protected CompletableFuture deleteById(Class type, ID id) { return this.action(type, dao -> { - ParcelLockers.DEBUG_LOGGER.info("Deleting: {}", id); return dao.deleteById(id); }); } protected CompletableFuture> selectAll(Class type) { - ParcelLockers.DEBUG_LOGGER.info("Selecting all entities of type: {}", type.getSimpleName()); return this.action(type, Dao::queryForAll); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/argument/ParcelLockerArgument.java b/src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java similarity index 91% rename from src/main/java/com/eternalcode/parcellockers/locker/argument/ParcelLockerArgument.java rename to src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java index 13a0281e5..31d5694ec 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/argument/ParcelLockerArgument.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java @@ -10,11 +10,11 @@ import dev.rollczi.litecommands.suggestion.SuggestionResult; import org.bukkit.command.CommandSender; -public class ParcelLockerArgument extends ArgumentResolver { +public class LockerArgument extends ArgumentResolver { private final LockerCache cache; - public ParcelLockerArgument(LockerCache cache) { + public LockerArgument(LockerCache cache) { this.cache = cache; } From 8d2d6cf140aba10fb3567217f8b70241f4ae5450 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 17:42:54 +0200 Subject: [PATCH 08/51] Finish general refactor --- .../parcellockers/ParcelLockers.java | 39 ++--- .../parcellockers/ParcelLockersCommand.java | 13 +- .../command/debug/DebugCommand.java | 92 +++++++---- .../handler/InvalidUsageHandlerImpl.java | 32 ++++ .../command/handler/InvalidUsageImpl.java | 43 ----- .../MissingPermissionsHandlerImpl.java | 28 ++++ .../command/handler/PermissionMessage.java | 31 ---- .../implementation/MessageConfig.java | 48 ++++++ .../implementation/MessagesConfig.java | 6 - .../implementation/PluginConfig.java | 47 ------ .../conversation/ParcelLockerPlacePrompt.java | 10 +- .../wrapper/AbstractRepositoryOrmLite.java | 28 +--- .../locker/DestinationSelectionGui.java | 18 +-- .../implementation/locker/LockerMainGui.java | 26 +-- .../locker/ParcelCollectionGui.java | 12 +- .../locker/ParcelItemStorageGui.java | 31 ++-- .../locker/ParcelSendingGui.java | 148 ++++++++++-------- .../locker/ReceiverSelectionGui.java | 22 ++- .../gui/implementation/remote/MainGui.java | 16 +- .../implementation/remote/ParcelListGui.java | 14 +- .../implementation/remote/SentParcelsGui.java | 14 +- .../controller/LockerBreakController.java | 31 ++-- .../controller/LockerPlaceController.java | 64 +++++--- .../notification/NoticeService.java | 10 +- .../parcel/ParcelServiceImpl.java | 81 +++++----- .../parcel/command/ParcelCommand.java | 36 +---- 26 files changed, 473 insertions(+), 467 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageHandlerImpl.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java create mode 100644 src/main/java/com/eternalcode/parcellockers/command/handler/MissingPermissionsHandlerImpl.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java create mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index ae273edd3..129ebc92b 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -5,10 +5,10 @@ import com.eternalcode.commons.bukkit.scheduler.BukkitSchedulerImpl; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.command.debug.DebugCommand; -import com.eternalcode.parcellockers.command.handler.InvalidUsageImpl; -import com.eternalcode.parcellockers.command.handler.PermissionMessage; +import com.eternalcode.parcellockers.command.handler.InvalidUsageHandlerImpl; +import com.eternalcode.parcellockers.command.handler.MissingPermissionsHandlerImpl; import com.eternalcode.parcellockers.configuration.ConfigService; -import com.eternalcode.parcellockers.configuration.implementation.MessagesConfig; +import com.eternalcode.parcellockers.configuration.implementation.MessageConfig; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.content.repository.ParcelContentRepositoryOrmLite; @@ -91,9 +91,10 @@ public void onEnable() { ConfigService configManager = new ConfigService(); PluginConfig config = configManager.create(PluginConfig.class, new File(this.getDataFolder(), "config.yml")); - MessagesConfig messagesConfig = configManager.create(MessagesConfig.class, new File(this.getDataFolder(), "messages.yml")); + MessageConfig + messageConfig = configManager.create(MessageConfig.class, new File(this.getDataFolder(), "messages.yml")); Server server = this.getServer(); - NoticeService noticeService = new NoticeService(messagesConfig, miniMessage, this.audiences); + NoticeService noticeService = new NoticeService(messageConfig, miniMessage, this.audiences); Scheduler scheduler = new BukkitSchedulerImpl(this); DatabaseManager databaseManager = new DatabaseManager(config, this.getLogger(), this.getDataFolder()); @@ -124,41 +125,41 @@ public void onEnable() { DeliveryRepositoryOrmLite deliveryRepository = new DeliveryRepositoryOrmLite(databaseManager, scheduler); ParcelContentRepository parcelContentRepository = new ParcelContentRepositoryOrmLite(databaseManager, scheduler); - ParcelService parcelService = new ParcelServiceImpl(config, announcer, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); + ParcelService parcelService = new ParcelServiceImpl(config, + noticeService, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); ItemStorageRepository itemStorageRepository = new ItemStorageRepositoryOrmLite(databaseManager, scheduler); UserRepository userRepository = new UserRepositoryOrmLite(databaseManager, scheduler); UserManager userManager = new UserManagerImpl(userRepository); - MainGui mainGUI = new MainGui(this, server, miniMessage, config, parcelRepository, lockerRepository, + MainGui mainGUI = new MainGui(scheduler, miniMessage, config, parcelRepository, lockerRepository, userManager); - ParcelListGui parcelListGUI = new ParcelListGui(this, miniMessage, config, parcelRepository, lockerRepository, + ParcelListGui parcelListGUI = new ParcelListGui(scheduler, miniMessage, config, parcelRepository, lockerRepository, userManager, mainGUI); this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .argument(Parcel.class, new ParcelArgument(parcelCache)) .argument(Locker.class, new LockerArgument(lockerCache)) .extension(new LiteAdventureExtension<>()) - .message(LiteBukkitMessages.PLAYER_ONLY, config.messages.onlyForPlayers) - .message(LiteBukkitMessages.PLAYER_NOT_FOUND, config.messages.cantFindPlayer) + .message(LiteBukkitMessages.PLAYER_ONLY, messageConfig.playerOnlyCommand) + .message(LiteBukkitMessages.PLAYER_NOT_FOUND, messageConfig.playerNotFound) .commands(LiteCommandsAnnotations.of( - new ParcelCommand(lockerRepository, announcer, config, mainGUI, parcelListGUI, - parcelService, userManager), - new ParcelLockersCommand(configManager, config, announcer), - new DebugCommand(parcelRepository, lockerRepository, itemStorageRepository, parcelContentRepository, announcer) + new ParcelCommand(mainGUI, parcelListGUI, parcelService), + new ParcelLockersCommand(configManager, config, noticeService), + new DebugCommand(parcelRepository, lockerRepository, itemStorageRepository, parcelContentRepository, noticeService) )) - .invalidUsage(new InvalidUsageImpl(announcer, config)) - .missingPermission(new PermissionMessage(announcer, config)) + .invalidUsage(new InvalidUsageHandlerImpl(noticeService)) + .missingPermission(new MissingPermissionsHandlerImpl(noticeService)) .build(); - LockerMainGui lockerMainGUI = new LockerMainGui(this, miniMessage, config, itemStorageRepository, parcelRepository, lockerRepository, announcer, parcelContentRepository, userRepository, this.skullAPI, + LockerMainGui lockerMainGUI = new LockerMainGui(miniMessage, scheduler, config, itemStorageRepository, parcelRepository, lockerRepository, noticeService, parcelContentRepository, userRepository, this.skullAPI, parcelService); Stream.of( new LockerInteractionController(lockerCache, lockerMainGUI), - new LockerPlaceController(config, this, lockerRepository, announcer), - new LockerBreakController(lockerRepository, lockerCache, announcer, config.messages), + new LockerPlaceController(config, this, lockerRepository, noticeService), + new LockerBreakController(lockerRepository, lockerCache, noticeService), new PrepareUserController(userManager), new LoadUserController(userManager, server) ).forEach(controller -> server.getPluginManager().registerEvents(controller, this)); diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java index 4ce303fd8..5087b7f02 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java @@ -2,7 +2,7 @@ import com.eternalcode.parcellockers.configuration.ConfigService; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import dev.rollczi.litecommands.annotations.command.Command; import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; @@ -17,18 +17,21 @@ public class ParcelLockersCommand { private final ConfigService configManager; private final PluginConfig config; - private final NotificationAnnouncer announcer; + private final NoticeService noticeService; - public ParcelLockersCommand(ConfigService configManager, PluginConfig config, NotificationAnnouncer announcer) { + public ParcelLockersCommand(ConfigService configManager, PluginConfig config, NoticeService noticeService) { this.configManager = configManager; this.config = config; - this.announcer = announcer; + this.noticeService = noticeService; } @Execute(name = "reload") void reload(@Sender CommandSender sender) { this.configManager.reload(); - this.announcer.sendMessage(sender, this.config.messages.reload); + this.noticeService.create() + .viewer(sender) + .notice(messages -> messages.reload) + .send(); } @Execute(name = "give") diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index fb1f3a1e7..edb1e1a55 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -1,13 +1,14 @@ package com.eternalcode.parcellockers.command.debug; +import com.eternalcode.multification.notice.Notice; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import dev.rollczi.litecommands.annotations.argument.Arg; import dev.rollczi.litecommands.annotations.command.Command; -import dev.rollczi.litecommands.annotations.context.Context; +import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; import java.util.Arrays; @@ -19,6 +20,8 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +// TODO move notices to MessagesConfig + @Command(name = "parcel debug") @Permission("parcellockers.debug") public class DebugCommand { @@ -27,56 +30,82 @@ public class DebugCommand { private final LockerRepository lockerRepository; private final ItemStorageRepository itemStorageRepository; private final ParcelContentRepository contentRepository; - private final NotificationAnnouncer announcer; + private final NoticeService noticeService; public DebugCommand( - ParcelRepository parcelRepository, - LockerRepository lockerRepository, - ItemStorageRepository itemStorageRepository, - ParcelContentRepository contentRepository, - NotificationAnnouncer announcer + ParcelRepository parcelRepository, + LockerRepository lockerRepository, + ItemStorageRepository itemStorageRepository, + ParcelContentRepository contentRepository, + NoticeService noticeService ) { this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; this.itemStorageRepository = itemStorageRepository; this.contentRepository = contentRepository; - this.announcer = announcer; + this.noticeService = noticeService; } @Execute(name = "delete parcels") - void deleteParcels(@Context CommandSender sender) { + void deleteParcels(@Sender CommandSender sender) { this.parcelRepository.removeAll().exceptionally(throwable -> { - this.announcer.sendMessage(sender, "&4Failed to delete parcels"); + this.noticeService.create() + .notice(Notice.chat("&4Failed to delete parcels")) + .viewer(sender) + .send(); return null; - }).thenRun(() -> this.announcer.sendMessage(sender, "&cParcels deleted")); + }).thenRun(() -> this.noticeService.create() + .notice(Notice.chat("&cParcels deleted")) + .viewer(sender) + .send()); } @Execute(name = "delete lockers") - void deleteLockers(@Context CommandSender sender) { + void deleteLockers(@Sender CommandSender sender) { this.lockerRepository.deleteAll().exceptionally(throwable -> { - this.announcer.sendMessage(sender, "&4Failed to delete lockers"); + this.noticeService.create() + .notice(Notice.chat("&4Failed to delete lockers")) + .viewer(sender) + .send(); return null; - }).thenRun(() -> this.announcer.sendMessage(sender, "&cLockers deleted")); + }).thenRun(() -> this.noticeService.create() + .notice(Notice.chat("&cLockers deleted")) + .viewer(sender) + .send()); } @Execute(name = "delete itemstorages") - void deleteItemStorages(@Context CommandSender sender) { - this.itemStorageRepository.deleteAll().exceptionally(throwable -> { - this.announcer.sendMessage(sender, "&4Failed to delete item storages"); - return null; - }).thenRun(() -> this.announcer.sendMessage(sender, "&cItem storages deleted")); + void deleteItemStorages(@Sender CommandSender sender) { + this.itemStorageRepository.deleteAll() + .exceptionally(throwable -> { + this.noticeService.create() + .notice(Notice.chat("&4Failed to delete item storages")) + .viewer(sender) + .send(); + return null; + }) + .thenRun(() -> this.noticeService.create() + .notice(Notice.chat("&cItem storages deleted")) + .viewer(sender) + .send()); } @Execute(name = "delete parcelcontents") - void deleteParcelContents(@Context CommandSender sender) { + void deleteParcelContents(@Sender CommandSender sender) { this.contentRepository.deleteAll().exceptionally(throwable -> { - this.announcer.sendMessage(sender, "&4Failed to delete parcel contents"); + this.noticeService.create() + .notice(Notice.chat("&4Failed to delete parcel contents")) + .viewer(sender) + .send(); return null; - }).thenRun(() -> this.announcer.sendMessage(sender, "&cParcel contents deleted")); + }).thenRun(() -> this.noticeService.create() + .notice(Notice.chat("&cParcel contents deleted")) + .viewer(sender) + .send()); } @Execute(name = "delete all") - void deleteAll(@Context CommandSender sender) { + void deleteAll(@Sender CommandSender sender) { this.deleteItemStorages(sender); this.deleteLockers(sender); this.deleteParcels(sender); @@ -84,22 +113,28 @@ void deleteAll(@Context CommandSender sender) { } @Execute(name = "getrandomitem") - void getRandomItem(@Context Player player, @Arg int stacks) { + void getRandomItem(@Sender Player player, @Arg int stacks) { if (stacks <= 0 || stacks > 36) { - this.announcer.sendMessage(player, "&cPlease request between 1 and 36 stacks"); + this.noticeService.create() + .notice(Notice.chat("&cInvalid number of stacks. Must be between 1 and 36.")) + .player(player.getUniqueId()) + .send(); return; } List itemMaterials = Arrays.stream(Material.values()).filter(Material::isItem).toList(); if (itemMaterials.isEmpty()) { - this.announcer.sendMessage(player, "&cNo valid items found."); + this.noticeService.create() + .notice(Notice.chat("&cNo valid item materials found.")) + .player(player.getUniqueId()) + .send(); return; } - // Faster solution than Random#nextInt Random random = ThreadLocalRandom.current(); + // give player random items for (int i = 0; i < stacks; i++) { Material randomMaterial = itemMaterials.get(random.nextInt(itemMaterials.size())); int randomAmount = Math.min(random.nextInt(64) + 1, randomMaterial.getMaxStackSize()); @@ -108,5 +143,4 @@ void getRandomItem(@Context Player player, @Arg int stacks) { player.getInventory().addItem(itemStack); } } - } diff --git a/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageHandlerImpl.java b/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageHandlerImpl.java new file mode 100644 index 000000000..be7af2335 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageHandlerImpl.java @@ -0,0 +1,32 @@ +package com.eternalcode.parcellockers.command.handler; + +import com.eternalcode.parcellockers.notification.NoticeService; +import dev.rollczi.litecommands.handler.result.ResultHandlerChain; +import dev.rollczi.litecommands.invalidusage.InvalidUsage; +import dev.rollczi.litecommands.invalidusage.InvalidUsageHandler; +import dev.rollczi.litecommands.invocation.Invocation; +import dev.rollczi.litecommands.schematic.Schematic; +import org.bukkit.command.CommandSender; + +public class InvalidUsageHandlerImpl implements InvalidUsageHandler { + + private final NoticeService noticeService; + + public InvalidUsageHandlerImpl(NoticeService noticeService) { + this.noticeService = noticeService; + } + + @Override + public void handle(Invocation invocation, InvalidUsage invalidUsage, ResultHandlerChain chain) { + Schematic schematic = invalidUsage.getSchematic(); + + for (String usage : schematic.all()) { + this.noticeService.create() + .viewer(invocation.sender()) + .notice(messages -> messages.invalidUsage) + .placeholder("{USAGE}", usage) + .send(); + } + } + +} diff --git a/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java b/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java deleted file mode 100644 index 88face257..000000000 --- a/src/main/java/com/eternalcode/parcellockers/command/handler/InvalidUsageImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.eternalcode.parcellockers.command.handler; - -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; -import dev.rollczi.litecommands.handler.result.ResultHandlerChain; -import dev.rollczi.litecommands.invalidusage.InvalidUsage; -import dev.rollczi.litecommands.invalidusage.InvalidUsageHandler; -import dev.rollczi.litecommands.invocation.Invocation; -import dev.rollczi.litecommands.schematic.Schematic; -import java.util.List; -import org.bukkit.command.CommandSender; -import panda.utilities.text.Formatter; - -public class InvalidUsageImpl implements InvalidUsageHandler { - - private final NotificationAnnouncer announcer; - private final PluginConfig config; - - public InvalidUsageImpl(NotificationAnnouncer announcer, PluginConfig config) { - this.announcer = announcer; - this.config = config; - } - - @Override - public void handle(Invocation invocation, InvalidUsage result, ResultHandlerChain chain) { - Schematic schematic = result.getSchematic(); - - if (schematic.isOnlyFirst()) { - this.announcer.sendMessage(invocation.sender(), this.config.messages.parcelCommandUsage); - return; - } - - List schematics = schematic.all(); - - for (String scheme : schematics) { - Formatter formatter = new Formatter() - .register("{USAGE}", scheme); - - this.announcer.sendMessage(invocation.sender(), formatter.format(this.config.messages.invalidUsage)); - } - } - -} diff --git a/src/main/java/com/eternalcode/parcellockers/command/handler/MissingPermissionsHandlerImpl.java b/src/main/java/com/eternalcode/parcellockers/command/handler/MissingPermissionsHandlerImpl.java new file mode 100644 index 000000000..cff33e778 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/command/handler/MissingPermissionsHandlerImpl.java @@ -0,0 +1,28 @@ +package com.eternalcode.parcellockers.command.handler; + +import com.eternalcode.parcellockers.notification.NoticeService; +import dev.rollczi.litecommands.handler.result.ResultHandlerChain; +import dev.rollczi.litecommands.invocation.Invocation; +import dev.rollczi.litecommands.permission.MissingPermissions; +import dev.rollczi.litecommands.permission.MissingPermissionsHandler; +import org.bukkit.command.CommandSender; + +public class MissingPermissionsHandlerImpl implements MissingPermissionsHandler { + + private final NoticeService noticeService; + + public MissingPermissionsHandlerImpl(NoticeService noticeService) { + this.noticeService = noticeService; + } + + @Override + public void handle(Invocation invocation, MissingPermissions missingPermissions, ResultHandlerChain chain) { + String joinedText = missingPermissions.asJoinedText(); + + this.noticeService.create() + .viewer(invocation.sender()) + .notice(messages -> messages.noPermission) + .placeholder("{PERMISSION}", joinedText) + .send(); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java b/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java deleted file mode 100644 index 699f492ba..000000000 --- a/src/main/java/com/eternalcode/parcellockers/command/handler/PermissionMessage.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.eternalcode.parcellockers.command.handler; - -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; -import dev.rollczi.litecommands.handler.result.ResultHandlerChain; -import dev.rollczi.litecommands.invocation.Invocation; -import dev.rollczi.litecommands.permission.MissingPermissions; -import dev.rollczi.litecommands.permission.MissingPermissionsHandler; -import org.bukkit.command.CommandSender; -import panda.utilities.text.Formatter; - -public class PermissionMessage implements MissingPermissionsHandler { - - private final NotificationAnnouncer announcer; - private final PluginConfig config; - - public PermissionMessage(NotificationAnnouncer announcer, PluginConfig config) { - this.announcer = announcer; - this.config = config; - } - - @Override - public void handle(Invocation invocation, MissingPermissions missingPermissions, ResultHandlerChain chain) { - String permissions = missingPermissions.asJoinedText(); - - Formatter formatter = new Formatter() - .register("{PERMISSION}", permissions); - - this.announcer.sendMessage(invocation.sender(), formatter.format(this.config.messages.noPermission)); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java new file mode 100644 index 000000000..bc06f849d --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -0,0 +1,48 @@ +package com.eternalcode.parcellockers.configuration.implementation; + +import com.eternalcode.multification.notice.Notice; +import eu.okaeri.configs.OkaeriConfig; +import eu.okaeri.configs.annotation.Comment; + +public class MessageConfig extends OkaeriConfig { + + public Notice playerOnlyCommand = Notice.chat("&4โœ˜ &cThis command is only available to players!"); + public Notice noPermission = Notice.chat("&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"); + public Notice playerNotFound = Notice.chat("&4โœ˜ &cThe specified player could not be found!"); + public Notice invalidUsage = Notice.chat("&4โฃ &cCorrect usage: &6{USAGE}"); + public Notice reload = Notice.chat("&3โฃ &bConfiguration has been successfully reloaded!"); + public Notice parcelSuccessfullyDeleted = Notice.chat("&2โœ” &aParcel deleted successfully."); + public Notice failedToDeleteParcel = Notice.chat("&4โœ˜ &cAn error occurred while deleting the parcel."); + public Notice failedToCreateParcelLocker = Notice.chat("&4โœ˜ &cCould not create the parcel locker."); + public Notice parcelLockerSuccessfullyCreated = Notice.chat("&7ยป &aParcel locker created successfully."); + public Notice enterDescriptionPrompt = Notice.chat("&6โ†ต &eEnter a description for the parcel locker:"); + public Notice cannotBreakParcelLocker = Notice.chat("&4โœ˜ &cYou have no permission to break the parcel locker."); + public Notice parcelLockerSuccessfullyDeleted = Notice.chat("&2โœ” &aParcel locker deleted successfully."); + public Notice broadcastParcelLockerRemoved = Notice.chat("&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"); + public Notice parcelSent = Notice.chat("&2โœ” &aParcel sent successfully."); + public Notice parcelFailedToSend = Notice.chat("&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."); + public Notice illegalItemFailedToSend = Notice.chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"); + public Notice parcelCannotBeEmpty = Notice.chat("&4โœ˜ &cThe parcel cannot be empty!"); + public Notice parcelNameCannotBeEmpty = Notice.chat("&4โœ˜ &cThe parcel name cannot be empty!"); + public Notice parcelNameSet = Notice.chat("&2โœ” &aParcel name set successfully."); + public Notice parcelDescriptionSet = Notice.chat("&2โœ” &aParcel description set successfully."); + public Notice parcelReceiverSet = Notice.chat("&2โœ” &aParcel receiver set successfully."); + public Notice parcelDestinationSet = Notice.chat("&2โœ” &aParcel destination locker set successfully."); + public Notice alreadyCreatingLocker = Notice.chat("&4โœ˜ &cYou are already creating a parcel locker!"); + public Notice receiverNotSet = Notice.chat("&4โœ˜ &cThe parcel receiver is not set!"); + public Notice parcelSuccessfullyCollected = Notice.chat("&2โœ” &aParcel collected successfully."); + public Notice failedToCollectParcel = Notice.chat("&4โœ˜ &cAn error occurred while collecting the parcel."); + public Notice notEnoughInventorySpace = Notice.chat("&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"); + + @Comment({" ", "# The parcel info message." }) + public Notice parcelInfoMessages = Notice.chat( + "&7ยป &6Parcel info:", + "&fโ€ข &6UUID: &e{UUID}", + "&fโ€ข &6Sender: &e{SENDER}", + "&fโ€ข &6Receiver: &e{RECEIVER}", + "&fโ€ข &6Size: &e{SIZE}", + "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", + "&fโ€ข &6Priority: &e{PRIORITY}", + "&fโ€ข &6Description: &e{DESCRIPTION}" + ); +} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java deleted file mode 100644 index 7bef38fb7..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessagesConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.eternalcode.parcellockers.configuration.implementation; - -import eu.okaeri.configs.OkaeriConfig; - -public class MessagesConfig extends OkaeriConfig { -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 767a3fbfa..a813f138f 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -15,9 +15,6 @@ public class PluginConfig extends OkaeriConfig { @Comment({" ", "# Parcel Lockers plugin configuration file." }) public Settings settings = new Settings(); - @Comment({ " ", "# The plugin messages." }) - public Messages messages = new Messages(); - @Comment({ " ", "# The plugin GUI settings." }) public GuiSettings guiSettings = new GuiSettings(); @@ -67,50 +64,6 @@ public static class Settings extends OkaeriConfig { } - - public static class Messages extends OkaeriConfig { - - public String onlyForPlayers = "&4โœ˜ &cThis command is only available to players!"; - public String noPermission = "&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"; - public String cantFindPlayer = "&4โœ˜ &cThe specified player could not be found!"; - public String invalidUsage = "&4โฃ &cCorrect usage: &6{USAGE}"; - public String reload = "&3โฃ &bConfiguration has been successfully reloaded!"; - public String parcelCommandUsage = "&9โ“˜ Correct usage: &3/parcel &b &3[parcel]"; - public String parcelSuccessfullyDeleted = "&2โœ” &aParcel deleted successfully."; - public String failedToDeleteParcel = "&4โœ˜ &cAn error occurred while deleting the parcel."; - public String failedToCreateParcelLocker = "&4โœ˜ &cCould not create the parcel locker."; - public String parcelLockerSuccessfullyCreated = "&7ยป &aParcel locker created successfully."; - public String enterDescriptionPrompt = "&6โ†ต &eEnter a description for the parcel locker:"; - public String cannotBreakParcelLocker = "&4โœ˜ &cYou have no permission to break the parcel locker."; - public String parcelLockerSuccessfullyDeleted = "&2โœ” &aParcel locker deleted successfully."; - public String broadcastParcelLockerRemoved = "&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"; - public String parcelSent = "&2โœ” &aParcel sent successfully."; - public String parcelFailedToSend = "&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."; - public String illegalItemFailedToSend = "&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"; - public String parcelCannotBeEmpty = "&4โœ˜ &cThe parcel cannot be empty!"; - public String parcelNameCannotBeEmpty = "&4โœ˜ &cThe parcel name cannot be empty!"; - public String parcelNameSet = "&2โœ” &aParcel name set successfully."; - public String parcelDescriptionSet = "&2โœ” &aParcel description set successfully."; - public String parcelReceiverSet = "&2โœ” &aParcel receiver set successfully."; - public String parcelDestinationSet = "&2โœ” &aParcel destination locker set successfully."; - public String alreadyCreatingLocker = "&4โœ˜ &cYou are already creating a parcel locker!"; - public String receiverNotSet = "&4โœ˜ &cThe parcel receiver is not set!"; - public String parcelSuccessfullyCollected = "&2โœ” &aParcel collected successfully."; - public String failedToCollectParcel = "&4โœ˜ &cAn error occurred while collecting the parcel."; - public String notEnoughInventorySpace = "&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"; - - @Comment({ " ", "# The parcel info message." }) - public List parcelInfoMessages = List.of( - "&7ยป &6Parcel info:", - "&fโ€ข &6UUID: &e{UUID}", - "&fโ€ข &6Sender: &e{SENDER}", - "&fโ€ข &6Receiver: &e{RECEIVER}", - "&fโ€ข &6Size: &e{SIZE}", - "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", - "&fโ€ข &6Priority: &e{PRIORITY}", - "&fโ€ข &6Description: &e{DESCRIPTION}" - ); - } public static class GuiSettings extends OkaeriConfig { diff --git a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java b/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java index 192c8a1ba..fb0ae0e63 100644 --- a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java +++ b/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java @@ -1,6 +1,5 @@ package com.eternalcode.parcellockers.conversation; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import org.bukkit.ChatColor; import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.Prompt; @@ -9,12 +8,6 @@ public class ParcelLockerPlacePrompt implements Prompt { - private final PluginConfig config; - - public ParcelLockerPlacePrompt(PluginConfig config) { - this.config = config; - } - @Override public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) { context.setSessionData("description", input); @@ -24,7 +17,8 @@ public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String @NotNull @Override public String getPromptText(@NotNull ConversationContext context) { - return ChatColor.translateAlternateColorCodes('&', this.config.messages.enterDescriptionPrompt); + // TODO do not hardcode this + return ChatColor.translateAlternateColorCodes('&', "&6โ†ต &eEnter a description for the parcel locker:"); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java index 9d99bed4a..4a46fee16 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java @@ -20,45 +20,31 @@ protected AbstractRepositoryOrmLite(DatabaseManager databaseManager, Scheduler s } protected CompletableFuture save(Class type, T entity) { - return this.action(type, dao -> { - return dao.createOrUpdate(entity); - }); + return this.action(type, dao -> dao.createOrUpdate(entity)); } protected CompletableFuture saveIfNotExist(Class type, T entity) { - return this.action(type, dao -> { - return dao.createIfNotExists(entity); - }); + return this.action(type, dao -> dao.createIfNotExists(entity)); } protected CompletableFuture select(Class type, ID id) { - return this.action(type, dao -> { - return dao.queryForId(id); - }); + return this.action(type, dao -> dao.queryForId(id)); } protected CompletableFuture> selectSafe(Class type, ID id) { - return this.action(type, dao -> { - return Optional.ofNullable(dao.queryForId(id)); - }); + return this.action(type, dao -> Optional.ofNullable(dao.queryForId(id))); } protected CompletableFuture delete(Class type, T entity) { - return this.action(type, dao -> { - return dao.delete(entity); - }); + return this.action(type, dao -> dao.delete(entity)); } protected CompletableFuture deleteAll(Class type) { - return this.action(type, dao -> { - return dao.deleteBuilder().delete(); - }); + return this.action(type, dao -> dao.deleteBuilder().delete()); } protected CompletableFuture deleteById(Class type, ID id) { - return this.action(type, dao -> { - return dao.deleteById(id); - }); + return this.action(type, dao -> dao.deleteById(id)); } protected CompletableFuture> selectAll(Class type) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java index e022492f8..4f0b85239 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.gui.implementation.locker; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; @@ -17,8 +18,6 @@ import java.util.function.Supplier; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; public class DestinationSelectionGui implements GuiView { @@ -26,8 +25,7 @@ public class DestinationSelectionGui implements GuiView { private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); - private final Plugin plugin; - private final BukkitScheduler scheduler; + private final Scheduler scheduler; private final PluginConfig config; private final MiniMessage miniMessage; private final LockerRepository lockerRepository; @@ -35,15 +33,13 @@ public class DestinationSelectionGui implements GuiView { private final ParcelSendingGuiState state; public DestinationSelectionGui( - Plugin plugin, - BukkitScheduler scheduler, + Scheduler scheduler, PluginConfig config, MiniMessage miniMessage, LockerRepository lockerRepository, ParcelSendingGui sendingGUI, ParcelSendingGuiState state ) { - this.plugin = plugin; this.scheduler = scheduler; this.config = config; this.miniMessage = miniMessage; @@ -91,7 +87,7 @@ private void show(Player player, Page page) { } this.loadLockers(player, result, refresher).forEach(refresher::addItem); - this.scheduler.runTask(this.plugin, () -> gui.open(player)); + this.scheduler.run(() -> gui.open(player)); }).orTimeout(5, TimeUnit.SECONDS); } @@ -107,7 +103,7 @@ private Supplier toItem(Player player, Locker locker, PaginatedGuiRefre return () -> { String name = parcelItem.name().replace("{DESCRIPTION}", locker.description()); - boolean isLockerSelected = uuid.equals(this.state.getDestinationLocker()); + boolean isLockerSelected = uuid.equals(this.state.destinationLocker()); String oneLineLore = isLockerSelected ? this.config.guiSettings.parcelDestinationSetLine : this.config.guiSettings.parcelDestinationNotSetLine; @@ -118,13 +114,13 @@ private Supplier toItem(Player player, Locker locker, PaginatedGuiRefre .lore(List.of(oneLineLore)) .toGuiItem(event -> { if (isLockerSelected) { - this.state.setDestinationLocker(null); + this.state.destinationLocker(null); this.sendingGUI.updateDestinationItem(player, ""); refresher.refresh(); return; } - this.state.setDestinationLocker(uuid); + this.state.destinationLocker(uuid); this.sendingGUI.updateDestinationItem(player, locker.description()); refresher.refresh(); }); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index a57ad00b5..50d851a75 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -2,12 +2,13 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.user.UserManager; @@ -19,17 +20,16 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; public class LockerMainGui implements GuiView { - private final Plugin plugin; private final MiniMessage miniMessage; + private final Scheduler scheduler; private final PluginConfig config; private final ItemStorageRepository itemStorageRepository; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final NotificationAnnouncer announcer; + private final NoticeService noticeService; private final ParcelContentRepository parcelContentRepository; private final UserRepository userRepository; private final SkullAPI skullAPI; @@ -38,25 +38,24 @@ public class LockerMainGui implements GuiView { private final UserManager userManager; public LockerMainGui( - Plugin plugin, - MiniMessage miniMessage, + MiniMessage miniMessage, Scheduler scheduler, PluginConfig config, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, LockerRepository lockerRepository, - NotificationAnnouncer announcer, + NoticeService noticeService, ParcelContentRepository parcelContentRepository, UserRepository userRepository, SkullAPI skullAPI, ParcelService parcelService ) { - this.plugin = plugin; this.miniMessage = miniMessage; + this.scheduler = scheduler; this.config = config; this.itemStorageRepository = itemStorageRepository; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.announcer = announcer; + this.noticeService = noticeService; this.parcelContentRepository = parcelContentRepository; this.userRepository = userRepository; this.skullAPI = skullAPI; @@ -90,9 +89,9 @@ public void show(Player player) { gui.setItem(slot, cornerItem); } - ParcelCollectionGui collectionGui = new ParcelCollectionGui(this.plugin, + ParcelCollectionGui collectionGui = new ParcelCollectionGui( this.config, - this.plugin.getServer().getScheduler(), + this.scheduler, this.parcelRepository, this.miniMessage, this.parcelService, @@ -101,13 +100,14 @@ public void show(Player player) { ); gui.setItem(21, this.config.guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); - gui.setItem(23, this.config.guiSettings.parcelLockerSendItem.toGuiItem(event -> new ParcelSendingGui(this.plugin, + gui.setItem(23, this.config.guiSettings.parcelLockerSendItem.toGuiItem(event -> new ParcelSendingGui( + this.scheduler, this.config, this.miniMessage, this.itemStorageRepository, this.parcelRepository, this.lockerRepository, - this.announcer, + this.noticeService, this.parcelContentRepository, this.userRepository, this.skullAPI, diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java index b9e223cb6..4fb44e54a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.gui.implementation.locker; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; @@ -18,8 +19,6 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; public class ParcelCollectionGui implements GuiView { @@ -27,9 +26,8 @@ public class ParcelCollectionGui implements GuiView { private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); - private final Plugin plugin; private final PluginConfig config; - private final BukkitScheduler scheduler; + private final Scheduler scheduler; private final ParcelRepository parcelRepository; private final MiniMessage miniMessage; private final ParcelService parcelService; @@ -37,16 +35,14 @@ public class ParcelCollectionGui implements GuiView { private final LockerRepository lockerRepository; public ParcelCollectionGui( - Plugin plugin, PluginConfig config, - BukkitScheduler scheduler, + Scheduler scheduler, ParcelRepository parcelRepository, MiniMessage miniMessage, ParcelService parcelService, UserManager userManager, LockerRepository lockerRepository ) { - this.plugin = plugin; this.config = config; this.scheduler = scheduler; this.parcelRepository = parcelRepository; @@ -129,7 +125,7 @@ private void show(Player player, Page page) { })); } - this.scheduler.runTask(this.plugin, () -> gui.open(player)); + this.scheduler.run(() -> gui.open(player)); }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java index ea0048e27..152d1216d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java @@ -1,12 +1,13 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.bukkit.ItemUtil; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.itemstorage.ItemStorage; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; @@ -20,20 +21,18 @@ import java.util.stream.IntStream; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Material; -import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; public class ParcelItemStorageGui { - private final Plugin plugin; + private final Scheduler scheduler; private final PluginConfig config; private final MiniMessage miniMessage; private final ItemStorageRepository itemStorageRepository; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final NotificationAnnouncer announcer; + private final NoticeService noticeService; private final ParcelContentRepository parcelContentRepository; private final UserRepository userRepository; private final SkullAPI skullAPI; @@ -41,25 +40,25 @@ public class ParcelItemStorageGui { private final ParcelService parcelService; public ParcelItemStorageGui( - Plugin plugin, + Scheduler scheduler, PluginConfig config, MiniMessage miniMessage, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, LockerRepository lockerRepository, - NotificationAnnouncer announcer, + NoticeService noticeService, ParcelContentRepository parcelContentRepository, UserRepository userRepository, SkullAPI skullAPI, ParcelSendingGuiState state, ParcelService parcelService ) { - this.plugin = plugin; + this.scheduler = scheduler; this.config = config; this.miniMessage = miniMessage; this.itemStorageRepository = itemStorageRepository; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.announcer = announcer; + this.noticeService = noticeService; this.parcelContentRepository = parcelContentRepository; this.userRepository = userRepository; this.skullAPI = skullAPI; @@ -74,13 +73,13 @@ void show(Player player, ParcelSize size) { GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); GuiItem confirmItem = guiSettings.confirmItemsItem.toGuiItem(event -> new ParcelSendingGui( - this.plugin, + this.scheduler, this.config, this.miniMessage, this.itemStorageRepository, this.parcelRepository, this.lockerRepository, - this.announcer, + this.noticeService, this.parcelContentRepository, this.userRepository, this.skullAPI, @@ -124,8 +123,12 @@ void show(Player player, ParcelSize size) { if (item.getType() == type) { ItemUtil.giveItem(player, item); gui.removeItem(item); - player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_AMBIENT, 1, 1); - this.announcer.sendMessage(player, this.config.messages.illegalItemFailedToSend.replace("{ITEMS}", item.getType().name())); + // player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_AMBIENT, 1, 1); + this.noticeService.create() + .notice(messages -> messages.illegalItemFailedToSend) + .placeholder("{ITEMS}", item.getType().name()) + .player(player.getUniqueId()) + .send(); } } @@ -146,7 +149,7 @@ void show(Player player, ParcelSize size) { } } - this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); + this.scheduler.run(() -> gui.open(player)); }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java index 034fb4da2..c0a915709 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java @@ -1,20 +1,20 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.adventure.AdventureUtil; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.user.repository.UserRepository; import de.rapha149.signgui.SignGUI; -import de.rapha149.signgui.SignGUIAction; import de.rapha149.signgui.exception.SignGUIVersionException; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; @@ -26,13 +26,11 @@ import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitScheduler; import org.jetbrains.annotations.NotNull; public class ParcelSendingGui implements GuiView { @@ -48,14 +46,13 @@ public class ParcelSendingGui implements GuiView { private static final int PRIORITY_BUTTON_SLOT = 42; private static final int SUBMIT_ITEM_SLOT = 43; private static final int CLOSE_ITEM_SLOT = 49; - private final Plugin plugin; - private final BukkitScheduler scheduler; + private final Scheduler scheduler; private final PluginConfig config; private final MiniMessage miniMessage; private final ItemStorageRepository itemStorageRepository; private final ParcelRepository parcelRepository; private final LockerRepository lockerRepository; - private final NotificationAnnouncer announcer; + private final NoticeService noticeService; private final ParcelContentRepository parcelContentRepository; private final UserRepository userRepository; private final SkullAPI skullAPI; @@ -66,38 +63,35 @@ public class ParcelSendingGui implements GuiView { private Gui gui; public ParcelSendingGui( - Plugin plugin, - PluginConfig config, + Scheduler scheduler, PluginConfig config, MiniMessage miniMessage, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, LockerRepository lockerRepository, - NotificationAnnouncer announcer, + NoticeService noticeService, ParcelContentRepository parcelContentRepository, UserRepository userRepository, SkullAPI skullAPI, ParcelService parcelService, ParcelSendingGuiState state ) { - this.plugin = plugin; + this.scheduler = scheduler; this.config = config; this.miniMessage = miniMessage; this.itemStorageRepository = itemStorageRepository; this.parcelRepository = parcelRepository; this.lockerRepository = lockerRepository; - this.announcer = announcer; + this.noticeService = noticeService; this.parcelContentRepository = parcelContentRepository; this.userRepository = userRepository; this.skullAPI = skullAPI; this.parcelService = parcelService; this.state = state; - this.scheduler = this.plugin.getServer().getScheduler(); } @Override public void show(Player player) { - PluginConfig settings = this.config; - PluginConfig.GuiSettings guiSettings = settings.guiSettings; + PluginConfig.GuiSettings guiSettings = this.config.guiSettings; Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelLockerSendingGuiTitle); @@ -118,32 +112,40 @@ public void show(Player player) { .setLine(0, "Enter parcel name:") .setHandler((p, result) -> { String name = result.getLineWithoutColor(1); - if (name.isBlank()) { - this.announcer.sendMessage(player, settings.messages.parcelNameCannotBeEmpty); + this.noticeService.create() + .notice(messages -> messages.parcelNameCannotBeEmpty) + .player(player.getUniqueId()) + .send(); return Collections.emptyList(); } - this.state.setParcelName(name); - this.announcer.sendMessage(player, settings.messages.parcelNameSet); + this.state.parcelName(name); + this.noticeService.create() + .notice(messages -> messages.parcelNameSet) + .player(player.getUniqueId()) + .send(); - List lore = nameItem.lore; + List lore = nameItem.lore(); if (lore.size() > 1) { lore.remove(1); } - lore.add(this.config.guiSettings.parcelNameSetLine.replace("{NAME}", this.state.getParcelName() == null - ? "None" : this.state.getParcelName())); + lore.add( + this.config.guiSettings.parcelNameSetLine.replace("{NAME}", + this.state.parcelName() == null ? "None" : this.state.parcelName()) + ); this.gui.updateItem(NAME_ITEM_SLOT, nameItem .lore(lore) .toItemStack()); - return List.of(SignGUIAction.runSync((JavaPlugin) this.plugin, () -> this.gui.open(player))); + this.gui.open(player); + return List.of(); }) .build(); nameSignGui.open(player); } catch (SignGUIVersionException e) { - this.plugin.getLogger().severe("The server version is unsupported by SignGUI API!"); + Bukkit.getLogger().severe("The server version is unsupported by SignGUI API!"); } }); @@ -159,10 +161,13 @@ public void show(Player player) { .setHandler((p, result) -> { String description = result.getLineWithoutColor(1); - this.state.setParcelDescription(description); - this.announcer.sendMessage(player, settings.messages.parcelDescriptionSet); + this.state.parcelDescription(description); + this.noticeService.create() + .notice(messages -> messages.parcelDescriptionSet) + .player(player.getUniqueId()) + .send(); - List lore = descriptionItem.clone().lore; + List lore = descriptionItem.clone().lore(); if (lore.size() > 1) { lore.remove(1); } @@ -172,24 +177,25 @@ public void show(Player player) { this.gui.updateItem(DESCRIPTION_ITEM_SLOT, descriptionItem .lore(lore) .toItemStack()); - return List.of(SignGUIAction.runSync((JavaPlugin) this.plugin, () -> this.gui.open(player))); + this.gui.open(player); + return List.of(); }) .build(); } catch (SignGUIVersionException e) { - this.plugin.getLogger().severe("The server version is unsupported by SignGUI API!"); + Bukkit.getLogger().severe("The server version is unsupported by SignGUI API!"); } descriptionSignGui.open(player); }); GuiItem storageItem = guiSettings.parcelStorageItem.toGuiItem(event -> { ParcelItemStorageGui storageGUI = new ParcelItemStorageGui( - this.plugin, + this.scheduler, this.config, this.miniMessage, this.itemStorageRepository, this.parcelRepository, this.lockerRepository, - this.announcer, + this.noticeService, this.parcelContentRepository, this.userRepository, this.skullAPI, @@ -200,14 +206,14 @@ public void show(Player player) { if (result.isPresent()) { int slotsSize = result.get().items().size(); if (slotsSize <= 9) { - this.scheduler.runTask(this.plugin, () -> storageGUI.show(player, this.state.getSize())); - } else if (slotsSize <= 18 && this.state.getSize() == ParcelSize.SMALL) { - this.scheduler.runTask(this.plugin, () -> storageGUI.show(player, ParcelSize.MEDIUM)); + this.scheduler.run(() -> storageGUI.show(player, this.state.size())); + } else if (slotsSize <= 18 && this.state.size() == ParcelSize.SMALL) { + this.scheduler.run(() -> storageGUI.show(player, ParcelSize.MEDIUM)); } else { - this.scheduler.runTask(this.plugin, () -> storageGUI.show(player, ParcelSize.LARGE)); + this.scheduler.run(() -> storageGUI.show(player, ParcelSize.LARGE)); } } else { - this.scheduler.runTask(this.plugin, () -> storageGUI.show(player, this.state.getSize())); + this.scheduler.run(() -> storageGUI.show(player, this.state.size())); } } ).orTimeout(2, TimeUnit.SECONDS); @@ -215,20 +221,26 @@ public void show(Player player) { GuiItem submitItem = guiSettings.submitParcelItem.toGuiItem(event -> this.itemStorageRepository.find(player.getUniqueId()).thenAccept(result -> { if (result.isEmpty() || result.get().items().isEmpty()) { - this.announcer.sendMessage(player, settings.messages.parcelCannotBeEmpty); - player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); + this.noticeService.create() + .notice(messages -> messages.parcelCannotBeEmpty) + .player(player.getUniqueId()) + .send(); + // TODO player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); return; } - if (this.state.getReceiver() == null) { - this.announcer.sendMessage(player, settings.messages.receiverNotSet); + if (this.state.receiver() == null) { + this.noticeService.create() + .notice(messages -> messages.receiverNotSet) + .player(player.getUniqueId()) + .send(); player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); return; } - Parcel parcel = new Parcel(UUID.randomUUID(), player.getUniqueId(), this.state.getParcelName(), - this.state.getParcelDescription(), this.state.isPriority(), this.state.getReceiver(), - this.state.getSize(), this.state.getEntryLocker(), this.state.getDestinationLocker(), this.state.getStatus()); + Parcel parcel = new Parcel(UUID.randomUUID(), player.getUniqueId(), this.state.parcelName(), + this.state.parcelDescription(), this.state.priority(), this.state.receiver(), + this.state.size(), this.state.entryLocker(), this.state.destinationLocker(), this.state.status()); if (this.parcelService.send(player, parcel, result.get().items())) { this.itemStorageRepository.delete(player.getUniqueId()); @@ -238,13 +250,14 @@ public void show(Player player) { }).orTimeout(5, TimeUnit.SECONDS)); GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> - new LockerMainGui(this.plugin, + new LockerMainGui( this.miniMessage, + this.scheduler, this.config, this.itemStorageRepository, this.parcelRepository, this.lockerRepository, - this.announcer, + this.noticeService, this.parcelContentRepository, this.userRepository, this.skullAPI, @@ -271,7 +284,6 @@ public void show(Player player) { this.gui.setItem(NAME_ITEM_SLOT, nameGuiItem); this.gui.setItem(DESCRIPTION_ITEM_SLOT, descriptionGuiItem); this.gui.setItem(RECEIVER_ITEM_SLOT, guiSettings.parcelReceiverItem.toGuiItem(event -> new ReceiverSelectionGui( - this.plugin, this.scheduler, this.config, this.miniMessage, @@ -282,7 +294,6 @@ public void show(Player player) { ).show(player))); this.gui.setItem(DESTINATION_ITEM_SLOT, guiSettings.parcelDestinationLockerItem.toGuiItem(event -> new DestinationSelectionGui( - this.plugin, this.scheduler, this.config, this.miniMessage, @@ -293,19 +304,18 @@ public void show(Player player) { this.gui.setItem(STORAGE_ITEM_SLOT, storageItem); this.gui.setItem(SUBMIT_ITEM_SLOT, submitItem); - this.gui.setItem(PRIORITY_BUTTON_SLOT, priorityItem.toGuiItem(event -> this.setSelected(this.gui, !this.state.isPriority()))); + this.gui.setItem(PRIORITY_BUTTON_SLOT, priorityItem.toGuiItem(event -> this.setSelected(this.gui, !this.state.priority()))); this.gui.setItem(CLOSE_ITEM_SLOT, closeItem); - this.setSelected(this.gui, this.state.getSize() == null ? ParcelSize.SMALL : this.state.getSize()); + this.setSelected(this.gui, this.state.size() == null ? ParcelSize.SMALL : this.state.size()); this.updateNameItem(); this.updateDescriptionItem(); - this.userRepository.find(this.state.getReceiver()).thenAccept(userOptional -> { - userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name())); - }); - this.lockerRepository.find(this.state.getDestinationLocker()).thenAccept(lockerOptional -> { - lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.description())); - }); + this.userRepository.find(this.state.receiver()).thenAccept(userOptional -> + userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); + + this.lockerRepository.find(this.state.destinationLocker()).thenAccept(lockerOptional -> + lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.description()))); this.gui.open(player); @@ -313,12 +323,12 @@ public void show(Player player) { private void setSelected(Gui gui, ParcelSize size) { PluginConfig.GuiSettings settings = this.config.guiSettings; - this.state.setSize(size); + this.state.size(size); ConfigItem smallButton = size == ParcelSize.SMALL ? settings.selectedSmallParcelSizeItem : settings.smallParcelSizeItem; ConfigItem mediumButton = size == ParcelSize.MEDIUM ? settings.selectedMediumParcelSizeItem : settings.mediumParcelSizeItem; ConfigItem largeButton = size == ParcelSize.LARGE ? settings.selectedLargeParcelSizeItem : settings.largeParcelSizeItem; - ConfigItem priorityButton = this.state.isPriority() ? settings.selectedPriorityItem : settings.priorityItem; + ConfigItem priorityButton = this.state.priority() ? settings.selectedPriorityItem : settings.priorityItem; gui.updateItem(SMALL_BUTTON_SLOT, smallButton.toItemStack()); gui.updateItem(MEDIUM_BUTTON_SLOT, mediumButton.toItemStack()); @@ -328,7 +338,7 @@ private void setSelected(Gui gui, ParcelSize size) { private void setSelected(Gui gui, boolean priority) { PluginConfig.GuiSettings settings = this.config.guiSettings; - this.state.setPriority(priority); + this.state.priority(priority); ConfigItem priorityButton = priority ? settings.selectedPriorityItem : settings.priorityItem; @@ -336,27 +346,30 @@ private void setSelected(Gui gui, boolean priority) { } public void updateNameItem() { - if (this.state.getParcelName() == null || this.state.getParcelName().isEmpty()) { + if (this.state.parcelName() == null || this.state.parcelName().isEmpty()) { this.gui.updateItem(NAME_ITEM_SLOT, this.config.guiSettings.parcelNameItem.toItemStack()); return; } - String line = this.config.guiSettings.parcelNameSetLine.replace("{NAME}", this.state.getParcelName()); + String line = this.config.guiSettings.parcelNameSetLine.replace("{NAME}", this.state.parcelName()); this.gui.updateItem(NAME_ITEM_SLOT, this.createActiveItem(this.config.guiSettings.parcelNameItem, line)); } public void updateDescriptionItem() { - if (this.state.getParcelDescription() == null || this.state.getParcelDescription().isEmpty()) { + if (this.state.parcelDescription() == null || this.state.parcelDescription().isEmpty()) { this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.config.guiSettings.parcelDescriptionItem.toItemStack()); return; } - String line = this.config.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", this.state.getParcelDescription()); + String line = this.config.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", this.state.parcelDescription()); this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.createActiveItem(this.config.guiSettings.parcelDescriptionItem, line)); } public void updateReceiverItem(Player player, String receiverName) { - this.announcer.sendMessage(player, this.config.messages.parcelReceiverSet); + this.noticeService.create() + .notice(messages -> messages.parcelReceiverSet) + .player(player.getUniqueId()) + .send(); if (receiverName == null || receiverName.isEmpty()) { this.gui.updateItem(RECEIVER_ITEM_SLOT, this.config.guiSettings.parcelReceiverItem.toItemStack()); @@ -368,7 +381,10 @@ public void updateReceiverItem(Player player, String receiverName) { } public void updateDestinationItem(Player player, String destinationLockerDesc) { - this.announcer.sendMessage(player, this.config.messages.parcelDestinationSet); + this.noticeService.create() + .notice(messages -> messages.parcelDestinationSet) + .player(player.getUniqueId()) + .send(); if (destinationLockerDesc == null || destinationLockerDesc.isEmpty()) { this.gui.updateItem(DESTINATION_ITEM_SLOT, this.config.guiSettings.parcelDestinationLockerItem.toItemStack()); @@ -380,7 +396,7 @@ public void updateDestinationItem(Player player, String destinationLockerDesc) { } private @NotNull ItemStack createActiveItem(ConfigItem item, String appendLore) { - List itemLore = new ArrayList<>(item.lore); + List itemLore = new ArrayList<>(item.lore()); itemLore.add(appendLore); return item.toBuilder() diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java index a3a74762c..efef12627 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.gui.implementation.locker; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; @@ -20,8 +21,6 @@ import java.util.function.Supplier; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; public class ReceiverSelectionGui implements GuiView { @@ -30,8 +29,7 @@ public class ReceiverSelectionGui implements GuiView { private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); - private final Plugin plugin; - private final BukkitScheduler scheduler; + private final Scheduler scheduler; private final PluginConfig config; private final MiniMessage miniMessage; private final UserRepository userRepository; @@ -41,8 +39,7 @@ public class ReceiverSelectionGui implements GuiView { public ReceiverSelectionGui( - Plugin plugin, - BukkitScheduler scheduler, + Scheduler scheduler, PluginConfig config, MiniMessage miniMessage, UserRepository userRepository, @@ -50,7 +47,6 @@ public ReceiverSelectionGui( SkullAPI skullAPI, ParcelSendingGuiState state ) { - this.plugin = plugin; this.scheduler = scheduler; this.config = config; this.miniMessage = miniMessage; @@ -103,7 +99,7 @@ private void show(Player player, Page page) { refresh.addItem(item); } - this.scheduler.runTask(this.plugin, () -> gui.open(player)); + this.scheduler.run(() -> gui.open(player)); }); }); } @@ -119,7 +115,7 @@ private Supplier toItem(Player player, User user, SkullData skullData, UUID uuid = user.uuid(); return () -> { - boolean isReceiverSelected = uuid.equals(this.state.getReceiver()); + boolean isReceiverSelected = uuid.equals(this.state.receiver()); String lore = isReceiverSelected ? this.config.guiSettings.parcelReceiverSetLine : this.config.guiSettings.parcelReceiverNotSetLine; @@ -128,17 +124,17 @@ private Supplier toItem(Player player, User user, SkullData skullData, .texture(skullData.getTexture()) .name(this.miniMessage.deserialize(user.name())) .lore(this.miniMessage.deserialize(lore)) - .glow(uuid.equals(this.state.getReceiver())) + .glow(uuid.equals(this.state.receiver())) .asGuiItem(event -> { - if (uuid.equals(this.state.getReceiver())) { + if (uuid.equals(this.state.receiver())) { refresher.refresh(); this.sendingGUI.updateReceiverItem(player, ""); - this.state.setReceiver(null); + this.state.receiver(null); return; } this.sendingGUI.updateReceiverItem(player, user.name()); - this.state.setReceiver(uuid); + this.state.receiver(uuid); refresher.refresh(); }); }; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index 36d6cdef8..96e1760aa 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -2,6 +2,7 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; @@ -10,14 +11,11 @@ import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.Server; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; public class MainGui implements GuiView { - private final Plugin plugin; - private final Server server; + private final Scheduler scheduler; private final MiniMessage miniMessage; private final PluginConfig config; private final ParcelRepository parcelRepository; @@ -25,16 +23,14 @@ public class MainGui implements GuiView { private final UserManager userManager; public MainGui( - Plugin plugin, - Server server, + Scheduler scheduler, MiniMessage miniMessage, PluginConfig config, ParcelRepository parcelRepository, LockerRepository lockerRepository, UserManager userManager ) { - this.plugin = plugin; - this.server = server; + this.scheduler = scheduler; this.miniMessage = miniMessage; this.config = config; this.parcelRepository = parcelRepository; @@ -73,8 +69,8 @@ public void show(Player player) { gui.setItem(24, parcelArchiveItem); gui.setItem(40, closeItem); - gui.addSlotAction(20, event -> new ParcelListGui(this.plugin, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userManager, this).show(player)); - gui.addSlotAction(22, event -> new SentParcelsGui(this.plugin, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userManager).show(player)); + gui.addSlotAction(20, event -> new ParcelListGui(this.scheduler, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userManager, this).show(player)); + gui.addSlotAction(22, event -> new SentParcelsGui(this.scheduler, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userManager).show(player)); gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.open(player); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 8ea5457c9..b6f101f3a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -2,6 +2,7 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; @@ -19,14 +20,13 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; public class ParcelListGui implements GuiView { private static final int WIDTH = 7; private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); - private final Plugin plugin; + private final Scheduler scheduler; private final MiniMessage miniMessage; private final PluginConfig config; private final ParcelRepository parcelRepository; @@ -35,7 +35,7 @@ public class ParcelListGui implements GuiView { private final MainGui mainGUI; public ParcelListGui( - Plugin plugin, + Scheduler scheduler, MiniMessage miniMessage, PluginConfig config, ParcelRepository parcelRepository, @@ -43,7 +43,7 @@ public ParcelListGui( UserManager userManager, MainGui mainGUI ) { - this.plugin = plugin; + this.scheduler = scheduler; this.miniMessage = miniMessage; this.config = config; this.parcelRepository = parcelRepository; @@ -88,11 +88,11 @@ private void show(Player player, Page page) { for (Parcel parcel : result.parcels()) { ItemBuilder parcelItem = item.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore, this.userManager, this.lockerRepository).stream() + List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.userManager, this.lockerRepository).stream() .map(line -> resetItalic(this.miniMessage.deserialize(line))) .toList(); parcelItem.lore(newLore); - parcelItem.name(this.miniMessage.deserialize(item.name.replace("{NAME}", parcel.name()))); + parcelItem.name(this.miniMessage.deserialize(item.name().replace("{NAME}", parcel.name()))); gui.addItem(parcelItem.asGuiItem()); } @@ -107,7 +107,7 @@ private void show(Player player, Page page) { gui.setItem(47, previousPageItem); } - this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); + this.scheduler.run(() -> gui.open(player)); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 0b1d89682..51edc2da3 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.gui.implementation.remote; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; @@ -17,11 +18,10 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; public class SentParcelsGui implements GuiView { - private final Plugin plugin; + private final Scheduler scheduler; private final MiniMessage miniMessage; private final PluginConfig config; private final ParcelRepository parcelRepository; @@ -30,7 +30,7 @@ public class SentParcelsGui implements GuiView { private final UserManager userManager; public SentParcelsGui( - Plugin plugin, + Scheduler scheduler, MiniMessage miniMessage, PluginConfig config, ParcelRepository parcelRepository, @@ -38,7 +38,7 @@ public SentParcelsGui( MainGui mainGUI, UserManager userManager ) { - this.plugin = plugin; + this.scheduler = scheduler; this.miniMessage = miniMessage; this.config = config; this.parcelRepository = parcelRepository; @@ -77,16 +77,16 @@ public void show(Player player) { for (Parcel parcel : parcels) { ItemBuilder item = parcelItem.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore, this.userManager, this.lockerRepository) + List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore(), this.userManager, this.lockerRepository) .stream() .map(line -> this.miniMessage.deserialize(line)) .toList(); item.lore(newLore); - item.name(this.miniMessage.deserialize(parcelItem.name.replace("{NAME}", parcel.name()))); + item.name(this.miniMessage.deserialize(parcelItem.name())); gui.addItem(item.asGuiItem()); } - this.plugin.getServer().getScheduler().runTask(this.plugin, () -> gui.open(player)); + this.scheduler.run(() -> gui.open(player)); }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java index 84271f020..4a80fe343 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java @@ -1,9 +1,9 @@ package com.eternalcode.parcellockers.locker.controller; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.multification.shared.Formatter; import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.shared.Position; import com.eternalcode.parcellockers.shared.PositionAdapter; import java.util.UUID; @@ -18,26 +18,21 @@ import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.entity.EntityExplodeEvent; -import panda.utilities.text.Formatter; - public class LockerBreakController implements Listener { private final LockerRepository lockerRepository; private final LockerCache cache; - private final NotificationAnnouncer announcer; - private final PluginConfig.Messages messages; + private final NoticeService noticeService; public LockerBreakController( LockerRepository lockerRepository, LockerCache cache, - NotificationAnnouncer announcer, - PluginConfig.Messages messages + NoticeService noticeService ) { this.lockerRepository = lockerRepository; this.cache = cache; - this.announcer = announcer; - this.messages = messages; + this.noticeService = noticeService; } @EventHandler @@ -53,7 +48,10 @@ public void onBlockBreak(BlockBreakEvent event) { if (!player.hasPermission("parcellockers.admin.break")) { event.setCancelled(true); - this.announcer.sendMessage(player, this.messages.cannotBreakParcelLocker); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.cannotBreakParcelLocker) + .send(); return; } @@ -65,7 +63,10 @@ public void onBlockBreak(BlockBreakEvent event) { UUID toRemove = this.cache.get(position).get().uuid(); this.lockerRepository.delete(toRemove); - this.announcer.sendMessage(player, this.messages.parcelLockerSuccessfullyDeleted); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.parcelLockerSuccessfullyDeleted) + .send(); Formatter formatter = new Formatter() .register("{X}", position.x()) @@ -74,7 +75,11 @@ public void onBlockBreak(BlockBreakEvent event) { .register("{WORLD}", position.world()) .register("{PLAYER}", player.getName()); - this.announcer.broadcast(formatter.format(this.messages.broadcastParcelLockerRemoved)); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.parcelLockerSuccessfullyDeleted) + .formatter(formatter) + .send(); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java index 72b30259f..c07f206d8 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java @@ -4,12 +4,13 @@ import com.eternalcode.parcellockers.conversation.ParcelLockerPlacePrompt; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.shared.PositionAdapter; -import java.util.HashMap; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import java.util.HashSet; -import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; import org.bukkit.Location; import org.bukkit.conversations.ConversationFactory; import org.bukkit.conversations.NullConversationPrefix; @@ -27,19 +28,21 @@ public class LockerPlaceController implements Listener { private final PluginConfig config; private final Plugin plugin; private final LockerRepository databaseService; - private final NotificationAnnouncer announcer; - private final Map lockerCreators = new HashMap<>(); + private final NoticeService noticeService; + private final Cache lockerCreators = Caffeine.newBuilder() + .expireAfterWrite(2, TimeUnit.MINUTES) + .build(); public LockerPlaceController( PluginConfig config, Plugin plugin, LockerRepository databaseService, - NotificationAnnouncer announcer + NoticeService noticeService ) { this.config = config; this.plugin = plugin; this.databaseService = databaseService; - this.announcer = announcer; + this.noticeService = noticeService; } private static boolean compareMeta(ItemStack first, ItemStack second) { @@ -76,37 +79,50 @@ public void onBlockPlace(BlockPlaceEvent event) { return; } - if (this.lockerCreators.containsKey(player.getUniqueId())) { + if (this.lockerCreators.getIfPresent(player.getUniqueId()) != null) { event.setCancelled(true); - this.announcer.sendMessage(player, this.config.messages.alreadyCreatingLocker); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.alreadyCreatingLocker) + .send(); return; } this.lockerCreators.put(player.getUniqueId(), true); ConversationFactory conversationFactory = new ConversationFactory(this.plugin) .addConversationAbandonedListener(e -> { - if (e.gracefulExit()) { - String description = (String) e.getContext().getSessionData("description"); - Location location = event.getBlockPlaced().getLocation(); - - this.databaseService.save(new Locker(UUID.randomUUID(), description, PositionAdapter.convert(location))).whenComplete((parcelLocker, throwable) -> { - if (throwable != null) { - throwable.printStackTrace(); - this.announcer.sendMessage(player, this.config.messages.failedToCreateParcelLocker); - return; - } - this.announcer.sendMessage(player, this.config.messages.parcelLockerSuccessfullyCreated); - }); - } else { + if (!e.gracefulExit()) { event.setCancelled(true); + return; } - this.lockerCreators.remove(player.getUniqueId()); + String description = (String) e.getContext().getSessionData("description"); + Location location = event.getBlockPlaced().getLocation(); + + this.databaseService.save(new Locker( + UUID.randomUUID(), + description, + PositionAdapter.convert(location))).whenComplete((parcelLocker, throwable) -> { + if (throwable != null) { + throwable.printStackTrace(); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.failedToCreateParcelLocker) + .send(); + return; + } + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.parcelLockerSuccessfullyCreated) + .send(); + }); + + this.lockerCreators.invalidate(player.getUniqueId()); }) .withPrefix(new NullConversationPrefix()) .withModality(false) .withLocalEcho(false) .withTimeout(60) - .withFirstPrompt(new ParcelLockerPlacePrompt(this.config)); + .withFirstPrompt(new ParcelLockerPlacePrompt()); player.beginConversation(conversationFactory.buildConversation(player)); } diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java b/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java index b84bfd2a3..0b18a7412 100644 --- a/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java +++ b/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java @@ -3,7 +3,7 @@ import com.eternalcode.multification.adventure.AudienceConverter; import com.eternalcode.multification.bukkit.BukkitMultification; import com.eternalcode.multification.translation.TranslationProvider; -import com.eternalcode.parcellockers.configuration.implementation.MessagesConfig; +import com.eternalcode.parcellockers.configuration.implementation.MessageConfig; import net.kyori.adventure.platform.AudienceProvider; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -12,20 +12,20 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -public class NoticeService extends BukkitMultification { +public class NoticeService extends BukkitMultification { - private final MessagesConfig messages; + private final MessageConfig messages; private final MiniMessage miniMessage; private final AudienceProvider audienceProvider; - public NoticeService(MessagesConfig messages, MiniMessage miniMessage, AudienceProvider audienceProvider) { + public NoticeService(MessageConfig messages, MiniMessage miniMessage, AudienceProvider audienceProvider) { this.messages = messages; this.miniMessage = miniMessage; this.audienceProvider = audienceProvider; } @Override - protected @NotNull TranslationProvider translationProvider() { + protected @NotNull TranslationProvider translationProvider() { return locale -> this.messages; } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 692bc439e..0d56b46c9 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -9,14 +9,13 @@ import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.delivery.Delivery; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; +import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.shared.ParcelLockersException; import java.time.Duration; import java.time.Instant; import java.util.List; -import org.bukkit.Sound; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -24,7 +23,7 @@ public class ParcelServiceImpl implements ParcelService { private final PluginConfig config; - private final NotificationAnnouncer announcer; + private final NoticeService noticeService; private final ParcelRepository parcelRepository; private final DeliveryRepository deliveryRepository; private final ParcelContentRepository parcelContentRepository; @@ -32,14 +31,14 @@ public class ParcelServiceImpl implements ParcelService { public ParcelServiceImpl( PluginConfig config, - NotificationAnnouncer announcer, + NoticeService noticeService, ParcelRepository parcelRepository, DeliveryRepository deliveryRepository, ParcelContentRepository parcelContentRepository, Scheduler scheduler ) { this.config = config; - this.announcer = announcer; + this.noticeService = noticeService; this.parcelRepository = parcelRepository; this.deliveryRepository = deliveryRepository; this.parcelContentRepository = parcelContentRepository; @@ -54,17 +53,25 @@ public boolean send(Player sender, Parcel parcel, List items) { this.parcelRepository.save(parcel); - parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { + this.parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { if (throwable != null) { - announcer.sendMessage(sender, config.messages.parcelFailedToSend); + this.noticeService.create() + .notice(messages -> messages.parcelFailedToSend) + .player(sender.getUniqueId()) + .send(); + throw new ParcelLockersException("Failed to save parcel content", throwable); } - announcer.sendMessage(sender, config.messages.parcelSent); + + this.noticeService.create() + .notice(messages -> messages.parcelSent) + .player(sender.getUniqueId()) + .send(); Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); - scheduler.runLaterAsync(task, delay); + this.scheduler.runLaterAsync(task, delay); return true; }); @@ -74,11 +81,17 @@ public boolean send(Player sender, Parcel parcel, List items) { @Override public void remove(CommandSender sender, Parcel parcel) { this.parcelRepository.remove(parcel) - .thenAccept(v -> announcer.sendMessage(sender, config.messages.parcelSuccessfullyDeleted)) - .whenComplete((v, throwable) -> { - if (throwable != null) { - announcer.sendMessage(sender, config.messages.failedToDeleteParcel); - } + .thenAccept(v -> + this.noticeService.create() + .notice(messages -> messages.parcelSuccessfullyDeleted) + .viewer(sender) + .send()) + .exceptionally(throwable -> { + this.noticeService.create() + .notice(messages -> messages.failedToDeleteParcel) + .viewer(sender) + .send(); + return null; }); } @@ -86,43 +99,39 @@ public void remove(CommandSender sender, Parcel parcel) { public void collect(Player player, Parcel parcel) { this.parcelContentRepository.find(parcel.uuid()).thenAccept(optional -> { if (optional.isEmpty()) { - playErrorSound(player); - this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); + this.noticeService.create() + .notice(messages -> messages.failedToCollectParcel) + .player(player.getUniqueId()) + .send(); return; } List items = optional.get().items(); if (items.size() > freeSlotsInInventory(player)) { - playErrorSound(player); - this.announcer.sendMessage(player, this.config.messages.notEnoughInventorySpace); + this.noticeService.create() + .notice(messages -> messages.notEnoughInventorySpace) + .player(player.getUniqueId()) + .send(); return; } items.forEach(item -> this.scheduler.run(() -> ItemUtil.giveItem(player, item))); this.parcelRepository.remove(parcel) - .thenCompose(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) + .thenAccept(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) .whenComplete((v, throwable) -> { if (throwable != null) { - this.announcer.sendMessage(player, this.config.messages.failedToCollectParcel); - } else { - playSuccessSound(player); - this.announcer.sendMessage(player, this.config.messages.parcelSuccessfullyCollected); + this.noticeService.create() + .notice(messages -> messages.failedToCollectParcel) + .player(player.getUniqueId()) + .send(); + return; } + this.noticeService.create() + .notice(messages -> messages.parcelSuccessfullyCollected) + .player(player.getUniqueId()) + .send(); }); }); } - - private void playErrorSound(Player player) { - player.playSound( - player.getLocation(), - this.config.settings.errorSound, - this.config.settings.errorSoundVolume, - this.config.settings.errorSoundPitch - ); - } - - private void playSuccessSound(Player player) { - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5F, 1); - } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java index 1854c2bed..195886fc9 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java @@ -1,21 +1,14 @@ package com.eternalcode.parcellockers.parcel.command; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.gui.implementation.remote.MainGui; import com.eternalcode.parcellockers.gui.implementation.remote.ParcelListGui; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NotificationAnnouncer; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; -import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; -import com.eternalcode.parcellockers.user.UserManager; import dev.rollczi.litecommands.annotations.argument.Arg; -import dev.rollczi.litecommands.annotations.async.Async; import dev.rollczi.litecommands.annotations.command.Command; -import dev.rollczi.litecommands.annotations.context.Context; +import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; -import java.util.List; import org.bukkit.entity.Player; @SuppressWarnings({"unused", "ClassCanBeRecord"}) @@ -23,51 +16,32 @@ @Permission("parcellockers.command.parcel") public class ParcelCommand { - private final LockerRepository lockerRepository; - private final NotificationAnnouncer announcer; - private final PluginConfig config; private final MainGui mainGUI; private final ParcelListGui parcelListGUI; private final ParcelService parcelService; - private final UserManager userManager; public ParcelCommand( - LockerRepository lockerRepository, - NotificationAnnouncer announcer, - PluginConfig config, MainGui mainGUI, ParcelListGui parcelListGUI, - ParcelService parcelService, - UserManager userManager + ParcelService parcelService ) { - this.lockerRepository = lockerRepository; - this.announcer = announcer; - this.config = config; this.mainGUI = mainGUI; this.parcelListGUI = parcelListGUI; this.parcelService = parcelService; - this.userManager = userManager; } @Execute(name = "list") - void list(@Context Player player) { + void list(@Sender Player player) { this.parcelListGUI.show(player); } - @Async - @Execute(name = "info") - void info(@Context Player player, @Arg Parcel parcel) { - List messagesToSend = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, this.config.messages.parcelInfoMessages, this.userManager, this.lockerRepository); - messagesToSend.forEach(message -> this.announcer.sendMessage(player, message)); - } - @Execute(name = "delete") - void delete(@Context Player player, @Arg Parcel parcel) { + void delete(@Sender Player player, @Arg Parcel parcel) { this.parcelService.remove(player, parcel); } @Execute(name = "gui") - void gui(@Context Player player) { + void gui(@Sender Player player) { this.mainGUI.show(player); } } From 883856c8cf52545544eb38f193cbed8d2ff31c1d Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 18:26:55 +0200 Subject: [PATCH 09/51] update gradle config --- .github/workflows/gradle.yml | 4 +- build.gradle.kts | 36 +++++-------- gradle.properties | 7 +-- .../parcellockers/ParcelLockers.java | 54 +++++++++++-------- .../LockerRepositoryIntegrationTest.java | 2 +- .../ParcelRepositoryIntegrationTest.java | 2 +- 6 files changed, 49 insertions(+), 56 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index a851355b9..4e9324064 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -16,7 +16,7 @@ jobs: - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' cache: gradle - uses: actions/cache@v4 @@ -34,5 +34,5 @@ jobs: - name: Upload a Build Artifact uses: actions/upload-artifact@v4.6.2 with: - name: 'ParcelLockers (MC 1.8.8 - 1.20.x)' + name: 'ParcelLockers' path: build/libs/ParcelLockers* \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 357dd8080..773b72fbc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { `java-library` - id("net.minecrell.plugin-yml.bukkit") version "0.6.0" - id("xyz.jpenilla.run-paper") version "2.3.1" + id("de.eldoria.plugin-yml.bukkit") version "0.7.1" + id("xyz.jpenilla.run-paper") version "3.0.0-beta.1" id("com.gradleup.shadow") version "9.0.2" } @@ -24,9 +24,7 @@ repositories { dependencies { // minecraft development api - compileOnly("org.spigotmc:spigot-api:1.21.5-R0.1-SNAPSHOT") - implementation("net.kyori:adventure-platform-bukkit:4.4.1") - implementation("net.kyori:adventure-text-minimessage:4.24.0") + compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT") implementation("dev.rollczi:litecommands-bukkit:3.10.4") implementation("dev.rollczi:litecommands-adventure:3.10.4") @@ -64,9 +62,6 @@ dependencies { // jetbrains annotations api("org.jetbrains:annotations:26.0.2") - // paperlib - implementation("io.papermc:paperlib:1.0.8") - // panda-utilities implementation("org.panda-lang:panda-utilities:0.5.2-alpha") @@ -76,13 +71,13 @@ dependencies { // completable-futures implementation("com.spotify:completable-futures:0.3.6") - // eternalcode-commons + // eternalcode commons implementation("com.eternalcode:eternalcode-commons-adventure:1.3.0") implementation("com.eternalcode:eternalcode-commons-bukkit:1.3.0") - // notification library + // multification implementation("com.eternalcode:multification-bukkit:1.2.2") - implementation("com.eternalcode:multification-okaeri:1.1.4") + implementation("com.eternalcode:multification-okaeri:1.2.2") // caffeine implementation("com.github.ben-manes.caffeine:caffeine:3.2.2") @@ -102,14 +97,14 @@ java { } bukkit { - main = "com.eternalcode.parcellockers.ParcelLockers" - apiVersion = "1.13" - prefix = "ParcelLockers" - author = "EternalCodeTeam" name = "ParcelLockers" + main = "com.eternalcode.parcellockers.ParcelLockers" + version = project.version.toString() + apiVersion = "1.21" description = project.description + author = "EternalCodeTeam" website = "https://github.com/EternalCodeTeam/ParcelLockers" - version = project.version.toString() + } tasks.withType { @@ -121,14 +116,7 @@ tasks.withType { tasks { runServer { - minecraftVersion("1.21.5") - } - - clean { - doLast { - project.file("run/plugins").deleteRecursively() - project.file("run/logs").deleteRecursively() - } + minecraftVersion("1.21.8") } test { diff --git a/gradle.properties b/gradle.properties index 196e28259..581d5b712 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,4 @@ -org.gradle.daemon=true -org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=2048m org.gradle.parallel=true -org.gradle.workers.max=8 org.gradle.caching=true -#org.gradle.configuration-cache=true -org.gradle.vfs.watch=true \ No newline at end of file +org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true \ No newline at end of file diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 129ebc92b..14d3a6e60 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -51,8 +51,6 @@ import dev.rollczi.litecommands.bukkit.LiteBukkitMessages; import dev.rollczi.liteskullapi.LiteSkullFactory; import dev.rollczi.liteskullapi.SkullAPI; -import io.papermc.lib.PaperLib; -import io.papermc.lib.environments.Environment; import java.io.File; import java.sql.SQLException; import java.time.Duration; @@ -60,7 +58,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Stream; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -81,8 +78,6 @@ public final class ParcelLockers extends JavaPlugin { public void onEnable() { Stopwatch started = Stopwatch.createStarted(); - this.softwareCheck(); - this.audiences = BukkitAudiences.create(this); MiniMessage miniMessage = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) @@ -91,8 +86,7 @@ public void onEnable() { ConfigService configManager = new ConfigService(); PluginConfig config = configManager.create(PluginConfig.class, new File(this.getDataFolder(), "config.yml")); - MessageConfig - messageConfig = configManager.create(MessageConfig.class, new File(this.getDataFolder(), "messages.yml")); + MessageConfig messageConfig = configManager.create(MessageConfig.class, new File(this.getDataFolder(), "messages.yml")); Server server = this.getServer(); NoticeService noticeService = new NoticeService(messageConfig, miniMessage, this.audiences); Scheduler scheduler = new BukkitSchedulerImpl(this); @@ -133,10 +127,23 @@ public void onEnable() { UserRepository userRepository = new UserRepositoryOrmLite(databaseManager, scheduler); UserManager userManager = new UserManagerImpl(userRepository); - MainGui mainGUI = new MainGui(scheduler, miniMessage, config, parcelRepository, lockerRepository, - userManager); - ParcelListGui parcelListGUI = new ParcelListGui(scheduler, miniMessage, config, parcelRepository, lockerRepository, - userManager, mainGUI); + MainGui mainGUI = new MainGui( + scheduler, + miniMessage, + config, + parcelRepository, + lockerRepository, + userManager + ); + ParcelListGui parcelListGUI = new ParcelListGui( + scheduler, + miniMessage, + config, + parcelRepository, + lockerRepository, + userManager, + mainGUI + ); this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .argument(Parcel.class, new ParcelArgument(parcelCache)) @@ -153,8 +160,19 @@ public void onEnable() { .missingPermission(new MissingPermissionsHandlerImpl(noticeService)) .build(); - LockerMainGui lockerMainGUI = new LockerMainGui(miniMessage, scheduler, config, itemStorageRepository, parcelRepository, lockerRepository, noticeService, parcelContentRepository, userRepository, this.skullAPI, - parcelService); + LockerMainGui lockerMainGUI = new LockerMainGui( + miniMessage, + scheduler, + config, + itemStorageRepository, + parcelRepository, + lockerRepository, + noticeService, + parcelContentRepository, + userRepository, + this.skullAPI, + parcelService + ); Stream.of( new LockerInteractionController(lockerCache, lockerMainGUI), @@ -205,16 +223,6 @@ public void onDisable() { this.skullAPI.shutdown(); } - - private void softwareCheck() { - Logger logger = this.getLogger(); - Environment environment = PaperLib.getEnvironment(); - - if (!environment.isPaper()) { - logger.warning("Your server running on unsupported software, please use Paper or its forks"); - logger.warning("You can easily download Paper from https://papermc.io/downloads"); - } - } } diff --git a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java index 63ccd4385..a118060ea 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java @@ -40,7 +40,7 @@ class LockerRepositoryIntegrationTest extends IntegrationTestSpec { @Test void test() { File dataFolder = tempDir.resolve("ParcelLockers").toFile(); - PluginConfig config = new ConfigService(dataFolder).load(new PluginConfig()); + PluginConfig config = new ConfigService().create(PluginConfig.class, new File(dataFolder, "config.yml")); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; LockerCache cache = new LockerCache(); diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index 0225ee61d..81f3b7217 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -43,7 +43,7 @@ class ParcelRepositoryIntegrationTest extends IntegrationTestSpec { @Test void test() { File dataFolder = tempDir.resolve("ParcelLockers").toFile(); - PluginConfig config = new ConfigService(dataFolder).load(new PluginConfig()); + PluginConfig config = new ConfigService().create(PluginConfig.class, new File(dataFolder, "config.yml")); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; ParcelCache cache = new ParcelCache(); From 06048c4d00e6c91581eea5a99bc83eed158f199e Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:53:03 +0200 Subject: [PATCH 10/51] continue refactoring --- .github/workflows/gradle.yml | 4 +- build.gradle.kts | 88 +++++++----------- .../parcellockers/ParcelLockers.java | 11 +-- .../ParcelLockersLibraryLoader.java | 47 ++++++++++ .../configuration/ConfigService.java | 6 +- .../implementation/MessageConfig.java | 90 ++++++++++++------- .../implementation/PluginConfig.java | 12 ++- .../serializable/ConfigItem.java | 10 +-- .../PositionTransformer.java | 2 +- .../transformer/SoundTransformer.java | 26 ++++++ .../wrapper/AbstractRepositoryOrmLite.java | 2 +- .../locker/ParcelItemStorageGui.java | 2 +- .../locker/ParcelSendingGui.java | 14 +-- .../gui/implementation/remote/MainGui.java | 1 - .../controller/LockerBreakController.java | 6 +- .../LockerInteractionController.java | 9 +- .../controller/LockerPlaceController.java | 6 +- .../locker/repository/LockerCache.java | 5 +- .../notification/NoticeService.java | 14 +-- .../notification/NotificationAnnouncer.java | 64 ------------- .../notification/NotificationType.java | 11 --- .../parcel/ParcelServiceImpl.java | 16 ++-- .../parcel/util/ParcelPlaceholderUtil.java | 2 +- .../UpdaterNotificationController.java | 20 ++--- .../parcellockers/updater/UpdaterService.java | 5 +- 25 files changed, 230 insertions(+), 243 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java rename src/main/java/com/eternalcode/parcellockers/configuration/{composer => transformer}/PositionTransformer.java (92%) create mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 4e9324064..01707dac0 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -8,9 +8,7 @@ on: jobs: build: - runs-on: ubuntu-latest - steps: - uses: actions/checkout@v5 - name: Set up JDK 17 @@ -30,7 +28,7 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew clean shadowJar + run: ./gradlew shadowJar - name: Upload a Build Artifact uses: actions/upload-artifact@v4.6.2 with: diff --git a/build.gradle.kts b/build.gradle.kts index 773b72fbc..004afcdfd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,19 +1,19 @@ plugins { `java-library` - id("de.eldoria.plugin-yml.bukkit") version "0.7.1" + id("de.eldoria.plugin-yml.paper") version "0.7.1" id("xyz.jpenilla.run-paper") version "3.0.0-beta.1" id("com.gradleup.shadow") version "9.0.2" } group = "com.eternalcode" version = "0.0.2-SNAPSHOT" -description = "Plugin that provides functionality of parcel lockers in Minecraft, allowing players to send and receive parcels safely." repositories { gradlePluginPortal() - mavenCentral() + maven { url = uri("https://maven-central.storage-download.googleapis.com/maven2/")} maven { url = uri("https://repo.panda-lang.org/releases") } + maven { url = uri("https://repo.triumphteam.dev/snapshots/")} maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") } maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } maven { url = uri("https://oss.sonatype.org/content/repositories/central") } @@ -25,62 +25,57 @@ repositories { dependencies { // minecraft development api compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT") - implementation("dev.rollczi:litecommands-bukkit:3.10.4") - implementation("dev.rollczi:litecommands-adventure:3.10.4") + paperLibrary("dev.rollczi:litecommands-bukkit:3.10.4") + paperLibrary("dev.rollczi:litecommands-adventure:3.10.4") // skull api - implementation("dev.rollczi:liteskullapi:2.0.0") + paperLibrary("dev.rollczi:liteskullapi:2.0.0") // gui - implementation("dev.triumphteam:triumph-gui:3.1.12") - implementation("de.rapha149.signgui:signgui:2.5.4") + implementation("dev.triumphteam:triumph-gui-paper:3.1.13-SNAPSHOT") + paperLibrary("de.rapha149.signgui:signgui:2.5.4") // configs - implementation("eu.okaeri:okaeri-configs-serdes-commons:5.0.9") - implementation("eu.okaeri:okaeri-configs-serdes-bukkit:5.0.9") - implementation("eu.okaeri:okaeri-configs-yaml-bukkit:5.0.9") - - // expressible - implementation("org.panda-lang:expressible:1.3.6") + paperLibrary("eu.okaeri:okaeri-configs-serdes-commons:5.0.9") + paperLibrary("eu.okaeri:okaeri-configs-serdes-bukkit:5.0.9") + paperLibrary("eu.okaeri:okaeri-configs-yaml-bukkit:5.0.9") // gitcheck - implementation("com.eternalcode:gitcheck:1.0.0") + paperLibrary("com.eternalcode:gitcheck:1.0.0") // metrics and sentry implementation("org.bstats:bstats-bukkit:3.1.0") // database - implementation("com.zaxxer:HikariCP:7.0.1") - implementation("com.j256.ormlite:ormlite-jdbc:6.1") - implementation("com.h2database:h2:2.3.232") - implementation("org.postgresql:postgresql:42.7.7") + paperLibrary("com.zaxxer:HikariCP:7.0.1") + paperLibrary("com.j256.ormlite:ormlite-jdbc:6.1") + paperLibrary("com.h2database:h2:2.3.232") + paperLibrary("org.postgresql:postgresql:42.7.7") // lombok compileOnly("org.projectlombok:lombok:1.18.38") annotationProcessor("org.projectlombok:lombok:1.18.38") // jetbrains annotations - api("org.jetbrains:annotations:26.0.2") - - // panda-utilities - implementation("org.panda-lang:panda-utilities:0.5.2-alpha") + paperLibrary("org.jetbrains:annotations:26.0.2") // jackson-bukkit - implementation("de.eldoria.jacksonbukkit:paper:1.2.0") + paperLibrary("de.eldoria.jacksonbukkit:paper:1.2.0") // completable-futures - implementation("com.spotify:completable-futures:0.3.6") + paperLibrary("com.spotify:completable-futures:0.3.6") // eternalcode commons - implementation("com.eternalcode:eternalcode-commons-adventure:1.3.0") - implementation("com.eternalcode:eternalcode-commons-bukkit:1.3.0") + paperLibrary("com.eternalcode:eternalcode-commons-adventure:1.3.0") + paperLibrary("com.eternalcode:eternalcode-commons-bukkit:1.3.0") + paperLibrary("com.eternalcode:eternalcode-commons-shared:1.3.0") // multification - implementation("com.eternalcode:multification-bukkit:1.2.2") - implementation("com.eternalcode:multification-okaeri:1.2.2") + paperLibrary("com.eternalcode:multification-bukkit:1.2.2") + paperLibrary("com.eternalcode:multification-okaeri:1.2.2") // caffeine - implementation("com.github.ben-manes.caffeine:caffeine:3.2.2") + paperLibrary("com.github.ben-manes.caffeine:caffeine:3.2.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.4") testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.4") @@ -96,15 +91,15 @@ java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } -bukkit { +paper { name = "ParcelLockers" main = "com.eternalcode.parcellockers.ParcelLockers" version = project.version.toString() apiVersion = "1.21" - description = project.description author = "EternalCodeTeam" website = "https://github.com/EternalCodeTeam/ParcelLockers" - + loader = "com.eternalcode.parcellockers.ParcelLockersLibraryLoader" + generateLibrariesJson = true } tasks.withType { @@ -117,6 +112,7 @@ tasks.withType { tasks { runServer { minecraftVersion("1.21.8") + downloadPlugins.modrinth("luckperms", "v5.5.0-bukkit") } test { @@ -129,37 +125,15 @@ tasks { exclude( "org/intellij/lang/annotations/**", "org/jetbrains/annotations/**", - "META-INF/**", - "javax/**", - "javassist/**", - "org/h2/util/**" + "META-INF/**" ) mergeServiceFiles() - minimize { - exclude(dependency("de\\.rapha149\\.signgui:signgui:.*")) // https://github.com/Rapha149/SignGUI/issues/15 - } val relocationPrefix = "com.eternalcode.parcellockers.libs" listOf( - "panda", "org.bstats", - "org.json", - "org.postgresql", - "eu.okaeri", - "net.kyori", - "io.papermc", - "io.sentry", - "dev.rollczi", - "de.eldoria", - "com.eternalcode", - "com.fasterxml", - "com.j256", - "com.spotify", - "com.zaxxer", - "de.rapha149", - "dev.triumphteam", - "com.github.benmanes.caffeine" + "dev.triumphteam" ).forEach { relocate(it, "$relocationPrefix.$it") } } } diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 14d3a6e60..416b3e0a5 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -59,7 +59,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.stream.Stream; -import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bstats.bukkit.Metrics; import org.bukkit.Server; @@ -69,7 +68,6 @@ public final class ParcelLockers extends JavaPlugin { private LiteCommands liteCommands; - private BukkitAudiences audiences; private SkullAPI skullAPI; private DatabaseManager databaseManager; @@ -78,7 +76,6 @@ public final class ParcelLockers extends JavaPlugin { public void onEnable() { Stopwatch started = Stopwatch.createStarted(); - this.audiences = BukkitAudiences.create(this); MiniMessage miniMessage = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) @@ -88,7 +85,7 @@ public void onEnable() { PluginConfig config = configManager.create(PluginConfig.class, new File(this.getDataFolder(), "config.yml")); MessageConfig messageConfig = configManager.create(MessageConfig.class, new File(this.getDataFolder(), "messages.yml")); Server server = this.getServer(); - NoticeService noticeService = new NoticeService(messageConfig, miniMessage, this.audiences); + NoticeService noticeService = new NoticeService(messageConfig, miniMessage); Scheduler scheduler = new BukkitSchedulerImpl(this); DatabaseManager databaseManager = new DatabaseManager(config, this.getLogger(), this.getDataFolder()); @@ -217,11 +214,9 @@ public void onDisable() { this.liteCommands.unregister(); } - if (this.audiences != null) { - this.audiences.close(); + if (this.skullAPI != null) { + this.skullAPI.shutdown(); } - - this.skullAPI.shutdown(); } } diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java new file mode 100644 index 000000000..a4576a33f --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java @@ -0,0 +1,47 @@ +package com.eternalcode.parcellockers; + +import com.google.gson.Gson; +import io.papermc.paper.plugin.loader.PluginClasspathBuilder; +import io.papermc.paper.plugin.loader.PluginLoader; +import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.repository.RemoteRepository; +import org.jetbrains.annotations.NotNull; + +public class ParcelLockersLibraryLoader implements PluginLoader { + @Override + public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) { + MavenLibraryResolver resolver = new MavenLibraryResolver(); + PluginLibraries pluginLibraries = load(); + pluginLibraries.asDependencies().forEach(resolver::addDependency); + pluginLibraries.asRepositories().forEach(resolver::addRepository); + classpathBuilder.addLibrary(resolver); + } + + public PluginLibraries load() { + try (var in = getClass().getResourceAsStream("/paper-libraries.json")) { + return new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), PluginLibraries.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private record PluginLibraries(Map repositories, List dependencies) { + public Stream asDependencies() { + return dependencies.stream() + .map(d -> new Dependency(new DefaultArtifact(d), null)); + } + + public Stream asRepositories() { + return repositories.entrySet().stream() + .map(e -> new RemoteRepository.Builder(e.getKey(), "default", e.getValue()).build()); + } + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java index fc5135b67..81f6150d3 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java @@ -4,6 +4,7 @@ import com.eternalcode.multification.notice.resolver.NoticeResolverDefaults; import com.eternalcode.multification.notice.resolver.NoticeResolverRegistry; import com.eternalcode.multification.okaeri.MultificationSerdesPack; +import com.eternalcode.parcellockers.configuration.transformer.SoundTransformer; import eu.okaeri.configs.ConfigManager; import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.serdes.OkaeriSerdesPack; @@ -14,6 +15,7 @@ import java.io.File; import java.util.HashSet; import java.util.Set; +import lombok.NonNull; public class ConfigService { @@ -51,8 +53,8 @@ public void reload() { private static class DefaultSerdesPack implements OkaeriSerdesPack { @Override - public void register(SerdesRegistry config) { - + public void register(@NonNull SerdesRegistry registry) { + registry.register(new SoundTransformer()); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index bc06f849d..1a54b0779 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -3,46 +3,68 @@ import com.eternalcode.multification.notice.Notice; import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.annotation.Comment; +import eu.okaeri.configs.annotation.Header; +@Header({ + " ", + "# This file contains messages used by the ParcelLockers plugin.", + "# You can customize these messages to fit your server's theme or language.", + " ", +}) public class MessageConfig extends OkaeriConfig { + @Comment({" ", "# Messages related to general commands can be configured here." }) public Notice playerOnlyCommand = Notice.chat("&4โœ˜ &cThis command is only available to players!"); public Notice noPermission = Notice.chat("&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"); public Notice playerNotFound = Notice.chat("&4โœ˜ &cThe specified player could not be found!"); public Notice invalidUsage = Notice.chat("&4โฃ &cCorrect usage: &6{USAGE}"); public Notice reload = Notice.chat("&3โฃ &bConfiguration has been successfully reloaded!"); - public Notice parcelSuccessfullyDeleted = Notice.chat("&2โœ” &aParcel deleted successfully."); - public Notice failedToDeleteParcel = Notice.chat("&4โœ˜ &cAn error occurred while deleting the parcel."); - public Notice failedToCreateParcelLocker = Notice.chat("&4โœ˜ &cCould not create the parcel locker."); - public Notice parcelLockerSuccessfullyCreated = Notice.chat("&7ยป &aParcel locker created successfully."); - public Notice enterDescriptionPrompt = Notice.chat("&6โ†ต &eEnter a description for the parcel locker:"); - public Notice cannotBreakParcelLocker = Notice.chat("&4โœ˜ &cYou have no permission to break the parcel locker."); - public Notice parcelLockerSuccessfullyDeleted = Notice.chat("&2โœ” &aParcel locker deleted successfully."); - public Notice broadcastParcelLockerRemoved = Notice.chat("&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"); - public Notice parcelSent = Notice.chat("&2โœ” &aParcel sent successfully."); - public Notice parcelFailedToSend = Notice.chat("&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."); - public Notice illegalItemFailedToSend = Notice.chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"); - public Notice parcelCannotBeEmpty = Notice.chat("&4โœ˜ &cThe parcel cannot be empty!"); - public Notice parcelNameCannotBeEmpty = Notice.chat("&4โœ˜ &cThe parcel name cannot be empty!"); - public Notice parcelNameSet = Notice.chat("&2โœ” &aParcel name set successfully."); - public Notice parcelDescriptionSet = Notice.chat("&2โœ” &aParcel description set successfully."); - public Notice parcelReceiverSet = Notice.chat("&2โœ” &aParcel receiver set successfully."); - public Notice parcelDestinationSet = Notice.chat("&2โœ” &aParcel destination locker set successfully."); - public Notice alreadyCreatingLocker = Notice.chat("&4โœ˜ &cYou are already creating a parcel locker!"); - public Notice receiverNotSet = Notice.chat("&4โœ˜ &cThe parcel receiver is not set!"); - public Notice parcelSuccessfullyCollected = Notice.chat("&2โœ” &aParcel collected successfully."); - public Notice failedToCollectParcel = Notice.chat("&4โœ˜ &cAn error occurred while collecting the parcel."); - public Notice notEnoughInventorySpace = Notice.chat("&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"); - - @Comment({" ", "# The parcel info message." }) - public Notice parcelInfoMessages = Notice.chat( - "&7ยป &6Parcel info:", - "&fโ€ข &6UUID: &e{UUID}", - "&fโ€ข &6Sender: &e{SENDER}", - "&fโ€ข &6Receiver: &e{RECEIVER}", - "&fโ€ข &6Size: &e{SIZE}", - "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", - "&fโ€ข &6Priority: &e{PRIORITY}", - "&fโ€ข &6Description: &e{DESCRIPTION}" - ); + + @Comment({" ", "# Messages related to parcels can be configured here." }) + @Comment({" ", "# These messages are used when sending, collecting, or managing parcels."}) + public ParcelMessages parcel = new ParcelMessages(); + + @Comment({" ", "# Messages related to parcel lockers can be configured here." }) + @Comment({" ", "# These messages are used when creating, deleting, or managing parcel lockers."}) + public LockerMessages locker = new LockerMessages(); + + public static class ParcelMessages extends OkaeriConfig { + public Notice sent = Notice.chat("&2โœ” &aParcel sent successfully."); + public Notice cannotSend = Notice.chat("&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."); + public Notice emptyName = Notice.chat("&4โœ˜ &cThe parcel name cannot be empty!"); + public Notice nameSet = Notice.chat("&2โœ” &aParcel name set successfully."); + public Notice empty = Notice.chat("&4โœ˜ &cThe parcel cannot be empty!"); + public Notice receiverSet = Notice.chat("&2โœ” &aParcel receiver set successfully."); + public Notice descriptionSet = Notice.chat("&2โœ” &aParcel description set successfully."); + public Notice destinationSet = Notice.chat("&2โœ” &aParcel destination locker set successfully."); + public Notice cannotCollect = Notice.chat("&4โœ˜ &cAn error occurred while collecting the parcel."); + public Notice noInventorySpace = Notice.chat("&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"); + public Notice collected = Notice.chat("&2โœ” &aParcel collected successfully."); + public Notice receiverNotSet = Notice.chat("&4โœ˜ &cThe parcel receiver is not set!"); + public Notice illegalItem = Notice.chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"); + public Notice cannotDelete = Notice.chat("&4โœ˜ &cAn error occurred while deleting the parcel."); + public Notice deleted = Notice.chat("&2โœ” &aParcel deleted successfully."); + + @Comment({" ", "# The parcel info message." }) + public Notice parcelInfoMessages = Notice.chat( + "&7ยป &6Parcel info:", + "&fโ€ข &6UUID: &e{UUID}", + "&fโ€ข &6Sender: &e{SENDER}", + "&fโ€ข &6Receiver: &e{RECEIVER}", + "&fโ€ข &6Size: &e{SIZE}", + "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", + "&fโ€ข &6Priority: &e{PRIORITY}", + "&fโ€ข &6Description: &e{DESCRIPTION}" + ); + } + + public static class LockerMessages extends OkaeriConfig { + public Notice cannotCreate = Notice.chat("&4โœ˜ &cCould not create the parcel locker."); + public Notice created = Notice.chat("&7ยป &aParcel locker created successfully."); + public Notice descriptionPrompt = Notice.chat("&6โ†ต &eEnter a description for the parcel locker:"); + public Notice cannotBreak = Notice.chat("&4โœ˜ &cYou have no permission to break the parcel locker."); + public Notice deleted = Notice.chat("&2โœ” &aParcel locker deleted successfully."); + public Notice broadcastRemoved = Notice.chat("&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"); + public Notice alreadyCreating = Notice.chat("&4โœ˜ &cYou are already creating a parcel locker!"); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index a813f138f..5ad57a0b8 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -4,12 +4,22 @@ import com.eternalcode.parcellockers.database.DatabaseType; import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.annotation.Comment; +import eu.okaeri.configs.annotation.Header; import java.time.Duration; import java.util.Collections; import java.util.List; import org.bukkit.Material; import org.bukkit.Sound; +@Header({ + " ", + "# Parcel Lockers plugin configuration file.", + "#", + "# This file is used to configure the ParcelLockers plugin.", + "# You can change the settings here to customize the plugin behavior.", + "#", + "# If you want to change the settings, you can do it in-game using the /parcellockers reload command." +}) public class PluginConfig extends OkaeriConfig { @Comment({" ", "# Parcel Lockers plugin configuration file." }) @@ -61,8 +71,6 @@ public static class Settings extends OkaeriConfig { @Comment({ " ", "# The sound pitch for the error sound." }) public float errorSoundPitch = 1.0F; - - } public static class GuiSettings extends OkaeriConfig { diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index c802c8a95..70baa33f0 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -6,7 +6,7 @@ import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.components.GuiAction; import dev.triumphteam.gui.guis.GuiItem; -import eu.okaeri.configs.OkaeriConfig; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; import lombok.Getter; @@ -22,9 +22,9 @@ @Getter @Setter @Accessors(fluent = true) -public class ConfigItem extends OkaeriConfig implements Cloneable { +public class ConfigItem implements Serializable, Cloneable { - private static final MiniMessage MINI_MESSAGE = MiniMessage.builder() + private final transient MiniMessage MINI_MESSAGE = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) .build(); @@ -67,10 +67,10 @@ public ItemStack toItemStack() { public ConfigItem clone() { try { ConfigItem cloned = (ConfigItem) super.clone(); - cloned.lore = new ArrayList<>(this.lore); // Deep copy of the list + cloned.lore = new ArrayList<>(this.lore); return cloned; } catch (CloneNotSupportedException e) { - throw new AssertionError("Failed to clone " + this); // Should never happen + throw new AssertionError("Failed to clone " + this); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java b/src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java similarity index 92% rename from src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java rename to src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java index 0c45d16c5..b3f3aa2f7 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/composer/PositionTransformer.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java @@ -1,4 +1,4 @@ -package com.eternalcode.parcellockers.configuration.composer; +package com.eternalcode.parcellockers.configuration.transformer; import com.eternalcode.parcellockers.shared.Position; import eu.okaeri.configs.schema.GenericsPair; diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java b/src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java new file mode 100644 index 000000000..93a99abf6 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java @@ -0,0 +1,26 @@ +package com.eternalcode.parcellockers.configuration.transformer; + +import eu.okaeri.configs.schema.GenericsPair; +import eu.okaeri.configs.serdes.BidirectionalTransformer; +import eu.okaeri.configs.serdes.SerdesContext; +import lombok.NonNull; +import org.bukkit.Sound; +import org.jetbrains.annotations.NotNull; + +public class SoundTransformer extends BidirectionalTransformer { + + @Override + public GenericsPair getPair() { + return this.genericsPair(Sound.class, String.class); + } + + @Override + public String leftToRight(@NotNull Sound data, @NonNull SerdesContext serdesContext) { + return data.name(); + } + + @Override + public Sound rightToLeft(@NonNull String data, @NonNull SerdesContext serdesContext) { + return Sound.valueOf(data); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java index 4a46fee16..bcb1f0d22 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/database/wrapper/AbstractRepositoryOrmLite.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.database.wrapper; +import com.eternalcode.commons.ThrowingFunction; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.database.DatabaseManager; import com.j256.ormlite.dao.Dao; @@ -7,7 +8,6 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; -import panda.std.function.ThrowingFunction; public abstract class AbstractRepositoryOrmLite { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java index 152d1216d..310fa2a5e 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java @@ -125,7 +125,7 @@ void show(Player player, ParcelSize size) { gui.removeItem(item); // player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_AMBIENT, 1, 1); this.noticeService.create() - .notice(messages -> messages.illegalItemFailedToSend) + .notice(messages -> messages.parcel.illegalItem) .placeholder("{ITEMS}", item.getType().name()) .player(player.getUniqueId()) .send(); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java index c0a915709..7e2e84f66 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java @@ -114,7 +114,7 @@ public void show(Player player) { String name = result.getLineWithoutColor(1); if (name.isBlank()) { this.noticeService.create() - .notice(messages -> messages.parcelNameCannotBeEmpty) + .notice(messages -> messages.parcel.emptyName) .player(player.getUniqueId()) .send(); return Collections.emptyList(); @@ -122,7 +122,7 @@ public void show(Player player) { this.state.parcelName(name); this.noticeService.create() - .notice(messages -> messages.parcelNameSet) + .notice(messages -> messages.parcel.nameSet) .player(player.getUniqueId()) .send(); @@ -163,7 +163,7 @@ public void show(Player player) { this.state.parcelDescription(description); this.noticeService.create() - .notice(messages -> messages.parcelDescriptionSet) + .notice(messages -> messages.parcel.descriptionSet) .player(player.getUniqueId()) .send(); @@ -222,7 +222,7 @@ public void show(Player player) { this.itemStorageRepository.find(player.getUniqueId()).thenAccept(result -> { if (result.isEmpty() || result.get().items().isEmpty()) { this.noticeService.create() - .notice(messages -> messages.parcelCannotBeEmpty) + .notice(messages -> messages.parcel.empty) .player(player.getUniqueId()) .send(); // TODO player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); @@ -231,7 +231,7 @@ public void show(Player player) { if (this.state.receiver() == null) { this.noticeService.create() - .notice(messages -> messages.receiverNotSet) + .notice(messages -> messages.parcel.receiverNotSet) .player(player.getUniqueId()) .send(); player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); @@ -367,7 +367,7 @@ public void updateDescriptionItem() { public void updateReceiverItem(Player player, String receiverName) { this.noticeService.create() - .notice(messages -> messages.parcelReceiverSet) + .notice(messages -> messages.parcel.receiverSet) .player(player.getUniqueId()) .send(); @@ -382,7 +382,7 @@ public void updateReceiverItem(Player player, String receiverName) { public void updateDestinationItem(Player player, String destinationLockerDesc) { this.noticeService.create() - .notice(messages -> messages.parcelDestinationSet) + .notice(messages -> messages.parcel.destinationSet) .player(player.getUniqueId()) .send(); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index 96e1760aa..910667c66 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -73,6 +73,5 @@ public void show(Player player) { gui.addSlotAction(22, event -> new SentParcelsGui(this.scheduler, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userManager).show(player)); gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.open(player); - } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java index 4a80fe343..712997430 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java @@ -50,7 +50,7 @@ public void onBlockBreak(BlockBreakEvent event) { event.setCancelled(true); this.noticeService.create() .player(player.getUniqueId()) - .notice(messages -> messages.cannotBreakParcelLocker) + .notice(messages -> messages.locker.cannotBreak) .send(); return; } @@ -65,7 +65,7 @@ public void onBlockBreak(BlockBreakEvent event) { this.noticeService.create() .player(player.getUniqueId()) - .notice(messages -> messages.parcelLockerSuccessfullyDeleted) + .notice(messages -> messages.locker.deleted) .send(); Formatter formatter = new Formatter() @@ -77,7 +77,7 @@ public void onBlockBreak(BlockBreakEvent event) { this.noticeService.create() .player(player.getUniqueId()) - .notice(messages -> messages.parcelLockerSuccessfullyDeleted) + .notice(messages -> messages.locker.deleted) .formatter(formatter) .send(); }); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java index 87ed2f43a..d0bf60a36 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java @@ -5,6 +5,7 @@ import com.eternalcode.parcellockers.shared.Position; import com.eternalcode.parcellockers.shared.PositionAdapter; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -24,16 +25,18 @@ public LockerInteractionController(LockerCache cache, LockerMainGui lockerMainGU @EventHandler public void onInventoryOpen(PlayerInteractEvent event) { Player player = event.getPlayer(); - Position blockPos = PositionAdapter.convert(event.getClickedBlock().getLocation()); + Block block = event.getClickedBlock(); - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + if (block == null || event.getAction() != Action.RIGHT_CLICK_BLOCK) { return; } - if (event.getClickedBlock().getType() != Material.CHEST) { + if (block.getType() != Material.CHEST) { return; } + Position blockPos = PositionAdapter.convert(block.getLocation()); + if (this.cache.get(blockPos).isPresent()) { event.setCancelled(true); this.lockerMainGUI.show(player); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java index c07f206d8..e175d1ce9 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java @@ -83,7 +83,7 @@ public void onBlockPlace(BlockPlaceEvent event) { event.setCancelled(true); this.noticeService.create() .player(player.getUniqueId()) - .notice(messages -> messages.alreadyCreatingLocker) + .notice(messages -> messages.locker.alreadyCreating) .send(); return; } @@ -106,13 +106,13 @@ public void onBlockPlace(BlockPlaceEvent event) { throwable.printStackTrace(); this.noticeService.create() .player(player.getUniqueId()) - .notice(messages -> messages.failedToCreateParcelLocker) + .notice(messages -> messages.locker.cannotCreate) .send(); return; } this.noticeService.create() .player(player.getUniqueId()) - .notice(messages -> messages.parcelLockerSuccessfullyCreated) + .notice(messages -> messages.locker.created) .send(); }); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java index 7230ee4f8..856ae2878 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java @@ -9,11 +9,12 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; +import org.jetbrains.annotations.NotNull; public class LockerCache { - private final Cache cache; - private final Cache positionCache; + private final Cache<@NotNull UUID, Locker> cache; + private final Cache<@NotNull Position, Locker> positionCache; public LockerCache() { this.cache = Caffeine.newBuilder() diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java b/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java index 0b18a7412..072523d6d 100644 --- a/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java +++ b/src/main/java/com/eternalcode/parcellockers/notification/NoticeService.java @@ -4,24 +4,20 @@ import com.eternalcode.multification.bukkit.BukkitMultification; import com.eternalcode.multification.translation.TranslationProvider; import com.eternalcode.parcellockers.configuration.implementation.MessageConfig; -import net.kyori.adventure.platform.AudienceProvider; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.ComponentSerializer; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; public class NoticeService extends BukkitMultification { private final MessageConfig messages; private final MiniMessage miniMessage; - private final AudienceProvider audienceProvider; - public NoticeService(MessageConfig messages, MiniMessage miniMessage, AudienceProvider audienceProvider) { + public NoticeService(MessageConfig messages, MiniMessage miniMessage) { this.messages = messages; this.miniMessage = miniMessage; - this.audienceProvider = audienceProvider; } @Override @@ -31,13 +27,7 @@ public NoticeService(MessageConfig messages, MiniMessage miniMessage, AudiencePr @Override protected @NotNull AudienceConverter audienceConverter() { - return commandSender -> { - if (commandSender instanceof Player player) { - return this.audienceProvider.player(player.getUniqueId()); - } - - return this.audienceProvider.console(); - }; + return commandSender -> commandSender; } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java b/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java deleted file mode 100644 index 796ae317e..000000000 --- a/src/main/java/com/eternalcode/parcellockers/notification/NotificationAnnouncer.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.eternalcode.parcellockers.notification; - -import java.util.Map; -import java.util.function.BiConsumer; -import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.platform.AudienceProvider; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.title.Title; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -@Deprecated -public class NotificationAnnouncer { - - private static final Map> NOTIFICATION_HANDLERS = Map.of( - NotificationType.CHAT, Audience::sendMessage, - NotificationType.ACTION_BAR, Audience::sendActionBar, - NotificationType.TITLE, (audience, component) -> audience.showTitle(Title.title(component, Component.empty())), - NotificationType.SUBTITLE, (audience, component) -> audience.showTitle(Title.title(Component.empty(), component)) - ); - - private final AudienceProvider audienceProvider; - private final MiniMessage miniMessage; - - public NotificationAnnouncer(AudienceProvider audienceProvider, MiniMessage miniMessage) { - this.audienceProvider = audienceProvider; - this.miniMessage = miniMessage; - } - - public void send(CommandSender commandSender, NotificationType notificationType, String text) { - Audience audience = this.audience(commandSender); - Component component = this.miniMessage.deserialize(text); - - BiConsumer handler = NOTIFICATION_HANDLERS.get(notificationType); - - if (handler == null) { - return; - } - - handler.accept(audience, component); - } - - public void sendMessage(CommandSender commandSender, String text) { - Audience audience = this.audience(commandSender); - - audience.sendMessage(this.miniMessage.deserialize(text)); - } - - public void broadcast(String text) { - Audience audience = this.audienceProvider.all(); - Component message = this.miniMessage.deserialize(text); - - audience.sendMessage(message); - } - - private Audience audience(CommandSender sender) { - if (sender instanceof Player player) { - return this.audienceProvider.player(player.getUniqueId()); - } - - return this.audienceProvider.console(); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java b/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java deleted file mode 100644 index 9b58e9b0d..000000000 --- a/src/main/java/com/eternalcode/parcellockers/notification/NotificationType.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.eternalcode.parcellockers.notification; - -@Deprecated -public enum NotificationType { - - ACTION_BAR, - CHAT, - TITLE, - SUBTITLE, - BOSS_BAR -} diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 0d56b46c9..f9fa867ac 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -56,7 +56,7 @@ public boolean send(Player sender, Parcel parcel, List items) { this.parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { if (throwable != null) { this.noticeService.create() - .notice(messages -> messages.parcelFailedToSend) + .notice(messages -> messages.parcel.cannotSend) .player(sender.getUniqueId()) .send(); @@ -64,7 +64,7 @@ public boolean send(Player sender, Parcel parcel, List items) { } this.noticeService.create() - .notice(messages -> messages.parcelSent) + .notice(messages -> messages.parcel.sent) .player(sender.getUniqueId()) .send(); @@ -83,12 +83,12 @@ public void remove(CommandSender sender, Parcel parcel) { this.parcelRepository.remove(parcel) .thenAccept(v -> this.noticeService.create() - .notice(messages -> messages.parcelSuccessfullyDeleted) + .notice(messages -> messages.parcel.deleted) .viewer(sender) .send()) .exceptionally(throwable -> { this.noticeService.create() - .notice(messages -> messages.failedToDeleteParcel) + .notice(messages -> messages.parcel.cannotDelete) .viewer(sender) .send(); return null; @@ -100,7 +100,7 @@ public void collect(Player player, Parcel parcel) { this.parcelContentRepository.find(parcel.uuid()).thenAccept(optional -> { if (optional.isEmpty()) { this.noticeService.create() - .notice(messages -> messages.failedToCollectParcel) + .notice(messages -> messages.parcel.cannotCollect) .player(player.getUniqueId()) .send(); return; @@ -109,7 +109,7 @@ public void collect(Player player, Parcel parcel) { List items = optional.get().items(); if (items.size() > freeSlotsInInventory(player)) { this.noticeService.create() - .notice(messages -> messages.notEnoughInventorySpace) + .notice(messages -> messages.parcel.noInventorySpace) .player(player.getUniqueId()) .send(); return; @@ -122,13 +122,13 @@ public void collect(Player player, Parcel parcel) { .whenComplete((v, throwable) -> { if (throwable != null) { this.noticeService.create() - .notice(messages -> messages.failedToCollectParcel) + .notice(messages -> messages.parcel.cannotCollect) .player(player.getUniqueId()) .send(); return; } this.noticeService.create() - .notice(messages -> messages.parcelSuccessfullyCollected) + .notice(messages -> messages.parcel.collected) .player(player.getUniqueId()) .send(); }); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java index f5b13b070..d11e1cf40 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.parcel.util; +import com.eternalcode.multification.shared.Formatter; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; @@ -12,7 +13,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.Blocking; -import panda.utilities.text.Formatter; public class ParcelPlaceholderUtil { diff --git a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java index 92f9fadee..4d4fd3996 100644 --- a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java +++ b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterNotificationController.java @@ -1,11 +1,10 @@ package com.eternalcode.parcellockers.updater; +import com.eternalcode.multification.notice.Notice; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.notification.NoticeService; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.platform.AudienceProvider; -import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -17,25 +16,21 @@ public class UpdaterNotificationController implements Listener { private final UpdaterService updaterService; private final PluginConfig pluginConfig; - private final AudienceProvider audienceProvider; - private final MiniMessage miniMessage; + private final NoticeService noticeService; public UpdaterNotificationController( UpdaterService updaterService, PluginConfig pluginConfig, - AudienceProvider audienceProvider, - MiniMessage miniMessage + NoticeService noticeService ) { this.updaterService = updaterService; this.pluginConfig = pluginConfig; - this.audienceProvider = audienceProvider; - this.miniMessage = miniMessage; + this.noticeService = noticeService; } @EventHandler void onJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - Audience audience = this.audienceProvider.player(player.getUniqueId()); if (!player.hasPermission("parcellockers.receiveupdates") || !this.pluginConfig.settings.receiveUpdates) { return; @@ -45,7 +40,10 @@ void onJoin(PlayerJoinEvent event) { upToDate.thenAccept(isUpToDate -> { if (!isUpToDate) { - audience.sendMessage(this.miniMessage.deserialize(NEW_VERSION_AVAILABLE)); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(Notice.chat(NEW_VERSION_AVAILABLE)) + .send(); } }).orTimeout(5, TimeUnit.SECONDS); } diff --git a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java index e724d6e6a..713a5d112 100644 --- a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java +++ b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java @@ -1,13 +1,12 @@ package com.eternalcode.parcellockers.updater; +import com.eternalcode.commons.Lazy; import com.eternalcode.gitcheck.GitCheck; import com.eternalcode.gitcheck.GitCheckResult; import com.eternalcode.gitcheck.git.GitRepository; import com.eternalcode.gitcheck.git.GitTag; -import org.bukkit.plugin.PluginDescriptionFile; -import panda.std.Lazy; - import java.util.concurrent.CompletableFuture; +import org.bukkit.plugin.PluginDescriptionFile; public class UpdaterService { From ce4dcdfd4b1bdd466e1a05da46ee79c68ae7bbf7 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:54:23 +0200 Subject: [PATCH 11/51] ItemBuilder -> PaperItemBuilder --- .../configuration/serializable/ConfigItem.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index 70baa33f0..4ebc1b76a 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -3,7 +3,7 @@ import com.eternalcode.commons.adventure.AdventureLegacyColorPostProcessor; import com.eternalcode.commons.adventure.AdventureLegacyColorPreProcessor; import com.eternalcode.commons.adventure.AdventureUtil; -import dev.triumphteam.gui.builder.item.ItemBuilder; +import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.components.GuiAction; import dev.triumphteam.gui.guis.GuiItem; import java.io.Serializable; @@ -35,7 +35,7 @@ public class ConfigItem implements Serializable, Cloneable { private boolean glow = false; public GuiItem toGuiItem(GuiAction action) { - return ItemBuilder.from(this.type) + return PaperItemBuilder.from(this.type) .name(AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(this.name))) .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ATTRIBUTES) @@ -45,8 +45,8 @@ public GuiItem toGuiItem(GuiAction action) { .asGuiItem(action); } - public @NotNull ItemBuilder toBuilder() { - return ItemBuilder.from(this.type) + public @NotNull PaperItemBuilder toBuilder() { + return PaperItemBuilder.from(this.type) .name(AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(this.name))) .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ATTRIBUTES) From 4e3fac2ab9359f0cfb3a18f318cd3351d03b8841 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:56:59 +0200 Subject: [PATCH 12/51] ItemBuilder -> PaperItemBuilder --- .../gui/implementation/remote/ParcelListGui.java | 4 ++-- .../gui/implementation/remote/SentParcelsGui.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index b6f101f3a..e647e379e 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -12,7 +12,7 @@ import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.user.UserManager; -import dev.triumphteam.gui.builder.item.ItemBuilder; +import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; @@ -86,7 +86,7 @@ private void show(Player player, Page page) { ConfigItem item = this.config.guiSettings.parcelItem; for (Parcel parcel : result.parcels()) { - ItemBuilder parcelItem = item.toBuilder(); + PaperItemBuilder parcelItem = item.toBuilder(); List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.userManager, this.lockerRepository).stream() .map(line -> resetItalic(this.miniMessage.deserialize(line))) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 51edc2da3..f979951ae 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -9,7 +9,7 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; import com.eternalcode.parcellockers.user.UserManager; -import dev.triumphteam.gui.builder.item.ItemBuilder; +import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; @@ -75,7 +75,7 @@ public void show(Player player) { List parcels = optionalParcels.orElse(Collections.emptyList()); for (Parcel parcel : parcels) { - ItemBuilder item = parcelItem.toBuilder(); + PaperItemBuilder item = parcelItem.toBuilder(); List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore(), this.userManager, this.lockerRepository) .stream() From f9a53ef1cd6441cb222ddefade06614614475de5 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Fri, 22 Aug 2025 19:11:24 +0200 Subject: [PATCH 13/51] Refactor --- build.gradle.kts | 1 + .../implementation/MessageConfig.java | 30 +++-- .../implementation/PluginConfig.java | 124 +++++++++--------- .../implementation/locker/LockerMainGui.java | 2 - .../locker/ParcelCollectionGui.java | 1 - .../locker/ParcelItemStorageGui.java | 3 +- .../parcel/util/ParcelPlaceholderUtil.java | 3 +- .../parcellockers/util/ItemSerdesUtil.java | 55 -------- .../parcellockers/util/MaterialUtil.java | 15 +++ 9 files changed, 103 insertions(+), 131 deletions(-) delete mode 100644 src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java create mode 100644 src/main/java/com/eternalcode/parcellockers/util/MaterialUtil.java diff --git a/build.gradle.kts b/build.gradle.kts index 004afcdfd..da1edc7fa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -85,6 +85,7 @@ dependencies { testImplementation("org.testcontainers:junit-jupiter:1.21.3") testImplementation("org.testcontainers:mysql:1.21.3") testImplementation("mysql:mysql-connector-java:8.0.33") + testImplementation("com.eternalcode:eternalcode-commons-shared:1.3.0") } java { diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 1a54b0779..4bf5ac795 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -4,7 +4,9 @@ import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.annotation.Comment; import eu.okaeri.configs.annotation.Header; +import org.bukkit.Sound; +@SuppressWarnings("ALL") @Header({ " ", "# This file contains messages used by the ParcelLockers plugin.", @@ -13,23 +15,27 @@ }) public class MessageConfig extends OkaeriConfig { - @Comment({" ", "# Messages related to general commands can be configured here." }) + @Comment({"", "# Messages related to general commands can be configured here." }) public Notice playerOnlyCommand = Notice.chat("&4โœ˜ &cThis command is only available to players!"); public Notice noPermission = Notice.chat("&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"); public Notice playerNotFound = Notice.chat("&4โœ˜ &cThe specified player could not be found!"); public Notice invalidUsage = Notice.chat("&4โฃ &cCorrect usage: &6{USAGE}"); public Notice reload = Notice.chat("&3โฃ &bConfiguration has been successfully reloaded!"); - @Comment({" ", "# Messages related to parcels can be configured here." }) - @Comment({" ", "# These messages are used when sending, collecting, or managing parcels."}) + @Comment({"", "# Messages related to parcels can be configured here." }) + @Comment("# These messages are used when sending, collecting, or managing parcels.") public ParcelMessages parcel = new ParcelMessages(); - @Comment({" ", "# Messages related to parcel lockers can be configured here." }) - @Comment({" ", "# These messages are used when creating, deleting, or managing parcel lockers."}) + @Comment({"", "# Messages related to parcel lockers can be configured here." }) + @Comment("# These messages are used when creating, deleting, or managing parcel lockers.") public LockerMessages locker = new LockerMessages(); public static class ParcelMessages extends OkaeriConfig { - public Notice sent = Notice.chat("&2โœ” &aParcel sent successfully."); + public Notice sent = Notice.builder() + .chat("&2โœ” &aParcel sent successfully.") + .sound(Sound.ENTITY_ITEM_PICKUP.key()) + .build(); + public Notice cannotSend = Notice.chat("&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."); public Notice emptyName = Notice.chat("&4โœ˜ &cThe parcel name cannot be empty!"); public Notice nameSet = Notice.chat("&2โœ” &aParcel name set successfully."); @@ -39,13 +45,19 @@ public static class ParcelMessages extends OkaeriConfig { public Notice destinationSet = Notice.chat("&2โœ” &aParcel destination locker set successfully."); public Notice cannotCollect = Notice.chat("&4โœ˜ &cAn error occurred while collecting the parcel."); public Notice noInventorySpace = Notice.chat("&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"); - public Notice collected = Notice.chat("&2โœ” &aParcel collected successfully."); - public Notice receiverNotSet = Notice.chat("&4โœ˜ &cThe parcel receiver is not set!"); + public Notice collected = Notice.builder() + .chat("&2โœ” &aParcel collected successfully.") + .sound("ENTITY_PLAYER_LEVELUP") + .build(); + public Notice receiverNotSet = Notice.builder() + .chat("&4โœ˜ &cThe parcel receiver is not set!") + .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) + .build(); public Notice illegalItem = Notice.chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"); public Notice cannotDelete = Notice.chat("&4โœ˜ &cAn error occurred while deleting the parcel."); public Notice deleted = Notice.chat("&2โœ” &aParcel deleted successfully."); - @Comment({" ", "# The parcel info message." }) + @Comment({"", "# The parcel info message." }) public Notice parcelInfoMessages = Notice.chat( "&7ยป &6Parcel info:", "&fโ€ข &6UUID: &e{UUID}", diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 5ad57a0b8..2bb48c148 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -22,188 +22,188 @@ }) public class PluginConfig extends OkaeriConfig { - @Comment({" ", "# Parcel Lockers plugin configuration file." }) + @Comment({"", "# Parcel Lockers plugin configuration file." }) public Settings settings = new Settings(); - @Comment({ " ", "# The plugin GUI settings." }) + @Comment({ "", "# The plugin GUI settings." }) public GuiSettings guiSettings = new GuiSettings(); public static class Settings extends OkaeriConfig { - @Comment({ " ", "# Whether the player after entering the server should receive information about the new version of the plugin?" }) + @Comment({ "", "# Whether the player after entering the server should receive information about the new version of the plugin?" }) public boolean receiveUpdates = true; - @Comment({ " ", "# The database type. (MYSQL, SQLITE)" }) + @Comment({ "", "# The database type. (MYSQL, SQLITE)" }) public DatabaseType databaseType = DatabaseType.SQLITE; - @Comment({ " ", "# The URL to the database." }) + @Comment({ "", "# The URL to the database." }) public String host = "localhost"; - @Comment({ " ", "# The database name." }) + @Comment({ "", "# The database name." }) public String databaseName = "parcellockers"; - @Comment({ " ", "# The database user." }) + @Comment({ "", "# The database user." }) public String user = "root"; - @Comment({ " ", "# The database port." }) + @Comment({ "", "# The database port." }) public String port = "3306"; - @Comment({ " ", "# The database password." }) + @Comment({ "", "# The database password." }) public String password = ""; - @Comment({ " ", "# The parcel locker item." }) + @Comment({ "", "# The parcel locker item." }) public ConfigItem parcelLockerItem = new ConfigItem() .name("&3Parcel locker") .type(Material.CHEST) .lore(List.of("&bPlace to create a parcel locker.")); - @Comment({" ", "# Standard parcel sending duration"}) + @Comment({"", "# Standard parcel sending duration"}) public Duration parcelSendDuration = Duration.ofSeconds(10); - @Comment({" ", "# Parcel sending duration for priority parcels"}) + @Comment({"", "# Parcel sending duration for priority parcels"}) public Duration priorityParcelSendDuration = Duration.ofSeconds(5); - @Comment({" ", "# Error sound used in the plugin."}) + @Comment({"", "# Error sound used in the plugin."}) public Sound errorSound = Sound.ENTITY_ENDERMAN_AMBIENT; - @Comment({ " ", "# The sound volume for the error sound." }) + @Comment({ "", "# The sound volume for the error sound." }) public float errorSoundVolume = 1.0F; - @Comment({ " ", "# The sound pitch for the error sound." }) + @Comment({ "", "# The sound pitch for the error sound." }) public float errorSoundPitch = 1.0F; } public static class GuiSettings extends OkaeriConfig { - @Comment({ " ", "# The title of the main GUI" }) + @Comment({ "", "# The title of the main GUI" }) public String mainGuiTitle = "&3Main menu"; - @Comment({ " ", "# The title of the parcel list GUI" }) + @Comment({ "", "# The title of the parcel list GUI" }) public String parcelListGuiTitle = "&aMy parcels"; - @Comment({ " ", "# The item of the sent parcels GUI" }) + @Comment({ "", "# The item of the sent parcels GUI" }) public String sentParcelsTitle = "&6Sent parcels"; - @Comment({ " ", "# The item of the parcel locker sending GUI" }) + @Comment({ "", "# The item of the parcel locker sending GUI" }) public String parcelLockerSendingGuiTitle = "&3Parcel sending"; - @Comment({ " ", "# The item of the parcel recipient pick GUI" }) + @Comment({ "", "# The item of the parcel recipient pick GUI" }) public String parcelReceiverSelectionGuiTitle = "&5Select recipient"; - @Comment({ " ", "# The item of the parcel collection GUI" }) + @Comment({ "", "# The item of the parcel collection GUI" }) public String parcelCollectionGuiTitle = "&aCollect parcels"; - @Comment({ " ", "# The item of the small parcel size button" }) + @Comment({ "", "# The item of the small parcel size button" }) public ConfigItem smallParcelSizeItem = new ConfigItem() .name("&aโžป Small") .lore(List.of("&aClick to select the small parcel size.")) .type(Material.LIME_WOOL); - @Comment({ " ", "# The item of the medium parcel size button" }) + @Comment({ "", "# The item of the medium parcel size button" }) public ConfigItem mediumParcelSizeItem = new ConfigItem() .name("&eโžผ Medium") .lore(List.of("&eClick to select the medium parcel size.")) .type(Material.YELLOW_WOOL); - @Comment({ " ", "# The item of the large parcel size button" }) + @Comment({ "", "# The item of the large parcel size button" }) public ConfigItem largeParcelSizeItem = new ConfigItem() .name("&cโžฝ Large") .lore(List.of("&cClick to select the large parcel size.")) .type(Material.RED_WOOL); - @Comment({ " ", "# The item represents selected small parcel size." }) + @Comment({ "", "# The item represents selected small parcel size." }) public ConfigItem selectedSmallParcelSizeItem = new ConfigItem() .name("&aโžป Small") .lore(List.of("&aโœง Currently selected!")) .glow(true) .type(Material.OAK_CHEST_BOAT); - @Comment({ " ", "# The item represents selected medium parcel size." }) + @Comment({ "", "# The item represents selected medium parcel size." }) public ConfigItem selectedMediumParcelSizeItem = new ConfigItem() .name("&eโžผ Medium") .lore(List.of("&aCurrently selected!")) .glow(true) .type(Material.CHEST_MINECART); - @Comment({ " ", "# The item represents selected large parcel size." }) + @Comment({ "", "# The item represents selected large parcel size." }) public ConfigItem selectedLargeParcelSizeItem = new ConfigItem() .name("&cโžฝ Large") .lore(List.of("&aCurrently selected!")) .glow(true) .type(Material.TNT_MINECART); - @Comment({ " ", "# The item of the priority button" }) + @Comment({ "", "# The item of the priority button" }) public ConfigItem priorityItem = new ConfigItem() .name("&c\uD83D\uDE80 Priority") .lore(List.of("&cClick to select the priority.")) .type(Material.FIREWORK_ROCKET); - @Comment({ " ", "# The item of the selected priority button" }) + @Comment({ "", "# The item of the selected priority button" }) public ConfigItem selectedPriorityItem = new ConfigItem() .name("&c\uD83D\uDE80 Priority") .lore(List.of("&4Currently selected!", "&7&oClick to unselect.")) .type(Material.FIREWORK_ROCKET) .glow(true); - @Comment({ " ", "# The close button item" }) + @Comment({ "", "# The close button item" }) public ConfigItem closeItem = new ConfigItem() .name("&cโ˜“ Close") .lore(List.of("&cClick to close the GUI.")) .type(Material.BARRIER); - @Comment({ " ", "# The item of the main GUI" }) + @Comment({ "", "# The item of the main GUI" }) public ConfigItem mainGuiBackgroundItem = new ConfigItem() .name("") .lore(Collections.emptyList()) .type(Material.GRAY_STAINED_GLASS_PANE); - @Comment({ " ", "# The item of the corner GUI item.", "# Purely for decoration purposes." }) + @Comment({ "", "# The item of the corner GUI item.", "# Purely for decoration purposes." }) public ConfigItem cornerItem = new ConfigItem() .name("") .lore(Collections.emptyList()) .type(Material.BLUE_STAINED_GLASS_PANE); - @Comment({ " ", "# The item of the parcel submit button" }) + @Comment({ "", "# The item of the parcel submit button" }) public ConfigItem submitParcelItem = new ConfigItem() .name("&aโœ” Submit") .lore(List.of("Click to submit the parcel.", "Proceed with caution! This action is final and cannot be undone.")) .type(Material.ENDER_PEARL) .glow(true); - @Comment({ " ", "# The item of the parcel list button" }) + @Comment({ "", "# The item of the parcel list button" }) public ConfigItem myParcelsItem = new ConfigItem() .name("&3โ›ƒ My parcels") .lore(List.of("&bClick to open your parcels.")) .type(Material.ENDER_CHEST); - @Comment({ " ", "# The item of the sent parcels button" }) + @Comment({ "", "# The item of the sent parcels button" }) public ConfigItem sentParcelsItem = new ConfigItem() .name("&6\uD83D\uDCE6 Sent parcels") .lore(List.of("&eClick to show parcels, which you sent.", "&eYou can also cancel them here, if you want to.")) .type(Material.YELLOW_SHULKER_BOX) .glow(true); - @Comment({ " ", "# The parcel archive item button." }) + @Comment({ "", "# The parcel archive item button." }) public ConfigItem parcelArchiveItem = new ConfigItem() .name("&5\uD83D\uDCDA Parcel archive") .lore(List.of("&eClick to show all parcels, which you sent or received in the past.", "&c&oNot implemented yet")) .type(Material.BOOKSHELF); - @Comment({ " ", "# The item of the parcel locker collect button" }) + @Comment({ "", "# The item of the parcel locker collect button" }) public ConfigItem parcelLockerCollectItem = new ConfigItem() .name("&2โฌ‡ Collect parcels") .lore(List.of("&2Click to collect your parcels.")) .type(Material.CHEST) .glow(true); - @Comment({ " ", "# The item of the parcel locker send button" }) + @Comment({ "", "# The item of the parcel locker send button" }) public ConfigItem parcelLockerSendItem = new ConfigItem() .name("&6โฌ† Send parcels") .lore(List.of("&6Click to send parcels.")) .type(Material.CHEST_MINECART) .glow(true); - @Comment({ " ", "# The item of the parcel" }) + @Comment({ "", "# The item of the parcel" }) public ConfigItem parcelItem = new ConfigItem() .name("&6{NAME}") .lore(List.of( @@ -218,22 +218,22 @@ public static class GuiSettings extends OkaeriConfig { ) .type(Material.CHEST_MINECART); - @Comment({ " ", "# The item of the parcel item storage button" }) + @Comment({ "", "# The item of the parcel item storage button" }) public ConfigItem parcelStorageItem = new ConfigItem() .name("&6\uD83D\uDCE4 Parcel storage") .lore(List.of("&eClick to edit the parcel content.")) .type(Material.CHEST); - @Comment({ " ", "# The item of the parcel name button" }) + @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelNameItem = new ConfigItem() .name("&4โœŽ &cParcel name") .lore(List.of("&cClick to edit the parcel name.")) .type(Material.NAME_TAG); - @Comment({ " ", "# The value of the GUI line, when parcel name is set" }) + @Comment({ "", "# The value of the GUI line, when parcel name is set" }) public String parcelNameSetLine = "&6> Current parcel name: &e{NAME}"; - @Comment({ " ", "# The item of the parcel description button" }) + @Comment({ "", "# The item of the parcel description button" }) public ConfigItem parcelDescriptionItem = new ConfigItem() .name("&2โ˜ฐ &aParcel description") .lore(List.of("&aClick to edit the parcel description.")) @@ -241,73 +241,73 @@ public static class GuiSettings extends OkaeriConfig { public String parcelDescriptionSetLine = "&2> &aCurrent parcel description: &2{DESCRIPTION}"; - @Comment({ " ", "# The item of the parcel receiver button" }) + @Comment({ "", "# The item of the parcel receiver button" }) public ConfigItem parcelReceiverItem = new ConfigItem() .name("&5\uD83E\uDDCD &dParcel receiver") .lore(List.of("&dClick to edit the parcel receiver.")) .type(Material.PLAYER_HEAD); - @Comment({ " ", "# The value of the GUI line, when parcel name is set" }) + @Comment({ "", "# The value of the GUI line, when parcel name is set" }) public String parcelReceiverGuiSetLine = "&5ยป &dCurrent parcel receiver: &5{RECEIVER}"; - @Comment({ " ", "# The value of the player itemlore line, when parcel receiver is not set" }) + @Comment({ "", "# The value of the player itemlore line, when parcel receiver is not set" }) public String parcelReceiverNotSetLine = "&9โ€บ &bClick to select."; - @Comment({ " ", "# The value of the player item lore line, when parcel receiver is set" }) + @Comment({ "", "# The value of the player item lore line, when parcel receiver is set" }) public String parcelReceiverSetLine = "&2โœ” &aSelected!"; - @Comment({ " ", "# The item of the parcel destination locker button" }) + @Comment({ "", "# The item of the parcel destination locker button" }) public ConfigItem parcelDestinationLockerItem = new ConfigItem() .name("&3\uD83D\uDCCD Destination locker") .lore(List.of("&3Click to edit the parcel destination locker.")) .type(Material.COMPASS); - @Comment({ " ", "# The item of the previous page button" }) + @Comment({ "", "# The item of the previous page button" }) public ConfigItem previousPageItem = new ConfigItem() .name("&bโ† Previous page") .lore(List.of("&bClick to go to the previous page.")) .type(Material.ARROW); - @Comment({ " ", "# The item of the next page button" }) + @Comment({ "", "# The item of the next page button" }) public ConfigItem nextPageItem = new ConfigItem() .name("&bโ†’ Next page") .lore(List.of("&bClick to go to the next page.")) .type(Material.ARROW); - @Comment({ " ", "# The item of the confirm items button" }) + @Comment({ "", "# The item of the confirm items button" }) public ConfigItem confirmItemsItem = new ConfigItem() .name("&aโœ” Confirm items") .lore(List.of("&aClick to confirm the items.")) .type(Material.LIME_WOOL); - @Comment({ " ", "# The name of the parcel small content GUI" }) + @Comment({ "", "# The name of the parcel small content GUI" }) public String parcelSmallContentGuiTitle = "&2Small parcel content"; - @Comment({ " ", "# The name of the parcel medium content GUI" }) + @Comment({ "", "# The name of the parcel medium content GUI" }) public String parcelMediumContentGuiTitle = "&6Medium parcel content"; - @Comment({ " ", "# The name of the parcel large content GUI" }) + @Comment({ "", "# The name of the parcel large content GUI" }) public String parcelLargeContentGuiTitle = "&4Large parcel content"; - @Comment({ " ", "# The title of the parcel destination locker selection GUI" }) + @Comment({ "", "# The title of the parcel destination locker selection GUI" }) public String parcelDestinationLockerSelectionGuiTitle = "&3Select destination locker"; - @Comment({ " ", "# The item of the parcel in destination selection GUI" }) + @Comment({ "", "# The item of the parcel in destination selection GUI" }) public ConfigItem destinationLockerItem = new ConfigItem() .name("&3{DESCRIPTION}") .lore(List.of("&bClick to select this locker.")) .type(Material.CHEST); - @Comment({ " ", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) + @Comment({ "", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) public String parcelDestinationLockerSetLine = "&6โ€บ &eCurrent destination locker: &6{DESCRIPTION}"; - @Comment({ " ", "# The destination GUI locker button lore in case the destination locker is set." }) + @Comment({ "", "# The destination GUI locker button lore in case the destination locker is set." }) public String parcelDestinationSetLine = "&2โœ” &aSelected!"; - @Comment({ " ", "# The destination GUI locker button lore in case the destination locker is not set." }) + @Comment({ "", "# The destination GUI locker button lore in case the destination locker is not set." }) public String parcelDestinationNotSetLine = "&9โ€บ &bClick to select."; - @Comment({ " ", "# Illegal items list, that cannot be stored in the parcel." }) + @Comment({ "", "# Illegal items list, that cannot be stored in the parcel." }) public List illegalItems = List.of( Material.BARRIER, Material.COMMAND_BLOCK, @@ -324,7 +324,7 @@ public static class GuiSettings extends OkaeriConfig { Material.END_PORTAL_FRAME ); - @Comment({ " ", "# The item of the parcel item in the collection GUI" }) + @Comment({ "", "# The item of the parcel item in the collection GUI" }) public ConfigItem parcelCollectionItem = new ConfigItem() .name("&a{NAME}") .lore(List.of( @@ -336,7 +336,7 @@ public static class GuiSettings extends OkaeriConfig { ) .type(Material.CHEST_MINECART); - @Comment({ " ", "# The item that is displayed in the collection GUI when no parcels are found" }) + @Comment({ "", "# The item that is displayed in the collection GUI when no parcels are found" }) public ConfigItem noParcelsItem = new ConfigItem() .name("&cNo parcels found") .lore(List.of("&cYou don't have any parcels to collect.")) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index 50d851a75..d2b4a8def 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -78,8 +78,6 @@ public void show(Player player) { GuiItem cornerItem = this.config.guiSettings.cornerItem.toGuiItem(); GuiItem closeItem = this.config.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); - //gui.setDefaultClickAction(event -> event.setCancelled(true)); - int size = gui.getRows() * 9; for (int i = 0; i < size; i++) { gui.setItem(i, backgroundItem); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java index 4fb44e54a..b7fdb0e3a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java @@ -106,7 +106,6 @@ private void show(Player player, Page page) { } for (Parcel parcel : result.parcels()) { - if (parcel.status() != ParcelStatus.DELIVERED) { continue; } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java index 310fa2a5e..43826f9cc 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java @@ -12,6 +12,7 @@ import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.user.repository.UserRepository; +import com.eternalcode.parcellockers.util.MaterialUtil; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -126,7 +127,7 @@ void show(Player player, ParcelSize size) { // player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_AMBIENT, 1, 1); this.noticeService.create() .notice(messages -> messages.parcel.illegalItem) - .placeholder("{ITEMS}", item.getType().name()) + .placeholder("{ITEMS}", MaterialUtil.format(item.getType())) .player(player.getUniqueId()) .send(); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java index d11e1cf40..34e254bb2 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java @@ -4,6 +4,7 @@ import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; +import com.eternalcode.parcellockers.user.User; import com.eternalcode.parcellockers.user.UserManager; import java.util.ArrayList; import java.util.Collections; @@ -60,7 +61,7 @@ public static List replaceParcelPlaceholders(Parcel parcel, List private static CompletableFuture getName(UUID userUuid, UserManager userManager) { return userManager.get(userUuid).thenApply(userOptional -> userOptional - .map(user -> user.name()) + .map(User::name) .orElse("Unknown") ); } diff --git a/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java b/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java deleted file mode 100644 index ef1eb5f29..000000000 --- a/src/main/java/com/eternalcode/parcellockers/util/ItemSerdesUtil.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.eternalcode.parcellockers.util; - -import com.eternalcode.parcellockers.shared.ParcelLockersException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; -import de.eldoria.jacksonbukkit.JacksonPaper; -import java.util.List; -import org.bukkit.inventory.ItemStack; - -public class ItemSerdesUtil { - - private static final ObjectMapper JSON = JsonMapper.builder() - .addModule(JacksonPaper.builder() - .useLegacyItemStackSerialization() - .build() - ) - .build(); - - private ItemSerdesUtil() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); - } - - public static String serialize(ItemStack stack) { - try { - return JSON.writeValueAsString(stack); - } catch (JsonProcessingException e) { - throw new ParcelLockersException("Failed to serialize itemstack", e); - } - } - - public static String serializeItems(List stack) { - try { - return JSON.writeValueAsString(stack); - } catch (JsonProcessingException e) { - throw new ParcelLockersException("Failed to serialize itemstack", e); - } - } - - public static ItemStack deserialize(String string) { - try { - return JSON.readValue(string, ItemStack.class); - } catch (JsonProcessingException e) { - throw new ParcelLockersException("Failed to deserialize itemstack", e); - } - } - - public static List deserializeItems(String string) { - try { - return JSON.readValue(string, JSON.getTypeFactory().constructCollectionType(List.class, ItemStack.class)); - } catch (JsonProcessingException exception) { - throw new ParcelLockersException("Failed to deserialize itemstack", exception); - } - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/util/MaterialUtil.java b/src/main/java/com/eternalcode/parcellockers/util/MaterialUtil.java new file mode 100644 index 000000000..0982fee18 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/util/MaterialUtil.java @@ -0,0 +1,15 @@ +package com.eternalcode.parcellockers.util; + +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Material; + +public final class MaterialUtil { + + private MaterialUtil() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } + + public static String format(Material material) { + return StringUtils.capitalize(material.name().toLowerCase().replace("_", " ")); + } +} From b7b3e625b6b05a4f8b202e4ee42225fd1d9cdfc8 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Fri, 22 Aug 2025 20:55:33 +0200 Subject: [PATCH 14/51] Refactor GUI buttons --- .../command/debug/DebugCommand.java | 6 +- .../implementation/MessageConfig.java | 121 +++++++++++++----- .../implementation/PluginConfig.java | 106 +++++++-------- .../serializable/ConfigItem.java | 4 - .../parcel/command/ParcelCommand.java | 24 +--- 5 files changed, 148 insertions(+), 113 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index edb1e1a55..87525137f 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -90,8 +90,8 @@ void deleteItemStorages(@Sender CommandSender sender) { .send()); } - @Execute(name = "delete parcelcontents") - void deleteParcelContents(@Sender CommandSender sender) { + @Execute(name = "delete items") + void deleteItems(@Sender CommandSender sender) { this.contentRepository.deleteAll().exceptionally(throwable -> { this.noticeService.create() .notice(Notice.chat("&4Failed to delete parcel contents")) @@ -109,7 +109,7 @@ void deleteAll(@Sender CommandSender sender) { this.deleteItemStorages(sender); this.deleteLockers(sender); this.deleteParcels(sender); - this.deleteParcelContents(sender); + this.deleteItems(sender); } @Execute(name = "getrandomitem") diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 4bf5ac795..6f4d60934 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -19,7 +19,11 @@ public class MessageConfig extends OkaeriConfig { public Notice playerOnlyCommand = Notice.chat("&4โœ˜ &cThis command is only available to players!"); public Notice noPermission = Notice.chat("&4โœ˜ &cYou don't have permission to perform this command! &6(&c{PERMISSION}&6)"); public Notice playerNotFound = Notice.chat("&4โœ˜ &cThe specified player could not be found!"); - public Notice invalidUsage = Notice.chat("&4โฃ &cCorrect usage: &6{USAGE}"); + public Notice invalidUsage = Notice.builder() + .chat("&4ยป &cCorrect usage: &6{USAGE}") + .sound(Sound.BLOCK_NOTE_BLOCK_PLING.key()) + .build(); + public Notice reload = Notice.chat("&3โฃ &bConfiguration has been successfully reloaded!"); @Comment({"", "# Messages related to parcels can be configured here." }) @@ -36,47 +40,104 @@ public static class ParcelMessages extends OkaeriConfig { .sound(Sound.ENTITY_ITEM_PICKUP.key()) .build(); - public Notice cannotSend = Notice.chat("&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information."); - public Notice emptyName = Notice.chat("&4โœ˜ &cThe parcel name cannot be empty!"); - public Notice nameSet = Notice.chat("&2โœ” &aParcel name set successfully."); - public Notice empty = Notice.chat("&4โœ˜ &cThe parcel cannot be empty!"); - public Notice receiverSet = Notice.chat("&2โœ” &aParcel receiver set successfully."); - public Notice descriptionSet = Notice.chat("&2โœ” &aParcel description set successfully."); - public Notice destinationSet = Notice.chat("&2โœ” &aParcel destination locker set successfully."); - public Notice cannotCollect = Notice.chat("&4โœ˜ &cAn error occurred while collecting the parcel."); - public Notice noInventorySpace = Notice.chat("&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!"); + public Notice cannotSend = Notice.builder() + .chat("&4โœ˜ &cAn error occurred while sending the parcel. Check the console for more information.") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice emptyName = Notice.builder() + .chat("&4โœ˜ &cThe parcel name cannot be empty!") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice nameSet = Notice.builder() + .chat("&2โœ” &aParcel name set successfully.") + .sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key()) + .build(); + public Notice empty = Notice.builder() + .chat("&4โœ˜ &cThe parcel cannot be empty!") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice receiverSet = Notice.builder() + .chat("&2โœ” &aParcel receiver set successfully.") + .sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key()) + .build(); + public Notice descriptionSet = Notice.builder() + .chat("&2โœ” &aParcel description set successfully.") + .sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key()) + .build(); + public Notice destinationSet = Notice.builder() + .chat("&2โœ” &aParcel destination locker set successfully.") + .sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key()) + .build(); + public Notice cannotCollect = Notice.builder() + .chat("&4โœ˜ &cAn error occurred while collecting the parcel.") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice noInventorySpace = Notice.builder() + .chat("&4โœ˜ &cYou don't have enough space in your inventory to collect the parcel!") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); public Notice collected = Notice.builder() .chat("&2โœ” &aParcel collected successfully.") - .sound("ENTITY_PLAYER_LEVELUP") + .sound(Sound.ENTITY_PLAYER_LEVELUP.key()) .build(); public Notice receiverNotSet = Notice.builder() .chat("&4โœ˜ &cThe parcel receiver is not set!") .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) .build(); - public Notice illegalItem = Notice.chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})"); - public Notice cannotDelete = Notice.chat("&4โœ˜ &cAn error occurred while deleting the parcel."); - public Notice deleted = Notice.chat("&2โœ” &aParcel deleted successfully."); + public Notice illegalItem = Notice.builder() + .chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice cannotDelete = Notice.builder() + .chat("&4โœ˜ &cAn error occurred while deleting the parcel.") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice deleted = Notice.builder() + .chat("&2โœ” &aParcel deleted successfully.") + .sound(Sound.ENTITY_ITEM_BREAK.key()) + .build(); @Comment({"", "# The parcel info message." }) - public Notice parcelInfoMessages = Notice.chat( - "&7ยป &6Parcel info:", - "&fโ€ข &6UUID: &e{UUID}", - "&fโ€ข &6Sender: &e{SENDER}", - "&fโ€ข &6Receiver: &e{RECEIVER}", - "&fโ€ข &6Size: &e{SIZE}", - "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", - "&fโ€ข &6Priority: &e{PRIORITY}", - "&fโ€ข &6Description: &e{DESCRIPTION}" - ); + public Notice parcelInfoMessages = Notice.builder() + .chat( + "&7ยป &6Parcel info:", + "&fโ€ข &6UUID: &e{UUID}", + "&fโ€ข &6Sender: &e{SENDER}", + "&fโ€ข &6Receiver: &e{RECEIVER}", + "&fโ€ข &6Size: &e{SIZE}", + "&fโ€ข &6Position: &6X: &e{POSITION_X}, &6Y: &e{POSITION_Y}, &6Z: &e{POSITION_Z}", + "&fโ€ข &6Priority: &e{PRIORITY}", + "&fโ€ข &6Description: &e{DESCRIPTION}" + ) + .sound(Sound.BLOCK_NOTE_BLOCK_CHIME.key()) + .build(); } public static class LockerMessages extends OkaeriConfig { - public Notice cannotCreate = Notice.chat("&4โœ˜ &cCould not create the parcel locker."); - public Notice created = Notice.chat("&7ยป &aParcel locker created successfully."); - public Notice descriptionPrompt = Notice.chat("&6โ†ต &eEnter a description for the parcel locker:"); - public Notice cannotBreak = Notice.chat("&4โœ˜ &cYou have no permission to break the parcel locker."); - public Notice deleted = Notice.chat("&2โœ” &aParcel locker deleted successfully."); + public Notice cannotCreate = Notice.builder() + .chat("&4โœ˜ &cCould not create the parcel locker.") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice created = Notice.builder() + .chat("&2โœ” &aParcel locker created successfully.") + .sound(Sound.BLOCK_ANVIL_USE.key()) + .build(); + public Notice descriptionPrompt = Notice.builder() + .chat("&6\uD83D\uDDC8 &eEnter a description for the parcel locker:") + .sound(Sound.BLOCK_NOTE_BLOCK_PLING.key()) + .build(); + public Notice cannotBreak = Notice.builder() + .chat("&4โœ˜ &cYou have no permission to break the parcel locker.") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); + public Notice deleted = Notice.builder() + .chat("&2โœ” &aParcel locker deleted successfully.") + .sound(Sound.BLOCK_ANVIL_BREAK.key()) + .build(); public Notice broadcastRemoved = Notice.chat("&4โฃ &cThe parcel locker at &4{X} {Y} {Z} &cin &4{WORLD} &chas been removed by &4{PLAYER}!"); - public Notice alreadyCreating = Notice.chat("&4โœ˜ &cYou are already creating a parcel locker!"); + public Notice alreadyCreating = Notice.builder() + .chat("&4โœ˜ &cYou are already creating a parcel locker!") + .sound(Sound.ENTITY_VILLAGER_NO.key()) + .build(); } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 2bb48c148..5d42ce1f1 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -22,7 +22,7 @@ }) public class PluginConfig extends OkaeriConfig { - @Comment({"", "# Parcel Lockers plugin configuration file." }) + @Comment({ "", "# Parcel Lockers plugin configuration file." }) public Settings settings = new Settings(); @Comment({ "", "# The plugin GUI settings." }) @@ -76,16 +76,16 @@ public static class Settings extends OkaeriConfig { public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The title of the main GUI" }) - public String mainGuiTitle = "&3Main menu"; + public String mainGuiTitle = "&6Parcel management"; @Comment({ "", "# The title of the parcel list GUI" }) - public String parcelListGuiTitle = "&aMy parcels"; + public String parcelListGuiTitle = "&9My parcels"; @Comment({ "", "# The item of the sent parcels GUI" }) public String sentParcelsTitle = "&6Sent parcels"; @Comment({ "", "# The item of the parcel locker sending GUI" }) - public String parcelLockerSendingGuiTitle = "&3Parcel sending"; + public String parcelLockerSendingGuiTitle = "&6Send parcel"; @Comment({ "", "# The item of the parcel recipient pick GUI" }) public String parcelReceiverSelectionGuiTitle = "&5Select recipient"; @@ -95,59 +95,59 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the small parcel size button" }) public ConfigItem smallParcelSizeItem = new ConfigItem() - .name("&aโžป Small") + .name("&2\uD83C\uDF37 &aSmall") .lore(List.of("&aClick to select the small parcel size.")) - .type(Material.LIME_WOOL); + .type(Material.OAK_CHEST_BOAT); @Comment({ "", "# The item of the medium parcel size button" }) public ConfigItem mediumParcelSizeItem = new ConfigItem() - .name("&eโžผ Medium") + .name("&6\uD83C\uDF39 &eMedium") .lore(List.of("&eClick to select the medium parcel size.")) - .type(Material.YELLOW_WOOL); + .type(Material.CHEST_MINECART); @Comment({ "", "# The item of the large parcel size button" }) public ConfigItem largeParcelSizeItem = new ConfigItem() - .name("&cโžฝ Large") + .name("&4\uD83C\uDFDD &cLarge") .lore(List.of("&cClick to select the large parcel size.")) - .type(Material.RED_WOOL); + .type(Material.TNT_MINECART); @Comment({ "", "# The item represents selected small parcel size." }) public ConfigItem selectedSmallParcelSizeItem = new ConfigItem() - .name("&aโžป Small") - .lore(List.of("&aโœง Currently selected!")) + .name("&2\uD83C\uDF37 &aSmall") + .lore(List.of("&2โœ” Currently selected!")) .glow(true) .type(Material.OAK_CHEST_BOAT); @Comment({ "", "# The item represents selected medium parcel size." }) public ConfigItem selectedMediumParcelSizeItem = new ConfigItem() - .name("&eโžผ Medium") - .lore(List.of("&aCurrently selected!")) + .name("&6\uD83C\uDF39 &eMedium") + .lore(List.of("&6โœ” &eCurrently selected!")) .glow(true) .type(Material.CHEST_MINECART); @Comment({ "", "# The item represents selected large parcel size." }) public ConfigItem selectedLargeParcelSizeItem = new ConfigItem() - .name("&cโžฝ Large") - .lore(List.of("&aCurrently selected!")) + .name("&4\uD83C\uDFDD &cLarge") + .lore(List.of("&4โœ” &cCurrently selected!")) .glow(true) .type(Material.TNT_MINECART); @Comment({ "", "# The item of the priority button" }) public ConfigItem priorityItem = new ConfigItem() - .name("&c\uD83D\uDE80 Priority") - .lore(List.of("&cClick to select the priority.")) + .name("&4\uD83D\uDE80 &cPriority") + .lore(List.of("&cClick to send the parcel faster.")) .type(Material.FIREWORK_ROCKET); @Comment({ "", "# The item of the selected priority button" }) public ConfigItem selectedPriorityItem = new ConfigItem() - .name("&c\uD83D\uDE80 Priority") - .lore(List.of("&4Currently selected!", "&7&oClick to unselect.")) + .name("&4\uD83D\uDE80 &cPriority") + .lore(List.of("&4โœ” &cCurrently selected!", "&8&oClick to unselect.")) .type(Material.FIREWORK_ROCKET) .glow(true); @Comment({ "", "# The close button item" }) public ConfigItem closeItem = new ConfigItem() - .name("&cโ˜“ Close") + .name("&4โœ– &cClose") .lore(List.of("&cClick to close the GUI.")) .type(Material.BARRIER); @@ -161,45 +161,45 @@ public static class GuiSettings extends OkaeriConfig { public ConfigItem cornerItem = new ConfigItem() .name("") .lore(Collections.emptyList()) - .type(Material.BLUE_STAINED_GLASS_PANE); + .type(Material.ORANGE_STAINED_GLASS_PANE); @Comment({ "", "# The item of the parcel submit button" }) public ConfigItem submitParcelItem = new ConfigItem() - .name("&aโœ” Submit") - .lore(List.of("Click to submit the parcel.", "Proceed with caution! This action is final and cannot be undone.")) - .type(Material.ENDER_PEARL) + .name("&2โœ” &aSubmit") + .lore(List.of("Before submitting, check if everything has been filled correctly!", "Before submitting, check if everything has been filled correctly!")) + .type(Material.EMERALD_BLOCK) .glow(true); @Comment({ "", "# The item of the parcel list button" }) public ConfigItem myParcelsItem = new ConfigItem() - .name("&3โ›ƒ My parcels") - .lore(List.of("&bClick to open your parcels.")) + .name("&9\uD83D\uDD83 My parcels") + .lore(List.of("&9ยป Click to open your parcels.")) .type(Material.ENDER_CHEST); @Comment({ "", "# The item of the sent parcels button" }) public ConfigItem sentParcelsItem = new ConfigItem() - .name("&6\uD83D\uDCE6 Sent parcels") - .lore(List.of("&eClick to show parcels, which you sent.", "&eYou can also cancel them here, if you want to.")) + .name("&6\uD83D\uDD85 &eSent parcels") + .lore(List.of("&6ยป &eClick to list parcels that you have sent.")) .type(Material.YELLOW_SHULKER_BOX) .glow(true); @Comment({ "", "# The parcel archive item button." }) public ConfigItem parcelArchiveItem = new ConfigItem() - .name("&5\uD83D\uDCDA Parcel archive") - .lore(List.of("&eClick to show all parcels, which you sent or received in the past.", "&c&oNot implemented yet")) + .name("&5\uD83D\uDCDA &dParcel archive") + .lore(List.of("&5ยป &dClick to show all parcels, which you sent or received in the past.", "&c&oNot implemented yet")) .type(Material.BOOKSHELF); @Comment({ "", "# The item of the parcel locker collect button" }) public ConfigItem parcelLockerCollectItem = new ConfigItem() - .name("&2โฌ‡ Collect parcels") - .lore(List.of("&2Click to collect your parcels.")) - .type(Material.CHEST) + .name("&2\uD83C\uDF20 Collect parcels") + .lore(List.of("&2ยป &aClick to collect your parcels.")) + .type(Material.LECTERN) .glow(true); @Comment({ "", "# The item of the parcel locker send button" }) public ConfigItem parcelLockerSendItem = new ConfigItem() - .name("&6โฌ† Send parcels") - .lore(List.of("&6Click to send parcels.")) + .name("&6\uD83D\uDCE6 Send parcels") + .lore(List.of("&6ยป &eClick to send parcels.")) .type(Material.CHEST_MINECART) .glow(true); @@ -220,45 +220,45 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel item storage button" }) public ConfigItem parcelStorageItem = new ConfigItem() - .name("&6\uD83D\uDCE4 Parcel storage") - .lore(List.of("&eClick to edit the parcel content.")) + .name("&6\uD83D\uDCBE Parcel storage") + .lore(List.of("&6ยป &eClick to add/remove items from this parcel")) .type(Material.CHEST); @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelNameItem = new ConfigItem() .name("&4โœŽ &cParcel name") - .lore(List.of("&cClick to edit the parcel name.")) + .lore(List.of("&4ยป &cClick to name the parcel.")) .type(Material.NAME_TAG); @Comment({ "", "# The value of the GUI line, when parcel name is set" }) - public String parcelNameSetLine = "&6> Current parcel name: &e{NAME}"; + public String parcelNameSetLine = "&4ยป &cCurrent parcel name: &e{NAME}"; @Comment({ "", "# The item of the parcel description button" }) public ConfigItem parcelDescriptionItem = new ConfigItem() - .name("&2โ˜ฐ &aParcel description") - .lore(List.of("&aClick to edit the parcel description.")) - .type(Material.PAPER); + .name("&2\uD83D\uDDC9 &aParcel description") + .lore(List.of("&2ยป &aClick to add parcel description.")) + .type(Material.OAK_SIGN); - public String parcelDescriptionSetLine = "&2> &aCurrent parcel description: &2{DESCRIPTION}"; + public String parcelDescriptionSetLine = "&2ยป &aCurrent parcel description: &2{DESCRIPTION}"; @Comment({ "", "# The item of the parcel receiver button" }) public ConfigItem parcelReceiverItem = new ConfigItem() .name("&5\uD83E\uDDCD &dParcel receiver") - .lore(List.of("&dClick to edit the parcel receiver.")) + .lore(List.of("&5ยป &dClick to choose the parcel receiver.")) .type(Material.PLAYER_HEAD); @Comment({ "", "# The value of the GUI line, when parcel name is set" }) public String parcelReceiverGuiSetLine = "&5ยป &dCurrent parcel receiver: &5{RECEIVER}"; @Comment({ "", "# The value of the player itemlore line, when parcel receiver is not set" }) - public String parcelReceiverNotSetLine = "&9โ€บ &bClick to select."; + public String parcelReceiverNotSetLine = "&9ยป &bClick to select."; @Comment({ "", "# The value of the player item lore line, when parcel receiver is set" }) public String parcelReceiverSetLine = "&2โœ” &aSelected!"; @Comment({ "", "# The item of the parcel destination locker button" }) public ConfigItem parcelDestinationLockerItem = new ConfigItem() - .name("&3\uD83D\uDCCD Destination locker") + .name("&3\uD83D\uDEE3 Destination locker") .lore(List.of("&3Click to edit the parcel destination locker.")) .type(Material.COMPASS); @@ -276,9 +276,9 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the confirm items button" }) public ConfigItem confirmItemsItem = new ConfigItem() - .name("&aโœ” Confirm items") + .name("&2โœ” &aConfirm items") .lore(List.of("&aClick to confirm the items.")) - .type(Material.LIME_WOOL); + .type(Material.GREEN_DYE); @Comment({ "", "# The name of the parcel small content GUI" }) public String parcelSmallContentGuiTitle = "&2Small parcel content"; @@ -296,7 +296,7 @@ public static class GuiSettings extends OkaeriConfig { public ConfigItem destinationLockerItem = new ConfigItem() .name("&3{DESCRIPTION}") .lore(List.of("&bClick to select this locker.")) - .type(Material.CHEST); + .type(Material.CHISELED_BOOKSHELF); @Comment({ "", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) public String parcelDestinationLockerSetLine = "&6โ€บ &eCurrent destination locker: &6{DESCRIPTION}"; @@ -305,7 +305,7 @@ public static class GuiSettings extends OkaeriConfig { public String parcelDestinationSetLine = "&2โœ” &aSelected!"; @Comment({ "", "# The destination GUI locker button lore in case the destination locker is not set." }) - public String parcelDestinationNotSetLine = "&9โ€บ &bClick to select."; + public String parcelDestinationNotSetLine = "&9ยป &bClick to select."; @Comment({ "", "# Illegal items list, that cannot be stored in the parcel." }) public List illegalItems = List.of( @@ -338,8 +338,8 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item that is displayed in the collection GUI when no parcels are found" }) public ConfigItem noParcelsItem = new ConfigItem() - .name("&cNo parcels found") + .name("&4โœ˜ &cNo parcels found") .lore(List.of("&cYou don't have any parcels to collect.")) - .type(Material.BARRIER); + .type(Material.STRUCTURE_VOID); } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index 4ebc1b76a..d971b46da 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -38,9 +38,7 @@ public GuiItem toGuiItem(GuiAction action) { return PaperItemBuilder.from(this.type) .name(AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(this.name))) .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(element))).toList()) - .flags(ItemFlag.HIDE_ATTRIBUTES) .flags(ItemFlag.HIDE_ENCHANTS) - .flags(ItemFlag.HIDE_ADDITIONAL_TOOLTIP) .glow(this.glow) .asGuiItem(action); } @@ -49,9 +47,7 @@ public GuiItem toGuiItem(GuiAction action) { return PaperItemBuilder.from(this.type) .name(AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(this.name))) .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(element))).toList()) - .flags(ItemFlag.HIDE_ATTRIBUTES) .flags(ItemFlag.HIDE_ENCHANTS) - .flags(ItemFlag.HIDE_ADDITIONAL_TOOLTIP) .glow(this.glow); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java index 195886fc9..47b32af6e 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/command/ParcelCommand.java @@ -1,10 +1,6 @@ package com.eternalcode.parcellockers.parcel.command; import com.eternalcode.parcellockers.gui.implementation.remote.MainGui; -import com.eternalcode.parcellockers.gui.implementation.remote.ParcelListGui; -import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelService; -import dev.rollczi.litecommands.annotations.argument.Arg; import dev.rollczi.litecommands.annotations.command.Command; import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; @@ -17,27 +13,9 @@ public class ParcelCommand { private final MainGui mainGUI; - private final ParcelListGui parcelListGUI; - private final ParcelService parcelService; - public ParcelCommand( - MainGui mainGUI, - ParcelListGui parcelListGUI, - ParcelService parcelService - ) { + public ParcelCommand(MainGui mainGUI) { this.mainGUI = mainGUI; - this.parcelListGUI = parcelListGUI; - this.parcelService = parcelService; - } - - @Execute(name = "list") - void list(@Sender Player player) { - this.parcelListGUI.show(player); - } - - @Execute(name = "delete") - void delete(@Sender Player player, @Arg Parcel parcel) { - this.parcelService.remove(player, parcel); } @Execute(name = "gui") From 7677c1bb73cc216cf66fccfdeb08b1979a62d52d Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Fri, 22 Aug 2025 22:01:33 +0200 Subject: [PATCH 15/51] Continue refactor --- deletePluginConfigs.bat | 2 + .../parcellockers/ParcelLockers.java | 2 +- .../implementation/MessageConfig.java | 4 +- .../implementation/locker/LockerMainGui.java | 14 ++++--- .../locker/ParcelCollectionGui.java | 3 +- .../locker/ParcelItemStorageGui.java | 8 ++-- .../locker/ParcelSendingGui.java | 38 ++++++++++--------- .../locker/ReceiverSelectionGui.java | 19 ++++++---- .../implementation/remote/SentParcelsGui.java | 1 + 9 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 deletePluginConfigs.bat diff --git a/deletePluginConfigs.bat b/deletePluginConfigs.bat new file mode 100644 index 000000000..b5cabcb9a --- /dev/null +++ b/deletePluginConfigs.bat @@ -0,0 +1,2 @@ +del run\plugins\ParcelLockers\config.yml +del run\plugins\ParcelLockers\messages.yml \ No newline at end of file diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 416b3e0a5..c69e00ecd 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -149,7 +149,7 @@ public void onEnable() { .message(LiteBukkitMessages.PLAYER_ONLY, messageConfig.playerOnlyCommand) .message(LiteBukkitMessages.PLAYER_NOT_FOUND, messageConfig.playerNotFound) .commands(LiteCommandsAnnotations.of( - new ParcelCommand(mainGUI, parcelListGUI, parcelService), + new ParcelCommand(mainGUI), new ParcelLockersCommand(configManager, config, noticeService), new DebugCommand(parcelRepository, lockerRepository, itemStorageRepository, parcelContentRepository, noticeService) )) diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 6f4d60934..a16f4cbc8 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -54,7 +54,7 @@ public static class ParcelMessages extends OkaeriConfig { .build(); public Notice empty = Notice.builder() .chat("&4โœ˜ &cThe parcel cannot be empty!") - .sound(Sound.ENTITY_VILLAGER_NO.key()) + .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) .build(); public Notice receiverSet = Notice.builder() .chat("&2โœ” &aParcel receiver set successfully.") @@ -86,7 +86,7 @@ public static class ParcelMessages extends OkaeriConfig { .build(); public Notice illegalItem = Notice.builder() .chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})") - .sound(Sound.ENTITY_VILLAGER_NO.key()) + .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) .build(); public Notice cannotDelete = Notice.builder() .chat("&4โœ˜ &cAn error occurred while deleting the parcel.") diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java index d2b4a8def..688c19ad4 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java @@ -4,6 +4,7 @@ import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; @@ -66,7 +67,8 @@ public LockerMainGui( @Override public void show(Player player) { - Component guiTitle = this.miniMessage.deserialize(this.config.guiSettings.mainGuiTitle); + GuiSettings guiSettings = this.config.guiSettings; + Component guiTitle = this.miniMessage.deserialize(guiSettings.mainGuiTitle); Gui gui = Gui.gui() .title(resetItalic(guiTitle)) @@ -74,9 +76,9 @@ public void show(Player player) { .disableAllInteractions() .create(); - GuiItem backgroundItem = this.config.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = this.config.guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = this.config.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> gui.close(player)); int size = gui.getRows() * 9; for (int i = 0; i < size; i++) { @@ -97,8 +99,8 @@ public void show(Player player) { this.lockerRepository ); - gui.setItem(21, this.config.guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); - gui.setItem(23, this.config.guiSettings.parcelLockerSendItem.toGuiItem(event -> new ParcelSendingGui( + gui.setItem(21, guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); + gui.setItem(23, guiSettings.parcelLockerSendItem.toGuiItem(event -> new ParcelSendingGui( this.scheduler, this.config, this.miniMessage, diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java index b7fdb0e3a..f96c3e9c2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java @@ -2,6 +2,7 @@ import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.locker.repository.LockerRepository; @@ -58,7 +59,7 @@ public void show(Player player) { } private void show(Player player, Page page) { - PluginConfig.GuiSettings guiSettings = this.config.guiSettings; + GuiSettings guiSettings = this.config.guiSettings; Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelCollectionGuiTitle); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java index 43826f9cc..bb21fe0e2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java @@ -3,6 +3,7 @@ import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.itemstorage.ItemStorage; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; @@ -69,7 +70,7 @@ public ParcelItemStorageGui( void show(Player player, ParcelSize size) { StorageGui gui; - PluginConfig.GuiSettings guiSettings = this.config.guiSettings; + GuiSettings guiSettings = this.config.guiSettings; GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); @@ -105,8 +106,8 @@ void show(Player player, ParcelSize size) { } // Set background items and confirm/cancel items + close gui action - IntStream.rangeClosed(2, 9).forEach(i -> gui.setItem(gui.getRows(), i, backgroundItem)); - gui.setItem(gui.getRows(), 1, confirmItem); + IntStream.rangeClosed(1, 9).forEach(i -> gui.setItem(gui.getRows(), i, backgroundItem)); + gui.setItem(gui.getRows(), 5, confirmItem); gui.setCloseGuiAction(event -> { ItemStack[] contents = gui.getInventory().getContents(); @@ -124,7 +125,6 @@ void show(Player player, ParcelSize size) { if (item.getType() == type) { ItemUtil.giveItem(player, item); gui.removeItem(item); - // player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_AMBIENT, 1, 1); this.noticeService.create() .notice(messages -> messages.parcel.illegalItem) .placeholder("{ITEMS}", MaterialUtil.format(item.getType())) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java index 7e2e84f66..bb1ab60f2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java @@ -3,6 +3,7 @@ import com.eternalcode.commons.adventure.AdventureUtil; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.gui.GuiView; @@ -63,7 +64,8 @@ public class ParcelSendingGui implements GuiView { private Gui gui; public ParcelSendingGui( - Scheduler scheduler, PluginConfig config, + Scheduler scheduler, + PluginConfig config, MiniMessage miniMessage, ItemStorageRepository itemStorageRepository, ParcelRepository parcelRepository, @@ -91,7 +93,7 @@ public ParcelSendingGui( @Override public void show(Player player) { - PluginConfig.GuiSettings guiSettings = this.config.guiSettings; + GuiSettings guiSettings = this.config.guiSettings; Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelLockerSendingGuiTitle); @@ -172,7 +174,7 @@ public void show(Player player) { lore.remove(1); } - lore.add(this.config.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", description)); + lore.add(guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", description)); this.gui.updateItem(DESCRIPTION_ITEM_SLOT, descriptionItem .lore(lore) @@ -225,7 +227,6 @@ public void show(Player player) { .notice(messages -> messages.parcel.empty) .player(player.getUniqueId()) .send(); - // TODO player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); return; } @@ -234,7 +235,6 @@ public void show(Player player) { .notice(messages -> messages.parcel.receiverNotSet) .player(player.getUniqueId()) .send(); - player.playSound(player, this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch); return; } @@ -346,23 +346,25 @@ private void setSelected(Gui gui, boolean priority) { } public void updateNameItem() { + GuiSettings settings = this.config.guiSettings; if (this.state.parcelName() == null || this.state.parcelName().isEmpty()) { - this.gui.updateItem(NAME_ITEM_SLOT, this.config.guiSettings.parcelNameItem.toItemStack()); + this.gui.updateItem(NAME_ITEM_SLOT, settings.parcelNameItem.toItemStack()); return; } - String line = this.config.guiSettings.parcelNameSetLine.replace("{NAME}", this.state.parcelName()); - this.gui.updateItem(NAME_ITEM_SLOT, this.createActiveItem(this.config.guiSettings.parcelNameItem, line)); + String line = settings.parcelNameSetLine.replace("{NAME}", this.state.parcelName()); + this.gui.updateItem(NAME_ITEM_SLOT, this.createActiveItem(settings.parcelNameItem, line)); } public void updateDescriptionItem() { + GuiSettings settings = this.config.guiSettings; if (this.state.parcelDescription() == null || this.state.parcelDescription().isEmpty()) { - this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.config.guiSettings.parcelDescriptionItem.toItemStack()); + this.gui.updateItem(DESCRIPTION_ITEM_SLOT, settings.parcelDescriptionItem.toItemStack()); return; } - String line = this.config.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", this.state.parcelDescription()); - this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.createActiveItem(this.config.guiSettings.parcelDescriptionItem, line)); + String line = settings.parcelDescriptionSetLine.replace("{DESCRIPTION}", this.state.parcelDescription()); + this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.createActiveItem(settings.parcelDescriptionItem, line)); } public void updateReceiverItem(Player player, String receiverName) { @@ -371,13 +373,14 @@ public void updateReceiverItem(Player player, String receiverName) { .player(player.getUniqueId()) .send(); + GuiSettings settings = this.config.guiSettings; if (receiverName == null || receiverName.isEmpty()) { - this.gui.updateItem(RECEIVER_ITEM_SLOT, this.config.guiSettings.parcelReceiverItem.toItemStack()); + this.gui.updateItem(RECEIVER_ITEM_SLOT, settings.parcelReceiverItem.toItemStack()); return; } - String line = this.config.guiSettings.parcelReceiverGuiSetLine.replace("{RECEIVER}", receiverName); - this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(this.config.guiSettings.parcelReceiverItem, line)); + String line = settings.parcelReceiverGuiSetLine.replace("{RECEIVER}", receiverName); + this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(settings.parcelReceiverItem, line)); } public void updateDestinationItem(Player player, String destinationLockerDesc) { @@ -386,13 +389,14 @@ public void updateDestinationItem(Player player, String destinationLockerDesc) { .player(player.getUniqueId()) .send(); + GuiSettings settings = this.config.guiSettings; if (destinationLockerDesc == null || destinationLockerDesc.isEmpty()) { - this.gui.updateItem(DESTINATION_ITEM_SLOT, this.config.guiSettings.parcelDestinationLockerItem.toItemStack()); + this.gui.updateItem(DESTINATION_ITEM_SLOT, settings.parcelDestinationLockerItem.toItemStack()); return; } - String line = this.config.guiSettings.parcelDestinationLockerSetLine.replace("{DESCRIPTION}", destinationLockerDesc); - this.gui.updateItem(DESTINATION_ITEM_SLOT, this.createActiveItem(this.config.guiSettings.parcelDestinationLockerItem, line)); + String line = settings.parcelDestinationLockerSetLine.replace("{DESCRIPTION}", destinationLockerDesc); + this.gui.updateItem(DESTINATION_ITEM_SLOT, this.createActiveItem(settings.parcelDestinationLockerItem, line)); } private @NotNull ItemStack createActiveItem(ConfigItem item, String appendLore) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java index efef12627..916054788 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java @@ -2,6 +2,7 @@ import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.shared.Page; @@ -62,17 +63,18 @@ public void show(Player player) { } private void show(Player player, Page page) { + GuiSettings settings = this.config.guiSettings; PaginatedGui gui = Gui.paginated() - .title(this.miniMessage.deserialize(this.config.guiSettings.parcelReceiverSelectionGuiTitle)) + .title(this.miniMessage.deserialize(settings.parcelReceiverSelectionGuiTitle)) .rows(6) .disableAllInteractions() .create(); - GuiItem backgroundItem = this.config.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = this.config.guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = this.config.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); - GuiItem previousPageItem = this.config.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = this.config.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); + GuiItem backgroundItem = settings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = settings.cornerItem.toGuiItem(); + GuiItem closeItem = settings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); + GuiItem previousPageItem = settings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); + GuiItem nextPageItem = settings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); for (int slot : CORNER_SLOTS) { gui.setItem(slot, cornerItem); @@ -116,9 +118,10 @@ private Supplier toItem(Player player, User user, SkullData skullData, return () -> { boolean isReceiverSelected = uuid.equals(this.state.receiver()); + GuiSettings settings = this.config.guiSettings; String lore = isReceiverSelected - ? this.config.guiSettings.parcelReceiverSetLine - : this.config.guiSettings.parcelReceiverNotSetLine; + ? settings.parcelReceiverSetLine + : settings.parcelReceiverNotSetLine; return ItemBuilder.skull() .texture(skullData.getTexture()) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index f979951ae..8f9c9f79d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -19,6 +19,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; +@SuppressWarnings({"Convert2MethodRef", "ClassCanBeRecord"}) public class SentParcelsGui implements GuiView { private final Scheduler scheduler; From 927dc0540b82c7b1ffdb5545c2e6d28ac34e2c87 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 23 Aug 2025 10:25:13 +0200 Subject: [PATCH 16/51] Refactor GUI dependencies --- .../parcellockers/ParcelLockers.java | 15 +- .../implementation/PluginConfig.java | 10 - .../parcellockers/gui/GuiManager.java | 97 ++++++++++ ...lCollectionGui.java => CollectionGui.java} | 66 +++---- ...nSelectionGui.java => DestinationGui.java} | 55 +++--- ...temStorageGui.java => ItemStorageGui.java} | 73 +++----- .../gui/implementation/locker/LockerGui.java | 85 +++++++++ .../implementation/locker/LockerMainGui.java | 121 ------------ ...iverSelectionGui.java => ReceiverGui.java} | 50 +++-- ...{ParcelSendingGui.java => SendingGui.java} | 176 +++++++----------- ...dingGuiState.java => SendingGuiState.java} | 4 +- .../gui/implementation/remote/MainGui.java | 29 ++- .../implementation/remote/ParcelListGui.java | 48 +++-- .../implementation/remote/SentParcelsGui.java | 40 ++-- .../parcellockers/locker/LockerManager.java | 102 ++++++++++ .../controller/LockerBreakController.java | 118 ++++++------ .../LockerInteractionController.java | 10 +- .../locker/repository/LockerPageResult.java | 9 - .../locker/repository/LockerRepository.java | 3 +- .../repository/LockerRepositoryOrmLite.java | 5 +- .../parcellockers/parcel/ParcelService.java | 2 +- .../parcel/ParcelServiceImpl.java | 4 +- .../parcel/repository/ParcelPageResult.java | 11 -- .../parcel/repository/ParcelRepository.java | 5 +- .../repository/ParcelRepositoryOrmLite.java | 9 +- ...ceholderUtil.java => PlaceholderUtil.java} | 17 +- .../parcellockers/shared/PageResult.java | 10 + .../parcellockers/user/UserManager.java | 4 + .../parcellockers/user/UserManagerImpl.java | 7 + .../LockerRepositoryIntegrationTest.java | 1 - .../ParcelRepositoryIntegrationTest.java | 4 +- 31 files changed, 625 insertions(+), 565 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java rename src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/{ParcelCollectionGui.java => CollectionGui.java} (53%) rename src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/{DestinationSelectionGui.java => DestinationGui.java} (66%) rename src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/{ParcelItemStorageGui.java => ItemStorageGui.java} (55%) create mode 100644 src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java rename src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/{ReceiverSelectionGui.java => ReceiverGui.java} (73%) rename src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/{ParcelSendingGui.java => SendingGui.java} (64%) rename src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/{ParcelSendingGuiState.java => SendingGuiState.java} (92%) create mode 100644 src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/locker/repository/LockerPageResult.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java rename src/main/java/com/eternalcode/parcellockers/parcel/util/{ParcelPlaceholderUtil.java => PlaceholderUtil.java} (77%) create mode 100644 src/main/java/com/eternalcode/parcellockers/shared/PageResult.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index c69e00ecd..132f3f464 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -14,7 +14,7 @@ import com.eternalcode.parcellockers.content.repository.ParcelContentRepositoryOrmLite; import com.eternalcode.parcellockers.database.DatabaseManager; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepositoryOrmLite; -import com.eternalcode.parcellockers.gui.implementation.locker.LockerMainGui; +import com.eternalcode.parcellockers.gui.implementation.locker.LockerGui; import com.eternalcode.parcellockers.gui.implementation.remote.MainGui; import com.eternalcode.parcellockers.gui.implementation.remote.ParcelListGui; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; @@ -127,15 +127,14 @@ public void onEnable() { MainGui mainGUI = new MainGui( scheduler, miniMessage, - config, + config.guiSettings, parcelRepository, - lockerRepository, - userManager + lockerRepository ); ParcelListGui parcelListGUI = new ParcelListGui( scheduler, miniMessage, - config, + config.guiSettings, parcelRepository, lockerRepository, userManager, @@ -157,10 +156,10 @@ public void onEnable() { .missingPermission(new MissingPermissionsHandlerImpl(noticeService)) .build(); - LockerMainGui lockerMainGUI = new LockerMainGui( + LockerGui lockerGUI = new LockerGui( miniMessage, scheduler, - config, + config.guiSettings, itemStorageRepository, parcelRepository, lockerRepository, @@ -172,7 +171,7 @@ public void onEnable() { ); Stream.of( - new LockerInteractionController(lockerCache, lockerMainGUI), + new LockerInteractionController(lockerCache, lockerGUI), new LockerPlaceController(config, this, lockerRepository, noticeService), new LockerBreakController(lockerRepository, lockerCache, noticeService), new PrepareUserController(userManager), diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 5d42ce1f1..1b17c10cc 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -9,7 +9,6 @@ import java.util.Collections; import java.util.List; import org.bukkit.Material; -import org.bukkit.Sound; @Header({ " ", @@ -62,15 +61,6 @@ public static class Settings extends OkaeriConfig { @Comment({"", "# Parcel sending duration for priority parcels"}) public Duration priorityParcelSendDuration = Duration.ofSeconds(5); - - @Comment({"", "# Error sound used in the plugin."}) - public Sound errorSound = Sound.ENTITY_ENDERMAN_AMBIENT; - - @Comment({ "", "# The sound volume for the error sound." }) - public float errorSoundVolume = 1.0F; - - @Comment({ "", "# The sound pitch for the error sound." }) - public float errorSoundPitch = 1.0F; } public static class GuiSettings extends OkaeriConfig { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java new file mode 100644 index 000000000..9ad8a6226 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java @@ -0,0 +1,97 @@ +package com.eternalcode.parcellockers.gui; + +import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; +import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; +import com.eternalcode.parcellockers.itemstorage.ItemStorage; +import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; +import com.eternalcode.parcellockers.locker.Locker; +import com.eternalcode.parcellockers.locker.LockerManager; +import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.parcel.Parcel; +import com.eternalcode.parcellockers.parcel.ParcelService; +import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; +import com.eternalcode.parcellockers.user.User; +import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.user.repository.UserPageResult; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class GuiManager { + + private final ParcelRepository parcelRepository; + private final ParcelService parcelService; + private final LockerRepository lockerRepository; + private final DeliveryRepository deliveryRepository; + private final ItemStorageRepository itemStorageRepository; + private final ParcelContentRepository contentRepository; + private final UserManager userManager; + private final LockerManager lockerManager; + + public GuiManager( + ParcelRepository parcelRepository, ParcelService parcelService, + LockerRepository lockerRepository, + DeliveryRepository deliveryRepository, + ItemStorageRepository itemStorageRepository, + ParcelContentRepository contentRepository, + UserManager userManager, LockerManager lockerManager + ) { + this.parcelRepository = parcelRepository; + this.parcelService = parcelService; + this.lockerRepository = lockerRepository; + this.deliveryRepository = deliveryRepository; + this.itemStorageRepository = itemStorageRepository; + this.contentRepository = contentRepository; + this.userManager = userManager; + this.lockerManager = lockerManager; + } + + public CompletableFuture> getParcelByReceiver(UUID receiver, Page page) { + return this.parcelRepository.findByReceiver(receiver, page); + } + + public CompletableFuture>> getParcelBySender(UUID sender) { + return this.parcelRepository.findBySender(sender); + } + + public CompletableFuture> getUser(UUID userUuid) { + return this.userManager.get(userUuid); + } + + public CompletableFuture getUserPage(Page page) { + return this.userManager.getPage(page); + } + + public CompletableFuture> getLocker(UUID lockerUuid) { + return this.lockerManager.get(lockerUuid); + } + + public CompletableFuture> getLockerPage(Page page) { + return this.lockerRepository.findPage(page); + } + + public CompletableFuture> getItemStorage(UUID owner) { + return this.itemStorageRepository.find(owner); + } + + public boolean sendParcel(Player sender, Parcel parcel, List items) { + return this.parcelService.send(sender, parcel, items); + } + + public void collectParcel(Player player, Parcel parcel) { + this.parcelService.collect(player, parcel); + } + + public CompletableFuture saveItemStorage(ItemStorage itemStorage) { + return this.itemStorageRepository.save(itemStorage); + } + + public CompletableFuture deleteItemStorage(UUID owner) { + return this.itemStorageRepository.delete(owner); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java similarity index 53% rename from src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java rename to src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index f96c3e9c2..a5d8b975e 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelCollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -1,18 +1,14 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelStatus; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; +import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.user.UserManager; import com.eternalcode.parcellockers.util.InventoryUtil; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -21,36 +17,28 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -public class ParcelCollectionGui implements GuiView { +@SuppressWarnings("ClassCanBeRecord") +public class CollectionGui implements GuiView { private static final int WIDTH = 7; private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); - private final PluginConfig config; + private final GuiSettings guiSettings; private final Scheduler scheduler; - private final ParcelRepository parcelRepository; + private final GuiManager guiManager; private final MiniMessage miniMessage; - private final ParcelService parcelService; - private final UserManager userManager; - private final LockerRepository lockerRepository; - public ParcelCollectionGui( - PluginConfig config, + public CollectionGui( + GuiSettings guiSettings, Scheduler scheduler, - ParcelRepository parcelRepository, - MiniMessage miniMessage, - ParcelService parcelService, - UserManager userManager, - LockerRepository lockerRepository + GuiManager guiManager, + MiniMessage miniMessage ) { - this.config = config; + this.guiSettings = guiSettings; this.scheduler = scheduler; - this.parcelRepository = parcelRepository; + this.guiManager = guiManager; this.miniMessage = miniMessage; - this.parcelService = parcelService; - this.userManager = userManager; - this.lockerRepository = lockerRepository; } @Override @@ -59,9 +47,7 @@ public void show(Player player) { } private void show(Player player, Page page) { - GuiSettings guiSettings = this.config.guiSettings; - - Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelCollectionGuiTitle); + Component guiTitle = this.miniMessage.deserialize(this.guiSettings.parcelCollectionGuiTitle); PaginatedGui gui = Gui.paginated() .rows(6) @@ -69,16 +55,16 @@ private void show(Player player, Page page) { .title(guiTitle) .create(); - ConfigItem parcelItem = guiSettings.parcelCollectionItem; - GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> gui.close(player)); - GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); - GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem nextPageItem = guiSettings.nextPageItem.toGuiItem(event -> { + ConfigItem parcelItem = this.guiSettings.parcelCollectionItem; + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> { Page nextPage = new Page(page.page() + 1, page.size()); this.show(player, nextPage); }); - GuiItem previousPageItem = guiSettings.previousPageItem.toGuiItem(event -> { + GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> { Page previousPage = new Page(page.page() - 1, page.size()); this.show(player, previousPage); }); @@ -93,9 +79,11 @@ private void show(Player player, Page page) { gui.setItem(49, closeItem); - this.parcelRepository.findByReceiver(player.getUniqueId(), page).thenAccept(result -> { - if (result == null || result.parcels().isEmpty()) { - gui.setItem(22, guiSettings.noParcelsItem.toGuiItem(event -> player.playSound(player.getLocation(), this.config.settings.errorSound, this.config.settings.errorSoundVolume, this.config.settings.errorSoundPitch))); + this.guiManager.getParcelByReceiver(player.getUniqueId(), page).thenAccept(result -> { + if (result == null || result.items().isEmpty()) { + gui.setItem(22, this.guiSettings.noParcelsItem.toGuiItem()); + this.scheduler.run(() -> gui.open(player)); + return; } if (result.hasNextPage()) { @@ -106,19 +94,19 @@ private void show(Player player, Page page) { gui.setItem(47, previousPageItem); } - for (Parcel parcel : result.parcels()) { + for (Parcel parcel : result.items()) { if (parcel.status() != ParcelStatus.DELIVERED) { continue; } ConfigItem item = parcelItem.clone(); item.name(item.name().replace("{NAME}", parcel.name())); - item.lore(ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.userManager, this.lockerRepository)); + item.lore(PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager)); item.glow(true); gui.addItem(item.toGuiItem(event -> { - this.parcelService.collect(player, parcel); + this.guiManager.collectParcel(player, parcel); gui.removeItem(event.getSlot()); InventoryUtil.shiftItems(event.getSlot(), gui, item.type()); gui.update(); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java similarity index 66% rename from src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java rename to src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java index 4f0b85239..a4e7bfc9c 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java @@ -1,14 +1,14 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.repository.LockerPageResult; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; @@ -19,31 +19,32 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -public class DestinationSelectionGui implements GuiView { +@SuppressWarnings("ClassCanBeRecord") +public class DestinationGui implements GuiView { private static final int WIDTH = 7; private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); private final Scheduler scheduler; - private final PluginConfig config; + private final GuiSettings guiSettings; private final MiniMessage miniMessage; - private final LockerRepository lockerRepository; - private final ParcelSendingGui sendingGUI; - private final ParcelSendingGuiState state; + private final GuiManager guiManager; + private final SendingGui sendingGUI; + private final SendingGuiState state; - public DestinationSelectionGui( + public DestinationGui( Scheduler scheduler, - PluginConfig config, + GuiSettings guiSettings, MiniMessage miniMessage, - LockerRepository lockerRepository, - ParcelSendingGui sendingGUI, - ParcelSendingGuiState state + GuiManager guiManager, + SendingGui sendingGUI, + SendingGuiState state ) { this.scheduler = scheduler; - this.config = config; + this.guiSettings = guiSettings; this.miniMessage = miniMessage; - this.lockerRepository = lockerRepository; + this.guiManager = guiManager; this.sendingGUI = sendingGUI; this.state = state; } @@ -54,14 +55,14 @@ public void show(Player player) { } private void show(Player player, Page page) { - GuiItem previousPageItem = this.config.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = this.config.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); - GuiItem cornerItem = this.config.guiSettings.cornerItem.toGuiItem(); - GuiItem backgroundItem = this.config.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem closeItem = this.config.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); + GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); + GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); PaginatedGui gui = Gui.paginated() - .title(this.miniMessage.deserialize(this.config.guiSettings.parcelDestinationLockerSelectionGuiTitle)) + .title(this.miniMessage.deserialize(this.guiSettings.parcelDestinationLockerSelectionGuiTitle)) .rows(6) .disableAllInteractions() .create(); @@ -77,7 +78,7 @@ private void show(Player player, Page page) { gui.setItem(49, closeItem); - this.lockerRepository.findPage(page).thenAccept(result -> { + this.guiManager.getLockerPage(page).thenAccept(result -> { if (result.hasNextPage()) { gui.setItem(51, nextPageItem); } @@ -91,22 +92,22 @@ private void show(Player player, Page page) { }).orTimeout(5, TimeUnit.SECONDS); } - private List> loadLockers(Player player, LockerPageResult result, PaginatedGuiRefresher refresh) { - return result.lockers().stream() + private List> loadLockers(Player player, PageResult result, PaginatedGuiRefresher refresh) { + return result.items().stream() .map(locker -> this.toItem(player, locker, refresh)) .toList(); } private Supplier toItem(Player player, Locker locker, PaginatedGuiRefresher refresher) { UUID uuid = locker.uuid(); - ConfigItem parcelItem = this.config.guiSettings.destinationLockerItem.clone(); + ConfigItem parcelItem = this.guiSettings.destinationLockerItem.clone(); return () -> { String name = parcelItem.name().replace("{DESCRIPTION}", locker.description()); boolean isLockerSelected = uuid.equals(this.state.destinationLocker()); String oneLineLore = isLockerSelected - ? this.config.guiSettings.parcelDestinationSetLine - : this.config.guiSettings.parcelDestinationNotSetLine; + ? this.guiSettings.parcelDestinationSetLine + : this.guiSettings.parcelDestinationNotSetLine; return parcelItem .name(name) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java similarity index 55% rename from src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java rename to src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index bb21fe0e2..abc7e10fc 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -2,17 +2,11 @@ import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; -import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.itemstorage.ItemStorage; -import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NoticeService; -import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.repository.UserRepository; import com.eternalcode.parcellockers.util.MaterialUtil; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; @@ -26,80 +20,61 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class ParcelItemStorageGui { +@SuppressWarnings("ClassCanBeRecord") +public class ItemStorageGui { private final Scheduler scheduler; - private final PluginConfig config; + private final GuiSettings guiSettings; private final MiniMessage miniMessage; - private final ItemStorageRepository itemStorageRepository; - private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; + private final GuiManager guiManager; private final NoticeService noticeService; - private final ParcelContentRepository parcelContentRepository; - private final UserRepository userRepository; private final SkullAPI skullAPI; - private final ParcelSendingGuiState state; - private final ParcelService parcelService; + private final SendingGuiState state; - public ParcelItemStorageGui( + public ItemStorageGui( Scheduler scheduler, - PluginConfig config, + GuiSettings guiSettings, MiniMessage miniMessage, - ItemStorageRepository itemStorageRepository, - ParcelRepository parcelRepository, - LockerRepository lockerRepository, + GuiManager guiManager, NoticeService noticeService, - ParcelContentRepository parcelContentRepository, - UserRepository userRepository, SkullAPI skullAPI, - ParcelSendingGuiState state, ParcelService parcelService + SendingGuiState state ) { this.scheduler = scheduler; - this.config = config; + this.guiSettings = guiSettings; this.miniMessage = miniMessage; - this.itemStorageRepository = itemStorageRepository; - this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; + this.guiManager = guiManager; this.noticeService = noticeService; - this.parcelContentRepository = parcelContentRepository; - this.userRepository = userRepository; this.skullAPI = skullAPI; this.state = state; - this.parcelService = parcelService; } void show(Player player, ParcelSize size) { StorageGui gui; - GuiSettings guiSettings = this.config.guiSettings; - GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); - GuiItem confirmItem = guiSettings.confirmItemsItem.toGuiItem(event -> new ParcelSendingGui( + GuiItem confirmItem = this.guiSettings.confirmItemsItem.toGuiItem(event -> new SendingGui( this.scheduler, - this.config, + this.guiSettings, this.miniMessage, - this.itemStorageRepository, - this.parcelRepository, - this.lockerRepository, this.noticeService, - this.parcelContentRepository, - this.userRepository, + this.guiManager, this.skullAPI, - this.parcelService, this.state ).show(player)); switch (size) { case SMALL -> gui = Gui.storage() - .title(this.miniMessage.deserialize(guiSettings.parcelSmallContentGuiTitle)) + .title(this.miniMessage.deserialize(this.guiSettings.parcelSmallContentGuiTitle)) .rows(2) .create(); case MEDIUM -> gui = Gui.storage() - .title(this.miniMessage.deserialize(guiSettings.parcelMediumContentGuiTitle)) + .title(this.miniMessage.deserialize(this.guiSettings.parcelMediumContentGuiTitle)) .rows(3) .create(); case LARGE -> gui = Gui.storage() - .title(this.miniMessage.deserialize(guiSettings.parcelLargeContentGuiTitle)) + .title(this.miniMessage.deserialize(this.guiSettings.parcelLargeContentGuiTitle)) .rows(4) .create(); default -> throw new IllegalStateException("Unexpected value: " + size); @@ -121,7 +96,7 @@ void show(Player player, ParcelSize size) { continue; } - for (Material type : this.config.guiSettings.illegalItems) { + for (Material type : this.guiSettings.illegalItems) { if (item.getType() == type) { ItemUtil.giveItem(player, item); gui.removeItem(item); @@ -136,12 +111,12 @@ void show(Player player, ParcelSize size) { items.add(item); } - this.itemStorageRepository.delete(player.getUniqueId()).thenAccept(unused -> { - this.itemStorageRepository.save(new ItemStorage(player.getUniqueId(), items)); - }); + this.guiManager.deleteItemStorage(player.getUniqueId()).thenAccept( + unused -> this.guiManager.saveItemStorage(new ItemStorage(player.getUniqueId(), items)) + ); }); - this.itemStorageRepository.find(player.getUniqueId()).thenAccept(optional -> { + this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(optional -> { if (optional.isPresent()) { ItemStorage itemStorage = optional.get(); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java new file mode 100644 index 000000000..8dbef7bb8 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java @@ -0,0 +1,85 @@ +package com.eternalcode.parcellockers.gui.implementation.locker; + +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + +import com.eternalcode.commons.scheduler.Scheduler; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; +import com.eternalcode.parcellockers.gui.GuiManager; +import com.eternalcode.parcellockers.gui.GuiView; +import com.eternalcode.parcellockers.notification.NoticeService; +import dev.rollczi.liteskullapi.SkullAPI; +import dev.triumphteam.gui.guis.Gui; +import dev.triumphteam.gui.guis.GuiItem; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.entity.Player; + +@SuppressWarnings("ClassCanBeRecord") +public class LockerGui implements GuiView { + + private final MiniMessage miniMessage; + private final Scheduler scheduler; + private final GuiSettings guiSettings; + private final GuiManager guiManager; + private final NoticeService noticeService; + private final SkullAPI skullAPI; + + public LockerGui( + MiniMessage miniMessage, Scheduler scheduler, + GuiSettings guiSettings, GuiManager guiManager, + NoticeService noticeService, + SkullAPI skullAPI + ) { + this.miniMessage = miniMessage; + this.scheduler = scheduler; + this.guiSettings = guiSettings; + this.guiManager = guiManager; + this.noticeService = noticeService; + this.skullAPI = skullAPI; + } + + @Override + public void show(Player player) { + Component guiTitle = this.miniMessage.deserialize(guiSettings.mainGuiTitle); + + Gui gui = Gui.gui() + .title(resetItalic(guiTitle)) + .rows(6) + .disableAllInteractions() + .create(); + + GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + + int size = gui.getRows() * 9; + for (int i = 0; i < size; i++) { + gui.setItem(i, backgroundItem); + } + + for (int slot : CORNER_SLOTS) { + gui.setItem(slot, cornerItem); + } + + CollectionGui collectionGui = new CollectionGui( + this.guiSettings, + this.scheduler, + this.guiManager, + this.miniMessage + ); + + gui.setItem(21, guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); + gui.setItem(23, guiSettings.parcelLockerSendItem.toGuiItem(event -> new SendingGui( + this.scheduler, + this.guiSettings, + this.miniMessage, + this.noticeService, + this.guiManager, + this.skullAPI, + new SendingGuiState() + ).show(player))); + + gui.setItem(49, closeItem); + gui.open(player); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java deleted file mode 100644 index 688c19ad4..000000000 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerMainGui.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.eternalcode.parcellockers.gui.implementation.locker; - -import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; - -import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; -import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; -import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; -import com.eternalcode.parcellockers.notification.NoticeService; -import com.eternalcode.parcellockers.parcel.ParcelService; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.UserManager; -import com.eternalcode.parcellockers.user.UserManagerImpl; -import com.eternalcode.parcellockers.user.repository.UserRepository; -import dev.rollczi.liteskullapi.SkullAPI; -import dev.triumphteam.gui.guis.Gui; -import dev.triumphteam.gui.guis.GuiItem; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.entity.Player; - -public class LockerMainGui implements GuiView { - - private final MiniMessage miniMessage; - private final Scheduler scheduler; - private final PluginConfig config; - private final ItemStorageRepository itemStorageRepository; - private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; - private final NoticeService noticeService; - private final ParcelContentRepository parcelContentRepository; - private final UserRepository userRepository; - private final SkullAPI skullAPI; - private final ParcelService parcelService; - - private final UserManager userManager; - - public LockerMainGui( - MiniMessage miniMessage, Scheduler scheduler, - PluginConfig config, - ItemStorageRepository itemStorageRepository, - ParcelRepository parcelRepository, - LockerRepository lockerRepository, - NoticeService noticeService, - ParcelContentRepository parcelContentRepository, - UserRepository userRepository, - SkullAPI skullAPI, - ParcelService parcelService - ) { - this.miniMessage = miniMessage; - this.scheduler = scheduler; - this.config = config; - this.itemStorageRepository = itemStorageRepository; - this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; - this.noticeService = noticeService; - this.parcelContentRepository = parcelContentRepository; - this.userRepository = userRepository; - this.skullAPI = skullAPI; - this.parcelService = parcelService; - - this.userManager = new UserManagerImpl(this.userRepository); - } - - @Override - public void show(Player player) { - GuiSettings guiSettings = this.config.guiSettings; - Component guiTitle = this.miniMessage.deserialize(guiSettings.mainGuiTitle); - - Gui gui = Gui.gui() - .title(resetItalic(guiTitle)) - .rows(6) - .disableAllInteractions() - .create(); - - GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> gui.close(player)); - - int size = gui.getRows() * 9; - for (int i = 0; i < size; i++) { - gui.setItem(i, backgroundItem); - } - - for (int slot : CORNER_SLOTS) { - gui.setItem(slot, cornerItem); - } - - ParcelCollectionGui collectionGui = new ParcelCollectionGui( - this.config, - this.scheduler, - this.parcelRepository, - this.miniMessage, - this.parcelService, - this.userManager, - this.lockerRepository - ); - - gui.setItem(21, guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); - gui.setItem(23, guiSettings.parcelLockerSendItem.toGuiItem(event -> new ParcelSendingGui( - this.scheduler, - this.config, - this.miniMessage, - this.itemStorageRepository, - this.parcelRepository, - this.lockerRepository, - this.noticeService, - this.parcelContentRepository, - this.userRepository, - this.skullAPI, - this.parcelService, - new ParcelSendingGuiState() - ).show(player))); - - gui.setItem(49, closeItem); - gui.open(player); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java similarity index 73% rename from src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java rename to src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index 916054788..7be577f18 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverSelectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -1,14 +1,13 @@ package com.eternalcode.parcellockers.gui.implementation.locker; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.user.User; import com.eternalcode.parcellockers.user.repository.UserPageResult; -import com.eternalcode.parcellockers.user.repository.UserRepository; import com.spotify.futures.CompletableFutures; import dev.rollczi.liteskullapi.SkullAPI; import dev.rollczi.liteskullapi.SkullData; @@ -23,35 +22,34 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; - -public class ReceiverSelectionGui implements GuiView { +@SuppressWarnings("ClassCanBeRecord") +public class ReceiverGui implements GuiView { private static final int WIDTH = 7; private static final int HEIGHT = 4; private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); private final Scheduler scheduler; - private final PluginConfig config; + private final GuiSettings guiSettings; private final MiniMessage miniMessage; - private final UserRepository userRepository; - private final ParcelSendingGui sendingGUI; + private final GuiManager guiManager; + private final SendingGui sendingGUI; private final SkullAPI skullAPI; - private final ParcelSendingGuiState state; - + private final SendingGuiState state; - public ReceiverSelectionGui( + public ReceiverGui( Scheduler scheduler, - PluginConfig config, + GuiSettings guiSettings, MiniMessage miniMessage, - UserRepository userRepository, - ParcelSendingGui sendingGUI, + GuiManager guiManager, + SendingGui sendingGUI, SkullAPI skullAPI, - ParcelSendingGuiState state + SendingGuiState state ) { this.scheduler = scheduler; - this.config = config; + this.guiSettings = guiSettings; this.miniMessage = miniMessage; - this.userRepository = userRepository; + this.guiManager = guiManager; this.sendingGUI = sendingGUI; this.skullAPI = skullAPI; this.state = state; @@ -63,18 +61,17 @@ public void show(Player player) { } private void show(Player player, Page page) { - GuiSettings settings = this.config.guiSettings; PaginatedGui gui = Gui.paginated() - .title(this.miniMessage.deserialize(settings.parcelReceiverSelectionGuiTitle)) + .title(this.miniMessage.deserialize(this.guiSettings.parcelReceiverSelectionGuiTitle)) .rows(6) .disableAllInteractions() .create(); - GuiItem backgroundItem = settings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = settings.cornerItem.toGuiItem(); - GuiItem closeItem = settings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); - GuiItem previousPageItem = settings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = settings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); + GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); + GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); for (int slot : CORNER_SLOTS) { gui.setItem(slot, cornerItem); @@ -85,7 +82,7 @@ private void show(Player player, Page page) { gui.setItem(49, closeItem); - this.userRepository.findPage(page).thenAccept(result -> { + this.guiManager.getUserPage(page).thenAccept(result -> { if (result.hasNextPage()) { gui.setItem(51, nextPageItem); } @@ -118,10 +115,9 @@ private Supplier toItem(Player player, User user, SkullData skullData, return () -> { boolean isReceiverSelected = uuid.equals(this.state.receiver()); - GuiSettings settings = this.config.guiSettings; String lore = isReceiverSelected - ? settings.parcelReceiverSetLine - : settings.parcelReceiverNotSetLine; + ? this.guiSettings.parcelReceiverSetLine + : this.guiSettings.parcelReceiverNotSetLine; return ItemBuilder.skull() .texture(skullData.getTexture()) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java similarity index 64% rename from src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java rename to src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index bb1ab60f2..66aac634d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -2,19 +2,13 @@ import com.eternalcode.commons.adventure.AdventureUtil; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; -import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelSize; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.repository.UserRepository; import de.rapha149.signgui.SignGUI; import de.rapha149.signgui.exception.SignGUIVersionException; import dev.rollczi.liteskullapi.SkullAPI; @@ -34,7 +28,7 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -public class ParcelSendingGui implements GuiView { +public class SendingGui implements GuiView { private static final int RECEIVER_ITEM_SLOT = 23; private static final int SMALL_BUTTON_SLOT = 12; @@ -48,54 +42,38 @@ public class ParcelSendingGui implements GuiView { private static final int SUBMIT_ITEM_SLOT = 43; private static final int CLOSE_ITEM_SLOT = 49; private final Scheduler scheduler; - private final PluginConfig config; + private final GuiSettings guiSettings; private final MiniMessage miniMessage; - private final ItemStorageRepository itemStorageRepository; - private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; private final NoticeService noticeService; - private final ParcelContentRepository parcelContentRepository; - private final UserRepository userRepository; + private final GuiManager guiManager; private final SkullAPI skullAPI; - private final ParcelService parcelService; - private final ParcelSendingGuiState state; + private final SendingGuiState state; private Gui gui; - public ParcelSendingGui( - Scheduler scheduler, - PluginConfig config, - MiniMessage miniMessage, - ItemStorageRepository itemStorageRepository, - ParcelRepository parcelRepository, - LockerRepository lockerRepository, - NoticeService noticeService, - ParcelContentRepository parcelContentRepository, - UserRepository userRepository, - SkullAPI skullAPI, - ParcelService parcelService, - ParcelSendingGuiState state + public SendingGui( + Scheduler scheduler, + GuiSettings guiSettings, + MiniMessage miniMessage, + NoticeService noticeService, + GuiManager guiManager, + SkullAPI skullAPI, + SendingGuiState state ) { this.scheduler = scheduler; - this.config = config; + this.guiSettings = guiSettings; this.miniMessage = miniMessage; - this.itemStorageRepository = itemStorageRepository; - this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; this.noticeService = noticeService; - this.parcelContentRepository = parcelContentRepository; - this.userRepository = userRepository; + this.guiManager = guiManager; this.skullAPI = skullAPI; - this.parcelService = parcelService; this.state = state; } @Override public void show(Player player) { - GuiSettings guiSettings = this.config.guiSettings; - Component guiTitle = this.miniMessage.deserialize(guiSettings.parcelLockerSendingGuiTitle); + Component guiTitle = this.miniMessage.deserialize(this.guiSettings.parcelLockerSendingGuiTitle); this.gui = Gui.gui() .rows(6) @@ -103,9 +81,9 @@ public void show(Player player) { .title(guiTitle) .create(); - GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); - ConfigItem nameItem = guiSettings.parcelNameItem.clone(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + ConfigItem nameItem = this.guiSettings.parcelNameItem.clone(); GuiItem nameGuiItem = nameItem.toGuiItem(event -> { try { SignGUI nameSignGui = SignGUI.builder() @@ -134,7 +112,7 @@ public void show(Player player) { } lore.add( - this.config.guiSettings.parcelNameSetLine.replace("{NAME}", + this.guiSettings.parcelNameSetLine.replace("{NAME}", this.state.parcelName() == null ? "None" : this.state.parcelName()) ); @@ -149,10 +127,9 @@ public void show(Player player) { } catch (SignGUIVersionException e) { Bukkit.getLogger().severe("The server version is unsupported by SignGUI API!"); } - }); - ConfigItem descriptionItem = guiSettings.parcelDescriptionItem.clone(); + ConfigItem descriptionItem = this.guiSettings.parcelDescriptionItem.clone(); GuiItem descriptionGuiItem = descriptionItem.toGuiItem(event -> { SignGUI descriptionSignGui = null; try { @@ -174,7 +151,7 @@ public void show(Player player) { lore.remove(1); } - lore.add(guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", description)); + lore.add(this.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", description)); this.gui.updateItem(DESCRIPTION_ITEM_SLOT, descriptionItem .lore(lore) @@ -185,26 +162,24 @@ public void show(Player player) { .build(); } catch (SignGUIVersionException e) { Bukkit.getLogger().severe("The server version is unsupported by SignGUI API!"); + } finally { + if (descriptionSignGui != null) { + descriptionSignGui.open(player); + } } - descriptionSignGui.open(player); }); - GuiItem storageItem = guiSettings.parcelStorageItem.toGuiItem(event -> { - ParcelItemStorageGui storageGUI = new ParcelItemStorageGui( + GuiItem storageItem = this.guiSettings.parcelStorageItem.toGuiItem(event -> { + ItemStorageGui storageGUI = new ItemStorageGui( this.scheduler, - this.config, + this.guiSettings, this.miniMessage, - this.itemStorageRepository, - this.parcelRepository, - this.lockerRepository, + this.guiManager, this.noticeService, - this.parcelContentRepository, - this.userRepository, this.skullAPI, - this.state, - this.parcelService + this.state ); - this.itemStorageRepository.find(player.getUniqueId()).thenAccept(result -> { + this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(result -> { if (result.isPresent()) { int slotsSize = result.get().items().size(); if (slotsSize <= 9) { @@ -220,8 +195,8 @@ public void show(Player player) { } ).orTimeout(2, TimeUnit.SECONDS); }); - GuiItem submitItem = guiSettings.submitParcelItem.toGuiItem(event -> - this.itemStorageRepository.find(player.getUniqueId()).thenAccept(result -> { + GuiItem submitItem = this.guiSettings.submitParcelItem.toGuiItem(event -> + this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(result -> { if (result.isEmpty() || result.get().items().isEmpty()) { this.noticeService.create() .notice(messages -> messages.parcel.empty) @@ -242,32 +217,27 @@ public void show(Player player) { this.state.parcelDescription(), this.state.priority(), this.state.receiver(), this.state.size(), this.state.entryLocker(), this.state.destinationLocker(), this.state.status()); - if (this.parcelService.send(player, parcel, result.get().items())) { - this.itemStorageRepository.delete(player.getUniqueId()); + if (this.guiManager.sendParcel(player, parcel, result.get().items())) { + this.guiManager.deleteItemStorage(player.getUniqueId()); } this.gui.close(player); }).orTimeout(5, TimeUnit.SECONDS)); - GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> - new LockerMainGui( + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> + new LockerGui( this.miniMessage, this.scheduler, - this.config, - this.itemStorageRepository, - this.parcelRepository, - this.lockerRepository, + this.guiSettings, + this.guiManager, this.noticeService, - this.parcelContentRepository, - this.userRepository, - this.skullAPI, - this.parcelService + this.skullAPI ).show(player)); - ConfigItem smallButton = guiSettings.smallParcelSizeItem; - ConfigItem mediumButton = guiSettings.mediumParcelSizeItem; - ConfigItem largeButton = guiSettings.largeParcelSizeItem; - ConfigItem priorityItem = guiSettings.priorityItem; + ConfigItem smallButton = this.guiSettings.smallParcelSizeItem; + ConfigItem mediumButton = this.guiSettings.mediumParcelSizeItem; + ConfigItem largeButton = this.guiSettings.largeParcelSizeItem; + ConfigItem priorityItem = this.guiSettings.priorityItem; int size = gui.getRows() * 9; @@ -283,21 +253,21 @@ public void show(Player player) { this.gui.setItem(LARGE_BUTTON_SLOT, largeButton.toGuiItem(event -> this.setSelected(this.gui, ParcelSize.LARGE))); this.gui.setItem(NAME_ITEM_SLOT, nameGuiItem); this.gui.setItem(DESCRIPTION_ITEM_SLOT, descriptionGuiItem); - this.gui.setItem(RECEIVER_ITEM_SLOT, guiSettings.parcelReceiverItem.toGuiItem(event -> new ReceiverSelectionGui( + this.gui.setItem(RECEIVER_ITEM_SLOT, this.guiSettings.parcelReceiverItem.toGuiItem(event -> new ReceiverGui( this.scheduler, - this.config, + this.guiSettings, this.miniMessage, - this.userRepository, + this.guiManager, this, this.skullAPI, this.state ).show(player))); - this.gui.setItem(DESTINATION_ITEM_SLOT, guiSettings.parcelDestinationLockerItem.toGuiItem(event -> new DestinationSelectionGui( + this.gui.setItem(DESTINATION_ITEM_SLOT, this.guiSettings.parcelDestinationLockerItem.toGuiItem(event -> new DestinationGui( this.scheduler, - this.config, + this.guiSettings, this.miniMessage, - this.lockerRepository, + this.guiManager, this, this.state ).show(player))); @@ -311,10 +281,10 @@ public void show(Player player) { this.updateNameItem(); this.updateDescriptionItem(); - this.userRepository.find(this.state.receiver()).thenAccept(userOptional -> + this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); - this.lockerRepository.find(this.state.destinationLocker()).thenAccept(lockerOptional -> + this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.description()))); @@ -322,13 +292,12 @@ public void show(Player player) { } private void setSelected(Gui gui, ParcelSize size) { - PluginConfig.GuiSettings settings = this.config.guiSettings; this.state.size(size); - ConfigItem smallButton = size == ParcelSize.SMALL ? settings.selectedSmallParcelSizeItem : settings.smallParcelSizeItem; - ConfigItem mediumButton = size == ParcelSize.MEDIUM ? settings.selectedMediumParcelSizeItem : settings.mediumParcelSizeItem; - ConfigItem largeButton = size == ParcelSize.LARGE ? settings.selectedLargeParcelSizeItem : settings.largeParcelSizeItem; - ConfigItem priorityButton = this.state.priority() ? settings.selectedPriorityItem : settings.priorityItem; + ConfigItem smallButton = size == ParcelSize.SMALL ? this.guiSettings.selectedSmallParcelSizeItem : this.guiSettings.smallParcelSizeItem; + ConfigItem mediumButton = size == ParcelSize.MEDIUM ? this.guiSettings.selectedMediumParcelSizeItem : this.guiSettings.mediumParcelSizeItem; + ConfigItem largeButton = size == ParcelSize.LARGE ? this.guiSettings.selectedLargeParcelSizeItem : this.guiSettings.largeParcelSizeItem; + ConfigItem priorityButton = this.state.priority() ? this.guiSettings.selectedPriorityItem : this.guiSettings.priorityItem; gui.updateItem(SMALL_BUTTON_SLOT, smallButton.toItemStack()); gui.updateItem(MEDIUM_BUTTON_SLOT, mediumButton.toItemStack()); @@ -337,34 +306,31 @@ private void setSelected(Gui gui, ParcelSize size) { } private void setSelected(Gui gui, boolean priority) { - PluginConfig.GuiSettings settings = this.config.guiSettings; this.state.priority(priority); - ConfigItem priorityButton = priority ? settings.selectedPriorityItem : settings.priorityItem; + ConfigItem priorityButton = priority ? this.guiSettings.selectedPriorityItem : this.guiSettings.priorityItem; gui.updateItem(PRIORITY_BUTTON_SLOT, priorityButton.toItemStack()); } public void updateNameItem() { - GuiSettings settings = this.config.guiSettings; if (this.state.parcelName() == null || this.state.parcelName().isEmpty()) { - this.gui.updateItem(NAME_ITEM_SLOT, settings.parcelNameItem.toItemStack()); + this.gui.updateItem(NAME_ITEM_SLOT, this.guiSettings.parcelNameItem.toItemStack()); return; } - String line = settings.parcelNameSetLine.replace("{NAME}", this.state.parcelName()); - this.gui.updateItem(NAME_ITEM_SLOT, this.createActiveItem(settings.parcelNameItem, line)); + String line = this.guiSettings.parcelNameSetLine.replace("{NAME}", this.state.parcelName()); + this.gui.updateItem(NAME_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelNameItem, line)); } public void updateDescriptionItem() { - GuiSettings settings = this.config.guiSettings; if (this.state.parcelDescription() == null || this.state.parcelDescription().isEmpty()) { - this.gui.updateItem(DESCRIPTION_ITEM_SLOT, settings.parcelDescriptionItem.toItemStack()); + this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.guiSettings.parcelDescriptionItem.toItemStack()); return; } - String line = settings.parcelDescriptionSetLine.replace("{DESCRIPTION}", this.state.parcelDescription()); - this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.createActiveItem(settings.parcelDescriptionItem, line)); + String line = this.guiSettings.parcelDescriptionSetLine.replace("{DESCRIPTION}", this.state.parcelDescription()); + this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelDescriptionItem, line)); } public void updateReceiverItem(Player player, String receiverName) { @@ -373,14 +339,13 @@ public void updateReceiverItem(Player player, String receiverName) { .player(player.getUniqueId()) .send(); - GuiSettings settings = this.config.guiSettings; if (receiverName == null || receiverName.isEmpty()) { - this.gui.updateItem(RECEIVER_ITEM_SLOT, settings.parcelReceiverItem.toItemStack()); + this.gui.updateItem(RECEIVER_ITEM_SLOT, this.guiSettings.parcelReceiverItem.toItemStack()); return; } - String line = settings.parcelReceiverGuiSetLine.replace("{RECEIVER}", receiverName); - this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(settings.parcelReceiverItem, line)); + String line = this.guiSettings.parcelReceiverGuiSetLine.replace("{RECEIVER}", receiverName); + this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelReceiverItem, line)); } public void updateDestinationItem(Player player, String destinationLockerDesc) { @@ -389,14 +354,13 @@ public void updateDestinationItem(Player player, String destinationLockerDesc) { .player(player.getUniqueId()) .send(); - GuiSettings settings = this.config.guiSettings; if (destinationLockerDesc == null || destinationLockerDesc.isEmpty()) { - this.gui.updateItem(DESTINATION_ITEM_SLOT, settings.parcelDestinationLockerItem.toItemStack()); + this.gui.updateItem(DESTINATION_ITEM_SLOT, this.guiSettings.parcelDestinationLockerItem.toItemStack()); return; } - String line = settings.parcelDestinationLockerSetLine.replace("{DESCRIPTION}", destinationLockerDesc); - this.gui.updateItem(DESTINATION_ITEM_SLOT, this.createActiveItem(settings.parcelDestinationLockerItem, line)); + String line = this.guiSettings.parcelDestinationLockerSetLine.replace("{DESCRIPTION}", destinationLockerDesc); + this.gui.updateItem(DESTINATION_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelDestinationLockerItem, line)); } private @NotNull ItemStack createActiveItem(ConfigItem item, String appendLore) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java similarity index 92% rename from src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java rename to src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java index 27372ad5e..4d9e8abfe 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ParcelSendingGuiState.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java @@ -10,7 +10,7 @@ @Getter @Setter @Accessors(fluent = true) -public class ParcelSendingGuiState { +public class SendingGuiState { private String parcelName; private String parcelDescription; @@ -21,7 +21,7 @@ public class ParcelSendingGuiState { private UUID destinationLocker; private ParcelStatus status; - public ParcelSendingGuiState() { + public SendingGuiState() { this.parcelName = null; this.parcelDescription = null; this.size = ParcelSize.SMALL; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index 910667c66..a008bda75 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -3,44 +3,39 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; +@SuppressWarnings("ClassCanBeRecord") public class MainGui implements GuiView { private final Scheduler scheduler; private final MiniMessage miniMessage; - private final PluginConfig config; + private final GuiSettings guiSettings; + private final GuiManager guiManager; private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; - private final UserManager userManager; public MainGui( Scheduler scheduler, MiniMessage miniMessage, - PluginConfig config, - ParcelRepository parcelRepository, - LockerRepository lockerRepository, - UserManager userManager + GuiSettings guiSettings, GuiManager guiManager, + ParcelRepository parcelRepository ) { this.scheduler = scheduler; this.miniMessage = miniMessage; - this.config = config; + this.guiSettings = guiSettings; + this.guiManager = guiManager; this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; - this.userManager = userManager; } @Override public void show(Player player) { - PluginConfig.GuiSettings guiSettings = this.config.guiSettings; Gui gui = Gui.gui() .title(resetItalic(this.miniMessage.deserialize(guiSettings.mainGuiTitle))) @@ -48,7 +43,7 @@ public void show(Player player) { .disableAllInteractions() .create(); - GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); GuiItem myParcelsItem = guiSettings.myParcelsItem.toGuiItem(); GuiItem sentParcelsItem = guiSettings.sentParcelsItem.toGuiItem(); GuiItem parcelArchiveItem = guiSettings.parcelArchiveItem.toGuiItem(); @@ -69,8 +64,8 @@ public void show(Player player) { gui.setItem(24, parcelArchiveItem); gui.setItem(40, closeItem); - gui.addSlotAction(20, event -> new ParcelListGui(this.scheduler, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this.userManager, this).show(player)); - gui.addSlotAction(22, event -> new SentParcelsGui(this.scheduler, this.miniMessage, this.config, this.parcelRepository, this.lockerRepository, this, this.userManager).show(player)); + gui.addSlotAction(20, event -> new ParcelListGui(this.scheduler, this.miniMessage, this.guiSettings, this.parcelRepository, this.guiManager, this).show(player)); + gui.addSlotAction(22, event -> new SentParcelsGui(this.scheduler, this.miniMessage, this.guiSettings, this, this.guiManager).show(player)); gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.open(player); } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index e647e379e..788579e5d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -3,15 +3,14 @@ import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; +import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.user.UserManager; import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -21,6 +20,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; +@SuppressWarnings("ClassCanBeRecord") public class ParcelListGui implements GuiView { private static final int WIDTH = 7; @@ -28,27 +28,24 @@ public class ParcelListGui implements GuiView { private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); private final Scheduler scheduler; private final MiniMessage miniMessage; - private final PluginConfig config; + private final GuiSettings guiSettings; private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; - private final UserManager userManager; + private final GuiManager guiManager; private final MainGui mainGUI; public ParcelListGui( Scheduler scheduler, MiniMessage miniMessage, - PluginConfig config, + GuiSettings guiSettings, ParcelRepository parcelRepository, - LockerRepository lockerRepository, - UserManager userManager, + GuiManager guiManager, MainGui mainGUI ) { this.scheduler = scheduler; this.miniMessage = miniMessage; - this.config = config; + this.guiSettings = guiSettings; this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; - this.userManager = userManager; + this.guiManager = guiManager; this.mainGUI = mainGUI; } @@ -59,16 +56,16 @@ public void show(Player player) { private void show(Player player, Page page) { PaginatedGui gui = Gui.paginated() - .title(resetItalic(this.miniMessage.deserialize(this.config.guiSettings.parcelListGuiTitle))) - .disableAllInteractions() + .title(resetItalic(this.miniMessage.deserialize(this.guiSettings.parcelListGuiTitle))) .rows(6) + .disableAllInteractions() .create(); - GuiItem backgroundItem = this.config.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = this.config.guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = this.config.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); - GuiItem previousPageItem = this.config.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = this.config.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); + GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); + GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); for (int slot : CORNER_SLOTS) { gui.setItem(slot, cornerItem); @@ -77,18 +74,17 @@ private void show(Player player, Page page) { gui.setItem(slot, backgroundItem); } - this.parcelRepository.findPage(page).thenAccept(result -> { - if (result.parcels().isEmpty() && page.hasPrevious()) { + this.parcelRepository.findByReceiver(player.getUniqueId(), page).thenAccept(result -> { + if (result.items().isEmpty() && page.hasPrevious()) { this.show(player, page.previous()); return; } - ConfigItem item = this.config.guiSettings.parcelItem; - - for (Parcel parcel : result.parcels()) { + for (Parcel parcel : result.items()) { + ConfigItem item = this.guiSettings.parcelItem; PaperItemBuilder parcelItem = item.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.userManager, this.lockerRepository).stream() + List newLore = PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager).stream() .map(line -> resetItalic(this.miniMessage.deserialize(line))) .toList(); parcelItem.lore(newLore); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 8f9c9f79d..842b6c6d3 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -1,14 +1,12 @@ package com.eternalcode.parcellockers.gui.implementation.remote; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.parcel.util.ParcelPlaceholderUtil; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -24,42 +22,36 @@ public class SentParcelsGui implements GuiView { private final Scheduler scheduler; private final MiniMessage miniMessage; - private final PluginConfig config; - private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; + private final GuiSettings guiSettings; private final MainGui mainGUI; - private final UserManager userManager; + private final GuiManager guiManager; public SentParcelsGui( Scheduler scheduler, MiniMessage miniMessage, - PluginConfig config, - ParcelRepository parcelRepository, - LockerRepository lockerRepository, + GuiSettings guiSettings, MainGui mainGUI, - UserManager userManager + GuiManager guiManager ) { this.scheduler = scheduler; this.miniMessage = miniMessage; - this.config = config; - this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; + this.guiSettings = guiSettings; this.mainGUI = mainGUI; - this.userManager = userManager; + this.guiManager = guiManager; } @Override public void show(Player player) { PaginatedGui gui = Gui.paginated() - .title(this.miniMessage.deserialize(this.config.guiSettings.sentParcelsTitle)) + .title(this.miniMessage.deserialize(this.guiSettings.sentParcelsTitle)) .rows(6) .disableAllInteractions() .create(); - ConfigItem parcelItem = this.config.guiSettings.parcelItem; - GuiItem cornerItem = this.config.guiSettings.cornerItem.toGuiItem(); - GuiItem backgroundItem = this.config.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem closeItem = this.config.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); + ConfigItem parcelItem = this.guiSettings.parcelItem; + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); for (int slot : CORNER_SLOTS) { gui.setItem(slot, cornerItem); @@ -72,13 +64,13 @@ public void show(Player player) { gui.setItem(49, closeItem); - this.parcelRepository.findBySender(player.getUniqueId()).thenAccept(optionalParcels -> { + this.guiManager.getParcelBySender(player.getUniqueId()).thenAccept(optionalParcels -> { List parcels = optionalParcels.orElse(Collections.emptyList()); for (Parcel parcel : parcels) { PaperItemBuilder item = parcelItem.toBuilder(); - List newLore = ParcelPlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore(), this.userManager, this.lockerRepository) + List newLore = PlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore(), this.guiManager) .stream() .map(line -> this.miniMessage.deserialize(line)) .toList(); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java new file mode 100644 index 000000000..8b2220979 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -0,0 +1,102 @@ +package com.eternalcode.parcellockers.locker; + +import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.shared.Position; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.time.Duration; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +public class LockerManager { + + private final LockerRepository lockerRepository; + + private final Cache lockersByUUID = Caffeine.newBuilder() + .expireAfterAccess(Duration.ofHours(2)) + .maximumSize(10_000) + .build(); + + private final Cache lockersByPosition = Caffeine.newBuilder() + .expireAfterAccess(Duration.ofHours(2)) + .maximumSize(10_000) + .build(); + + public LockerManager(LockerRepository lockerRepository) { + this.lockerRepository = lockerRepository; + } + + public CompletableFuture> get(UUID uniqueId) { + Locker locker = this.lockersByUUID.getIfPresent(uniqueId); + + if (locker != null) { + return CompletableFuture.completedFuture(Optional.of(locker)); + } + + return this.lockerRepository.find(uniqueId).thenApply(optionalLocker -> { + optionalLocker.ifPresent(locker1 -> { + this.lockersByUUID.put(locker1.uuid(), locker1); + this.lockersByPosition.put(locker1.position(), locker1); + }); + return optionalLocker; + }); + } + + public CompletableFuture> get(Position position) { + Locker locker = this.lockersByPosition.getIfPresent(position); + + if (locker != null) { + return CompletableFuture.completedFuture(Optional.of(locker)); + } + + return this.lockerRepository.find(position).thenApply(optionalLocker -> { + optionalLocker.ifPresent(locker1 -> { + this.lockersByUUID.put(locker1.uuid(), locker1); + this.lockersByPosition.put(locker1.position(), locker1); + }); + return optionalLocker; + }); + } + + public Locker getOrCreate(UUID uniqueId, String name, Position position) { + Locker lockerByUUID = this.lockersByUUID.getIfPresent(uniqueId); + if (lockerByUUID != null) { + return lockerByUUID; + } + + Locker lockerByPosition = this.lockersByPosition.getIfPresent(position); + if (lockerByPosition != null) { + return lockerByPosition; + } + + return this.create(uniqueId, name, position); + } + + public Locker create(UUID uniqueId, String name, Position position) { + if (this.lockersByUUID.getIfPresent(uniqueId) != null) { + throw new IllegalStateException("Locker with UUID " + uniqueId + " already exists in cache"); + } + + if (this.lockersByPosition.getIfPresent(position) != null) { + throw new IllegalStateException("Locker at position " + position + " already exists in cache"); + } + + Locker locker = new Locker(uniqueId, name, position); + this.lockersByUUID.put(uniqueId, locker); + this.lockersByPosition.put(position, locker); + this.lockerRepository.save(locker); + + return locker; + } + + public CompletableFuture delete(UUID uniqueId) { + this.lockersByUUID.invalidate(uniqueId); + return this.lockerRepository.delete(uniqueId).thenApply(deleted -> { + if (deleted > 0) { + this.lockersByPosition.asMap().values().removeIf(locker -> locker.uuid().equals(uniqueId)); + } + return deleted; + }); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java index 712997430..597754871 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java @@ -1,14 +1,13 @@ package com.eternalcode.parcellockers.locker.controller; import com.eternalcode.multification.shared.Formatter; -import com.eternalcode.parcellockers.locker.repository.LockerCache; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.shared.Position; import com.eternalcode.parcellockers.shared.PositionAdapter; -import java.util.UUID; import org.bukkit.Location; import org.bukkit.block.Block; +import org.bukkit.block.BlockState; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -21,17 +20,14 @@ public class LockerBreakController implements Listener { - private final LockerRepository lockerRepository; - private final LockerCache cache; + private final LockerManager lockerManager; private final NoticeService noticeService; public LockerBreakController( - LockerRepository lockerRepository, - LockerCache cache, + LockerManager lockerManager, NoticeService noticeService ) { - this.lockerRepository = lockerRepository; - this.cache = cache; + this.lockerManager = lockerManager; this.noticeService = noticeService; } @@ -42,26 +38,21 @@ public void onBlockBreak(BlockBreakEvent event) { Position position = PositionAdapter.convert(location); Player player = event.getPlayer(); - if (this.cache.get(position).isEmpty()) { - return; - } - - if (!player.hasPermission("parcellockers.admin.break")) { - event.setCancelled(true); - this.noticeService.create() - .player(player.getUniqueId()) - .notice(messages -> messages.locker.cannotBreak) - .send(); - return; - } - - this.lockerRepository.find(position).thenAccept((locker) -> { + this.lockerManager.get(position).thenAccept((locker) -> { if (locker.isEmpty()) { return; } - UUID toRemove = this.cache.get(position).get().uuid(); - this.lockerRepository.delete(toRemove); + if (!player.hasPermission("parcellockers.admin.break")) { + event.setCancelled(true); + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.locker.cannotBreak) + .send(); + return; + } + + this.lockerManager.delete(locker.get().uuid()); this.noticeService.create() .player(player.getUniqueId()) @@ -69,15 +60,15 @@ public void onBlockBreak(BlockBreakEvent event) { .send(); Formatter formatter = new Formatter() - .register("{X}", position.x()) - .register("{Y}", position.y()) - .register("{Z}", position.z()) - .register("{WORLD}", position.world()) - .register("{PLAYER}", player.getName()); + .register("{X}", position.x()) + .register("{Y}", position.y()) + .register("{Z}", position.z()) + .register("{WORLD}", position.world()) + .register("{PLAYER}", player.getName()); this.noticeService.create() - .player(player.getUniqueId()) - .notice(messages -> messages.locker.deleted) + .onlinePlayers() + .notice(messages -> messages.locker.broadcastRemoved) .formatter(formatter) .send(); }); @@ -85,54 +76,59 @@ public void onBlockBreak(BlockBreakEvent event) { @EventHandler public void onBlockBurn(BlockBurnEvent event) { - Block block = event.getBlock(); - Location location = block.getLocation(); - Position position = PositionAdapter.convert(location); + Position position = PositionAdapter.convert(event.getBlock().getLocation()); - if (this.cache.get(position).isPresent()) { - event.setCancelled(true); - } + this.lockerManager.get(position).thenAccept(locker -> { + if (locker.isPresent()) { + event.setCancelled(true); + } + }); } @EventHandler public void onBlockExplode(BlockExplodeEvent event) { - Block block = event.getBlock(); - Location location = block.getLocation(); - Position position = PositionAdapter.convert(location); + BlockState explodedBlockState = event.getExplodedBlockState(); + Position position = PositionAdapter.convert(explodedBlockState.getLocation()); - if (this.cache.get(position).isPresent()) { - event.setCancelled(true); - } + this.lockerManager.get(position).thenAccept(locker -> { + if (locker.isPresent()) { + event.blockList().remove(explodedBlockState.getBlock()); + } + }); } @EventHandler public void onEntityExplode(EntityExplodeEvent event) { - event.blockList().removeIf(block -> { - Location location = block.getLocation(); - Position position = PositionAdapter.convert(location); - return this.cache.get(position).isPresent(); - }); + for (Block block : event.blockList()) { + Position position = PositionAdapter.convert(block.getLocation()); + + this.lockerManager.get(position).thenAccept(locker -> { + if (locker.isPresent()) { + event.blockList().remove(block); + } + }); + } } @EventHandler public void onBlockIgnite(BlockIgniteEvent event) { - Block block = event.getBlock(); - Location location = block.getLocation(); - Position position = PositionAdapter.convert(location); + Position position = PositionAdapter.convert(event.getBlock().getLocation()); - if (this.cache.get(position).isPresent()) { - event.setCancelled(true); - } + this.lockerManager.get(position).thenAccept(locker -> { + if (locker.isPresent()) { + event.setCancelled(true); + } + }); } @EventHandler public void onBlockDamage(BlockDamageEvent event) { - Block block = event.getBlock(); - Location location = block.getLocation(); - Position position = PositionAdapter.convert(location); + Position position = PositionAdapter.convert(event.getBlock().getLocation()); - if (this.cache.get(position).isPresent()) { - event.setCancelled(true); - } + this.lockerManager.get(position).thenAccept(locker -> { + if (locker.isPresent()) { + event.setCancelled(true); + } + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java index d0bf60a36..a63af89d7 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.locker.controller; -import com.eternalcode.parcellockers.gui.implementation.locker.LockerMainGui; +import com.eternalcode.parcellockers.gui.implementation.locker.LockerGui; import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.shared.Position; import com.eternalcode.parcellockers.shared.PositionAdapter; @@ -15,11 +15,11 @@ public class LockerInteractionController implements Listener { private final LockerCache cache; - private final LockerMainGui lockerMainGUI; + private final LockerGui lockerGUI; - public LockerInteractionController(LockerCache cache, LockerMainGui lockerMainGUI) { + public LockerInteractionController(LockerCache cache, LockerGui lockerGUI) { this.cache = cache; - this.lockerMainGUI = lockerMainGUI; + this.lockerGUI = lockerGUI; } @EventHandler @@ -39,7 +39,7 @@ public void onInventoryOpen(PlayerInteractEvent event) { if (this.cache.get(blockPos).isPresent()) { event.setCancelled(true); - this.lockerMainGUI.show(player); + this.lockerGUI.show(player); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerPageResult.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerPageResult.java deleted file mode 100644 index 239e6851a..000000000 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerPageResult.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.eternalcode.parcellockers.locker.repository; - -import com.eternalcode.parcellockers.locker.Locker; - -import java.util.List; - -public record LockerPageResult(List lockers, boolean hasNextPage) { - -} diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java index 8f12ab2f3..171d47038 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java @@ -2,6 +2,7 @@ import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.shared.Position; import java.util.List; import java.util.Optional; @@ -24,5 +25,5 @@ public interface LockerRepository { CompletableFuture deleteAll(); - CompletableFuture findPage(Page page); + CompletableFuture> findPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index 87cc9df60..08293bea9 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -5,6 +5,7 @@ import com.eternalcode.parcellockers.database.wrapper.AbstractRepositoryOrmLite; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.shared.ParcelLockersException; import com.eternalcode.parcellockers.shared.Position; import com.j256.ormlite.table.TableUtils; @@ -80,7 +81,7 @@ public CompletableFuture delete(Locker locker) { } @Override - public CompletableFuture findPage(Page page) { + public CompletableFuture> findPage(Page page) { return this.action( LockerTable.class, dao -> { List lockers = dao.queryBuilder() @@ -95,7 +96,7 @@ public CompletableFuture findPage(Page page) { lockers.removeLast(); } - return new LockerPageResult(lockers, hasNext); + return new PageResult<>(lockers, hasNext); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index a4eed1fa8..9b32b9bc3 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -9,7 +9,7 @@ public interface ParcelService { void collect(Player player, Parcel parcel); - void remove(CommandSender sender, Parcel parcel); + void delete(CommandSender sender, Parcel parcel); boolean send(Player sender, Parcel parcel, List items); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index f9fa867ac..01fdbaeb9 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -60,6 +60,7 @@ public boolean send(Player sender, Parcel parcel, List items) { .player(sender.getUniqueId()) .send(); + this.parcelRepository.remove(parcel); throw new ParcelLockersException("Failed to save parcel content", throwable); } @@ -69,6 +70,7 @@ public boolean send(Player sender, Parcel parcel, List items) { .send(); Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); + this.deliveryRepository.save(delivery); ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); this.scheduler.runLaterAsync(task, delay); @@ -79,7 +81,7 @@ public boolean send(Player sender, Parcel parcel, List items) { } @Override - public void remove(CommandSender sender, Parcel parcel) { + public void delete(CommandSender sender, Parcel parcel) { this.parcelRepository.remove(parcel) .thenAccept(v -> this.noticeService.create() diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java deleted file mode 100644 index 409e97884..000000000 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelPageResult.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.eternalcode.parcellockers.parcel.repository; - -import com.eternalcode.parcellockers.parcel.Parcel; -import java.util.List; - -public record ParcelPageResult(List parcels, boolean hasNextPage) { - - public static ParcelPageResult empty() { - return new ParcelPageResult(List.of(), false); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java index dafaaa7a7..d400c1d37 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java @@ -2,6 +2,7 @@ import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -21,7 +22,7 @@ public interface ParcelRepository { CompletableFuture>> findByReceiver(UUID receiver); - CompletableFuture findByReceiver(UUID receiver, Page page); + CompletableFuture> findByReceiver(UUID receiver, Page page); CompletableFuture remove(Parcel parcel); @@ -29,5 +30,5 @@ public interface ParcelRepository { CompletableFuture removeAll(); - CompletableFuture findPage(Page page); + CompletableFuture> findPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java index c48312f73..e9e785d1f 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java @@ -5,6 +5,7 @@ import com.eternalcode.parcellockers.database.wrapper.AbstractRepositoryOrmLite; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.j256.ormlite.table.TableUtils; import java.sql.SQLException; import java.util.List; @@ -73,7 +74,7 @@ public CompletableFuture>> findByReceiver(UUID receiver) { .toList())); } - public CompletableFuture findByReceiver(UUID receiver, Page page) { + public CompletableFuture> findByReceiver(UUID receiver, Page page) { return this.action( ParcelTable.class, dao -> { List parcels = dao.queryBuilder() @@ -90,7 +91,7 @@ public CompletableFuture findByReceiver(UUID receiver, Page pa if (hasNext) { parcels.removeLast(); } - return new ParcelPageResult(parcels, hasNext); + return new PageResult<>(parcels, hasNext); }); } @@ -111,7 +112,7 @@ public CompletableFuture remove(UUID uuid) { } @Override - public CompletableFuture findPage(Page page) { + public CompletableFuture> findPage(Page page) { return this.action( ParcelTable.class, dao -> { List parcels = dao.queryBuilder() @@ -125,7 +126,7 @@ public CompletableFuture findPage(Page page) { if (hasNext) { parcels.removeLast(); } - return new ParcelPageResult(parcels, hasNext); + return new PageResult<>(parcels, hasNext); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java similarity index 77% rename from src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java rename to src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index 34e254bb2..9cd1565c5 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/ParcelPlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -1,11 +1,10 @@ package com.eternalcode.parcellockers.parcel.util; import com.eternalcode.multification.shared.Formatter; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.user.User; -import com.eternalcode.parcellockers.user.UserManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -15,16 +14,16 @@ import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.Blocking; -public class ParcelPlaceholderUtil { +public class PlaceholderUtil { @Blocking - public static List replaceParcelPlaceholders(Parcel parcel, List lore, UserManager userManager, LockerRepository lockerRepository) { + public static List replaceParcelPlaceholders(Parcel parcel, List lore, GuiManager guiManager) { if (lore == null || lore.isEmpty()) { return Collections.emptyList(); } - String senderName = getName(parcel.sender(), userManager).join(); - String receiver = getName(parcel.receiver(), userManager).join(); + String senderName = getName(parcel.sender(), guiManager).join(); + String receiver = getName(parcel.receiver(), guiManager).join(); Formatter formatter = new Formatter() .register("{UUID}", parcel.uuid().toString()) @@ -35,7 +34,7 @@ public static List replaceParcelPlaceholders(Parcel parcel, List .register("{PRIORITY}", parcel.priority() ? "&aYes" : "&cNo") .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-"); - Optional lockerOptional = lockerRepository.find(parcel.destinationLocker()) + Optional lockerOptional = guiManager.getLocker(parcel.destinationLocker()) .orTimeout(3, TimeUnit.SECONDS) .join(); @@ -59,8 +58,8 @@ public static List replaceParcelPlaceholders(Parcel parcel, List return newLore; } - private static CompletableFuture getName(UUID userUuid, UserManager userManager) { - return userManager.get(userUuid).thenApply(userOptional -> userOptional + private static CompletableFuture getName(UUID userUuid, GuiManager guiManager) { + return guiManager.getUser(userUuid).thenApply(userOptional -> userOptional .map(User::name) .orElse("Unknown") ); diff --git a/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java b/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java new file mode 100644 index 000000000..db3da6675 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java @@ -0,0 +1,10 @@ +package com.eternalcode.parcellockers.shared; + +import java.util.List; + +public record PageResult(List items, boolean hasNextPage) { + + public static PageResult empty() { + return new PageResult(List.of(), false); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java index f48a069d5..fb0e1cba2 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java @@ -1,5 +1,7 @@ package com.eternalcode.parcellockers.user; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.user.repository.UserPageResult; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -13,4 +15,6 @@ public interface UserManager { CompletableFuture> get(String username); CompletableFuture> get(UUID uniqueId); + + CompletableFuture getPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index 412361f8f..583849893 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -1,5 +1,7 @@ package com.eternalcode.parcellockers.user; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.user.repository.UserPageResult; import com.eternalcode.parcellockers.user.repository.UserRepository; import java.util.HashMap; import java.util.Map; @@ -57,6 +59,11 @@ public User getOrCreate(UUID uuid, String name) { return this.create(uuid, name); } + @Override + public CompletableFuture getPage(Page page) { + return this.userRepository.findPage(page); + } + @Override public User create(UUID uuid, String name) { if (this.usersByUUID.containsKey(uuid) || this.usersByName.containsKey(name)) { diff --git a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java index a118060ea..06bc77f10 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java @@ -8,7 +8,6 @@ import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.repository.LockerCache; -import com.eternalcode.parcellockers.locker.repository.LockerPageResult; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; import com.eternalcode.parcellockers.shared.Page; diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index 81f3b7217..654e8c0bf 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -10,10 +10,10 @@ import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.repository.ParcelCache; -import com.eternalcode.parcellockers.parcel.repository.ParcelPageResult; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.repository.ParcelRepositoryOrmLite; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import java.io.File; import java.nio.file.Path; import java.util.Collections; @@ -70,7 +70,7 @@ void test() { assertEquals(1, bySender.size()); assertEquals(uuid, bySender.getFirst().uuid()); - ParcelPageResult pageResult = this.await(parcelRepository.findPage(new Page(0, 28))); + PageResult pageResult = this.await(parcelRepository.findPage(new Page(0, 28))); assertEquals(1, pageResult.parcels().size()); assertEquals(uuid, pageResult.parcels().getFirst().uuid()); From 6910e157b9606383c172808084c85a4501090d55 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 23 Aug 2025 11:28:53 +0200 Subject: [PATCH 17/51] continue refactoring services, isolate repositories --- .../parcellockers/ParcelLockers.java | 23 +----- .../ParcelLockersLibraryLoader.java | 8 +- .../implementation/MessageConfig.java | 4 +- .../implementation/PluginConfig.java | 8 +- .../serializable/ConfigItem.java | 10 +-- .../repository/ParcelContentRepository.java | 2 +- .../ParcelContentRepositoryOrmLite.java | 4 +- .../conversation/ParcelLockerPlacePrompt.java | 3 +- .../repository/DeliveryRepository.java | 4 +- .../repository/DeliveryRepositoryOrmLite.java | 8 +- .../parcellockers/gui/GuiManager.java | 4 +- .../implementation/locker/CollectionGui.java | 1 - .../implementation/locker/DestinationGui.java | 5 +- .../implementation/locker/ItemStorageGui.java | 1 - .../gui/implementation/locker/LockerGui.java | 13 ++-- .../implementation/locker/ReceiverGui.java | 1 - .../gui/implementation/locker/SendingGui.java | 8 +- .../gui/implementation/remote/MainGui.java | 22 +++--- .../implementation/remote/ParcelListGui.java | 7 +- .../implementation/remote/SentParcelsGui.java | 1 - .../parcellockers/locker/Locker.java | 3 +- .../parcellockers/locker/LockerManager.java | 19 ++++- .../locker/argument/LockerArgument.java | 39 ---------- .../LockerInteractionController.java | 17 +++-- .../locker/repository/LockerCache.java | 76 ------------------- .../repository/LockerRepositoryOrmLite.java | 31 +------- .../locker/repository/LockerTable.java | 2 +- .../parcellockers/parcel/ParcelService.java | 2 + .../parcel/ParcelServiceImpl.java | 21 ++++- .../command/argument/ParcelArgument.java | 44 ----------- .../parcel/repository/ParcelCache.java | 50 ------------ .../parcel/repository/ParcelRepository.java | 4 +- .../repository/ParcelRepositoryOrmLite.java | 41 ++-------- .../parcel/task/ParcelSendTask.java | 47 +++++------- .../parcellockers/user/UserManager.java | 2 +- .../parcellockers/user/UserManagerImpl.java | 8 +- .../user/repository/UserRepository.java | 2 +- .../repository/UserRepositoryOrmLite.java | 6 +- .../parcellockers/TestScheduler.java | 29 +++---- .../LockerRepositoryIntegrationTest.java | 21 +++-- .../ParcelRepositoryIntegrationTest.java | 5 +- .../locker/repository/LockerCacheTest.java | 71 +++++++++-------- .../parcel/repository/ParcelCacheTest.java | 54 ++++++------- 43 files changed, 230 insertions(+), 501 deletions(-) delete mode 100644 src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/parcel/command/argument/ParcelArgument.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 132f3f464..9cc739b81 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -19,12 +19,9 @@ import com.eternalcode.parcellockers.gui.implementation.remote.ParcelListGui; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepositoryOrmLite; -import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.argument.LockerArgument; import com.eternalcode.parcellockers.locker.controller.LockerBreakController; import com.eternalcode.parcellockers.locker.controller.LockerInteractionController; import com.eternalcode.parcellockers.locker.controller.LockerPlaceController; -import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.Parcel; @@ -32,8 +29,6 @@ import com.eternalcode.parcellockers.parcel.ParcelServiceImpl; import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.command.ParcelCommand; -import com.eternalcode.parcellockers.parcel.command.argument.ParcelArgument; -import com.eternalcode.parcellockers.parcel.repository.ParcelCache; import com.eternalcode.parcellockers.parcel.repository.ParcelRepositoryOrmLite; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.updater.UpdaterService; @@ -104,14 +99,9 @@ public void onEnable() { .threadPool(20) .build(); - LockerCache lockerCache = new LockerCache(); - ParcelCache parcelCache = new ParcelCache(); - - LockerRepositoryOrmLite lockerRepository = new LockerRepositoryOrmLite(databaseManager, scheduler, lockerCache); - lockerRepository.updateCaches(); + LockerRepositoryOrmLite lockerRepository = new LockerRepositoryOrmLite(databaseManager, scheduler); ParcelRepositoryOrmLite parcelRepository = new ParcelRepositoryOrmLite(databaseManager, scheduler, parcelCache); - parcelRepository.updateCaches(); DeliveryRepositoryOrmLite deliveryRepository = new DeliveryRepositoryOrmLite(databaseManager, scheduler); @@ -128,22 +118,17 @@ public void onEnable() { scheduler, miniMessage, config.guiSettings, - parcelRepository, - lockerRepository + guiManager ); ParcelListGui parcelListGUI = new ParcelListGui( scheduler, miniMessage, config.guiSettings, - parcelRepository, - lockerRepository, - userManager, + guiManager, mainGUI ); this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) - .argument(Parcel.class, new ParcelArgument(parcelCache)) - .argument(Locker.class, new LockerArgument(lockerCache)) .extension(new LiteAdventureExtension<>()) .message(LiteBukkitMessages.PLAYER_ONLY, messageConfig.playerOnlyCommand) .message(LiteBukkitMessages.PLAYER_NOT_FOUND, messageConfig.playerNotFound) @@ -191,7 +176,7 @@ public void onEnable() { optionalDelivery.ifPresent(delivery -> { long delay = Math.max(0, delivery.deliveryTimestamp().toEpochMilli() - System.currentTimeMillis()); scheduler.runLaterAsync( - new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config), + new ParcelSendTask(parcel, parcelService, deliveryRepository), Duration.ofMillis(delay) ); }) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java index a4576a33f..4cf77f211 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java @@ -19,14 +19,14 @@ public class ParcelLockersLibraryLoader implements PluginLoader { @Override public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) { MavenLibraryResolver resolver = new MavenLibraryResolver(); - PluginLibraries pluginLibraries = load(); + PluginLibraries pluginLibraries = this.load(); pluginLibraries.asDependencies().forEach(resolver::addDependency); pluginLibraries.asRepositories().forEach(resolver::addRepository); classpathBuilder.addLibrary(resolver); } public PluginLibraries load() { - try (var in = getClass().getResourceAsStream("/paper-libraries.json")) { + try (var in = this.getClass().getResourceAsStream("/paper-libraries.json")) { return new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), PluginLibraries.class); } catch (IOException e) { throw new RuntimeException(e); @@ -35,12 +35,12 @@ public PluginLibraries load() { private record PluginLibraries(Map repositories, List dependencies) { public Stream asDependencies() { - return dependencies.stream() + return this.dependencies.stream() .map(d -> new Dependency(new DefaultArtifact(d), null)); } public Stream asRepositories() { - return repositories.entrySet().stream() + return this.repositories.entrySet().stream() .map(e -> new RemoteRepository.Builder(e.getKey(), "default", e.getValue()).build()); } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index a16f4cbc8..6d84b87a9 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -61,7 +61,7 @@ public static class ParcelMessages extends OkaeriConfig { .sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key()) .build(); public Notice descriptionSet = Notice.builder() - .chat("&2โœ” &aParcel description set successfully.") + .chat("&2โœ” &aParcel name set successfully.") .sound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key()) .build(); public Notice destinationSet = Notice.builder() @@ -123,7 +123,7 @@ public static class LockerMessages extends OkaeriConfig { .sound(Sound.BLOCK_ANVIL_USE.key()) .build(); public Notice descriptionPrompt = Notice.builder() - .chat("&6\uD83D\uDDC8 &eEnter a description for the parcel locker:") + .chat("&6\uD83D\uDDC8 &eEnter a name for the parcel locker:") .sound(Sound.BLOCK_NOTE_BLOCK_PLING.key()) .build(); public Notice cannotBreak = Notice.builder() diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 1b17c10cc..0a616f1a8 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -223,13 +223,13 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The value of the GUI line, when parcel name is set" }) public String parcelNameSetLine = "&4ยป &cCurrent parcel name: &e{NAME}"; - @Comment({ "", "# The item of the parcel description button" }) + @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelDescriptionItem = new ConfigItem() - .name("&2\uD83D\uDDC9 &aParcel description") - .lore(List.of("&2ยป &aClick to add parcel description.")) + .name("&2\uD83D\uDDC9 &aParcel name") + .lore(List.of("&2ยป &aClick to add parcel name.")) .type(Material.OAK_SIGN); - public String parcelDescriptionSetLine = "&2ยป &aCurrent parcel description: &2{DESCRIPTION}"; + public String parcelDescriptionSetLine = "&2ยป &aCurrent parcel name: &2{DESCRIPTION}"; @Comment({ "", "# The item of the parcel receiver button" }) public ConfigItem parcelReceiverItem = new ConfigItem() diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index d971b46da..63c3b778e 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -24,7 +24,7 @@ @Accessors(fluent = true) public class ConfigItem implements Serializable, Cloneable { - private final transient MiniMessage MINI_MESSAGE = MiniMessage.builder() + private final transient MiniMessage miniMessage = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) .build(); @@ -36,8 +36,8 @@ public class ConfigItem implements Serializable, Cloneable { public GuiItem toGuiItem(GuiAction action) { return PaperItemBuilder.from(this.type) - .name(AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(this.name))) - .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(element))).toList()) + .name(AdventureUtil.resetItalic(this.miniMessage.deserialize(this.name))) + .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(this.miniMessage.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ENCHANTS) .glow(this.glow) .asGuiItem(action); @@ -45,8 +45,8 @@ public GuiItem toGuiItem(GuiAction action) { public @NotNull PaperItemBuilder toBuilder() { return PaperItemBuilder.from(this.type) - .name(AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(this.name))) - .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(MINI_MESSAGE.deserialize(element))).toList()) + .name(AdventureUtil.resetItalic(this.miniMessage.deserialize(this.name))) + .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(this.miniMessage.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ENCHANTS) .glow(this.glow); } diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java index d71292620..71e2ebcc1 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java @@ -11,7 +11,7 @@ public interface ParcelContentRepository { CompletableFuture> find(UUID uniqueId); - CompletableFuture delete(UUID uniqueId); + void delete(UUID uniqueId); CompletableFuture deleteAll(); diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java index ca71befca..e1cb1fca3 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java @@ -29,8 +29,8 @@ public CompletableFuture save(ParcelContent parcelContent) { } @Override - public CompletableFuture delete(UUID uniqueId) { - return this.deleteById(ParcelContentTable.class, uniqueId); + public void delete(UUID uniqueId) { + this.deleteById(ParcelContentTable.class, uniqueId); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java b/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java index fb0ae0e63..6f96c0041 100644 --- a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java +++ b/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java @@ -17,8 +17,7 @@ public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String @NotNull @Override public String getPromptText(@NotNull ConversationContext context) { - // TODO do not hardcode this - return ChatColor.translateAlternateColorCodes('&', "&6โ†ต &eEnter a description for the parcel locker:"); + return ChatColor.translateAlternateColorCodes('&', "&6โ†ต &eEnter a name for the parcel locker:"); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java index 67e720b9e..c3d47f0bd 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java @@ -8,11 +8,11 @@ public interface DeliveryRepository { - CompletableFuture save(Delivery delivery); + void save(Delivery delivery); CompletableFuture> find(UUID parcel); - CompletableFuture delete(UUID parcel); + void delete(UUID parcel); CompletableFuture>> findAll(); } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java index 8864b109b..1598ccf62 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java @@ -24,8 +24,8 @@ public DeliveryRepositoryOrmLite(DatabaseManager databaseManager, Scheduler sche } @Override - public CompletableFuture save(Delivery delivery) { - return this.saveIfNotExist(DeliveryTable.class, DeliveryTable.from(delivery)).thenApply(dao -> null); + public void save(Delivery delivery) { + this.saveIfNotExist(DeliveryTable.class, DeliveryTable.from(delivery)).thenApply(dao -> null); } @Override @@ -42,7 +42,7 @@ public CompletableFuture>> findAll() { } @Override - public CompletableFuture delete(UUID parcel) { - return this.deleteById(DeliveryTable.class, parcel); + public void delete(UUID parcel) { + this.deleteById(DeliveryTable.class, parcel); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java index 9ad8a6226..ee3e4cf63 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java @@ -87,8 +87,8 @@ public void collectParcel(Player player, Parcel parcel) { this.parcelService.collect(player, parcel); } - public CompletableFuture saveItemStorage(ItemStorage itemStorage) { - return this.itemStorageRepository.save(itemStorage); + public void saveItemStorage(ItemStorage itemStorage) { + this.itemStorageRepository.save(itemStorage); } public CompletableFuture deleteItemStorage(UUID owner) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index a5d8b975e..cd1b8b68a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -17,7 +17,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings("ClassCanBeRecord") public class CollectionGui implements GuiView { private static final int WIDTH = 7; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java index a4e7bfc9c..ff5527799 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java @@ -19,7 +19,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings("ClassCanBeRecord") public class DestinationGui implements GuiView { private static final int WIDTH = 7; @@ -103,7 +102,7 @@ private Supplier toItem(Player player, Locker locker, PaginatedGuiRefre ConfigItem parcelItem = this.guiSettings.destinationLockerItem.clone(); return () -> { - String name = parcelItem.name().replace("{DESCRIPTION}", locker.description()); + String name = parcelItem.name().replace("{DESCRIPTION}", locker.name()); boolean isLockerSelected = uuid.equals(this.state.destinationLocker()); String oneLineLore = isLockerSelected ? this.guiSettings.parcelDestinationSetLine @@ -122,7 +121,7 @@ private Supplier toItem(Player player, Locker locker, PaginatedGuiRefre } this.state.destinationLocker(uuid); - this.sendingGUI.updateDestinationItem(player, locker.description()); + this.sendingGUI.updateDestinationItem(player, locker.name()); refresher.refresh(); }); }; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index abc7e10fc..cd2b28b00 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -20,7 +20,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -@SuppressWarnings("ClassCanBeRecord") public class ItemStorageGui { private final Scheduler scheduler; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java index 8dbef7bb8..9af1c8824 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java @@ -14,7 +14,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings("ClassCanBeRecord") public class LockerGui implements GuiView { private final MiniMessage miniMessage; @@ -40,7 +39,7 @@ public LockerGui( @Override public void show(Player player) { - Component guiTitle = this.miniMessage.deserialize(guiSettings.mainGuiTitle); + Component guiTitle = this.miniMessage.deserialize(this.guiSettings.mainGuiTitle); Gui gui = Gui.gui() .title(resetItalic(guiTitle)) @@ -48,9 +47,9 @@ public void show(Player player) { .disableAllInteractions() .create(); - GuiItem backgroundItem = guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); int size = gui.getRows() * 9; for (int i = 0; i < size; i++) { @@ -68,8 +67,8 @@ public void show(Player player) { this.miniMessage ); - gui.setItem(21, guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); - gui.setItem(23, guiSettings.parcelLockerSendItem.toGuiItem(event -> new SendingGui( + gui.setItem(21, this.guiSettings.parcelLockerCollectItem.toGuiItem(event -> collectionGui.show(player))); + gui.setItem(23, this.guiSettings.parcelLockerSendItem.toGuiItem(event -> new SendingGui( this.scheduler, this.guiSettings, this.miniMessage, diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index 7be577f18..95893edaf 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -22,7 +22,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings("ClassCanBeRecord") public class ReceiverGui implements GuiView { private static final int WIDTH = 7; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 66aac634d..d431fb61d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -136,7 +136,7 @@ public void show(Player player) { descriptionSignGui = SignGUI.builder() .setColor(DyeColor.BLACK) .setType(Material.OAK_SIGN) - .setLine(0, "Enter parcel description:") + .setLine(0, "Enter parcel name:") .setHandler((p, result) -> { String description = result.getLineWithoutColor(1); @@ -240,9 +240,9 @@ public void show(Player player) { ConfigItem priorityItem = this.guiSettings.priorityItem; - int size = gui.getRows() * 9; + int size = this.gui.getRows() * 9; for (int i = 0; i < size; i++) { - gui.setItem(i, backgroundItem); + this.gui.setItem(i, backgroundItem); } for (int slot : CORNER_SLOTS) { this.gui.setItem(slot, cornerItem); @@ -285,7 +285,7 @@ public void show(Player player) { userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> - lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.description()))); + lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.name()))); this.gui.open(player); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index a008bda75..464a8c634 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -6,49 +6,45 @@ import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings("ClassCanBeRecord") public class MainGui implements GuiView { private final Scheduler scheduler; private final MiniMessage miniMessage; private final GuiSettings guiSettings; private final GuiManager guiManager; - private final ParcelRepository parcelRepository; public MainGui( Scheduler scheduler, MiniMessage miniMessage, - GuiSettings guiSettings, GuiManager guiManager, - ParcelRepository parcelRepository + GuiSettings guiSettings, + GuiManager guiManager ) { this.scheduler = scheduler; this.miniMessage = miniMessage; this.guiSettings = guiSettings; this.guiManager = guiManager; - this.parcelRepository = parcelRepository; } @Override public void show(Player player) { Gui gui = Gui.gui() - .title(resetItalic(this.miniMessage.deserialize(guiSettings.mainGuiTitle))) + .title(resetItalic(this.miniMessage.deserialize(this.guiSettings.mainGuiTitle))) .rows(6) .disableAllInteractions() .create(); GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem myParcelsItem = guiSettings.myParcelsItem.toGuiItem(); - GuiItem sentParcelsItem = guiSettings.sentParcelsItem.toGuiItem(); - GuiItem parcelArchiveItem = guiSettings.parcelArchiveItem.toGuiItem(); - GuiItem closeItem = guiSettings.closeItem.toGuiItem(event -> gui.close(player)); - GuiItem cornerItem = guiSettings.cornerItem.toGuiItem(); + GuiItem myParcelsItem = this.guiSettings.myParcelsItem.toGuiItem(); + GuiItem sentParcelsItem = this.guiSettings.sentParcelsItem.toGuiItem(); + GuiItem parcelArchiveItem = this.guiSettings.parcelArchiveItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); int size = gui.getRows() * 9; for (int i = 0; i < size; i++) { @@ -64,7 +60,7 @@ public void show(Player player) { gui.setItem(24, parcelArchiveItem); gui.setItem(40, closeItem); - gui.addSlotAction(20, event -> new ParcelListGui(this.scheduler, this.miniMessage, this.guiSettings, this.parcelRepository, this.guiManager, this).show(player)); + gui.addSlotAction(20, event -> new ParcelListGui(this.scheduler, this.miniMessage, this.guiSettings, this.guiManager, this).show(player)); gui.addSlotAction(22, event -> new SentParcelsGui(this.scheduler, this.miniMessage, this.guiSettings, this, this.guiManager).show(player)); gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.open(player); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 788579e5d..e06401eea 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -8,7 +8,6 @@ import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; import dev.triumphteam.gui.builder.item.PaperItemBuilder; @@ -20,7 +19,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings("ClassCanBeRecord") public class ParcelListGui implements GuiView { private static final int WIDTH = 7; @@ -29,7 +27,6 @@ public class ParcelListGui implements GuiView { private final Scheduler scheduler; private final MiniMessage miniMessage; private final GuiSettings guiSettings; - private final ParcelRepository parcelRepository; private final GuiManager guiManager; private final MainGui mainGUI; @@ -37,14 +34,12 @@ public ParcelListGui( Scheduler scheduler, MiniMessage miniMessage, GuiSettings guiSettings, - ParcelRepository parcelRepository, GuiManager guiManager, MainGui mainGUI ) { this.scheduler = scheduler; this.miniMessage = miniMessage; this.guiSettings = guiSettings; - this.parcelRepository = parcelRepository; this.guiManager = guiManager; this.mainGUI = mainGUI; } @@ -74,7 +69,7 @@ private void show(Player player, Page page) { gui.setItem(slot, backgroundItem); } - this.parcelRepository.findByReceiver(player.getUniqueId(), page).thenAccept(result -> { + this.guiManager.getParcelByReceiver(player.getUniqueId(), page).thenAccept(result -> { if (result.items().isEmpty() && page.hasPrevious()) { this.show(player, page.previous()); return; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 842b6c6d3..efc7c117d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -17,7 +17,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; -@SuppressWarnings({"Convert2MethodRef", "ClassCanBeRecord"}) public class SentParcelsGui implements GuiView { private final Scheduler scheduler; diff --git a/src/main/java/com/eternalcode/parcellockers/locker/Locker.java b/src/main/java/com/eternalcode/parcellockers/locker/Locker.java index 7c670477b..1e3400295 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/Locker.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/Locker.java @@ -1,9 +1,8 @@ package com.eternalcode.parcellockers.locker; import com.eternalcode.parcellockers.shared.Position; - import java.util.UUID; -public record Locker(UUID uuid, String description, Position position) { +public record Locker(UUID uuid, String name, Position position) { } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 8b2220979..09f195f20 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -5,6 +5,7 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import java.time.Duration; +import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -59,6 +60,20 @@ public CompletableFuture> get(Position position) { }); } + public CompletableFuture>> getAll() { + List lockers = List.copyOf(this.lockersByUUID.asMap().values()); + if (!lockers.isEmpty()) { + return CompletableFuture.completedFuture(Optional.of(lockers)); + } + return this.lockerRepository.findAll().thenApply(optionalLockers -> { + optionalLockers.ifPresent(lockers1 -> lockers1.forEach(locker -> { + this.lockersByUUID.put(locker.uuid(), locker); + this.lockersByPosition.put(locker.position(), locker); + })); + return optionalLockers; + }); + } + public Locker getOrCreate(UUID uniqueId, String name, Position position) { Locker lockerByUUID = this.lockersByUUID.getIfPresent(uniqueId); if (lockerByUUID != null) { @@ -90,9 +105,9 @@ public Locker create(UUID uniqueId, String name, Position position) { return locker; } - public CompletableFuture delete(UUID uniqueId) { + public void delete(UUID uniqueId) { this.lockersByUUID.invalidate(uniqueId); - return this.lockerRepository.delete(uniqueId).thenApply(deleted -> { + this.lockerRepository.delete(uniqueId).thenApply(deleted -> { if (deleted > 0) { this.lockersByPosition.asMap().values().removeIf(locker -> locker.uuid().equals(uniqueId)); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java b/src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java deleted file mode 100644 index 31d5694ec..000000000 --- a/src/main/java/com/eternalcode/parcellockers/locker/argument/LockerArgument.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.eternalcode.parcellockers.locker.argument; - -import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.repository.LockerCache; -import dev.rollczi.litecommands.argument.Argument; -import dev.rollczi.litecommands.argument.parser.ParseResult; -import dev.rollczi.litecommands.argument.resolver.ArgumentResolver; -import dev.rollczi.litecommands.invocation.Invocation; -import dev.rollczi.litecommands.suggestion.SuggestionContext; -import dev.rollczi.litecommands.suggestion.SuggestionResult; -import org.bukkit.command.CommandSender; - -public class LockerArgument extends ArgumentResolver { - - private final LockerCache cache; - - public LockerArgument(LockerCache cache) { - this.cache = cache; - } - - @Override - protected ParseResult parse(Invocation invocation, Argument argument, String s) { - return this.cache.cache().values() - .stream() - .filter(locker -> locker.description().equalsIgnoreCase(s)) - .findFirst() - .map(ParseResult::success) - .orElseThrow(() -> new IllegalArgumentException("Locker with description '" + s + "' not found")); - } - - @Override - public SuggestionResult suggest(Invocation invocation, Argument argument, SuggestionContext context) { - return this.cache.cache() - .values() - .stream() - .map(Locker::description) - .collect(SuggestionResult.collector()); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java index a63af89d7..a84041834 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java @@ -1,8 +1,7 @@ package com.eternalcode.parcellockers.locker.controller; import com.eternalcode.parcellockers.gui.implementation.locker.LockerGui; -import com.eternalcode.parcellockers.locker.repository.LockerCache; -import com.eternalcode.parcellockers.shared.Position; +import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.shared.PositionAdapter; import org.bukkit.Material; import org.bukkit.block.Block; @@ -14,11 +13,11 @@ public class LockerInteractionController implements Listener { - private final LockerCache cache; + private final LockerManager lockerManager; private final LockerGui lockerGUI; - public LockerInteractionController(LockerCache cache, LockerGui lockerGUI) { - this.cache = cache; + public LockerInteractionController(LockerManager lockerManager, LockerGui lockerGUI) { + this.lockerManager = lockerManager; this.lockerGUI = lockerGUI; } @@ -35,11 +34,13 @@ public void onInventoryOpen(PlayerInteractEvent event) { return; } - Position blockPos = PositionAdapter.convert(block.getLocation()); + this.lockerManager.get(PositionAdapter.convert(block.getLocation())).thenAccept(optionalLocker -> { + if (optionalLocker.isEmpty()) { + return; + } - if (this.cache.get(blockPos).isPresent()) { event.setCancelled(true); this.lockerGUI.show(player); - } + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java deleted file mode 100644 index 856ae2878..000000000 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerCache.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.eternalcode.parcellockers.locker.repository; - -import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.shared.Position; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import java.time.Duration; -import java.util.Collections; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import org.jetbrains.annotations.NotNull; - -public class LockerCache { - - private final Cache<@NotNull UUID, Locker> cache; - private final Cache<@NotNull Position, Locker> positionCache; - - public LockerCache() { - this.cache = Caffeine.newBuilder() - .maximumSize(10_000) - .expireAfterAccess(Duration.ofHours(2)) - .build(); - - this.positionCache = Caffeine.newBuilder() - .maximumSize(10_000) - .expireAfterAccess(Duration.ofHours(2)) - .build(); - } - - public void put(Locker locker) { - this.cache.put(locker.uuid(), locker); - this.positionCache.put(locker.position(), locker); - } - - public void putAll(Map lockers) { - this.cache.putAll(lockers); - lockers.values().forEach(locker -> this.positionCache.put(locker.position(), locker)); - } - - public Locker remove(UUID uuid) { - Locker locker = this.cache.getIfPresent(uuid); - if (locker != null) { - this.positionCache.invalidate(locker.position()); - this.cache.invalidate(uuid); - } - return locker; - } - - public Locker remove(Locker locker) { - this.positionCache.invalidate(locker.position()); - this.cache.invalidate(locker.uuid()); - return locker; - } - - public Map cache() { - return Collections.unmodifiableMap(this.cache.asMap()); - } - - public Map positionCache() { - return Collections.unmodifiableMap(this.positionCache.asMap()); - } - - public Optional get(UUID uuid) { - return Optional.ofNullable(this.cache.getIfPresent(uuid)); - } - - public Optional get(Position position) { - return Optional.ofNullable(this.positionCache.getIfPresent(position)); - } - - public void clear() { - this.cache.invalidateAll(); - this.positionCache.invalidateAll(); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index 08293bea9..c3105063c 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -10,9 +10,7 @@ import com.eternalcode.parcellockers.shared.Position; import com.j256.ormlite.table.TableUtils; import java.sql.SQLException; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -20,11 +18,8 @@ public class LockerRepositoryOrmLite extends AbstractRepositoryOrmLite implements LockerRepository { - private final LockerCache cache; - - public LockerRepositoryOrmLite(DatabaseManager databaseManager, Scheduler scheduler, LockerCache cache) { + public LockerRepositoryOrmLite(DatabaseManager databaseManager, Scheduler scheduler) { super(databaseManager, scheduler); - this.cache = cache; try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), LockerTable.class); @@ -36,10 +31,7 @@ public LockerRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu @Override public CompletableFuture save(Locker locker) { - return this.save(LockerTable.class, LockerTable.from(locker)).thenApply(dao -> { - this.cache.put(locker); - return null; - }); + return this.save(LockerTable.class, LockerTable.from(locker)).thenApply(dao -> null); } @Override @@ -66,13 +58,7 @@ public CompletableFuture> find(Position position) { @Override public CompletableFuture delete(UUID uuid) { - return this.deleteById(LockerTable.class, uuid) - .thenApply(result -> { - if (result > 0) { - this.cache.remove(uuid); - } - return result; - }); + return this.deleteById(LockerTable.class, uuid); } @Override @@ -104,15 +90,4 @@ public CompletableFuture> findPage(Page page) { public CompletableFuture deleteAll() { return this.deleteAll(LockerTable.class); } - - public void updateCaches() { - this.findAll().thenAccept(lockers -> { - Map newCache = new HashMap<>(); - if (lockers.isPresent()) { - lockers.get().forEach(locker -> newCache.put(locker.uuid(), locker)); - this.cache.clear(); - this.cache.putAll(newCache); - } - }); - } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerTable.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerTable.java index 0abd1e060..1986815cb 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerTable.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerTable.java @@ -29,7 +29,7 @@ class LockerTable { } static LockerTable from(Locker locker) { - return new LockerTable(locker.uuid(), locker.description(), locker.position()); + return new LockerTable(locker.uuid(), locker.name(), locker.position()); } Locker toLocker() { diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index 9b32b9bc3..06f643be9 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -9,6 +9,8 @@ public interface ParcelService { void collect(Player player, Parcel parcel); + void update(Parcel parcel); + void delete(CommandSender sender, Parcel parcel); boolean send(Player sender, Parcel parcel, List items); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 01fdbaeb9..2218f5470 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -13,9 +13,13 @@ import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.shared.ParcelLockersException; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import java.time.Duration; import java.time.Instant; import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -29,6 +33,11 @@ public class ParcelServiceImpl implements ParcelService { private final ParcelContentRepository parcelContentRepository; private final Scheduler scheduler; + private final Cache cache = Caffeine.newBuilder() + .expireAfterWrite(6, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); + public ParcelServiceImpl( PluginConfig config, NoticeService noticeService, @@ -48,8 +57,8 @@ public ParcelServiceImpl( @Override public boolean send(Player sender, Parcel parcel, List items) { Duration delay = parcel.priority() - ? config.settings.priorityParcelSendDuration - : config.settings.parcelSendDuration; + ? this.config.settings.priorityParcelSendDuration + : this.config.settings.parcelSendDuration; this.parcelRepository.save(parcel); @@ -71,7 +80,8 @@ public boolean send(Player sender, Parcel parcel, List items) { Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); this.deliveryRepository.save(delivery); - ParcelSendTask task = new ParcelSendTask(parcel, delivery, parcelRepository, deliveryRepository, config); + ParcelSendTask task = new ParcelSendTask(parcel, this, this.deliveryRepository + ); this.scheduler.runLaterAsync(task, delay); @@ -80,6 +90,11 @@ public boolean send(Player sender, Parcel parcel, List items) { return true; } + @Override + public void update(Parcel updated) { + this.parcelRepository.update(updated) ; + } + @Override public void delete(CommandSender sender, Parcel parcel) { this.parcelRepository.remove(parcel) diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/command/argument/ParcelArgument.java b/src/main/java/com/eternalcode/parcellockers/parcel/command/argument/ParcelArgument.java deleted file mode 100644 index 2f416ee42..000000000 --- a/src/main/java/com/eternalcode/parcellockers/parcel/command/argument/ParcelArgument.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.eternalcode.parcellockers.parcel.command.argument; - -import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.repository.ParcelCache; -import dev.rollczi.litecommands.argument.Argument; -import dev.rollczi.litecommands.argument.parser.ParseResult; -import dev.rollczi.litecommands.argument.resolver.ArgumentResolver; -import dev.rollczi.litecommands.invalidusage.InvalidUsage; -import dev.rollczi.litecommands.invocation.Invocation; -import dev.rollczi.litecommands.suggestion.SuggestionContext; -import dev.rollczi.litecommands.suggestion.SuggestionResult; -import org.bukkit.command.CommandSender; - -import java.util.Optional; -import java.util.UUID; - -public class ParcelArgument extends ArgumentResolver { - - private final ParcelCache cache; - - public ParcelArgument(ParcelCache cache) { - this.cache = cache; - } - - @Override - protected ParseResult parse(Invocation invocation, Argument context, String argument) { - try { - UUID parcelId = UUID.fromString(argument); - Optional parcel = this.cache.get(parcelId); - return parcel.map(ParseResult::success) - .orElseGet(() -> ParseResult.failure(InvalidUsage.Cause.INVALID_ARGUMENT)); - } catch (IllegalArgumentException e) { - return ParseResult.failure(InvalidUsage.Cause.INVALID_ARGUMENT); - } - } - - @Override - public SuggestionResult suggest(Invocation invocation, Argument argument, SuggestionContext context) { - return this.cache.cache().values().stream() - .map(Parcel::uuid) - .map(UUID::toString) - .collect(SuggestionResult.collector()); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java deleted file mode 100644 index 47247215d..000000000 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelCache.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.eternalcode.parcellockers.parcel.repository; - -import com.eternalcode.parcellockers.parcel.Parcel; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import java.time.Duration; -import java.util.Collections; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -public class ParcelCache { - - private final Cache cache; - - public ParcelCache() { - this.cache = Caffeine.newBuilder() - .maximumSize(10_000) - .expireAfterAccess(Duration.ofHours(2)) - .build(); - } - - public void put(Parcel parcel) { - this.cache.put(parcel.uuid(), parcel); - } - - public void putAll(Map parcels) { - this.cache.putAll(parcels); - } - - public Optional get(UUID uuid) { - return Optional.ofNullable(this.cache.getIfPresent(uuid)); - } - - public Parcel remove(UUID uuid) { - Parcel parcel = this.cache.getIfPresent(uuid); - if (parcel != null) { - this.cache.invalidate(uuid); - } - return parcel; - } - - public void clear() { - this.cache.invalidateAll(); - } - - public Map cache() { - return Collections.unmodifiableMap(this.cache.asMap()); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java index d400c1d37..ae16b4e13 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java @@ -10,9 +10,9 @@ public interface ParcelRepository { - CompletableFuture save(Parcel parcel); + void save(Parcel parcel); - CompletableFuture update(Parcel parcel); + void update(Parcel parcel); CompletableFuture>> findAll(); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java index e9e785d1f..acbe59110 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java @@ -9,11 +9,9 @@ import com.j256.ormlite.table.TableUtils; import java.sql.SQLException; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; public class ParcelRepositoryOrmLite extends AbstractRepositoryOrmLite implements ParcelRepository { @@ -21,11 +19,8 @@ public class ParcelRepositoryOrmLite extends AbstractRepositoryOrmLite implement private static final String RECEIVER_COLUMN = "receiver"; private static final String SENDER_COLUMN = "sender"; - private final ParcelCache cache; - - public ParcelRepositoryOrmLite(DatabaseManager databaseManager, Scheduler scheduler, ParcelCache cache) { + public ParcelRepositoryOrmLite(DatabaseManager databaseManager, Scheduler scheduler) { super(databaseManager, scheduler); - this.cache = cache; try { TableUtils.createTableIfNotExists(databaseManager.connectionSource(), ParcelTable.class); @@ -35,20 +30,13 @@ public ParcelRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu } @Override - public CompletableFuture save(Parcel parcel) { - return this.saveIfNotExist(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> { - this.cache.put(parcel); - return null; - }); + public void save(Parcel parcel) { + this.saveIfNotExist(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> null); } @Override - public CompletableFuture update(Parcel parcel) { - return this.save(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> { - this.cache.remove(parcel.uuid()); - this.cache.put(parcel); - return null; - }); + public void update(Parcel parcel) { + this.save(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> null); } @Override @@ -102,13 +90,7 @@ public CompletableFuture remove(Parcel parcel) { @Override public CompletableFuture remove(UUID uuid) { - CompletableFuture removeFuture = this.deleteById(ParcelTable.class, uuid); - removeFuture.thenAccept(deletedCount -> { - if (deletedCount > 0) { - this.cache.remove(uuid); - } - }); - return removeFuture; + return this.deleteById(ParcelTable.class, uuid); } @Override @@ -141,15 +123,4 @@ public CompletableFuture>> findAll() { public CompletableFuture removeAll() { return this.deleteAll(ParcelTable.class); } - - public void updateCaches() { - this.findAll().thenAccept(parcels -> { - List parcelList = parcels.orElse(List.of()); - Map newCache = new ConcurrentHashMap<>(); - - parcelList.forEach(parcel -> newCache.put(parcel.uuid(), parcel)); - this.cache.clear(); - this.cache.putAll(newCache); - }); - } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java index 17959aa7f..b517f002c 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java @@ -1,51 +1,44 @@ package com.eternalcode.parcellockers.parcel.task; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.delivery.Delivery; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; import com.eternalcode.parcellockers.parcel.Parcel; +import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelStatus; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import org.bukkit.scheduler.BukkitRunnable; public class ParcelSendTask extends BukkitRunnable { private final Parcel parcel; - private final Delivery delivery; - private final ParcelRepository parcelRepository; + private final ParcelService parcelService; private final DeliveryRepository deliveryRepository; - private final PluginConfig config; public ParcelSendTask( - Parcel parcel, - Delivery delivery, - ParcelRepository parcelRepository, - DeliveryRepository deliveryRepository, - PluginConfig config + Parcel parcel, + ParcelService parcelService, + DeliveryRepository deliveryRepository ) { this.parcel = parcel; - this.delivery = delivery; - this.parcelRepository = parcelRepository; + this.parcelService = parcelService; this.deliveryRepository = deliveryRepository; - this.config = config; } @Override public void run() { Parcel updated = new Parcel( - parcel.uuid(), - parcel.sender(), - parcel.name(), - parcel.description(), - parcel.priority(), - parcel.receiver(), - parcel.size(), - parcel.entryLocker(), - parcel.destinationLocker(), - ParcelStatus.DELIVERED); - - - this.parcelRepository.update(updated); + this.parcel.uuid(), + this.parcel.sender(), + this.parcel.name(), + this.parcel.description(), + this.parcel.priority(), + this.parcel.receiver(), + this.parcel.size(), + this.parcel.entryLocker(), + this.parcel.destinationLocker(), + ParcelStatus.DELIVERED + ); + + + this.parcelService.update(updated); this.deliveryRepository.delete(updated.uuid()); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java index fb0e1cba2..5f25602ef 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java @@ -10,7 +10,7 @@ public interface UserManager { User create(UUID uuid, String name); - User getOrCreate(UUID uuid, String name); + void getOrCreate(UUID uuid, String name); CompletableFuture> get(String username); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index 583849893..fcae1b8e6 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -43,20 +43,20 @@ public CompletableFuture> get(String username) { } @Override - public User getOrCreate(UUID uuid, String name) { + public void getOrCreate(UUID uuid, String name) { User userByUUID = this.usersByUUID.get(uuid); if (userByUUID != null) { - return userByUUID; + return; } User userByName = this.usersByName.get(name); if (userByName != null) { - return userByName; + return; } - return this.create(uuid, name); + this.create(uuid, name); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java index 784dbbc5c..073ed0e57 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java @@ -8,7 +8,7 @@ public interface UserRepository { - CompletableFuture save(User user); + void save(User user); CompletableFuture changeName(UUID uuid, String newName); diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index c2da22206..3e279c4cc 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -42,8 +42,8 @@ public CompletableFuture> find(String name) { } @Override - public CompletableFuture save(User user) { - return this.save(UserTable.class, UserTable.from(user)).thenApply(dao -> null); + public void save(User user) { + this.save(UserTable.class, UserTable.from(user)).thenApply(dao -> null); } @Override @@ -70,7 +70,7 @@ public CompletableFuture findPage(Page page) { boolean hasNext = users.size() > page.getLimit(); if (hasNext) { - users.remove(users.size() - 1); + users.removeLast(); } return new UserPageResult(users, hasNext); }); diff --git a/src/test/java/com/eternalcode/parcellockers/TestScheduler.java b/src/test/java/com/eternalcode/parcellockers/TestScheduler.java index 9cc596152..366ab4c3f 100644 --- a/src/test/java/com/eternalcode/parcellockers/TestScheduler.java +++ b/src/test/java/com/eternalcode/parcellockers/TestScheduler.java @@ -2,7 +2,6 @@ import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.commons.scheduler.Task; - import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; @@ -17,75 +16,77 @@ public class TestScheduler implements Scheduler { private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(8); public void shutdown() { - executorService.shutdown(); + this.executorService.shutdown(); } @Override public Task run(Runnable runnable) { - Future future = executorService.submit(runnable); + Future future = this.executorService.submit(runnable); return new TestTask(future, false); } @Override public Task runAsync(Runnable runnable) { - Future future = CompletableFuture.runAsync(runnable, executorService); + Future future = CompletableFuture.runAsync(runnable, this.executorService); return new TestTask(future, false); } @Override public Task runLater(Runnable runnable, Duration duration) { - ScheduledFuture future = executorService.schedule(runnable, duration.toMillis(), TimeUnit.MILLISECONDS); + ScheduledFuture future = this.executorService.schedule(runnable, duration.toMillis(), TimeUnit.MILLISECONDS); return new TestTask(future, false); } @Override public Task runLaterAsync(Runnable runnable, Duration duration) { - ScheduledFuture future = executorService.schedule(() -> CompletableFuture.runAsync(runnable, executorService), duration.toMillis(), TimeUnit.MILLISECONDS); + ScheduledFuture future = this.executorService.schedule(() -> CompletableFuture.runAsync(runnable, + this.executorService), duration.toMillis(), TimeUnit.MILLISECONDS); return new TestTask(future, false); } @Override public Task timer(Runnable runnable, Duration initialDelay, Duration period) { - ScheduledFuture future = executorService.scheduleAtFixedRate(runnable, initialDelay.toMillis(), period.toMillis(), TimeUnit.MILLISECONDS); + ScheduledFuture future = this.executorService.scheduleAtFixedRate(runnable, initialDelay.toMillis(), period.toMillis(), TimeUnit.MILLISECONDS); return new TestTask(future, true); } @Override public Task timerAsync(Runnable runnable, Duration initialDelay, Duration period) { - ScheduledFuture future = executorService.scheduleAtFixedRate(() -> CompletableFuture.runAsync(runnable, executorService), initialDelay.toMillis(), period.toMillis(), TimeUnit.MILLISECONDS); + ScheduledFuture future = this.executorService.scheduleAtFixedRate(() -> CompletableFuture.runAsync(runnable, + this.executorService), initialDelay.toMillis(), period.toMillis(), TimeUnit.MILLISECONDS); return new TestTask(future, true); } @Override public CompletableFuture complete(Supplier supplier) { - return CompletableFuture.supplyAsync(supplier, executorService); + return CompletableFuture.supplyAsync(supplier, this.executorService); } @Override public CompletableFuture completeAsync(Supplier supplier) { - return CompletableFuture.supplyAsync(supplier, executorService); + return CompletableFuture.supplyAsync(supplier, this.executorService); } private record TestTask(Future future, boolean isRepeating) implements Task { @Override public void cancel() { - future.cancel(false); + this.future.cancel(false); } @Override public boolean isCanceled() { - return future.isCancelled(); + return this.future.isCancelled(); } @Override public boolean isAsync() { - return future instanceof CompletableFuture || future instanceof ScheduledFuture; + return this.future instanceof CompletableFuture || this.future instanceof ScheduledFuture; } @Override public boolean isRunning() { - return !future.isDone(); + return !this.future.isDone(); } } } diff --git a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java index 06bc77f10..37dc66a92 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java @@ -7,7 +7,6 @@ import com.eternalcode.parcellockers.configuration.ConfigService; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.repository.LockerCache; import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; import com.eternalcode.parcellockers.shared.Page; @@ -38,42 +37,42 @@ class LockerRepositoryIntegrationTest extends IntegrationTestSpec { @Test void test() { - File dataFolder = tempDir.resolve("ParcelLockers").toFile(); + File dataFolder = this.tempDir.resolve("ParcelLockers").toFile(); PluginConfig config = new ConfigService().create(PluginConfig.class, new File(dataFolder, "config.yml")); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; LockerCache cache = new LockerCache(); - LockerRepository parcelLockerRepository = new LockerRepositoryOrmLite(databaseManager, new TestScheduler(), cache); + LockerRepository parcelLockerRepository = new LockerRepositoryOrmLite(databaseManager, new TestScheduler()); UUID uuid = UUID.randomUUID(); - String description = "Parcel locker description."; + String description = "Parcel locker name."; Position position = new Position(1, 2, 3, "world"); parcelLockerRepository.save(new Locker(uuid, description, position)); - Optional parcelLocker = await(parcelLockerRepository.find(uuid)); + Optional parcelLocker = this.await(parcelLockerRepository.find(uuid)); assertTrue(parcelLocker.isPresent()); assertEquals(uuid, parcelLocker.get().uuid()); - Optional byPosition = await(parcelLockerRepository.find(position)); + Optional byPosition = this.await(parcelLockerRepository.find(position)); assertTrue(byPosition.isPresent()); assertEquals(uuid, byPosition.get().uuid()); - LockerPageResult pageResult = await(parcelLockerRepository.findPage(new Page(0, 28))); + LockerPageResult pageResult = this.await(parcelLockerRepository.findPage(new Page(0, 28))); assertEquals(1, pageResult.lockers().size()); assertEquals(uuid, pageResult.lockers().getFirst().uuid()); - await(parcelLockerRepository.delete(uuid)); - Optional removed = await(parcelLockerRepository.find(uuid)); + this.await(parcelLockerRepository.delete(uuid)); + Optional removed = this.await(parcelLockerRepository.find(uuid)); assertTrue(removed.isEmpty()); } @AfterEach void tearDown() { - if (databaseManager != null) { - databaseManager.disconnect(); + if (this.databaseManager != null) { + this.databaseManager.disconnect(); } } } diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index 654e8c0bf..b73ab8f75 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -9,7 +9,6 @@ import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.parcel.ParcelStatus; -import com.eternalcode.parcellockers.parcel.repository.ParcelCache; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.parcel.repository.ParcelRepositoryOrmLite; import com.eternalcode.parcellockers.shared.Page; @@ -42,7 +41,7 @@ class ParcelRepositoryIntegrationTest extends IntegrationTestSpec { @Test void test() { - File dataFolder = tempDir.resolve("ParcelLockers").toFile(); + File dataFolder = this.tempDir.resolve("ParcelLockers").toFile(); PluginConfig config = new ConfigService().create(PluginConfig.class, new File(dataFolder, "config.yml")); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; @@ -70,7 +69,7 @@ void test() { assertEquals(1, bySender.size()); assertEquals(uuid, bySender.getFirst().uuid()); - PageResult pageResult = this.await(parcelRepository.findPage(new Page(0, 28))); + PageResult pageResult = this.await(parcelRepository.findPage(new Page(0, 28))); assertEquals(1, pageResult.parcels().size()); assertEquals(uuid, pageResult.parcels().getFirst().uuid()); diff --git a/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java b/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java index 6f5bf581c..19cc56f1c 100644 --- a/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java +++ b/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java @@ -1,7 +1,6 @@ package com.eternalcode.parcellockers.locker.repository; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -21,63 +20,63 @@ class LockerCacheTest { @BeforeEach void setUp() { - lockerCache = new LockerCache(); - testPosition = new Position(10, 20, 30, "world"); - testLocker = new Locker(UUID.randomUUID(), "Test locker", testPosition); + this.lockerCache = new LockerCache(); + this.testPosition = new Position(10, 20, 30, "world"); + this.testLocker = new Locker(UUID.randomUUID(), "Test locker", this.testPosition); } @Test void shouldPutAndGetLockerByUuid() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when - Optional result = lockerCache.get(testLocker.uuid()); + Optional result = this.lockerCache.get(this.testLocker.uuid()); // then assertTrue(result.isPresent()); - assertEquals(testLocker, result.get()); + assertEquals(this.testLocker, result.get()); } @Test void shouldPutAndGetLockerByPosition() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when - Optional result = lockerCache.get(testPosition); + Optional result = this.lockerCache.get(this.testPosition); // then assertTrue(result.isPresent()); - assertEquals(testLocker, result.get()); + assertEquals(this.testLocker, result.get()); } @Test void shouldRemoveLockerByUuid() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when - Locker removed = lockerCache.remove(testLocker.uuid()); + Locker removed = this.lockerCache.remove(this.testLocker.uuid()); // then - assertEquals(testLocker, removed); - assertFalse(lockerCache.get(testLocker.uuid()).isPresent()); - assertFalse(lockerCache.get(testPosition).isPresent()); + assertEquals(this.testLocker, removed); + assertFalse(this.lockerCache.get(this.testLocker.uuid()).isPresent()); + assertFalse(this.lockerCache.get(this.testPosition).isPresent()); } @Test void shouldRemoveLockerByObject() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when - Locker removed = lockerCache.remove(testLocker); + Locker removed = this.lockerCache.remove(this.testLocker); // then - assertEquals(testLocker, removed); - assertFalse(lockerCache.get(testLocker.uuid()).isPresent()); - assertFalse(lockerCache.get(testPosition).isPresent()); + assertEquals(this.testLocker, removed); + assertFalse(this.lockerCache.get(this.testLocker.uuid()).isPresent()); + assertFalse(this.lockerCache.get(this.testPosition).isPresent()); } @Test @@ -91,47 +90,47 @@ void shouldPutAllLockers() { ); // when - lockerCache.putAll(lockers); + this.lockerCache.putAll(lockers); // then - assertTrue(lockerCache.get(locker1.uuid()).isPresent()); - assertTrue(lockerCache.get(locker2.uuid()).isPresent()); - assertTrue(lockerCache.get(locker1.position()).isPresent()); - assertTrue(lockerCache.get(locker2.position()).isPresent()); + assertTrue(this.lockerCache.get(locker1.uuid()).isPresent()); + assertTrue(this.lockerCache.get(locker2.uuid()).isPresent()); + assertTrue(this.lockerCache.get(locker1.position()).isPresent()); + assertTrue(this.lockerCache.get(locker2.position()).isPresent()); } @Test void shouldClearCache() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when - lockerCache.clear(); + this.lockerCache.clear(); // then - assertFalse(lockerCache.get(testLocker.uuid()).isPresent()); - assertFalse(lockerCache.get(testPosition).isPresent()); - assertEquals(0, lockerCache.cache().size()); + assertFalse(this.lockerCache.get(this.testLocker.uuid()).isPresent()); + assertFalse(this.lockerCache.get(this.testPosition).isPresent()); + assertEquals(0, this.lockerCache.cache().size()); } @Test void shouldReturnCorrectSize() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when & then - assertEquals(1, lockerCache.cache().size()); - assertEquals(1, lockerCache.positionCache().size()); + assertEquals(1, this.lockerCache.cache().size()); + assertEquals(1, this.lockerCache.positionCache().size()); } @Test void shouldReturnUnmodifiableMaps() { // given - lockerCache.put(testLocker); + this.lockerCache.put(this.testLocker); // when - Map cache = lockerCache.cache(); - Map positionCache = lockerCache.positionCache(); + Map cache = this.lockerCache.cache(); + Map positionCache = this.lockerCache.positionCache(); // then assertThrows(UnsupportedOperationException.class, () -> cache.clear()); diff --git a/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java b/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java index b08b59f86..1389c0c83 100644 --- a/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java +++ b/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java @@ -22,12 +22,12 @@ class ParcelCacheTest { @BeforeEach void setUp() { - parcelCache = new ParcelCache(); - testParcel = new Parcel( + this.parcelCache = new ParcelCache(); + this.testParcel = new Parcel( UUID.randomUUID(), UUID.randomUUID(), "Test Package", - "Test package description", + "Test package name", false, UUID.randomUUID(), ParcelSize.MEDIUM, @@ -40,20 +40,20 @@ void setUp() { @Test void shouldPutAndGetParcel() { // given - parcelCache.put(testParcel); + this.parcelCache.put(this.testParcel); // when - Optional result = parcelCache.get(testParcel.uuid()); + Optional result = this.parcelCache.get(this.testParcel.uuid()); // then assertTrue(result.isPresent()); - assertEquals(testParcel, result.get()); + assertEquals(this.testParcel, result.get()); } @Test void shouldReturnEmptyWhenParcelNotFound() { // when - Optional result = parcelCache.get(UUID.randomUUID()); + Optional result = this.parcelCache.get(UUID.randomUUID()); // then assertFalse(result.isPresent()); @@ -62,20 +62,20 @@ void shouldReturnEmptyWhenParcelNotFound() { @Test void shouldRemoveParcel() { // given - parcelCache.put(testParcel); + this.parcelCache.put(this.testParcel); // when - Parcel removed = parcelCache.remove(testParcel.uuid()); + Parcel removed = this.parcelCache.remove(this.testParcel.uuid()); // then - assertEquals(testParcel, removed); - assertFalse(parcelCache.get(testParcel.uuid()).isPresent()); + assertEquals(this.testParcel, removed); + assertFalse(this.parcelCache.get(this.testParcel.uuid()).isPresent()); } @Test void shouldReturnNullWhenRemovingNonExistentParcel() { // when - Parcel removed = parcelCache.remove(UUID.randomUUID()); + Parcel removed = this.parcelCache.remove(UUID.randomUUID()); // then assertNull(removed); @@ -116,48 +116,48 @@ void shouldPutAllParcels() { ); // when - parcelCache.putAll(parcels); + this.parcelCache.putAll(parcels); // then - assertTrue(parcelCache.get(parcel1.uuid()).isPresent()); - assertTrue(parcelCache.get(parcel2.uuid()).isPresent()); - assertEquals(2, parcelCache.cache().size()); + assertTrue(this.parcelCache.get(parcel1.uuid()).isPresent()); + assertTrue(this.parcelCache.get(parcel2.uuid()).isPresent()); + assertEquals(2, this.parcelCache.cache().size()); } @Test void shouldClearCache() { // given - parcelCache.put(testParcel); + this.parcelCache.put(this.testParcel); // when - parcelCache.clear(); + this.parcelCache.clear(); // then - assertFalse(parcelCache.get(testParcel.uuid()).isPresent()); - assertEquals(0, parcelCache.cache().size()); + assertFalse(this.parcelCache.get(this.testParcel.uuid()).isPresent()); + assertEquals(0, this.parcelCache.cache().size()); } @Test void shouldReturnCorrectSize() { // given - parcelCache.put(testParcel); + this.parcelCache.put(this.testParcel); // when & then - assertEquals(1, parcelCache.cache().size()); + assertEquals(1, this.parcelCache.cache().size()); } @Test void shouldReturnUnmodifiableMap() { // given - parcelCache.put(testParcel); + this.parcelCache.put(this.testParcel); // when - Map cache = parcelCache.cache(); + Map cache = this.parcelCache.cache(); // then assertThrows(UnsupportedOperationException.class, () -> cache.clear()); assertEquals(1, cache.size()); - assertTrue(cache.containsKey(testParcel.uuid())); + assertTrue(cache.containsKey(this.testParcel.uuid())); } @Test @@ -166,10 +166,10 @@ void shouldWorkWithCustomConfiguration() { ParcelCache cache = new ParcelCache(); // when - cache.put(testParcel); + cache.put(this.testParcel); // then - assertTrue(cache.get(testParcel.uuid()).isPresent()); + assertTrue(cache.get(this.testParcel.uuid()).isPresent()); assertEquals(1, cache.cache().size()); } } From 65992b9161dc7c25c38a9a104334a61e6646b115 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:03:16 +0200 Subject: [PATCH 18/51] more refactoring... --- .../parcellockers/ParcelLockers.java | 73 ++++---- .../command/debug/DebugCommand.java | 89 ++++------ .../implementation/MessageConfig.java | 16 +- .../implementation/PluginConfig.java | 2 - .../content/ParcelContentManager.java | 68 ++++++++ .../ParcelContentRepositoryOrmLite.java | 4 +- .../database/persister/PositionPersister.java | 26 +-- .../delivery/DeliveryManager.java | 41 +++++ .../parcellockers/gui/GuiManager.java | 104 ++++++----- .../implementation/locker/CollectionGui.java | 2 +- .../implementation/locker/ItemStorageGui.java | 18 +- .../gui/implementation/locker/LockerGui.java | 15 +- .../implementation/locker/ReceiverGui.java | 8 +- .../gui/implementation/locker/SendingGui.java | 43 ++--- .../implementation/remote/ParcelListGui.java | 2 +- .../implementation/remote/SentParcelsGui.java | 2 +- .../itemstorage/ItemStorageManager.java | 69 ++++++++ .../ItemStorageRepositoryOrmLite.java | 2 +- .../parcellockers/locker/LockerManager.java | 21 +++ .../LockerInteractionController.java | 4 +- .../controller/LockerPlaceController.java | 42 ++--- .../prompt/LockerPlacePrompt.java} | 4 +- .../repository/LockerRepositoryOrmLite.java | 25 ++- .../parcellockers/parcel/Parcel.java | 22 +-- .../parcellockers/parcel/ParcelService.java | 27 ++- .../parcel/ParcelServiceImpl.java | 162 ++++++++++++++---- .../parcel/repository/ParcelRepository.java | 10 +- .../repository/ParcelRepositoryOrmLite.java | 16 +- .../parcel/task/ParcelSendTask.java | 10 +- .../parcel/util/PlaceholderUtil.java | 3 +- .../parcellockers/shared/PageResult.java | 2 +- .../parcellockers/updater/UpdaterService.java | 9 +- .../parcellockers/user/UserManager.java | 4 +- .../parcellockers/user/UserManagerImpl.java | 4 +- .../user/repository/UserPageResult.java | 8 - .../user/repository/UserRepository.java | 3 +- .../repository/UserRepositoryOrmLite.java | 7 +- .../ParcelRepositoryIntegrationTest.java | 9 +- 38 files changed, 636 insertions(+), 340 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java create mode 100644 src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java create mode 100644 src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java rename src/main/java/com/eternalcode/parcellockers/{conversation/ParcelLockerPlacePrompt.java => locker/prompt/LockerPlacePrompt.java} (87%) delete mode 100644 src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 9cc739b81..2afa460a8 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -10,15 +10,19 @@ import com.eternalcode.parcellockers.configuration.ConfigService; import com.eternalcode.parcellockers.configuration.implementation.MessageConfig; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.content.ParcelContentManager; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.content.repository.ParcelContentRepositoryOrmLite; import com.eternalcode.parcellockers.database.DatabaseManager; +import com.eternalcode.parcellockers.delivery.DeliveryManager; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepositoryOrmLite; +import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.implementation.locker.LockerGui; import com.eternalcode.parcellockers.gui.implementation.remote.MainGui; -import com.eternalcode.parcellockers.gui.implementation.remote.ParcelListGui; +import com.eternalcode.parcellockers.itemstorage.ItemStorageManager; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepositoryOrmLite; +import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.locker.controller.LockerBreakController; import com.eternalcode.parcellockers.locker.controller.LockerInteractionController; import com.eternalcode.parcellockers.locker.controller.LockerPlaceController; @@ -99,20 +103,41 @@ public void onEnable() { .threadPool(20) .build(); + // database repositories + ParcelRepositoryOrmLite parcelRepository = new ParcelRepositoryOrmLite(databaseManager, scheduler); LockerRepositoryOrmLite lockerRepository = new LockerRepositoryOrmLite(databaseManager, scheduler); - - ParcelRepositoryOrmLite parcelRepository = new ParcelRepositoryOrmLite(databaseManager, scheduler, parcelCache); - - DeliveryRepositoryOrmLite deliveryRepository = new DeliveryRepositoryOrmLite(databaseManager, scheduler); - ParcelContentRepository parcelContentRepository = new ParcelContentRepositoryOrmLite(databaseManager, scheduler); - ParcelService parcelService = new ParcelServiceImpl(config, - noticeService, parcelRepository, deliveryRepository, parcelContentRepository, scheduler); - + DeliveryRepositoryOrmLite deliveryRepository = new DeliveryRepositoryOrmLite(databaseManager, scheduler); ItemStorageRepository itemStorageRepository = new ItemStorageRepositoryOrmLite(databaseManager, scheduler); - UserRepository userRepository = new UserRepositoryOrmLite(databaseManager, scheduler); + + // service and managers + ParcelService parcelService = new ParcelServiceImpl( + config, + noticeService, + parcelRepository, + deliveryRepository, + parcelContentRepository, + scheduler + ); + UserManager userManager = new UserManagerImpl(userRepository); + LockerManager lockerManager = new LockerManager(lockerRepository); + ParcelContentManager parcelContentManager = new ParcelContentManager(parcelContentRepository); + ItemStorageManager itemStorageManager = new ItemStorageManager(itemStorageRepository); + DeliveryManager deliveryManager = new DeliveryManager(deliveryRepository); + + // guis + GuiManager guiManager = new GuiManager( + config, + scheduler, + parcelService, + lockerManager, + userManager, + itemStorageManager, + parcelContentManager, + deliveryManager + ); MainGui mainGUI = new MainGui( scheduler, @@ -120,13 +145,6 @@ public void onEnable() { config.guiSettings, guiManager ); - ParcelListGui parcelListGUI = new ParcelListGui( - scheduler, - miniMessage, - config.guiSettings, - guiManager, - mainGUI - ); this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .extension(new LiteAdventureExtension<>()) @@ -135,7 +153,7 @@ public void onEnable() { .commands(LiteCommandsAnnotations.of( new ParcelCommand(mainGUI), new ParcelLockersCommand(configManager, config, noticeService), - new DebugCommand(parcelRepository, lockerRepository, itemStorageRepository, parcelContentRepository, noticeService) + new DebugCommand(parcelService, lockerManager, itemStorageManager, parcelContentManager, deliveryManager, userManager, noticeService) )) .invalidUsage(new InvalidUsageHandlerImpl(noticeService)) .missingPermission(new MissingPermissionsHandlerImpl(noticeService)) @@ -145,26 +163,21 @@ public void onEnable() { miniMessage, scheduler, config.guiSettings, - itemStorageRepository, - parcelRepository, - lockerRepository, + guiManager, noticeService, - parcelContentRepository, - userRepository, - this.skullAPI, - parcelService + this.skullAPI ); Stream.of( - new LockerInteractionController(lockerCache, lockerGUI), - new LockerPlaceController(config, this, lockerRepository, noticeService), - new LockerBreakController(lockerRepository, lockerCache, noticeService), + new LockerInteractionController(lockerManager, lockerGUI), + new LockerPlaceController(config, this, lockerManager, noticeService), + new LockerBreakController(lockerManager, noticeService), new PrepareUserController(userManager), new LoadUserController(userManager, server) ).forEach(controller -> server.getPluginManager().registerEvents(controller, this)); new Metrics(this, 17677); - new UpdaterService(this.getDescription()); + new UpdaterService(this.getPluginMeta().getVersion()); parcelRepository.findAll().thenAccept(optionalParcels -> { List parcels = optionalParcels.orElseGet(ArrayList::new).stream() @@ -176,7 +189,7 @@ public void onEnable() { optionalDelivery.ifPresent(delivery -> { long delay = Math.max(0, delivery.deliveryTimestamp().toEpochMilli() - System.currentTimeMillis()); scheduler.runLaterAsync( - new ParcelSendTask(parcel, parcelService, deliveryRepository), + new ParcelSendTask(parcel, parcelService, deliveryManager), Duration.ofMillis(delay) ); }) diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index 87525137f..a48084ed7 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -1,11 +1,14 @@ package com.eternalcode.parcellockers.command.debug; +import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.multification.notice.Notice; -import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; -import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.content.ParcelContentManager; +import com.eternalcode.parcellockers.delivery.DeliveryManager; +import com.eternalcode.parcellockers.itemstorage.ItemStorageManager; +import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.notification.NoticeService; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; +import com.eternalcode.parcellockers.parcel.ParcelService; +import com.eternalcode.parcellockers.user.UserManager; import dev.rollczi.litecommands.annotations.argument.Arg; import dev.rollczi.litecommands.annotations.command.Command; import dev.rollczi.litecommands.annotations.context.Sender; @@ -26,82 +29,50 @@ @Permission("parcellockers.debug") public class DebugCommand { - private final ParcelRepository parcelRepository; - private final LockerRepository lockerRepository; - private final ItemStorageRepository itemStorageRepository; - private final ParcelContentRepository contentRepository; + private final ParcelService parcelService; + private final LockerManager lockerManager; + private final ItemStorageManager itemStorageManager; + private final ParcelContentManager contentManager; + private final DeliveryManager deliveryManager; + private final UserManager userManager; private final NoticeService noticeService; public DebugCommand( - ParcelRepository parcelRepository, - LockerRepository lockerRepository, - ItemStorageRepository itemStorageRepository, - ParcelContentRepository contentRepository, + ParcelService parcelService, + LockerManager lockerManager, + ItemStorageManager itemStorageManager, + ParcelContentManager contentManager, + DeliveryManager deliveryManager, + UserManager userManager, NoticeService noticeService ) { - this.parcelRepository = parcelRepository; - this.lockerRepository = lockerRepository; - this.itemStorageRepository = itemStorageRepository; - this.contentRepository = contentRepository; + this.parcelService = parcelService; + this.lockerManager = lockerManager; + this.itemStorageManager = itemStorageManager; + this.contentManager = contentManager; + this.deliveryManager = deliveryManager; + this.userManager = userManager; this.noticeService = noticeService; } @Execute(name = "delete parcels") void deleteParcels(@Sender CommandSender sender) { - this.parcelRepository.removeAll().exceptionally(throwable -> { - this.noticeService.create() - .notice(Notice.chat("&4Failed to delete parcels")) - .viewer(sender) - .send(); - return null; - }).thenRun(() -> this.noticeService.create() - .notice(Notice.chat("&cParcels deleted")) - .viewer(sender) - .send()); + this.parcelService.deleteAll(sender, this.noticeService); } @Execute(name = "delete lockers") void deleteLockers(@Sender CommandSender sender) { - this.lockerRepository.deleteAll().exceptionally(throwable -> { - this.noticeService.create() - .notice(Notice.chat("&4Failed to delete lockers")) - .viewer(sender) - .send(); - return null; - }).thenRun(() -> this.noticeService.create() - .notice(Notice.chat("&cLockers deleted")) - .viewer(sender) - .send()); + this.lockerManager.deleteAll(sender, this.noticeService); } @Execute(name = "delete itemstorages") void deleteItemStorages(@Sender CommandSender sender) { - this.itemStorageRepository.deleteAll() - .exceptionally(throwable -> { - this.noticeService.create() - .notice(Notice.chat("&4Failed to delete item storages")) - .viewer(sender) - .send(); - return null; - }) - .thenRun(() -> this.noticeService.create() - .notice(Notice.chat("&cItem storages deleted")) - .viewer(sender) - .send()); + this.itemStorageManager.deleteAll(sender, this.noticeService); } @Execute(name = "delete items") void deleteItems(@Sender CommandSender sender) { - this.contentRepository.deleteAll().exceptionally(throwable -> { - this.noticeService.create() - .notice(Notice.chat("&4Failed to delete parcel contents")) - .viewer(sender) - .send(); - return null; - }).thenRun(() -> this.noticeService.create() - .notice(Notice.chat("&cParcel contents deleted")) - .viewer(sender) - .send()); + this.contentManager.deleteAll(sender, this.noticeService); } @Execute(name = "delete all") @@ -140,7 +111,7 @@ void getRandomItem(@Sender Player player, @Arg int stacks) { int randomAmount = Math.min(random.nextInt(64) + 1, randomMaterial.getMaxStackSize()); ItemStack itemStack = new ItemStack(randomMaterial, randomAmount); - player.getInventory().addItem(itemStack); + ItemUtil.giveItem(player, itemStack); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 6d84b87a9..4ae88f1c4 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -34,6 +34,10 @@ public class MessageConfig extends OkaeriConfig { @Comment("# These messages are used when creating, deleting, or managing parcel lockers.") public LockerMessages locker = new LockerMessages(); + @Comment({"", "# Messages related to admin commands can be configured here." }) + @Comment("# These messages are used for administrative actions such as deleting all lockers or parcels.") + public AdminMessages admin = new AdminMessages(); + public static class ParcelMessages extends OkaeriConfig { public Notice sent = Notice.builder() .chat("&2โœ” &aParcel sent successfully.") @@ -86,7 +90,6 @@ public static class ParcelMessages extends OkaeriConfig { .build(); public Notice illegalItem = Notice.builder() .chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})") - .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) .build(); public Notice cannotDelete = Notice.builder() .chat("&4โœ˜ &cAn error occurred while deleting the parcel.") @@ -140,4 +143,15 @@ public static class LockerMessages extends OkaeriConfig { .sound(Sound.ENTITY_VILLAGER_NO.key()) .build(); } + + public static class AdminMessages extends OkaeriConfig { + public Notice deletedLockers = Notice.chat("&4โš  &cAll parcel lockers have been deleted!"); + public Notice deletedParcels = Notice.chat("&4โš  &cAll parcels have been deleted!"); + public Notice deletedItemStorages = Notice.chat("&4โš  &cAll item storages have been deleted!"); + public Notice deletedContents = Notice.chat("&4โš  &cAll parcel contents have been deleted!"); + public Notice deletedDeliveries = Notice.chat("&4โš  &cAll deliveries have been deleted!"); + public Notice deletedUsers = Notice.chat("&4โš  &cAll users have been deleted!"); + public Notice invalidNumberOfStacks = Notice.chat("&4โœ˜ &cInvalid number of stacks. Must be between 1 and 36."); + public Notice invalidItemMaterials = Notice.chat("&4โœ˜ &cItem materials to give are invalid (should never happen, if it does report this on our discord)."); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 0a616f1a8..7b9933073 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -197,7 +197,6 @@ public static class GuiSettings extends OkaeriConfig { public ConfigItem parcelItem = new ConfigItem() .name("&6{NAME}") .lore(List.of( - "&6UUID: &e{UUID}", "&6Sender: &e{SENDER}", "&6Receiver: &e{RECEIVER}", "&6Size: &e{SIZE}", @@ -318,7 +317,6 @@ public static class GuiSettings extends OkaeriConfig { public ConfigItem parcelCollectionItem = new ConfigItem() .name("&a{NAME}") .lore(List.of( - "&6UUID: &e{UUID}", "&6Sender: &e{SENDER}", "&6Size: &e{SIZE}", "&6Description: &e{DESCRIPTION}" diff --git a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java new file mode 100644 index 000000000..5e1bfddc5 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java @@ -0,0 +1,68 @@ +package com.eternalcode.parcellockers.content; + +import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; +import com.eternalcode.parcellockers.notification.NoticeService; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.bukkit.command.CommandSender; +import org.bukkit.inventory.ItemStack; + +public class ParcelContentManager { + + private final Cache cache = Caffeine.newBuilder() + .expireAfterWrite(6, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); + + private final ParcelContentRepository contentRepository; + + public ParcelContentManager(ParcelContentRepository contentRepository) { + this.contentRepository = contentRepository; + } + + public CompletableFuture> get(UUID parcelId) { + ParcelContent content = this.cache.getIfPresent(parcelId); + if (content != null) { + return CompletableFuture.completedFuture(Optional.of(content)); + } + return this.contentRepository.find(parcelId).thenApply(optional -> { + optional.ifPresent(value -> this.cache.put(parcelId, value)); + return optional; + }); + } + + public ParcelContent getOrCreate(UUID parcelId, List items) { + return this.cache.get(parcelId, key -> this.create(key, items)); + } + + public ParcelContent create(UUID parcel, List items) { + ParcelContent content = new ParcelContent(parcel, items); + if (this.cache.getIfPresent(parcel) != null) { + throw new IllegalStateException("ParcelContent for parcel " + parcel + " already exists. Use ParcelContentManager#getOrCreate method instead."); + } + this.cache.put(parcel, content); + this.contentRepository.save(content); + return content; + } + + public void delete(UUID parcel) { + this.cache.invalidate(parcel); + this.contentRepository.delete(parcel); + } + + public void deleteAll(CommandSender sender, NoticeService noticeService) { + this.contentRepository.deleteAll().thenAccept(deleted -> { + noticeService.create() + .viewer(sender) + .notice(messages -> messages.admin.deletedContents) + .placeholder("{COUNT}", deleted.toString()) + .send(); + this.cache.invalidateAll(); + }); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java index e1cb1fca3..e899d43be 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java @@ -40,7 +40,7 @@ public CompletableFuture deleteAll() { @Override public CompletableFuture> find(UUID uniqueId) { - return this.select(ParcelContentTable.class, uniqueId).thenApply(parcelContentTable -> Optional.ofNullable( - parcelContentTable.toParcelContent())); + return this.selectSafe(ParcelContentTable.class, uniqueId) + .thenApply(optional -> optional.map(ParcelContentTable::toParcelContent)); } } diff --git a/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java b/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java index bddf9e571..8a44b1a5c 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java +++ b/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java @@ -5,7 +5,6 @@ import com.j256.ormlite.field.SqlType; import com.j256.ormlite.field.types.BaseDataType; import com.j256.ormlite.support.DatabaseResults; - import java.sql.SQLException; public class PositionPersister extends BaseDataType { @@ -23,13 +22,7 @@ public static PositionPersister getSingleton() { @Override public Object javaToSqlArg(FieldType fieldType, Object javaObject) { Position pos = (Position) javaObject; - String worldName = "world"; - - if (!pos.isNoneWorld()) { - worldName = pos.world(); - } - - return worldName + "/" + pos.x() + "/" + pos.y() + "/" + pos.z(); + return pos.toString(); } @@ -45,21 +38,8 @@ public Object parseDefaultString(FieldType fieldType, String defaultStr) { @Override public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) { - String s = (String) sqlArg; - String[] params = s.split("/"); - if (params.length != 4) { - throw new IllegalArgumentException("Invalid position format: " + s); - } - try { - return new Position( - Integer.parseInt(params[1]), - Integer.parseInt(params[2]), - Integer.parseInt(params[3]), - params[0] - ); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid coordinate format: " + s, e); - } + String string = (String) sqlArg; + return Position.parse(string); } } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java new file mode 100644 index 000000000..37ce1ba4a --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java @@ -0,0 +1,41 @@ +package com.eternalcode.parcellockers.delivery; + +import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.time.Duration; +import java.time.Instant; +import java.util.UUID; + +public class DeliveryManager { + + private final DeliveryRepository deliveryRepository; + + private final Cache deliveryCache = Caffeine.newBuilder() + .maximumSize(10_000) + .expireAfterAccess(Duration.ofHours(6)) + .build(); + + public DeliveryManager(DeliveryRepository deliveryRepository) { + this.deliveryRepository = deliveryRepository; + } + + public Delivery getOrCreate(UUID parcel, Instant deliveryTimestamp) { + return this.deliveryCache.get(parcel, key -> this.create(key, deliveryTimestamp)); + } + + public Delivery create(UUID parcel, Instant deliveryTimestamp) { + Delivery delivery = new Delivery(parcel, deliveryTimestamp); + if (this.deliveryCache.getIfPresent(parcel) != null) { + throw new IllegalStateException("Delivery for parcel " + parcel + " already exists. Use Delivery#getOrCreate method instead."); + } + this.deliveryCache.put(parcel, delivery); + this.deliveryRepository.save(delivery); + return delivery; + } + + public void delete(UUID parcel) { + this.deliveryCache.invalidate(parcel); + this.deliveryRepository.delete(parcel); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java index ee3e4cf63..ab760955a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java @@ -1,20 +1,22 @@ package com.eternalcode.parcellockers.gui; -import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; -import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; +import com.eternalcode.commons.scheduler.Scheduler; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.content.ParcelContentManager; +import com.eternalcode.parcellockers.delivery.DeliveryManager; import com.eternalcode.parcellockers.itemstorage.ItemStorage; -import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; +import com.eternalcode.parcellockers.itemstorage.ItemStorageManager; import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.locker.LockerManager; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; -import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; +import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.user.User; import com.eternalcode.parcellockers.user.UserManager; -import com.eternalcode.parcellockers.user.repository.UserPageResult; +import java.time.Duration; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -24,46 +26,67 @@ public class GuiManager { - private final ParcelRepository parcelRepository; + private final PluginConfig config; + private final Scheduler scheduler; private final ParcelService parcelService; - private final LockerRepository lockerRepository; - private final DeliveryRepository deliveryRepository; - private final ItemStorageRepository itemStorageRepository; - private final ParcelContentRepository contentRepository; - private final UserManager userManager; private final LockerManager lockerManager; + private final UserManager userManager; + private final ItemStorageManager itemStorageManager; + private final ParcelContentManager parcelContentManager; + private final DeliveryManager deliveryManager; public GuiManager( - ParcelRepository parcelRepository, ParcelService parcelService, - LockerRepository lockerRepository, - DeliveryRepository deliveryRepository, - ItemStorageRepository itemStorageRepository, - ParcelContentRepository contentRepository, - UserManager userManager, LockerManager lockerManager + PluginConfig config, Scheduler scheduler, ParcelService parcelService, + LockerManager lockerManager, + UserManager userManager, + ItemStorageManager itemStorageManager, + ParcelContentManager parcelContentManager, + DeliveryManager deliveryManager ) { - this.parcelRepository = parcelRepository; + this.config = config; + this.scheduler = scheduler; this.parcelService = parcelService; - this.lockerRepository = lockerRepository; - this.deliveryRepository = deliveryRepository; - this.itemStorageRepository = itemStorageRepository; - this.contentRepository = contentRepository; - this.userManager = userManager; this.lockerManager = lockerManager; + this.userManager = userManager; + this.itemStorageManager = itemStorageManager; + this.parcelContentManager = parcelContentManager; + this.deliveryManager = deliveryManager; + } + + public void sendParcel(Player sender, Parcel parcel, List items) { + Duration delay = parcel.priority() + ? this.config.settings.priorityParcelSendDuration + : this.config.settings.parcelSendDuration; + this.parcelService.send(sender, parcel, items); + this.deliveryManager.create(parcel.uuid(), Instant.now().plus(delay)); + this.parcelContentManager.create(parcel.uuid(), items); + + ParcelSendTask task = new ParcelSendTask( + parcel, + this.parcelService, + this.deliveryManager + ); + + this.scheduler.runLaterAsync(task, delay); + } + + public void collectParcel(Player player, Parcel parcel) { + this.parcelService.collect(player, parcel); } - public CompletableFuture> getParcelByReceiver(UUID receiver, Page page) { - return this.parcelRepository.findByReceiver(receiver, page); + public CompletableFuture> getParcelsByReceiver(UUID receiver, Page page) { + return this.parcelService.getByReceiver(receiver, page); } - public CompletableFuture>> getParcelBySender(UUID sender) { - return this.parcelRepository.findBySender(sender); + public CompletableFuture>> getParcelsBySender(UUID sender) { + return this.parcelService.getBySender(sender); } public CompletableFuture> getUser(UUID userUuid) { return this.userManager.get(userUuid); } - public CompletableFuture getUserPage(Page page) { + public CompletableFuture> getUsers(Page page) { return this.userManager.getPage(page); } @@ -72,26 +95,19 @@ public CompletableFuture> getLocker(UUID lockerUuid) { } public CompletableFuture> getLockerPage(Page page) { - return this.lockerRepository.findPage(page); - } - - public CompletableFuture> getItemStorage(UUID owner) { - return this.itemStorageRepository.find(owner); + return this.lockerManager.get(page); } - public boolean sendParcel(Player sender, Parcel parcel, List items) { - return this.parcelService.send(sender, parcel, items); - } - - public void collectParcel(Player player, Parcel parcel) { - this.parcelService.collect(player, parcel); + public CompletableFuture getItemStorage(UUID owner) { + return this.itemStorageManager.get(owner) + .thenApply(optional -> optional.orElse(new ItemStorage(owner, List.of()))); } - public void saveItemStorage(ItemStorage itemStorage) { - this.itemStorageRepository.save(itemStorage); + public void saveItemStorage(UUID player, List items) { + this.itemStorageManager.create(player, items); } - public CompletableFuture deleteItemStorage(UUID owner) { - return this.itemStorageRepository.delete(owner); + public void deleteItemStorage(UUID owner) { + this.itemStorageManager.delete(owner); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index cd1b8b68a..1e19fade2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -78,7 +78,7 @@ private void show(Player player, Page page) { gui.setItem(49, closeItem); - this.guiManager.getParcelByReceiver(player.getUniqueId(), page).thenAccept(result -> { + this.guiManager.getParcelsByReceiver(player.getUniqueId(), page).thenAccept(result -> { if (result == null || result.items().isEmpty()) { gui.setItem(22, this.guiSettings.noParcelsItem.toGuiItem()); this.scheduler.run(() -> gui.open(player)); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index cd2b28b00..987d14b41 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -4,7 +4,6 @@ import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.gui.GuiManager; -import com.eternalcode.parcellockers.itemstorage.ItemStorage; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.util.MaterialUtil; @@ -110,21 +109,14 @@ void show(Player player, ParcelSize size) { items.add(item); } - this.guiManager.deleteItemStorage(player.getUniqueId()).thenAccept( - unused -> this.guiManager.saveItemStorage(new ItemStorage(player.getUniqueId(), items)) - ); + this.guiManager.deleteItemStorage(player.getUniqueId()); + this.guiManager.saveItemStorage(player.getUniqueId(), items); }); - this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(optional -> { - if (optional.isPresent()) { - ItemStorage itemStorage = optional.get(); - - for (ItemStack item : itemStorage.items()) { - gui.addItem(item); - } - } - + this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(itemStorage -> { + gui.addItem(itemStorage.items()); this.scheduler.run(() -> gui.open(player)); }); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java index 9af1c8824..11b161564 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java @@ -7,9 +7,13 @@ import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.notification.NoticeService; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; +import java.util.UUID; +import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; @@ -23,6 +27,10 @@ public class LockerGui implements GuiView { private final NoticeService noticeService; private final SkullAPI skullAPI; + private final Cache userEntryLockerCache = Caffeine.newBuilder() + .expireAfterAccess(2, TimeUnit.MINUTES) + .build(); + public LockerGui( MiniMessage miniMessage, Scheduler scheduler, GuiSettings guiSettings, GuiManager guiManager, @@ -37,6 +45,11 @@ public LockerGui( this.skullAPI = skullAPI; } + public void show(Player player, UUID entryLocker) { + this.userEntryLockerCache.put(player.getUniqueId(), entryLocker); + this.show(player); + } + @Override public void show(Player player) { Component guiTitle = this.miniMessage.deserialize(this.guiSettings.mainGuiTitle); @@ -75,7 +88,7 @@ public void show(Player player) { this.noticeService, this.guiManager, this.skullAPI, - new SendingGuiState() + new SendingGuiState().entryLocker(this.userEntryLockerCache.getIfPresent(player.getUniqueId())) ).show(player))); gui.setItem(49, closeItem); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index 95893edaf..c7a193d26 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -6,8 +6,8 @@ import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.user.User; -import com.eternalcode.parcellockers.user.repository.UserPageResult; import com.spotify.futures.CompletableFutures; import dev.rollczi.liteskullapi.SkullAPI; import dev.rollczi.liteskullapi.SkullData; @@ -81,7 +81,7 @@ private void show(Player player, Page page) { gui.setItem(49, closeItem); - this.guiManager.getUserPage(page).thenAccept(result -> { + this.guiManager.getUsers(page).thenAccept(result -> { if (result.hasNextPage()) { gui.setItem(51, nextPageItem); } @@ -102,8 +102,8 @@ private void show(Player player, Page page) { }); } - private CompletableFuture>> loadSkulls(Player player, UserPageResult result, PaginatedGuiRefresher refresh) { - return result.users().stream() + private CompletableFuture>> loadSkulls(Player player, PageResult result, PaginatedGuiRefresher refresh) { + return result.items().stream() // .filter(user -> !user.uuid().equals(player.getUniqueId())) .map(user -> this.skullAPI.getSkullData(user.uuid()).thenApply(skullData -> this.toItem(player, user, skullData, refresh))) .collect(CompletableFutures.joinList()); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index d431fb61d..605125f25 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -180,24 +180,20 @@ public void show(Player player) { this.state ); this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(result -> { - if (result.isPresent()) { - int slotsSize = result.get().items().size(); - if (slotsSize <= 9) { - this.scheduler.run(() -> storageGUI.show(player, this.state.size())); - } else if (slotsSize <= 18 && this.state.size() == ParcelSize.SMALL) { - this.scheduler.run(() -> storageGUI.show(player, ParcelSize.MEDIUM)); - } else { - this.scheduler.run(() -> storageGUI.show(player, ParcelSize.LARGE)); - } - } else { + int slotsSize = result.items().size(); + if (slotsSize <= 9) { this.scheduler.run(() -> storageGUI.show(player, this.state.size())); + } else if (slotsSize <= 18 && this.state.size() == ParcelSize.SMALL) { + this.scheduler.run(() -> storageGUI.show(player, ParcelSize.MEDIUM)); + } else { + this.scheduler.run(() -> storageGUI.show(player, ParcelSize.LARGE)); } } ).orTimeout(2, TimeUnit.SECONDS); }); GuiItem submitItem = this.guiSettings.submitParcelItem.toGuiItem(event -> this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(result -> { - if (result.isEmpty() || result.get().items().isEmpty()) { + if (result.items().isEmpty()) { this.noticeService.create() .notice(messages -> messages.parcel.empty) .player(player.getUniqueId()) @@ -213,13 +209,21 @@ public void show(Player player) { return; } - Parcel parcel = new Parcel(UUID.randomUUID(), player.getUniqueId(), this.state.parcelName(), - this.state.parcelDescription(), this.state.priority(), this.state.receiver(), - this.state.size(), this.state.entryLocker(), this.state.destinationLocker(), this.state.status()); - - if (this.guiManager.sendParcel(player, parcel, result.get().items())) { - this.guiManager.deleteItemStorage(player.getUniqueId()); - } + Parcel parcel = new Parcel( + UUID.randomUUID(), + player.getUniqueId(), + this.state.parcelName(), + this.state.parcelDescription(), + this.state.priority(), + this.state.receiver(), + this.state.size(), + this.state.entryLocker(), + this.state.destinationLocker(), + this.state.status() + ); + + this.guiManager.sendParcel(player, parcel, result.items()); + this.guiManager.deleteItemStorage(player.getUniqueId()); this.gui.close(player); }).orTimeout(5, TimeUnit.SECONDS)); @@ -287,8 +291,7 @@ public void show(Player player) { this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.name()))); - - this.gui.open(player); + this.scheduler.run(() -> this.gui.open(player)); } private void setSelected(Gui gui, ParcelSize size) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index e06401eea..189f62c6d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -69,7 +69,7 @@ private void show(Player player, Page page) { gui.setItem(slot, backgroundItem); } - this.guiManager.getParcelByReceiver(player.getUniqueId(), page).thenAccept(result -> { + this.guiManager.getParcelsByReceiver(player.getUniqueId(), page).thenAccept(result -> { if (result.items().isEmpty() && page.hasPrevious()) { this.show(player, page.previous()); return; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index efc7c117d..e3e725147 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -63,7 +63,7 @@ public void show(Player player) { gui.setItem(49, closeItem); - this.guiManager.getParcelBySender(player.getUniqueId()).thenAccept(optionalParcels -> { + this.guiManager.getParcelsBySender(player.getUniqueId()).thenAccept(optionalParcels -> { List parcels = optionalParcels.orElse(Collections.emptyList()); for (Parcel parcel : parcels) { diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java new file mode 100644 index 000000000..68d7f93ad --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -0,0 +1,69 @@ +package com.eternalcode.parcellockers.itemstorage; + +import com.eternalcode.parcellockers.itemstorage.repository.ItemStorageRepository; +import com.eternalcode.parcellockers.notification.NoticeService; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.bukkit.command.CommandSender; +import org.bukkit.inventory.ItemStack; + +public class ItemStorageManager { + + private final Cache cache = Caffeine.newBuilder() + .expireAfterWrite(6, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); + + private final ItemStorageRepository itemStorageRepository; + + public ItemStorageManager(ItemStorageRepository itemStorageRepository) { + this.itemStorageRepository = itemStorageRepository; + } + + public CompletableFuture> get(UUID parcelId) { + ItemStorage content = this.cache.getIfPresent(parcelId); + if (content != null) { + return CompletableFuture.completedFuture(Optional.of(content)); + } + return this.itemStorageRepository.find(parcelId).thenApply(optional -> { + optional.ifPresent(value -> this.cache.put(parcelId, value)); + return optional; + }); + } + + public ItemStorage getOrCreate(UUID parcelId, List items) { + return this.cache.get(parcelId, key -> this.create(key, items)); + } + + public ItemStorage create(UUID parcel, List items) { + ItemStorage content = new ItemStorage(parcel, items); + if (this.cache.getIfPresent(parcel) != null) { + throw new IllegalStateException("ParcelContent for parcel " + parcel + " already exists. Use ParcelContentManager#getOrCreate method instead."); + } + this.cache.put(parcel, content); + this.itemStorageRepository.save(content); + return content; + } + + public void delete(UUID parcel) { + this.cache.invalidate(parcel); + this.itemStorageRepository.delete(parcel); + } + + public void deleteAll(CommandSender sender, NoticeService noticeService) { + this.itemStorageRepository.deleteAll().thenAccept(deleted -> { + noticeService.create() + .viewer(sender) + .notice(messages -> messages.admin.deletedItemStorages) + .placeholder("{COUNT}", deleted.toString()) + .send(); + + this.cache.invalidateAll(); + }); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java index ddbe86191..37a7830a4 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java @@ -24,7 +24,7 @@ public ItemStorageRepositoryOrmLite(DatabaseManager databaseManager, Scheduler s @Override public CompletableFuture save(ItemStorage itemStorage) { - return this.save(ItemStorageTable.class, ItemStorageTable.from(itemStorage.owner(), itemStorage.items())).thenApply(dao -> null); + return this.saveIfNotExist(ItemStorageTable.class, ItemStorageTable.from(itemStorage.owner(), itemStorage.items())).thenApply(dao -> null); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 09f195f20..323c9cae5 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -1,6 +1,9 @@ package com.eternalcode.parcellockers.locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.notification.NoticeService; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.shared.Position; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; @@ -9,6 +12,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import org.bukkit.command.CommandSender; public class LockerManager { @@ -60,6 +64,10 @@ public CompletableFuture> get(Position position) { }); } + public CompletableFuture> get(Page page) { + return this.lockerRepository.findPage(page); + } + public CompletableFuture>> getAll() { List lockers = List.copyOf(this.lockersByUUID.asMap().values()); if (!lockers.isEmpty()) { @@ -114,4 +122,17 @@ public void delete(UUID uniqueId) { return deleted; }); } + + public void deleteAll(CommandSender sender, NoticeService noticeService) { + this.lockerRepository.deleteAll().thenAccept(deleted -> { + noticeService.create() + .notice(messages -> messages.admin.deletedLockers) + .placeholder("{COUNT}", deleted.toString()) + .viewer(sender) + .send(); + + this.lockersByUUID.invalidateAll(); + this.lockersByPosition.invalidateAll(); + }); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java index a84041834..ae6185ec0 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerInteractionController.java @@ -3,6 +3,7 @@ import com.eternalcode.parcellockers.gui.implementation.locker.LockerGui; import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.shared.PositionAdapter; +import java.util.UUID; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -38,9 +39,10 @@ public void onInventoryOpen(PlayerInteractEvent event) { if (optionalLocker.isEmpty()) { return; } + UUID uuid = optionalLocker.get().uuid(); event.setCancelled(true); - this.lockerGUI.show(player); + this.lockerGUI.show(player, uuid); }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java index e175d1ce9..d2b526ff0 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java @@ -1,9 +1,8 @@ package com.eternalcode.parcellockers.locker.controller; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.conversation.ParcelLockerPlacePrompt; -import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.locker.LockerManager; +import com.eternalcode.parcellockers.locker.prompt.LockerPlacePrompt; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.shared.PositionAdapter; import com.github.benmanes.caffeine.cache.Cache; @@ -27,21 +26,21 @@ public class LockerPlaceController implements Listener { private final PluginConfig config; private final Plugin plugin; - private final LockerRepository databaseService; + private final LockerManager lockerManager; private final NoticeService noticeService; private final Cache lockerCreators = Caffeine.newBuilder() .expireAfterWrite(2, TimeUnit.MINUTES) .build(); public LockerPlaceController( - PluginConfig config, - Plugin plugin, - LockerRepository databaseService, - NoticeService noticeService + PluginConfig config, + Plugin plugin, + LockerManager lockerManager, + NoticeService noticeService ) { this.config = config; this.plugin = plugin; - this.databaseService = databaseService; + this.lockerManager = lockerManager; this.noticeService = noticeService; } @@ -98,23 +97,12 @@ public void onBlockPlace(BlockPlaceEvent event) { String description = (String) e.getContext().getSessionData("description"); Location location = event.getBlockPlaced().getLocation(); - this.databaseService.save(new Locker( - UUID.randomUUID(), - description, - PositionAdapter.convert(location))).whenComplete((parcelLocker, throwable) -> { - if (throwable != null) { - throwable.printStackTrace(); - this.noticeService.create() - .player(player.getUniqueId()) - .notice(messages -> messages.locker.cannotCreate) - .send(); - return; - } - this.noticeService.create() - .player(player.getUniqueId()) - .notice(messages -> messages.locker.created) - .send(); - }); + this.lockerManager.create(UUID.randomUUID(), description, PositionAdapter.convert(location)); + + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.locker.created) + .send(); this.lockerCreators.invalidate(player.getUniqueId()); }) @@ -122,7 +110,7 @@ public void onBlockPlace(BlockPlaceEvent event) { .withModality(false) .withLocalEcho(false) .withTimeout(60) - .withFirstPrompt(new ParcelLockerPlacePrompt()); + .withFirstPrompt(new LockerPlacePrompt()); player.beginConversation(conversationFactory.buildConversation(player)); } diff --git a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java b/src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java similarity index 87% rename from src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java rename to src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java index 6f96c0041..487c586d2 100644 --- a/src/main/java/com/eternalcode/parcellockers/conversation/ParcelLockerPlacePrompt.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java @@ -1,4 +1,4 @@ -package com.eternalcode.parcellockers.conversation; +package com.eternalcode.parcellockers.locker.prompt; import org.bukkit.ChatColor; import org.bukkit.conversations.ConversationContext; @@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ParcelLockerPlacePrompt implements Prompt { +public class LockerPlacePrompt implements Prompt { @Override public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) { diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index c3105063c..49e0ee0e6 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -31,7 +31,7 @@ public LockerRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu @Override public CompletableFuture save(Locker locker) { - return this.save(LockerTable.class, LockerTable.from(locker)).thenApply(dao -> null); + return this.saveIfNotExist(LockerTable.class, LockerTable.from(locker)).thenApply(dao -> null); } @Override @@ -48,12 +48,11 @@ public CompletableFuture> find(UUID uuid) { @Override public CompletableFuture> find(Position position) { - // We have to assume that there is only one locker per position return this.action( - LockerTable.class, dao -> { - List lockers = dao.queryForEq("position", position); - return lockers.isEmpty() ? Optional.empty() : Optional.of(lockers.getFirst().toLocker()); - }); + LockerTable.class, dao -> { + List lockers = dao.queryForEq("position", position); + return lockers.isEmpty() ? Optional.empty() : Optional.of(lockers.getFirst().toLocker()); + }); } @Override @@ -69,13 +68,13 @@ public CompletableFuture delete(Locker locker) { @Override public CompletableFuture> findPage(Page page) { return this.action( - LockerTable.class, dao -> { - List lockers = dao.queryBuilder() - .offset((long) page.getOffset()) - .limit((long) page.getLimit() + 1) - .query() - .stream().map(LockerTable::toLocker) - .collect(Collectors.toList()); + LockerTable.class, dao -> { + List lockers = dao.queryBuilder() + .offset((long) page.getOffset()) + .limit((long) page.getLimit() + 1) + .query() + .stream().map(LockerTable::toLocker) + .collect(Collectors.toList()); boolean hasNext = lockers.size() > page.getLimit(); if (hasNext) { diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/Parcel.java b/src/main/java/com/eternalcode/parcellockers/parcel/Parcel.java index 36875f38b..c248c7ed4 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/Parcel.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/Parcel.java @@ -2,14 +2,16 @@ import java.util.UUID; -public record Parcel(UUID uuid, - UUID sender, - String name, - String description, - boolean priority, - UUID receiver, - ParcelSize size, - UUID entryLocker, - UUID destinationLocker, - ParcelStatus status) { +public record Parcel( + UUID uuid, + UUID sender, + String name, + String description, + boolean priority, + UUID receiver, + ParcelSize size, + UUID entryLocker, + UUID destinationLocker, + ParcelStatus status +) { } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index 06f643be9..d711e9720 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -1,17 +1,40 @@ package com.eternalcode.parcellockers.parcel; +import com.eternalcode.parcellockers.notification.NoticeService; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; public interface ParcelService { - void collect(Player player, Parcel parcel); + void send(Player sender, Parcel parcel, List items); void update(Parcel parcel); + void collect(Player player, Parcel parcel); + void delete(CommandSender sender, Parcel parcel); - boolean send(Player sender, Parcel parcel, List items); + void deleteAll(CommandSender sender, NoticeService noticeService); + + CompletableFuture> get(UUID uuid); + + CompletableFuture>> getBySender(UUID sender); + + CompletableFuture>> getByReceiver(UUID receiver); + + CompletableFuture> getByReceiver(UUID receiver, Page page); + + CompletableFuture>> getAll(); + + CompletableFuture delete(UUID uuid); + + CompletableFuture delete(Parcel parcel); + } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 2218f5470..0cd4585db 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -5,21 +5,21 @@ import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; -import com.eternalcode.parcellockers.content.ParcelContent; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; -import com.eternalcode.parcellockers.delivery.Delivery; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; -import com.eternalcode.parcellockers.parcel.task.ParcelSendTask; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.shared.ParcelLockersException; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; -import java.time.Duration; -import java.time.Instant; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import java.util.List; +import java.util.Optional; import java.util.UUID; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.CompletableFuture; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -33,11 +33,13 @@ public class ParcelServiceImpl implements ParcelService { private final ParcelContentRepository parcelContentRepository; private final Scheduler scheduler; - private final Cache cache = Caffeine.newBuilder() - .expireAfterWrite(6, TimeUnit.HOURS) + private final Cache parcelsByUuid = Caffeine.newBuilder() .maximumSize(10_000) .build(); + private final Multimap parcelsBySender = HashMultimap.create(); + private final Multimap parcelsByReceiver = HashMultimap.create(); + public ParcelServiceImpl( PluginConfig config, NoticeService noticeService, @@ -55,54 +57,40 @@ public ParcelServiceImpl( } @Override - public boolean send(Player sender, Parcel parcel, List items) { - Duration delay = parcel.priority() - ? this.config.settings.priorityParcelSendDuration - : this.config.settings.parcelSendDuration; - - this.parcelRepository.save(parcel); - - this.parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)).handle((content, throwable) -> { + public void send(Player sender, Parcel parcel, List items) { + this.parcelRepository.save(parcel).handle((v, throwable) -> { if (throwable != null) { this.noticeService.create() .notice(messages -> messages.parcel.cannotSend) .player(sender.getUniqueId()) .send(); - - this.parcelRepository.remove(parcel); - throw new ParcelLockersException("Failed to save parcel content", throwable); + throw new ParcelLockersException("Failed to save parcel", throwable); } this.noticeService.create() .notice(messages -> messages.parcel.sent) .player(sender.getUniqueId()) .send(); - - Delivery delivery = new Delivery(parcel.uuid(), Instant.now().plus(delay)); - this.deliveryRepository.save(delivery); - ParcelSendTask task = new ParcelSendTask(parcel, this, this.deliveryRepository - ); - - this.scheduler.runLaterAsync(task, delay); - - return true; + return null; }); - return true; } @Override public void update(Parcel updated) { - this.parcelRepository.update(updated) ; + this.parcelRepository.update(updated); + this.cache(updated); } @Override public void delete(CommandSender sender, Parcel parcel) { - this.parcelRepository.remove(parcel) - .thenAccept(v -> + this.parcelRepository.delete(parcel) + .thenAccept(v -> { this.noticeService.create() .notice(messages -> messages.parcel.deleted) .viewer(sender) - .send()) + .send(); + this.invalidate(parcel); + }) .exceptionally(throwable -> { this.noticeService.create() .notice(messages -> messages.parcel.cannotDelete) @@ -134,7 +122,10 @@ public void collect(Player player, Parcel parcel) { items.forEach(item -> this.scheduler.run(() -> ItemUtil.giveItem(player, item))); - this.parcelRepository.remove(parcel) + + // TODO: Do not delete, archive instead + this.invalidate(parcel); + this.parcelRepository.delete(parcel) .thenAccept(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) .whenComplete((v, throwable) -> { if (throwable != null) { @@ -151,4 +142,107 @@ public void collect(Player player, Parcel parcel) { }); }); } + + @Override + public CompletableFuture> get(UUID uuid) { + Parcel cached = this.parcelsByUuid.getIfPresent(uuid); + if (cached != null) { + return CompletableFuture.completedFuture(Optional.of(cached)); + } + return this.parcelRepository.findById(uuid).thenApply(optional -> { + optional.ifPresent(this::cache); + return optional; + }); + } + + @Override + public CompletableFuture>> getBySender(UUID sender) { + List cached = List.copyOf(this.parcelsBySender.get(sender)); + if (!cached.isEmpty()) { + return CompletableFuture.completedFuture(Optional.of(cached)); + } + return this.parcelRepository.findBySender(sender).thenApply(optional -> { + optional.ifPresent(parcels -> parcels.forEach(this::cache)); + return optional; + }); + } + + @Override + public CompletableFuture>> getByReceiver(UUID receiver) { + List cached = List.copyOf(this.parcelsByReceiver.get(receiver)); + if (!cached.isEmpty()) { + return CompletableFuture.completedFuture(Optional.of(cached)); + } + return this.parcelRepository.findByReceiver(receiver).thenApply(optional -> { + optional.ifPresent(parcels -> parcels.forEach(this::cache)); + return optional; + }); + } + + @Override + public CompletableFuture> getByReceiver(UUID receiver, Page page) { + return this.parcelRepository.findByReceiver(receiver, page).thenApply(result -> { + result.items().forEach(this::cache); + return result; + }); + } + + @Override + public CompletableFuture>> getAll() { + List cached = List.copyOf(this.parcelsByUuid.asMap().values()); + if (!cached.isEmpty()) { + return CompletableFuture.completedFuture(Optional.of(cached)); + } + + return this.parcelRepository.findAll().thenApply(optional -> { + optional.ifPresent(parcels -> parcels.forEach(this::cache)); + return optional; + }); + } + + @Override + public CompletableFuture delete(UUID uuid) { + this.parcelsByUuid.invalidate(uuid); + return this.parcelRepository.delete(uuid).thenApply(deleted -> { + if (deleted > 0) { + Parcel cached = this.parcelsByUuid.getIfPresent(uuid); + if (cached != null) { + this.invalidate(cached); + } + } + return deleted; + }); + } + + @Override + public CompletableFuture delete(Parcel parcel) { + return this.delete(parcel.uuid()); + } + + @Override + public void deleteAll(CommandSender sender, NoticeService noticeService) { + this.parcelRepository.deleteAll().thenAccept(deleted -> { + noticeService.create() + .notice(messages -> messages.admin.deletedParcels) + .viewer(sender) + .placeholder("{COUNT}", deleted.toString()) + .send(); + + this.parcelsByUuid.invalidateAll(); + this.parcelsBySender.clear(); + this.parcelsByReceiver.clear(); + }); + } + + private void cache(Parcel parcel) { + this.parcelsByUuid.put(parcel.uuid(), parcel); + this.parcelsBySender.put(parcel.sender(), parcel); + this.parcelsByReceiver.put(parcel.receiver(), parcel); + } + + private void invalidate(Parcel parcel) { + this.parcelsByUuid.invalidate(parcel.uuid()); + this.parcelsBySender.remove(parcel.sender(), parcel); + this.parcelsByReceiver.remove(parcel.receiver(), parcel); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java index ae16b4e13..aa718aff6 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java @@ -10,9 +10,9 @@ public interface ParcelRepository { - void save(Parcel parcel); + CompletableFuture save(Parcel parcel); - void update(Parcel parcel); + CompletableFuture update(Parcel parcel); CompletableFuture>> findAll(); @@ -24,11 +24,11 @@ public interface ParcelRepository { CompletableFuture> findByReceiver(UUID receiver, Page page); - CompletableFuture remove(Parcel parcel); + CompletableFuture delete(Parcel parcel); - CompletableFuture remove(UUID uuid); + CompletableFuture delete(UUID uuid); - CompletableFuture removeAll(); + CompletableFuture deleteAll(); CompletableFuture> findPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java index acbe59110..f9c703711 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java @@ -30,13 +30,13 @@ public ParcelRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu } @Override - public void save(Parcel parcel) { - this.saveIfNotExist(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> null); + public CompletableFuture save(Parcel parcel) { + return this.saveIfNotExist(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> null); } @Override - public void update(Parcel parcel) { - this.save(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> null); + public CompletableFuture update(Parcel parcel) { + return this.save(ParcelTable.class, ParcelTable.from(parcel)).thenApply(dao -> null); } @Override @@ -84,12 +84,12 @@ public CompletableFuture> findByReceiver(UUID receiver, Page } @Override - public CompletableFuture remove(Parcel parcel) { - return this.remove(parcel.uuid()); + public CompletableFuture delete(Parcel parcel) { + return this.delete(parcel.uuid()); } @Override - public CompletableFuture remove(UUID uuid) { + public CompletableFuture delete(UUID uuid) { return this.deleteById(ParcelTable.class, uuid); } @@ -120,7 +120,7 @@ public CompletableFuture>> findAll() { } @Override - public CompletableFuture removeAll() { + public CompletableFuture deleteAll() { return this.deleteAll(ParcelTable.class); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java index b517f002c..c271c9f8f 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/task/ParcelSendTask.java @@ -1,6 +1,6 @@ package com.eternalcode.parcellockers.parcel.task; -import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; +import com.eternalcode.parcellockers.delivery.DeliveryManager; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelStatus; @@ -10,16 +10,16 @@ public class ParcelSendTask extends BukkitRunnable { private final Parcel parcel; private final ParcelService parcelService; - private final DeliveryRepository deliveryRepository; + private final DeliveryManager deliveryManager; public ParcelSendTask( Parcel parcel, ParcelService parcelService, - DeliveryRepository deliveryRepository + DeliveryManager deliveryManager ) { this.parcel = parcel; this.parcelService = parcelService; - this.deliveryRepository = deliveryRepository; + this.deliveryManager = deliveryManager; } @Override @@ -39,7 +39,7 @@ public void run() { this.parcelService.update(updated); - this.deliveryRepository.delete(updated.uuid()); + this.deliveryManager.delete(updated.uuid()); } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index 9cd1565c5..f0366b642 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -12,6 +12,7 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Blocking; public class PlaceholderUtil { @@ -30,7 +31,7 @@ public static List replaceParcelPlaceholders(Parcel parcel, List .register("{NAME}", parcel.name()) .register("{SENDER}", senderName) .register("{RECEIVER}", receiver) - .register("{SIZE}", parcel.size().toString()) + .register("{SIZE}", StringUtils.capitalize(parcel.size().toString().toLowerCase())) .register("{PRIORITY}", parcel.priority() ? "&aYes" : "&cNo") .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-"); diff --git a/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java b/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java index db3da6675..f8486f0ad 100644 --- a/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java +++ b/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java @@ -5,6 +5,6 @@ public record PageResult(List items, boolean hasNextPage) { public static PageResult empty() { - return new PageResult(List.of(), false); + return new PageResult<>(List.of(), false); } } diff --git a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java index 713a5d112..76c0e2dbb 100644 --- a/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java +++ b/src/main/java/com/eternalcode/parcellockers/updater/UpdaterService.java @@ -6,7 +6,6 @@ import com.eternalcode.gitcheck.git.GitRepository; import com.eternalcode.gitcheck.git.GitTag; import java.util.concurrent.CompletableFuture; -import org.bukkit.plugin.PluginDescriptionFile; public class UpdaterService { @@ -14,12 +13,8 @@ public class UpdaterService { private final GitCheck gitCheck = new GitCheck(); private final Lazy gitCheckResult; - public UpdaterService(PluginDescriptionFile descriptionFile) { - this.gitCheckResult = new Lazy<>(() -> { - String version = descriptionFile.getVersion(); - - return this.gitCheck.checkRelease(GIT_REPOSITORY, GitTag.of("v" + version)); - }); + public UpdaterService(String version) { + this.gitCheckResult = new Lazy<>(() -> this.gitCheck.checkRelease(GIT_REPOSITORY, GitTag.of("v" + version))); } public CompletableFuture isUpToDate() { diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java index 5f25602ef..54e1745d0 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java @@ -1,7 +1,7 @@ package com.eternalcode.parcellockers.user; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.user.repository.UserPageResult; +import com.eternalcode.parcellockers.shared.PageResult; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -16,5 +16,5 @@ public interface UserManager { CompletableFuture> get(UUID uniqueId); - CompletableFuture getPage(Page page); + CompletableFuture> getPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index fcae1b8e6..0c222c076 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -1,7 +1,7 @@ package com.eternalcode.parcellockers.user; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.user.repository.UserPageResult; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.user.repository.UserRepository; import java.util.HashMap; import java.util.Map; @@ -60,7 +60,7 @@ public void getOrCreate(UUID uuid, String name) { } @Override - public CompletableFuture getPage(Page page) { + public CompletableFuture> getPage(Page page) { return this.userRepository.findPage(page); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java deleted file mode 100644 index 333d99ccd..000000000 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserPageResult.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.eternalcode.parcellockers.user.repository; - -import com.eternalcode.parcellockers.user.User; -import java.util.List; - -public record UserPageResult(List users, boolean hasNextPage) { - -} diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java index 073ed0e57..3e04c81ad 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java @@ -1,6 +1,7 @@ package com.eternalcode.parcellockers.user.repository; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.user.User; import java.util.Optional; import java.util.UUID; @@ -16,5 +17,5 @@ public interface UserRepository { CompletableFuture> find(String name); - CompletableFuture findPage(Page page); + CompletableFuture> findPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index 3e279c4cc..45d1f203a 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -4,6 +4,7 @@ import com.eternalcode.parcellockers.database.DatabaseManager; import com.eternalcode.parcellockers.database.wrapper.AbstractRepositoryOrmLite; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.user.User; import com.j256.ormlite.table.TableUtils; import java.sql.SQLException; @@ -27,7 +28,7 @@ public UserRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedule @Override public CompletableFuture> find(UUID uuid) { - return this.select(UserTable.class, uuid).thenApply(userTable -> Optional.ofNullable(userTable) + return this.selectSafe(UserTable.class, uuid).thenApply(optional -> optional .map(UserTable::toUser) ); } @@ -58,7 +59,7 @@ public CompletableFuture changeName(UUID uuid, String newName) { } @Override - public CompletableFuture findPage(Page page) { + public CompletableFuture> findPage(Page page) { return this.action( UserTable.class, dao -> { List users = dao.queryBuilder() @@ -72,7 +73,7 @@ public CompletableFuture findPage(Page page) { if (hasNext) { users.removeLast(); } - return new UserPageResult(users, hasNext); + return new PageResult<>(users, hasNext); }); } } diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index b73ab8f75..23aa9d658 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -45,9 +45,8 @@ void test() { PluginConfig config = new ConfigService().create(PluginConfig.class, new File(dataFolder, "config.yml")); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; - ParcelCache cache = new ParcelCache(); - ParcelRepository parcelRepository = new ParcelRepositoryOrmLite(databaseManager, new TestScheduler(), cache); + ParcelRepository parcelRepository = new ParcelRepositoryOrmLite(databaseManager, new TestScheduler()); UUID uuid = UUID.randomUUID(); UUID sender = UUID.randomUUID(); UUID receiver = UUID.randomUUID(); @@ -70,10 +69,10 @@ void test() { assertEquals(uuid, bySender.getFirst().uuid()); PageResult pageResult = this.await(parcelRepository.findPage(new Page(0, 28))); - assertEquals(1, pageResult.parcels().size()); - assertEquals(uuid, pageResult.parcels().getFirst().uuid()); + assertEquals(1, pageResult.items().size()); + assertEquals(uuid, pageResult.items().getFirst().uuid()); - this.await(parcelRepository.remove(uuid)); + this.await(parcelRepository.delete(uuid)); Optional removedParcel = this.await(parcelRepository.findById(uuid)); assertTrue(removedParcel.isEmpty()); } From aaf94a75fe0e6b37c0df1e30f02b9ae2052297e6 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:23:00 +0200 Subject: [PATCH 19/51] change persister type class --- .../parcellockers/database/persister/PositionPersister.java | 2 +- .../parcellockers/gui/implementation/locker/SendingGui.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java b/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java index 8a44b1a5c..4b07dd10f 100644 --- a/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java +++ b/src/main/java/com/eternalcode/parcellockers/database/persister/PositionPersister.java @@ -12,7 +12,7 @@ public class PositionPersister extends BaseDataType { private static final PositionPersister INSTANCE = new PositionPersister(); private PositionPersister() { - super(SqlType.LONG_STRING, new Class[] { PositionPersister.class }); + super(SqlType.LONG_STRING, new Class[] { Position.class }); } public static PositionPersister getSingleton() { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 605125f25..65ec9fb53 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -289,7 +289,10 @@ public void show(Player player) { userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> - lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.name()))); + lockerOptional.ifPresent(locker -> { + System.out.println(locker); + this.updateDestinationItem(player, locker.name()); + })); this.scheduler.run(() -> this.gui.open(player)); } From b21140780eb3138bd6d5bba28d8a6ddac9ca7a5f Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:42:34 +0200 Subject: [PATCH 20/51] Simplify ReceiverGui --- .../implementation/PluginConfig.java | 6 +-- .../parcellockers/gui/GuiView.java | 5 +- .../gui/implementation/locker/LockerGui.java | 17 +----- .../implementation/locker/ReceiverGui.java | 53 +++++++++++-------- .../gui/implementation/locker/SendingGui.java | 19 ++++--- .../parcellockers/locker/LockerManager.java | 4 ++ .../parcellockers/shared/Position.java | 4 +- 7 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 7b9933073..9eabc383f 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -156,7 +156,7 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel submit button" }) public ConfigItem submitParcelItem = new ConfigItem() .name("&2โœ” &aSubmit") - .lore(List.of("Before submitting, check if everything has been filled correctly!", "Before submitting, check if everything has been filled correctly!")) + .lore(List.of("Click to send your parcel.", "Before submitting, check if everything has been filled correctly!")) .type(Material.EMERALD_BLOCK) .glow(true); @@ -224,8 +224,8 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelDescriptionItem = new ConfigItem() - .name("&2\uD83D\uDDC9 &aParcel name") - .lore(List.of("&2ยป &aClick to add parcel name.")) + .name("&2\uD83D\uDDC9 &aParcel description") + .lore(List.of("&2ยป &aClick to add parcel description.")) .type(Material.OAK_SIGN); public String parcelDescriptionSetLine = "&2ยป &aCurrent parcel name: &2{DESCRIPTION}"; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java index efa130a95..7f86e06db 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java @@ -4,9 +4,10 @@ public interface GuiView { - int[] CORNER_SLOTS = { 0, 8, 45, 53 }; int[] BORDER_SLOTS = { 1, 2, 3, 4, 5, 6, 7, 9, 17, 18, 26, 27, 35, 36, 44, 46, 47, 48, 49, 50, 51, 52 }; - void show(Player player); + default void show(Player player) { + throw new UnsupportedOperationException("This GUI requires additional context"); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java index 11b161564..4a08325dc 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java @@ -7,13 +7,10 @@ import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.notification.NoticeService; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; import dev.rollczi.liteskullapi.SkullAPI; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import java.util.UUID; -import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; @@ -27,10 +24,6 @@ public class LockerGui implements GuiView { private final NoticeService noticeService; private final SkullAPI skullAPI; - private final Cache userEntryLockerCache = Caffeine.newBuilder() - .expireAfterAccess(2, TimeUnit.MINUTES) - .build(); - public LockerGui( MiniMessage miniMessage, Scheduler scheduler, GuiSettings guiSettings, GuiManager guiManager, @@ -46,12 +39,6 @@ public LockerGui( } public void show(Player player, UUID entryLocker) { - this.userEntryLockerCache.put(player.getUniqueId(), entryLocker); - this.show(player); - } - - @Override - public void show(Player player) { Component guiTitle = this.miniMessage.deserialize(this.guiSettings.mainGuiTitle); Gui gui = Gui.gui() @@ -88,8 +75,8 @@ public void show(Player player) { this.noticeService, this.guiManager, this.skullAPI, - new SendingGuiState().entryLocker(this.userEntryLockerCache.getIfPresent(player.getUniqueId())) - ).show(player))); + new SendingGuiState().entryLocker(entryLocker) + ).show(player, entryLocker))); gui.setItem(49, closeItem); gui.open(player); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index c7a193d26..2b937b230 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; @@ -66,29 +67,10 @@ private void show(Player player, Page page) { .disableAllInteractions() .create(); - GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); - GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); - - for (int slot : CORNER_SLOTS) { - gui.setItem(slot, cornerItem); - } - for (int slot : BORDER_SLOTS) { - gui.setItem(slot, backgroundItem); - } - - gui.setItem(49, closeItem); + this.setupStaticItems(gui, player); this.guiManager.getUsers(page).thenAccept(result -> { - if (result.hasNextPage()) { - gui.setItem(51, nextPageItem); - } - - if (page.hasPrevious()) { - gui.setItem(47, previousPageItem); - } + this.setupNavigation(gui, page, result, player); PaginatedGuiRefresher refresh = new PaginatedGuiRefresher(gui); @@ -106,7 +88,8 @@ private CompletableFuture>> loadSkulls(Player player, Pag return result.items().stream() // .filter(user -> !user.uuid().equals(player.getUniqueId())) .map(user -> this.skullAPI.getSkullData(user.uuid()).thenApply(skullData -> this.toItem(player, user, skullData, refresh))) - .collect(CompletableFutures.joinList()); + .collect(CompletableFutures.joinList()) + .orTimeout(10, TimeUnit.SECONDS); } private Supplier toItem(Player player, User user, SkullData skullData, PaginatedGuiRefresher refresher) { @@ -137,4 +120,30 @@ private Supplier toItem(Player player, User user, SkullData skullData, }); }; } + + private void setupStaticItems(PaginatedGui gui, Player player) { + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); + + for (int slot : CORNER_SLOTS) { + gui.setItem(slot, cornerItem); + } + for (int slot : BORDER_SLOTS) { + gui.setItem(slot, backgroundItem); + } + gui.setItem(49, closeItem); + } + + private void setupNavigation(PaginatedGui gui, Page page, PageResult result, Player player) { + if (result.hasNextPage()) { + GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); + gui.setItem(51, nextPageItem); + } + + if (page.hasPrevious()) { + GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); + gui.setItem(47, previousPageItem); + } + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 65ec9fb53..3fa355c20 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -70,6 +70,11 @@ public SendingGui( this.state = state; } + public void show(Player player, UUID entryLocker) { + this.state.entryLocker(entryLocker); + this.show(player); + } + @Override public void show(Player player) { @@ -236,7 +241,7 @@ public void show(Player player) { this.guiManager, this.noticeService, this.skullAPI - ).show(player)); + ).show(player, this.state.entryLocker())); ConfigItem smallButton = this.guiSettings.smallParcelSizeItem; ConfigItem mediumButton = this.guiSettings.mediumParcelSizeItem; @@ -288,11 +293,13 @@ public void show(Player player) { this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); - this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> - lockerOptional.ifPresent(locker -> { - System.out.println(locker); - this.updateDestinationItem(player, locker.name()); - })); + + if (this.state.destinationLocker() != null) { + this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> + lockerOptional.ifPresent(locker -> { + this.updateDestinationItem(player, locker.name()); + })); + } this.scheduler.run(() -> this.gui.open(player)); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 323c9cae5..254e3fc57 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -33,6 +33,10 @@ public LockerManager(LockerRepository lockerRepository) { } public CompletableFuture> get(UUID uniqueId) { + if (uniqueId == null) { + return CompletableFuture.completedFuture(Optional.empty()); + } + Locker locker = this.lockersByUUID.getIfPresent(uniqueId); if (locker != null) { diff --git a/src/main/java/com/eternalcode/parcellockers/shared/Position.java b/src/main/java/com/eternalcode/parcellockers/shared/Position.java index 9297da148..941384980 100644 --- a/src/main/java/com/eternalcode/parcellockers/shared/Position.java +++ b/src/main/java/com/eternalcode/parcellockers/shared/Position.java @@ -12,7 +12,7 @@ public record Position(int x, int y, int z, String world) { public static final String NONE_WORLD = "__NONE__"; - private static final Pattern PARSE_FORMAT = Pattern.compile("Position\\{x=(?-?\\d+), y=(?-?\\d+), z=(?-?\\d+), world='(?.+)'}"); + private static final Pattern PARSE_FORMAT = Pattern.compile("Position\\{x=(?-?\\d+), y=(?-?\\d+), z=(?-?\\d+), world=\"(?.+)\"}"); public static Position parse(String parse) { Matcher matcher = PARSE_FORMAT.matcher(parse); @@ -82,7 +82,7 @@ public String toString() { "x=" + this.x + ", y=" + this.y + ", z=" + this.z + - ", world='" + this.world + '\'' + + ", world=\"" + this.world + "\"" + // Uลผywaj podwรณjnych cudzysล‚owรณw '}'; } } From 6883c04f904e38db91635fe4427d769b489a5aff Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 23 Aug 2025 20:56:08 +0200 Subject: [PATCH 21/51] fix gui issues --- build.gradle.kts | 4 +-- .../parcellockers/ParcelLockers.java | 2 ++ .../implementation/locker/ReceiverGui.java | 20 ++++++++--- .../gui/implementation/locker/SendingGui.java | 35 ++++++++++--------- .../shared/ScheduledGuiAction.java | 28 +++++++++++++++ 5 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/shared/ScheduledGuiAction.java diff --git a/build.gradle.kts b/build.gradle.kts index da1edc7fa..99fdbfd5b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,7 +32,7 @@ dependencies { paperLibrary("dev.rollczi:liteskullapi:2.0.0") // gui - implementation("dev.triumphteam:triumph-gui-paper:3.1.13-SNAPSHOT") + paperLibrary("dev.triumphteam:triumph-gui-paper:3.1.13-SNAPSHOT") paperLibrary("de.rapha149.signgui:signgui:2.5.4") // configs @@ -134,7 +134,7 @@ tasks { val relocationPrefix = "com.eternalcode.parcellockers.libs" listOf( "org.bstats", - "dev.triumphteam" +// "dev.triumphteam" ).forEach { relocate(it, "$relocationPrefix.$it") } } } diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 2afa460a8..e17fc7350 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -50,6 +50,7 @@ import dev.rollczi.litecommands.bukkit.LiteBukkitMessages; import dev.rollczi.liteskullapi.LiteSkullFactory; import dev.rollczi.liteskullapi.SkullAPI; +import dev.triumphteam.gui.TriumphGui; import java.io.File; import java.sql.SQLException; import java.time.Duration; @@ -128,6 +129,7 @@ public void onEnable() { DeliveryManager deliveryManager = new DeliveryManager(deliveryRepository); // guis + TriumphGui.init(this); GuiManager guiManager = new GuiManager( config, scheduler, diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index 2b937b230..b71d344f7 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -11,7 +11,7 @@ import com.spotify.futures.CompletableFutures; import dev.rollczi.liteskullapi.SkullAPI; import dev.rollczi.liteskullapi.SkullData; -import dev.triumphteam.gui.builder.item.ItemBuilder; +import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; @@ -79,15 +79,27 @@ private void show(Player player, Page page) { refresh.addItem(item); } - this.scheduler.run(() -> gui.open(player)); + this.scheduler.run(() -> { + gui.open(player); + }); + }).exceptionally(ex -> { + ex.printStackTrace(); + return null; }); + }).exceptionally(ex -> { + ex.printStackTrace(); + return null; }); } private CompletableFuture>> loadSkulls(Player player, PageResult result, PaginatedGuiRefresher refresh) { return result.items().stream() // .filter(user -> !user.uuid().equals(player.getUniqueId())) - .map(user -> this.skullAPI.getSkullData(user.uuid()).thenApply(skullData -> this.toItem(player, user, skullData, refresh))) + .map(user -> this.skullAPI.getSkullData(user.uuid()).thenApply(skullData -> this.toItem(player, user, skullData, refresh)) + .exceptionally(throwable -> { + System.err.println("ReceiverGui: Error fetching skull for user " + user.uuid() + ": " + throwable.getMessage()); + return null; + })) .collect(CompletableFutures.joinList()) .orTimeout(10, TimeUnit.SECONDS); } @@ -101,7 +113,7 @@ private Supplier toItem(Player player, User user, SkullData skullData, ? this.guiSettings.parcelReceiverSetLine : this.guiSettings.parcelReceiverNotSetLine; - return ItemBuilder.skull() + return PaperItemBuilder.skull() .texture(skullData.getTexture()) .name(this.miniMessage.deserialize(user.name())) .lore(this.miniMessage.deserialize(lore)) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 3fa355c20..46f1adcf8 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -9,6 +9,7 @@ import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelSize; +import com.eternalcode.parcellockers.shared.ScheduledGuiAction; import de.rapha149.signgui.SignGUI; import de.rapha149.signgui.exception.SignGUIVersionException; import dev.rollczi.liteskullapi.SkullAPI; @@ -77,7 +78,6 @@ public void show(Player player, UUID entryLocker) { @Override public void show(Player player) { - Component guiTitle = this.miniMessage.deserialize(this.guiSettings.parcelLockerSendingGuiTitle); this.gui = Gui.gui() @@ -124,8 +124,7 @@ public void show(Player player) { this.gui.updateItem(NAME_ITEM_SLOT, nameItem .lore(lore) .toItemStack()); - this.gui.open(player); - return List.of(); + return List.of(new ScheduledGuiAction(this.scheduler, () -> this.gui.open(player))); }) .build(); nameSignGui.open(player); @@ -161,8 +160,7 @@ public void show(Player player) { this.gui.updateItem(DESCRIPTION_ITEM_SLOT, descriptionItem .lore(lore) .toItemStack()); - this.gui.open(player); - return List.of(); + return List.of(new ScheduledGuiAction(this.scheduler, () -> this.gui.open(player))); }) .build(); } catch (SignGUIVersionException e) { @@ -293,13 +291,10 @@ public void show(Player player) { this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); - - if (this.state.destinationLocker() != null) { - this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> - lockerOptional.ifPresent(locker -> { - this.updateDestinationItem(player, locker.name()); - })); - } + this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> + lockerOptional.ifPresent(locker -> { + this.updateDestinationItem(player, locker.name()); + })); this.scheduler.run(() -> this.gui.open(player)); } @@ -346,11 +341,13 @@ public void updateDescriptionItem() { this.gui.updateItem(DESCRIPTION_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelDescriptionItem, line)); } - public void updateReceiverItem(Player player, String receiverName) { - this.noticeService.create() - .notice(messages -> messages.parcel.receiverSet) - .player(player.getUniqueId()) - .send(); + public void updateReceiverItem(Player player, String receiverName, boolean sendNotice) { + if (sendNotice) { + this.noticeService.create() + .notice(messages -> messages.parcel.receiverSet) + .player(player.getUniqueId()) + .send(); + } if (receiverName == null || receiverName.isEmpty()) { this.gui.updateItem(RECEIVER_ITEM_SLOT, this.guiSettings.parcelReceiverItem.toItemStack()); @@ -361,6 +358,10 @@ public void updateReceiverItem(Player player, String receiverName) { this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelReceiverItem, line)); } + public void updateReceiverItem(Player player, String receiverName) { + this.updateReceiverItem(player, receiverName, false); + } + public void updateDestinationItem(Player player, String destinationLockerDesc) { this.noticeService.create() .notice(messages -> messages.parcel.destinationSet) diff --git a/src/main/java/com/eternalcode/parcellockers/shared/ScheduledGuiAction.java b/src/main/java/com/eternalcode/parcellockers/shared/ScheduledGuiAction.java new file mode 100644 index 000000000..0db1e2c84 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/shared/ScheduledGuiAction.java @@ -0,0 +1,28 @@ +package com.eternalcode.parcellockers.shared; + +import com.eternalcode.commons.scheduler.Scheduler; +import de.rapha149.signgui.SignEditor; +import de.rapha149.signgui.SignGUI; +import de.rapha149.signgui.SignGUIAction; +import org.bukkit.entity.Player; + +public class ScheduledGuiAction implements SignGUIAction { + + private final Scheduler scheduler; + private final Runnable runnable; + + public ScheduledGuiAction(Scheduler scheduler, Runnable runnable) { + this.scheduler = scheduler; + this.runnable = runnable; + } + + @Override + public SignGUIActionInfo getInfo() { + return new SignGUIActionInfo("scheduledGuiAction", false, 0); + } + + @Override + public void execute(SignGUI gui, SignEditor signEditor, Player player) { + this.scheduler.run(this.runnable); + } +} From 90a0d837d1a2580db674cc4ed670cf2c1150b566 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 24 Aug 2025 13:59:24 +0200 Subject: [PATCH 22/51] Beautify GUI classes --- build.gradle.kts | 5 +- .../command/debug/DebugCommand.java | 2 - .../implementation/PluginConfig.java | 37 +++++++------ .../parcellockers/gui/GuiView.java | 21 ++++++++ .../implementation/locker/CollectionGui.java | 52 ++++++++----------- .../implementation/locker/DestinationGui.java | 44 ++++++++-------- .../implementation/locker/ItemStorageGui.java | 5 +- .../gui/implementation/locker/LockerGui.java | 31 ++++++----- .../implementation/locker/ReceiverGui.java | 28 ++++------ .../gui/implementation/locker/SendingGui.java | 22 ++++---- .../gui/implementation/remote/MainGui.java | 1 - .../implementation/remote/ParcelListGui.java | 41 +++++++-------- .../implementation/remote/SentParcelsGui.java | 31 ++++++----- .../parcel/ParcelServiceImpl.java | 22 +++----- 14 files changed, 167 insertions(+), 175 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 99fdbfd5b..3bf34edfa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,11 +12,7 @@ repositories { gradlePluginPortal() maven { url = uri("https://maven-central.storage-download.googleapis.com/maven2/")} - maven { url = uri("https://repo.panda-lang.org/releases") } maven { url = uri("https://repo.triumphteam.dev/snapshots/")} - maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") } - maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } - maven { url = uri("https://oss.sonatype.org/content/repositories/central") } maven { url = uri("https://repo.papermc.io/repository/maven-public/") } maven { url = uri("https://repo.eternalcode.pl/releases") } maven { url = uri("https://storehouse.okaeri.eu/repository/maven-public/") } @@ -101,6 +97,7 @@ paper { website = "https://github.com/EternalCodeTeam/ParcelLockers" loader = "com.eternalcode.parcellockers.ParcelLockersLibraryLoader" generateLibrariesJson = true + foliaSupported = false } tasks.withType { diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index a48084ed7..8fce11fd5 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -23,8 +23,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -// TODO move notices to MessagesConfig - @Command(name = "parcel debug") @Permission("parcellockers.debug") public class DebugCommand { diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 9eabc383f..8fa491bee 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -12,16 +12,15 @@ @Header({ " ", - "# Parcel Lockers plugin configuration file.", + "# ParcelLockers plugin configuration file.", "#", - "# This file is used to configure the ParcelLockers plugin.", - "# You can change the settings here to customize the plugin behavior.", + "# This file is used to configure the plugin.", + "# You can change the settings here to customize the plugin behavior or appearance.", "#", - "# If you want to change the settings, you can do it in-game using the /parcellockers reload command." + "# If you want to reload the configuration, you can do it using the /parcellockers reload command." }) public class PluginConfig extends OkaeriConfig { - - @Comment({ "", "# Parcel Lockers plugin configuration file." }) + @Comment({ "", "# The plugin settings." }) public Settings settings = new Settings(); @Comment({ "", "# The plugin GUI settings." }) @@ -57,10 +56,10 @@ public static class Settings extends OkaeriConfig { .lore(List.of("&bPlace to create a parcel locker.")); @Comment({"", "# Standard parcel sending duration"}) - public Duration parcelSendDuration = Duration.ofSeconds(10); + public Duration parcelSendDuration = Duration.ofSeconds(5); @Comment({"", "# Parcel sending duration for priority parcels"}) - public Duration priorityParcelSendDuration = Duration.ofSeconds(5); + public Duration priorityParcelSendDuration = Duration.ofSeconds(2); } public static class GuiSettings extends OkaeriConfig { @@ -81,24 +80,24 @@ public static class GuiSettings extends OkaeriConfig { public String parcelReceiverSelectionGuiTitle = "&5Select recipient"; @Comment({ "", "# The item of the parcel collection GUI" }) - public String parcelCollectionGuiTitle = "&aCollect parcels"; + public String parcelCollectionGuiTitle = "&2Collect parcels"; @Comment({ "", "# The item of the small parcel size button" }) public ConfigItem smallParcelSizeItem = new ConfigItem() .name("&2\uD83C\uDF37 &aSmall") - .lore(List.of("&aClick to select the small parcel size.")) + .lore(List.of("&2ยป &aClick to select the small parcel size.")) .type(Material.OAK_CHEST_BOAT); @Comment({ "", "# The item of the medium parcel size button" }) public ConfigItem mediumParcelSizeItem = new ConfigItem() .name("&6\uD83C\uDF39 &eMedium") - .lore(List.of("&eClick to select the medium parcel size.")) + .lore(List.of("&6ยป &eClick to select the medium parcel size.")) .type(Material.CHEST_MINECART); @Comment({ "", "# The item of the large parcel size button" }) public ConfigItem largeParcelSizeItem = new ConfigItem() .name("&4\uD83C\uDFDD &cLarge") - .lore(List.of("&cClick to select the large parcel size.")) + .lore(List.of("&4ยป &cClick to select the large parcel size.")) .type(Material.TNT_MINECART); @Comment({ "", "# The item represents selected small parcel size." }) @@ -220,7 +219,7 @@ public static class GuiSettings extends OkaeriConfig { .type(Material.NAME_TAG); @Comment({ "", "# The value of the GUI line, when parcel name is set" }) - public String parcelNameSetLine = "&4ยป &cCurrent parcel name: &e{NAME}"; + public String parcelNameSetLine = "&4โ€บ &cCurrent parcel name: &e{NAME}"; @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelDescriptionItem = new ConfigItem() @@ -228,7 +227,7 @@ public static class GuiSettings extends OkaeriConfig { .lore(List.of("&2ยป &aClick to add parcel description.")) .type(Material.OAK_SIGN); - public String parcelDescriptionSetLine = "&2ยป &aCurrent parcel name: &2{DESCRIPTION}"; + public String parcelDescriptionSetLine = "&2โ€บ &aCurrent parcel name: &2{DESCRIPTION}"; @Comment({ "", "# The item of the parcel receiver button" }) public ConfigItem parcelReceiverItem = new ConfigItem() @@ -237,7 +236,7 @@ public static class GuiSettings extends OkaeriConfig { .type(Material.PLAYER_HEAD); @Comment({ "", "# The value of the GUI line, when parcel name is set" }) - public String parcelReceiverGuiSetLine = "&5ยป &dCurrent parcel receiver: &5{RECEIVER}"; + public String parcelReceiverGuiSetLine = "&5โ€บ &dCurrent parcel receiver: &5{RECEIVER}"; @Comment({ "", "# The value of the player itemlore line, when parcel receiver is not set" }) public String parcelReceiverNotSetLine = "&9ยป &bClick to select."; @@ -248,8 +247,8 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel destination locker button" }) public ConfigItem parcelDestinationLockerItem = new ConfigItem() .name("&3\uD83D\uDEE3 Destination locker") - .lore(List.of("&3Click to edit the parcel destination locker.")) - .type(Material.COMPASS); + .lore(List.of("&3ยป &bClick to edit the parcel destination locker.")) + .type(Material.END_PORTAL_FRAME); @Comment({ "", "# The item of the previous page button" }) public ConfigItem previousPageItem = new ConfigItem() @@ -266,7 +265,7 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the confirm items button" }) public ConfigItem confirmItemsItem = new ConfigItem() .name("&2โœ” &aConfirm items") - .lore(List.of("&aClick to confirm the items.")) + .lore(List.of("&2ยป &aClick to confirm the items.")) .type(Material.GREEN_DYE); @Comment({ "", "# The name of the parcel small content GUI" }) @@ -284,7 +283,7 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel in destination selection GUI" }) public ConfigItem destinationLockerItem = new ConfigItem() .name("&3{DESCRIPTION}") - .lore(List.of("&bClick to select this locker.")) + .lore(List.of("&3ยป &bClick to select this locker.")) .type(Material.CHISELED_BOOKSHELF); @Comment({ "", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java index 7f86e06db..6abd3d1be 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiView.java @@ -1,5 +1,10 @@ package com.eternalcode.parcellockers.gui; +import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; +import dev.triumphteam.gui.guis.GuiItem; +import dev.triumphteam.gui.guis.PaginatedGui; import org.bukkit.entity.Player; @@ -10,4 +15,20 @@ public interface GuiView { default void show(Player player) { throw new UnsupportedOperationException("This GUI requires additional context"); } + + default void show(Player player, Page page) { + throw new UnsupportedOperationException("This GUI requires additional context"); + } + + default void setupNavigation(PaginatedGui gui, Page page, PageResult result, Player player, PluginConfig.GuiSettings guiSettings) { + if (result.hasNextPage()) { + GuiItem nextPageItem = guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); + gui.setItem(51, nextPageItem); + } + + if (page.hasPrevious()) { + GuiItem previousPageItem = guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); + gui.setItem(47, previousPageItem); + } + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 1e19fade2..ad9e82be2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -45,8 +45,10 @@ public void show(Player player) { this.show(player, FIRST_PAGE); } - private void show(Player player, Page page) { + @Override + public void show(Player player, Page page) { Component guiTitle = this.miniMessage.deserialize(this.guiSettings.parcelCollectionGuiTitle); + ConfigItem parcelItem = this.guiSettings.parcelCollectionItem; PaginatedGui gui = Gui.paginated() .rows(6) @@ -54,29 +56,7 @@ private void show(Player player, Page page) { .title(guiTitle) .create(); - ConfigItem parcelItem = this.guiSettings.parcelCollectionItem; - GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); - GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); - GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> { - Page nextPage = new Page(page.page() + 1, page.size()); - this.show(player, nextPage); - }); - - GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> { - Page previousPage = new Page(page.page() - 1, page.size()); - this.show(player, previousPage); - }); - - for (int cornerSlot : CORNER_SLOTS) { - gui.setItem(cornerSlot, cornerItem); - } - - for (int borderSlot : BORDER_SLOTS) { - gui.setItem(borderSlot, backgroundItem); - } - - gui.setItem(49, closeItem); + this.setupStaticItems(player, gui); this.guiManager.getParcelsByReceiver(player.getUniqueId(), page).thenAccept(result -> { if (result == null || result.items().isEmpty()) { @@ -85,13 +65,7 @@ private void show(Player player, Page page) { return; } - if (result.hasNextPage()) { - gui.setItem(51, nextPageItem); - } - - if (page.hasPrevious()) { - gui.setItem(47, previousPageItem); - } + this.setupNavigation(gui, page, result, player, this.guiSettings); for (Parcel parcel : result.items()) { if (parcel.status() != ParcelStatus.DELIVERED) { @@ -115,4 +89,20 @@ private void show(Player player, Page page) { this.scheduler.run(() -> gui.open(player)); }); } + + private void setupStaticItems(Player player, PaginatedGui gui) { + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + + for (int cornerSlot : CORNER_SLOTS) { + gui.setItem(cornerSlot, cornerItem); + } + + for (int borderSlot : BORDER_SLOTS) { + gui.setItem(borderSlot, backgroundItem); + } + + gui.setItem(49, closeItem); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java index ff5527799..56206966b 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java @@ -53,12 +53,8 @@ public void show(Player player) { this.show(player, FIRST_PAGE); } - private void show(Player player, Page page) { - GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); - GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); - GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); + @Override + public void show(Player player, Page page) { PaginatedGui gui = Gui.paginated() .title(this.miniMessage.deserialize(this.guiSettings.parcelDestinationLockerSelectionGuiTitle)) @@ -68,23 +64,10 @@ private void show(Player player, Page page) { PaginatedGuiRefresher refresher = new PaginatedGuiRefresher(gui); - for (int slot : CORNER_SLOTS) { - gui.setItem(slot, cornerItem); - } - for (int slot : BORDER_SLOTS) { - gui.setItem(slot, backgroundItem); - } - - gui.setItem(49, closeItem); + this.setupStaticItems(player, gui); this.guiManager.getLockerPage(page).thenAccept(result -> { - if (result.hasNextPage()) { - gui.setItem(51, nextPageItem); - } - - if (page.hasPrevious()) { - gui.setItem(47, previousPageItem); - } + this.setupNavigation(gui, page, result, player, this.guiSettings); this.loadLockers(player, result, refresher).forEach(refresher::addItem); this.scheduler.run(() -> gui.open(player)); @@ -115,15 +98,30 @@ private Supplier toItem(Player player, Locker locker, PaginatedGuiRefre .toGuiItem(event -> { if (isLockerSelected) { this.state.destinationLocker(null); - this.sendingGUI.updateDestinationItem(player, ""); + this.sendingGUI.updateDestinationItem(player, "", false); refresher.refresh(); return; } this.state.destinationLocker(uuid); - this.sendingGUI.updateDestinationItem(player, locker.name()); + this.sendingGUI.updateDestinationItem(player, locker.name(), true); refresher.refresh(); }); }; } + + private void setupStaticItems(Player player, PaginatedGui gui) { + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); + + for (int slot : CORNER_SLOTS) { + gui.setItem(slot, cornerItem); + } + for (int slot : BORDER_SLOTS) { + gui.setItem(slot, backgroundItem); + } + + gui.setItem(49, closeItem); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index 987d14b41..2ce654ec9 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -94,6 +94,8 @@ void show(Player player, ParcelSize size) { continue; } + // todo fix duplication glitch with illegal items + // if the item is illegal, give it back to the player and do not save it for (Material type : this.guiSettings.illegalItems) { if (item.getType() == type) { ItemUtil.giveItem(player, item); @@ -103,10 +105,11 @@ void show(Player player, ParcelSize size) { .placeholder("{ITEMS}", MaterialUtil.format(item.getType())) .player(player.getUniqueId()) .send(); + return; } } - items.add(item); + } this.guiManager.deleteItemStorage(player.getUniqueId()); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java index 4a08325dc..3116ad977 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java @@ -47,18 +47,7 @@ public void show(Player player, UUID entryLocker) { .disableAllInteractions() .create(); - GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); - - int size = gui.getRows() * 9; - for (int i = 0; i < size; i++) { - gui.setItem(i, backgroundItem); - } - - for (int slot : CORNER_SLOTS) { - gui.setItem(slot, cornerItem); - } + this.setupStaticItems(player, gui); CollectionGui collectionGui = new CollectionGui( this.guiSettings, @@ -78,7 +67,23 @@ public void show(Player player, UUID entryLocker) { new SendingGuiState().entryLocker(entryLocker) ).show(player, entryLocker))); - gui.setItem(49, closeItem); gui.open(player); } + + private void setupStaticItems(Gui gui, Player player) { + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); + + int size = gui.getRows() * 9; + for (int i = 0; i < size; i++) { + gui.setItem(i, backgroundItem); + } + + for (int slot : CORNER_SLOTS) { + gui.setItem(slot, cornerItem); + } + gui.setItem(49, closeItem); + + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index b71d344f7..71cb031c4 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -60,14 +60,15 @@ public void show(Player player) { this.show(player, FIRST_PAGE); } - private void show(Player player, Page page) { + @Override + public void show(Player player, Page page) { PaginatedGui gui = Gui.paginated() .title(this.miniMessage.deserialize(this.guiSettings.parcelReceiverSelectionGuiTitle)) .rows(6) .disableAllInteractions() .create(); - this.setupStaticItems(gui, player); + this.setupStaticItems(player, gui); this.guiManager.getUsers(page).thenAccept(result -> { this.setupNavigation(gui, page, result, player); @@ -79,25 +80,18 @@ private void show(Player player, Page page) { refresh.addItem(item); } - this.scheduler.run(() -> { - gui.open(player); - }); - }).exceptionally(ex -> { - ex.printStackTrace(); - return null; + this.scheduler.run(() -> gui.open(player)); }); - }).exceptionally(ex -> { - ex.printStackTrace(); - return null; }); } private CompletableFuture>> loadSkulls(Player player, PageResult result, PaginatedGuiRefresher refresh) { return result.items().stream() -// .filter(user -> !user.uuid().equals(player.getUniqueId())) - .map(user -> this.skullAPI.getSkullData(user.uuid()).thenApply(skullData -> this.toItem(player, user, skullData, refresh)) + // .filter(user -> !user.uuid().equals(player.getUniqueId())) + .map(user -> this.skullAPI.getSkullData(user.uuid()) + .thenApply(skullData -> this.toItem(player, user, skullData, refresh)) .exceptionally(throwable -> { - System.err.println("ReceiverGui: Error fetching skull for user " + user.uuid() + ": " + throwable.getMessage()); + throwable.printStackTrace(); return null; })) .collect(CompletableFutures.joinList()) @@ -121,19 +115,19 @@ private Supplier toItem(Player player, User user, SkullData skullData, .asGuiItem(event -> { if (uuid.equals(this.state.receiver())) { refresher.refresh(); - this.sendingGUI.updateReceiverItem(player, ""); + this.sendingGUI.updateReceiverItem(player, "", false); this.state.receiver(null); return; } - this.sendingGUI.updateReceiverItem(player, user.name()); + this.sendingGUI.updateReceiverItem(player, user.name(), true); this.state.receiver(uuid); refresher.refresh(); }); }; } - private void setupStaticItems(PaginatedGui gui, Player player) { + private void setupStaticItems(Player player, PaginatedGui gui) { GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.sendingGUI.show(player)); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 46f1adcf8..93fd9ce5a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -289,12 +289,10 @@ public void show(Player player) { this.updateNameItem(); this.updateDescriptionItem(); this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> - userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name()))); + userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name(), false))); this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> - lockerOptional.ifPresent(locker -> { - this.updateDestinationItem(player, locker.name()); - })); + lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.name(), false))); this.scheduler.run(() -> this.gui.open(player)); } @@ -358,15 +356,13 @@ public void updateReceiverItem(Player player, String receiverName, boolean sendN this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelReceiverItem, line)); } - public void updateReceiverItem(Player player, String receiverName) { - this.updateReceiverItem(player, receiverName, false); - } - - public void updateDestinationItem(Player player, String destinationLockerDesc) { - this.noticeService.create() - .notice(messages -> messages.parcel.destinationSet) - .player(player.getUniqueId()) - .send(); + public void updateDestinationItem(Player player, String destinationLockerDesc, boolean sendNotice) { + if (sendNotice){ + this.noticeService.create() + .notice(messages -> messages.parcel.destinationSet) + .player(player.getUniqueId()) + .send(); + } if (destinationLockerDesc == null || destinationLockerDesc.isEmpty()) { this.gui.updateItem(DESTINATION_ITEM_SLOT, this.guiSettings.parcelDestinationLockerItem.toItemStack()); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java index 464a8c634..90e25136b 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/MainGui.java @@ -32,7 +32,6 @@ public MainGui( @Override public void show(Player player) { - Gui gui = Gui.gui() .title(resetItalic(this.miniMessage.deserialize(this.guiSettings.mainGuiTitle))) .rows(6) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 189f62c6d..7507b4aa7 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -49,25 +49,15 @@ public void show(Player player) { this.show(player, FIRST_PAGE); } - private void show(Player player, Page page) { + @Override + public void show(Player player, Page page) { PaginatedGui gui = Gui.paginated() .title(resetItalic(this.miniMessage.deserialize(this.guiSettings.parcelListGuiTitle))) .rows(6) .disableAllInteractions() .create(); - GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); - GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); - GuiItem previousPageItem = this.guiSettings.previousPageItem.toGuiItem(event -> this.show(player, page.previous())); - GuiItem nextPageItem = this.guiSettings.nextPageItem.toGuiItem(event -> this.show(player, page.next())); - - for (int slot : CORNER_SLOTS) { - gui.setItem(slot, cornerItem); - } - for (int slot : BORDER_SLOTS) { - gui.setItem(slot, backgroundItem); - } + this.setupStaticItems(player, gui); this.guiManager.getParcelsByReceiver(player.getUniqueId(), page).thenAccept(result -> { if (result.items().isEmpty() && page.hasPrevious()) { @@ -88,18 +78,25 @@ private void show(Player player, Page page) { gui.addItem(parcelItem.asGuiItem()); } - gui.setItem(49, closeItem); - - if (result.hasNextPage()) { - gui.setItem(51, nextPageItem); - } - - if (page.hasPrevious()) { - gui.setItem(47, previousPageItem); - } + this.setupNavigation(gui, page, result, player, this.guiSettings); this.scheduler.run(() -> gui.open(player)); }); } + + private void setupStaticItems(Player player, PaginatedGui gui) { + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); + + for (int slot : CORNER_SLOTS) { + gui.setItem(slot, cornerItem); + } + for (int slot : BORDER_SLOTS) { + gui.setItem(slot, backgroundItem); + } + + gui.setItem(49, closeItem); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index e3e725147..a8e171388 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -48,20 +48,7 @@ public void show(Player player) { .create(); ConfigItem parcelItem = this.guiSettings.parcelItem; - GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); - GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); - GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); - - for (int slot : CORNER_SLOTS) { - gui.setItem(slot, cornerItem); - } - - for (int slot : BORDER_SLOTS) { - gui.setItem(slot, backgroundItem); - } - - gui.setItem(49, closeItem); - + this.setupStaticItems(player, gui); this.guiManager.getParcelsBySender(player.getUniqueId()).thenAccept(optionalParcels -> { List parcels = optionalParcels.orElse(Collections.emptyList()); @@ -81,4 +68,20 @@ public void show(Player player) { this.scheduler.run(() -> gui.open(player)); }); } + + private void setupStaticItems(Player player, PaginatedGui gui) { + GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); + GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); + GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> this.mainGUI.show(player)); + + for (int slot : CORNER_SLOTS) { + gui.setItem(slot, cornerItem); + } + + for (int slot : BORDER_SLOTS) { + gui.setItem(slot, backgroundItem); + } + + gui.setItem(49, closeItem); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 0cd4585db..6134c7ada 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -125,21 +125,13 @@ public void collect(Player player, Parcel parcel) { // TODO: Do not delete, archive instead this.invalidate(parcel); - this.parcelRepository.delete(parcel) - .thenAccept(v -> this.parcelContentRepository.delete(optional.get().uniqueId())) - .whenComplete((v, throwable) -> { - if (throwable != null) { - this.noticeService.create() - .notice(messages -> messages.parcel.cannotCollect) - .player(player.getUniqueId()) - .send(); - return; - } - this.noticeService.create() - .notice(messages -> messages.parcel.collected) - .player(player.getUniqueId()) - .send(); - }); + this.parcelRepository.delete(parcel); + this.parcelContentRepository.delete(parcel.uuid()); + + this.noticeService.create() + .notice(messages -> messages.parcel.collected) + .player(player.getUniqueId()) + .send(); }); } From 30c175753df9eaa176c5e6f8011b5096108582c8 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 24 Aug 2025 14:25:21 +0200 Subject: [PATCH 23/51] Beautify configs, delete unnecessary tests --- .../implementation/MessageConfig.java | 14 +- .../implementation/PluginConfig.java | 10 +- .../gui/implementation/locker/LockerGui.java | 2 +- .../locker/repository/LockerCacheTest.java | 139 -------------- .../parcel/repository/ParcelCacheTest.java | 175 ------------------ 5 files changed, 10 insertions(+), 330 deletions(-) delete mode 100644 src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java delete mode 100644 src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 4ae88f1c4..2b2ebba4e 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -8,10 +8,8 @@ @SuppressWarnings("ALL") @Header({ - " ", "# This file contains messages used by the ParcelLockers plugin.", "# You can customize these messages to fit your server's theme or language.", - " ", }) public class MessageConfig extends OkaeriConfig { @@ -145,12 +143,12 @@ public static class LockerMessages extends OkaeriConfig { } public static class AdminMessages extends OkaeriConfig { - public Notice deletedLockers = Notice.chat("&4โš  &cAll parcel lockers have been deleted!"); - public Notice deletedParcels = Notice.chat("&4โš  &cAll parcels have been deleted!"); - public Notice deletedItemStorages = Notice.chat("&4โš  &cAll item storages have been deleted!"); - public Notice deletedContents = Notice.chat("&4โš  &cAll parcel contents have been deleted!"); - public Notice deletedDeliveries = Notice.chat("&4โš  &cAll deliveries have been deleted!"); - public Notice deletedUsers = Notice.chat("&4โš  &cAll users have been deleted!"); + public Notice deletedLockers = Notice.chat("&4โš  &cAll ({COUNT}) parcel lockers have been deleted!"); + public Notice deletedParcels = Notice.chat("&4โš  &cAll ({COUNT}) parcels have been deleted!"); + public Notice deletedItemStorages = Notice.chat("&4โš  &cAll ({COUNT}) item storages have been deleted!"); + public Notice deletedContents = Notice.chat("&4โš  &cAll ({COUNT}) parcel contents have been deleted!"); + public Notice deletedDeliveries = Notice.chat("&4โš  &cAll ({COUNT}) deliveries have been deleted!"); + public Notice deletedUsers = Notice.chat("&4โš  &cAll ({COUNT}) users have been deleted!"); public Notice invalidNumberOfStacks = Notice.chat("&4โœ˜ &cInvalid number of stacks. Must be between 1 and 36."); public Notice invalidItemMaterials = Notice.chat("&4โœ˜ &cItem materials to give are invalid (should never happen, if it does report this on our discord)."); } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 8fa491bee..14b8bbbb4 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -11,16 +11,12 @@ import org.bukkit.Material; @Header({ - " ", "# ParcelLockers plugin configuration file.", - "#", - "# This file is used to configure the plugin.", + "", "# You can change the settings here to customize the plugin behavior or appearance.", - "#", - "# If you want to reload the configuration, you can do it using the /parcellockers reload command." + "# If you want to reload the configuration, you can do it using the '/parcellockers reload' command." }) public class PluginConfig extends OkaeriConfig { - @Comment({ "", "# The plugin settings." }) public Settings settings = new Settings(); @Comment({ "", "# The plugin GUI settings." }) @@ -28,7 +24,7 @@ public class PluginConfig extends OkaeriConfig { public static class Settings extends OkaeriConfig { - @Comment({ "", "# Whether the player after entering the server should receive information about the new version of the plugin?" }) + @Comment("# Whether the player after entering the server should receive information about the new version of the plugin?") public boolean receiveUpdates = true; @Comment({ "", "# The database type. (MYSQL, SQLITE)" }) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java index 3116ad977..662220e80 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/LockerGui.java @@ -70,7 +70,7 @@ public void show(Player player, UUID entryLocker) { gui.open(player); } - private void setupStaticItems(Gui gui, Player player) { + private void setupStaticItems(Player player, Gui gui) { GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(); GuiItem cornerItem = this.guiSettings.cornerItem.toGuiItem(); GuiItem closeItem = this.guiSettings.closeItem.toGuiItem(event -> gui.close(player)); diff --git a/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java b/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java deleted file mode 100644 index 19cc56f1c..000000000 --- a/src/test/java/com/eternalcode/parcellockers/locker/repository/LockerCacheTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.eternalcode.parcellockers.locker.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.eternalcode.parcellockers.locker.Locker; -import com.eternalcode.parcellockers.shared.Position; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class LockerCacheTest { - - private LockerCache lockerCache; - private Locker testLocker; - private Position testPosition; - - @BeforeEach - void setUp() { - this.lockerCache = new LockerCache(); - this.testPosition = new Position(10, 20, 30, "world"); - this.testLocker = new Locker(UUID.randomUUID(), "Test locker", this.testPosition); - } - - @Test - void shouldPutAndGetLockerByUuid() { - // given - this.lockerCache.put(this.testLocker); - - // when - Optional result = this.lockerCache.get(this.testLocker.uuid()); - - // then - assertTrue(result.isPresent()); - assertEquals(this.testLocker, result.get()); - } - - @Test - void shouldPutAndGetLockerByPosition() { - // given - this.lockerCache.put(this.testLocker); - - // when - Optional result = this.lockerCache.get(this.testPosition); - - // then - assertTrue(result.isPresent()); - assertEquals(this.testLocker, result.get()); - } - - @Test - void shouldRemoveLockerByUuid() { - // given - this.lockerCache.put(this.testLocker); - - // when - Locker removed = this.lockerCache.remove(this.testLocker.uuid()); - - // then - assertEquals(this.testLocker, removed); - assertFalse(this.lockerCache.get(this.testLocker.uuid()).isPresent()); - assertFalse(this.lockerCache.get(this.testPosition).isPresent()); - } - - @Test - void shouldRemoveLockerByObject() { - // given - this.lockerCache.put(this.testLocker); - - // when - Locker removed = this.lockerCache.remove(this.testLocker); - - // then - assertEquals(this.testLocker, removed); - assertFalse(this.lockerCache.get(this.testLocker.uuid()).isPresent()); - assertFalse(this.lockerCache.get(this.testPosition).isPresent()); - } - - @Test - void shouldPutAllLockers() { - // given - Locker locker1 = new Locker(UUID.randomUUID(), "Locker 1", new Position(1, 2, 3, "world")); - Locker locker2 = new Locker(UUID.randomUUID(), "Locker 2", new Position(4, 5, 6, "world")); - Map lockers = Map.of( - locker1.uuid(), locker1, - locker2.uuid(), locker2 - ); - - // when - this.lockerCache.putAll(lockers); - - // then - assertTrue(this.lockerCache.get(locker1.uuid()).isPresent()); - assertTrue(this.lockerCache.get(locker2.uuid()).isPresent()); - assertTrue(this.lockerCache.get(locker1.position()).isPresent()); - assertTrue(this.lockerCache.get(locker2.position()).isPresent()); - } - - @Test - void shouldClearCache() { - // given - this.lockerCache.put(this.testLocker); - - // when - this.lockerCache.clear(); - - // then - assertFalse(this.lockerCache.get(this.testLocker.uuid()).isPresent()); - assertFalse(this.lockerCache.get(this.testPosition).isPresent()); - assertEquals(0, this.lockerCache.cache().size()); - } - - @Test - void shouldReturnCorrectSize() { - // given - this.lockerCache.put(this.testLocker); - - // when & then - assertEquals(1, this.lockerCache.cache().size()); - assertEquals(1, this.lockerCache.positionCache().size()); - } - - @Test - void shouldReturnUnmodifiableMaps() { - // given - this.lockerCache.put(this.testLocker); - - // when - Map cache = this.lockerCache.cache(); - Map positionCache = this.lockerCache.positionCache(); - - // then - assertThrows(UnsupportedOperationException.class, () -> cache.clear()); - assertThrows(UnsupportedOperationException.class, () -> positionCache.clear()); - } -} diff --git a/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java b/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java deleted file mode 100644 index 1389c0c83..000000000 --- a/src/test/java/com/eternalcode/parcellockers/parcel/repository/ParcelCacheTest.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.eternalcode.parcellockers.parcel.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.eternalcode.parcellockers.parcel.Parcel; -import com.eternalcode.parcellockers.parcel.ParcelSize; -import com.eternalcode.parcellockers.parcel.ParcelStatus; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class ParcelCacheTest { - - private ParcelCache parcelCache; - private Parcel testParcel; - - @BeforeEach - void setUp() { - this.parcelCache = new ParcelCache(); - this.testParcel = new Parcel( - UUID.randomUUID(), - UUID.randomUUID(), - "Test Package", - "Test package name", - false, - UUID.randomUUID(), - ParcelSize.MEDIUM, - UUID.randomUUID(), - UUID.randomUUID(), - ParcelStatus.PENDING - ); - } - - @Test - void shouldPutAndGetParcel() { - // given - this.parcelCache.put(this.testParcel); - - // when - Optional result = this.parcelCache.get(this.testParcel.uuid()); - - // then - assertTrue(result.isPresent()); - assertEquals(this.testParcel, result.get()); - } - - @Test - void shouldReturnEmptyWhenParcelNotFound() { - // when - Optional result = this.parcelCache.get(UUID.randomUUID()); - - // then - assertFalse(result.isPresent()); - } - - @Test - void shouldRemoveParcel() { - // given - this.parcelCache.put(this.testParcel); - - // when - Parcel removed = this.parcelCache.remove(this.testParcel.uuid()); - - // then - assertEquals(this.testParcel, removed); - assertFalse(this.parcelCache.get(this.testParcel.uuid()).isPresent()); - } - - @Test - void shouldReturnNullWhenRemovingNonExistentParcel() { - // when - Parcel removed = this.parcelCache.remove(UUID.randomUUID()); - - // then - assertNull(removed); - } - - @Test - void shouldPutAllParcels() { - // given - Parcel parcel1 = new Parcel( - UUID.randomUUID(), - UUID.randomUUID(), - "Package 1", - "Description 1", - true, - UUID.randomUUID(), - ParcelSize.SMALL, - UUID.randomUUID(), - UUID.randomUUID(), - ParcelStatus.PENDING - ); - - Parcel parcel2 = new Parcel( - UUID.randomUUID(), - UUID.randomUUID(), - "Package 2", - "Description 2", - false, - UUID.randomUUID(), - ParcelSize.LARGE, - UUID.randomUUID(), - UUID.randomUUID(), - ParcelStatus.DELIVERED - ); - - Map parcels = Map.of( - parcel1.uuid(), parcel1, - parcel2.uuid(), parcel2 - ); - - // when - this.parcelCache.putAll(parcels); - - // then - assertTrue(this.parcelCache.get(parcel1.uuid()).isPresent()); - assertTrue(this.parcelCache.get(parcel2.uuid()).isPresent()); - assertEquals(2, this.parcelCache.cache().size()); - } - - @Test - void shouldClearCache() { - // given - this.parcelCache.put(this.testParcel); - - // when - this.parcelCache.clear(); - - // then - assertFalse(this.parcelCache.get(this.testParcel.uuid()).isPresent()); - assertEquals(0, this.parcelCache.cache().size()); - } - - @Test - void shouldReturnCorrectSize() { - // given - this.parcelCache.put(this.testParcel); - - // when & then - assertEquals(1, this.parcelCache.cache().size()); - } - - @Test - void shouldReturnUnmodifiableMap() { - // given - this.parcelCache.put(this.testParcel); - - // when - Map cache = this.parcelCache.cache(); - - // then - assertThrows(UnsupportedOperationException.class, () -> cache.clear()); - assertEquals(1, cache.size()); - assertTrue(cache.containsKey(this.testParcel.uuid())); - } - - @Test - void shouldWorkWithCustomConfiguration() { - // given - ParcelCache cache = new ParcelCache(); - - // when - cache.put(this.testParcel); - - // then - assertTrue(cache.get(this.testParcel.uuid()).isPresent()); - assertEquals(1, cache.cache().size()); - } -} From a23fc6c5fb208409da5401258c9468f9f519678f Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Mon, 25 Aug 2025 09:59:56 +0200 Subject: [PATCH 24/51] find -> fetch, fix improper item type set in config --- .../parcellockers/ParcelLockers.java | 73 ++++++++----------- .../command/debug/DebugCommand.java | 51 +++++++++++-- .../implementation/PluginConfig.java | 12 +-- .../content/ParcelContentManager.java | 2 +- .../repository/ParcelContentRepository.java | 2 +- .../ParcelContentRepositoryOrmLite.java | 2 +- .../delivery/DeliveryManager.java | 7 ++ .../repository/DeliveryRepository.java | 4 +- .../repository/DeliveryRepositoryOrmLite.java | 4 +- .../parcellockers/gui/GuiManager.java | 4 +- .../implementation/locker/DestinationGui.java | 13 +++- .../implementation/locker/ItemStorageGui.java | 21 +++--- .../gui/implementation/locker/SendingGui.java | 21 ++++-- .../implementation/remote/SentParcelsGui.java | 16 +++- .../itemstorage/ItemStorageManager.java | 8 +- .../repository/ItemStorageRepository.java | 5 +- .../ItemStorageRepositoryOrmLite.java | 11 ++- .../parcellockers/locker/LockerManager.java | 33 +++++---- .../locker/repository/LockerRepository.java | 8 +- .../repository/LockerRepositoryOrmLite.java | 8 +- .../parcellockers/parcel/ParcelService.java | 6 +- .../parcel/ParcelServiceImpl.java | 49 +++++-------- .../parcel/repository/ParcelRepository.java | 16 ++-- .../repository/ParcelRepositoryOrmLite.java | 54 ++++++++------ .../parcellockers/user/UserManagerImpl.java | 6 +- .../user/repository/UserRepository.java | 6 +- .../repository/UserRepositoryOrmLite.java | 6 +- .../LockerRepositoryIntegrationTest.java | 14 ++-- .../ParcelRepositoryIntegrationTest.java | 10 +-- 29 files changed, 270 insertions(+), 202 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index e17fc7350..a92532d55 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -28,7 +28,6 @@ import com.eternalcode.parcellockers.locker.controller.LockerPlaceController; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; import com.eternalcode.parcellockers.notification.NoticeService; -import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelServiceImpl; import com.eternalcode.parcellockers.parcel.ParcelStatus; @@ -42,7 +41,6 @@ import com.eternalcode.parcellockers.user.controller.PrepareUserController; import com.eternalcode.parcellockers.user.repository.UserRepository; import com.eternalcode.parcellockers.user.repository.UserRepositoryOrmLite; -import com.google.common.base.Stopwatch; import dev.rollczi.litecommands.LiteCommands; import dev.rollczi.litecommands.adventure.LiteAdventureExtension; import dev.rollczi.litecommands.annotations.LiteCommandsAnnotations; @@ -55,9 +53,6 @@ import java.sql.SQLException; import java.time.Duration; import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; import java.util.stream.Stream; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bstats.bukkit.Metrics; @@ -69,21 +64,18 @@ public final class ParcelLockers extends JavaPlugin { private LiteCommands liteCommands; private SkullAPI skullAPI; - private DatabaseManager databaseManager; @Override public void onEnable() { - Stopwatch started = Stopwatch.createStarted(); - MiniMessage miniMessage = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) .build(); - ConfigService configManager = new ConfigService(); - PluginConfig config = configManager.create(PluginConfig.class, new File(this.getDataFolder(), "config.yml")); - MessageConfig messageConfig = configManager.create(MessageConfig.class, new File(this.getDataFolder(), "messages.yml")); + ConfigService configService = new ConfigService(); + PluginConfig config = configService.create(PluginConfig.class, new File(this.getDataFolder(), "config.yml")); + MessageConfig messageConfig = configService.create(MessageConfig.class, new File(this.getDataFolder(), "messages.yml")); Server server = this.getServer(); NoticeService noticeService = new NoticeService(messageConfig, miniMessage); Scheduler scheduler = new BukkitSchedulerImpl(this); @@ -94,8 +86,10 @@ public void onEnable() { try { databaseManager.connect(); } catch (SQLException exception) { - this.getLogger().severe("Could not connect to database! Some functions may not work properly!"); - throw new RuntimeException(exception); + this.getLogger().severe("Could not connect to database! Disabling..."); + exception.printStackTrace(); + this.getServer().getPluginManager().disablePlugin(this); + return; } this.skullAPI = LiteSkullFactory.builder() @@ -148,28 +142,29 @@ public void onEnable() { guiManager ); + LockerGui lockerGUI = new LockerGui( + miniMessage, + scheduler, + config.guiSettings, + guiManager, + noticeService, + this.skullAPI + ); + this.liteCommands = LiteBukkitFactory.builder(this.getName(), this) .extension(new LiteAdventureExtension<>()) .message(LiteBukkitMessages.PLAYER_ONLY, messageConfig.playerOnlyCommand) .message(LiteBukkitMessages.PLAYER_NOT_FOUND, messageConfig.playerNotFound) .commands(LiteCommandsAnnotations.of( new ParcelCommand(mainGUI), - new ParcelLockersCommand(configManager, config, noticeService), - new DebugCommand(parcelService, lockerManager, itemStorageManager, parcelContentManager, deliveryManager, userManager, noticeService) + new ParcelLockersCommand(configService, config, noticeService), + new DebugCommand(parcelService, lockerManager, itemStorageManager, parcelContentManager, + noticeService) )) .invalidUsage(new InvalidUsageHandlerImpl(noticeService)) .missingPermission(new MissingPermissionsHandlerImpl(noticeService)) .build(); - LockerGui lockerGUI = new LockerGui( - miniMessage, - scheduler, - config.guiSettings, - guiManager, - noticeService, - this.skullAPI - ); - Stream.of( new LockerInteractionController(lockerManager, lockerGUI), new LockerPlaceController(config, this, lockerManager, noticeService), @@ -181,26 +176,16 @@ public void onEnable() { new Metrics(this, 17677); new UpdaterService(this.getPluginMeta().getVersion()); - parcelRepository.findAll().thenAccept(optionalParcels -> { - List parcels = optionalParcels.orElseGet(ArrayList::new).stream() - .filter(parcel -> parcel.status() != ParcelStatus.DELIVERED) - .toList(); - - parcels.forEach(parcel -> - deliveryRepository.find(parcel.uuid()).thenAccept(optionalDelivery -> - optionalDelivery.ifPresent(delivery -> { - long delay = Math.max(0, delivery.deliveryTimestamp().toEpochMilli() - System.currentTimeMillis()); - scheduler.runLaterAsync( - new ParcelSendTask(parcel, parcelService, deliveryManager), - Duration.ofMillis(delay) - ); - }) - ) - ); - }); - - long millis = started.elapsed(TimeUnit.MILLISECONDS); - this.getLogger().log(Level.INFO, "Successfully enabled ParcelLockers in {0}ms", millis); + parcelRepository.fetchAll().thenAccept(optionalParcels -> optionalParcels + .orElseGet(ArrayList::new) + .stream() + .filter(parcel -> parcel.status() != ParcelStatus.DELIVERED) + .forEach(parcel -> deliveryRepository.fetch(parcel.uuid()).thenAccept(optionalDelivery -> + optionalDelivery.ifPresent(delivery -> { + long delay = Math.max(0, delivery.deliveryTimestamp().toEpochMilli() - System.currentTimeMillis()); + scheduler.runLaterAsync(new ParcelSendTask(parcel, parcelService, deliveryManager), Duration.ofMillis(delay)); + }) + ))); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index 8fce11fd5..ec5cd84e6 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -1,23 +1,29 @@ package com.eternalcode.parcellockers.command.debug; +import com.eternalcode.commons.RandomElementUtil; import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.multification.notice.Notice; import com.eternalcode.parcellockers.content.ParcelContentManager; -import com.eternalcode.parcellockers.delivery.DeliveryManager; import com.eternalcode.parcellockers.itemstorage.ItemStorageManager; import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.notification.NoticeService; +import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelService; -import com.eternalcode.parcellockers.user.UserManager; +import com.eternalcode.parcellockers.parcel.ParcelSize; +import com.eternalcode.parcellockers.parcel.ParcelStatus; import dev.rollczi.litecommands.annotations.argument.Arg; import dev.rollczi.litecommands.annotations.command.Command; import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; +import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -31,8 +37,6 @@ public class DebugCommand { private final LockerManager lockerManager; private final ItemStorageManager itemStorageManager; private final ParcelContentManager contentManager; - private final DeliveryManager deliveryManager; - private final UserManager userManager; private final NoticeService noticeService; public DebugCommand( @@ -40,16 +44,12 @@ public DebugCommand( LockerManager lockerManager, ItemStorageManager itemStorageManager, ParcelContentManager contentManager, - DeliveryManager deliveryManager, - UserManager userManager, NoticeService noticeService ) { this.parcelService = parcelService; this.lockerManager = lockerManager; this.itemStorageManager = itemStorageManager; this.contentManager = contentManager; - this.deliveryManager = deliveryManager; - this.userManager = userManager; this.noticeService = noticeService; } @@ -112,4 +112,39 @@ void getRandomItem(@Sender Player player, @Arg int stacks) { ItemUtil.giveItem(player, itemStack); } } + + @Execute(name = "send") + void send(@Sender Player player, @Arg int count) { + Random random = new Random(); + for (int i = 0; i < count; i++) { + this.parcelService.send( + player, + new Parcel( + UUID.randomUUID(), + player.getUniqueId(), + RandomStringUtils.random(12), + "", + RandomUtils.nextBoolean(), + player.getUniqueId(), + ParcelSize.LARGE, + UUID.randomUUID(), + UUID.randomUUID(), + ParcelStatus.PENDING + ), + this.generateRandomItems(random.nextInt(1, 20)) + ); + } + } + + private List generateRandomItems(int count) { + List items = new ArrayList<>(); + List itemMaterials = Arrays.stream(Material.values()).filter(Material::isItem).toList(); + Random random = ThreadLocalRandom.current(); + for (int i = 0; i < count; i++) { + Material material = RandomElementUtil.randomElement(itemMaterials).get(); + int randomAmount = Math.min(random.nextInt(64) + 1, material.getMaxStackSize()); + items.add(new ItemStack(material, randomAmount)); + } + return items; + } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 14b8bbbb4..dd69e91b0 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -205,7 +205,7 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel item storage button" }) public ConfigItem parcelStorageItem = new ConfigItem() .name("&6\uD83D\uDCBE Parcel storage") - .lore(List.of("&6ยป &eClick to add/remove items from this parcel")) + .lore(List.of("&6ยป &eClick to add/remove items from this parcel.")) .type(Material.CHEST); @Comment({ "", "# The item of the parcel name button" }) @@ -223,7 +223,7 @@ public static class GuiSettings extends OkaeriConfig { .lore(List.of("&2ยป &aClick to add parcel description.")) .type(Material.OAK_SIGN); - public String parcelDescriptionSetLine = "&2โ€บ &aCurrent parcel name: &2{DESCRIPTION}"; + public String parcelDescriptionSetLine = "&2โ€บ &aCurrent parcel description: &2{DESCRIPTION}"; @Comment({ "", "# The item of the parcel receiver button" }) public ConfigItem parcelReceiverItem = new ConfigItem() @@ -242,8 +242,8 @@ public static class GuiSettings extends OkaeriConfig { @Comment({ "", "# The item of the parcel destination locker button" }) public ConfigItem parcelDestinationLockerItem = new ConfigItem() - .name("&3\uD83D\uDEE3 Destination locker") - .lore(List.of("&3ยป &bClick to edit the parcel destination locker.")) + .name("&9\uD83D\uDEE3 Destination locker") + .lore(List.of("&9ยป &3Click to edit the parcel destination locker.")) .type(Material.END_PORTAL_FRAME); @Comment({ "", "# The item of the previous page button" }) @@ -280,10 +280,10 @@ public static class GuiSettings extends OkaeriConfig { public ConfigItem destinationLockerItem = new ConfigItem() .name("&3{DESCRIPTION}") .lore(List.of("&3ยป &bClick to select this locker.")) - .type(Material.CHISELED_BOOKSHELF); + .type(Material.END_PORTAL_FRAME); @Comment({ "", "# The lore of the button in the sending GUI of the parcel destination locker selection GUI" }) - public String parcelDestinationLockerSetLine = "&6โ€บ &eCurrent destination locker: &6{DESCRIPTION}"; + public String parcelDestinationLockerSetLine = "&9โ€บ &3Current destination locker: &9{DESCRIPTION}"; @Comment({ "", "# The destination GUI locker button lore in case the destination locker is set." }) public String parcelDestinationSetLine = "&2โœ” &aSelected!"; diff --git a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java index 5e1bfddc5..6679be80f 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java +++ b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java @@ -30,7 +30,7 @@ public CompletableFuture> get(UUID parcelId) { if (content != null) { return CompletableFuture.completedFuture(Optional.of(content)); } - return this.contentRepository.find(parcelId).thenApply(optional -> { + return this.contentRepository.fetch(parcelId).thenApply(optional -> { optional.ifPresent(value -> this.cache.put(parcelId, value)); return optional; }); diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java index 71e2ebcc1..7b93a320d 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java @@ -9,7 +9,7 @@ public interface ParcelContentRepository { CompletableFuture save(ParcelContent parcelContent); - CompletableFuture> find(UUID uniqueId); + CompletableFuture> fetch(UUID uniqueId); void delete(UUID uniqueId); diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java index e899d43be..b9d4c35e4 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java @@ -39,7 +39,7 @@ public CompletableFuture deleteAll() { } @Override - public CompletableFuture> find(UUID uniqueId) { + public CompletableFuture> fetch(UUID uniqueId) { return this.selectSafe(ParcelContentTable.class, uniqueId) .thenApply(optional -> optional.map(ParcelContentTable::toParcelContent)); } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java index 37ce1ba4a..518bfb8eb 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java @@ -18,6 +18,8 @@ public class DeliveryManager { public DeliveryManager(DeliveryRepository deliveryRepository) { this.deliveryRepository = deliveryRepository; + + this.cacheAll(); } public Delivery getOrCreate(UUID parcel, Instant deliveryTimestamp) { @@ -38,4 +40,9 @@ public void delete(UUID parcel) { this.deliveryCache.invalidate(parcel); this.deliveryRepository.delete(parcel); } + + private void cacheAll() { + this.deliveryRepository.fetchAll() + .thenAccept(all -> all.ifPresent(list -> list.forEach(delivery -> this.deliveryCache.put(delivery.parcel(), delivery)))); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java index c3d47f0bd..ae8fd55fd 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java @@ -10,9 +10,9 @@ public interface DeliveryRepository { void save(Delivery delivery); - CompletableFuture> find(UUID parcel); + CompletableFuture> fetch(UUID parcel); void delete(UUID parcel); - CompletableFuture>> findAll(); + CompletableFuture>> fetchAll(); } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java index 1598ccf62..36d11501e 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java @@ -29,13 +29,13 @@ public void save(Delivery delivery) { } @Override - public CompletableFuture> find(UUID parcel) { + public CompletableFuture> fetch(UUID parcel) { return this.selectSafe(DeliveryTable.class, parcel) .thenApply(optional -> optional.map(DeliveryTable::toDelivery)); } @Override - public CompletableFuture>> findAll() { + public CompletableFuture>> fetchAll() { return this.selectAll(DeliveryTable.class).thenApply(parcels -> Optional.of(parcels.stream() .map(DeliveryTable::toDelivery) .toList())); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java index ab760955a..f669f8378 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java @@ -78,8 +78,8 @@ public CompletableFuture> getParcelsByReceiver(UUID receiver, return this.parcelService.getByReceiver(receiver, page); } - public CompletableFuture>> getParcelsBySender(UUID sender) { - return this.parcelService.getBySender(sender); + public CompletableFuture> getParcelsBySender(UUID sender, Page page) { + return this.parcelService.getBySender(sender, page); } public CompletableFuture> getUser(UUID userUuid) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java index 56206966b..7baed7166 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/DestinationGui.java @@ -71,7 +71,12 @@ public void show(Player player, Page page) { this.loadLockers(player, result, refresher).forEach(refresher::addItem); this.scheduler.run(() -> gui.open(player)); - }).orTimeout(5, TimeUnit.SECONDS); + }).orTimeout(5, TimeUnit.SECONDS) + .exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + } private List> loadLockers(Player player, PageResult result, PaginatedGuiRefresher refresh) { @@ -82,16 +87,16 @@ private List> loadLockers(Player player, PageResult re private Supplier toItem(Player player, Locker locker, PaginatedGuiRefresher refresher) { UUID uuid = locker.uuid(); - ConfigItem parcelItem = this.guiSettings.destinationLockerItem.clone(); + ConfigItem lockerItem = this.guiSettings.destinationLockerItem.clone(); return () -> { - String name = parcelItem.name().replace("{DESCRIPTION}", locker.name()); + String name = lockerItem.name().replace("{DESCRIPTION}", locker.name()); boolean isLockerSelected = uuid.equals(this.state.destinationLocker()); String oneLineLore = isLockerSelected ? this.guiSettings.parcelDestinationSetLine : this.guiSettings.parcelDestinationNotSetLine; - return parcelItem + return lockerItem .name(name) .glow(isLockerSelected) .lore(List.of(oneLineLore)) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index 2ce654ec9..332bdcce8 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -52,15 +52,18 @@ void show(Player player, ParcelSize size) { GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); - GuiItem confirmItem = this.guiSettings.confirmItemsItem.toGuiItem(event -> new SendingGui( - this.scheduler, - this.guiSettings, - this.miniMessage, - this.noticeService, - this.guiManager, - this.skullAPI, - this.state - ).show(player)); + GuiItem confirmItem = this.guiSettings.confirmItemsItem.toGuiItem(event -> { + event.setCancelled(true); + new SendingGui( + this.scheduler, + this.guiSettings, + this.miniMessage, + this.noticeService, + this.guiManager, + this.skullAPI, + this.state + ).show(player); + }); switch (size) { case SMALL -> gui = Gui.storage() diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 93fd9ce5a..30d2bef0e 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -288,11 +288,15 @@ public void show(Player player) { this.updateNameItem(); this.updateDescriptionItem(); - this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> - userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name(), false))); + if (this.state.receiver() != null) { + this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> + userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name(), false))); + } - this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> - lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.name(), false))); + if (this.state.destinationLocker() != null) { + this.guiManager.getLocker(this.state.destinationLocker()).thenAccept(lockerOptional -> + lockerOptional.ifPresent(locker -> this.updateDestinationItem(player, locker.name(), false))); + } this.scheduler.run(() -> this.gui.open(player)); } @@ -365,7 +369,14 @@ public void updateDestinationItem(Player player, String destinationLockerDesc, b } if (destinationLockerDesc == null || destinationLockerDesc.isEmpty()) { - this.gui.updateItem(DESTINATION_ITEM_SLOT, this.guiSettings.parcelDestinationLockerItem.toItemStack()); + this.gui.setItem(DESTINATION_ITEM_SLOT, this.guiSettings.parcelDestinationLockerItem.toGuiItem(event -> new DestinationGui( + this.scheduler, + this.guiSettings, + this.miniMessage, + this.guiManager, + this, + this.state + ).show(player))); return; } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index a8e171388..0ccc63a90 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -7,11 +7,11 @@ import com.eternalcode.parcellockers.gui.GuiView; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; +import com.eternalcode.parcellockers.shared.Page; import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; -import java.util.Collections; import java.util.List; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -19,6 +19,10 @@ public class SentParcelsGui implements GuiView { + private static final int WIDTH = 7; + private static final int HEIGHT = 4; + private static final Page FIRST_PAGE = new Page(0, WIDTH * HEIGHT); + private final Scheduler scheduler; private final MiniMessage miniMessage; private final GuiSettings guiSettings; @@ -39,8 +43,12 @@ public SentParcelsGui( this.guiManager = guiManager; } - @Override public void show(Player player) { + this.show(player, FIRST_PAGE); + } + + @Override + public void show(Player player, Page page) { PaginatedGui gui = Gui.paginated() .title(this.miniMessage.deserialize(this.guiSettings.sentParcelsTitle)) .rows(6) @@ -50,8 +58,8 @@ public void show(Player player) { ConfigItem parcelItem = this.guiSettings.parcelItem; this.setupStaticItems(player, gui); - this.guiManager.getParcelsBySender(player.getUniqueId()).thenAccept(optionalParcels -> { - List parcels = optionalParcels.orElse(Collections.emptyList()); + this.guiManager.getParcelsBySender(player.getUniqueId(), page).thenAccept(result -> { + List parcels = result.items(); for (Parcel parcel : parcels) { PaperItemBuilder item = parcelItem.toBuilder(); diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java index 68d7f93ad..598b3d62c 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -23,6 +23,8 @@ public class ItemStorageManager { public ItemStorageManager(ItemStorageRepository itemStorageRepository) { this.itemStorageRepository = itemStorageRepository; + + this.cacheAll(); } public CompletableFuture> get(UUID parcelId) { @@ -30,7 +32,7 @@ public CompletableFuture> get(UUID parcelId) { if (content != null) { return CompletableFuture.completedFuture(Optional.of(content)); } - return this.itemStorageRepository.find(parcelId).thenApply(optional -> { + return this.itemStorageRepository.fetch(parcelId).thenApply(optional -> { optional.ifPresent(value -> this.cache.put(parcelId, value)); return optional; }); @@ -49,6 +51,10 @@ public ItemStorage create(UUID parcel, List items) { this.itemStorageRepository.save(content); return content; } + + private void cacheAll() { + this.itemStorageRepository.fetchAll().thenAccept(all -> all.ifPresent(list -> list.forEach(itemStorage -> this.cache.put(itemStorage.owner(), itemStorage)))); + } public void delete(UUID parcel) { this.cache.invalidate(parcel); diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java index 22b09f516..b00c80dd8 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepository.java @@ -1,6 +1,7 @@ package com.eternalcode.parcellockers.itemstorage.repository; import com.eternalcode.parcellockers.itemstorage.ItemStorage; +import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -9,7 +10,9 @@ public interface ItemStorageRepository { CompletableFuture save(ItemStorage itemStorage); - CompletableFuture> find(UUID uuid); + CompletableFuture> fetch(UUID uuid); + + CompletableFuture>> fetchAll(); CompletableFuture delete(UUID uuid); diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java index 37a7830a4..65b3e9c7b 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/repository/ItemStorageRepositoryOrmLite.java @@ -6,6 +6,7 @@ import com.eternalcode.parcellockers.itemstorage.ItemStorage; import com.j256.ormlite.table.TableUtils; import java.sql.SQLException; +import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -28,10 +29,18 @@ public CompletableFuture save(ItemStorage itemStorage) { } @Override - public CompletableFuture> find(UUID uuid) { + public CompletableFuture> fetch(UUID uuid) { return this.selectSafe(ItemStorageTable.class, uuid).thenApply(optional -> optional.map(ItemStorageTable::toItemStorage)); } + @Override + public CompletableFuture>> fetchAll() { + return this.selectAll(ItemStorageTable.class) + .thenApply(list -> Optional.of(list.stream() + .map(ItemStorageTable::toItemStorage) + .toList())); + } + @Override public CompletableFuture delete(UUID uuid) { return this.deleteById(ItemStorageTable.class, uuid); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 254e3fc57..55406af55 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -30,6 +30,8 @@ public class LockerManager { public LockerManager(LockerRepository lockerRepository) { this.lockerRepository = lockerRepository; + + this.cacheAll(); } public CompletableFuture> get(UUID uniqueId) { @@ -43,7 +45,7 @@ public CompletableFuture> get(UUID uniqueId) { return CompletableFuture.completedFuture(Optional.of(locker)); } - return this.lockerRepository.find(uniqueId).thenApply(optionalLocker -> { + return this.lockerRepository.fetch(uniqueId).thenApply(optionalLocker -> { optionalLocker.ifPresent(locker1 -> { this.lockersByUUID.put(locker1.uuid(), locker1); this.lockersByPosition.put(locker1.position(), locker1); @@ -59,7 +61,7 @@ public CompletableFuture> get(Position position) { return CompletableFuture.completedFuture(Optional.of(locker)); } - return this.lockerRepository.find(position).thenApply(optionalLocker -> { + return this.lockerRepository.fetch(position).thenApply(optionalLocker -> { optionalLocker.ifPresent(locker1 -> { this.lockersByUUID.put(locker1.uuid(), locker1); this.lockersByPosition.put(locker1.position(), locker1); @@ -69,21 +71,12 @@ public CompletableFuture> get(Position position) { } public CompletableFuture> get(Page page) { - return this.lockerRepository.findPage(page); - } - - public CompletableFuture>> getAll() { - List lockers = List.copyOf(this.lockersByUUID.asMap().values()); - if (!lockers.isEmpty()) { - return CompletableFuture.completedFuture(Optional.of(lockers)); + List cached = List.copyOf(this.lockersByUUID.asMap().values()); + boolean hasNextPage = cached.size() > page.getLimit(); + if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { + return CompletableFuture.completedFuture(new PageResult<>(cached, false)); } - return this.lockerRepository.findAll().thenApply(optionalLockers -> { - optionalLockers.ifPresent(lockers1 -> lockers1.forEach(locker -> { - this.lockersByUUID.put(locker.uuid(), locker); - this.lockersByPosition.put(locker.position(), locker); - })); - return optionalLockers; - }); + return this.lockerRepository.fetchPage(page); } public Locker getOrCreate(UUID uniqueId, String name, Position position) { @@ -139,4 +132,12 @@ public void deleteAll(CommandSender sender, NoticeService noticeService) { this.lockersByPosition.invalidateAll(); }); } + + private void cacheAll() { + this.lockerRepository.fetchAll() + .thenAccept(optionalLockers -> optionalLockers.ifPresent(lockers -> lockers.forEach(locker -> { + this.lockersByUUID.put(locker.uuid(), locker); + this.lockersByPosition.put(locker.position(), locker); + }))); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java index 171d47038..24e2a1a44 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java @@ -13,11 +13,11 @@ public interface LockerRepository { CompletableFuture save(Locker locker); - CompletableFuture>> findAll(); + CompletableFuture>> fetchAll(); - CompletableFuture> find(UUID uuid); + CompletableFuture> fetch(UUID uuid); - CompletableFuture> find(Position position); + CompletableFuture> fetch(Position position); CompletableFuture delete(UUID uuid); @@ -25,5 +25,5 @@ public interface LockerRepository { CompletableFuture deleteAll(); - CompletableFuture> findPage(Page page); + CompletableFuture> fetchPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index 49e0ee0e6..8f32efaf2 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -35,19 +35,19 @@ public CompletableFuture save(Locker locker) { } @Override - public CompletableFuture>> findAll() { + public CompletableFuture>> fetchAll() { return this.selectAll(LockerTable.class).thenApply(lockers -> Optional.of(lockers.stream() .map(LockerTable::toLocker) .collect(Collectors.toList()))); } @Override - public CompletableFuture> find(UUID uuid) { + public CompletableFuture> fetch(UUID uuid) { return this.selectSafe(LockerTable.class, uuid).thenApply(optional -> optional.map(LockerTable::toLocker)); } @Override - public CompletableFuture> find(Position position) { + public CompletableFuture> fetch(Position position) { return this.action( LockerTable.class, dao -> { List lockers = dao.queryForEq("position", position); @@ -66,7 +66,7 @@ public CompletableFuture delete(Locker locker) { } @Override - public CompletableFuture> findPage(Page page) { + public CompletableFuture> fetchPage(Page page) { return this.action( LockerTable.class, dao -> { List lockers = dao.queryBuilder() diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index d711e9720..58a4c9a8d 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -25,14 +25,10 @@ public interface ParcelService { CompletableFuture> get(UUID uuid); - CompletableFuture>> getBySender(UUID sender); - - CompletableFuture>> getByReceiver(UUID receiver); + CompletableFuture> getBySender(UUID sender, Page page); CompletableFuture> getByReceiver(UUID receiver, Page page); - CompletableFuture>> getAll(); - CompletableFuture delete(UUID uuid); CompletableFuture delete(Parcel parcel); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 6134c7ada..9c42fec35 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -54,6 +54,8 @@ public ParcelServiceImpl( this.deliveryRepository = deliveryRepository; this.parcelContentRepository = parcelContentRepository; this.scheduler = scheduler; + + this.cacheAll(); } @Override @@ -102,7 +104,7 @@ public void delete(CommandSender sender, Parcel parcel) { @Override public void collect(Player player, Parcel parcel) { - this.parcelContentRepository.find(parcel.uuid()).thenAccept(optional -> { + this.parcelContentRepository.fetch(parcel.uuid()).thenAccept(optional -> { if (optional.isEmpty()) { this.noticeService.create() .notice(messages -> messages.parcel.cannotCollect) @@ -141,55 +143,40 @@ public CompletableFuture> get(UUID uuid) { if (cached != null) { return CompletableFuture.completedFuture(Optional.of(cached)); } - return this.parcelRepository.findById(uuid).thenApply(optional -> { + return this.parcelRepository.fetchById(uuid).thenApply(optional -> { optional.ifPresent(this::cache); return optional; }); } @Override - public CompletableFuture>> getBySender(UUID sender) { + public CompletableFuture> getBySender(UUID sender, Page page) { List cached = List.copyOf(this.parcelsBySender.get(sender)); - if (!cached.isEmpty()) { - return CompletableFuture.completedFuture(Optional.of(cached)); + boolean hasNextPage = cached.size() > page.getLimit(); + if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { + return CompletableFuture.completedFuture(new PageResult<>(cached, false)); } - return this.parcelRepository.findBySender(sender).thenApply(optional -> { - optional.ifPresent(parcels -> parcels.forEach(this::cache)); - return optional; + return this.parcelRepository.fetchBySender(sender, page).thenApply(result -> { + result.items().forEach(this::cache); + return result; }); } @Override - public CompletableFuture>> getByReceiver(UUID receiver) { + public CompletableFuture> getByReceiver(UUID receiver, Page page) { List cached = List.copyOf(this.parcelsByReceiver.get(receiver)); - if (!cached.isEmpty()) { - return CompletableFuture.completedFuture(Optional.of(cached)); + boolean hasNextPage = cached.size() > page.getLimit(); + if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { + return CompletableFuture.completedFuture(new PageResult<>(cached, false)); } - return this.parcelRepository.findByReceiver(receiver).thenApply(optional -> { - optional.ifPresent(parcels -> parcels.forEach(this::cache)); - return optional; - }); - } - - @Override - public CompletableFuture> getByReceiver(UUID receiver, Page page) { - return this.parcelRepository.findByReceiver(receiver, page).thenApply(result -> { + return this.parcelRepository.fetchByReceiver(receiver, page).thenApply(result -> { result.items().forEach(this::cache); return result; }); } - @Override - public CompletableFuture>> getAll() { - List cached = List.copyOf(this.parcelsByUuid.asMap().values()); - if (!cached.isEmpty()) { - return CompletableFuture.completedFuture(Optional.of(cached)); - } - - return this.parcelRepository.findAll().thenApply(optional -> { - optional.ifPresent(parcels -> parcels.forEach(this::cache)); - return optional; - }); + private void cacheAll() { + this.parcelRepository.fetchAll().thenAccept(optional -> optional.ifPresent(parcels -> parcels.forEach(this::cache))); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java index aa718aff6..6952245e0 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java @@ -14,15 +14,19 @@ public interface ParcelRepository { CompletableFuture update(Parcel parcel); - CompletableFuture>> findAll(); + CompletableFuture>> fetchAll(); - CompletableFuture> findById(UUID uuid); + CompletableFuture> fetchById(UUID uuid); - CompletableFuture>> findBySender(UUID sender); + @Deprecated + CompletableFuture>> fetchBySender(UUID sender); - CompletableFuture>> findByReceiver(UUID receiver); + CompletableFuture> fetchBySender(UUID sender, Page page); - CompletableFuture> findByReceiver(UUID receiver, Page page); + @Deprecated + CompletableFuture>> fetchByReceiver(UUID receiver); + + CompletableFuture> fetchByReceiver(UUID receiver, Page page); CompletableFuture delete(Parcel parcel); @@ -30,5 +34,5 @@ public interface ParcelRepository { CompletableFuture deleteAll(); - CompletableFuture> findPage(Page page); + CompletableFuture> fetchPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java index f9c703711..f03ab585c 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java @@ -40,12 +40,12 @@ public CompletableFuture update(Parcel parcel) { } @Override - public CompletableFuture> findById(UUID uuid) { + public CompletableFuture> fetchById(UUID uuid) { return this.selectSafe(ParcelTable.class, uuid).thenApply(optional -> optional.map(ParcelTable::toParcel)); } @Override - public CompletableFuture>> findBySender(UUID sender) { + public CompletableFuture>> fetchBySender(UUID sender) { return this.action( ParcelTable.class, dao -> Optional.of(dao.queryForEq(SENDER_COLUMN, sender) .stream() @@ -53,8 +53,12 @@ public CompletableFuture>> findBySender(UUID sender) { .toList())); } + public CompletableFuture> fetchBySender(UUID sender, Page page) { + return this.fetchByPaged(sender, page, SENDER_COLUMN); + } + @Override - public CompletableFuture>> findByReceiver(UUID receiver) { + public CompletableFuture>> fetchByReceiver(UUID receiver) { return this.action( ParcelTable.class, dao -> Optional.of(dao.queryForEq(RECEIVER_COLUMN, receiver) .stream() @@ -62,25 +66,29 @@ public CompletableFuture>> findByReceiver(UUID receiver) { .toList())); } - public CompletableFuture> findByReceiver(UUID receiver, Page page) { - return this.action( - ParcelTable.class, dao -> { - List parcels = dao.queryBuilder() - .limit((long) page.getLimit() + 1) - .offset((long) page.getOffset()) - .where() - .eq(RECEIVER_COLUMN, receiver) - .query() - .stream() - .map(ParcelTable::toParcel) - .toList(); + public CompletableFuture> fetchByReceiver(UUID receiver, Page page) { + return this.fetchByPaged(receiver, page, RECEIVER_COLUMN); + } - boolean hasNext = parcels.size() > page.getLimit(); - if (hasNext) { - parcels.removeLast(); - } - return new PageResult<>(parcels, hasNext); - }); + private CompletableFuture> fetchByPaged(UUID key, Page page, String column) { + return this.action( + ParcelTable.class, dao -> { + List parcels = dao.queryBuilder() + .limit((long) page.getLimit() + 1) + .offset((long) page.getOffset()) + .where() + .eq(column, key) + .query() + .stream() + .map(ParcelTable::toParcel) + .toList(); + + boolean hasNext = parcels.size() > page.getLimit(); + if (hasNext) { + parcels.removeLast(); + } + return new PageResult<>(parcels, hasNext); + }); } @Override @@ -94,7 +102,7 @@ public CompletableFuture delete(UUID uuid) { } @Override - public CompletableFuture> findPage(Page page) { + public CompletableFuture> fetchPage(Page page) { return this.action( ParcelTable.class, dao -> { List parcels = dao.queryBuilder() @@ -113,7 +121,7 @@ public CompletableFuture> findPage(Page page) { } @Override - public CompletableFuture>> findAll() { + public CompletableFuture>> fetchAll() { return this.selectAll(ParcelTable.class).thenApply(parcels -> Optional.of(parcels.stream() .map(ParcelTable::toParcel) .toList())); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index 0c222c076..a6b60f3c3 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -28,7 +28,7 @@ public CompletableFuture> get(UUID uniqueId) { return CompletableFuture.completedFuture(Optional.of(user)); } - return this.userRepository.find(uniqueId); + return this.userRepository.fetch(uniqueId); } @Override @@ -39,7 +39,7 @@ public CompletableFuture> get(String username) { return CompletableFuture.completedFuture(Optional.of(user)); } - return this.userRepository.find(username); + return this.userRepository.fetch(username); } @Override @@ -61,7 +61,7 @@ public void getOrCreate(UUID uuid, String name) { @Override public CompletableFuture> getPage(Page page) { - return this.userRepository.findPage(page); + return this.userRepository.fetchPage(page); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java index 3e04c81ad..4203a6f62 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java @@ -13,9 +13,9 @@ public interface UserRepository { CompletableFuture changeName(UUID uuid, String newName); - CompletableFuture> find(UUID uuid); + CompletableFuture> fetch(UUID uuid); - CompletableFuture> find(String name); + CompletableFuture> fetch(String name); - CompletableFuture> findPage(Page page); + CompletableFuture> fetchPage(Page page); } diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index 45d1f203a..77840f87d 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -27,14 +27,14 @@ public UserRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedule } @Override - public CompletableFuture> find(UUID uuid) { + public CompletableFuture> fetch(UUID uuid) { return this.selectSafe(UserTable.class, uuid).thenApply(optional -> optional .map(UserTable::toUser) ); } @Override - public CompletableFuture> find(String name) { + public CompletableFuture> fetch(String name) { return this.action( UserTable.class, dao -> { UserTable userTable = dao.queryForEq("username", name).stream().findFirst().orElse(null); @@ -59,7 +59,7 @@ public CompletableFuture changeName(UUID uuid, String newName) { } @Override - public CompletableFuture> findPage(Page page) { + public CompletableFuture> fetchPage(Page page) { return this.action( UserTable.class, dao -> { List users = dao.queryBuilder() diff --git a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java index 37dc66a92..6c91e9ce7 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/LockerRepositoryIntegrationTest.java @@ -10,6 +10,7 @@ import com.eternalcode.parcellockers.locker.repository.LockerRepository; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; import com.eternalcode.parcellockers.shared.Page; +import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.shared.Position; import java.io.File; import java.nio.file.Path; @@ -41,7 +42,6 @@ void test() { PluginConfig config = new ConfigService().create(PluginConfig.class, new File(dataFolder, "config.yml")); DatabaseManager databaseManager = new DatabaseManager(config, Logger.getLogger("ParcelLockers"), dataFolder); this.databaseManager = databaseManager; - LockerCache cache = new LockerCache(); LockerRepository parcelLockerRepository = new LockerRepositoryOrmLite(databaseManager, new TestScheduler()); @@ -52,20 +52,20 @@ void test() { parcelLockerRepository.save(new Locker(uuid, description, position)); - Optional parcelLocker = this.await(parcelLockerRepository.find(uuid)); + Optional parcelLocker = this.await(parcelLockerRepository.fetch(uuid)); assertTrue(parcelLocker.isPresent()); assertEquals(uuid, parcelLocker.get().uuid()); - Optional byPosition = this.await(parcelLockerRepository.find(position)); + Optional byPosition = this.await(parcelLockerRepository.fetch(position)); assertTrue(byPosition.isPresent()); assertEquals(uuid, byPosition.get().uuid()); - LockerPageResult pageResult = this.await(parcelLockerRepository.findPage(new Page(0, 28))); - assertEquals(1, pageResult.lockers().size()); - assertEquals(uuid, pageResult.lockers().getFirst().uuid()); + PageResult pageResult = this.await(parcelLockerRepository.fetchPage(new Page(0, 28))); + assertEquals(1, pageResult.items().size()); + assertEquals(uuid, pageResult.items().getFirst().uuid()); this.await(parcelLockerRepository.delete(uuid)); - Optional removed = this.await(parcelLockerRepository.find(uuid)); + Optional removed = this.await(parcelLockerRepository.fetch(uuid)); assertTrue(removed.isEmpty()); } diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index 23aa9d658..0b12f6fcc 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -56,24 +56,24 @@ void test() { parcelRepository.save(new Parcel(uuid, sender, "name", "description", true, receiver, ParcelSize.SMALL, entryLocker, destinationLocker, ParcelStatus.PENDING)); - Optional parcel = this.await(parcelRepository.findById(uuid)); + Optional parcel = this.await(parcelRepository.fetchById(uuid)); assertTrue(parcel.isPresent()); assertEquals(uuid, parcel.get().uuid()); - List byReceiver = this.await(parcelRepository.findByReceiver(receiver)).orElse(Collections.emptyList()); + List byReceiver = this.await(parcelRepository.fetchByReceiver(receiver)).orElse(Collections.emptyList()); assertEquals(1, byReceiver.size()); assertEquals(uuid, byReceiver.getFirst().uuid()); - List bySender = this.await(parcelRepository.findBySender(sender)).orElse(Collections.emptyList()); + List bySender = this.await(parcelRepository.fetchBySender(sender)).orElse(Collections.emptyList()); assertEquals(1, bySender.size()); assertEquals(uuid, bySender.getFirst().uuid()); - PageResult pageResult = this.await(parcelRepository.findPage(new Page(0, 28))); + PageResult pageResult = this.await(parcelRepository.fetchPage(new Page(0, 28))); assertEquals(1, pageResult.items().size()); assertEquals(uuid, pageResult.items().getFirst().uuid()); this.await(parcelRepository.delete(uuid)); - Optional removedParcel = this.await(parcelRepository.findById(uuid)); + Optional removedParcel = this.await(parcelRepository.fetchById(uuid)); assertTrue(removedParcel.isEmpty()); } From 9f079c6423a998c90119e3bb960da2135a4bc8c3 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:30:45 +0200 Subject: [PATCH 25/51] fix gui stuff and immutable list supplying --- build.gradle.kts | 2 +- .../command/debug/DebugCommand.java | 37 ++++++------------- .../implementation/locker/CollectionGui.java | 3 ++ .../implementation/remote/SentParcelsGui.java | 5 ++- .../parcel/ParcelServiceImpl.java | 3 +- .../repository/ParcelRepositoryOrmLite.java | 2 +- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3bf34edfa..324ef4df0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { annotationProcessor("org.projectlombok:lombok:1.18.38") // jetbrains annotations - paperLibrary("org.jetbrains:annotations:26.0.2") + compileOnly("org.jetbrains:annotations:26.0.2") // jackson-bukkit paperLibrary("de.eldoria.jacksonbukkit:paper:1.2.0") diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index ec5cd84e6..39dbc2fcb 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -1,6 +1,5 @@ package com.eternalcode.parcellockers.command.debug; -import com.eternalcode.commons.RandomElementUtil; import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.multification.notice.Notice; import com.eternalcode.parcellockers.content.ParcelContentManager; @@ -22,8 +21,6 @@ import java.util.Random; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.RandomUtils; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -115,36 +112,26 @@ void getRandomItem(@Sender Player player, @Arg int stacks) { @Execute(name = "send") void send(@Sender Player player, @Arg int count) { - Random random = new Random(); for (int i = 0; i < count; i++) { + UUID locker = UUID.randomUUID(); this.parcelService.send( player, new Parcel( UUID.randomUUID(), player.getUniqueId(), - RandomStringUtils.random(12), - "", - RandomUtils.nextBoolean(), + "test", + "test", + false, player.getUniqueId(), - ParcelSize.LARGE, - UUID.randomUUID(), - UUID.randomUUID(), - ParcelStatus.PENDING + ParcelSize.MEDIUM, + locker, + locker, + ParcelStatus.DELIVERED ), - this.generateRandomItems(random.nextInt(1, 20)) - ); - } - } - - private List generateRandomItems(int count) { - List items = new ArrayList<>(); - List itemMaterials = Arrays.stream(Material.values()).filter(Material::isItem).toList(); - Random random = ThreadLocalRandom.current(); - for (int i = 0; i < count; i++) { - Material material = RandomElementUtil.randomElement(itemMaterials).get(); - int randomAmount = Math.min(random.nextInt(64) + 1, material.getMaxStackSize()); - items.add(new ItemStack(material, randomAmount)); + new ArrayList<>(Arrays.asList( + new ItemStack(Material.STONE, 5), + new ItemStack(Material.DIAMOND, 10) + ))); } - return items; } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index ad9e82be2..77a9e240a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -67,6 +67,8 @@ public void show(Player player, Page page) { this.setupNavigation(gui, page, result, player, this.guiSettings); + + //todo fix not opening? maybe too many parcels for (Parcel parcel : result.items()) { if (parcel.status() != ParcelStatus.DELIVERED) { continue; @@ -84,6 +86,7 @@ public void show(Player player, Page page) { InventoryUtil.shiftItems(event.getSlot(), gui, item.type()); gui.update(); })); + } this.scheduler.run(() -> gui.open(player)); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 0ccc63a90..7d9f61f3f 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.gui.implementation.remote; +import com.eternalcode.commons.adventure.AdventureUtil; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; @@ -66,10 +67,10 @@ public void show(Player player, Page page) { List newLore = PlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore(), this.guiManager) .stream() - .map(line -> this.miniMessage.deserialize(line)) + .map(line -> AdventureUtil.resetItalic(this.miniMessage.deserialize(line))) .toList(); item.lore(newLore); - item.name(this.miniMessage.deserialize(parcelItem.name())); + item.name(AdventureUtil.resetItalic(this.miniMessage.deserialize(parcelItem.name().replace("{NAME}", parcel.name())))); gui.addItem(item.asGuiItem()); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 9c42fec35..b49387a5b 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -60,7 +60,7 @@ public ParcelServiceImpl( @Override public void send(Player sender, Parcel parcel, List items) { - this.parcelRepository.save(parcel).handle((v, throwable) -> { + this.parcelRepository.save(parcel).whenComplete((v, throwable) -> { if (throwable != null) { this.noticeService.create() .notice(messages -> messages.parcel.cannotSend) @@ -73,7 +73,6 @@ public void send(Player sender, Parcel parcel, List items) { .notice(messages -> messages.parcel.sent) .player(sender.getUniqueId()) .send(); - return null; }); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java index f03ab585c..2f89fa10e 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepositoryOrmLite.java @@ -81,7 +81,7 @@ private CompletableFuture> fetchByPaged(UUID key, Page page, .query() .stream() .map(ParcelTable::toParcel) - .toList(); + .collect(Collectors.toList()); boolean hasNext = parcels.size() > page.getLimit(); if (hasNext) { From f1e5e6c724bbb825505a8a7035eb64206b4d2cd2 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:37:06 +0200 Subject: [PATCH 26/51] shifting items fix attempt --- .../implementation/locker/CollectionGui.java | 8 ++-- .../parcel/ParcelServiceImpl.java | 2 + .../parcellockers/util/InventoryUtil.java | 42 ++++++++++++++----- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 77a9e240a..806961913 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -9,7 +9,6 @@ import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; -import com.eternalcode.parcellockers.util.InventoryUtil; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; @@ -68,22 +67,25 @@ public void show(Player player, Page page) { this.setupNavigation(gui, page, result, player, this.guiSettings); - //todo fix not opening? maybe too many parcels for (Parcel parcel : result.items()) { if (parcel.status() != ParcelStatus.DELIVERED) { continue; } ConfigItem item = parcelItem.clone(); + System.out.println("Item type: " + item.type()); item.name(item.name().replace("{NAME}", parcel.name())); item.lore(PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager)); item.glow(true); gui.addItem(item.toGuiItem(event -> { + System.out.println("Clicked slot: " + event.getSlot()); + System.out.println("Item type at slot: " + event.getCurrentItem().getType()); this.guiManager.collectParcel(player, parcel); gui.removeItem(event.getSlot()); - InventoryUtil.shiftItems(event.getSlot(), gui, item.type()); + System.out.println("removeItem called"); + // InventoryUtil.shiftItems(event.getSlot(), gui, item.type()); gui.update(); })); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index b49387a5b..5a7614abb 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -5,6 +5,7 @@ import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; +import com.eternalcode.parcellockers.content.ParcelContent; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; import com.eternalcode.parcellockers.notification.NoticeService; @@ -69,6 +70,7 @@ public void send(Player sender, Parcel parcel, List items) { throw new ParcelLockersException("Failed to save parcel", throwable); } + this.parcelContentRepository.save(new ParcelContent(parcel.uuid(), items)); this.noticeService.create() .notice(messages -> messages.parcel.sent) .player(sender.getUniqueId()) diff --git a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java index 265ebe168..fb9960793 100644 --- a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java @@ -1,14 +1,15 @@ package com.eternalcode.parcellockers.util; -import dev.triumphteam.gui.guis.BaseGui; import dev.triumphteam.gui.guis.GuiItem; +import dev.triumphteam.gui.guis.PaginatedGui; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import java.util.Map; -import java.util.stream.Collectors; - public class InventoryUtil { public static int freeSlotsInInventory(Player player) { @@ -21,20 +22,39 @@ public static int freeSlotsInInventory(Player player) { return freeSlots; } - public static void shiftItems(int removedSlot, BaseGui gui, Material typeToShift) { + public static void shiftItems(int removedSlot, PaginatedGui gui, Material typeToShift) { if (removedSlot < 0 || gui == null) { - return; + throw new IllegalArgumentException("Invalid arguments provided for shifting items."); } - Map itemsToShift = gui.getGuiItems().entrySet() + System.out.println("=== DEBUG shiftItems ==="); + System.out.println("Removed slot: " + removedSlot); + System.out.println("Type to shift: " + typeToShift); + System.out.println("Total GUI items: " + gui.getGuiItems().size()); + + // Pobierz wszystkie itemy do przesuniฤ™cia (tylko te po usuniฤ™tym slocie) + List> itemsToShift = gui.getGuiItems().entrySet() .stream() .filter(entry -> entry.getKey() > removedSlot) .filter(entry -> entry.getValue().getItemStack().getType() == typeToShift) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + .sorted(Comparator.comparingInt(Map.Entry::getKey)) // Sortowanie rosnฤ…ce wedล‚ug slotu + .toList(); + + // Jeล›li nie ma itemรณw do przesuniฤ™cia, zakoล„cz + if (itemsToShift.isEmpty()) { + return; + } + + // Usuล„ itemy z ich obecnych pozycji (od koล„ca, ลผeby nie pomieszaฤ‡ indeksรณw) + for (int i = itemsToShift.size() - 1; i >= 0; i--) { + gui.removeItem(itemsToShift.get(i).getKey()); + } - for (Map.Entry entry : itemsToShift.entrySet()) { - GuiItem item = entry.getValue(); - gui.setItem(entry.getKey() - 1, item); + // Przesuล„ itemy w lewo - kaลผdy item trafia do slotu o 1 mniejszego niลผ byล‚ + int targetSlot = removedSlot; + for (Map.Entry entry : itemsToShift) { + gui.setItem(targetSlot, entry.getValue()); + targetSlot++; } } } From 26443e5fedd45498cce6c7f28f7cd7f7b96bd063 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 30 Aug 2025 10:26:31 +0200 Subject: [PATCH 27/51] shifting works but only in a certain order. atomic counter still does not work --- .../gui/PaginatedGuiRefresher.java | 15 +++++- .../implementation/locker/CollectionGui.java | 46 +++++++++++-------- .../parcel/util/PlaceholderUtil.java | 31 ++++++------- .../parcellockers/util/InventoryUtil.java | 6 --- 4 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java b/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java index 7f407d3ec..af0de397c 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java @@ -2,7 +2,6 @@ import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; - import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; @@ -21,6 +20,20 @@ public void addItem(Supplier item) { this.gui.addItem(item.get()); } + public void removeItemAt(int index) { + if (index >= 0 && index < this.items.size()) { + this.items.remove(index); + this.refresh(); + } + } + + + public void removeItem(Supplier itemToRemove) { + if (this.items.remove(itemToRemove)) { + this.refresh(); + } + } + public void refresh() { this.gui.clearPageItems(false); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 806961913..731764b4c 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -5,6 +5,7 @@ import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; +import com.eternalcode.parcellockers.gui.PaginatedGuiRefresher; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; @@ -12,6 +13,8 @@ import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; @@ -64,34 +67,41 @@ public void show(Player player, Page page) { return; } + PaginatedGuiRefresher refresher = new PaginatedGuiRefresher(gui); + this.setupNavigation(gui, page, result, player, this.guiSettings); + AtomicInteger parcelCounter = new AtomicInteger(0); + for (Parcel parcel : result.items()) { if (parcel.status() != ParcelStatus.DELIVERED) { continue; } - - ConfigItem item = parcelItem.clone(); - System.out.println("Item type: " + item.type()); - item.name(item.name().replace("{NAME}", parcel.name())); - item.lore(PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager)); - - item.glow(true); - - gui.addItem(item.toGuiItem(event -> { - System.out.println("Clicked slot: " + event.getSlot()); - System.out.println("Item type at slot: " + event.getCurrentItem().getType()); - this.guiManager.collectParcel(player, parcel); - gui.removeItem(event.getSlot()); - System.out.println("removeItem called"); - // InventoryUtil.shiftItems(event.getSlot(), gui, item.type()); - gui.update(); - })); - + // TODO fix atomicinteger not changing with removals (refresher indexes changes, but counter not) + final int parcelIndex = parcelCounter.getAndIncrement(); + + // Stwรณrz supplier dla tego itemu + Supplier itemSupplier = () -> { + ConfigItem item = parcelItem.clone(); + item.name(item.name().replace("{NAME}", parcel.name())); + item.lore(PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager)); + item.glow(true); + + return item.toGuiItem(event -> { + this.guiManager.collectParcel(player, parcel); + refresher.removeItemAt(parcelIndex); + }); + }; + + refresher.addItem(itemSupplier); + refresher.refresh(); } this.scheduler.run(() -> gui.open(player)); + }).exceptionally(throwable -> { + throwable.printStackTrace(); + return null; }); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index f0366b642..133f3efad 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -2,16 +2,13 @@ import com.eternalcode.multification.shared.Formatter; import com.eternalcode.parcellockers.gui.GuiManager; -import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.user.User; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Blocking; @@ -35,20 +32,22 @@ public static List replaceParcelPlaceholders(Parcel parcel, List .register("{PRIORITY}", parcel.priority() ? "&aYes" : "&cNo") .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-"); - Optional lockerOptional = guiManager.getLocker(parcel.destinationLocker()) - .orTimeout(3, TimeUnit.SECONDS) - .join(); + /*if (parcel.destinationLocker() != null) { + Optional lockerOptional = guiManager.getLocker(parcel.destinationLocker()) + .orTimeout(3, TimeUnit.SECONDS) + .join(); - if (lockerOptional.isPresent()) { - Locker locker = lockerOptional.get(); - formatter.register("{POSITION_X}", locker.position().x()) - .register("{POSITION_Y}", locker.position().y()) - .register("{POSITION_Z}", locker.position().z()); - } else { - formatter.register("{POSITION_X}", "-") - .register("{POSITION_Y}", "-") - .register("{POSITION_Z}", "-"); - } + if (lockerOptional.isPresent()) { + Locker locker = lockerOptional.get(); + formatter.register("{POSITION_X}", locker.position().x()) + .register("{POSITION_Y}", locker.position().y()) + .register("{POSITION_Z}", locker.position().z()); + } else { + formatter.register("{POSITION_X}", "-") + .register("{POSITION_Y}", "-") + .register("{POSITION_Z}", "-"); + } + }*/ List newLore = new ArrayList<>(); diff --git a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java index fb9960793..d04835765 100644 --- a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java @@ -26,12 +26,6 @@ public static void shiftItems(int removedSlot, PaginatedGui gui, Material typeTo if (removedSlot < 0 || gui == null) { throw new IllegalArgumentException("Invalid arguments provided for shifting items."); } - - System.out.println("=== DEBUG shiftItems ==="); - System.out.println("Removed slot: " + removedSlot); - System.out.println("Type to shift: " + typeToShift); - System.out.println("Total GUI items: " + gui.getGuiItems().size()); - // Pobierz wszystkie itemy do przesuniฤ™cia (tylko te po usuniฤ™tym slocie) List> itemsToShift = gui.getGuiItems().entrySet() .stream() From 1a1094fc117b1b37d8a9d0effc318d7b96dd7ac3 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 09:35:03 +0200 Subject: [PATCH 28/51] Fix shifting and refreshing --- .../command/debug/DebugCommand.java | 7 +-- .../gui/PaginatedGuiRefresher.java | 59 +++++++++++++++++-- .../implementation/locker/CollectionGui.java | 17 +++--- .../implementation/locker/ReceiverGui.java | 9 +-- .../gui/implementation/locker/SendingGui.java | 2 +- .../parcel/util/PlaceholderUtil.java | 7 ++- .../parcellockers/util/InventoryUtil.java | 2 + 7 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java index 39dbc2fcb..7383b4efd 100644 --- a/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java @@ -15,7 +15,6 @@ import dev.rollczi.litecommands.annotations.context.Sender; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; @@ -128,10 +127,8 @@ void send(@Sender Player player, @Arg int count) { locker, ParcelStatus.DELIVERED ), - new ArrayList<>(Arrays.asList( - new ItemStack(Material.STONE, 5), - new ItemStack(Material.DIAMOND, 10) - ))); + List.of(new ItemStack(Material.DIRT, 1)) + ); } } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java b/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java index af0de397c..6437f9c7d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java @@ -4,6 +4,8 @@ import dev.triumphteam.gui.guis.PaginatedGui; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.function.Predicate; import java.util.function.Supplier; public class PaginatedGuiRefresher { @@ -20,16 +22,42 @@ public void addItem(Supplier item) { this.gui.addItem(item.get()); } - public void removeItemAt(int index) { - if (index >= 0 && index < this.items.size()) { - this.items.remove(index); + /** + * Deletes item by its slot in the current page (not absolute slot in the inventory) + */ + public void removeItemByPageSlot(int pageSlot) { + Map currentPageItems = this.gui.getCurrentPageItems(); + + if (!currentPageItems.containsKey(pageSlot)) { + return; + } + + List sortedSlots = currentPageItems.keySet().stream() + .sorted() + .toList(); + + int indexInList = sortedSlots.indexOf(pageSlot); + + if (indexInList >= 0 && indexInList < this.items.size()) { + this.items.remove(indexInList); this.refresh(); } } + /** + * Deletes items matching the given predicate + */ + public void removeItem(Predicate predicate) { + this.items.removeIf(supplier -> predicate.test(supplier.get())); + this.refresh(); + } - public void removeItem(Supplier itemToRemove) { - if (this.items.remove(itemToRemove)) { + /** + * Deletes item at specific index in the items list + */ + public void removeItemAt(int index) { + if (index >= 0 && index < this.items.size()) { + this.items.remove(index); this.refresh(); } } @@ -37,6 +65,7 @@ public void removeItem(Supplier itemToRemove) { public void refresh() { this.gui.clearPageItems(false); + // Dodaj wszystkie itemy z powrotem for (Supplier item : this.items) { this.gui.addItem(item.get()); } @@ -44,4 +73,22 @@ public void refresh() { this.gui.update(); } -} + /** + * Debug: Pokaลผ informacje o slotach + */ + public void debugSlots() { + System.out.println("=== DEBUG SLOTS ==="); + System.out.println("Static items (setItem): " + this.gui.getGuiItems().keySet()); + System.out.println("Current page items (addItem): " + this.gui.getCurrentPageItems().keySet()); + System.out.println("Items list size: " + this.items.size()); + System.out.println("=================="); + } + + public int size() { + return this.items.size(); + } + + public boolean isEmpty() { + return this.items.isEmpty(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 731764b4c..0c66dcf44 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -13,7 +13,6 @@ import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -71,17 +70,11 @@ public void show(Player player, Page page) { this.setupNavigation(gui, page, result, player, this.guiSettings); - - AtomicInteger parcelCounter = new AtomicInteger(0); - for (Parcel parcel : result.items()) { if (parcel.status() != ParcelStatus.DELIVERED) { continue; } - // TODO fix atomicinteger not changing with removals (refresher indexes changes, but counter not) - final int parcelIndex = parcelCounter.getAndIncrement(); - // Stwรณrz supplier dla tego itemu Supplier itemSupplier = () -> { ConfigItem item = parcelItem.clone(); item.name(item.name().replace("{NAME}", parcel.name())); @@ -90,12 +83,18 @@ public void show(Player player, Page page) { return item.toGuiItem(event -> { this.guiManager.collectParcel(player, parcel); - refresher.removeItemAt(parcelIndex); + + // Debug - zobacz ktรณre sloty sฤ… uลผywane + System.out.println("BEFORE removal:"); + refresher.debugSlots(); + // Usuล„ item uลผywajฤ…c slotu z PAGE ITEMS + refresher.removeItemByPageSlot(event.getSlot()); + System.out.println("AFTER removal:"); + refresher.debugSlots(); }); }; refresher.addItem(itemSupplier); - refresher.refresh(); } this.scheduler.run(() -> gui.open(player)); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index 71cb031c4..f40441d53 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -1,5 +1,6 @@ package com.eternalcode.parcellockers.gui.implementation.locker; +import com.eternalcode.commons.adventure.AdventureUtil; import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.gui.GuiManager; @@ -110,13 +111,13 @@ private Supplier toItem(Player player, User user, SkullData skullData, return PaperItemBuilder.skull() .texture(skullData.getTexture()) .name(this.miniMessage.deserialize(user.name())) - .lore(this.miniMessage.deserialize(lore)) - .glow(uuid.equals(this.state.receiver())) + .lore(AdventureUtil.resetItalic(this.miniMessage.deserialize(lore))) + .glow(isReceiverSelected) .asGuiItem(event -> { - if (uuid.equals(this.state.receiver())) { - refresher.refresh(); + if (isReceiverSelected) { this.sendingGUI.updateReceiverItem(player, "", false); this.state.receiver(null); + refresher.refresh(); return; } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 30d2bef0e..22d3ddc8a 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -352,7 +352,7 @@ public void updateReceiverItem(Player player, String receiverName, boolean sendN } if (receiverName == null || receiverName.isEmpty()) { - this.gui.updateItem(RECEIVER_ITEM_SLOT, this.guiSettings.parcelReceiverItem.toItemStack()); + this.gui.updateItem(RECEIVER_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelReceiverItem, this.guiSettings.parcelReceiverNotSetLine)); return; } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index 133f3efad..6d1a3b858 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -2,13 +2,16 @@ import com.eternalcode.multification.shared.Formatter; import com.eternalcode.parcellockers.gui.GuiManager; +import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.user.User; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Blocking; @@ -32,7 +35,7 @@ public static List replaceParcelPlaceholders(Parcel parcel, List .register("{PRIORITY}", parcel.priority() ? "&aYes" : "&cNo") .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-"); - /*if (parcel.destinationLocker() != null) { + if (parcel.destinationLocker() != null) { Optional lockerOptional = guiManager.getLocker(parcel.destinationLocker()) .orTimeout(3, TimeUnit.SECONDS) .join(); @@ -47,7 +50,7 @@ public static List replaceParcelPlaceholders(Parcel parcel, List .register("{POSITION_Y}", "-") .register("{POSITION_Z}", "-"); } - }*/ + } List newLore = new ArrayList<>(); diff --git a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java index d04835765..8cb337620 100644 --- a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java @@ -9,6 +9,7 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus.Obsolete; public class InventoryUtil { @@ -22,6 +23,7 @@ public static int freeSlotsInInventory(Player player) { return freeSlots; } + @Obsolete public static void shiftItems(int removedSlot, PaginatedGui gui, Material typeToShift) { if (removedSlot < 0 || gui == null) { throw new IllegalArgumentException("Invalid arguments provided for shifting items."); From 673b815a6f65381e99d173334445da0be271bd79 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 09:59:19 +0200 Subject: [PATCH 29/51] Simplify PlaceholderUtil and CollectionGui through CompletableFutures --- .../implementation/locker/CollectionGui.java | 61 ++++---- .../parcel/util/PlaceholderUtil.java | 137 +++++++++++++----- 2 files changed, 129 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 0c66dcf44..04d2c7e79 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -10,9 +10,11 @@ import com.eternalcode.parcellockers.parcel.ParcelStatus; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; +import com.spotify.futures.CompletableFutures; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -70,38 +72,18 @@ public void show(Player player, Page page) { this.setupNavigation(gui, page, result, player, this.guiSettings); - for (Parcel parcel : result.items()) { - if (parcel.status() != ParcelStatus.DELIVERED) { - continue; - } - - Supplier itemSupplier = () -> { - ConfigItem item = parcelItem.clone(); - item.name(item.name().replace("{NAME}", parcel.name())); - item.lore(PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager)); - item.glow(true); - - return item.toGuiItem(event -> { - this.guiManager.collectParcel(player, parcel); - - // Debug - zobacz ktรณre sloty sฤ… uลผywane - System.out.println("BEFORE removal:"); - refresher.debugSlots(); - // Usuล„ item uลผywajฤ…c slotu z PAGE ITEMS - refresher.removeItemByPageSlot(event.getSlot()); - System.out.println("AFTER removal:"); - refresher.debugSlots(); - }); - }; - - refresher.addItem(itemSupplier); - } - - this.scheduler.run(() -> gui.open(player)); - }).exceptionally(throwable -> { - throwable.printStackTrace(); - return null; + result.items().stream() + .filter(parcel -> parcel.status() == ParcelStatus.DELIVERED) + .map(parcel -> this.createParcelItemAsync(parcel, parcelItem, player, refresher)) + .collect(CompletableFutures.joinList()) // ๐ŸŽฏ Spotify magic! + .thenAccept(suppliers -> { + for (Supplier supplier : suppliers) { + refresher.addItem(supplier); + } + this.scheduler.run(() -> gui.open(player)); + }); }); + } private void setupStaticItems(Player player, PaginatedGui gui) { @@ -119,4 +101,21 @@ private void setupStaticItems(Player player, PaginatedGui gui) { gui.setItem(49, closeItem); } + + private CompletableFuture> createParcelItemAsync( + Parcel parcel, ConfigItem parcelItem, Player player, PaginatedGuiRefresher refresher) { + + return PlaceholderUtil.replaceParcelPlaceholdersAsync(parcel, parcelItem.lore(), this.guiManager) + .thenApply(processedLore -> () -> { + ConfigItem item = parcelItem.clone(); + item.name(item.name().replace("{NAME}", parcel.name())); + item.lore(processedLore); + item.glow(true); + + return item.toGuiItem(event -> { + this.guiManager.collectParcel(player, parcel); + refresher.removeItemByPageSlot(event.getSlot()); + }); + }); + } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index 6d1a3b858..f24f82066 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -5,6 +5,7 @@ import com.eternalcode.parcellockers.locker.Locker; import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.user.User; +import com.spotify.futures.CompletableFutures; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -17,54 +18,114 @@ public class PlaceholderUtil { - @Blocking - public static List replaceParcelPlaceholders(Parcel parcel, List lore, GuiManager guiManager) { + public static CompletableFuture> replaceParcelPlaceholdersAsync( + Parcel parcel, + List lore, + GuiManager guiManager + ) { + if (lore == null || lore.isEmpty()) { - return Collections.emptyList(); + return CompletableFuture.completedFuture(Collections.emptyList()); + } + + CompletableFuture senderNameFuture = getName(parcel.sender(), guiManager); + CompletableFuture receiverNameFuture = getName(parcel.receiver(), guiManager); + CompletableFuture> lockerFuture = getLockerInfo(parcel.destinationLocker(), guiManager); + + return CompletableFutures.combine( + senderNameFuture, receiverNameFuture, lockerFuture, + (senderName, receiverName, lockerOptional) -> { + + Formatter formatter = new Formatter() + .register("{UUID}", parcel.uuid().toString()) + .register("{NAME}", parcel.name()) + .register("{SENDER}", senderName) + .register("{RECEIVER}", receiverName) + .register("{SIZE}", StringUtils.capitalize(parcel.size().toString().toLowerCase())) + .register("{PRIORITY}", parcel.priority() ? "&aYes" : "&cNo") + .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-"); + + if (lockerOptional.isPresent()) { + Locker locker = lockerOptional.get(); + formatter.register("{POSITION_X}", String.valueOf(locker.position().x())) + .register("{POSITION_Y}", String.valueOf(locker.position().y())) + .register("{POSITION_Z}", String.valueOf(locker.position().z())); + } else { + formatter.register("{POSITION_X}", "-") + .register("{POSITION_Y}", "-") + .register("{POSITION_Z}", "-"); + } + + List newLore = new ArrayList<>(); + for (String line : lore) { + newLore.add(formatter.format(line)); + } + + return newLore; + }) + .toCompletableFuture() + .orTimeout(5, TimeUnit.SECONDS) + .exceptionally(throwable -> { + throwable.printStackTrace(); + return createFallbackLore(parcel, lore); + }); + } + + private static CompletableFuture getName(UUID userUuid, GuiManager guiManager) { + return guiManager.getUser(userUuid) + .orTimeout(3, TimeUnit.SECONDS) + .thenApply(userOptional -> userOptional + .map(User::name) + .orElse("Unknown")) + .exceptionally(throwable -> { + System.err.println("Failed to get user name for " + userUuid + ": " + throwable.getMessage()); + return "Unknown"; + }); + } + + private static CompletableFuture> getLockerInfo(UUID lockerId, GuiManager guiManager) { + if (lockerId == null) { + return CompletableFuture.completedFuture(Optional.empty()); } - String senderName = getName(parcel.sender(), guiManager).join(); - String receiver = getName(parcel.receiver(), guiManager).join(); + return guiManager.getLocker(lockerId) + .orTimeout(3, TimeUnit.SECONDS) + .exceptionally(throwable -> { + System.err.println("Failed to get locker info for " + lockerId + ": " + throwable.getMessage()); + return Optional.empty(); + }); + } - Formatter formatter = new Formatter() + private static List createFallbackLore(Parcel parcel, List originalLore) { + // Podstawowe placeholdery bez asynchronicznych wywoล‚aล„ + Formatter fallbackFormatter = new Formatter() .register("{UUID}", parcel.uuid().toString()) .register("{NAME}", parcel.name()) - .register("{SENDER}", senderName) - .register("{RECEIVER}", receiver) + .register("{SENDER}", "Loading...") + .register("{RECEIVER}", "Loading...") .register("{SIZE}", StringUtils.capitalize(parcel.size().toString().toLowerCase())) .register("{PRIORITY}", parcel.priority() ? "&aYes" : "&cNo") - .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-"); - - if (parcel.destinationLocker() != null) { - Optional lockerOptional = guiManager.getLocker(parcel.destinationLocker()) - .orTimeout(3, TimeUnit.SECONDS) - .join(); - - if (lockerOptional.isPresent()) { - Locker locker = lockerOptional.get(); - formatter.register("{POSITION_X}", locker.position().x()) - .register("{POSITION_Y}", locker.position().y()) - .register("{POSITION_Z}", locker.position().z()); - } else { - formatter.register("{POSITION_X}", "-") - .register("{POSITION_Y}", "-") - .register("{POSITION_Z}", "-"); - } - } - - List newLore = new ArrayList<>(); - - for (String line : lore) { - newLore.add(formatter.format(line)); - } + .register("{DESCRIPTION}", parcel.description() != null ? parcel.description() : "-") + .register("{POSITION_X}", "-") + .register("{POSITION_Y}", "-") + .register("{POSITION_Z}", "-"); - return newLore; + return originalLore.stream() + .map(fallbackFormatter::format) + .toList(); } - private static CompletableFuture getName(UUID userUuid, GuiManager guiManager) { - return guiManager.getUser(userUuid).thenApply(userOptional -> userOptional - .map(User::name) - .orElse("Unknown") - ); + // Zachowaj starฤ… metodฤ™ dla kompatybilnoล›ci wstecznej, ale z lepszym error handlingiem + @Blocking + @Deprecated + public static List replaceParcelPlaceholders(Parcel parcel, List lore, GuiManager guiManager) { + try { + return replaceParcelPlaceholdersAsync(parcel, lore, guiManager).join(); + } catch (Exception e) { + System.err.println("Timeout or error in replaceParcelPlaceholders: " + e.getMessage()); + return createFallbackLore(parcel, lore); + } } } + + From d2289a172fe6c066de267df89100e88656b25c78 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:25:16 +0200 Subject: [PATCH 30/51] Use CompletableFutures from spotify where applicable, clarify some comments --- .../ParcelLockersLibraryLoader.java | 3 +- .../gui/PaginatedGuiRefresher.java | 43 +--------------- .../implementation/locker/CollectionGui.java | 3 +- .../implementation/locker/ItemStorageGui.java | 1 - .../gui/implementation/locker/SendingGui.java | 3 +- .../implementation/remote/ParcelListGui.java | 50 ++++++++++++------- .../implementation/remote/SentParcelsGui.java | 49 +++++++++++++----- .../parcel/util/PlaceholderUtil.java | 2 - 8 files changed, 74 insertions(+), 80 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java index 4cf77f211..a8dfff5bc 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java @@ -5,6 +5,7 @@ import io.papermc.paper.plugin.loader.PluginLoader; import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.List; @@ -26,7 +27,7 @@ public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) { } public PluginLibraries load() { - try (var in = this.getClass().getResourceAsStream("/paper-libraries.json")) { + try (InputStream in = this.getClass().getResourceAsStream("/paper-libraries.json")) { return new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), PluginLibraries.class); } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java b/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java index 6437f9c7d..a160ad2b5 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/PaginatedGuiRefresher.java @@ -5,7 +5,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.function.Predicate; import java.util.function.Supplier; public class PaginatedGuiRefresher { @@ -23,9 +22,9 @@ public void addItem(Supplier item) { } /** - * Deletes item by its slot in the current page (not absolute slot in the inventory) + * Deletes item by its absolute slot in the inventory */ - public void removeItemByPageSlot(int pageSlot) { + public void removeItemBySlot(int pageSlot) { Map currentPageItems = this.gui.getCurrentPageItems(); if (!currentPageItems.containsKey(pageSlot)) { @@ -44,51 +43,13 @@ public void removeItemByPageSlot(int pageSlot) { } } - /** - * Deletes items matching the given predicate - */ - public void removeItem(Predicate predicate) { - this.items.removeIf(supplier -> predicate.test(supplier.get())); - this.refresh(); - } - - /** - * Deletes item at specific index in the items list - */ - public void removeItemAt(int index) { - if (index >= 0 && index < this.items.size()) { - this.items.remove(index); - this.refresh(); - } - } - public void refresh() { this.gui.clearPageItems(false); - // Dodaj wszystkie itemy z powrotem for (Supplier item : this.items) { this.gui.addItem(item.get()); } this.gui.update(); } - - /** - * Debug: Pokaลผ informacje o slotach - */ - public void debugSlots() { - System.out.println("=== DEBUG SLOTS ==="); - System.out.println("Static items (setItem): " + this.gui.getGuiItems().keySet()); - System.out.println("Current page items (addItem): " + this.gui.getCurrentPageItems().keySet()); - System.out.println("Items list size: " + this.items.size()); - System.out.println("=================="); - } - - public int size() { - return this.items.size(); - } - - public boolean isEmpty() { - return this.items.isEmpty(); - } } \ No newline at end of file diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 04d2c7e79..168122c81 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -83,7 +83,6 @@ public void show(Player player, Page page) { this.scheduler.run(() -> gui.open(player)); }); }); - } private void setupStaticItems(Player player, PaginatedGui gui) { @@ -114,7 +113,7 @@ private CompletableFuture> createParcelItemAsync( return item.toGuiItem(event -> { this.guiManager.collectParcel(player, parcel); - refresher.removeItemByPageSlot(event.getSlot()); + refresher.removeItemBySlot(event.getSlot()); }); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index 332bdcce8..e613817bd 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -112,7 +112,6 @@ void show(Player player, ParcelSize size) { } } items.add(item); - } this.guiManager.deleteItemStorage(player.getUniqueId()); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 22d3ddc8a..11adb50ca 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -27,7 +27,6 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; public class SendingGui implements GuiView { @@ -384,7 +383,7 @@ public void updateDestinationItem(Player player, String destinationLockerDesc, b this.gui.updateItem(DESTINATION_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelDestinationLockerItem, line)); } - private @NotNull ItemStack createActiveItem(ConfigItem item, String appendLore) { + private ItemStack createActiveItem(ConfigItem item, String appendLore) { List itemLore = new ArrayList<>(item.lore()); itemLore.add(appendLore); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 7507b4aa7..21cf9d4a2 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -7,14 +7,15 @@ import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; import com.eternalcode.parcellockers.gui.GuiManager; import com.eternalcode.parcellockers.gui.GuiView; -import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; +import com.spotify.futures.CompletableFutures; import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; import java.util.List; +import java.util.concurrent.CompletableFuture; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; @@ -65,24 +66,37 @@ public void show(Player player, Page page) { return; } - for (Parcel parcel : result.items()) { - ConfigItem item = this.guiSettings.parcelItem; - PaperItemBuilder parcelItem = item.toBuilder(); - - List newLore = PlaceholderUtil.replaceParcelPlaceholders(parcel, item.lore(), this.guiManager).stream() - .map(line -> resetItalic(this.miniMessage.deserialize(line))) - .toList(); - parcelItem.lore(newLore); - parcelItem.name(this.miniMessage.deserialize(item.name().replace("{NAME}", parcel.name()))); - - gui.addItem(parcelItem.asGuiItem()); - } - - this.setupNavigation(gui, page, result, player, this.guiSettings); - - this.scheduler.run(() -> gui.open(player)); + ConfigItem item = this.guiSettings.parcelItem; + + List> itemFutures = result.items().stream() + .map(parcel -> PlaceholderUtil.replaceParcelPlaceholdersAsync(parcel, item.lore(), this.guiManager) + .thenApply(processedLore -> { + PaperItemBuilder parcelItem = item.toBuilder(); + + List newLore = processedLore.stream() + .map(line -> resetItalic(this.miniMessage.deserialize(line))) + .toList(); + + parcelItem.lore(newLore); + parcelItem.name(this.miniMessage.deserialize(item.name().replace("{NAME}", parcel.name()))); + + return parcelItem.asGuiItem(); + })) + .toList(); + + CompletableFutures.allAsList(itemFutures) + .thenAccept(guiItems -> { + guiItems.forEach(gui::addItem); + this.setupNavigation(gui, page, result, player, this.guiSettings); + this.scheduler.run(() -> gui.open(player)); + }) + .exceptionally(throwable -> { + System.err.println("Failed to process parcel items: " + throwable.getMessage()); + this.setupNavigation(gui, page, result, player, this.guiSettings); + this.scheduler.run(() -> gui.open(player)); + return null; + }); }); - } private void setupStaticItems(Player player, PaginatedGui gui) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 7d9f61f3f..632347159 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -9,11 +9,13 @@ import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.util.PlaceholderUtil; import com.eternalcode.parcellockers.shared.Page; +import com.spotify.futures.CompletableFutures; import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.PaginatedGui; import java.util.List; +import java.util.concurrent.CompletableFuture; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.entity.Player; @@ -62,19 +64,40 @@ public void show(Player player, Page page) { this.guiManager.getParcelsBySender(player.getUniqueId(), page).thenAccept(result -> { List parcels = result.items(); - for (Parcel parcel : parcels) { - PaperItemBuilder item = parcelItem.toBuilder(); - - List newLore = PlaceholderUtil.replaceParcelPlaceholders(parcel, parcelItem.lore(), this.guiManager) - .stream() - .map(line -> AdventureUtil.resetItalic(this.miniMessage.deserialize(line))) - .toList(); - item.lore(newLore); - item.name(AdventureUtil.resetItalic(this.miniMessage.deserialize(parcelItem.name().replace("{NAME}", parcel.name())))); - - gui.addItem(item.asGuiItem()); - } - this.scheduler.run(() -> gui.open(player)); + List> itemFutures = parcels.stream() + .map(parcel -> PlaceholderUtil.replaceParcelPlaceholdersAsync( + parcel, + parcelItem.lore(), + this.guiManager) + .thenApply(processedLore -> { + PaperItemBuilder item = parcelItem.toBuilder(); + + List newLore = processedLore + .stream() + .map(line -> AdventureUtil.resetItalic(this.miniMessage.deserialize(line))) + .toList(); + + item.lore(newLore); + item.name(AdventureUtil.resetItalic( + this.miniMessage.deserialize( + parcelItem.name().replace("{NAME}", parcel.name()) + ) + )); + + return item.asGuiItem(); + })) + .toList(); + + CompletableFutures.allAsList(itemFutures) + .thenAccept(guiItems -> { + guiItems.forEach(gui::addItem); + this.scheduler.run(() -> gui.open(player)); + }) + .exceptionally(throwable -> { + System.err.println("Failed to process parcel items: " + throwable.getMessage()); + this.scheduler.run(() -> gui.open(player)); + return null; + }); }); } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index f24f82066..476bd583b 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -97,7 +97,6 @@ private static CompletableFuture> getLockerInfo(UUID lockerId, } private static List createFallbackLore(Parcel parcel, List originalLore) { - // Podstawowe placeholdery bez asynchronicznych wywoล‚aล„ Formatter fallbackFormatter = new Formatter() .register("{UUID}", parcel.uuid().toString()) .register("{NAME}", parcel.name()) @@ -115,7 +114,6 @@ private static List createFallbackLore(Parcel parcel, List origi .toList(); } - // Zachowaj starฤ… metodฤ™ dla kompatybilnoล›ci wstecznej, ale z lepszym error handlingiem @Blocking @Deprecated public static List replaceParcelPlaceholders(Parcel parcel, List lore, GuiManager guiManager) { From 3aee0e0001322e3f349cd918ab7d4d85b83e7ba5 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:28:34 +0200 Subject: [PATCH 31/51] Simplify .gitignore and .gitattributes --- .gitattributes | 2 +- .gitignore | 45 +++++++++------------------------------------ 2 files changed, 10 insertions(+), 37 deletions(-) diff --git a/.gitattributes b/.gitattributes index f133f07bd..29bde31dd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,7 @@ * text=auto + *.sh text eol=lf gradlew text eol=lf *.bat text eol=crlf -*.java text eol=lf *.jar binary \ No newline at end of file diff --git a/.gitignore b/.gitignore index 61404e1e7..c11db7447 100644 --- a/.gitignore +++ b/.gitignore @@ -1,41 +1,14 @@ -.idea/ *.iml *.ipr *.iws +.idea/ +.gradle/ +.kotlin/ +run/ out/ -*.class -*.log -*.ctxt -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar -hs_err_pid* -*~ -.fuse_hidden* -.directory -.Trash-* -.nfs* -.DS_Store -.AppleDouble -.LSOverride -Icon -._* -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent -*.stackdump -.gradle build/ -gradle-app.setting -.gradletasknamecache -**/build/ -run/ -!gradle-wrapper.jar + +.DS_Store +[Dd]esktop.ini + +!gradle/wrapper/gradle-wrapper.jar From 68aa4e1aa62e93d734476a01130c04eb29b13fb8 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:42:59 +0200 Subject: [PATCH 32/51] change annotations, use expiring cache --- .../parcellockers/ParcelLockers.java | 2 -- .../delivery/DeliveryManager.java | 2 +- .../parcel/ParcelServiceImpl.java | 10 ++----- .../parcel/repository/ParcelRepository.java | 5 ++-- .../parcellockers/user/UserManagerImpl.java | 26 ++++++++++++------- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index a92532d55..c6a6a59a5 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -108,10 +108,8 @@ public void onEnable() { // service and managers ParcelService parcelService = new ParcelServiceImpl( - config, noticeService, parcelRepository, - deliveryRepository, parcelContentRepository, scheduler ); diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java index 518bfb8eb..93d2a5b5c 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java @@ -12,8 +12,8 @@ public class DeliveryManager { private final DeliveryRepository deliveryRepository; private final Cache deliveryCache = Caffeine.newBuilder() + .expireAfterWrite(Duration.ofHours(6)) .maximumSize(10_000) - .expireAfterAccess(Duration.ofHours(6)) .build(); public DeliveryManager(DeliveryRepository deliveryRepository) { diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 5a7614abb..e45b497d1 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -4,10 +4,8 @@ import com.eternalcode.commons.bukkit.ItemUtil; import com.eternalcode.commons.scheduler.Scheduler; -import com.eternalcode.parcellockers.configuration.implementation.PluginConfig; import com.eternalcode.parcellockers.content.ParcelContent; import com.eternalcode.parcellockers.content.repository.ParcelContentRepository; -import com.eternalcode.parcellockers.delivery.repository.DeliveryRepository; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.repository.ParcelRepository; import com.eternalcode.parcellockers.shared.Page; @@ -21,20 +19,20 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; public class ParcelServiceImpl implements ParcelService { - private final PluginConfig config; private final NoticeService noticeService; private final ParcelRepository parcelRepository; - private final DeliveryRepository deliveryRepository; private final ParcelContentRepository parcelContentRepository; private final Scheduler scheduler; private final Cache parcelsByUuid = Caffeine.newBuilder() + .expireAfterAccess(3, TimeUnit.HOURS) .maximumSize(10_000) .build(); @@ -42,17 +40,13 @@ public class ParcelServiceImpl implements ParcelService { private final Multimap parcelsByReceiver = HashMultimap.create(); public ParcelServiceImpl( - PluginConfig config, NoticeService noticeService, ParcelRepository parcelRepository, - DeliveryRepository deliveryRepository, ParcelContentRepository parcelContentRepository, Scheduler scheduler ) { - this.config = config; this.noticeService = noticeService; this.parcelRepository = parcelRepository; - this.deliveryRepository = deliveryRepository; this.parcelContentRepository = parcelContentRepository; this.scheduler = scheduler; diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java index 6952245e0..b2813733c 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/repository/ParcelRepository.java @@ -7,6 +7,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import org.jetbrains.annotations.TestOnly; public interface ParcelRepository { @@ -18,12 +19,12 @@ public interface ParcelRepository { CompletableFuture> fetchById(UUID uuid); - @Deprecated + @TestOnly CompletableFuture>> fetchBySender(UUID sender); CompletableFuture> fetchBySender(UUID sender, Page page); - @Deprecated + @TestOnly CompletableFuture>> fetchByReceiver(UUID receiver); CompletableFuture> fetchByReceiver(UUID receiver, Page page); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index a6b60f3c3..b82a170cd 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -3,18 +3,26 @@ import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.user.repository.UserRepository; -import java.util.HashMap; -import java.util.Map; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; public class UserManagerImpl implements UserManager { private final UserRepository userRepository; - private final Map usersByUUID = new HashMap<>(); - private final Map usersByName = new HashMap<>(); + private final Cache usersByUUID = Caffeine.newBuilder() + .expireAfterAccess(2, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); + + private final Cache usersByName = Caffeine.newBuilder() + .expireAfterAccess(2, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); public UserManagerImpl(UserRepository userRepository) { this.userRepository = userRepository; @@ -22,7 +30,7 @@ public UserManagerImpl(UserRepository userRepository) { @Override public CompletableFuture> get(UUID uniqueId) { - User user = this.usersByUUID.get(uniqueId); + User user = this.usersByUUID.getIfPresent(uniqueId); if (user != null) { return CompletableFuture.completedFuture(Optional.of(user)); @@ -33,7 +41,7 @@ public CompletableFuture> get(UUID uniqueId) { @Override public CompletableFuture> get(String username) { - User user = this.usersByName.get(username); + User user = this.usersByName.getIfPresent(username); if (user != null) { return CompletableFuture.completedFuture(Optional.of(user)); @@ -44,13 +52,13 @@ public CompletableFuture> get(String username) { @Override public void getOrCreate(UUID uuid, String name) { - User userByUUID = this.usersByUUID.get(uuid); + User userByUUID = this.usersByUUID.getIfPresent(uuid); if (userByUUID != null) { return; } - User userByName = this.usersByName.get(name); + User userByName = this.usersByName.getIfPresent(name); if (userByName != null) { return; @@ -66,7 +74,7 @@ public CompletableFuture> getPage(Page page) { @Override public User create(UUID uuid, String name) { - if (this.usersByUUID.containsKey(uuid) || this.usersByName.containsKey(name)) { + if (this.usersByUUID.getIfPresent(uuid) != null || this.usersByName.getIfPresent(name) != null) { throw new IllegalStateException("User already exists"); } From a077a3981fc61d3c9a2a997e6851d0a71777b7ef Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:45:47 +0200 Subject: [PATCH 33/51] remove unused InventoryUtil#shiftItems method --- .../parcellockers/util/InventoryUtil.java | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java index 8cb337620..3026473fd 100644 --- a/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java @@ -1,15 +1,7 @@ package com.eternalcode.parcellockers.util; -import dev.triumphteam.gui.guis.GuiItem; -import dev.triumphteam.gui.guis.PaginatedGui; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.ApiStatus.Obsolete; public class InventoryUtil { @@ -22,35 +14,4 @@ public static int freeSlotsInInventory(Player player) { } return freeSlots; } - - @Obsolete - public static void shiftItems(int removedSlot, PaginatedGui gui, Material typeToShift) { - if (removedSlot < 0 || gui == null) { - throw new IllegalArgumentException("Invalid arguments provided for shifting items."); - } - // Pobierz wszystkie itemy do przesuniฤ™cia (tylko te po usuniฤ™tym slocie) - List> itemsToShift = gui.getGuiItems().entrySet() - .stream() - .filter(entry -> entry.getKey() > removedSlot) - .filter(entry -> entry.getValue().getItemStack().getType() == typeToShift) - .sorted(Comparator.comparingInt(Map.Entry::getKey)) // Sortowanie rosnฤ…ce wedล‚ug slotu - .toList(); - - // Jeล›li nie ma itemรณw do przesuniฤ™cia, zakoล„cz - if (itemsToShift.isEmpty()) { - return; - } - - // Usuล„ itemy z ich obecnych pozycji (od koล„ca, ลผeby nie pomieszaฤ‡ indeksรณw) - for (int i = itemsToShift.size() - 1; i >= 0; i--) { - gui.removeItem(itemsToShift.get(i).getKey()); - } - - // Przesuล„ itemy w lewo - kaลผdy item trafia do slotu o 1 mniejszego niลผ byล‚ - int targetSlot = removedSlot; - for (Map.Entry entry : itemsToShift) { - gui.setItem(targetSlot, entry.getValue()); - targetSlot++; - } - } } From c65e8957887a803a343360a917864d3460d61045 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:46:31 +0200 Subject: [PATCH 34/51] delete unnecessary comment --- .../java/com/eternalcode/parcellockers/shared/Position.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eternalcode/parcellockers/shared/Position.java b/src/main/java/com/eternalcode/parcellockers/shared/Position.java index 941384980..6a43f3b56 100644 --- a/src/main/java/com/eternalcode/parcellockers/shared/Position.java +++ b/src/main/java/com/eternalcode/parcellockers/shared/Position.java @@ -82,7 +82,7 @@ public String toString() { "x=" + this.x + ", y=" + this.y + ", z=" + this.z + - ", world=\"" + this.world + "\"" + // Uลผywaj podwรณjnych cudzysล‚owรณw + ", world=\"" + this.world + "\"" + '}'; } } From 99d231e38a88b8a2091fd8f8e15a525bc6accb42 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:08:29 +0200 Subject: [PATCH 35/51] better empty PageResult handling --- .../com/eternalcode/parcellockers/shared/PageResult.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java b/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java index f8486f0ad..978cd902d 100644 --- a/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java +++ b/src/main/java/com/eternalcode/parcellockers/shared/PageResult.java @@ -4,7 +4,10 @@ public record PageResult(List items, boolean hasNextPage) { - public static PageResult empty() { - return new PageResult<>(List.of(), false); + private static final PageResult EMPTY = new PageResult<>(List.of(), false); + + @SuppressWarnings("unchecked") + public static PageResult empty() { + return (PageResult) EMPTY; } } From cb91929226b7fd2318d3ce72fa67b80c8ff052a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20K=C4=99dziora?= <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:15:12 +0200 Subject: [PATCH 36/51] Update src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../parcellockers/parcel/util/PlaceholderUtil.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java index 476bd583b..802df830a 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/util/PlaceholderUtil.java @@ -114,16 +114,6 @@ private static List createFallbackLore(Parcel parcel, List origi .toList(); } - @Blocking - @Deprecated - public static List replaceParcelPlaceholders(Parcel parcel, List lore, GuiManager guiManager) { - try { - return replaceParcelPlaceholdersAsync(parcel, lore, guiManager).join(); - } catch (Exception e) { - System.err.println("Timeout or error in replaceParcelPlaceholders: " + e.getMessage()); - return createFallbackLore(parcel, lore); - } - } } From 8616000e6f8cccefe93a565f6085f5e7178feff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20K=C4=99dziora?= <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:15:20 +0200 Subject: [PATCH 37/51] Update src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../user/repository/UserRepositoryOrmLite.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index 77840f87d..88e81e3ef 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -43,8 +43,12 @@ public CompletableFuture> fetch(String name) { } @Override - public void save(User user) { - this.save(UserTable.class, UserTable.from(user)).thenApply(dao -> null); + this.save(UserTable.class, UserTable.from(user)) + .exceptionally(ex -> { + System.err.println("Failed to save user: " + ex.getMessage()); + ex.printStackTrace(); + return null; + }); } @Override From ad4c92560b232965dceb0dbf860cf0044f98c2d9 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:17:37 +0200 Subject: [PATCH 38/51] Fix potential CME --- .../gui/implementation/locker/SendingGui.java | 8 ++-- .../controller/LockerBreakController.java | 39 ++++++++++++++----- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 11adb50ca..3fc81b0d4 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -164,10 +164,10 @@ public void show(Player player) { .build(); } catch (SignGUIVersionException e) { Bukkit.getLogger().severe("The server version is unsupported by SignGUI API!"); - } finally { - if (descriptionSignGui != null) { - descriptionSignGui.open(player); - } + } + + if (descriptionSignGui != null) { + descriptionSignGui.open(player); } }); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java index 597754871..8049a8262 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerBreakController.java @@ -1,10 +1,17 @@ package com.eternalcode.parcellockers.locker.controller; +import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.multification.shared.Formatter; import com.eternalcode.parcellockers.locker.LockerManager; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.shared.Position; import com.eternalcode.parcellockers.shared.PositionAdapter; +import com.spotify.futures.CompletableFutures; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.BlockState; @@ -22,13 +29,15 @@ public class LockerBreakController implements Listener { private final LockerManager lockerManager; private final NoticeService noticeService; + private final Scheduler scheduler; public LockerBreakController( LockerManager lockerManager, - NoticeService noticeService + NoticeService noticeService, Scheduler scheduler ) { this.lockerManager = lockerManager; this.noticeService = noticeService; + this.scheduler = scheduler; } @EventHandler @@ -92,22 +101,32 @@ public void onBlockExplode(BlockExplodeEvent event) { this.lockerManager.get(position).thenAccept(locker -> { if (locker.isPresent()) { - event.blockList().remove(explodedBlockState.getBlock()); + this.scheduler.run(() -> event.blockList().remove(explodedBlockState.getBlock())); } }); } @EventHandler public void onEntityExplode(EntityExplodeEvent event) { - for (Block block : event.blockList()) { - Position position = PositionAdapter.convert(block.getLocation()); - - this.lockerManager.get(position).thenAccept(locker -> { - if (locker.isPresent()) { - event.blockList().remove(block); - } + List blocks = new ArrayList<>(event.blockList()); + + List>> futures = blocks.stream() + .map(block -> { + Position position = PositionAdapter.convert(block.getLocation()); + return this.lockerManager.get(position) + .thenApply(locker -> locker.isPresent() ? Optional.of(block) : Optional.empty()); + }) + .collect(Collectors.toList()); + + CompletableFutures.allAsList(futures) + .thenAccept(results -> { + List blocksToRemove = results.stream() + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); + + this.scheduler.run(() -> event.blockList().removeAll(blocksToRemove)); }); - } } @EventHandler From 0576608630615a16c6d54a7c5a72a5cbf0d5328f Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:19:28 +0200 Subject: [PATCH 39/51] fix build --- .../user/repository/UserRepositoryOrmLite.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index 88e81e3ef..91e910635 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -43,12 +43,12 @@ public CompletableFuture> fetch(String name) { } @Override - this.save(UserTable.class, UserTable.from(user)) - .exceptionally(ex -> { - System.err.println("Failed to save user: " + ex.getMessage()); - ex.printStackTrace(); - return null; - }); + public void save(User user) { + this.save(UserTable.class, UserTable.from(user)).exceptionally(ex -> { + System.err.println("Failed to save user: " + ex.getMessage()); + ex.printStackTrace(); + return null; + }); } @Override From 4c017ce66fb1927a7bbb418b56bacee3dedaf7e8 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:20:19 +0200 Subject: [PATCH 40/51] fix build --- src/main/java/com/eternalcode/parcellockers/ParcelLockers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index c6a6a59a5..265150f1d 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -166,7 +166,7 @@ public void onEnable() { Stream.of( new LockerInteractionController(lockerManager, lockerGUI), new LockerPlaceController(config, this, lockerManager, noticeService), - new LockerBreakController(lockerManager, noticeService), + new LockerBreakController(lockerManager, noticeService, scheduler), new PrepareUserController(userManager), new LoadUserController(userManager, server) ).forEach(controller -> server.getPluginManager().registerEvents(controller, this)); From bba70498fb84620cd65c9d9d28501aced574d4e2 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Tue, 2 Sep 2025 21:40:14 +0200 Subject: [PATCH 41/51] move cache initialization to constructor --- .../content/ParcelContentManager.java | 9 +++++---- .../delivery/DeliveryManager.java | 9 +++++---- .../itemstorage/ItemStorageManager.java | 9 +++++---- .../parcellockers/locker/LockerManager.java | 19 ++++++++++--------- .../parcel/ParcelServiceImpl.java | 10 ++++++---- .../parcellockers/user/UserManagerImpl.java | 19 ++++++++++--------- 6 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java index 6679be80f..c66d3b0d3 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java +++ b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java @@ -14,15 +14,16 @@ public class ParcelContentManager { - private final Cache cache = Caffeine.newBuilder() - .expireAfterWrite(6, TimeUnit.HOURS) - .maximumSize(10_000) - .build(); + private final Cache cache; private final ParcelContentRepository contentRepository; public ParcelContentManager(ParcelContentRepository contentRepository) { this.contentRepository = contentRepository; + this.cache = Caffeine.newBuilder() + .expireAfterWrite(6, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); } public CompletableFuture> get(UUID parcelId) { diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java index 93d2a5b5c..292461735 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java @@ -11,15 +11,16 @@ public class DeliveryManager { private final DeliveryRepository deliveryRepository; - private final Cache deliveryCache = Caffeine.newBuilder() - .expireAfterWrite(Duration.ofHours(6)) - .maximumSize(10_000) - .build(); + private final Cache deliveryCache; public DeliveryManager(DeliveryRepository deliveryRepository) { this.deliveryRepository = deliveryRepository; this.cacheAll(); + this.deliveryCache = Caffeine.newBuilder() + .expireAfterWrite(Duration.ofHours(6)) + .maximumSize(10_000) + .build(); } public Delivery getOrCreate(UUID parcel, Instant deliveryTimestamp) { diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java index 598b3d62c..a20e15ae2 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -14,10 +14,7 @@ public class ItemStorageManager { - private final Cache cache = Caffeine.newBuilder() - .expireAfterWrite(6, TimeUnit.HOURS) - .maximumSize(10_000) - .build(); + private final Cache cache; private final ItemStorageRepository itemStorageRepository; @@ -25,6 +22,10 @@ public ItemStorageManager(ItemStorageRepository itemStorageRepository) { this.itemStorageRepository = itemStorageRepository; this.cacheAll(); + this.cache = Caffeine.newBuilder() + .expireAfterWrite(6, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); } public CompletableFuture> get(UUID parcelId) { diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 55406af55..999231d6a 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -18,20 +18,21 @@ public class LockerManager { private final LockerRepository lockerRepository; - private final Cache lockersByUUID = Caffeine.newBuilder() - .expireAfterAccess(Duration.ofHours(2)) - .maximumSize(10_000) - .build(); - - private final Cache lockersByPosition = Caffeine.newBuilder() - .expireAfterAccess(Duration.ofHours(2)) - .maximumSize(10_000) - .build(); + private final Cache lockersByUUID; + private final Cache lockersByPosition; public LockerManager(LockerRepository lockerRepository) { this.lockerRepository = lockerRepository; this.cacheAll(); + this.lockersByUUID = Caffeine.newBuilder() + .expireAfterAccess(Duration.ofHours(2)) + .maximumSize(10_000) + .build(); + this.lockersByPosition = Caffeine.newBuilder() + .expireAfterAccess(Duration.ofHours(2)) + .maximumSize(10_000) + .build(); } public CompletableFuture> get(UUID uniqueId) { diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index e45b497d1..d397211b7 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -31,11 +31,9 @@ public class ParcelServiceImpl implements ParcelService { private final ParcelContentRepository parcelContentRepository; private final Scheduler scheduler; - private final Cache parcelsByUuid = Caffeine.newBuilder() - .expireAfterAccess(3, TimeUnit.HOURS) - .maximumSize(10_000) - .build(); + private final Cache parcelsByUuid; + // todo - use cache instead of multimaps for thread safety private final Multimap parcelsBySender = HashMultimap.create(); private final Multimap parcelsByReceiver = HashMultimap.create(); @@ -51,6 +49,10 @@ public ParcelServiceImpl( this.scheduler = scheduler; this.cacheAll(); + this.parcelsByUuid = Caffeine.newBuilder() + .expireAfterAccess(3, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index b82a170cd..384b0d6a5 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -14,18 +14,19 @@ public class UserManagerImpl implements UserManager { private final UserRepository userRepository; - private final Cache usersByUUID = Caffeine.newBuilder() - .expireAfterAccess(2, TimeUnit.HOURS) - .maximumSize(10_000) - .build(); - - private final Cache usersByName = Caffeine.newBuilder() - .expireAfterAccess(2, TimeUnit.HOURS) - .maximumSize(10_000) - .build(); + private final Cache usersByUUID; + private final Cache usersByName; public UserManagerImpl(UserRepository userRepository) { this.userRepository = userRepository; + this.usersByUUID = Caffeine.newBuilder() + .expireAfterAccess(2, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); + this.usersByName = Caffeine.newBuilder() + .expireAfterAccess(2, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); } @Override From a92d4726ef5b40d54616d91d13f5436e967721b7 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:23:27 +0200 Subject: [PATCH 42/51] Add Validation classes and architecture (suggestion from @noyzys) --- .../parcellockers/locker/LockerManager.java | 1 + .../LockerConflictDetectionStrategy.java | 15 +++ .../validation/LockerValidationService.java | 16 +++ .../locker/validation/LockerValidator.java | 111 ++++++++++++++++++ .../parcel/ParcelServiceImpl.java | 61 +++++++--- .../shared/validation/ValidationResult.java | 15 +++ .../shared/validation/ValidationRule.java | 14 +++ 7 files changed, 219 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java create mode 100644 src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidationService.java create mode 100644 src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidator.java create mode 100644 src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationResult.java create mode 100644 src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 999231d6a..d88b7c6d7 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -14,6 +14,7 @@ import java.util.concurrent.CompletableFuture; import org.bukkit.command.CommandSender; +// TODO: Implement validation public class LockerManager { private final LockerRepository lockerRepository; diff --git a/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java new file mode 100644 index 000000000..da483faf0 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java @@ -0,0 +1,15 @@ +package com.eternalcode.parcellockers.locker.validation; + +import com.eternalcode.parcellockers.locker.Locker; +import com.eternalcode.parcellockers.shared.Position; +import com.eternalcode.parcellockers.shared.validation.ValidationResult; +import java.util.Optional; +import java.util.UUID; + +public interface LockerConflictDetectionStrategy { + + ValidationResult detectConflicts( + UUID uniqueId, Position position, + Optional existingByUUID, + Optional existingByPosition); +} \ No newline at end of file diff --git a/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidationService.java b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidationService.java new file mode 100644 index 000000000..f8cddadd9 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidationService.java @@ -0,0 +1,16 @@ +package com.eternalcode.parcellockers.locker.validation; + +import com.eternalcode.parcellockers.locker.Locker; +import com.eternalcode.parcellockers.shared.Position; +import com.eternalcode.parcellockers.shared.validation.ValidationResult; +import java.util.Optional; +import java.util.UUID; + +public interface LockerValidationService { + + ValidationResult validateCreateParameters(UUID uniqueId, String name, Position position); + + ValidationResult validateNoConflicts(UUID uniqueId, Position position, + Optional existingByUUID, + Optional existingByPosition); +} diff --git a/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidator.java b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidator.java new file mode 100644 index 000000000..0aadec138 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerValidator.java @@ -0,0 +1,111 @@ +package com.eternalcode.parcellockers.locker.validation; + +import com.eternalcode.parcellockers.locker.Locker; +import com.eternalcode.parcellockers.shared.Position; +import com.eternalcode.parcellockers.shared.validation.ValidationResult; +import com.eternalcode.parcellockers.shared.validation.ValidationRule; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public final class LockerValidator implements LockerValidationService { + + private final List> creationRules; + private final LockerConflictDetectionStrategy conflictStrategy; + + public LockerValidator() { + this.creationRules = List.of( + this::validateUUID, + this::validateName, + this::validatePosition); + + this.conflictStrategy = this::defaultConflictDetection; + } + + public LockerValidator(List> creationRules, + LockerConflictDetectionStrategy conflictStrategy) { + this.creationRules = creationRules; + this.conflictStrategy = conflictStrategy; + } + + @Override + public ValidationResult validateCreateParameters(UUID uniqueId, String name, Position position) { + CreateLockerRequest request = new CreateLockerRequest(uniqueId, name, position); + + return this.creationRules.stream() + .reduce(ValidationRule::and) + .map(rule -> rule.validate(request)) + .orElse(ValidationResult.valid()); + } + + @Override + public ValidationResult validateNoConflicts(UUID uniqueId, Position position, + Optional existingByUUID, + Optional existingByPosition) { + return this.conflictStrategy.detectConflicts(uniqueId, position, existingByUUID, existingByPosition); + } + + private ValidationResult validateUUID(CreateLockerRequest request) { + return request.uniqueId() != null ? + ValidationResult.valid() : + ValidationResult.invalid("UUID cannot be null"); + } + + private ValidationResult validateName(CreateLockerRequest request) { + return request.name() != null && !request.name().trim().isEmpty() ? + ValidationResult.valid() : + ValidationResult.invalid("Name cannot be empty"); + } + + private ValidationResult validatePosition(CreateLockerRequest request) { + return request.position() != null ? + ValidationResult.valid() : + ValidationResult.invalid("Position cannot be null"); + } + + private ValidationResult defaultConflictDetection( + UUID uniqueId, Position position, + Optional existingByUUID, + Optional existingByPosition) { + return existingByUUID.flatMap(byUUID -> existingByPosition.map(byPosition -> this.validateBothExist(uniqueId, position, byUUID, byPosition))) + .orElseGet(() -> existingByUUID + .map(locker -> this.validateUUIDConflict(uniqueId, position, locker)) + .orElseGet(() -> existingByPosition + .map(locker -> this.validatePositionConflict(uniqueId, position, locker)) + .orElse(ValidationResult.valid()))); + } + + private ValidationResult validateBothExist(UUID uniqueId, Position position, + Locker byUUID, Locker byPosition) { + if (!byUUID.equals(byPosition)) { + return ValidationResult.invalid(String.format("Conflicting lockers found. UUID %s vs Position %s", + uniqueId, position)); + } + + return ValidationResult.valid(); + } + + private ValidationResult validateUUIDConflict(UUID uniqueId, Position position, Locker locker) { + if (!locker.position().equals(position)) { + return ValidationResult.invalid(String.format("Locker with UUID %s exists at different position: %s", + uniqueId, locker.position())); + } + + return ValidationResult.valid(); + } + + private ValidationResult validatePositionConflict(UUID uniqueId, Position position, Locker locker) { + if (!locker.uuid().equals(uniqueId)) { + return ValidationResult.invalid(String.format("Locker at position %s has different UUID: %s", + position, locker.uuid())); + } + + return ValidationResult.valid(); + } + + private record CreateLockerRequest( + UUID uniqueId, + String name, + Position position) { + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index d397211b7..336a2de02 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -13,8 +13,7 @@ import com.eternalcode.parcellockers.shared.ParcelLockersException; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -32,10 +31,8 @@ public class ParcelServiceImpl implements ParcelService { private final Scheduler scheduler; private final Cache parcelsByUuid; - - // todo - use cache instead of multimaps for thread safety - private final Multimap parcelsBySender = HashMultimap.create(); - private final Multimap parcelsByReceiver = HashMultimap.create(); + private final Cache> parcelsBySender; + private final Cache> parcelsByReceiver; public ParcelServiceImpl( NoticeService noticeService, @@ -53,6 +50,16 @@ public ParcelServiceImpl( .expireAfterAccess(3, TimeUnit.HOURS) .maximumSize(10_000) .build(); + + this.parcelsBySender = Caffeine.newBuilder() + .expireAfterAccess(3, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); + + this.parcelsByReceiver = Caffeine.newBuilder() + .expireAfterAccess(3, TimeUnit.HOURS) + .maximumSize(10_000) + .build(); } @Override @@ -148,7 +155,7 @@ public CompletableFuture> get(UUID uuid) { @Override public CompletableFuture> getBySender(UUID sender, Page page) { - List cached = List.copyOf(this.parcelsBySender.get(sender)); + List cached = List.copyOf(this.parcelsBySender.getIfPresent(sender)); boolean hasNextPage = cached.size() > page.getLimit(); if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { return CompletableFuture.completedFuture(new PageResult<>(cached, false)); @@ -161,7 +168,7 @@ public CompletableFuture> getBySender(UUID sender, Page page) @Override public CompletableFuture> getByReceiver(UUID receiver, Page page) { - List cached = List.copyOf(this.parcelsByReceiver.get(receiver)); + List cached = List.copyOf(this.parcelsByReceiver.getIfPresent(receiver)); boolean hasNextPage = cached.size() > page.getLimit(); if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { return CompletableFuture.completedFuture(new PageResult<>(cached, false)); @@ -205,20 +212,46 @@ public void deleteAll(CommandSender sender, NoticeService noticeService) { .send(); this.parcelsByUuid.invalidateAll(); - this.parcelsBySender.clear(); - this.parcelsByReceiver.clear(); + this.parcelsBySender.invalidateAll(); + this.parcelsByReceiver.invalidateAll(); }); } private void cache(Parcel parcel) { this.parcelsByUuid.put(parcel.uuid(), parcel); - this.parcelsBySender.put(parcel.sender(), parcel); - this.parcelsByReceiver.put(parcel.receiver(), parcel); + + List bySender = this.parcelsBySender.getIfPresent(parcel.sender()); + if (bySender == null) { + bySender = new ArrayList<>(); + } + bySender.add(parcel); + + List byReceiver = this.parcelsByReceiver.getIfPresent(parcel.receiver()); + if (byReceiver == null) { + byReceiver = new ArrayList<>(); + } + byReceiver.add(parcel); + + this.parcelsBySender.put(parcel.sender(), bySender); + this.parcelsByReceiver.put(parcel.receiver(), byReceiver); } private void invalidate(Parcel parcel) { this.parcelsByUuid.invalidate(parcel.uuid()); - this.parcelsBySender.remove(parcel.sender(), parcel); - this.parcelsByReceiver.remove(parcel.receiver(), parcel); + + List bySender = this.parcelsBySender.getIfPresent(parcel.sender()); + if (bySender == null) { + bySender = new ArrayList<>(); + } + bySender.remove(parcel); + + List byReceiver = this.parcelsByReceiver.getIfPresent(parcel.receiver()); + if (byReceiver == null) { + byReceiver = new ArrayList<>(); + } + byReceiver.remove(parcel); + + this.parcelsBySender.put(parcel.sender(), bySender); + this.parcelsByReceiver.put(parcel.receiver(), byReceiver); } } diff --git a/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationResult.java b/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationResult.java new file mode 100644 index 000000000..e6e91ce20 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationResult.java @@ -0,0 +1,15 @@ +package com.eternalcode.parcellockers.shared.validation; + +public record ValidationResult( + boolean isValid, + String errorMessage +) { + + public static ValidationResult valid() { + return new ValidationResult(true, null); + } + + public static ValidationResult invalid(String message) { + return new ValidationResult(false, message); + } +} diff --git a/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java b/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java new file mode 100644 index 000000000..57486815c --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java @@ -0,0 +1,14 @@ +package com.eternalcode.parcellockers.shared.validation; + +@FunctionalInterface +public interface ValidationRule { + + default ValidationRule and(ValidationRule other) { + return value -> { + + ValidationResult result = this.validate(value); + return result.isValid() ? other.validate(value) : result; + }; + } + ValidationResult validate(T value); +} From e0df0234c95f658854907a66cbb9a6c7baaab34b Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Wed, 3 Sep 2025 20:56:01 +0200 Subject: [PATCH 43/51] Implement validation --- .../parcellockers/ParcelLockers.java | 5 +- .../repository/ParcelContentRepository.java | 2 +- .../ParcelContentRepositoryOrmLite.java | 4 +- .../repository/DeliveryRepository.java | 6 ++- .../repository/DeliveryRepositoryOrmLite.java | 13 ++++-- .../itemstorage/ItemStorageManager.java | 5 +- .../parcellockers/locker/LockerManager.java | 46 ++++++++++++------- .../locker/repository/LockerRepository.java | 2 +- .../repository/LockerRepositoryOrmLite.java | 4 +- .../user/repository/UserRepository.java | 2 +- .../repository/UserRepositoryOrmLite.java | 6 +-- 11 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index 265150f1d..eb8bf514d 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -27,6 +27,8 @@ import com.eternalcode.parcellockers.locker.controller.LockerInteractionController; import com.eternalcode.parcellockers.locker.controller.LockerPlaceController; import com.eternalcode.parcellockers.locker.repository.LockerRepositoryOrmLite; +import com.eternalcode.parcellockers.locker.validation.LockerValidationService; +import com.eternalcode.parcellockers.locker.validation.LockerValidator; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.parcel.ParcelService; import com.eternalcode.parcellockers.parcel.ParcelServiceImpl; @@ -115,7 +117,8 @@ public void onEnable() { ); UserManager userManager = new UserManagerImpl(userRepository); - LockerManager lockerManager = new LockerManager(lockerRepository); + LockerValidationService lockerValidationService = new LockerValidator(); + LockerManager lockerManager = new LockerManager(lockerRepository, lockerValidationService); ParcelContentManager parcelContentManager = new ParcelContentManager(parcelContentRepository); ItemStorageManager itemStorageManager = new ItemStorageManager(itemStorageRepository); DeliveryManager deliveryManager = new DeliveryManager(deliveryRepository); diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java index 7b93a320d..966bdcb61 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepository.java @@ -11,7 +11,7 @@ public interface ParcelContentRepository { CompletableFuture> fetch(UUID uniqueId); - void delete(UUID uniqueId); + CompletableFuture delete(UUID uniqueId); CompletableFuture deleteAll(); diff --git a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java index b9d4c35e4..45f2c05e8 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/content/repository/ParcelContentRepositoryOrmLite.java @@ -29,8 +29,8 @@ public CompletableFuture save(ParcelContent parcelContent) { } @Override - public void delete(UUID uniqueId) { - this.deleteById(ParcelContentTable.class, uniqueId); + public CompletableFuture delete(UUID uniqueId) { + return this.deleteById(ParcelContentTable.class, uniqueId); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java index ae8fd55fd..72ff214a4 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepository.java @@ -8,11 +8,13 @@ public interface DeliveryRepository { - void save(Delivery delivery); + CompletableFuture save(Delivery delivery); CompletableFuture> fetch(UUID parcel); - void delete(UUID parcel); + CompletableFuture delete(UUID parcel); + + CompletableFuture deleteAll(); CompletableFuture>> fetchAll(); } diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java index 36d11501e..fd2a7355d 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/repository/DeliveryRepositoryOrmLite.java @@ -24,8 +24,8 @@ public DeliveryRepositoryOrmLite(DatabaseManager databaseManager, Scheduler sche } @Override - public void save(Delivery delivery) { - this.saveIfNotExist(DeliveryTable.class, DeliveryTable.from(delivery)).thenApply(dao -> null); + public CompletableFuture save(Delivery delivery) { + return this.saveIfNotExist(DeliveryTable.class, DeliveryTable.from(delivery)).thenApply(dao -> null); } @Override @@ -42,7 +42,12 @@ public CompletableFuture>> fetchAll() { } @Override - public void delete(UUID parcel) { - this.deleteById(DeliveryTable.class, parcel); + public CompletableFuture delete(UUID parcel) { + return this.deleteById(DeliveryTable.class, parcel); + } + + @Override + public CompletableFuture deleteAll() { + return this.deleteAll(DeliveryTable.class); } } diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java index a20e15ae2..4990dec19 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -54,7 +54,10 @@ public ItemStorage create(UUID parcel, List items) { } private void cacheAll() { - this.itemStorageRepository.fetchAll().thenAccept(all -> all.ifPresent(list -> list.forEach(itemStorage -> this.cache.put(itemStorage.owner(), itemStorage)))); + this.itemStorageRepository.fetchAll() + .thenAccept(all -> all.ifPresent(list -> list.forEach(itemStorage -> this.cache.put( + itemStorage.owner(), + itemStorage)))); } public void delete(UUID parcel) { diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index d88b7c6d7..61b1f2700 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -1,10 +1,12 @@ package com.eternalcode.parcellockers.locker; import com.eternalcode.parcellockers.locker.repository.LockerRepository; +import com.eternalcode.parcellockers.locker.validation.LockerValidationService; import com.eternalcode.parcellockers.notification.NoticeService; import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.PageResult; import com.eternalcode.parcellockers.shared.Position; +import com.eternalcode.parcellockers.shared.validation.ValidationResult; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import java.time.Duration; @@ -12,18 +14,21 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; import org.bukkit.command.CommandSender; // TODO: Implement validation public class LockerManager { private final LockerRepository lockerRepository; + private final LockerValidationService validationService; private final Cache lockersByUUID; private final Cache lockersByPosition; - public LockerManager(LockerRepository lockerRepository) { + public LockerManager(LockerRepository lockerRepository, LockerValidationService validationService) { this.lockerRepository = lockerRepository; + this.validationService = validationService; this.cacheAll(); this.lockersByUUID = Caffeine.newBuilder() @@ -81,35 +86,44 @@ public CompletableFuture> get(Page page) { return this.lockerRepository.fetchPage(page); } - public Locker getOrCreate(UUID uniqueId, String name, Position position) { + public CompletableFuture getOrCreate(UUID uniqueId, String name, Position position) { Locker lockerByUUID = this.lockersByUUID.getIfPresent(uniqueId); if (lockerByUUID != null) { - return lockerByUUID; + return CompletableFuture.completedFuture(lockerByUUID); } Locker lockerByPosition = this.lockersByPosition.getIfPresent(position); if (lockerByPosition != null) { - return lockerByPosition; + return CompletableFuture.completedFuture(lockerByPosition); } return this.create(uniqueId, name, position); } - public Locker create(UUID uniqueId, String name, Position position) { - if (this.lockersByUUID.getIfPresent(uniqueId) != null) { - throw new IllegalStateException("Locker with UUID " + uniqueId + " already exists in cache"); - } + public CompletableFuture create(UUID uniqueId, String name, Position position) { + return CompletableFuture.supplyAsync(() -> { - if (this.lockersByPosition.getIfPresent(position) != null) { - throw new IllegalStateException("Locker at position " + position + " already exists in cache"); - } + ValidationResult validation = this.validationService.validateCreateParameters(uniqueId, name, position); + if (!validation.isValid()) { + throw new IllegalArgumentException(validation.errorMessage()); + } + + Optional existingByUUID = Optional.ofNullable(this.lockersByUUID.get(uniqueId, uuid -> null)); + Optional existingByPosition = Optional.ofNullable(this.lockersByPosition.get(position, pos -> null)); + + ValidationResult conflictCheck = this.validationService.validateNoConflicts( + uniqueId, position, existingByUUID, existingByPosition); + + if (!conflictCheck.isValid()) { + throw new IllegalStateException(conflictCheck.errorMessage()); + } - Locker locker = new Locker(uniqueId, name, position); - this.lockersByUUID.put(uniqueId, locker); - this.lockersByPosition.put(position, locker); - this.lockerRepository.save(locker); + Locker locker = new Locker(uniqueId, name, position); + this.lockersByUUID.put(uniqueId, locker); + this.lockersByPosition.put(position, locker); - return locker; + return this.lockerRepository.save(locker); + }).thenCompose(Function.identity()); } public void delete(UUID uniqueId) { diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java index 24e2a1a44..ff339720f 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepository.java @@ -11,7 +11,7 @@ public interface LockerRepository { - CompletableFuture save(Locker locker); + CompletableFuture save(Locker locker); CompletableFuture>> fetchAll(); diff --git a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java index 8f32efaf2..4437155be 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/repository/LockerRepositoryOrmLite.java @@ -30,8 +30,8 @@ public LockerRepositoryOrmLite(DatabaseManager databaseManager, Scheduler schedu } @Override - public CompletableFuture save(Locker locker) { - return this.saveIfNotExist(LockerTable.class, LockerTable.from(locker)).thenApply(dao -> null); + public CompletableFuture save(Locker locker) { + return this.saveIfNotExist(LockerTable.class, LockerTable.from(locker)).thenApply(LockerTable::toLocker); } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java index 4203a6f62..6a44011a9 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepository.java @@ -9,7 +9,7 @@ public interface UserRepository { - void save(User user); + CompletableFuture save(User user); CompletableFuture changeName(UUID uuid, String newName); diff --git a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java index 91e910635..f33cea147 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java +++ b/src/main/java/com/eternalcode/parcellockers/user/repository/UserRepositoryOrmLite.java @@ -43,12 +43,12 @@ public CompletableFuture> fetch(String name) { } @Override - public void save(User user) { - this.save(UserTable.class, UserTable.from(user)).exceptionally(ex -> { + public CompletableFuture save(User user) { + return this.save(UserTable.class, UserTable.from(user)).exceptionally(ex -> { System.err.println("Failed to save user: " + ex.getMessage()); ex.printStackTrace(); return null; - }); + }).thenApply(dao -> null); } @Override From 22dad9c4f138db2fc47e0c0790ca91ae6595925d Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 6 Sep 2025 17:08:16 +0200 Subject: [PATCH 44/51] Use CompletableFuture in Service/Manager-like classes --- .../content/ParcelContentManager.java | 9 +++++--- .../delivery/DeliveryManager.java | 9 +++++--- .../implementation/locker/ItemStorageGui.java | 2 ++ .../itemstorage/ItemStorageManager.java | 22 +++++++++--------- .../parcellockers/locker/LockerManager.java | 11 ++++----- .../parcellockers/parcel/ParcelService.java | 10 ++++---- .../parcel/ParcelServiceImpl.java | 23 ++++++++++--------- .../parcellockers/user/UserManager.java | 2 +- .../parcellockers/user/UserManagerImpl.java | 8 +++---- 9 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java index c66d3b0d3..a51c7fe8f 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java +++ b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java @@ -12,6 +12,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.inventory.ItemStack; +// TODO: Use CompletableFuture wherever possible public class ParcelContentManager { private final Cache cache; @@ -51,9 +52,11 @@ public ParcelContent create(UUID parcel, List items) { return content; } - public void delete(UUID parcel) { - this.cache.invalidate(parcel); - this.contentRepository.delete(parcel); + public CompletableFuture delete(UUID parcel) { + return this.contentRepository.delete(parcel).thenApply(i -> { + this.cache.invalidate(parcel); + return null; + }); } public void deleteAll(CommandSender sender, NoticeService noticeService) { diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java index 292461735..aefa1ed66 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java @@ -6,6 +6,7 @@ import java.time.Duration; import java.time.Instant; import java.util.UUID; +import java.util.concurrent.CompletableFuture; public class DeliveryManager { @@ -37,9 +38,11 @@ public Delivery create(UUID parcel, Instant deliveryTimestamp) { return delivery; } - public void delete(UUID parcel) { - this.deliveryCache.invalidate(parcel); - this.deliveryRepository.delete(parcel); + public CompletableFuture delete(UUID parcel) { + return this.deliveryRepository.delete(parcel).thenApply(i -> { + this.deliveryCache.invalidate(parcel); + return null; + }); } private void cacheAll() { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index e613817bd..3d6f5db48 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -87,6 +87,8 @@ void show(Player player, ParcelSize size) { gui.setCloseGuiAction(event -> { ItemStack[] contents = gui.getInventory().getContents(); + // todo fix items not saving after clicking the confirm button on the gui + // when no new items were added List items = new ArrayList<>(); diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java index 4990dec19..96e0db9f8 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -39,16 +39,16 @@ public CompletableFuture> get(UUID parcelId) { }); } - public ItemStorage getOrCreate(UUID parcelId, List items) { - return this.cache.get(parcelId, key -> this.create(key, items)); + public ItemStorage getOrCreate(UUID owner, List items) { + return this.cache.get(owner, key -> this.create(key, items)); } - public ItemStorage create(UUID parcel, List items) { - ItemStorage content = new ItemStorage(parcel, items); - if (this.cache.getIfPresent(parcel) != null) { - throw new IllegalStateException("ParcelContent for parcel " + parcel + " already exists. Use ParcelContentManager#getOrCreate method instead."); + public ItemStorage create(UUID owner, List items) { + ItemStorage content = new ItemStorage(owner, items); + if (this.cache.getIfPresent(owner) != null) { + throw new IllegalStateException("ItemStorage for owner " + owner + " already exists. Use ItemStorageManager#getOrCreate method instead."); } - this.cache.put(parcel, content); + this.cache.put(owner, content); this.itemStorageRepository.save(content); return content; } @@ -60,13 +60,13 @@ private void cacheAll() { itemStorage)))); } - public void delete(UUID parcel) { + public CompletableFuture delete(UUID parcel) { this.cache.invalidate(parcel); - this.itemStorageRepository.delete(parcel); + return this.itemStorageRepository.delete(parcel).thenApply(i -> null); } - public void deleteAll(CommandSender sender, NoticeService noticeService) { - this.itemStorageRepository.deleteAll().thenAccept(deleted -> { + public CompletableFuture deleteAll(CommandSender sender, NoticeService noticeService) { + return this.itemStorageRepository.deleteAll().thenAccept(deleted -> { noticeService.create() .viewer(sender) .notice(messages -> messages.admin.deletedItemStorages) diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index 61b1f2700..da46d3a42 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -126,18 +126,17 @@ public CompletableFuture create(UUID uniqueId, String name, Position pos }).thenCompose(Function.identity()); } - public void delete(UUID uniqueId) { - this.lockersByUUID.invalidate(uniqueId); - this.lockerRepository.delete(uniqueId).thenApply(deleted -> { + public CompletableFuture delete(UUID uniqueId) { + return this.lockerRepository.delete(uniqueId).thenAccept(deleted -> { if (deleted > 0) { + this.lockersByUUID.invalidate(uniqueId); this.lockersByPosition.asMap().values().removeIf(locker -> locker.uuid().equals(uniqueId)); } - return deleted; }); } - public void deleteAll(CommandSender sender, NoticeService noticeService) { - this.lockerRepository.deleteAll().thenAccept(deleted -> { + public CompletableFuture deleteAll(CommandSender sender, NoticeService noticeService) { + return this.lockerRepository.deleteAll().thenAccept(deleted -> { noticeService.create() .notice(messages -> messages.admin.deletedLockers) .placeholder("{COUNT}", deleted.toString()) diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java index 58a4c9a8d..9b9243af4 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelService.java @@ -13,15 +13,15 @@ public interface ParcelService { - void send(Player sender, Parcel parcel, List items); + CompletableFuture send(Player sender, Parcel parcel, List items); - void update(Parcel parcel); + CompletableFuture update(Parcel parcel); - void collect(Player player, Parcel parcel); + CompletableFuture collect(Player player, Parcel parcel); - void delete(CommandSender sender, Parcel parcel); + CompletableFuture delete(CommandSender sender, Parcel parcel); - void deleteAll(CommandSender sender, NoticeService noticeService); + CompletableFuture deleteAll(CommandSender sender, NoticeService noticeService); CompletableFuture> get(UUID uuid); diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 336a2de02..528eff84b 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -63,7 +63,7 @@ public ParcelServiceImpl( } @Override - public void send(Player sender, Parcel parcel, List items) { + public CompletableFuture send(Player sender, Parcel parcel, List items) { this.parcelRepository.save(parcel).whenComplete((v, throwable) -> { if (throwable != null) { this.noticeService.create() @@ -79,17 +79,18 @@ public void send(Player sender, Parcel parcel, List items) { .player(sender.getUniqueId()) .send(); }); + return null; } @Override - public void update(Parcel updated) { - this.parcelRepository.update(updated); + public CompletableFuture update(Parcel updated) { this.cache(updated); + return this.parcelRepository.update(updated); } @Override - public void delete(CommandSender sender, Parcel parcel) { - this.parcelRepository.delete(parcel) + public CompletableFuture delete(CommandSender sender, Parcel parcel) { + return this.parcelRepository.delete(parcel) .thenAccept(v -> { this.noticeService.create() .notice(messages -> messages.parcel.deleted) @@ -107,8 +108,8 @@ public void delete(CommandSender sender, Parcel parcel) { } @Override - public void collect(Player player, Parcel parcel) { - this.parcelContentRepository.fetch(parcel.uuid()).thenAccept(optional -> { + public CompletableFuture collect(Player player, Parcel parcel) { + return this.parcelContentRepository.fetch(parcel.uuid()).thenAccept(optional -> { if (optional.isEmpty()) { this.noticeService.create() .notice(messages -> messages.parcel.cannotCollect) @@ -129,7 +130,7 @@ public void collect(Player player, Parcel parcel) { items.forEach(item -> this.scheduler.run(() -> ItemUtil.giveItem(player, item))); - // TODO: Do not delete, archive instead + // TODO in the future: Do not delete, archive instead this.invalidate(parcel); this.parcelRepository.delete(parcel); this.parcelContentRepository.delete(parcel.uuid()); @@ -185,8 +186,8 @@ private void cacheAll() { @Override public CompletableFuture delete(UUID uuid) { - this.parcelsByUuid.invalidate(uuid); return this.parcelRepository.delete(uuid).thenApply(deleted -> { + this.parcelsByUuid.invalidate(uuid); if (deleted > 0) { Parcel cached = this.parcelsByUuid.getIfPresent(uuid); if (cached != null) { @@ -203,8 +204,8 @@ public CompletableFuture delete(Parcel parcel) { } @Override - public void deleteAll(CommandSender sender, NoticeService noticeService) { - this.parcelRepository.deleteAll().thenAccept(deleted -> { + public CompletableFuture deleteAll(CommandSender sender, NoticeService noticeService) { + return this.parcelRepository.deleteAll().thenAccept(deleted -> { noticeService.create() .notice(messages -> messages.admin.deletedParcels) .viewer(sender) diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java index 54e1745d0..6b7e06391 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java @@ -10,7 +10,7 @@ public interface UserManager { User create(UUID uuid, String name); - void getOrCreate(UUID uuid, String name); + User getOrCreate(UUID uuid, String name); CompletableFuture> get(String username); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index 384b0d6a5..d85a65607 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -52,20 +52,20 @@ public CompletableFuture> get(String username) { } @Override - public void getOrCreate(UUID uuid, String name) { + public User getOrCreate(UUID uuid, String name) { User userByUUID = this.usersByUUID.getIfPresent(uuid); if (userByUUID != null) { - return; + return userByUUID; } User userByName = this.usersByName.getIfPresent(name); if (userByName != null) { - return; + return userByName; } - this.create(uuid, name); + return this.create(uuid, name); } @Override From 53aaaecf4732cd80ff0fcac536ad434d096f4eca Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 6 Sep 2025 17:50:49 +0200 Subject: [PATCH 45/51] Cache object after the cache is initialized --- .../delivery/DeliveryManager.java | 3 +- .../parcellockers/gui/GuiManager.java | 4 +- .../implementation/locker/ItemStorageGui.java | 5 +- .../itemstorage/ItemStorageManager.java | 3 +- .../parcellockers/locker/LockerManager.java | 3 +- .../parcel/ParcelServiceImpl.java | 87 ++++++++++--------- .../shared/validation/ValidationRule.java | 1 - 7 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java index aefa1ed66..251137a7f 100644 --- a/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java +++ b/src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java @@ -17,11 +17,12 @@ public class DeliveryManager { public DeliveryManager(DeliveryRepository deliveryRepository) { this.deliveryRepository = deliveryRepository; - this.cacheAll(); this.deliveryCache = Caffeine.newBuilder() .expireAfterWrite(Duration.ofHours(6)) .maximumSize(10_000) .build(); + + this.cacheAll(); } public Delivery getOrCreate(UUID parcel, Instant deliveryTimestamp) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java index f669f8378..8a870bbad 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java @@ -107,7 +107,7 @@ public void saveItemStorage(UUID player, List items) { this.itemStorageManager.create(player, items); } - public void deleteItemStorage(UUID owner) { - this.itemStorageManager.delete(owner); + public CompletableFuture deleteItemStorage(UUID owner) { + return this.itemStorageManager.delete(owner); } } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index 3d6f5db48..d8705c49d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -110,14 +110,13 @@ void show(Player player, ParcelSize size) { .placeholder("{ITEMS}", MaterialUtil.format(item.getType())) .player(player.getUniqueId()) .send(); - return; } } items.add(item); } - this.guiManager.deleteItemStorage(player.getUniqueId()); - this.guiManager.saveItemStorage(player.getUniqueId(), items); + this.guiManager.deleteItemStorage(player.getUniqueId()) + .thenAccept(action -> this.guiManager.saveItemStorage(player.getUniqueId(), items)); }); this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(itemStorage -> { diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java index 96e0db9f8..570b48e3a 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -21,11 +21,12 @@ public class ItemStorageManager { public ItemStorageManager(ItemStorageRepository itemStorageRepository) { this.itemStorageRepository = itemStorageRepository; - this.cacheAll(); this.cache = Caffeine.newBuilder() .expireAfterWrite(6, TimeUnit.HOURS) .maximumSize(10_000) .build(); + + this.cacheAll(); } public CompletableFuture> get(UUID parcelId) { diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index da46d3a42..e09a7aa50 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -30,7 +30,6 @@ public LockerManager(LockerRepository lockerRepository, LockerValidationService this.lockerRepository = lockerRepository; this.validationService = validationService; - this.cacheAll(); this.lockersByUUID = Caffeine.newBuilder() .expireAfterAccess(Duration.ofHours(2)) .maximumSize(10_000) @@ -39,6 +38,8 @@ public LockerManager(LockerRepository lockerRepository, LockerValidationService .expireAfterAccess(Duration.ofHours(2)) .maximumSize(10_000) .build(); + + this.cacheAll(); } public CompletableFuture> get(UUID uniqueId) { diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 528eff84b..9e055c186 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -45,7 +45,6 @@ public ParcelServiceImpl( this.parcelContentRepository = parcelContentRepository; this.scheduler = scheduler; - this.cacheAll(); this.parcelsByUuid = Caffeine.newBuilder() .expireAfterAccess(3, TimeUnit.HOURS) .maximumSize(10_000) @@ -60,11 +59,13 @@ public ParcelServiceImpl( .expireAfterAccess(3, TimeUnit.HOURS) .maximumSize(10_000) .build(); + + this.cacheAll(); } @Override public CompletableFuture send(Player sender, Parcel parcel, List items) { - this.parcelRepository.save(parcel).whenComplete((v, throwable) -> { + this.parcelRepository.save(parcel).whenComplete((unused, throwable) -> { if (throwable != null) { this.noticeService.create() .notice(messages -> messages.parcel.cannotSend) @@ -91,7 +92,7 @@ public CompletableFuture update(Parcel updated) { @Override public CompletableFuture delete(CommandSender sender, Parcel parcel) { return this.parcelRepository.delete(parcel) - .thenAccept(v -> { + .thenAccept(unused -> { this.noticeService.create() .notice(messages -> messages.parcel.deleted) .viewer(sender) @@ -155,33 +156,50 @@ public CompletableFuture> get(UUID uuid) { } @Override - public CompletableFuture> getBySender(UUID sender, Page page) { - List cached = List.copyOf(this.parcelsBySender.getIfPresent(sender)); - boolean hasNextPage = cached.size() > page.getLimit(); - if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { - return CompletableFuture.completedFuture(new PageResult<>(cached, false)); + public CompletableFuture> getBySender(UUID receiver, Page page) { + List cached = this.parcelsBySender.getIfPresent(receiver); + + if (cached != null) { + int fromIndex = Math.min(page.getOffset(), cached.size()); + int toIndex = Math.min(page.getOffset() + page.getLimit(), cached.size()); + + List pageItems = cached.subList(fromIndex, toIndex); + boolean hasNextPage = toIndex < cached.size(); + + return CompletableFuture.completedFuture(new PageResult<>(pageItems, hasNextPage)); } - return this.parcelRepository.fetchBySender(sender, page).thenApply(result -> { - result.items().forEach(this::cache); - return result; - }); + + return this.parcelRepository.fetchBySender(receiver, page) + .thenApply(result -> { + result.items().forEach(this::cache); + return result; + }); } @Override public CompletableFuture> getByReceiver(UUID receiver, Page page) { - List cached = List.copyOf(this.parcelsByReceiver.getIfPresent(receiver)); - boolean hasNextPage = cached.size() > page.getLimit(); - if (!cached.isEmpty() && page.getOffset() == 0 && !hasNextPage) { - return CompletableFuture.completedFuture(new PageResult<>(cached, false)); + List cached = this.parcelsByReceiver.getIfPresent(receiver); + + if (cached != null) { + int fromIndex = Math.min(page.getOffset(), cached.size()); + int toIndex = Math.min(page.getOffset() + page.getLimit(), cached.size()); + + List pageItems = cached.subList(fromIndex, toIndex); + boolean hasNextPage = toIndex < cached.size(); + + return CompletableFuture.completedFuture(new PageResult<>(pageItems, hasNextPage)); } - return this.parcelRepository.fetchByReceiver(receiver, page).thenApply(result -> { - result.items().forEach(this::cache); - return result; - }); + + return this.parcelRepository.fetchByReceiver(receiver, page) + .thenApply(result -> { + result.items().forEach(this::cache); + return result; + }); } private void cacheAll() { - this.parcelRepository.fetchAll().thenAccept(optional -> optional.ifPresent(parcels -> parcels.forEach(this::cache))); + this.parcelRepository.fetchAll() + .thenAccept(optional -> optional.ifPresent(parcels -> parcels.forEach(this::cache))); } @Override @@ -221,38 +239,25 @@ public CompletableFuture deleteAll(CommandSender sender, NoticeService not private void cache(Parcel parcel) { this.parcelsByUuid.put(parcel.uuid(), parcel); - List bySender = this.parcelsBySender.getIfPresent(parcel.sender()); - if (bySender == null) { - bySender = new ArrayList<>(); - } + List bySender = this.parcelsBySender.get(parcel.sender(), k -> new ArrayList<>()); bySender.add(parcel); + this.parcelsBySender.put(parcel.sender(), bySender); - List byReceiver = this.parcelsByReceiver.getIfPresent(parcel.receiver()); - if (byReceiver == null) { - byReceiver = new ArrayList<>(); - } + List byReceiver = this.parcelsByReceiver.get(parcel.receiver(), k -> new ArrayList<>()); byReceiver.add(parcel); - - this.parcelsBySender.put(parcel.sender(), bySender); this.parcelsByReceiver.put(parcel.receiver(), byReceiver); } + private void invalidate(Parcel parcel) { this.parcelsByUuid.invalidate(parcel.uuid()); - List bySender = this.parcelsBySender.getIfPresent(parcel.sender()); - if (bySender == null) { - bySender = new ArrayList<>(); - } + List bySender = this.parcelsBySender.get(parcel.sender(), k -> new ArrayList<>()); bySender.remove(parcel); + this.parcelsBySender.put(parcel.sender(), bySender); - List byReceiver = this.parcelsByReceiver.getIfPresent(parcel.receiver()); - if (byReceiver == null) { - byReceiver = new ArrayList<>(); - } + List byReceiver = this.parcelsByReceiver.get(parcel.receiver(), k -> new ArrayList<>()); byReceiver.remove(parcel); - - this.parcelsBySender.put(parcel.sender(), bySender); this.parcelsByReceiver.put(parcel.receiver(), byReceiver); } } diff --git a/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java b/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java index 57486815c..c79921ee4 100644 --- a/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java +++ b/src/main/java/com/eternalcode/parcellockers/shared/validation/ValidationRule.java @@ -5,7 +5,6 @@ public interface ValidationRule { default ValidationRule and(ValidationRule other) { return value -> { - ValidationResult result = this.validate(value); return result.isValid() ? other.validate(value) : result; }; From 8216045ed8a436d42df910506159da0cce149e92 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 6 Sep 2025 17:54:56 +0200 Subject: [PATCH 46/51] ParcelStatus.PENDING -> IN_PROGRESS --- .../gui/implementation/locker/SendingGuiState.java | 2 +- .../java/com/eternalcode/parcellockers/parcel/ParcelStatus.java | 2 +- .../parcellockers/user/controller/LoadUserController.java | 1 + .../parcellockers/database/ParcelRepositoryIntegrationTest.java | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java index 4d9e8abfe..936ea3752 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java @@ -29,7 +29,7 @@ public SendingGuiState() { this.priority = false; this.entryLocker = UUID.randomUUID(); this.destinationLocker = null; - this.status = ParcelStatus.PENDING; + this.status = ParcelStatus.IN_PROGRESS; } } diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelStatus.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelStatus.java index 67f7b1cff..6e8a598f2 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelStatus.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelStatus.java @@ -2,6 +2,6 @@ public enum ParcelStatus { - PENDING, + IN_PROGRESS, DELIVERED } diff --git a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java index adec0e29d..4354ce0bd 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java +++ b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java @@ -18,6 +18,7 @@ public LoadUserController(UserManager userManager, Server server) { } @EventHandler + @Deprecated void onLoad(ServerLoadEvent event) { for (Player player : this.server.getOnlinePlayers()) { this.userManager.create(player.getUniqueId(), player.getName()); diff --git a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java index 0b12f6fcc..3a6a37631 100644 --- a/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java +++ b/src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java @@ -54,7 +54,7 @@ void test() { UUID destinationLocker = UUID.randomUUID(); parcelRepository.save(new Parcel(uuid, sender, "name", "description", true, receiver, - ParcelSize.SMALL, entryLocker, destinationLocker, ParcelStatus.PENDING)); + ParcelSize.SMALL, entryLocker, destinationLocker, ParcelStatus.IN_PROGRESS)); Optional parcel = this.await(parcelRepository.fetchById(uuid)); assertTrue(parcel.isPresent()); From dcaabe07169228da4a664af86836749494e2ac4b Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sat, 6 Sep 2025 18:11:54 +0200 Subject: [PATCH 47/51] Add static import for AdventureUtil.resetItalic --- .../configuration/serializable/ConfigItem.java | 11 ++++++----- .../gui/implementation/locker/ReceiverGui.java | 7 ++++--- .../gui/implementation/locker/SendingGui.java | 5 +++-- .../gui/implementation/remote/ParcelListGui.java | 6 ++++++ .../gui/implementation/remote/SentParcelsGui.java | 7 ++++--- .../validation/LockerConflictDetectionStrategy.java | 1 + 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index 63c3b778e..70123bc73 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -1,8 +1,9 @@ package com.eternalcode.parcellockers.configuration.serializable; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.commons.adventure.AdventureLegacyColorPostProcessor; import com.eternalcode.commons.adventure.AdventureLegacyColorPreProcessor; -import com.eternalcode.commons.adventure.AdventureUtil; import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.components.GuiAction; import dev.triumphteam.gui.guis.GuiItem; @@ -36,8 +37,8 @@ public class ConfigItem implements Serializable, Cloneable { public GuiItem toGuiItem(GuiAction action) { return PaperItemBuilder.from(this.type) - .name(AdventureUtil.resetItalic(this.miniMessage.deserialize(this.name))) - .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(this.miniMessage.deserialize(element))).toList()) + .name(resetItalic(this.miniMessage.deserialize(this.name))) + .lore(this.lore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ENCHANTS) .glow(this.glow) .asGuiItem(action); @@ -45,8 +46,8 @@ public GuiItem toGuiItem(GuiAction action) { public @NotNull PaperItemBuilder toBuilder() { return PaperItemBuilder.from(this.type) - .name(AdventureUtil.resetItalic(this.miniMessage.deserialize(this.name))) - .lore(this.lore.stream().map(element -> AdventureUtil.resetItalic(this.miniMessage.deserialize(element))).toList()) + .name(resetItalic(this.miniMessage.deserialize(this.name))) + .lore(this.lore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ENCHANTS) .glow(this.glow); } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java index f40441d53..7779a9195 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ReceiverGui.java @@ -1,6 +1,7 @@ package com.eternalcode.parcellockers.gui.implementation.locker; -import com.eternalcode.commons.adventure.AdventureUtil; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.gui.GuiManager; @@ -110,8 +111,8 @@ private Supplier toItem(Player player, User user, SkullData skullData, return PaperItemBuilder.skull() .texture(skullData.getTexture()) - .name(this.miniMessage.deserialize(user.name())) - .lore(AdventureUtil.resetItalic(this.miniMessage.deserialize(lore))) + .name(resetItalic(this.miniMessage.deserialize(user.name()))) + .lore(resetItalic(this.miniMessage.deserialize(lore))) .glow(isReceiverSelected) .asGuiItem(event -> { if (isReceiverSelected) { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 3fc81b0d4..92448cb49 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -1,6 +1,7 @@ package com.eternalcode.parcellockers.gui.implementation.locker; -import com.eternalcode.commons.adventure.AdventureUtil; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; @@ -388,7 +389,7 @@ private ItemStack createActiveItem(ConfigItem item, String appendLore) { itemLore.add(appendLore); return item.toBuilder() - .lore(itemLore.stream().map(element -> AdventureUtil.resetItalic(this.miniMessage.deserialize(element))).toList()) + .lore(itemLore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) .glow(true) .build(); } diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 21cf9d4a2..10f03f25d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -66,6 +66,12 @@ public void show(Player player, Page page) { return; } + if (result.items().isEmpty()) { + gui.setItem(22, this.guiSettings.noParcelsItem.toGuiItem()); + this.scheduler.run(() -> gui.open(player)); + return; + } + ConfigItem item = this.guiSettings.parcelItem; List> itemFutures = result.items().stream() diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java index 632347159..d4ff3e16d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/SentParcelsGui.java @@ -1,6 +1,7 @@ package com.eternalcode.parcellockers.gui.implementation.remote; -import com.eternalcode.commons.adventure.AdventureUtil; +import static com.eternalcode.commons.adventure.AdventureUtil.resetItalic; + import com.eternalcode.commons.scheduler.Scheduler; import com.eternalcode.parcellockers.configuration.implementation.PluginConfig.GuiSettings; import com.eternalcode.parcellockers.configuration.serializable.ConfigItem; @@ -74,11 +75,11 @@ public void show(Player player, Page page) { List newLore = processedLore .stream() - .map(line -> AdventureUtil.resetItalic(this.miniMessage.deserialize(line))) + .map(line -> resetItalic(this.miniMessage.deserialize(line))) .toList(); item.lore(newLore); - item.name(AdventureUtil.resetItalic( + item.name(resetItalic( this.miniMessage.deserialize( parcelItem.name().replace("{NAME}", parcel.name()) ) diff --git a/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java index da483faf0..40eeedc0c 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/validation/LockerConflictDetectionStrategy.java @@ -6,6 +6,7 @@ import java.util.Optional; import java.util.UUID; +@FunctionalInterface public interface LockerConflictDetectionStrategy { ValidationResult detectConflicts( From 2b8cecf926d8ee57ea6299d183408f9f5a1193c5 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 7 Sep 2025 09:45:46 +0200 Subject: [PATCH 48/51] Delete unused transformers, change command route --- .../parcellockers/ParcelLockersCommand.java | 4 +-- .../configuration/ConfigService.java | 14 +--------- .../transformer/PositionTransformer.java | 25 ------------------ .../transformer/SoundTransformer.java | 26 ------------------- 4 files changed, 3 insertions(+), 66 deletions(-) delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java delete mode 100644 src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java index 5087b7f02..097706c69 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java @@ -34,8 +34,8 @@ void reload(@Sender CommandSender sender) { .send(); } - @Execute(name = "give") - void give(@Sender Player player) { + @Execute(name = "get") + void get(@Sender Player player) { ItemStack parcelItem = this.config.settings.parcelLockerItem.toGuiItem().getItemStack(); player.getInventory().addItem(parcelItem); } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java index 81f6150d3..ac4bc2a47 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/ConfigService.java @@ -4,18 +4,14 @@ import com.eternalcode.multification.notice.resolver.NoticeResolverDefaults; import com.eternalcode.multification.notice.resolver.NoticeResolverRegistry; import com.eternalcode.multification.okaeri.MultificationSerdesPack; -import com.eternalcode.parcellockers.configuration.transformer.SoundTransformer; import eu.okaeri.configs.ConfigManager; import eu.okaeri.configs.OkaeriConfig; -import eu.okaeri.configs.serdes.OkaeriSerdesPack; -import eu.okaeri.configs.serdes.SerdesRegistry; import eu.okaeri.configs.serdes.commons.SerdesCommons; import eu.okaeri.configs.yaml.bukkit.YamlBukkitConfigurer; import eu.okaeri.configs.yaml.bukkit.serdes.SerdesBukkit; import java.io.File; import java.util.HashSet; import java.util.Set; -import lombok.NonNull; public class ConfigService { @@ -31,8 +27,7 @@ public T create(Class config, File file) { configFile.withConfigurer(configurer, new SerdesCommons(), new SerdesBukkit(), - new MultificationSerdesPack(noticeRegistry), - new DefaultSerdesPack() + new MultificationSerdesPack(noticeRegistry) ); configFile.withBindFile(file); @@ -50,11 +45,4 @@ public void reload() { config.load(); } } - - private static class DefaultSerdesPack implements OkaeriSerdesPack { - @Override - public void register(@NonNull SerdesRegistry registry) { - registry.register(new SoundTransformer()); - } - } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java b/src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java deleted file mode 100644 index b3f3aa2f7..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/transformer/PositionTransformer.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.eternalcode.parcellockers.configuration.transformer; - -import com.eternalcode.parcellockers.shared.Position; -import eu.okaeri.configs.schema.GenericsPair; -import eu.okaeri.configs.serdes.BidirectionalTransformer; -import eu.okaeri.configs.serdes.SerdesContext; -import org.jetbrains.annotations.NotNull; - -public class PositionTransformer extends BidirectionalTransformer { - - @Override - public GenericsPair getPair() { - return this.genericsPair(Position.class, String.class); - } - - @Override - public String leftToRight(@NotNull Position position, @NotNull SerdesContext context) { - return position.toString(); - } - - @Override - public Position rightToLeft(@NotNull String data, @NotNull SerdesContext context) { - return Position.parse(data); - } -} diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java b/src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java deleted file mode 100644 index 93a99abf6..000000000 --- a/src/main/java/com/eternalcode/parcellockers/configuration/transformer/SoundTransformer.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.eternalcode.parcellockers.configuration.transformer; - -import eu.okaeri.configs.schema.GenericsPair; -import eu.okaeri.configs.serdes.BidirectionalTransformer; -import eu.okaeri.configs.serdes.SerdesContext; -import lombok.NonNull; -import org.bukkit.Sound; -import org.jetbrains.annotations.NotNull; - -public class SoundTransformer extends BidirectionalTransformer { - - @Override - public GenericsPair getPair() { - return this.genericsPair(Sound.class, String.class); - } - - @Override - public String leftToRight(@NotNull Sound data, @NonNull SerdesContext serdesContext) { - return data.name(); - } - - @Override - public Sound rightToLeft(@NonNull String data, @NonNull SerdesContext serdesContext) { - return Sound.valueOf(data); - } -} From 6c0e15ac28c041a982ab292039c9af1d9d153d53 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Sun, 7 Sep 2025 14:47:09 +0200 Subject: [PATCH 49/51] Add ItemStorage gui preview --- .../ParcelLockersLibraryLoader.java | 1 + .../implementation/MessageConfig.java | 2 + .../implementation/PluginConfig.java | 10 ++- .../serializable/ConfigItem.java | 16 ++--- .../content/ParcelContentManager.java | 5 +- .../implementation/locker/CollectionGui.java | 2 +- .../implementation/locker/ItemStorageGui.java | 62 ++++++++++--------- .../gui/implementation/locker/SendingGui.java | 38 +++++++++++- .../itemstorage/ItemStorageManager.java | 8 +-- .../parcellockers/locker/LockerManager.java | 1 - .../parcel/ParcelServiceImpl.java | 3 +- 11 files changed, 93 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java index a8dfff5bc..5364c949f 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersLibraryLoader.java @@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull; public class ParcelLockersLibraryLoader implements PluginLoader { + @Override public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) { MavenLibraryResolver resolver = new MavenLibraryResolver(); diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 2b2ebba4e..7beae122c 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -10,6 +10,8 @@ @Header({ "# This file contains messages used by the ParcelLockers plugin.", "# You can customize these messages to fit your server's theme or language.", + "# You may use legacy color codes with '&' (e.g., &a for green, &c for red)", + "# MiniMessage formatting is also supported for advanced text styling." }) public class MessageConfig extends OkaeriConfig { diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index dd69e91b0..74d66cd5c 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -14,9 +14,11 @@ "# ParcelLockers plugin configuration file.", "", "# You can change the settings here to customize the plugin behavior or appearance.", - "# If you want to reload the configuration, you can do it using the '/parcellockers reload' command." + "# If you want to reload the configuration, you can do it using the '/parcellockers reload' command.", + "# Both legacy color codes and MiniMessage formatting are supported in messages and GUI titles." }) public class PluginConfig extends OkaeriConfig { + public Settings settings = new Settings(); @Comment({ "", "# The plugin GUI settings." }) @@ -208,6 +210,12 @@ public static class GuiSettings extends OkaeriConfig { .lore(List.of("&6ยป &eClick to add/remove items from this parcel.")) .type(Material.CHEST); + @Comment({ "", "# The first line of lore when the parcel item storage contains items."}) + public String parcelStorageItemsSetLine = "&6โ€บ &eCurrent items:"; + + @Comment({ "", "# The line of lore containing the item name and amount when the parcel item storage contains items."}) + public String parcelStorageItemLine = "&6 - &e{AMOUNT}x {ITEM}"; + @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelNameItem = new ConfigItem() .name("&4โœŽ &cParcel name") diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index 70123bc73..edd3452bc 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -18,7 +18,6 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; @Getter @Setter @@ -35,16 +34,7 @@ public class ConfigItem implements Serializable, Cloneable { private List lore = List.of(); private boolean glow = false; - public GuiItem toGuiItem(GuiAction action) { - return PaperItemBuilder.from(this.type) - .name(resetItalic(this.miniMessage.deserialize(this.name))) - .lore(this.lore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) - .flags(ItemFlag.HIDE_ENCHANTS) - .glow(this.glow) - .asGuiItem(action); - } - - public @NotNull PaperItemBuilder toBuilder() { + public PaperItemBuilder toBuilder() { return PaperItemBuilder.from(this.type) .name(resetItalic(this.miniMessage.deserialize(this.name))) .lore(this.lore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) @@ -56,6 +46,10 @@ public GuiItem toGuiItem() { return this.toBuilder().asGuiItem(); } + public GuiItem toGuiItem(GuiAction action) { + return this.toBuilder().asGuiItem(action); + } + public ItemStack toItemStack() { return this.toBuilder().build(); } diff --git a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java index a51c7fe8f..2a4573ddd 100644 --- a/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java +++ b/src/main/java/com/eternalcode/parcellockers/content/ParcelContentManager.java @@ -12,7 +12,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.inventory.ItemStack; -// TODO: Use CompletableFuture wherever possible public class ParcelContentManager { private final Cache cache; @@ -59,8 +58,8 @@ public CompletableFuture delete(UUID parcel) { }); } - public void deleteAll(CommandSender sender, NoticeService noticeService) { - this.contentRepository.deleteAll().thenAccept(deleted -> { + public CompletableFuture deleteAll(CommandSender sender, NoticeService noticeService) { + return this.contentRepository.deleteAll().thenAccept(deleted -> { noticeService.create() .viewer(sender) .notice(messages -> messages.admin.deletedContents) diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 168122c81..7d9c28d6d 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -75,7 +75,7 @@ public void show(Player player, Page page) { result.items().stream() .filter(parcel -> parcel.status() == ParcelStatus.DELIVERED) .map(parcel -> this.createParcelItemAsync(parcel, parcelItem, player, refresher)) - .collect(CompletableFutures.joinList()) // ๐ŸŽฏ Spotify magic! + .collect(CompletableFutures.joinList()) .thenAccept(suppliers -> { for (Supplier supplier : suppliers) { refresher.addItem(supplier); diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java index d8705c49d..1ecc64adf 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/ItemStorageGui.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.stream.IntStream; import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -52,18 +51,6 @@ void show(Player player, ParcelSize size) { GuiItem backgroundItem = this.guiSettings.mainGuiBackgroundItem.toGuiItem(event -> event.setCancelled(true)); - GuiItem confirmItem = this.guiSettings.confirmItemsItem.toGuiItem(event -> { - event.setCancelled(true); - new SendingGui( - this.scheduler, - this.guiSettings, - this.miniMessage, - this.noticeService, - this.guiManager, - this.skullAPI, - this.state - ).show(player); - }); switch (size) { case SMALL -> gui = Gui.storage() @@ -81,16 +68,20 @@ void show(Player player, ParcelSize size) { default -> throw new IllegalStateException("Unexpected value: " + size); } + + GuiItem confirmItem = this.guiSettings.confirmItemsItem.toGuiItem(event -> { + event.setCancelled(true); + gui.close(player); + }); + // Set background items and confirm/cancel items + close gui action IntStream.rangeClosed(1, 9).forEach(i -> gui.setItem(gui.getRows(), i, backgroundItem)); gui.setItem(gui.getRows(), 5, confirmItem); gui.setCloseGuiAction(event -> { ItemStack[] contents = gui.getInventory().getContents(); - // todo fix items not saving after clicking the confirm button on the gui - // when no new items were added - List items = new ArrayList<>(); + List illegalItems = new ArrayList<>(); for (int i = 0; i < contents.length - 9; i++) { ItemStack item = contents[i]; @@ -99,24 +90,35 @@ void show(Player player, ParcelSize size) { continue; } - // todo fix duplication glitch with illegal items - // if the item is illegal, give it back to the player and do not save it - for (Material type : this.guiSettings.illegalItems) { - if (item.getType() == type) { - ItemUtil.giveItem(player, item); - gui.removeItem(item); - this.noticeService.create() - .notice(messages -> messages.parcel.illegalItem) - .placeholder("{ITEMS}", MaterialUtil.format(item.getType())) - .player(player.getUniqueId()) - .send(); - } + if (this.guiSettings.illegalItems.contains(item.getType())) { + illegalItems.add(item); + } else { + items.add(item); } - items.add(item); + } + + for (ItemStack illegalItem : illegalItems) { + ItemUtil.giveItem(player, illegalItem); + this.noticeService.create() + .notice(messages -> messages.parcel.illegalItem) + .placeholder("{ITEMS}", MaterialUtil.format(illegalItem.getType())) + .player(player.getUniqueId()) + .send(); } this.guiManager.deleteItemStorage(player.getUniqueId()) - .thenAccept(action -> this.guiManager.saveItemStorage(player.getUniqueId(), items)); + .thenAccept(action -> { + this.guiManager.saveItemStorage(player.getUniqueId(), items); + new SendingGui( + this.scheduler, + this.guiSettings, + this.miniMessage, + this.noticeService, + this.guiManager, + this.skullAPI, + this.state + ).show(player); + }); }); this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(itemStorage -> { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 92448cb49..50c0e1150 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -11,6 +11,7 @@ import com.eternalcode.parcellockers.parcel.Parcel; import com.eternalcode.parcellockers.parcel.ParcelSize; import com.eternalcode.parcellockers.shared.ScheduledGuiAction; +import com.eternalcode.parcellockers.util.MaterialUtil; import de.rapha149.signgui.SignGUI; import de.rapha149.signgui.exception.SignGUIVersionException; import dev.rollczi.liteskullapi.SkullAPI; @@ -140,7 +141,7 @@ public void show(Player player) { descriptionSignGui = SignGUI.builder() .setColor(DyeColor.BLACK) .setType(Material.OAK_SIGN) - .setLine(0, "Enter parcel name:") + .setLine(0, "Enter parcel description:") .setHandler((p, result) -> { String description = result.getLineWithoutColor(1); @@ -172,7 +173,8 @@ public void show(Player player) { } }); - GuiItem storageItem = this.guiSettings.parcelStorageItem.toGuiItem(event -> { + ConfigItem parcelStorageItem = this.guiSettings.parcelStorageItem.clone(); + GuiItem storageItem = parcelStorageItem.toGuiItem(event -> { ItemStorageGui storageGUI = new ItemStorageGui( this.scheduler, this.guiSettings, @@ -288,6 +290,7 @@ public void show(Player player) { this.updateNameItem(); this.updateDescriptionItem(); + this.updateStorageItem(player); if (this.state.receiver() != null) { this.guiManager.getUser(this.state.receiver()).thenAccept(userOptional -> userOptional.ifPresent(user -> this.updateReceiverItem(player, user.name(), false))); @@ -384,6 +387,27 @@ public void updateDestinationItem(Player player, String destinationLockerDesc, b this.gui.updateItem(DESTINATION_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelDestinationLockerItem, line)); } + public void updateStorageItem(Player player) { + this.guiManager.getItemStorage(player.getUniqueId()).thenAccept(result -> { + List items = result.items(); + if (items.isEmpty()) { + this.gui.updateItem(STORAGE_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelStorageItem, List.of())); + return; + } + + List lore = new ArrayList<>(); + lore.add(this.guiSettings.parcelStorageItemsSetLine); + + for (ItemStack item : items) { + lore.add(this.guiSettings.parcelStorageItemLine + .replace("{ITEM}", MaterialUtil.format(item.getType())) + .replace("{AMOUNT}", Integer.toString(item.getAmount())) + ); + } + this.gui.updateItem(STORAGE_ITEM_SLOT, this.createActiveItem(this.guiSettings.parcelStorageItem, lore)); + }); + } + private ItemStack createActiveItem(ConfigItem item, String appendLore) { List itemLore = new ArrayList<>(item.lore()); itemLore.add(appendLore); @@ -394,4 +418,14 @@ private ItemStack createActiveItem(ConfigItem item, String appendLore) { .build(); } + private ItemStack createActiveItem(ConfigItem item, List appendLore) { + List itemLore = new ArrayList<>(item.lore()); + itemLore.addAll(appendLore); + + return item.toBuilder() + .lore(itemLore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) + .glow(true) + .build(); + } + } diff --git a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java index 570b48e3a..2129b3c5d 100644 --- a/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java +++ b/src/main/java/com/eternalcode/parcellockers/itemstorage/ItemStorageManager.java @@ -45,13 +45,13 @@ public ItemStorage getOrCreate(UUID owner, List items) { } public ItemStorage create(UUID owner, List items) { - ItemStorage content = new ItemStorage(owner, items); + ItemStorage itemStorage = new ItemStorage(owner, items); if (this.cache.getIfPresent(owner) != null) { throw new IllegalStateException("ItemStorage for owner " + owner + " already exists. Use ItemStorageManager#getOrCreate method instead."); } - this.cache.put(owner, content); - this.itemStorageRepository.save(content); - return content; + this.cache.put(owner, itemStorage); + this.itemStorageRepository.save(itemStorage); + return itemStorage; } private void cacheAll() { diff --git a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java index e09a7aa50..641547c72 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/LockerManager.java @@ -17,7 +17,6 @@ import java.util.function.Function; import org.bukkit.command.CommandSender; -// TODO: Implement validation public class LockerManager { private final LockerRepository lockerRepository; diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 9e055c186..3d1c09b6d 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -65,7 +65,7 @@ public ParcelServiceImpl( @Override public CompletableFuture send(Player sender, Parcel parcel, List items) { - this.parcelRepository.save(parcel).whenComplete((unused, throwable) -> { + return this.parcelRepository.save(parcel).whenComplete((unused, throwable) -> { if (throwable != null) { this.noticeService.create() .notice(messages -> messages.parcel.cannotSend) @@ -80,7 +80,6 @@ public CompletableFuture send(Player sender, Parcel parcel, List Date: Thu, 11 Sep 2025 17:41:28 +0200 Subject: [PATCH 50/51] Add validation for users, more nullchecks in SendingGui and SendingGuiState, add comment to LoadUserController, improve CollectionGui empty result handling --- .../parcellockers/ParcelLockers.java | 5 +- .../parcellockers/ParcelLockersCommand.java | 4 +- .../implementation/MessageConfig.java | 8 ++ .../implementation/PluginConfig.java | 8 +- .../implementation/locker/CollectionGui.java | 11 +- .../gui/implementation/locker/SendingGui.java | 16 +++ .../locker/SendingGuiState.java | 2 +- .../implementation/remote/ParcelListGui.java | 2 +- .../parcellockers/user/UserManager.java | 4 +- .../parcellockers/user/UserManagerImpl.java | 44 +++++--- .../user/controller/LoadUserController.java | 2 + .../UserConflictDetectionStrategy.java | 15 +++ .../validation/UserValidationService.java | 16 +++ .../user/validation/UserValidator.java | 104 ++++++++++++++++++ 14 files changed, 216 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/eternalcode/parcellockers/user/validation/UserConflictDetectionStrategy.java create mode 100644 src/main/java/com/eternalcode/parcellockers/user/validation/UserValidationService.java create mode 100644 src/main/java/com/eternalcode/parcellockers/user/validation/UserValidator.java diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java index eb8bf514d..8dcb4358b 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockers.java @@ -43,6 +43,8 @@ import com.eternalcode.parcellockers.user.controller.PrepareUserController; import com.eternalcode.parcellockers.user.repository.UserRepository; import com.eternalcode.parcellockers.user.repository.UserRepositoryOrmLite; +import com.eternalcode.parcellockers.user.validation.UserValidationService; +import com.eternalcode.parcellockers.user.validation.UserValidator; import dev.rollczi.litecommands.LiteCommands; import dev.rollczi.litecommands.adventure.LiteAdventureExtension; import dev.rollczi.litecommands.annotations.LiteCommandsAnnotations; @@ -116,7 +118,8 @@ public void onEnable() { scheduler ); - UserManager userManager = new UserManagerImpl(userRepository); + UserValidationService userValidationService = new UserValidator(); + UserManager userManager = new UserManagerImpl(userRepository, userValidationService); LockerValidationService lockerValidationService = new LockerValidator(); LockerManager lockerManager = new LockerManager(lockerRepository, lockerValidationService); ParcelContentManager parcelContentManager = new ParcelContentManager(parcelContentRepository); diff --git a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java index 097706c69..c60409b07 100644 --- a/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java +++ b/src/main/java/com/eternalcode/parcellockers/ParcelLockersCommand.java @@ -36,7 +36,7 @@ void reload(@Sender CommandSender sender) { @Execute(name = "get") void get(@Sender Player player) { - ItemStack parcelItem = this.config.settings.parcelLockerItem.toGuiItem().getItemStack(); - player.getInventory().addItem(parcelItem); + ItemStack lockerItem = this.config.settings.parcelLockerItem.toGuiItem().getItemStack(); + player.getInventory().addItem(lockerItem); } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java index 7beae122c..87c96281f 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/MessageConfig.java @@ -84,10 +84,18 @@ public static class ParcelMessages extends OkaeriConfig { .chat("&2โœ” &aParcel collected successfully.") .sound(Sound.ENTITY_PLAYER_LEVELUP.key()) .build(); + public Notice nameNotSet = Notice.builder() + .chat("&4โœ˜ &cThe parcel name is not set!") + .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) + .build(); public Notice receiverNotSet = Notice.builder() .chat("&4โœ˜ &cThe parcel receiver is not set!") .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) .build(); + public Notice destinationNotSet = Notice.builder() + .chat("&4โœ˜ &cThe parcel destination locker is not set!") + .sound(Sound.ENTITY_ENDERMAN_AMBIENT.key()) + .build(); public Notice illegalItem = Notice.builder() .chat("&4โœ˜ &cThe parcel contains illegal items that cannot be sent. ({ITEMS})") .build(); diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java index 74d66cd5c..26db6c87a 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java @@ -54,10 +54,10 @@ public static class Settings extends OkaeriConfig { .lore(List.of("&bPlace to create a parcel locker.")); @Comment({"", "# Standard parcel sending duration"}) - public Duration parcelSendDuration = Duration.ofSeconds(5); + public Duration parcelSendDuration = Duration.ofMinutes(30); @Comment({"", "# Parcel sending duration for priority parcels"}) - public Duration priorityParcelSendDuration = Duration.ofSeconds(2); + public Duration priorityParcelSendDuration = Duration.ofSeconds(30); } public static class GuiSettings extends OkaeriConfig { @@ -211,10 +211,10 @@ public static class GuiSettings extends OkaeriConfig { .type(Material.CHEST); @Comment({ "", "# The first line of lore when the parcel item storage contains items."}) - public String parcelStorageItemsSetLine = "&6โ€บ &eCurrent items:"; + public String parcelStorageItemsSetLine = " &6โ€บ &eCurrent items:"; @Comment({ "", "# The line of lore containing the item name and amount when the parcel item storage contains items."}) - public String parcelStorageItemLine = "&6 - &e{AMOUNT}x {ITEM}"; + public String parcelStorageItemLine = " &6- &e{AMOUNT}x {ITEM}"; @Comment({ "", "# The item of the parcel name button" }) public ConfigItem parcelNameItem = new ConfigItem() diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java index 7d9c28d6d..8985f8625 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java @@ -77,6 +77,11 @@ public void show(Player player, Page page) { .map(parcel -> this.createParcelItemAsync(parcel, parcelItem, player, refresher)) .collect(CompletableFutures.joinList()) .thenAccept(suppliers -> { + if (suppliers.isEmpty()) { + gui.setItem(22, this.guiSettings.noParcelsItem.toGuiItem()); + this.scheduler.run(() -> gui.open(player)); + return; + } for (Supplier supplier : suppliers) { refresher.addItem(supplier); } @@ -102,7 +107,11 @@ private void setupStaticItems(Player player, PaginatedGui gui) { } private CompletableFuture> createParcelItemAsync( - Parcel parcel, ConfigItem parcelItem, Player player, PaginatedGuiRefresher refresher) { + Parcel parcel, + ConfigItem parcelItem, + Player player, + PaginatedGuiRefresher refresher + ) { return PlaceholderUtil.replaceParcelPlaceholdersAsync(parcel, parcelItem.lore(), this.guiManager) .thenApply(processedLore -> () -> { diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java index 50c0e1150..7417b0a5f 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGui.java @@ -206,6 +206,14 @@ public void show(Player player) { return; } + if (this.state.parcelName() == null || this.state.parcelName().isEmpty()) { + this.noticeService.create() + .notice(messages -> messages.parcel.nameNotSet) + .player(player.getUniqueId()) + .send(); + return; + } + if (this.state.receiver() == null) { this.noticeService.create() .notice(messages -> messages.parcel.receiverNotSet) @@ -214,6 +222,14 @@ public void show(Player player) { return; } + if (this.state.destinationLocker() == null) { + this.noticeService.create() + .notice(messages -> messages.parcel.destinationNotSet) + .player(player.getUniqueId()) + .send(); + return; + } + Parcel parcel = new Parcel( UUID.randomUUID(), player.getUniqueId(), diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java index 936ea3752..259c25a0e 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java @@ -23,7 +23,7 @@ public class SendingGuiState { public SendingGuiState() { this.parcelName = null; - this.parcelDescription = null; + this.parcelDescription = ""; this.size = ParcelSize.SMALL; this.receiver = null; this.priority = false; diff --git a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java index 10f03f25d..8ef907501 100644 --- a/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java +++ b/src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java @@ -84,7 +84,7 @@ public void show(Player player, Page page) { .toList(); parcelItem.lore(newLore); - parcelItem.name(this.miniMessage.deserialize(item.name().replace("{NAME}", parcel.name()))); + parcelItem.name(resetItalic(this.miniMessage.deserialize(item.name().replace("{NAME}", parcel.name())))); return parcelItem.asGuiItem(); })) diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java index 6b7e06391..e7daaaf24 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManager.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManager.java @@ -8,9 +8,9 @@ public interface UserManager { - User create(UUID uuid, String name); + CompletableFuture create(UUID uuid, String name); - User getOrCreate(UUID uuid, String name); + CompletableFuture getOrCreate(UUID uuid, String name); CompletableFuture> get(String username); diff --git a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java index d85a65607..3b245c6d6 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/user/UserManagerImpl.java @@ -2,7 +2,9 @@ import com.eternalcode.parcellockers.shared.Page; import com.eternalcode.parcellockers.shared.PageResult; +import com.eternalcode.parcellockers.shared.validation.ValidationResult; import com.eternalcode.parcellockers.user.repository.UserRepository; +import com.eternalcode.parcellockers.user.validation.UserValidationService; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import java.util.Optional; @@ -13,12 +15,14 @@ public class UserManagerImpl implements UserManager { private final UserRepository userRepository; + private final UserValidationService validationService; private final Cache usersByUUID; private final Cache usersByName; - public UserManagerImpl(UserRepository userRepository) { + public UserManagerImpl(UserRepository userRepository, UserValidationService validationService) { this.userRepository = userRepository; + this.validationService = validationService; this.usersByUUID = Caffeine.newBuilder() .expireAfterAccess(2, TimeUnit.HOURS) .maximumSize(10_000) @@ -52,17 +56,17 @@ public CompletableFuture> get(String username) { } @Override - public User getOrCreate(UUID uuid, String name) { + public CompletableFuture getOrCreate(UUID uuid, String name) { User userByUUID = this.usersByUUID.getIfPresent(uuid); if (userByUUID != null) { - return userByUUID; + return CompletableFuture.completedFuture(userByUUID); } User userByName = this.usersByName.getIfPresent(name); if (userByName != null) { - return userByName; + return CompletableFuture.completedFuture(userByName); } return this.create(uuid, name); @@ -74,16 +78,30 @@ public CompletableFuture> getPage(Page page) { } @Override - public User create(UUID uuid, String name) { - if (this.usersByUUID.getIfPresent(uuid) != null || this.usersByName.getIfPresent(name) != null) { - throw new IllegalStateException("User already exists"); - } + public CompletableFuture create(UUID uuid, String name) { + return CompletableFuture.supplyAsync(() -> { + ValidationResult validation = this.validationService.validateCreateParameters(uuid, name); + + if (!validation.isValid()) { + throw new IllegalArgumentException("Invalid parameters: " + validation.errorMessage()); + } + + Optional existingByUUID = Optional.ofNullable(this.usersByUUID.get(uuid, uniqueId -> null)); + Optional existingByName = Optional.ofNullable(this.usersByName.get(name, username -> null)); + + ValidationResult conflictCheck = this.validationService.validateNoConflicts( + uuid, name, existingByUUID, existingByName); + + if (!conflictCheck.isValid()) { + throw new IllegalStateException(conflictCheck.errorMessage()); + } - User user = new User(uuid, name); - this.usersByUUID.put(uuid, user); - this.usersByName.put(name, user); - this.userRepository.save(user); + User user = new User(uuid, name); + this.usersByUUID.put(uuid, user); + this.usersByName.put(name, user); + this.userRepository.save(user); - return user; + return user; + }); } } diff --git a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java index 4354ce0bd..a6e295469 100644 --- a/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java +++ b/src/main/java/com/eternalcode/parcellockers/user/controller/LoadUserController.java @@ -17,6 +17,8 @@ public LoadUserController(UserManager userManager, Server server) { this.server = server; } + // Deprecated: This event handler is no longer recommended for loading users. + // Use PlayerJoinEvent to handle user creation when players join the server instead. @EventHandler @Deprecated void onLoad(ServerLoadEvent event) { diff --git a/src/main/java/com/eternalcode/parcellockers/user/validation/UserConflictDetectionStrategy.java b/src/main/java/com/eternalcode/parcellockers/user/validation/UserConflictDetectionStrategy.java new file mode 100644 index 000000000..f444c99cc --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/user/validation/UserConflictDetectionStrategy.java @@ -0,0 +1,15 @@ +package com.eternalcode.parcellockers.user.validation; + +import com.eternalcode.parcellockers.shared.validation.ValidationResult; +import com.eternalcode.parcellockers.user.User; +import java.util.Optional; +import java.util.UUID; + +@FunctionalInterface +public interface UserConflictDetectionStrategy { + + ValidationResult detectConflicts( + UUID uuid, String username, + Optional existingByUUID, + Optional existingByUsername); +} diff --git a/src/main/java/com/eternalcode/parcellockers/user/validation/UserValidationService.java b/src/main/java/com/eternalcode/parcellockers/user/validation/UserValidationService.java new file mode 100644 index 000000000..0c6284ca4 --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/user/validation/UserValidationService.java @@ -0,0 +1,16 @@ +package com.eternalcode.parcellockers.user.validation; + +import com.eternalcode.parcellockers.shared.validation.ValidationResult; +import com.eternalcode.parcellockers.user.User; +import java.util.Optional; +import java.util.UUID; + +public interface UserValidationService { + + ValidationResult validateCreateParameters(UUID uniqueId, String username); + + ValidationResult validateNoConflicts( + UUID uuid, String username, + Optional existingByUUID, + Optional existingByUsername); +} diff --git a/src/main/java/com/eternalcode/parcellockers/user/validation/UserValidator.java b/src/main/java/com/eternalcode/parcellockers/user/validation/UserValidator.java new file mode 100644 index 000000000..1e28542cb --- /dev/null +++ b/src/main/java/com/eternalcode/parcellockers/user/validation/UserValidator.java @@ -0,0 +1,104 @@ +package com.eternalcode.parcellockers.user.validation; + +import com.eternalcode.parcellockers.shared.validation.ValidationResult; +import com.eternalcode.parcellockers.shared.validation.ValidationRule; +import com.eternalcode.parcellockers.user.User; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public final class UserValidator implements UserValidationService { + + private final List> creationRules; + private final UserConflictDetectionStrategy conflictStrategy; + + public UserValidator() { + this.creationRules = List.of( + this::validateUUID, + this::validateName + ); + + this.conflictStrategy = this::defaultConflictDetection; + } + + public UserValidator(List> creationRules, + UserConflictDetectionStrategy conflictStrategy) { + this.creationRules = creationRules; + this.conflictStrategy = conflictStrategy; + } + + @Override + public ValidationResult validateCreateParameters(UUID uniqueId, String name) { + CreateUserRequest request = new CreateUserRequest(uniqueId, name); + + return this.creationRules.stream() + .reduce(ValidationRule::and) + .map(rule -> rule.validate(request)) + .orElse(ValidationResult.valid()); + } + + @Override + public ValidationResult validateNoConflicts(UUID uniqueId, String username, + Optional existingByUUID, + Optional existingByUsername) { + return this.conflictStrategy.detectConflicts(uniqueId, username, existingByUUID, existingByUsername); + } + + private ValidationResult validateUUID(CreateUserRequest request) { + return request.uniqueId() != null ? + ValidationResult.valid() : + ValidationResult.invalid("UUID cannot be null"); + } + + private ValidationResult validateName(CreateUserRequest request) { + return request.name() != null && !request.name().trim().isEmpty() ? + ValidationResult.valid() : + ValidationResult.invalid("Name cannot be empty"); + } + + private ValidationResult defaultConflictDetection( + UUID uniqueId, String username, + Optional existingByUUID, + Optional existingByUsername) { + return existingByUUID.flatMap(byUUID -> existingByUsername.map(byUsername -> this.validateBothExist(uniqueId, username, byUUID, byUsername))) + .orElseGet(() -> existingByUUID + .map(user -> this.validateUUIDConflict(uniqueId, username, user)) + .orElseGet(() -> existingByUsername + .map(user -> this.validateUsernameConflict(uniqueId, username, user)) + .orElse(ValidationResult.valid()))); + } + + private ValidationResult validateBothExist(UUID uniqueId, String username, + User byUUID, User byUsername) { + if (!byUUID.equals(byUsername)) { + return ValidationResult.invalid(String.format("Conflicting users found. UUID %s vs username %s", + uniqueId, username)); + } + + return ValidationResult.valid(); + } + + private ValidationResult validateUUIDConflict(UUID uniqueId, String username, User user) { + if (!user.name().equals(username)) { + return ValidationResult.invalid(String.format("User with UUID %s exists at different username: %s", + uniqueId, username)); + } + + return ValidationResult.valid(); + } + + private ValidationResult validateUsernameConflict(UUID uniqueId, String username, User user) { + if (!user.uuid().equals(uniqueId)) { + return ValidationResult.invalid(String.format("User with username %s exists at different UUID: %s", + username, uniqueId)); + } + + return ValidationResult.valid(); + } + + private record CreateUserRequest( + UUID uniqueId, + String name + ) { + } +} From 32b1930e91a1ee73515b44da4268a579f6a54077 Mon Sep 17 00:00:00 2001 From: Jakubk15 <77227023+Jakubk15@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:23:59 +0200 Subject: [PATCH 51/51] adjust to AI requested changes --- build.gradle.kts | 3 +-- .../configuration/serializable/ConfigItem.java | 8 +++++--- .../controller/LockerPlaceController.java | 2 +- .../locker/prompt/LockerPlacePrompt.java | 18 ++++++++++++++++-- .../parcel/ParcelServiceImpl.java | 1 - 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7e42df09b..532063487 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -130,8 +130,7 @@ tasks { val relocationPrefix = "com.eternalcode.parcellockers.libs" listOf( - "org.bstats", -// "dev.triumphteam" + "org.bstats" ).forEach { relocate(it, "$relocationPrefix.$it") } } } diff --git a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java index edd3452bc..54833a4ba 100644 --- a/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java +++ b/src/main/java/com/eternalcode/parcellockers/configuration/serializable/ConfigItem.java @@ -7,6 +7,7 @@ import dev.triumphteam.gui.builder.item.PaperItemBuilder; import dev.triumphteam.gui.components.GuiAction; import dev.triumphteam.gui.guis.GuiItem; +import eu.okaeri.configs.annotation.Exclude; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -24,7 +25,8 @@ @Accessors(fluent = true) public class ConfigItem implements Serializable, Cloneable { - private final transient MiniMessage miniMessage = MiniMessage.builder() + @Exclude + private static final MiniMessage MINI_MESSAGE = MiniMessage.builder() .preProcessor(new AdventureLegacyColorPreProcessor()) .postProcessor(new AdventureLegacyColorPostProcessor()) .build(); @@ -36,8 +38,8 @@ public class ConfigItem implements Serializable, Cloneable { public PaperItemBuilder toBuilder() { return PaperItemBuilder.from(this.type) - .name(resetItalic(this.miniMessage.deserialize(this.name))) - .lore(this.lore.stream().map(element -> resetItalic(this.miniMessage.deserialize(element))).toList()) + .name(resetItalic(MINI_MESSAGE.deserialize(this.name))) + .lore(this.lore.stream().map(element -> resetItalic(MINI_MESSAGE.deserialize(element))).toList()) .flags(ItemFlag.HIDE_ENCHANTS) .glow(this.glow); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java index d2b526ff0..561781add 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/controller/LockerPlaceController.java @@ -110,7 +110,7 @@ public void onBlockPlace(BlockPlaceEvent event) { .withModality(false) .withLocalEcho(false) .withTimeout(60) - .withFirstPrompt(new LockerPlacePrompt()); + .withFirstPrompt(new LockerPlacePrompt(this.noticeService)); player.beginConversation(conversationFactory.buildConversation(player)); } diff --git a/src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java b/src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java index 487c586d2..28dd684d4 100644 --- a/src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java +++ b/src/main/java/com/eternalcode/parcellockers/locker/prompt/LockerPlacePrompt.java @@ -1,13 +1,21 @@ package com.eternalcode.parcellockers.locker.prompt; -import org.bukkit.ChatColor; +import com.eternalcode.parcellockers.notification.NoticeService; +import org.apache.commons.lang3.StringUtils; import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.Prompt; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class LockerPlacePrompt implements Prompt { + private final NoticeService noticeService; + + public LockerPlacePrompt(NoticeService noticeService) { + this.noticeService = noticeService; + } + @Override public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) { context.setSessionData("description", input); @@ -17,7 +25,13 @@ public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String @NotNull @Override public String getPromptText(@NotNull ConversationContext context) { - return ChatColor.translateAlternateColorCodes('&', "&6โ†ต &eEnter a name for the parcel locker:"); + if (context.getForWhom() instanceof Player player) { + this.noticeService.create() + .player(player.getUniqueId()) + .notice(messages -> messages.locker.descriptionPrompt) + .send(); + } + return StringUtils.EMPTY; } @Override diff --git a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java index 3d1c09b6d..a072ab1ca 100644 --- a/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java +++ b/src/main/java/com/eternalcode/parcellockers/parcel/ParcelServiceImpl.java @@ -204,7 +204,6 @@ private void cacheAll() { @Override public CompletableFuture delete(UUID uuid) { return this.parcelRepository.delete(uuid).thenApply(deleted -> { - this.parcelsByUuid.invalidate(uuid); if (deleted > 0) { Parcel cached = this.parcelsByUuid.getIfPresent(uuid); if (cached != null) {