diff --git a/.gitignore b/.gitignore index ec61117..fd2ad84 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ gradle-app.setting .classpath run -.idea \ No newline at end of file +.idea +.gradle +build \ No newline at end of file diff --git a/README.md b/README.md index f96b6e0..58feefa 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,2 @@ - - - # NoDropX -**Give no drop items!** - -The plugin will allow you to create items that will not drop out of your inventory at death! - -Give an no drop item: `/nodrop give [player] [item] (count)`
-Check all plugin commands: https://github.com/iRedTea/NoDropX/wiki/Commands
-Plugin wiki: https://github.com/iRedTea/NoDropX/wiki
-SpigotMC resource: https://www.spigotmc.org/resources/nodropx.111485/ - -**Features** -- Supports HEX Colors (MiniMessages and MD5 ChatColor) -- Supports all versions from 1.12.2 to 1.20.1 (Spigot/Paper) -- No drop items storage: `/nodrop gui` -- Fully customization -- Items that protect other slots from death -- Developer API -- Mods support (tested on Arclight 1.16.5) -- ItemsAdder support - - -This plugin uses CarcadeX library +Give no drop items! diff --git a/build.gradle b/build.gradle index 7933d76..0e0859a 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'me.redtea' -version = '1.0.2b-SNAPSHOT-HOTFIX' +version = '1.0.3-SNAPSHOT' repositories { mavenCentral() @@ -42,6 +42,7 @@ dependencies { implementation files("libs/MiniMessages.jar") implementation "dev.triumphteam:triumph-gui:3.1.2" compileOnly "com.github.LoneDev6:API-ItemsAdder:3.5.0b" + compileOnly files("libs/nodropxforgebridge-1.4.jar") } def targetJavaVersion = 8 diff --git a/libs/nodropxforgebridge-1.1.jar b/libs/nodropxforgebridge-1.1.jar deleted file mode 100644 index c7ed856..0000000 Binary files a/libs/nodropxforgebridge-1.1.jar and /dev/null differ diff --git a/libs/nodropxforgebridge-1.4.jar b/libs/nodropxforgebridge-1.4.jar new file mode 100644 index 0000000..eb9c462 Binary files /dev/null and b/libs/nodropxforgebridge-1.4.jar differ diff --git a/src/main/java/me/redtea/nodropx/NoDropX.java b/src/main/java/me/redtea/nodropx/NoDropX.java index 75112c2..5382a57 100644 --- a/src/main/java/me/redtea/nodropx/NoDropX.java +++ b/src/main/java/me/redtea/nodropx/NoDropX.java @@ -10,23 +10,35 @@ import me.redtea.nodropx.factory.item.impl.NoDropItemFactoryImpl; import me.redtea.nodropx.factory.text.TextContext; import me.redtea.nodropx.factory.text.TextServicesFactory; import me.redtea.nodropx.factory.text.impl.TextServicesFactoryImpl; -import me.redtea.nodropx.gui.facade.GuiFacade; -import me.redtea.nodropx.gui.facade.impl.GuiFacadeImpl; -import me.redtea.nodropx.gui.pages.StorageGui; +import me.redtea.nodropx.folia.FoliaSupporter; import me.redtea.nodropx.libs.bstats.Metrics; import me.redtea.nodropx.libs.carcadex.repo.MutableRepo; import me.redtea.nodropx.libs.carcadex.repo.Repo; -import me.redtea.nodropx.libs.carcadex.repo.impl.yaml.YamlRepo; import me.redtea.nodropx.libs.message.container.Messages; import me.redtea.nodropx.libs.message.verifier.impl.FileMessageVerifier; +import me.redtea.nodropx.listener.ConfirmDropHandler; import me.redtea.nodropx.listener.InventoryHandler; import me.redtea.nodropx.listener.PlayerHandler; +import me.redtea.nodropx.listener.menu.SinglePageGuiHandler; +import me.redtea.nodropx.menu.CachedMenu; +import me.redtea.nodropx.menu.Menu; +import me.redtea.nodropx.menu.dropconfirm.DropConfirmMFGui; +import me.redtea.nodropx.menu.facade.MenuFacade; +import me.redtea.nodropx.menu.facade.impl.MenuFacadeImpl; +import me.redtea.nodropx.menu.storage.pages.MFPageGui; +import me.redtea.nodropx.menu.storage.singlepage.SinglePageController; +import me.redtea.nodropx.menu.storage.singlepage.SinglePageGui; import me.redtea.nodropx.model.cosmetic.impl.DisplayNameCosmetic; import me.redtea.nodropx.model.materialprovider.impl.ItemStackProviderDefault; import me.redtea.nodropx.model.materialprovider.impl.ItemsAdderProvider; import me.redtea.nodropx.schema.ItemStackListSchema; +import me.redtea.nodropx.service.capasity.CapacityService; +import me.redtea.nodropx.service.capasity.impl.CapacityServiceImpl; import me.redtea.nodropx.service.cosmetic.CosmeticService; import me.redtea.nodropx.service.cosmetic.impl.CosmeticServiceImpl; +import me.redtea.nodropx.service.dropconfirm.DropConfirmService; +import me.redtea.nodropx.service.dropconfirm.impl.DropConfirmNull; +import me.redtea.nodropx.service.dropconfirm.impl.DropConfirmServiceImpl; import me.redtea.nodropx.service.event.EventService; import me.redtea.nodropx.service.event.impl.EventServiceImpl; import me.redtea.nodropx.service.material.ItemStackService; @@ -39,6 +51,8 @@ import me.redtea.nodropx.service.respawn.RespawnService; import me.redtea.nodropx.service.respawn.impl.RespawnServiceImpl; import me.redtea.nodropx.service.storage.StorageService; import me.redtea.nodropx.service.storage.impl.StorageServiceImpl; +import me.redtea.nodropx.util.ConfigVerifier; +import me.redtea.nodropx.util.FoliaSupportedUtils; import me.redtea.nodropx.util.UpdateChecker; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -50,29 +64,34 @@ import org.bukkit.plugin.java.JavaPlugin; import java.io.File; import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; public final class NoDropX extends JavaPlugin { private static NoDropAPI noDropAPIInstance; @Getter private static NoDropX instance; - + @Getter private Messages messages; - private CosmeticService cosmeticService; + private CosmeticService noDropCosmeticService; @Getter private boolean supportHEX; @Getter private boolean supportKyoriLore; @Getter private boolean supportItemsAdder; - private MutableRepo> pagesRepo; - private Repo> capacity; - + private MutableRepo> personalStorageRepo; + private CapacityService capacityService; + private MenuFacade menuFacade; + private NoDropService noDropService; + private ItemStackService itemStackService; + private DropConfirmService dropConfirmService; + private FoliaSupportedUtils foliaSupportedUtils; @Override public void onEnable() { instance = this; - saveDefaultConfig(); + new ConfigVerifier().verifyDefaults(this); + + foliaSupportedUtils = new FoliaSupportedUtils(this); TextServicesFactory textServicesFactory = new TextServicesFactoryImpl(); TextContext textContext = textServicesFactory.create(this); @@ -81,51 +100,43 @@ public final class NoDropX extends JavaPlugin { messages = supportKyoriLore ? Messages.of(textContext.getMessages()) : Messages.legacy(textContext.getMessages()); messages.setVerifier(new FileMessageVerifier(getResource(textContext.getPath()), YamlConfiguration.loadConfiguration(textContext.getMessages()), textContext.getMessages())); - cosmeticService = new CosmeticServiceImpl(); - cosmeticService.add(new DisplayNameCosmetic()); - cosmeticService.add(textContext.getLoreStrategy()); - cosmeticService.load(YamlConfiguration.loadConfiguration(textContext.getCosmetics())); - - capacity = new YamlRepo<>( - new File(getDataFolder(), "capacity.yml").toPath(), - this, - conf -> conf.getKeys(false).stream().collect(Collectors.toMap( - value -> value, - conf::getIntegerList)) - ); + noDropCosmeticService = new CosmeticServiceImpl(); + noDropCosmeticService.add(new DisplayNameCosmetic()); + noDropCosmeticService.add(textContext.getLoreStrategy()); + noDropCosmeticService.load(YamlConfiguration.loadConfiguration(textContext.getCosmetics())); NBTService nbtService = new Tr7zwNBTServiceImpl(); - NoDropService noDropService = new NoDropServiceImpl(nbtService, cosmeticService); + noDropService = new NoDropServiceImpl(nbtService, noDropCosmeticService); NoDropItemFactory noDropItemFactory = new NoDropItemFactoryImpl(noDropService); EventService eventService = new EventServiceImpl(noDropService); - RespawnService respawnService = new RespawnServiceImpl(noDropService, capacity); - pagesRepo = Repo.>builder() + capacityService = new CapacityServiceImpl(this); + RespawnService respawnService = new RespawnServiceImpl(noDropService, capacityService); + + //EXPERIMENTAL! Folia support! + FoliaSupporter foliaSupporter = new FoliaSupporter(); + foliaSupporter.run(respawnService, this); + + personalStorageRepo = Repo.>builder() .autoSave(1000 * 60 * 15L) .schema(new ItemStackListSchema(new File(getDataFolder(), "storage"))) .plugin(this) .build(); - ItemStackService itemStackService = initItemStackService(); + itemStackService = initItemStackService(); + dropConfirmService = getConfig().getBoolean("confirmThrowNoDropItem") ? new DropConfirmServiceImpl() : new DropConfirmNull(); - GuiFacade guiFacade = new GuiFacadeImpl( - new StorageGui(messages, pagesRepo, noDropService, this, itemStackService) - ); - StorageService storageService = new StorageServiceImpl(guiFacade, pagesRepo, noDropService); + menuFacade = initMenus(); + StorageService storageService = new StorageServiceImpl(menuFacade, personalStorageRepo, noDropService); - NoDropAPI noDropAPI = new NoDropXFacade(noDropService, noDropItemFactory, storageService, capacity, itemStackService); + NoDropAPI noDropAPI = new NoDropXFacade(noDropService, noDropItemFactory, storageService, capacityService, itemStackService); noDropAPIInstance = noDropAPI; - Bukkit.getPluginManager().registerEvents( - new InventoryHandler(eventService), - this - ); - Bukkit.getPluginManager().registerEvents( - new PlayerHandler(respawnService, eventService, guiFacade), - this - ); + Bukkit.getPluginManager().registerEvents(new InventoryHandler(eventService, noDropService, dropConfirmService), this); + Bukkit.getPluginManager().registerEvents(new PlayerHandler(respawnService, eventService, menuFacade), this); + Bukkit.getPluginManager().registerEvents(new ConfirmDropHandler(dropConfirmService, menuFacade), this); Bukkit.getServicesManager().register(NoDropAPI.class, noDropAPI, this, ServicePriority.Normal); @@ -136,12 +147,25 @@ public final class NoDropX extends JavaPlugin { commandManager.getMessageHandler().register("cmd.no.exists", sender -> messages.get("noExists").send(sender)); commandManager.getMessageHandler().register("cmd.wrong.usage", sender -> messages.get("usage").send(sender)); commandManager.getCompletionHandler().register("#materials", input -> itemStackService.allMaterials()); - commandManager.register(new NoDropCommand(messages, noDropAPI, guiFacade, this, itemStackService)); + commandManager.register(new NoDropCommand(messages, noDropAPI, menuFacade, this, itemStackService)); bStatsInit(); printCredits(); checkUpdates(); } + private MenuFacade initMenus() { + CachedMenu personalStorageCachedMenu; + if(getConfig().getString("personalStorageType").equalsIgnoreCase("SINGLE_PAGE")) { + SinglePageGui singlePageGui = new SinglePageGui(messages, personalStorageRepo); + personalStorageCachedMenu = singlePageGui; + Bukkit.getPluginManager().registerEvents(new SinglePageGuiHandler(new SinglePageController(noDropService, + singlePageGui, personalStorageRepo, foliaSupportedUtils), singlePageGui), this); + } else personalStorageCachedMenu = new MFPageGui(messages, personalStorageRepo, noDropService, itemStackService, this); + + Menu confirmMenu = new DropConfirmMFGui(messages, dropConfirmService); + return new MenuFacadeImpl(personalStorageCachedMenu, confirmMenu); + } + private ItemStackService initItemStackService() { ItemStackService result = new ItemStackServiceImpl(); if (Bukkit.getPluginManager().getPlugin("ItemsAdder") != null) { @@ -154,10 +178,10 @@ public final class NoDropX extends JavaPlugin { } private void checkUpdates() { - if(!(getConfig().contains("checkForUpdates") && getConfig().getBoolean("checkForUpdates"))) { + if(!getConfig().getBoolean("checkForUpdates")) { return; } - new UpdateChecker(this, 111485).getVersion(version -> { + new UpdateChecker(this, 111485, foliaSupportedUtils).getVersion(version -> { if (this.getDescription().getVersion().equals(version)) { getLogger().info("There is not a new update available."); } else { @@ -185,15 +209,16 @@ public final class NoDropX extends JavaPlugin { } public void onReload() { - pagesRepo.saveAll(); - capacity.reload(); + personalStorageRepo.saveAll(); + menuFacade.clearAllCache(); + capacityService.reload(); messages.reload(YamlConfiguration.loadConfiguration(new File(getDataFolder(), "messages.yml"))); - cosmeticService.load(YamlConfiguration.loadConfiguration(new File(getDataFolder(), "cosmetics.yml"))); + noDropCosmeticService.load(YamlConfiguration.loadConfiguration(new File(getDataFolder(), "cosmetics.yml"))); } @Override public void onDisable() { - pagesRepo.saveAll(); + personalStorageRepo.saveAll(); } public static NoDropAPI getAPI() { diff --git a/src/main/java/me/redtea/nodropx/api/facade/NoDropAPI.java b/src/main/java/me/redtea/nodropx/api/facade/NoDropAPI.java index 16ab20c..6088504 100644 --- a/src/main/java/me/redtea/nodropx/api/facade/NoDropAPI.java +++ b/src/main/java/me/redtea/nodropx/api/facade/NoDropAPI.java @@ -2,7 +2,6 @@ package me.redtea.nodropx.api.facade; import lombok.val; import me.redtea.nodropx.api.facade.manipulator.StorageManipulator; -import me.redtea.nodropx.util.MaterialUtils; import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.entity.HumanEntity; @@ -78,6 +77,15 @@ public interface NoDropAPI { */ @NotNull StorageManipulator getStorageManipulator(@NotNull UUID playerUniqueId); + /** + * returns the slot numbers that no drop item with this itemStack saves at death + * @param itemStack itemStack to check + * @return numbers of saved slots + * @author redtea + * @since 1.0.3 + */ + @NotNull Collection getCapacitySlots(ItemStack itemStack); + /** * returns the slot numbers that no drop item with this material saves at death * @param material material to check diff --git a/src/main/java/me/redtea/nodropx/api/facade/impl/NoDropXFacade.java b/src/main/java/me/redtea/nodropx/api/facade/impl/NoDropXFacade.java index 2f63c90..cff9c1e 100644 --- a/src/main/java/me/redtea/nodropx/api/facade/impl/NoDropXFacade.java +++ b/src/main/java/me/redtea/nodropx/api/facade/impl/NoDropXFacade.java @@ -5,6 +5,7 @@ import me.redtea.nodropx.api.facade.manipulator.StorageManipulator; import lombok.RequiredArgsConstructor; import me.redtea.nodropx.factory.item.NoDropItemFactory; import me.redtea.nodropx.libs.carcadex.repo.Repo; +import me.redtea.nodropx.service.capasity.CapacityService; import me.redtea.nodropx.service.material.ItemStackService; import me.redtea.nodropx.service.nodrop.NoDropService; import me.redtea.nodropx.service.storage.StorageService; @@ -24,7 +25,7 @@ public class NoDropXFacade implements NoDropAPI { private final NoDropService noDropService; private final NoDropItemFactory itemFactory; private final StorageService storageService; - private final Repo> capacity; + private final CapacityService capacityService; private final ItemStackService itemStackService; @Override @@ -74,9 +75,14 @@ public class NoDropXFacade implements NoDropAPI { }; } + @Override + public @NotNull Collection getCapacitySlots(ItemStack itemStack) { + return capacityService.get(itemStack); + } + @Override public @NotNull Collection getCapacitySlots(Material material) { - return capacity.get(material.name()).orElse(new ArrayList<>()); + return capacityService.get(material); } @Override diff --git a/src/main/java/me/redtea/nodropx/command/NoDropCommand.java b/src/main/java/me/redtea/nodropx/command/NoDropCommand.java index 8dcd168..5c20568 100644 --- a/src/main/java/me/redtea/nodropx/command/NoDropCommand.java +++ b/src/main/java/me/redtea/nodropx/command/NoDropCommand.java @@ -6,7 +6,7 @@ import me.mattstudios.mf.annotations.*; import me.mattstudios.mf.base.CommandBase; import me.redtea.nodropx.NoDropX; import me.redtea.nodropx.api.facade.NoDropAPI; -import me.redtea.nodropx.gui.facade.GuiFacade; +import me.redtea.nodropx.menu.facade.MenuFacade; import me.redtea.nodropx.libs.message.container.Messages; import me.redtea.nodropx.service.material.ItemStackService; import org.bukkit.Bukkit; @@ -27,7 +27,7 @@ import java.util.Date; public class NoDropCommand extends CommandBase { private final Messages messages; private final NoDropAPI noDropAPI; - private final GuiFacade guiFacade; + private final MenuFacade menuFacade; private final NoDropX plugin; private final ItemStackService itemStackService; @@ -68,9 +68,9 @@ public class NoDropCommand extends CommandBase { @Permission("nodropx.giveStorage") @Completion({"#players", "#materials", "#range:1-64"}) public void onGiveStorage(final CommandSender sender, - String playerName, + final String playerName, final String material, - @Optional Integer amount) { + @Optional final Integer amount) { try { val item = noDropAPI.setNoDrop(itemStackService.get(material, amount == null || amount == 0 ? 1 : amount), true); val player = getOfflinePlayer(playerName); @@ -82,11 +82,12 @@ public class NoDropCommand extends CommandBase { messages.get("giveToStorage.success") .replaceAll("%item%", material) .replaceAll("%player%", playerName) - .replaceAll("%amount%", amount == null ? "0" : amount.toString()) + .replaceAll("%amount%", amount == null ? "1" : amount.toString()) .send(sender); } catch (Throwable e) { messages.get("giveToStorage.fail").send(sender); } + } @SubCommand("applyHand") @@ -101,13 +102,14 @@ public class NoDropCommand extends CommandBase { } @SubCommand("gui") + @Alias("storage") @Permission("nodropx.gui") public void onGui(final Player sender) { - guiFacade.openNoDropStorage(sender); + menuFacade.openPersonalStorage(sender); } @Nullable - private OfflinePlayer getOfflinePlayer(String name) { + private OfflinePlayer getOfflinePlayer(final String name) { for(OfflinePlayer player : Bukkit.getOfflinePlayers()) { if(player.getName() != null && player.getName().equalsIgnoreCase(name)) return player; } diff --git a/src/main/java/me/redtea/nodropx/folia/FoliaSupporter.java b/src/main/java/me/redtea/nodropx/folia/FoliaSupporter.java new file mode 100644 index 0000000..ee9c45e --- /dev/null +++ b/src/main/java/me/redtea/nodropx/folia/FoliaSupporter.java @@ -0,0 +1,73 @@ +package me.redtea.nodropx.folia; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import lombok.Getter; +import lombok.SneakyThrows; +import me.redtea.nodropx.service.respawn.RespawnService; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.plugin.Plugin; + +import java.io.FileReader; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +//Experimental. Must be refactored in the future. +public class FoliaSupporter { + private RespawnService respawnService; + + @Getter + private static boolean runningOnFolia = false; + + @SneakyThrows + public void run(RespawnService respawnService, Plugin plugin) { + String version = ((JsonObject) new JsonParser().parse(new FileReader("version_history.json"))).get("currentVersion").getAsString(); + if(!version.toLowerCase().contains("folia") && !plugin.getConfig().getBoolean("forceUseFoliaPatches")) { + return; + } + runningOnFolia = true; + plugin.getLogger().info("Found Folia! Applying patches for this..."); + this.respawnService = respawnService; + Bukkit.getPluginManager().registerEvents(new FoliaDeathListener(), plugin); + plugin.getLogger().info("Patches for Folia successfully applied!"); + } + + + /* + temp fix when folia not called respawn event + */ + class FoliaDeathListener implements Listener { + private final Set toRespawn = new CopyOnWriteArraySet<>(); + + public FoliaDeathListener() { + new Thread(() -> { + while (true) { + for(Player player : toRespawn) { + if(!player.isDead()) { + onRespawn(player); + toRespawn.remove(player); + } + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }).start(); + } + + public void onRespawn(Player player) { + respawnService.giveSavedItems(player); + } + + @EventHandler + public void onDeath(PlayerDeathEvent event) { + toRespawn.add(event.getEntity()); + } + } +} diff --git a/src/main/java/me/redtea/nodropx/gui/facade/GuiFacade.java b/src/main/java/me/redtea/nodropx/gui/facade/GuiFacade.java deleted file mode 100644 index 5df3794..0000000 --- a/src/main/java/me/redtea/nodropx/gui/facade/GuiFacade.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.redtea.nodropx.gui.facade; - -import org.bukkit.entity.Player; - -public interface GuiFacade { - void openNoDropStorage(Player player); - void clearCache(Player player); - void clearAllCache(); -} diff --git a/src/main/java/me/redtea/nodropx/gui/facade/impl/GuiFacadeImpl.java b/src/main/java/me/redtea/nodropx/gui/facade/impl/GuiFacadeImpl.java deleted file mode 100644 index 6321b4a..0000000 --- a/src/main/java/me/redtea/nodropx/gui/facade/impl/GuiFacadeImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.redtea.nodropx.gui.facade.impl; - -import lombok.RequiredArgsConstructor; -import me.redtea.nodropx.gui.facade.GuiFacade; -import me.redtea.nodropx.gui.pages.StorageGui; -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class GuiFacadeImpl implements GuiFacade { - private final StorageGui storageGui; - - @Override - public void openNoDropStorage(Player player) { - storageGui.open(player); - } - - @Override - public void clearCache(Player player) { - storageGui.clearCache(player); - } - - @Override - public void clearAllCache() { - storageGui.clearAllCache(); - } -} diff --git a/src/main/java/me/redtea/nodropx/libs/message/container/impl/MessagesImpl.java b/src/main/java/me/redtea/nodropx/libs/message/container/impl/MessagesImpl.java index a7a7b51..f99eb6a 100644 --- a/src/main/java/me/redtea/nodropx/libs/message/container/impl/MessagesImpl.java +++ b/src/main/java/me/redtea/nodropx/libs/message/container/impl/MessagesImpl.java @@ -10,10 +10,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; import java.io.File; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.util.*; public class MessagesImpl implements Messages { private Map messages; @@ -53,9 +50,10 @@ public class MessagesImpl implements Messages { public Message get(String key) { if(!has(key)) { if(verifier != null) { - Optional def = verifier.fromDefault(key); + Optional def = verifier.fromDefault(key); if(def.isPresent()) { - messages.put(key, factory.message(def.get())); + if(def.get() instanceof List) messages.put(key, factory.message((List) def.get())); + else messages.put(key, factory.message((def.get().toString()))); return messages.get(key); } return NULL_MESSAGE; diff --git a/src/main/java/me/redtea/nodropx/libs/message/model/Message.java b/src/main/java/me/redtea/nodropx/libs/message/model/Message.java index dee72c7..1828c23 100644 --- a/src/main/java/me/redtea/nodropx/libs/message/model/Message.java +++ b/src/main/java/me/redtea/nodropx/libs/message/model/Message.java @@ -1,7 +1,9 @@ package me.redtea.nodropx.libs.message.model; +import me.redtea.nodropx.util.MaterialUtils; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; +import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; @@ -60,4 +62,8 @@ public interface Message extends ComponentLike { default Message replaceAll(@NotNull Object from, @NotNull Object to) { return replaceAll(String.valueOf(from), String.valueOf(to)); } + + default Material toMaterial() { + return Material.matchMaterial(asUnparsedString()) == null ? Material.STONE : Material.matchMaterial(asUnparsedString()); + } } diff --git a/src/main/java/me/redtea/nodropx/libs/message/verifier/MessageVerifier.java b/src/main/java/me/redtea/nodropx/libs/message/verifier/MessageVerifier.java index 50fa39b..92c1fa7 100644 --- a/src/main/java/me/redtea/nodropx/libs/message/verifier/MessageVerifier.java +++ b/src/main/java/me/redtea/nodropx/libs/message/verifier/MessageVerifier.java @@ -3,5 +3,5 @@ package me.redtea.nodropx.libs.message.verifier; import java.util.Optional; public interface MessageVerifier { - Optional fromDefault(String key); + Optional fromDefault(String key); } diff --git a/src/main/java/me/redtea/nodropx/libs/message/verifier/impl/FileMessageVerifier.java b/src/main/java/me/redtea/nodropx/libs/message/verifier/impl/FileMessageVerifier.java index a16b241..a021edb 100644 --- a/src/main/java/me/redtea/nodropx/libs/message/verifier/impl/FileMessageVerifier.java +++ b/src/main/java/me/redtea/nodropx/libs/message/verifier/impl/FileMessageVerifier.java @@ -9,6 +9,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.List; import java.util.Optional; public class FileMessageVerifier implements MessageVerifier { @@ -24,8 +25,8 @@ public class FileMessageVerifier implements MessageVerifier { } @Override - public Optional fromDefault(String key) { - Optional o = Optional.ofNullable(defaultSection.getString(key)); + public Optional fromDefault(String key) { + Optional o = Optional.ofNullable(defaultSection.get(key)); o.ifPresent(s -> saveToMain(key, s)); return o; } diff --git a/src/main/java/me/redtea/nodropx/listener/ConfirmDropHandler.java b/src/main/java/me/redtea/nodropx/listener/ConfirmDropHandler.java new file mode 100644 index 0000000..4ea3093 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/listener/ConfirmDropHandler.java @@ -0,0 +1,22 @@ +package me.redtea.nodropx.listener; + +import lombok.RequiredArgsConstructor; +import me.redtea.nodropx.api.event.NoDropItemThrownEvent; +import me.redtea.nodropx.menu.facade.MenuFacade; +import me.redtea.nodropx.service.dropconfirm.DropConfirmService; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +@RequiredArgsConstructor +public class ConfirmDropHandler implements Listener { + private final DropConfirmService confirmService; + private final MenuFacade menuFacade; + + @EventHandler + public void onDrop(NoDropItemThrownEvent event) { + if(!confirmService.isConfirmed(event.getPlayer()) && event.getReason() == NoDropItemThrownEvent.Reason.DROP_BY_PLAYER) { + menuFacade.openConfirmDrop(event.getPlayer()); + event.setCancelled(true); + } else confirmService.resetConfirm(event.getPlayer()); + } +} diff --git a/src/main/java/me/redtea/nodropx/listener/InventoryHandler.java b/src/main/java/me/redtea/nodropx/listener/InventoryHandler.java index acb5d69..bb0e333 100644 --- a/src/main/java/me/redtea/nodropx/listener/InventoryHandler.java +++ b/src/main/java/me/redtea/nodropx/listener/InventoryHandler.java @@ -1,8 +1,12 @@ package me.redtea.nodropx.listener; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import me.redtea.nodropx.api.event.NoDropItemThrownEvent; +import me.redtea.nodropx.service.dropconfirm.DropConfirmService; +import me.redtea.nodropx.service.dropconfirm.impl.DropConfirmNull; import me.redtea.nodropx.service.event.EventService; +import me.redtea.nodropx.service.nodrop.NoDropService; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -10,22 +14,32 @@ import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; +import java.util.List; import java.util.Optional; @RequiredArgsConstructor public class InventoryHandler implements Listener { private final EventService eventService; + private final NoDropService noDropService; + private final DropConfirmService dropConfirmService; + @EventHandler public void onMove(InventoryClickEvent event) { - if(event.getAction().equals(InventoryAction.MOVE_TO_OTHER_INVENTORY)) { + if(event.getAction().name().startsWith("DROP") + && (noDropService.isNoDrop(event.getCursor()) || noDropService.isNoDrop(event.getCurrentItem())) + && !(dropConfirmService instanceof DropConfirmNull)) { + event.setCancelled(true); + return; + } + + if(event.getAction().equals(InventoryAction.MOVE_TO_OTHER_INVENTORY) && !event.getInventory().equals(event.getClickedInventory())) { call(event, event.getCurrentItem()); } else if(event.getAction().equals(InventoryAction.PLACE_ALL) || event.getAction().equals(InventoryAction.PLACE_ONE) || event.getAction().equals(InventoryAction.PLACE_SOME)) { call(event, event.getCursor()); } - } private void call(InventoryClickEvent event, ItemStack item) { diff --git a/src/main/java/me/redtea/nodropx/listener/PlayerHandler.java b/src/main/java/me/redtea/nodropx/listener/PlayerHandler.java index e4b5af1..8ad8bfb 100644 --- a/src/main/java/me/redtea/nodropx/listener/PlayerHandler.java +++ b/src/main/java/me/redtea/nodropx/listener/PlayerHandler.java @@ -2,8 +2,9 @@ package me.redtea.nodropx.listener; import lombok.RequiredArgsConstructor; import me.redtea.nodropx.api.event.NoDropItemThrownEvent; -import me.redtea.nodropx.gui.facade.GuiFacade; +import me.redtea.nodropx.menu.facade.MenuFacade; import me.redtea.nodropx.service.event.EventService; +import me.redtea.nodropx.service.nodrop.NoDropService; import me.redtea.nodropx.service.respawn.RespawnService; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -19,9 +20,8 @@ import java.util.Optional; public class PlayerHandler implements Listener { private final RespawnService respawnService; private final EventService eventService; - private final GuiFacade guiFacade; + private final MenuFacade menuFacade; - //TODO check for armor @EventHandler public void onDrop(PlayerDropItemEvent event) { eventService.callThrownEvent( @@ -44,7 +44,7 @@ public class PlayerHandler implements Listener { @EventHandler public void onQuit(PlayerQuitEvent event) { - guiFacade.clearCache(event.getPlayer()); + menuFacade.clearCache(event.getPlayer()); } } diff --git a/src/main/java/me/redtea/nodropx/listener/menu/SinglePageGuiHandler.java b/src/main/java/me/redtea/nodropx/listener/menu/SinglePageGuiHandler.java new file mode 100644 index 0000000..974fd95 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/listener/menu/SinglePageGuiHandler.java @@ -0,0 +1,40 @@ +package me.redtea.nodropx.listener.menu; + +import me.redtea.nodropx.menu.storage.singlepage.SinglePageController; +import me.redtea.nodropx.menu.storage.singlepage.SinglePageGui; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; + +public class SinglePageGuiHandler implements Listener { + private final SinglePageController controller; + private final SinglePageGui gui; + + public SinglePageGuiHandler(SinglePageController controller, SinglePageGui gui) { + this.controller = controller; + this.gui = gui; + + } + + + @EventHandler + public void onClick(InventoryClickEvent event) { + if(gui.isStorageGui(event.getInventory())) { + if(event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) controller.onClick(event); + } + if(gui.isStorageGui(event.getClickedInventory()) && event.getWhoClicked() instanceof Player) { + controller.onClick(event); + } + } + + @EventHandler + public void onClose(InventoryCloseEvent event) { + if(gui.isStorageGui(event.getInventory()) && event.getPlayer() instanceof Player) { + controller.onClose(event); + } + } + +} diff --git a/src/main/java/me/redtea/nodropx/menu/CachedMenu.java b/src/main/java/me/redtea/nodropx/menu/CachedMenu.java new file mode 100644 index 0000000..0497389 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/CachedMenu.java @@ -0,0 +1,8 @@ +package me.redtea.nodropx.menu; + +import org.bukkit.entity.Player; + +public interface CachedMenu extends Menu { + void clearCache(Player player); + void clearAllCache(); +} diff --git a/src/main/java/me/redtea/nodropx/menu/Menu.java b/src/main/java/me/redtea/nodropx/menu/Menu.java new file mode 100644 index 0000000..67c803e --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/Menu.java @@ -0,0 +1,7 @@ +package me.redtea.nodropx.menu; + +import org.bukkit.entity.Player; + +public interface Menu { + void open(Player player); +} diff --git a/src/main/java/me/redtea/nodropx/menu/dropconfirm/DropConfirmMFGui.java b/src/main/java/me/redtea/nodropx/menu/dropconfirm/DropConfirmMFGui.java new file mode 100644 index 0000000..4320186 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/dropconfirm/DropConfirmMFGui.java @@ -0,0 +1,38 @@ +package me.redtea.nodropx.menu.dropconfirm; + +import dev.triumphteam.gui.builder.item.ItemBuilder; +import dev.triumphteam.gui.guis.Gui; +import me.redtea.nodropx.libs.message.container.Messages; +import me.redtea.nodropx.menu.Menu; +import me.redtea.nodropx.service.dropconfirm.DropConfirmService; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +public class DropConfirmMFGui implements Menu { + private final Gui gui; + public DropConfirmMFGui(Messages messages, DropConfirmService dropConfirmService) { + gui = Gui.gui() + .rows(1) + .title(messages.get("gui.confirm.title").asComponent()) + .disableAllInteractions() + .create(); + gui.setItem(1, ItemBuilder.from(messages.get("gui.confirm.yesButton.material").toMaterial()) + .name(messages.get("gui.confirm.yesButton.name").asComponent()) + .lore(messages.get("gui.confirm.yesButton.lore").asComponent()) + .asGuiItem((event -> { + dropConfirmService.confirm((Player) event.getWhoClicked()); + event.getWhoClicked().dropItem(true); + event.getWhoClicked().closeInventory(); + }))); + gui.setItem(7, ItemBuilder.from(messages.get("gui.confirm.noButton.material").toMaterial()) + .name(messages.get("gui.confirm.noButton.name").asComponent()) + .lore(messages.get("gui.confirm.noButton.lore").asComponent()) + .asGuiItem((event -> event.getWhoClicked().closeInventory()))); + } + + @Override + public void open(Player player) { + gui.open(player); + } +} diff --git a/src/main/java/me/redtea/nodropx/menu/facade/MenuFacade.java b/src/main/java/me/redtea/nodropx/menu/facade/MenuFacade.java new file mode 100644 index 0000000..dc7316f --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/facade/MenuFacade.java @@ -0,0 +1,12 @@ +package me.redtea.nodropx.menu.facade; + +import me.redtea.nodropx.menu.CachedMenu; +import org.bukkit.entity.Player; + +public interface MenuFacade { + CachedMenu noDropStorage(); + void openPersonalStorage(Player player); + void openConfirmDrop(Player player); + void clearCache(Player player); + void clearAllCache(); +} diff --git a/src/main/java/me/redtea/nodropx/menu/facade/impl/MenuFacadeImpl.java b/src/main/java/me/redtea/nodropx/menu/facade/impl/MenuFacadeImpl.java new file mode 100644 index 0000000..a68c38e --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/facade/impl/MenuFacadeImpl.java @@ -0,0 +1,38 @@ +package me.redtea.nodropx.menu.facade.impl; + +import lombok.RequiredArgsConstructor; +import me.redtea.nodropx.menu.CachedMenu; +import me.redtea.nodropx.menu.Menu; +import me.redtea.nodropx.menu.facade.MenuFacade; +import org.bukkit.entity.Player; + +@RequiredArgsConstructor +public class MenuFacadeImpl implements MenuFacade { + private final CachedMenu personalStorageCachedMenu; + private final Menu confirmDropMenu; + + @Override + public CachedMenu noDropStorage() { + return personalStorageCachedMenu; + } + + @Override + public void openPersonalStorage(Player player) { + personalStorageCachedMenu.open(player); + } + + @Override + public void openConfirmDrop(Player player) { + confirmDropMenu.open(player); + } + + @Override + public void clearCache(Player player) { + personalStorageCachedMenu.clearCache(player); + } + + @Override + public void clearAllCache() { + personalStorageCachedMenu.clearAllCache(); + } +} diff --git a/src/main/java/me/redtea/nodropx/gui/pages/StorageGui.java b/src/main/java/me/redtea/nodropx/menu/storage/pages/MFPageGui.java similarity index 76% rename from src/main/java/me/redtea/nodropx/gui/pages/StorageGui.java rename to src/main/java/me/redtea/nodropx/menu/storage/pages/MFPageGui.java index c694ff0..ad00910 100644 --- a/src/main/java/me/redtea/nodropx/gui/pages/StorageGui.java +++ b/src/main/java/me/redtea/nodropx/menu/storage/pages/MFPageGui.java @@ -1,15 +1,16 @@ -package me.redtea.nodropx.gui.pages; +package me.redtea.nodropx.menu.storage.pages; import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.ScrollingGui; import lombok.RequiredArgsConstructor; +import me.redtea.nodropx.menu.CachedMenu; import me.redtea.nodropx.libs.carcadex.repo.MutableRepo; import me.redtea.nodropx.libs.message.container.Messages; import me.redtea.nodropx.service.material.ItemStackService; import me.redtea.nodropx.service.nodrop.NoDropService; -import me.redtea.nodropx.util.MaterialUtils; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryAction; @@ -22,13 +23,14 @@ import java.util.*; import java.util.stream.Collectors; @RequiredArgsConstructor -public class StorageGui { - private final Map cache = new HashMap<>(); +public class MFPageGui implements CachedMenu { private final Messages messages; - private final MutableRepo> pagesRepo; + private final MutableRepo> personalStorageRepo; private final NoDropService noDropService; - private final Plugin plugin; private final ItemStackService itemStackService; + private final Plugin plugin; + + private final Map cache = new HashMap<>(); public void open(Player player) { if(cache.containsKey(player.getUniqueId())) { @@ -37,7 +39,7 @@ public class StorageGui { } ScrollingGui gui = Gui.scrolling() - .title(messages.get("gui.title").asComponent()) + .title(messages.get("gui.personalStorage.title").asComponent()) .rows(6) .pageSize(45) .disableAllInteractions() @@ -46,16 +48,16 @@ public class StorageGui { setButtons(gui); setAction(gui); setOnClose(gui); - for(ItemStack item : pagesRepo.get(player.getUniqueId()).orElse(new ArrayList<>())) { + for(ItemStack item : personalStorageRepo.get(player.getUniqueId()).orElse(new ArrayList<>())) { gui.addItem(ItemBuilder.from(item).asGuiItem()); } - gui.open(player); cache.put(player.getUniqueId(), gui); + gui.open(player); } private void setOnClose(ScrollingGui gui) { - gui.setCloseGuiAction(event -> pagesRepo.update(event.getPlayer().getUniqueId(), gui.getPageItems().stream() + gui.setCloseGuiAction(event -> personalStorageRepo.update(event.getPlayer().getUniqueId(), gui.getPageItems().stream() .map(GuiItem::getItemStack) .collect(Collectors.toList()))); } @@ -110,21 +112,21 @@ public class StorageGui { private void setFrame(ScrollingGui gui) { for(int i = 1; i < 10; ++i) { gui.setItem(6, i, ItemBuilder.from( - itemStackService.get(messages.get("gui.frame.material").asUnparsedString(), 1) - ).name(messages.get("gui.frame.name").asComponent()).asGuiItem(event -> event.setCancelled(true))); + itemStackService.get(messages.get("gui.personalStorage.frame.material").asUnparsedString(), 1) + ).name(messages.get("gui.personalStorage.frame.name").asComponent()).asGuiItem(event -> event.setCancelled(true))); } } private void setButtons(ScrollingGui gui) { gui.setItem(6, 3, ItemBuilder.from( - itemStackService.get(messages.get("gui.prev.material").asUnparsedString(), 1) - ).name(messages.get("gui.prev.name").asComponent()).asGuiItem(event -> { + itemStackService.get(messages.get("gui.personalStorage.prev.material").asUnparsedString(), 1) + ).name(messages.get("gui.personalStorage.prev.name").asComponent()).asGuiItem(event -> { gui.previous(); event.setCancelled(true); })); gui.setItem(6, 7, ItemBuilder.from( - itemStackService.get(messages.get("gui.next.material").asUnparsedString(), 1) - ).name(messages.get("gui.next.name").asComponent()).asGuiItem(event -> { + itemStackService.get(messages.get("gui.personalStorage.next.material").asUnparsedString(), 1) + ).name(messages.get("gui.personalStorage.next.name").asComponent()).asGuiItem(event -> { gui.next(); event.setCancelled(true); })); @@ -135,6 +137,10 @@ public class StorageGui { } public void clearAllCache() { + cache.forEach((k, v) -> { + Player player = Bukkit.getPlayer(k); + if(player != null) v.close(player); + }); cache.clear(); } diff --git a/src/main/java/me/redtea/nodropx/menu/storage/singlepage/SinglePageController.java b/src/main/java/me/redtea/nodropx/menu/storage/singlepage/SinglePageController.java new file mode 100644 index 0000000..9026bb7 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/storage/singlepage/SinglePageController.java @@ -0,0 +1,50 @@ +package me.redtea.nodropx.menu.storage.singlepage; + +import com.google.common.collect.Lists; +import lombok.RequiredArgsConstructor; +import me.redtea.nodropx.libs.carcadex.repo.MutableRepo; +import me.redtea.nodropx.service.nodrop.NoDropService; +import me.redtea.nodropx.util.FoliaSupportedUtils; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +@RequiredArgsConstructor +public class SinglePageController { + private final NoDropService noDropService; + private final SinglePageGui singlePageGui; + private final MutableRepo> personalStorageRepo; + private final FoliaSupportedUtils foliaSupportedUtils; + + private final List clickActions = Lists.newArrayList(InventoryAction.MOVE_TO_OTHER_INVENTORY, InventoryAction.PLACE_ALL, InventoryAction.PLACE_ONE, InventoryAction.PLACE_SOME, + InventoryAction.SWAP_WITH_CURSOR, InventoryAction.NOTHING, InventoryAction.COLLECT_TO_CURSOR, InventoryAction.HOTBAR_MOVE_AND_READD, InventoryAction.UNKNOWN); + + + public void onClick(InventoryClickEvent event) { + if(clickActions.contains(event.getAction()) && !(noDropService.isNoDrop(event.getCurrentItem()))) { + event.setCancelled(true); + } + foliaSupportedUtils.runTask(() -> { + for(ItemStack itemStack : event.getInventory()) { + if (itemStack != null && !noDropService.isNoDrop(itemStack)) { + event.getWhoClicked().getInventory().addItem(itemStack); + event.getInventory().remove(itemStack); + ((Player) event.getWhoClicked()).updateInventory(); + } + } + }); + + } + + public void onClose(InventoryCloseEvent event) { + Player player = (Player) event.getPlayer(); + personalStorageRepo.update(event.getPlayer().getUniqueId(), + Arrays.asList(singlePageGui.getCache().get(player.getUniqueId()).getContents())); + } +} diff --git a/src/main/java/me/redtea/nodropx/menu/storage/singlepage/SinglePageGui.java b/src/main/java/me/redtea/nodropx/menu/storage/singlepage/SinglePageGui.java new file mode 100644 index 0000000..a0ed1fd --- /dev/null +++ b/src/main/java/me/redtea/nodropx/menu/storage/singlepage/SinglePageGui.java @@ -0,0 +1,46 @@ +package me.redtea.nodropx.menu.storage.singlepage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.redtea.nodropx.libs.carcadex.repo.MutableRepo; +import me.redtea.nodropx.libs.message.container.Messages; +import me.redtea.nodropx.menu.CachedMenu; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.*; + +@RequiredArgsConstructor +public class SinglePageGui implements CachedMenu { + private final Messages messages; + private final MutableRepo> personalStorageRepo; + @Getter + private final Map cache = new HashMap<>(); + + @Override + public void open(Player player) { + if(cache.containsKey(player.getUniqueId())) { + player.openInventory(cache.get(player.getUniqueId())); + return; + } + Inventory gui = Bukkit.createInventory(null, 54, messages.get("gui.personalStorage.title").asComponent()); + for(ItemStack item : personalStorageRepo.get(player.getUniqueId()).orElse(new ArrayList<>())) if(item != null) gui.addItem(item); + + cache.put(player.getUniqueId(), gui); + player.openInventory(gui); + } + + public void clearCache(Player player) { + cache.remove(player.getUniqueId()); + } + + public void clearAllCache() { + cache.clear(); + } + + public boolean isStorageGui(Inventory inventory) { + return cache.containsValue(inventory); + } +} diff --git a/src/main/java/me/redtea/nodropx/service/capasity/CapacityService.java b/src/main/java/me/redtea/nodropx/service/capasity/CapacityService.java new file mode 100644 index 0000000..5868657 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/service/capasity/CapacityService.java @@ -0,0 +1,21 @@ +package me.redtea.nodropx.service.capasity; + +import me.redtea.nodropx.libs.carcadex.repo.Repo; +import me.redtea.nodropx.libs.carcadex.repo.impl.yaml.YamlRepo; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +public interface CapacityService { + + + List get(ItemStack item); + void reload(); + + default List get(Material material) { + return get(new ItemStack(material)); + } +} diff --git a/src/main/java/me/redtea/nodropx/service/capasity/impl/CapacityServiceImpl.java b/src/main/java/me/redtea/nodropx/service/capasity/impl/CapacityServiceImpl.java new file mode 100644 index 0000000..0361fca --- /dev/null +++ b/src/main/java/me/redtea/nodropx/service/capasity/impl/CapacityServiceImpl.java @@ -0,0 +1,52 @@ +package me.redtea.nodropx.service.capasity.impl; + +import me.redtea.nodropx.libs.carcadex.repo.Repo; +import me.redtea.nodropx.libs.carcadex.repo.impl.yaml.YamlRepo; +import me.redtea.nodropx.service.capasity.CapacityService; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +public class CapacityServiceImpl implements CapacityService { + private final Repo> capacityRepo; + private final Map customModelDataRequired = new HashMap<>(); + public CapacityServiceImpl(Plugin plugin) { + capacityRepo = new YamlRepo<>( + new File(plugin.getDataFolder(), "capacity.yml").toPath(), + plugin, + conf -> conf.getKeys(false).stream().collect(Collectors.toMap( + value -> { + if(value.contains("->")) { + String[] args = value.split("->"); + customModelDataRequired.put(args[0], Integer.parseInt(args[1])); + return args[0]; + } else return value; + }, + conf::getIntegerList)) + ); + } + + @Override + public List get(ItemStack item) { + String key = item.getType().name(); + Optional> result = capacityRepo.get(key); + if(!result.isPresent()) { + return Collections.emptyList(); + } + if(customModelDataRequired.containsKey(key)) { + int cmi = customModelDataRequired.get(key); + if(!item.getItemMeta().hasCustomModelData() || item.getItemMeta().getCustomModelData() != cmi) { + return Collections.emptyList(); + } + } + return result.get(); + } + + @Override + public void reload() { + capacityRepo.reload(); + } +} diff --git a/src/main/java/me/redtea/nodropx/service/dropconfirm/DropConfirmService.java b/src/main/java/me/redtea/nodropx/service/dropconfirm/DropConfirmService.java new file mode 100644 index 0000000..d5def24 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/service/dropconfirm/DropConfirmService.java @@ -0,0 +1,9 @@ +package me.redtea.nodropx.service.dropconfirm; + +import org.bukkit.entity.Player; + +public interface DropConfirmService { + boolean isConfirmed(Player player); + void confirm(Player player); + void resetConfirm(Player player); +} diff --git a/src/main/java/me/redtea/nodropx/service/dropconfirm/impl/DropConfirmNull.java b/src/main/java/me/redtea/nodropx/service/dropconfirm/impl/DropConfirmNull.java new file mode 100644 index 0000000..b52cb0b --- /dev/null +++ b/src/main/java/me/redtea/nodropx/service/dropconfirm/impl/DropConfirmNull.java @@ -0,0 +1,21 @@ +package me.redtea.nodropx.service.dropconfirm.impl; + +import me.redtea.nodropx.service.dropconfirm.DropConfirmService; +import org.bukkit.entity.Player; + +public class DropConfirmNull implements DropConfirmService { + @Override + public boolean isConfirmed(Player player) { + return true; + } + + @Override + public void confirm(Player player) { + + } + + @Override + public void resetConfirm(Player player) { + + } +} diff --git a/src/main/java/me/redtea/nodropx/service/dropconfirm/impl/DropConfirmServiceImpl.java b/src/main/java/me/redtea/nodropx/service/dropconfirm/impl/DropConfirmServiceImpl.java new file mode 100644 index 0000000..aa470b8 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/service/dropconfirm/impl/DropConfirmServiceImpl.java @@ -0,0 +1,27 @@ +package me.redtea.nodropx.service.dropconfirm.impl; + +import me.redtea.nodropx.service.dropconfirm.DropConfirmService; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public class DropConfirmServiceImpl implements DropConfirmService { + private Set confirmed = new HashSet<>(); + @Override + public boolean isConfirmed(Player player) { + return confirmed.contains(player.getUniqueId()); + } + + @Override + public void confirm(Player player) { + confirmed.add(player.getUniqueId()); + } + + @Override + public void resetConfirm(Player player) { + confirmed.remove(player.getUniqueId()); + } + +} diff --git a/src/main/java/me/redtea/nodropx/service/respawn/impl/NullRespawnService.java b/src/main/java/me/redtea/nodropx/service/respawn/impl/NullRespawnService.java new file mode 100644 index 0000000..bf21ef3 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/service/respawn/impl/NullRespawnService.java @@ -0,0 +1,17 @@ +package me.redtea.nodropx.service.respawn.impl; + +import me.redtea.nodropx.service.respawn.RespawnService; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class NullRespawnService implements RespawnService { + @Override + public void giveSavedItems(Player player) { + + } + + @Override + public void saveItemsBeforeDeath(PlayerDeathEvent event) { + + } +} diff --git a/src/main/java/me/redtea/nodropx/service/respawn/impl/RespawnServiceImpl.java b/src/main/java/me/redtea/nodropx/service/respawn/impl/RespawnServiceImpl.java index a3d9353..c91fe94 100644 --- a/src/main/java/me/redtea/nodropx/service/respawn/impl/RespawnServiceImpl.java +++ b/src/main/java/me/redtea/nodropx/service/respawn/impl/RespawnServiceImpl.java @@ -1,9 +1,12 @@ package me.redtea.nodropx.service.respawn.impl; import lombok.AllArgsConstructor; +import lombok.Data; import lombok.RequiredArgsConstructor; +import lombok.ToString; import me.redtea.nodropx.api.event.NoDropItemDropOnDeathEvent; import me.redtea.nodropx.libs.carcadex.repo.Repo; +import me.redtea.nodropx.service.capasity.CapacityService; import me.redtea.nodropx.service.nodrop.NoDropService; import me.redtea.nodropx.service.respawn.RespawnService; import org.bukkit.Bukkit; @@ -12,12 +15,13 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.inventory.ItemStack; import java.util.*; +import java.util.stream.Collectors; @RequiredArgsConstructor public class RespawnServiceImpl implements RespawnService { private final NoDropService noDropService; private final Map toRespawn = new HashMap<>(); - private final Repo> capacity; + private final CapacityService capacityService; @Override @@ -27,6 +31,7 @@ public class RespawnServiceImpl implements RespawnService { for(Pair pair : pairs) player.getInventory().setItem(pair.slot, pair.item); toRespawn.remove(player.getName()); } + player.updateInventory(); } @Override @@ -60,12 +65,13 @@ public class RespawnServiceImpl implements RespawnService { } @AllArgsConstructor + @ToString static class Pair { int slot; ItemStack item; } private List getProtectedSlots(ItemStack i) { - return capacity.get(i.getType().name()).orElse(new ArrayList<>()); + return capacityService.get(i); } } diff --git a/src/main/java/me/redtea/nodropx/service/storage/impl/StorageServiceImpl.java b/src/main/java/me/redtea/nodropx/service/storage/impl/StorageServiceImpl.java index 956743f..b864e4b 100644 --- a/src/main/java/me/redtea/nodropx/service/storage/impl/StorageServiceImpl.java +++ b/src/main/java/me/redtea/nodropx/service/storage/impl/StorageServiceImpl.java @@ -1,7 +1,7 @@ package me.redtea.nodropx.service.storage.impl; import lombok.RequiredArgsConstructor; -import me.redtea.nodropx.gui.facade.GuiFacade; +import me.redtea.nodropx.menu.facade.MenuFacade; import me.redtea.nodropx.libs.carcadex.repo.MutableRepo; import me.redtea.nodropx.service.nodrop.NoDropService; import me.redtea.nodropx.service.storage.StorageService; @@ -14,17 +14,17 @@ import java.util.UUID; @RequiredArgsConstructor public class StorageServiceImpl implements StorageService { - private final GuiFacade guiFacade; + private final MenuFacade menuFacade; private final MutableRepo> pagesRepo; private final NoDropService noDropService; @Override public void addItem(UUID playerId, ItemStack item) { - List items = pagesRepo.get(playerId).orElse(new ArrayList<>()); + List items = new ArrayList<>(pagesRepo.get(playerId).orElse(new ArrayList<>())); if(!noDropService.isNoDrop(item)) throw new IllegalArgumentException("Item must be no drop!"); items.add(item); pagesRepo.update(playerId, items); - guiFacade.clearCache(Bukkit.getPlayer(playerId)); + menuFacade.clearCache(Bukkit.getPlayer(playerId)); } @Override @@ -33,7 +33,7 @@ public class StorageServiceImpl implements StorageService { if(items == null) return; items.remove(item); pagesRepo.update(playerId, items); - guiFacade.clearCache(Bukkit.getPlayer(playerId)); + menuFacade.clearCache(Bukkit.getPlayer(playerId)); } @Override diff --git a/src/main/java/me/redtea/nodropx/util/ConfigVerifier.java b/src/main/java/me/redtea/nodropx/util/ConfigVerifier.java new file mode 100644 index 0000000..fa78114 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/util/ConfigVerifier.java @@ -0,0 +1,37 @@ +package me.redtea.nodropx.util; + +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.MemoryConfiguration; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.Plugin; + +import java.util.HashMap; +import java.util.Map; + +/* + Verify for versions: + - 1.0.2 + - 1.0.3 + */ +public class ConfigVerifier { + public void verifyDefaults(Plugin plugin) { + Map properties = new HashMap(){{ + put("forceUseLegacy", false); + put("forceUseMD5Colors", false); + + //1.0.3 + put("checkForUpdates", true); + put("personalStorageType", "SINGLE_PAGE"); + put("confirmThrowNoDropItem", true); + put("forceUseFoliaPatches", false); + }}; + + plugin.saveDefaultConfig(); + FileConfiguration config = plugin.getConfig(); + for(Map.Entry entry : properties.entrySet()) { + if(!config.contains(entry.getKey(), true)) + plugin.getConfig().set(entry.getKey(), entry.getValue()); + } + plugin.saveConfig(); + } +} diff --git a/src/main/java/me/redtea/nodropx/util/FoliaSupportedUtils.java b/src/main/java/me/redtea/nodropx/util/FoliaSupportedUtils.java new file mode 100644 index 0000000..93c8f25 --- /dev/null +++ b/src/main/java/me/redtea/nodropx/util/FoliaSupportedUtils.java @@ -0,0 +1,18 @@ +package me.redtea.nodropx.util; + +import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +@RequiredArgsConstructor +public class FoliaSupportedUtils { + private final Plugin plugin; + + public void runTask(Runnable runnable) { + try { + Bukkit.getScheduler().runTask(plugin, runnable); + } catch (UnsupportedOperationException e) { + new Thread(runnable).start(); + } + } +} diff --git a/src/main/java/me/redtea/nodropx/util/MaterialUtils.java b/src/main/java/me/redtea/nodropx/util/MaterialUtils.java index 4f5fc65..aba6f01 100644 --- a/src/main/java/me/redtea/nodropx/util/MaterialUtils.java +++ b/src/main/java/me/redtea/nodropx/util/MaterialUtils.java @@ -7,7 +7,7 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; public class MaterialUtils { - public void remove(Inventory inventory, Material type, int amount) { + public static void remove(Inventory inventory, Material type, int amount) { if (amount <= 0) return; int size = inventory.getSize(); for (int slot = 0; slot < size; slot++) { diff --git a/src/main/java/me/redtea/nodropx/util/UpdateChecker.java b/src/main/java/me/redtea/nodropx/util/UpdateChecker.java index 53952d8..a296d9c 100644 --- a/src/main/java/me/redtea/nodropx/util/UpdateChecker.java +++ b/src/main/java/me/redtea/nodropx/util/UpdateChecker.java @@ -1,6 +1,5 @@ package me.redtea.nodropx.util; -import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import java.io.IOException; @@ -12,14 +11,19 @@ import java.util.function.Consumer; public class UpdateChecker { private final JavaPlugin plugin; private final int resourceId; + private final FoliaSupportedUtils foliaSupportedUtils; - public UpdateChecker(JavaPlugin plugin, int resourceId) { + + public UpdateChecker(JavaPlugin plugin, int resourceId, FoliaSupportedUtils foliaSupportedUtils) { this.plugin = plugin; this.resourceId = resourceId; + + this.foliaSupportedUtils = foliaSupportedUtils; } + public void getVersion(final Consumer consumer) { - Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { + foliaSupportedUtils.runTask(() -> { try (InputStream is = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId).openStream(); Scanner scann = new Scanner(is)) { if (scann.hasNext()) { consumer.accept(scann.next()); @@ -28,5 +32,7 @@ public class UpdateChecker { plugin.getLogger().info("Unable to check for updates: " + e.getMessage()); } }); + + } } diff --git a/src/main/resources/capacity.yml b/src/main/resources/capacity.yml index 1b2b149..d042d69 100644 --- a/src/main/resources/capacity.yml +++ b/src/main/resources/capacity.yml @@ -1 +1,3 @@ -CHAINMAIL_HELMET: [ 9, 10, 11, 12, 13, 14, 15, 16, 17 ] \ No newline at end of file +CHAINMAIL_HELMET: [ 9, 10, 11, 12, 13, 14, 15, 16, 17 ] +#MATERIAL->CUSTOM_MODEL_DATA +DIAMOND_HELMET->1000: [ 9, 10, 11, 12, 13, 14, 15, 16, 17 ] \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ac87002..08f186f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,3 +1,10 @@ forceUseLegacy: false forceUseMD5Colors: false -checkForUpdates: true \ No newline at end of file +forceUseFoliaPatches: false + +checkForUpdates: true + +confirmThrowNoDropItem: true + +#Can be SINGLE_PAGE or MULTI_PAGES +personalStorageType: SINGLE_PAGE diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ed9c779..71d3686 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,6 +6,7 @@ description: Set no drop status to your items author: itzRedTea authors: [itzRedTea] softdepend: [ItemsAdder] +folia-supported: true permissions: nodropx.give: diff --git a/src/main/resources/text/legacy/messages.yml b/src/main/resources/text/legacy/messages.yml index 1de5e53..abf7639 100644 --- a/src/main/resources/text/legacy/messages.yml +++ b/src/main/resources/text/legacy/messages.yml @@ -17,13 +17,26 @@ noConsole: "&4&l[!] &cOnly players can use it!" noExists: "&4&l[!] &cThis player doesnt exists!" gui: - title: "&lPersonal storage" - frame: - name: "&7" - material: GLASS_PANE - prev: - name: "&cPrevious" - material: ARROW - next: - name: "&cNext" - material: ARROW \ No newline at end of file + confirm: + title: "&lConfirm drop" + yesButton: + name: "&aYES" + lore: + - "&7Confirm throw no drop item" + material: ARROW + noButton: + name: "&cNO" + lore: + - "&7Cancel throw no drop item" + material: ARROW + personalStorage: + title: "&lPersonal storage" + frame: + name: "&7" + material: GLASS_PANE + prev: + name: "&cPrevious" + material: ARROW + next: + name: "&cNext" + material: ARROW \ No newline at end of file diff --git a/src/main/resources/text/md5/cosmetics.yml b/src/main/resources/text/md5/cosmetics.yml index 51bf120..3d2847f 100644 --- a/src/main/resources/text/md5/cosmetics.yml +++ b/src/main/resources/text/md5/cosmetics.yml @@ -1,3 +1,4 @@ #name: "No drop" lore: - - "&7[&a✔&7] Dcf0cNcd41fo fd932dIdd46rMe259obe76cp eec7fiRf192tVf5a6eYfab9mdffcc!!" \ No newline at end of file + - "&7[&a✔&7] Dcf0cNcd41fo fd932dIdd46rMe259obe76cp eec7fiRf192tVf5a6eYfab9mdffcc!!" + diff --git a/src/main/resources/text/md5/messages.yml b/src/main/resources/text/md5/messages.yml index 1de5e53..6628936 100644 --- a/src/main/resources/text/md5/messages.yml +++ b/src/main/resources/text/md5/messages.yml @@ -17,13 +17,26 @@ noConsole: "&4&l[!] &cOnly players can use it!" noExists: "&4&l[!] &cThis player doesnt exists!" gui: - title: "&lPersonal storage" - frame: - name: "&7" - material: GLASS_PANE - prev: - name: "&cPrevious" - material: ARROW - next: - name: "&cNext" - material: ARROW \ No newline at end of file + confirm: + title: "&lConfirm drop" + yesButton: + name: "&aYES" + lore: + - "&7Confirm throw no drop item" + material: GREEN_WOOL + noButton: + name: "&cNO" + lore: + - "&7Cancel throw no drop item" + material: RED_WOOL + personalStorage: + title: "&lPersonal storage" + frame: + name: "&7" + material: GLASS_PANE + prev: + name: "&cPrevious" + material: ARROW + next: + name: "&cNext" + material: ARROW \ No newline at end of file diff --git a/src/main/resources/text/mm/cosmetics.yml b/src/main/resources/text/mm/cosmetics.yml index b9d0365..c59c3ea 100644 --- a/src/main/resources/text/mm/cosmetics.yml +++ b/src/main/resources/text/mm/cosmetics.yml @@ -1,3 +1,3 @@ #name: "No drop" lore: - - "[✔] No drop item!" \ No newline at end of file + - "[✔] No drop item!" diff --git a/src/main/resources/text/mm/messages.yml b/src/main/resources/text/mm/messages.yml index a94ff17..e250a6c 100644 --- a/src/main/resources/text/mm/messages.yml +++ b/src/main/resources/text/mm/messages.yml @@ -17,13 +17,26 @@ noConsole: "[!] Only players can use it!" noExists: "[!] This player doesnt exists!" gui: - title: "Personal storage" - frame: - name: "" - material: GLASS_PANE - prev: - name: "Previous" - material: ARROW - next: - name: "Next" - material: ARROW \ No newline at end of file + confirm: + title: "Confirm throw" + yesButton: + name: "YES" + lore: + - "Confirm throw no drop item" + material: GREEN_WOOL + noButton: + name: "NO" + lore: + - "Cancel throw no drop item" + material: RED_WOOL + personalStorage: + title: "Personal storage" + frame: + name: "" + material: GLASS_PANE + prev: + name: "Previous" + material: ARROW + next: + name: "Next" + material: ARROW \ No newline at end of file