Merge pull request #75 from JEFF-Media-GbR/invunload

8.11.0 release
This commit is contained in:
mfnalex 2020-06-24 17:56:43 +02:00 committed by GitHub
commit 202fdebd3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 556 additions and 470 deletions

View File

@ -1,8 +1,13 @@
# Changelog
## 9.0.0-SNAPSHOT1
- Using new universal Update (https://github.com/JEFF-Media-GbR/Spigot-UpdateChecker)
- TODO: InvUnload integration (see TODO.md)
## 8.11.0
- Adjustet Left-Click / Right-Click hotkeys:
- Left-Click outside of inventories will put matching items from your inventory into the chest
- Double-Left-Click will put all items into the chest
- Right-Click outside of inventories will put matching items from the chest into your inventory
- Double-Right-Click will put all items into your inventory
- Using new universal Update checker (https://github.com/JEFF-Media-GbR/Spigot-UpdateChecker)
Note: The last two messages in the config.yml have changed, so please retranslate them. I am also always happy to integrate your translations into the default config.yml if you send them to me.
## 8.10.5
- Added reload command (/chestsort reload) with permission chestsort.reload
- ChestSort checks if Minepacks version is recent enough and, if not, disable the Minepacks hook.

View File

@ -58,7 +58,9 @@ Enable/disable automatic inventory sorting[/SIZE]
Allows usage of automatic chest sorting and the /chestsort command.[/SIZE]
[SIZE=4][B]chestsort.use.inventory[/B]
Allows usage of automatic inventory sorting and the /invsort command.[/SIZE]
Allows usage of automatic inventory sorting and the /invsort command.
If you don't want to use a permissions plugin, you can also set "use-permissions" to false in the config.yml to allow every player to use ChestSort.[/SIZE]
[SIZE=6]Hotkeys[/SIZE]
You can use hotkeys to sort inventories without having to enter commands. This is useful if you only want to sort chests from time to time without having to enable the automatic sorting, or if you quickly want to sort your player inventory. Each hotkey can be enabled/disabled in the config.yml. By default, all hotkeys are enabled. Additionally, players can enable/disable each hotkey individually by running [I]/chestsort hotkeys
@ -87,7 +89,7 @@ Puts your stuff (except hotbar) into the chest, barrel etc.
[B]Right-Click outside inventory[/B]
Empties the chest, barrel etc. into your inventory
[IMG]http://api.jeff-media.de/chestsort/spigotmc/img/fillchest.gif[/IMG]
[IMG]http://api.jeff-media.de/chestsort/spigotmc/img/fillchest.gif[/IMG]
[SIZE=4][SIZE=6][COLOR=rgb(89, 179, 0)]Demo Servers[/COLOR][/SIZE][/SIZE][/SIZE]
[SIZE=4][SIZE=4][COLOR=rgb(89, 179, 0)][FONT=Trebuchet MS][B][I]Join one of our demo servers. You will be in creative mode. Take a chest and lots of random stuff. [/I][/B][/FONT][B][FONT=Trebuchet MS][I]Then toggle automatic chest sorting with /chestsort. Place the chest anywhere [/I][/FONT][/B][FONT=Trebuchet MS][B][I]and fill it[/I][/B][/FONT][B][FONT=Trebuchet MS][I]. It will be magically sorted when you close it. You can disable sorting by using /chestsort again. You can also use hotkeys (middle-click, shift-click, double-click and shift+right-click).[/I][/FONT][/B][/COLOR][/SIZE]
@ -107,7 +109,7 @@ Empties the chest, barrel etc. into your inventory
[SIZE=4][SIZE=6]WorldGuard and other protection plugins[/SIZE][/SIZE]
[SIZE=4]ChestSort will only sort chests that the player has access to. In other words: when some other plugin like WorldGuard prevents access to the chest, then ChestSort will not sort this chest.
This applies to all plugins that cancel the InventoryOpenEvent, as ChestSort will only sort when the InventoryCloseEvent is called.
[B]Furthermore, chests will not be sorted if the player is a spectator or in adventure mode.[/B][/SIZE]
Furthermore, chests will not be sorted if the player is a spectator or in adventure mode.[/SIZE]
[SIZE=4][SIZE=6]Notes[/SIZE][/SIZE]
[SIZE=4]To view the source code, please visit [URL]https://github.com/JEFF-Media-GbR/Spigot-ChestSort[/URL][/SIZE]
@ -120,7 +122,7 @@ This applies to all plugins that cancel the InventoryOpenEvent, as ChestSort wil
[SIZE=4]Please note that sorting in versions [B]before 1.13[/B] can be a bit random sometimes, because some item names were inconsistent (e.g. acacia stairs in 1.8 are named "acacia_stairs", while oak planks are just called "planks".) [B]The sorting algorithm has been optimized for 1.13+ only[/B].[/SIZE]
[SIZE=4]The sorting algorithm is extremely fast. It takes [B]less than half a millisecond[/B] to sort a chest.[/SIZE]
[SIZE=4]The sorting algorithm is extremely fast and should not have any effect on your server performance. Sorting a double chest takes about a quarter of a millisecond.[/SIZE]
[SIZE=6]3rd party Plugins[/SIZE]
[SIZE=4]ChestSort can hook into certain 3rd party plugins if they are installed on your server to allow better sorting for custom items.
@ -131,8 +133,8 @@ All CrackShot weapons will be grouped together and will be put into the default
[B]InventoryPages[/B]
ChestSort will ignore the "Next Page" and "Prev. Page" buttons when you have InventoryPages installed, so that your GUI does not get messed up.
[B]Better Shulker Boxes / Minepacks / ShulkerPacks[/B][/SIZE]
[SIZE=4]Sort your backpacks just like every other chest! Should work with almost every backpack plugin.
[B]Better Shulker Boxes / Minepacks / ShulkerPacks[/B]
Sort your backpacks just like every other chest! Should work with almost every backpack plugin.
[B]Plugins using GUI inventories[/B]
ChestSort tries to detect GUI inventories created by 3rd party plugins. If this detection fails, please message me at GitHub so that I can add support for that plugin.
@ -149,7 +151,7 @@ You can view the default configuration file [URL='https://github.com/JEFF-Media-
[/SIZE]
[SIZE=6]Other Plugins by me[/SIZE]
[SIZE=4]No time for putting your stuff into the right chests? Try out InvUnload:
[URL='https://www.spigotmc.org/resources/1-13-alpha-invunload.60095/'][1.13+] InvUnload: Automatically puts your stuff in the right chests![/URL]
[URL='https://www.spigotmc.org/resources/1-13-alpha-invunload.60095/'][1.12-1.15] InvUnload: Automatically puts your stuff in the right chests![/URL]
Tired of climbing trees like a monkey?
[URL='https://www.spigotmc.org/resources/1-13-lumberjack.60306/'][1.13+] LumberJack: Enable tree gravity for easy woodcutting.[/URL]
@ -158,4 +160,4 @@ May the odds be ever in your favor! Have an angel protect your loot when you die
[URL='https://www.spigotmc.org/resources/1-13-angelchest.60383/'][1.13+] AngelChest: Stores your inventory in a protected chest when you die![/URL]
Don't want to collect all drops manually? Use Drop2Inventory. Also reduces lag.
[URL='https://www.spigotmc.org/resources/1-13-drop2inventory.62214/'][1.13] Drop2Inventory: No more need to collect drops![/URL][/SIZE]
[URL='https://www.spigotmc.org/resources/1-13-drop2inventory.62214/'][1.13+] Drop2Inventory: No more need to collect drops![/URL][/SIZE]

View File

@ -1,6 +1,4 @@
# Todo
## InvUnload integration
Use InvUnload API to only put matching stuff into the chest when using left-click hotkey. On second click, everything is put into the chest.
## StackableItems
Make it configurable whether ItemStacks > 64 items will stay unsorted, or sorted and reverted back to stacks of 64 items

View File

@ -9,7 +9,7 @@
<name>JeffChestSort</name>
<url>https://www.chestsort.de</url>
<description>Automatically sorts your chests!</description>
<version>9.0.0-SNAPSHOT2</version>
<version>8.11.0</version>
<packaging>jar</packaging>
<properties>

View File

@ -1,5 +1,7 @@
package de.jeff_media.ChestSort;
import de.jeff_media.ChestSort.hooks.MinepacksHook;
import de.jeff_media.ChestSort.utils.LlamaUtils;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
@ -13,484 +15,495 @@ import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import de.jeff_media.ChestSort.hooks.MinepacksHook;
import de.jeff_media.ChestSort.utils.LlamaUtils;
public class ChestSortListener implements Listener {
ChestSortPlugin plugin;
MinepacksHook minepacksHook;
ChestSortPlugin plugin;
MinepacksHook minepacksHook;
ChestSortListener(ChestSortPlugin plugin) {
this.plugin = plugin;
this.minepacksHook = new MinepacksHook(plugin);
}
ChestSortListener(ChestSortPlugin plugin) {
this.plugin = plugin;
this.minepacksHook = new MinepacksHook(plugin);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
plugin.permissionsHandler.addPermissions(event.getPlayer());
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
// OPs will get an update notice if a new update is available
if (event.getPlayer().isOp()) {
plugin.updateChecker.sendUpdateMessage(event.getPlayer());
}
plugin.permissionsHandler.addPermissions(event.getPlayer());
// Put player into our perPlayerSettings map
plugin.registerPlayerIfNeeded(event.getPlayer());
// OPs will get an update notice if a new update is available
if (event.getPlayer().isOp()) {
plugin.updateChecker.sendUpdateMessage(event.getPlayer());
}
}
// Put player into our perPlayerSettings map
plugin.registerPlayerIfNeeded(event.getPlayer());
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
plugin.permissionsHandler.removePermissions(event.getPlayer());
plugin.unregisterPlayer(event.getPlayer());
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
plugin.permissionsHandler.removePermissions(event.getPlayer());
plugin.unregisterPlayer(event.getPlayer());
}
@EventHandler
public void onBackPackClose(InventoryCloseEvent event) {
if(plugin.getConfig().getString("sort-time").equalsIgnoreCase("close")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))
onBackPackUse(event.getInventory(),(Player)event.getPlayer());
}
@EventHandler
public void onBackPackOpen(InventoryOpenEvent event) {
if(plugin.getConfig().getString("sort-time").equalsIgnoreCase("open")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))
onBackPackUse(event.getInventory(),(Player)event.getPlayer());
}
void onBackPackUse(Inventory inv, Player p) {
if(!minepacksHook.isMinepacksBackpack(inv)) return;
if( !p.hasPermission("chestsort.use")) return;
plugin.registerPlayerIfNeeded(p);
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
if(!setting.sortingEnabled) return;
plugin.organizer.sortInventory(inv);
}
@EventHandler
public void onPlayerInventoryClose(InventoryCloseEvent event) {
if(event.getInventory()==null) return;
if(event.getInventory().getHolder()==null) return;
if(event.getInventory().getType() == null) return;
if(event.getInventory().getType() != InventoryType.CRAFTING) return; // Weird! Returns CRAFTING instead of PLAYER
if(!(event.getInventory().getHolder() instanceof Player)) return;
@EventHandler
public void onBackPackClose(InventoryCloseEvent event) {
if (plugin.getConfig().getString("sort-time").equalsIgnoreCase("close")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))
onBackPackUse(event.getInventory(), (Player) event.getPlayer());
}
Player p = (Player) event.getInventory().getHolder();
if( !p.hasPermission("chestsort.use.inventory")) return;
plugin.registerPlayerIfNeeded(p);
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
if(!setting.invSortingEnabled) return;
plugin.organizer.sortInventory(p.getInventory(),9,35);
}
@EventHandler
public void onBackPackOpen(InventoryOpenEvent event) {
if (plugin.getConfig().getString("sort-time").equalsIgnoreCase("open")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))
onBackPackUse(event.getInventory(), (Player) event.getPlayer());
}
// This event fires when someone closes an inventory
// We check if the closed inventory belongs to a chest, shulkerbox or barrel,
// and then call the Organizer to sort the inventory (if the player has
// the chestsort.use permission and has /chestsort enabled)
@EventHandler
public void onChestClose(InventoryCloseEvent event) {
void onBackPackUse(Inventory inv, Player p) {
if (!minepacksHook.isMinepacksBackpack(inv)) return;
if (!p.hasPermission("chestsort.use")) return;
plugin.registerPlayerIfNeeded(p);
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
if (!setting.sortingEnabled) return;
plugin.organizer.sortInventory(inv);
}
if (!(plugin.getConfig().getString("sort-time").equalsIgnoreCase("close")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))) {
return;
}
@EventHandler
public void onPlayerInventoryClose(InventoryCloseEvent event) {
if (event.getInventory() == null) return;
if (event.getInventory().getHolder() == null) return;
if (event.getInventory().getType() == null) return;
if (event.getInventory().getType() != InventoryType.CRAFTING)
return; // Weird! Returns CRAFTING instead of PLAYER
if (!(event.getInventory().getHolder() instanceof Player)) return;
// event.getPlayer returns HumanEntity, so it could also be an NPC or something
if (!(event.getPlayer() instanceof Player)) {
return;
}
Player p = (Player) event.getPlayer();
Inventory inventory = event.getInventory();
Player p = (Player) event.getInventory().getHolder();
if (!belongsToChestLikeBlock(inventory) && !LlamaUtils.belongsToLlama(inventory)) {
return;
}
if (!p.hasPermission("chestsort.use.inventory")) return;
plugin.registerPlayerIfNeeded(p);
if (!isReadyToSort(p)) {
return;
}
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
if (!setting.invSortingEnabled) return;
// Finally call the Organizer to sort the inventory
// Llama inventories need special start/end slots
if(LlamaUtils.belongsToLlama(event.getInventory())) {
ChestedHorse llama = (ChestedHorse) event.getInventory().getHolder();
plugin.organizer.sortInventory(event.getInventory(), 2, LlamaUtils.getLlamaChestSize(llama)+1);
return;
}
// Normal container inventories can be sorted completely
plugin.organizer.sortInventory(event.getInventory());
plugin.organizer.sortInventory(p.getInventory(), 9, 35);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onChestOpen(InventoryOpenEvent event) {
// This event fires when someone closes an inventory
// We check if the closed inventory belongs to a chest, shulkerbox or barrel,
// and then call the Organizer to sort the inventory (if the player has
// the chestsort.use permission and has /chestsort enabled)
@EventHandler
public void onChestClose(InventoryCloseEvent event) {
if (!(plugin.getConfig().getString("sort-time").equalsIgnoreCase("open")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))) {
return;
}
if (!(plugin.getConfig().getString("sort-time").equalsIgnoreCase("close")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))) {
return;
}
if (event.isCancelled()) {
return;
}
// event.getPlayer returns HumanEntity, so it could also be an NPC or something
if (!(event.getPlayer() instanceof Player)) {
return;
}
Player p = (Player) event.getPlayer();
Inventory inventory = event.getInventory();
// event.getPlayer returns HumanEntity, so it could also be an NPC or something
if (!(event.getPlayer() instanceof Player)) {
return;
}
Player p = (Player) event.getPlayer();
Inventory inventory = event.getInventory();
if (!belongsToChestLikeBlock(inventory) && !LlamaUtils.belongsToLlama(inventory)) {
return;
}
if (!belongsToChestLikeBlock(inventory) && !LlamaUtils.belongsToLlama(inventory)) {
return;
}
if (!isReadyToSort(p)) {
return;
}
if (!isReadyToSort(p)) {
return;
}
// Finally call the Organizer to sort the inventory
// Finally call the Organizer to sort the inventory
// Llama inventories need special start/end slots
if(LlamaUtils.belongsToLlama(event.getInventory())) {
ChestedHorse llama = (ChestedHorse) event.getInventory().getHolder();
plugin.organizer.sortInventory(event.getInventory(), 2, LlamaUtils.getLlamaChestSize(llama)+1);
return;
}
// Normal container inventories can be sorted completely
plugin.organizer.sortInventory(event.getInventory());
// Llama inventories need special start/end slots
if (LlamaUtils.belongsToLlama(event.getInventory())) {
ChestedHorse llama = (ChestedHorse) event.getInventory().getHolder();
plugin.organizer.sortInventory(event.getInventory(), 2, LlamaUtils.getLlamaChestSize(llama) + 1);
return;
}
}
// Normal container inventories can be sorted completely
plugin.organizer.sortInventory(event.getInventory());
private boolean belongsToChestLikeBlock(Inventory inventory) {
}
// Check by InventoryType
if (inventory.getType() == InventoryType.ENDER_CHEST || inventory.getType().name().equalsIgnoreCase("SHULKER_BOX")) {
return true;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onChestOpen(InventoryOpenEvent event) {
// Possible Fix for https://github.com/JEFF-Media-GbR/Spigot-ChestSort/issues/13
if (inventory.getHolder() == null) {
return false;
}
if (!(plugin.getConfig().getString("sort-time").equalsIgnoreCase("open")
|| plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))) {
return;
}
// Check by InventoryHolder
// Only continue if the inventory belongs to one of the following:
// - a chest,
// - double chest,
// - shulkerbox (MC 1.11) (obsolete, is checked above by InventoryType
// - barrel (MC 1.14)
// - Minecart with Chest (MC 1.0)
// NOTE: Hoppers are NOT included because it may break item sorters like those: https://minecraft.gamepedia.com/Tutorials/Hopper#Item_sorter
// NOTE: We use .getClass().toString() for new items instead of directly
// comparing the ENUM, because we
// want to keep compatability between different minecraft versions (e.g. there
// is no BARREL prior 1.14 and no shulker box prior 1.11)
// WARNING: The names are inconsistent! A chest will return
// org.bukkit.craftbukkit.v1_14_R1.block.CraftChest
// in Spigot 1.14 while a double chest returns org.bukkit.block.DoubleChest
if (!(inventory.getHolder() instanceof Chest) && !(inventory.getHolder() instanceof DoubleChest)
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftMinecartChest"))
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftShulkerBox")) //Obsolete, is checked above by InventoryType
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftBarrel"))) {
return false;
}
return true;
}
if (event.isCancelled()) {
return;
}
private boolean isReadyToSort(Player p) {
if ( !p.hasPermission("chestsort.use")) {
return false;
}
// event.getPlayer returns HumanEntity, so it could also be an NPC or something
if (!(event.getPlayer() instanceof Player)) {
return;
}
Player p = (Player) event.getPlayer();
Inventory inventory = event.getInventory();
// checking in lower case for lazy admins
if (plugin.disabledWorlds.contains(p.getWorld().getName().toLowerCase())) {
return false;
}
if (!belongsToChestLikeBlock(inventory) && !LlamaUtils.belongsToLlama(inventory)) {
return;
}
// Don't sort automatically when player is spectator or in adventure mode
// TODO: Make this configurable in config.yml
if (p.getGameMode() == GameMode.SPECTATOR || p.getGameMode() == GameMode.ADVENTURE) {
return false;
}
if (!isReadyToSort(p)) {
return;
}
// Fixes exception when using Spigot's stupid /reload command
plugin.registerPlayerIfNeeded(p);
// Finally call the Organizer to sort the inventory
// Get the current player's settings
// We do not immediately cancel when sorting is disabled because we might want
// to show the hint message
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
// Llama inventories need special start/end slots
if (LlamaUtils.belongsToLlama(event.getInventory())) {
ChestedHorse llama = (ChestedHorse) event.getInventory().getHolder();
plugin.organizer.sortInventory(event.getInventory(), 2, LlamaUtils.getLlamaChestSize(llama) + 1);
return;
}
// Show "how to enable ChestSort" message when ALL of the following criteria are
// met:
// - Player has sorting disabled
// - Player has not seen the message yet (whether or not this resets after a
// logout
// is defined by the config setting "show-message-again-after-logout")
// - "show-message-when-using-chest" is set to true in the config.yml
if (!plugin.isSortingEnabled(p)) {
if (!setting.hasSeenMessage) {
setting.hasSeenMessage = true;
if (plugin.getConfig().getBoolean("show-message-when-using-chest")) {
p.sendMessage(plugin.messages.MSG_COMMANDMESSAGE);
}
}
return false;
}
// Show "how to disable ChestSort" message when ALL of the following criteria
// are met:
// - Player has sorting enabled
// - Player has not seen the message yet (whether or not this resets after a
// logout
// is defined by the config setting "show-message-again-after-logout")
// - "show-message-when-using-chest-and-sorting-is-enabled" is set to true in
// the config.yml
else {
if (!setting.hasSeenMessage) {
setting.hasSeenMessage = true;
if (plugin.getConfig().getBoolean("show-message-when-using-chest-and-sorting-is-enabled")) {
p.sendMessage(plugin.messages.MSG_COMMANDMESSAGE2);
}
}
}
return true;
}
// Normal container inventories can be sorted completely
plugin.organizer.sortInventory(event.getInventory());
@EventHandler
public void onEnderChestOpen(InventoryOpenEvent event) {
}
if (!(event.getPlayer() instanceof Player)) {
return;
}
private boolean belongsToChestLikeBlock(Inventory inventory) {
Player p = (Player) event.getPlayer();
// Check by InventoryType
if (inventory.getType() == InventoryType.ENDER_CHEST || inventory.getType().name().equalsIgnoreCase("SHULKER_BOX")) {
return true;
}
// Check if this is an EnderChest (is there a smarter way?)
if (!event.getInventory().equals(p.getEnderChest())) {
return;
}
// Possible Fix for https://github.com/JEFF-Media-GbR/Spigot-ChestSort/issues/13
if (inventory.getHolder() == null) {
return false;
}
if (isReadyToSort(p)) {
// Check by InventoryHolder
// Only continue if the inventory belongs to one of the following:
// - a chest,
// - double chest,
// - shulkerbox (MC 1.11) (obsolete, is checked above by InventoryType
// - barrel (MC 1.14)
// - Minecart with Chest (MC 1.0)
// NOTE: Hoppers are NOT included because it may break item sorters like those: https://minecraft.gamepedia.com/Tutorials/Hopper#Item_sorter
// NOTE: We use .getClass().toString() for new items instead of directly
// comparing the ENUM, because we
// want to keep compatability between different minecraft versions (e.g. there
// is no BARREL prior 1.14 and no shulker box prior 1.11)
// WARNING: The names are inconsistent! A chest will return
// org.bukkit.craftbukkit.v1_14_R1.block.CraftChest
// in Spigot 1.14 while a double chest returns org.bukkit.block.DoubleChest
if (!(inventory.getHolder() instanceof Chest) && !(inventory.getHolder() instanceof DoubleChest)
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftMinecartChest"))
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftShulkerBox")) //Obsolete, is checked above by InventoryType
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftBarrel"))) {
return false;
}
return true;
}
// Finally call the Organizer to sort the inventory
plugin.organizer.sortInventory(event.getInventory());
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onHotkey(InventoryClickEvent event) {
if(!(event.getWhoClicked() instanceof Player)) {
return;
}
Player p = (Player) event.getWhoClicked();
plugin.registerPlayerIfNeeded(p);
if(!plugin.getConfig().getBoolean("allow-hotkeys")) {
return;
}
// DEBUG START
private boolean isReadyToSort(Player p) {
if (!p.hasPermission("chestsort.use")) {
return false;
}
// checking in lower case for lazy admins
if (plugin.disabledWorlds.contains(p.getWorld().getName().toLowerCase())) {
return false;
}
// Don't sort automatically when player is spectator or in adventure mode
// TODO: Make this configurable in config.yml
if (p.getGameMode() == GameMode.SPECTATOR || p.getGameMode() == GameMode.ADVENTURE) {
return false;
}
// Fixes exception when using Spigot's stupid /reload command
plugin.registerPlayerIfNeeded(p);
// Get the current player's settings
// We do not immediately cancel when sorting is disabled because we might want
// to show the hint message
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
// Show "how to enable ChestSort" message when ALL of the following criteria are
// met:
// - Player has sorting disabled
// - Player has not seen the message yet (whether or not this resets after a
// logout
// is defined by the config setting "show-message-again-after-logout")
// - "show-message-when-using-chest" is set to true in the config.yml
if (!plugin.isSortingEnabled(p)) {
if (!setting.hasSeenMessage) {
setting.hasSeenMessage = true;
if (plugin.getConfig().getBoolean("show-message-when-using-chest")) {
p.sendMessage(plugin.messages.MSG_COMMANDMESSAGE);
}
}
return false;
}
// Show "how to disable ChestSort" message when ALL of the following criteria
// are met:
// - Player has sorting enabled
// - Player has not seen the message yet (whether or not this resets after a
// logout
// is defined by the config setting "show-message-again-after-logout")
// - "show-message-when-using-chest-and-sorting-is-enabled" is set to true in
// the config.yml
else {
if (!setting.hasSeenMessage) {
setting.hasSeenMessage = true;
if (plugin.getConfig().getBoolean("show-message-when-using-chest-and-sorting-is-enabled")) {
p.sendMessage(plugin.messages.MSG_COMMANDMESSAGE2);
}
}
}
return true;
}
@EventHandler
public void onEnderChestOpen(InventoryOpenEvent event) {
if (!(event.getPlayer() instanceof Player)) {
return;
}
Player p = (Player) event.getPlayer();
// Check if this is an EnderChest (is there a smarter way?)
if (!event.getInventory().equals(p.getEnderChest())) {
return;
}
if (isReadyToSort(p)) {
// Finally call the Organizer to sort the inventory
plugin.organizer.sortInventory(event.getInventory());
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onHotkey(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Player p = (Player) event.getWhoClicked();
plugin.registerPlayerIfNeeded(p);
if (!plugin.getConfig().getBoolean("allow-hotkeys")) {
return;
}
// DEBUG START
// p.sendMessage("=====================");
// p.sendMessage("Click type: " + event.getClick().name());
// p.sendMessage("Right click: " + event.isRightClick());
// p.sendMessage("Shift click: " + event.isShiftClick());
// p.sendMessage("=====================");
// DEBUG END
if( !p.hasPermission("chestsort.use") && !p.hasPermission("chestsort.use.inventory")) {
return;
}
//InventoryHolder holder = event.getInventory().getHolder();
if(event.getClickedInventory() == null) {
return;
}
// Possible fix for #57
if(event.getClickedInventory().getHolder() != null
&& event.getClickedInventory().getHolder() == p
&& event.getClickedInventory() != p.getInventory()) return;
// End Possible fix for #57
InventoryHolder holder = event.getClickedInventory().getHolder();
boolean sort = false;
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
// Do not sort the GUI inventory
if(event.getClickedInventory() == setting.guiInventory) {
return;
}
// Prevent player from putting items into GUI inventory
if(event.getInventory() == setting.guiInventory) {
event.setCancelled(true);
return;
}
switch(event.getClick()) {
case MIDDLE:
//if(plugin.getConfig().getBoolean("hotkeys.middle-click")) {
if(setting.middleClick) {
if(event.getWhoClicked().getGameMode() != GameMode.CREATIVE) {
sort=true;
} else {
if(event.getCurrentItem()==null || event.getCurrentItem().getType()==Material.AIR) {
sort=false;
}
}
}
break;
case DOUBLE_CLICK:
//if(plugin.getConfig().getBoolean("hotkeys.double-click")) {
if(setting.doubleClick) {
// We need getCursor() instead of getCurrentItem(), because after picking up the item, it is gone into the cursor
if(event.getCursor() == null || (event.getCursor() != null && event.getCursor().getType() == Material.AIR)) {
sort=true;
}
}
break;
case SHIFT_LEFT:
//if(plugin.getConfig().getBoolean("hotkeys.shift-click")) {
if(setting.shiftClick) {
if(event.getCurrentItem() == null || (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.AIR) ){
sort=true;
}
}
break;
case SHIFT_RIGHT:
//if(plugin.getConfig().getBoolean("hotkeys.shift-right-click")) {
if(setting.shiftRightClick) {
if(event.getCurrentItem() == null || ( event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.AIR)) {
sort=true;
}
}
break;
default:
break;
}
if(!sort) {
return;
}
if(belongsToChestLikeBlock(event.getClickedInventory()) || LlamaUtils.belongsToLlama(event.getClickedInventory()) || minepacksHook.isMinepacksBackpack(event.getClickedInventory())) {
if( !p.hasPermission("chestsort.use")) {
return;
}
if(LlamaUtils.belongsToLlama(event.getClickedInventory())) {
ChestedHorse llama = (ChestedHorse) event.getInventory().getHolder();
plugin.organizer.sortInventory(event.getClickedInventory(), 2, LlamaUtils.getLlamaChestSize(llama)+1);
plugin.organizer.updateInventoryView(event);
return;
}
plugin.organizer.sortInventory(event.getClickedInventory());
plugin.organizer.updateInventoryView(event);
return;
} else if(holder instanceof Player) {
if( !p.hasPermission("chestsort.use.inventory")) {
return;
}
// DEBUG END
if(event.getSlotType() == SlotType.QUICKBAR) {
plugin.organizer.sortInventory(p.getInventory(),0,8);
plugin.organizer.updateInventoryView(event);
return;
}
else if(event.getSlotType() == SlotType.CONTAINER) {
plugin.organizer.sortInventory(p.getInventory(),9,35);
plugin.organizer.updateInventoryView(event);
return;
}
return;
}
}
@EventHandler
public void onAdditionalHotkeys(InventoryClickEvent e) {
if(LlamaUtils.belongsToLlama(e.getInventory()) || LlamaUtils.belongsToLlama(e.getClickedInventory())) {
return;
}
if(!plugin.getConfig().getBoolean("allow-hotkeys")) {
return;
}
if(!(e.getWhoClicked() instanceof Player)) {
return;
}
Player p = (Player) e.getWhoClicked();
// Only continue if clicked outside of the chest
if(e.getClickedInventory()!=null) {
return;
}
// Only continue if hand is empty
if(e.getCursor() != null && e.getCursor().getType() != null && e.getCursor().getType() != Material.AIR) {
return;
}
// Possible fix for #57
if(e.getInventory().getHolder()==null) return;
if(e.getInventory().getHolder() == p && e.getInventory() != p.getInventory()) return;
// End Possible fix for #57
if(e.getInventory().getType() != InventoryType.CHEST
&& e.getInventory().getType() != InventoryType.DISPENSER
&& e.getInventory().getType() != InventoryType.DROPPER
&& e.getInventory().getType() != InventoryType.ENDER_CHEST
&& !e.getInventory().getType().name().equalsIgnoreCase("SHULKER_BOX")
&& (e.getInventory().getHolder() == null || !e.getInventory().getHolder().getClass().toString().endsWith(".CraftBarrel"))) {
return;
}
// Don't sort inventories belonging to BossShopPro
if(e.getInventory()!=null && e.getInventory().getHolder()!=null && e.getInventory().getHolder().getClass().getName().equalsIgnoreCase("org.black_ixx.bossshop.core.BSShopHolder")) {
return;
}
if( !p.hasPermission("chestsort.use")) return;
plugin.registerPlayerIfNeeded(p);
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
ChestSortEvent chestSortEvent = new ChestSortEvent(e.getInventory());
chestSortEvent.loc=e.getWhoClicked().getLocation();
Bukkit.getPluginManager().callEvent(chestSortEvent);
if (chestSortEvent.isCancelled()) {
return;
}
if(e.isLeftClick() && setting.leftClick) {
plugin.organizer.stuffPlayerInventoryIntoAnother(p.getInventory(), e.getInventory());
plugin.organizer.sortInventory(e.getInventory());
plugin.organizer.updateInventoryView(e.getInventory());
} else if(e.isRightClick() && setting.rightClick) {
plugin.organizer.stuffInventoryIntoAnother(e.getInventory(), p.getInventory(),e.getInventory());
}
}
if (!p.hasPermission("chestsort.use") && !p.hasPermission("chestsort.use.inventory")) {
return;
}
//InventoryHolder holder = event.getInventory().getHolder();
if (event.getClickedInventory() == null) {
return;
}
// Possible fix for #57
if (event.getClickedInventory().getHolder() != null
&& event.getClickedInventory().getHolder() == p
&& event.getClickedInventory() != p.getInventory()) return;
// End Possible fix for #57
InventoryHolder holder = event.getClickedInventory().getHolder();
boolean sort = false;
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
// Do not sort the GUI inventory
if (event.getClickedInventory() == setting.guiInventory) {
return;
}
// Prevent player from putting items into GUI inventory
if (event.getInventory() == setting.guiInventory) {
event.setCancelled(true);
return;
}
switch (event.getClick()) {
case MIDDLE:
//if(plugin.getConfig().getBoolean("hotkeys.middle-click")) {
if (setting.middleClick) {
if (event.getWhoClicked().getGameMode() != GameMode.CREATIVE) {
sort = true;
} else {
if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR) {
sort = false;
}
}
}
break;
case DOUBLE_CLICK:
//if(plugin.getConfig().getBoolean("hotkeys.double-click")) {
if (setting.doubleClick) {
// We need getCursor() instead of getCurrentItem(), because after picking up the item, it is gone into the cursor
if (event.getCursor() == null || (event.getCursor() != null && event.getCursor().getType() == Material.AIR)) {
sort = true;
}
}
break;
case SHIFT_LEFT:
//if(plugin.getConfig().getBoolean("hotkeys.shift-click")) {
if (setting.shiftClick) {
if (event.getCurrentItem() == null || (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.AIR)) {
sort = true;
}
}
break;
case SHIFT_RIGHT:
//if(plugin.getConfig().getBoolean("hotkeys.shift-right-click")) {
if (setting.shiftRightClick) {
if (event.getCurrentItem() == null || (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.AIR)) {
sort = true;
}
}
break;
default:
break;
}
if (!sort) {
return;
}
if (belongsToChestLikeBlock(event.getClickedInventory()) || LlamaUtils.belongsToLlama(event.getClickedInventory()) || minepacksHook.isMinepacksBackpack(event.getClickedInventory())) {
if (!p.hasPermission("chestsort.use")) {
return;
}
if (LlamaUtils.belongsToLlama(event.getClickedInventory())) {
ChestedHorse llama = (ChestedHorse) event.getInventory().getHolder();
plugin.organizer.sortInventory(event.getClickedInventory(), 2, LlamaUtils.getLlamaChestSize(llama) + 1);
plugin.organizer.updateInventoryView(event);
return;
}
plugin.organizer.sortInventory(event.getClickedInventory());
plugin.organizer.updateInventoryView(event);
return;
} else if (holder instanceof Player) {
if (!p.hasPermission("chestsort.use.inventory")) {
return;
}
if (event.getSlotType() == SlotType.QUICKBAR) {
plugin.organizer.sortInventory(p.getInventory(), 0, 8);
plugin.organizer.updateInventoryView(event);
return;
} else if (event.getSlotType() == SlotType.CONTAINER) {
plugin.organizer.sortInventory(p.getInventory(), 9, 35);
plugin.organizer.updateInventoryView(event);
return;
}
return;
}
}
@EventHandler
public void onAdditionalHotkeys(InventoryClickEvent e) {
if (LlamaUtils.belongsToLlama(e.getInventory()) || LlamaUtils.belongsToLlama(e.getClickedInventory())) {
return;
}
if (!plugin.getConfig().getBoolean("allow-hotkeys")) {
return;
}
if (!(e.getWhoClicked() instanceof Player)) {
return;
}
Player p = (Player) e.getWhoClicked();
// Only continue if clicked outside of the chest
if (e.getClickedInventory() != null) {
return;
}
// Only continue if hand is empty
if (e.getCursor() != null && e.getCursor().getType() != null && e.getCursor().getType() != Material.AIR) {
return;
}
// Possible fix for #57
if (e.getInventory().getHolder() == null) return;
if (e.getInventory().getHolder() == p && e.getInventory() != p.getInventory()) return;
// End Possible fix for #57
if (e.getInventory().getType() != InventoryType.CHEST
&& e.getInventory().getType() != InventoryType.DISPENSER
&& e.getInventory().getType() != InventoryType.DROPPER
&& e.getInventory().getType() != InventoryType.ENDER_CHEST
&& !e.getInventory().getType().name().equalsIgnoreCase("SHULKER_BOX")
&& (e.getInventory().getHolder() == null || !e.getInventory().getHolder().getClass().toString().endsWith(".CraftBarrel"))) {
return;
}
// Don't sort inventories belonging to BossShopPro
if (e.getInventory() != null && e.getInventory().getHolder() != null && e.getInventory().getHolder().getClass().getName().equalsIgnoreCase("org.black_ixx.bossshop.core.BSShopHolder")) {
return;
}
if (!p.hasPermission("chestsort.use")) return;
plugin.registerPlayerIfNeeded(p);
ChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString());
ChestSortEvent chestSortEvent = new ChestSortEvent(e.getInventory());
chestSortEvent.loc = e.getWhoClicked().getLocation();
Bukkit.getPluginManager().callEvent(chestSortEvent);
if (chestSortEvent.isCancelled()) {
return;
}
if (e.isLeftClick() && setting.leftClick) {
if (setting.getCurrentDoubleClick(plugin, ChestSortPlayerSetting.DoubleClickType.LEFT_CLICK)
== ChestSortPlayerSetting.DoubleClickType.LEFT_CLICK) {
// Left double click: put everything into destination
plugin.organizer.stuffPlayerInventoryIntoAnother(p.getInventory(), e.getInventory(), false);
} else {
// Left single click: put only matching items into destination
plugin.organizer.stuffPlayerInventoryIntoAnother(p.getInventory(), e.getInventory(), true);
}
} else if (e.isRightClick() && setting.rightClick) {
if (setting.getCurrentDoubleClick(plugin, ChestSortPlayerSetting.DoubleClickType.RIGHT_CLICK)
== ChestSortPlayerSetting.DoubleClickType.RIGHT_CLICK) {
// Right double click: put everything into player inventory
plugin.organizer.stuffInventoryIntoAnother(e.getInventory(), p.getInventory(), e.getInventory(), false);
} else {
// Right single click: put only matching items into player inventory
plugin.organizer.stuffInventoryIntoAnother(e.getInventory(), p.getInventory(), e.getInventory(), true);
}
}
//plugin.organizer.sortInventory(e.getInventory());
plugin.organizer.updateInventoryView(e.getInventory());
}
}

View File

@ -70,9 +70,9 @@ public class ChestSortMessages {
MSG_GUI_SHIFTRIGHTCLICK = ChatColor.translateAlternateColorCodes('&', plugin.getConfig()
.getString("message-gui-shift-right-click","Shift + Right-Click"));
MSG_GUI_LEFTCLICK = ChatColor.translateAlternateColorCodes('&', plugin.getConfig().getString("message-gui-left-click","Fill Chest (Left-Click)"));
MSG_GUI_LEFTCLICK = ChatColor.translateAlternateColorCodes('&', plugin.getConfig().getString("message-gui-left-click","Fill Chest (Left-Click/Double-Left-Click)"));
MSG_GUI_RIGHTCLICK = ChatColor.translateAlternateColorCodes('&', plugin.getConfig().getString("message-gui-right-click","Unload Chest (Right-Click)"));
MSG_GUI_RIGHTCLICK = ChatColor.translateAlternateColorCodes('&', plugin.getConfig().getString("message-gui-right-click","Unload Chest (Right-Click/Double-Right-Click)"));
MSG_ERR_HOTKEYSDISABLED = ChatColor.RED + "[ChestSort] Hotkeys have been disabled by the admin.";
}

View File

@ -583,7 +583,7 @@ public class ChestSortOrganizer {
return false;
}
public void stuffInventoryIntoAnother(Inventory source, Inventory destination,Inventory origSource) {
public void stuffInventoryIntoAnother(Inventory source, Inventory destination,Inventory origSource, boolean onlyMatchingStuff) {
Material placeholderMaterial = Material.DIRT;
ItemStack[] hotbarStuff = new ItemStack[9];
@ -604,9 +604,12 @@ public class ChestSortOrganizer {
ArrayList<ItemStack> leftovers = new ArrayList<ItemStack>();
for(int i = 0;i<source.getSize();i++) {
ItemStack current = source.getItem(i);
if(current == null) continue;
if(onlyMatchingStuff && !doesInventoryContain(destination,current.getType())) continue;
if(isOversizedStack(current)) continue;
source.clear(i);
HashMap<Integer,ItemStack> currentLeftovers = destination.addItem(current);
@ -631,8 +634,14 @@ public class ChestSortOrganizer {
}
/*public void stuffPlayerInventoryIntoAnother(PlayerInventory source, Inventory destination) {
stuffPlayerInventoryIntoAnother(source,destination,false);
}*/
public void stuffPlayerInventoryIntoAnother(PlayerInventory source,
Inventory destination) {
Inventory destination, boolean onlyMatchingStuff) {
boolean destinationIsShulkerBox = destination.getType().name().equalsIgnoreCase("SHULKER_BOX");
Inventory temp = Bukkit.createInventory(null, maxInventorySize);
for(int i = playerInvStartSlot;i<=playerInvEndSlot;i++) {
@ -650,11 +659,23 @@ public class ChestSortOrganizer {
if(destinationIsShulkerBox && source.getItem(i).getType().name().endsWith("SHULKER_BOX")) continue;
if(isOversizedStack(source.getItem(i))) continue;
if(onlyMatchingStuff && !doesInventoryContain(destination,source.getItem(i).getType())) continue;
temp.addItem(source.getItem(i));
source.clear(i);
}
stuffInventoryIntoAnother(temp,destination,source);
stuffInventoryIntoAnother(temp,destination,source,false);
}
static boolean doesInventoryContain(Inventory inv, Material mat) {
for(ItemStack item : inv.getContents()) {
if(item==null) continue;
if(item.getType() == mat) {
return true;
}
}
return false;
}
}

View File

@ -1,5 +1,6 @@
package de.jeff_media.ChestSort;
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
public class ChestSortPlayerSetting {
@ -26,6 +27,12 @@ public class ChestSortPlayerSetting {
// Do we have to save these settings?
boolean changed = false;
DoubleClickType currentDoubleClick = DoubleClickType.NONE;
enum DoubleClickType {
NONE, RIGHT_CLICK, LEFT_CLICK;
}
ChestSortPlayerSetting(boolean sortingEnabled, boolean invSortingEnabled, boolean middleClick, boolean shiftClick, boolean doubleClick, boolean shiftRightClick, boolean leftClick, boolean rightClick, boolean changed) {
this.sortingEnabled = sortingEnabled;
this.middleClick = middleClick;
@ -37,6 +44,25 @@ public class ChestSortPlayerSetting {
this.rightClick = rightClick;
this.changed = changed;
}
DoubleClickType getCurrentDoubleClick(ChestSortPlugin plugin, DoubleClickType click) {
if(click == DoubleClickType.NONE) return DoubleClickType.NONE;
if(currentDoubleClick == click) {
currentDoubleClick = DoubleClickType.NONE;
return click;
}
if(currentDoubleClick != click) {
currentDoubleClick = click;
Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
@Override
public void run() {
currentDoubleClick = DoubleClickType.NONE;
}
}, 10);
return DoubleClickType.NONE;
}
return DoubleClickType.NONE;
}
void toggleMiddleClick() {
middleClick = !middleClick;

View File

@ -68,7 +68,7 @@ public class ChestSortPlugin extends JavaPlugin {
String sortingMethod;
ArrayList<String> disabledWorlds;
ChestSortAPI api;
int currentConfigVersion = 32;
int currentConfigVersion = 33;
boolean usingMatchingConfig = true;
protected boolean debug = false;
boolean verbose = true;

View File

@ -107,11 +107,15 @@ sorting-hotkeys:
# Additionally to sorting hotkeys, you can quickly unload your inventory into a chest and vice versa
# using left-click or richt-click outside of a chest's inventory.
# A single click will only affect matching items (items that are already present in the other inventory)
# and a double click will try to store/take all items.
# Players can also enable/disable these shortcuts individually via /chestsort hotkeys
additional-hotkeys:
# Use left-click outside inventory to quickly put your inventory (except hotbar) into the chest
# Use left-click outside inventory to quickly put matching items from your inventory (except hotbar)
# into the chest. Use left-double-click to put everything except your hotbar into the chest.
left-click: false
# Use right-click outside inventory to quickly take all items out of the chest and into your inventory
# Use right-click outside inventory to quickly take all matching items from the chest into your
# inventory. Use right-double-click to take all items out of the chest.
right-click: false
##########################
@ -263,8 +267,8 @@ message-gui-middle-click: "Middle-Click"
message-gui-shift-click: "Shift + Click"
message-gui-double-click: "Double-Click"
message-gui-shift-right-click: "Shift + Right-Click"
message-gui-left-click: "Fill Chest (Left-Click)"
message-gui-right-click: "Empty Chest (Right-Click)"
message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### English
#message-when-using-chest: "&7Hint: Type &6/chestsort&7 to enable automatic chest sorting."
@ -282,10 +286,13 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### Chinese - Thanks to qsefthuopq, Aira-Sakuranomiya and BackWheel for translating!
# Note: The following messages have been changed in version 8.11 and need a new translation:
# - message-gui-left-click
# - message-gui-right-click
#message-when-using-chest: "&7提示: 输入 &6/chestsort&7 来启用自动整理箱子."
#message-when-using-chest2: "&7提示: 输入 &6/chestsort&7 来关闭自动整理箱子."
#message-sorting-disabled: "&7自动整理箱子已 &c关闭&7."
@ -305,6 +312,9 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-right-click: "清空箱子 (右键)"
##### Chinese (Traditional) 繁體中文 - Thanks to Command1264 for translating!
# Note: The following messages have been changed in version 8.11 and need a new translation:
# - message-gui-left-click
# - message-gui-right-click
#message-when-using-chest: "&7小提醒: 輸入 &6/chestsort&7 來開啟自動整理箱子"
#message-when-using-chest2: "&7小提醒: 輸入 &6/chestsort&7 來關閉自動整理箱子"
#message-sorting-disabled: "&7自動整理箱子已 &c關閉&7"
@ -340,10 +350,13 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### French / Français - Thanks to automatizer, demon57730, FichdlMaa and Stalk3r77 for translating!
# Note: The following messages have been changed in version 8.11 and need a new translation:
# - message-gui-left-click
# - message-gui-right-click
#message-when-using-chest: "&7Astuce : Tape &6/chestsort&7 pour activer le classement automatique."
#message-when-using-chest2: "&7Astuce : Tape &6/chestsort&7 pour désactiver le classement automatique."
#message-sorting-disabled: "&7Le classement automatique a été &cdésactivé&7."
@ -378,10 +391,13 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Klick"
#message-gui-double-click: "Doppelklick"
#message-gui-shift-right-click: "Shift + Rechtsklick"
#message-gui-left-click: "Kiste füllen (Linksklick)"
#message-gui-right-click: "Kiste leeren (Rechtsklick)"
#message-gui-left-click: "Kiste füllen (Linksklick/doppelter Linksklick)"
#message-gui-right-click: "Kiste leeren (Rechtsklick/doppelter Rechtsklick)"
##### Hungarian - Thanks to Letter and Polaroli for translating!
# Note: The following messages have been changed in version 8.11 and need a new translation:
# - message-gui-left-click
# - message-gui-right-click
#message-when-using-chest: "&7Automatikus láda rendezés bekapcsolás: &6/chestsort"
#message-when-using-chest2: "&7Automatikus láda rendezés bekapcsolás: &6/chestsort"
#message-sorting-disabled: "&7Automatikus láda rendezés kikapcsolva."
@ -417,10 +433,13 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### Japanese - Thanks to Sefyy for translating!
# Note: The following messages have been changed in version 8.11 and need a new translation:
# - message-gui-left-click
# - message-gui-right-click
#message-when-using-chest: "&7ヒント: &6/chestsort&7 と入力して自動チェスト整理を有効にできます。"
#message-when-using-chest2: "&7ヒント: &6/chestsort&7 と入力すると自動チェスト整理を無効にできます。"
#message-sorting-disabled: "&7自動チェスト整理は現在&c無効&7です。"
@ -456,8 +475,8 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "쉬프트 + 클릭"
#message-gui-double-click: "더블 클릭"
#message-gui-shift-right-click: "쉬프트 + 우클릭"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### Portuguese - Thanks to wildastral for translating!
##### Note: Some messages are still untranslated. Please send me your translation at SpigotMC
@ -476,8 +495,8 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### Russian - Thanks to Gandon for translating!
##### Note: Some messages are still untranslated. Please send me your translation at SpigotMC
@ -496,8 +515,8 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### Spanish - Thanks to Bers_ for translating!
##### Note: Some messages are still untranslated. Please send me your translation at SpigotMC
@ -516,8 +535,8 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
##### Turkish - Thanks to bertek41 for translating!
##### Note: Some messages are still untranslated. Please send me your translation at SpigotMC
@ -536,8 +555,8 @@ message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-shift-click: "Shift + Click"
#message-gui-double-click: "Double-Click"
#message-gui-shift-right-click: "Shift + Right-Click"
#message-gui-left-click: "Fill Chest (Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click)"
#message-gui-left-click: "Fill Chest (Left-Click/Double-Left-Click)"
#message-gui-right-click: "Empty Chest (Right-Click/Double-Right-Click)"
############################
##### Technical stuff! #####
@ -554,4 +573,4 @@ debug: false
# Please DO NOT change the following line manually!
# It is used by the automatic config updater.
config-version: 32
config-version: 33

View File

@ -1,6 +1,6 @@
main: de.jeff_media.ChestSort.ChestSortPlugin
name: ChestSort
version: 9.0.0-SNAPSHOT2
version: 8.11.0
api-version: 1.13
description: Allows automatic chest sorting
author: mfnalex
@ -24,4 +24,6 @@ permissions:
chestsort.use:
description: Allows chest sorting
chestsort.use.inventory:
description: Allows inventory sorting
description: Allows inventory sorting
chestsort.reload:
description: Allows to reload the config via /chestsort reload