sorting on open now possible

This commit is contained in:
mfnalex 2019-05-02 15:28:39 +02:00
parent cc2777c017
commit af0931dcb3
3 changed files with 202 additions and 103 deletions

View File

@ -3,7 +3,6 @@ package de.jeffclan.JeffChestSort;
import java.util.UUID; import java.util.UUID;
import java.io.File; import java.io.File;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest; import org.bukkit.block.DoubleChest;
@ -12,11 +11,14 @@ import org.bukkit.block.ShulkerBox;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
public class JeffChestSortListener implements Listener { public class JeffChestSortListener implements Listener {
@ -30,10 +32,11 @@ public class JeffChestSortListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
// DEBUG // DEBUG
// Checking for my username because I always forget to comment this out before releases // Checking for my username because I always forget to comment this out before
//if (event.getPlayer().getName().equalsIgnoreCase("mfnalex")) { // releases
// plugin.debug = true; // if (event.getPlayer().getName().equalsIgnoreCase("mfnalex")) {
//} // plugin.debug = true;
// }
// OPs will get an update notice if a new update is available // OPs will get an update notice if a new update is available
if (event.getPlayer().isOp()) { if (event.getPlayer().isOp()) {
@ -43,14 +46,14 @@ public class JeffChestSortListener implements Listener {
// Put player into our perPlayerSettings map // Put player into our perPlayerSettings map
registerPlayerIfNeeded(event.getPlayer()); registerPlayerIfNeeded(event.getPlayer());
} }
// Put player into our perPlayerSettings map // Put player into our perPlayerSettings map
void registerPlayerIfNeeded(Player p) { void registerPlayerIfNeeded(Player p) {
// Players are stored by their UUID, so that name changes don't break player's settings // Players are stored by their UUID, so that name changes don't break player's
// settings
UUID uniqueId = p.getUniqueId(); UUID uniqueId = p.getUniqueId();
// Add player to map only if they aren't registered already // Add player to map only if they aren't registered already
if (!plugin.PerPlayerSettings.containsKey(uniqueId.toString())) { if (!plugin.PerPlayerSettings.containsKey(uniqueId.toString())) {
@ -62,7 +65,8 @@ public class JeffChestSortListener implements Listener {
boolean activeForThisPlayer = false; boolean activeForThisPlayer = false;
if (!playerFile.exists()) { if (!playerFile.exists()) {
// If the player settings file does not exist for this player, set it to the default value // If the player settings file does not exist for this player, set it to the
// default value
activeForThisPlayer = plugin.getConfig().getBoolean("sorting-enabled-by-default"); activeForThisPlayer = plugin.getConfig().getBoolean("sorting-enabled-by-default");
} else { } else {
// If the file exists, check if the player has sorting enabled // If the file exists, check if the player has sorting enabled
@ -70,12 +74,13 @@ public class JeffChestSortListener implements Listener {
} }
JeffChestSortPlayerSetting newSettings = new JeffChestSortPlayerSetting(activeForThisPlayer); JeffChestSortPlayerSetting newSettings = new JeffChestSortPlayerSetting(activeForThisPlayer);
// when "show-message-again-after-logout" is enabled, we don't care if the player already saw the message // when "show-message-again-after-logout" is enabled, we don't care if the
// player already saw the message
if (!plugin.getConfig().getBoolean("show-message-again-after-logout")) { if (!plugin.getConfig().getBoolean("show-message-again-after-logout")) {
newSettings.hasSeenMessage = playerConfig.getBoolean("hasSeenMessage"); newSettings.hasSeenMessage = playerConfig.getBoolean("hasSeenMessage");
} }
// Finally add the PlayerSetting object to the map // Finally add the PlayerSetting object to the map
plugin.PerPlayerSettings.put(uniqueId.toString(), newSettings); plugin.PerPlayerSettings.put(uniqueId.toString(), newSettings);
@ -87,28 +92,21 @@ public class JeffChestSortListener implements Listener {
plugin.unregisterPlayer(event.getPlayer()); plugin.unregisterPlayer(event.getPlayer());
} }
@EventHandler
public void onInventoryEvent(InventoryEvent event) {
plugin.getLogger().info("InventoryEvent");
}
// This event fires when someone closes an inventory // This event fires when someone closes an inventory
// We check if the closed inventory belongs to a chest, shulkerbox or barrel, // 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 // and then call the Organizer to sort the inventory (if the player has
// the chestsort.use permission and has /chestsort enabled) // the chestsort.use permission and has /chestsort enabled)
@EventHandler @EventHandler
public void onInventoryClose(InventoryCloseEvent event) { public void onChestClose(InventoryCloseEvent event) {
// Only continue if the inventory belongs to a chest, double chest, shulkerbox or barrel if (!(plugin.getConfig().getString("sort-time").equalsIgnoreCase("close")
// NOTE: We use .getClass().toString() for new items instead of directly comparing the ENUM, because we || plugin.getConfig().getString("sort-time").equalsIgnoreCase("both"))) {
// want to keep compatability between different minecraft versions (e.g. there is no BARREL prior 1.14)
// 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
// Possible Fix for https://github.com/JEFF-Media-GbR/Spigot-ChestSort/issues/13
if(event.getInventory().getHolder() == null) {
return;
}
if (!(event.getInventory().getHolder() instanceof Chest)
&& !(event.getInventory().getHolder() instanceof DoubleChest)
&& !(event.getInventory().getHolder() instanceof ShulkerBox)
&& !(event.getInventory().getHolder().getClass().toString().endsWith(".CraftBarrel"))) {
return; return;
} }
@ -117,14 +115,74 @@ public class JeffChestSortListener implements Listener {
return; return;
} }
Player p = (Player) event.getPlayer(); Player p = (Player) event.getPlayer();
Inventory inventory = event.getInventory();
if(isReadyToSort(p)) { if(!belongsToChestLikeBlock(inventory)) {
return;
}
if (isReadyToSort(p)) {
// Finally call the Organizer to sort the inventory // Finally call the Organizer to sort the inventory
plugin.organizer.sortInventory(event.getInventory()); plugin.organizer.sortInventory(event.getInventory());
} }
} }
@EventHandler(priority=EventPriority.MONITOR)
public void onChestClose(InventoryOpenEvent event) {
if (!(plugin.getConfig().getString("sort-time").equalsIgnoreCase("open")
|| 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();
if(!belongsToChestLikeBlock(inventory)) {
return;
}
if (isReadyToSort(p)) {
// Finally call the Organizer to sort the inventory
plugin.organizer.sortInventory(event.getInventory());
}
}
private boolean belongsToChestLikeBlock(Inventory inventory) {
// Possible Fix for https://github.com/JEFF-Media-GbR/Spigot-ChestSort/issues/13
if (inventory.getHolder() == null) {
return false;
}
// Only continue if the inventory belongs to a chest, double chest, shulkerbox
// or barrel
// 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)
// 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() instanceof ShulkerBox)
&& !(inventory.getHolder().getClass().toString().endsWith(".CraftBarrel"))) {
return false;
}
return true;
}
private boolean isReadyToSort(Player p) { private boolean isReadyToSort(Player p) {
if (!p.hasPermission("chestsort.use")) { if (!p.hasPermission("chestsort.use")) {
@ -132,7 +190,7 @@ public class JeffChestSortListener implements Listener {
} }
// checking in lower case for lazy admins // checking in lower case for lazy admins
if(plugin.disabledWorlds.contains(p.getWorld().getName().toLowerCase())) { if (plugin.disabledWorlds.contains(p.getWorld().getName().toLowerCase())) {
return false; return false;
} }
@ -146,14 +204,16 @@ public class JeffChestSortListener implements Listener {
registerPlayerIfNeeded(p); registerPlayerIfNeeded(p);
// Get the current player's settings // Get the current player's settings
// We do not immediately cancel when sorting is disabled because we might want to show the hint message // We do not immediately cancel when sorting is disabled because we might want
// to show the hint message
JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString());
// Show "how to enable ChestSort" message when ALL of the following criteria are met: // Show "how to enable ChestSort" message when ALL of the following criteria are
// met:
// - Player has sorting disabled // - Player has sorting disabled
// - Player has not seen the message yet (whether or not this resets after a logout // - Player has not seen the message yet (whether or not this resets after a
// is defined by the config setting "show-message-again-after-logout") // 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 // - "show-message-when-using-chest" is set to true in the config.yml
if (!plugin.sortingEnabled(p)) { if (!plugin.sortingEnabled(p)) {
if (!setting.hasSeenMessage) { if (!setting.hasSeenMessage) {
@ -164,11 +224,14 @@ public class JeffChestSortListener implements Listener {
} }
return false; return false;
} }
// Show "how to disable ChestSort" message when ALL of the following criteria are met: // Show "how to disable ChestSort" message when ALL of the following criteria
// are met:
// - Player has sorting enabled // - Player has sorting enabled
// - Player has not seen the message yet (whether or not this resets after a logout // - Player has not seen the message yet (whether or not this resets after a
// is defined by the config setting "show-message-again-after-logout") // logout
// - "show-message-when-using-chest-and-sorting-is-enabled" is set to true in the config.yml // 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 { else {
if (!setting.hasSeenMessage) { if (!setting.hasSeenMessage) {
setting.hasSeenMessage = true; setting.hasSeenMessage = true;
@ -179,26 +242,26 @@ public class JeffChestSortListener implements Listener {
} }
return true; return true;
} }
@EventHandler @EventHandler
public void onInventoryOpen(InventoryOpenEvent event) public void onEnderChestOpen(InventoryOpenEvent event) {
{
if(!(event.getPlayer() instanceof Player)) { if (!(event.getPlayer() instanceof Player)) {
return; return;
} }
Player p = (Player) event.getPlayer(); Player p = (Player) event.getPlayer();
// Check if this is an EnderChest (is there a smarter way?) // Check if this is an EnderChest (is there a smarter way?)
if(!event.getInventory().equals(p.getEnderChest())) { if (!event.getInventory().equals(p.getEnderChest())) {
return; return;
} }
if(isReadyToSort(p)) { if (isReadyToSort(p)) {
// Finally call the Organizer to sort the inventory // Finally call the Organizer to sort the inventory
plugin.organizer.sortInventory(event.getInventory()); plugin.organizer.sortInventory(event.getInventory());
} }
} }
} }

View File

@ -96,44 +96,42 @@ public class JeffChestSortPlugin extends JavaPlugin {
// Config version prior to 5? Then it must have been generated by ChestSort 1.x // Config version prior to 5? Then it must have been generated by ChestSort 1.x
if (getConfig().getInt("config-version", 0) < 5) { if (getConfig().getInt("config-version", 0) < 5) {
getLogger().warning("========================================================"); renameConfigIfTooOld();
getLogger().warning("You are using a config file that has been generated");
getLogger().warning("prior to ChestSort version 2.0.0.");
getLogger().warning("To allow everyone to use the new features, your config");
getLogger().warning("has been renamed to config.old.yml and a new one has");
getLogger().warning("been generated. Please examine the new config file to");
getLogger().warning("see the new possibilities and adjust your settings.");
getLogger().warning("========================================================");
File configFile = new File(getDataFolder().getAbsolutePath() + File.separator + "config.yml");
File oldConfigFile = new File(getDataFolder().getAbsolutePath() + File.separator + "config.old.yml");
if (oldConfigFile.getAbsoluteFile().exists()) {
oldConfigFile.getAbsoluteFile().delete();
}
configFile.getAbsoluteFile().renameTo(oldConfigFile.getAbsoluteFile());
saveDefaultConfig();
try {
getConfig().load(configFile.getAbsoluteFile());
} catch (IOException | InvalidConfigurationException e) {
getLogger().warning("Could not load freshly generated config file!");
e.printStackTrace();
}
// Using old config version, but it's no problem. We just print a warning and // Using old config version, but it's no problem. We just print a warning and
// use the default values later on // use the default values later on
} else if (getConfig().getInt("config-version", 0) != currentConfigVersion) { } else if (getConfig().getInt("config-version", 0) != currentConfigVersion) {
getLogger().warning("========================================================"); showOldConfigWarning();
getLogger().warning("YOU ARE USING AN OLD CONFIG FILE!");
getLogger().warning("This is not a problem, as ChestSort will just use the");
getLogger().warning("default settings for unset values. However, if you want");
getLogger().warning("to configure the new options, please go to");
getLogger().warning("https://www.chestsort.de and replace your config.yml");
getLogger().warning("with the new one. You can then insert your old changes");
getLogger().warning("into the new file.");
getLogger().warning("========================================================");
usingMatchingConfig = false; usingMatchingConfig = false;
} }
createDirectories();
setDefaultConfigValues();
// Load disabled-worlds. If it does not exist in the config, it returns null.
// That's no problem
disabledWorlds = (ArrayList<String>) getConfig().getStringList("disabled-worlds");
}
private void setDefaultConfigValues() {
// If you use an old config file with missing options, the following default
// values will be used instead
// for every missing option.
// By default, sorting is disabled. Every player has to run /chestsort once
getConfig().addDefault("sorting-enabled-by-default", false);
getConfig().addDefault("show-message-when-using-chest", true);
getConfig().addDefault("show-message-when-using-chest-and-sorting-is-enabled", false);
getConfig().addDefault("show-message-again-after-logout", true);
getConfig().addDefault("sorting-method", "{category},{itemsFirst},{name},{color}");
getConfig().addDefault("allow-player-inventory-sorting", false);
getConfig().addDefault("check-for-updates", "true");
getConfig().addDefault("auto-generate-category-files", true);
getConfig().addDefault("sort-time", "close");
getConfig().addDefault("verbose", true); // Prints some information in onEnable()
}
private void createDirectories() {
// Create a playerdata folder that contains all the perPlayerSettings as .yml // Create a playerdata folder that contains all the perPlayerSettings as .yml
File playerDataFolder = new File(getDataFolder().getPath() + File.separator + "playerdata"); File playerDataFolder = new File(getDataFolder().getPath() + File.separator + "playerdata");
if (!playerDataFolder.getAbsoluteFile().exists()) { if (!playerDataFolder.getAbsoluteFile().exists()) {
@ -147,24 +145,43 @@ public class JeffChestSortPlugin extends JavaPlugin {
if (!categoriesFolder.getAbsoluteFile().exists()) { if (!categoriesFolder.getAbsoluteFile().exists()) {
categoriesFolder.mkdir(); categoriesFolder.mkdir();
} }
}
// If you use an old config file with missing options, the following default private void showOldConfigWarning() {
// values will be used instead getLogger().warning("========================================================");
// for every missing option. getLogger().warning("YOU ARE USING AN OLD CONFIG FILE!");
// By default, sorting is disabled. Every player has to run /chestsort once getLogger().warning("This is not a problem, as ChestSort will just use the");
getConfig().addDefault("sorting-enabled-by-default", false); getLogger().warning("default settings for unset values. However, if you want");
getConfig().addDefault("show-message-when-using-chest", true); getLogger().warning("to configure the new options, please go to");
getConfig().addDefault("show-message-when-using-chest-and-sorting-is-enabled", false); getLogger().warning("https://www.chestsort.de and replace your config.yml");
getConfig().addDefault("show-message-again-after-logout", true); getLogger().warning("with the new one. You can then insert your old changes");
getConfig().addDefault("sorting-method", "{category},{itemsFirst},{name},{color}"); getLogger().warning("into the new file.");
getConfig().addDefault("allow-player-inventory-sorting", false); getLogger().warning("========================================================");
getConfig().addDefault("check-for-updates", "true"); }
getConfig().addDefault("auto-generate-category-files", true);
getConfig().addDefault("verbose", true); // Prints some information in onEnable()
// Load disabled-worlds. If it does not exist in the config, it returns null. private void renameConfigIfTooOld() {
// That's no problem getLogger().warning("========================================================");
disabledWorlds = (ArrayList<String>) getConfig().getStringList("disabled-worlds"); getLogger().warning("You are using a config file that has been generated");
getLogger().warning("prior to ChestSort version 2.0.0.");
getLogger().warning("To allow everyone to use the new features, your config");
getLogger().warning("has been renamed to config.old.yml and a new one has");
getLogger().warning("been generated. Please examine the new config file to");
getLogger().warning("see the new possibilities and adjust your settings.");
getLogger().warning("========================================================");
File configFile = new File(getDataFolder().getAbsolutePath() + File.separator + "config.yml");
File oldConfigFile = new File(getDataFolder().getAbsolutePath() + File.separator + "config.old.yml");
if (oldConfigFile.getAbsoluteFile().exists()) {
oldConfigFile.getAbsoluteFile().delete();
}
configFile.getAbsoluteFile().renameTo(oldConfigFile.getAbsoluteFile());
saveDefaultConfig();
try {
getConfig().load(configFile.getAbsoluteFile());
} catch (IOException | InvalidConfigurationException e) {
getLogger().warning("Could not load freshly generated config file!");
e.printStackTrace();
}
} }
@Override @Override
@ -222,6 +239,7 @@ public class JeffChestSortPlugin extends JavaPlugin {
getLogger().info("Current sorting method: " + sortingMethod); getLogger().info("Current sorting method: " + sortingMethod);
getLogger().info("Sorting enabled by default: " + getConfig().getBoolean("sorting-enabled-by-default")); getLogger().info("Sorting enabled by default: " + getConfig().getBoolean("sorting-enabled-by-default"));
getLogger().info("Auto generate category files: " + getConfig().getBoolean("auto-generate-category-files")); getLogger().info("Auto generate category files: " + getConfig().getBoolean("auto-generate-category-files"));
getLogger().info("Sort time: " + getConfig().getString("sort-time"));
getLogger().info("Check for updates: " + getConfig().getString("check-for-updates")); getLogger().info("Check for updates: " + getConfig().getString("check-for-updates"));
} }

View File

@ -41,6 +41,24 @@ show-message-again-after-logout: true
# files will be overwritten on each server startup. # files will be overwritten on each server startup.
auto-generate-category-files: true auto-generate-category-files: true
# you can choose when ChestSort should sort chests.
# The default option is to sort when an inventory is closed.
# This is useful, because the onInventoryClose event never
# gets fired when access to the chest is forbidden by
# another plugin, e.g. WorldGuard
# You can also sort whenenver a chest is opened.
# ChestSort will check if the onInventoryOpenEvent gets
# cancelled. If it does get cancelled, ChestSort will
# not sort the chest. However, if a plugin uses the
# MONITOR event priority, ChestSort cannot detect this.
# If you have problems with unaccessible chests being
# sorted, set this option to "close".
# If you want, you can sort twice, however this is not
# very useful.
# Available options:
# open, close, both
sort-time: close
# should we check for updates? # should we check for updates?
# when enabled, a message is printed in the console if a new # when enabled, a message is printed in the console if a new
# version has been found, and OPs will be notified when they # version has been found, and OPs will be notified when they