mirror of
https://github.com/JEFF-Media-GbR/ChestSort.git
synced 2025-01-22 08:02:33 +01:00
Update JeffChestSortOrganizer.java
comments
This commit is contained in:
parent
93b7882bbf
commit
7b6b024d4f
@ -13,6 +13,9 @@ import org.bukkit.inventory.Inventory;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public class JeffChestSortOrganizer {
|
public class JeffChestSortOrganizer {
|
||||||
|
|
||||||
|
// This is the heart of ChestSort!
|
||||||
|
// All of the sorting stuff happens here.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DEPRECATED: THE FOLLOWING INFOS ARE OUTDATED
|
* DEPRECATED: THE FOLLOWING INFOS ARE OUTDATED
|
||||||
@ -27,24 +30,26 @@ public class JeffChestSortOrganizer {
|
|||||||
|
|
||||||
JeffChestSortPlugin plugin;
|
JeffChestSortPlugin plugin;
|
||||||
|
|
||||||
|
// All available colors in the game. We will strip this from the item names and keep the color in a separate variable
|
||||||
static final String[] colors = { "white", "orange", "magenta", "light_blue", "light_gray", "yellow", "lime", "pink", "gray",
|
static final String[] colors = { "white", "orange", "magenta", "light_blue", "light_gray", "yellow", "lime", "pink", "gray",
|
||||||
"cyan", "purple", "blue", "brown", "green", "red", "black" };
|
"cyan", "purple", "blue", "brown", "green", "red", "black" };
|
||||||
|
|
||||||
|
// The same applies for wood. We strip the wood name from the item name and keep it in the above mentioned color variable
|
||||||
static final String[] woodNames = { "acacia", "birch", "jungle", "oak", "spruce", "dark_oak" };
|
static final String[] woodNames = { "acacia", "birch", "jungle", "oak", "spruce", "dark_oak" };
|
||||||
|
|
||||||
|
// We store a list of all Category objects
|
||||||
ArrayList<JeffChestSortCategory> categories = new ArrayList<JeffChestSortCategory>();
|
ArrayList<JeffChestSortCategory> categories = new ArrayList<JeffChestSortCategory>();
|
||||||
|
|
||||||
JeffChestSortOrganizer(JeffChestSortPlugin plugin) {
|
JeffChestSortOrganizer(JeffChestSortPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
|
||||||
// Load Categories
|
// Load Categories
|
||||||
File categoriesFolder = new File(plugin.getDataFolder().getAbsolutePath() + File.separator + "categories" + File.separator);
|
File categoriesFolder = new File(plugin.getDataFolder().getAbsolutePath() + File.separator + "categories" + File.separator);
|
||||||
File[] listOfCategoryFiles = categoriesFolder.listFiles();
|
File[] listOfCategoryFiles = categoriesFolder.listFiles();
|
||||||
|
|
||||||
for (File file : listOfCategoryFiles) {
|
for (File file : listOfCategoryFiles) {
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
|
// Category name is the filename without .txt
|
||||||
String categoryName = file.getName().replaceFirst(".txt", "");
|
String categoryName = file.getName().replaceFirst(".txt", "");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
categories.add(new JeffChestSortCategory(categoryName,getArrayFromCategoryFile(file)));
|
categories.add(new JeffChestSortCategory(categoryName,getArrayFromCategoryFile(file)));
|
||||||
if(plugin.verbose) {
|
if(plugin.verbose) {
|
||||||
@ -52,13 +57,14 @@ public class JeffChestSortOrganizer {
|
|||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
plugin.getLogger().warning("Could not load category file: "+file.getName());
|
plugin.getLogger().warning("Could not load category file: "+file.getName());
|
||||||
//e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns an array with all typematches listed in the category file
|
||||||
String[] getArrayFromCategoryFile(File file) throws FileNotFoundException {
|
String[] getArrayFromCategoryFile(File file) throws FileNotFoundException {
|
||||||
Scanner sc = new Scanner(file);
|
Scanner sc = new Scanner(file);
|
||||||
List<String> lines = new ArrayList<String>();
|
List<String> lines = new ArrayList<String>();
|
||||||
@ -67,28 +73,35 @@ public class JeffChestSortOrganizer {
|
|||||||
lines.add(sc.nextLine());
|
lines.add(sc.nextLine());
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] arr = lines.toArray(new String[0]);
|
String[] arr = lines.toArray(new String[0]);
|
||||||
sc.close();
|
sc.close();
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Convert the item name to what I call a "sortable item name".
|
||||||
|
// Sorry, the method name is a bit misleading.
|
||||||
|
// The array's [0] value contains the item name with a few fixes, see below
|
||||||
|
// The array's [1] value contains the color or wood name of the item, or "<none>"
|
||||||
String[] getTypeAndColor(String typeName) {
|
String[] getTypeAndColor(String typeName) {
|
||||||
|
|
||||||
// [0] = TypeName
|
// [0] = Sortable Item name
|
||||||
// [1] = Color
|
// [1] = Color/Wood
|
||||||
|
|
||||||
String myColor = "<none>";
|
String myColor = "<none>";
|
||||||
|
|
||||||
|
// Only work with lowercase
|
||||||
typeName = typeName.toLowerCase();
|
typeName = typeName.toLowerCase();
|
||||||
|
|
||||||
|
// When a color occurs at the beginning (e.g. "white_wool"), we omit the color so that the color will not
|
||||||
|
// determine the beginning letters of the sortable item name
|
||||||
for (String color : colors) {
|
for (String color : colors) {
|
||||||
if (typeName.startsWith(color)) {
|
if (typeName.startsWith(color)) {
|
||||||
typeName = typeName.replaceFirst(color + "_", "");
|
typeName = typeName.replaceFirst(color + "_", "");
|
||||||
myColor = color;
|
myColor = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Same for wood, but the wood name can also be in the middle of the item name, e.g. "stripped_oak_log"
|
||||||
for(String woodName : woodNames) {
|
for(String woodName : woodNames) {
|
||||||
if(typeName.equals(woodName+"_wood")) {
|
if(typeName.equals(woodName+"_wood")) {
|
||||||
typeName = "log_wood";
|
typeName = "log_wood";
|
||||||
@ -108,8 +121,8 @@ public class JeffChestSortOrganizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Egg has to be put in front to group spawn eggs
|
// "egg" has to be put in front to group spawn eggs
|
||||||
// E.g. cow_spawn_egg -> egg_cow_spawn
|
// e.g. cow_spawn_egg -> egg_cow_spawn
|
||||||
if(typeName.endsWith("_egg")) {
|
if(typeName.endsWith("_egg")) {
|
||||||
typeName = typeName.replaceFirst("_egg", "");
|
typeName = typeName.replaceFirst("_egg", "");
|
||||||
typeName = "egg_" + typeName;
|
typeName = "egg_" + typeName;
|
||||||
@ -121,16 +134,18 @@ public class JeffChestSortOrganizer {
|
|||||||
typeName = typeName + "_polished";
|
typeName = typeName + "_polished";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Group wet and dry sponges
|
||||||
if(typeName.equalsIgnoreCase("wet_sponge")) {
|
if(typeName.equalsIgnoreCase("wet_sponge")) {
|
||||||
typeName = "sponge_wet";
|
typeName = "sponge_wet";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Group pumpkins and jack-o-lanterns / carved pumpkins
|
||||||
if(typeName.equalsIgnoreCase("carved_pumpkin")) {
|
if(typeName.equalsIgnoreCase("carved_pumpkin")) {
|
||||||
typeName = "pumpkin_carved";
|
typeName = "pumpkin_carved";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort armor: helmet, chestplate, leggings, boots
|
// Sort armor: helmet, chestplate, leggings, boots
|
||||||
|
// We add a number to keep the armor in the "right" order
|
||||||
if(typeName.endsWith("helmet")) {
|
if(typeName.endsWith("helmet")) {
|
||||||
typeName = typeName.replaceFirst("helmet", "1_helmet");
|
typeName = typeName.replaceFirst("helmet", "1_helmet");
|
||||||
} else if(typeName.endsWith("chestplate")) {
|
} else if(typeName.endsWith("chestplate")) {
|
||||||
@ -154,24 +169,24 @@ public class JeffChestSortOrganizer {
|
|||||||
return typeAndColor;
|
return typeAndColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method takes a sortable item name and checks all categories for a match
|
||||||
|
// If none, matches, return "<none>" (it will be put behind all categorized items when sorting by category)
|
||||||
String getCategory(String typeName) {
|
String getCategory(String typeName) {
|
||||||
|
|
||||||
typeName = typeName.toLowerCase();
|
typeName = typeName.toLowerCase();
|
||||||
|
|
||||||
for (JeffChestSortCategory cat : categories) {
|
for (JeffChestSortCategory cat : categories) {
|
||||||
if (cat.matches(typeName)) {
|
if (cat.matches(typeName)) {
|
||||||
return cat.name;
|
return cat.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "<none>";
|
return "<none>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This puts together the sortable item name, the category, the color, and whether the item is a block or a "regular item"
|
||||||
String getSortableString(ItemStack item) {
|
String getSortableString(ItemStack item) {
|
||||||
char blocksFirst;
|
char blocksFirst;
|
||||||
char itemsFirst;
|
char itemsFirst;
|
||||||
if (item.getType().isBlock()) {
|
if (item.getType().isBlock()) {
|
||||||
blocksFirst = '!';
|
blocksFirst = '!'; // ! is before # in ASCII
|
||||||
itemsFirst = '#';
|
itemsFirst = '#';
|
||||||
} else {
|
} else {
|
||||||
blocksFirst = '#';
|
blocksFirst = '#';
|
||||||
@ -183,8 +198,11 @@ public class JeffChestSortOrganizer {
|
|||||||
String color = typeAndColor[1];
|
String color = typeAndColor[1];
|
||||||
String category = getCategory(item.getType().name());
|
String category = getCategory(item.getType().name());
|
||||||
|
|
||||||
|
// The hashcode actually not needed anymore, but I kept it for debugging purposes
|
||||||
String hashCode = String.valueOf(getBetterHash(item));
|
String hashCode = String.valueOf(getBetterHash(item));
|
||||||
|
|
||||||
|
// Generate the strings that finally are used for sorting.
|
||||||
|
// They are generated according to the config.yml's sorting-method option
|
||||||
String sortableString = plugin.sortingMethod.replaceAll("\\{itemsFirst\\}", String.valueOf(itemsFirst));
|
String sortableString = plugin.sortingMethod.replaceAll("\\{itemsFirst\\}", String.valueOf(itemsFirst));
|
||||||
sortableString = sortableString.replaceAll("\\{blocksFirst\\}", String.valueOf(blocksFirst));
|
sortableString = sortableString.replaceAll("\\{blocksFirst\\}", String.valueOf(blocksFirst));
|
||||||
sortableString = sortableString.replaceAll("\\{name\\}", typeName);
|
sortableString = sortableString.replaceAll("\\{name\\}", typeName);
|
||||||
@ -196,10 +214,12 @@ public class JeffChestSortOrganizer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort a complete inventory
|
||||||
void sortInventory(Inventory inv) {
|
void sortInventory(Inventory inv) {
|
||||||
sortInventory(inv,0,inv.getSize()-1);
|
sortInventory(inv,0,inv.getSize()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort an inventory only between startSlot and endSlot
|
||||||
void sortInventory(Inventory inv,int startSlot, int endSlot) {
|
void sortInventory(Inventory inv,int startSlot, int endSlot) {
|
||||||
|
|
||||||
// This has been optimized as of ChestSort 3.2.
|
// This has been optimized as of ChestSort 3.2.
|
||||||
@ -214,20 +234,21 @@ public class JeffChestSortOrganizer {
|
|||||||
// We copy the complete inventory into an array
|
// We copy the complete inventory into an array
|
||||||
ItemStack[] items = inv.getContents();
|
ItemStack[] items = inv.getContents();
|
||||||
|
|
||||||
// Get rid of all stuff before startSlot and after endSlot
|
// Get rid of all stuff before startSlot...
|
||||||
for(int i = 0; i<startSlot;i++) {
|
for(int i = 0; i<startSlot;i++) {
|
||||||
items[i] = null;
|
items[i] = null;
|
||||||
}
|
}
|
||||||
|
// ... and after endSlot
|
||||||
for(int i=endSlot+1;i<inv.getSize();i++) {
|
for(int i=endSlot+1;i<inv.getSize();i++) {
|
||||||
items[i] = null;
|
items[i] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the stuff that we took from the original inventory
|
// Remove the stuff from the original inventory
|
||||||
for(int i = startSlot; i<=endSlot;i++) {
|
for(int i = startSlot; i<=endSlot;i++) {
|
||||||
inv.clear(i);
|
inv.clear(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want to have stacks of null
|
// We don't want to have stacks of null, so we create a new ArrayList and put in everything != null
|
||||||
ArrayList<ItemStack> nonNullItemsList = new ArrayList<ItemStack>();
|
ArrayList<ItemStack> nonNullItemsList = new ArrayList<ItemStack>();
|
||||||
for(ItemStack item : items) {
|
for(ItemStack item : items) {
|
||||||
if(item!=null) {
|
if(item!=null) {
|
||||||
@ -235,38 +256,54 @@ public class JeffChestSortOrganizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need the copied inventory anymore
|
// We no longer need the original array that includes all the null-stacks
|
||||||
items=null;
|
items=null;
|
||||||
|
|
||||||
// We need the list as array
|
// We need the new list as array. So why did'nt we take an array from the beginning?
|
||||||
|
// Because I did not bother to count the number of non-null items beforehand.
|
||||||
|
// TODO: Feel free to make a Pull request if you want to save your server a few nanoseconds :)
|
||||||
ItemStack[] nonNullItems = nonNullItemsList.toArray(new ItemStack[nonNullItemsList.size()]);
|
ItemStack[] nonNullItems = nonNullItemsList.toArray(new ItemStack[nonNullItemsList.size()]);
|
||||||
|
|
||||||
// Sort the array with ItemStacks according to our sortable String
|
// Sort the array with ItemStacks according to each ItemStacks' sortable String
|
||||||
Arrays.sort(nonNullItems,new Comparator<ItemStack>(){
|
Arrays.sort(nonNullItems,new Comparator<ItemStack>(){
|
||||||
public int compare(ItemStack s1,ItemStack s2){
|
public int compare(ItemStack s1,ItemStack s2){
|
||||||
return(getSortableString(s1).compareTo(getSortableString(s2)));
|
return(getSortableString(s1).compareTo(getSortableString(s2)));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
// put everything back in a temporary inventory to combine ItemStacks even when using strict slot sorting
|
// Now, we put everything back in a temporary inventory to combine ItemStacks even when using strict slot sorting
|
||||||
// Thanks to SnackMix for this idea!
|
// Thanks to SnackMix for this idea!
|
||||||
|
// Without doing this, it would not be possible to sort an inventory with a startSlot other than 0,
|
||||||
|
// because Spigot's add(ItemStack...) method will always to store the ItemStack in the first possible slot
|
||||||
|
|
||||||
|
// Create the temporary inventory with a null holder. 54 slots is enough for every inventory
|
||||||
Inventory tempInventory = Bukkit.createInventory(null, 54); //cannot be bigger than 54 as of 1.14
|
Inventory tempInventory = Bukkit.createInventory(null, 54); //cannot be bigger than 54 as of 1.14
|
||||||
|
|
||||||
for(ItemStack item : nonNullItems) {
|
for(ItemStack item : nonNullItems) {
|
||||||
if(plugin.debug) System.out.println(getSortableString(item));
|
if(plugin.debug) System.out.println(getSortableString(item));
|
||||||
|
// Add the item to the temporary inventory
|
||||||
tempInventory.addItem(item);
|
tempInventory.addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now, we iterate through all slots between startSlot and endSlot in the original inventory
|
||||||
|
// and set those to whatever the temporary inventory contains
|
||||||
|
// Since we already deleted all those slots, there is no chance for item duplication
|
||||||
int currentSlot = startSlot;
|
int currentSlot = startSlot;
|
||||||
for(ItemStack item : tempInventory.getContents()) {
|
for(ItemStack item : tempInventory.getContents()) {
|
||||||
if(item==null) continue;
|
// Ignore null ItemStacks. TODO: Actually, we could skip the for-loop here because
|
||||||
|
// our temporary inventory was already sorted. Feel free to make a pull request to
|
||||||
|
// save your server half a nanosecond :)
|
||||||
|
if(item==null) continue;
|
||||||
inv.setItem(currentSlot, item);
|
inv.setItem(currentSlot, item);
|
||||||
currentSlot++;
|
currentSlot++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I wanted to fix the skull problems here. Instead, I ended up not using the hashCode at all.
|
||||||
|
// I still left this here for nostalgic reasons. Also it is nice to see the hashcodes when debug is enabled
|
||||||
|
// TODO: feel free to remove this and all references, it is really not needed anymore.
|
||||||
private static int getBetterHash(ItemStack item) {
|
private static int getBetterHash(ItemStack item) {
|
||||||
// I wanted to fix the skull problems here. Instead, I ended up not using the hashCode at all.
|
// I used to add some metadata here, but it has been removed since a long time
|
||||||
// I still left this here because it is nice to see the hashcodes when debug is enabled
|
// as I said: feel free to remove this completely
|
||||||
return item.hashCode();
|
return item.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user