Merge pull request #18 from JEFF-Media-GbR/linenumbers

4.3.1-beta
This commit is contained in:
JEFF 2019-05-03 03:44:01 +02:00 committed by GitHub
commit af55239476
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 280 additions and 50 deletions

View File

@ -6,7 +6,7 @@
<groupId>de.jeffclan</groupId>
<artifactId>JeffChestSort</artifactId>
<version>4.2</version>
<version>4.3.1-dev</version>
<packaging>jar</packaging>
<name>JeffChestSort</name>

View File

@ -1,5 +1,7 @@
package de.jeffclan.JeffChestSort;
import de.jeffclan.utils.TypeMatchPositionPair;
public class JeffChestSortCategory {
// Represents a sorting category
@ -11,21 +13,22 @@ public class JeffChestSortCategory {
// "COARSE_DIRT" will match the typeMatch "*dirt"
String name;
String[] typeMatches;
TypeMatchPositionPair[] typeMatches;
JeffChestSortCategory(String name, String[] typeMatches) {
JeffChestSortCategory(String name, TypeMatchPositionPair[] typeMatchPositionPairs) {
this.name = name;
this.typeMatches = typeMatches;
this.typeMatches = typeMatchPositionPairs;
}
// Checks whether a the given itemname fits into this category
boolean matches(String itemname) {
// Checks whether a the given itemname fits into this category and returns the line number. 0 means not found
short matches(String itemname) {
boolean asteriskBefore = false;
boolean asteriskAfter = false;
// Very, very simple wildcard checks
for (String typeMatch : typeMatches) {
for (TypeMatchPositionPair typeMatchPositionPair : typeMatches) {
String typeMatch = typeMatchPositionPair.getTypeMatch();
if (typeMatch.startsWith("*")) {
asteriskBefore = true;
typeMatch = typeMatch.substring(1);
@ -37,24 +40,24 @@ public class JeffChestSortCategory {
if (asteriskBefore == false && asteriskAfter == false) {
if (itemname.equalsIgnoreCase(typeMatch)) {
return true;
return typeMatchPositionPair.getPosition();
}
} else if (asteriskBefore == true && asteriskAfter == true) {
if (itemname.contains(typeMatch)) {
return true;
return typeMatchPositionPair.getPosition();
}
} else if (asteriskBefore == true && asteriskAfter == false) {
if (itemname.endsWith(typeMatch)) {
return true;
return typeMatchPositionPair.getPosition();
}
} else {
if (itemname.startsWith(typeMatch)) {
return true;
return typeMatchPositionPair.getPosition();
}
}
}
return false;
return 0;
}
}

View File

@ -2,6 +2,7 @@ package de.jeffclan.JeffChestSort;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@ -12,6 +13,9 @@ import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import de.jeffclan.utils.CategoryLinePair;
import de.jeffclan.utils.TypeMatchPositionPair;
public class JeffChestSortOrganizer {
// This is the heart of ChestSort!
@ -34,6 +38,8 @@ public class JeffChestSortOrganizer {
// 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" };
private static final String emptyPlaceholderString= "~";
// We store a list of all Category objects
ArrayList<JeffChestSortCategory> categories = new ArrayList<JeffChestSortCategory>();
@ -42,13 +48,24 @@ public class JeffChestSortOrganizer {
// Load Categories
File categoriesFolder = new File(plugin.getDataFolder().getAbsolutePath() + File.separator + "categories" + File.separator);
File[] listOfCategoryFiles = categoriesFolder.listFiles();
File[] listOfCategoryFiles = categoriesFolder.listFiles(new FilenameFilter() {
public boolean accept(File directory, String fileName) {
if (!fileName.endsWith(".txt")) {
return false;
}
if (fileName.matches("(?i)^\\d\\d\\d.*\\.txt$")) // Category between 900 and 999-... are default categories
{
return true;
}
return false;
}
});
for (File file : listOfCategoryFiles) {
if (file.isFile()) {
// Category name is the filename without .txt
String categoryName = file.getName().replaceFirst(".txt", "");
try {
categories.add(new JeffChestSortCategory(categoryName,getArrayFromCategoryFile(file)));
categories.add(new JeffChestSortCategory(categoryName,loadCategoryFile(file)));
if(plugin.verbose) {
plugin.getLogger().info("Loaded category file "+file.getName());
}
@ -62,17 +79,17 @@ public class JeffChestSortOrganizer {
}
// Returns an array with all typematches listed in the category file
String[] getArrayFromCategoryFile(File file) throws FileNotFoundException {
TypeMatchPositionPair[] loadCategoryFile(File file) throws FileNotFoundException {
Scanner sc = new Scanner(file);
List<String> lines = new ArrayList<String>();
List<TypeMatchPositionPair> lines = new ArrayList<TypeMatchPositionPair>();
short currentLine=1;
while (sc.hasNextLine()) {
//if(!sc.nextLine().startsWith("#")) {
lines.add(sc.nextLine());
//}
lines.add(new TypeMatchPositionPair(sc.nextLine(),currentLine));
currentLine++;
}
String[] arr = lines.toArray(new String[0]);
TypeMatchPositionPair[] result = lines.toArray(new TypeMatchPositionPair[0]);
sc.close();
return arr;
return result;
}
@ -85,7 +102,7 @@ public class JeffChestSortOrganizer {
// [0] = Sortable Item name
// [1] = Color/Wood
String myColor = "<none>";
String myColor = (plugin.debug) ? "~color~" : emptyPlaceholderString;
// Only work with lowercase
typeName = typeName.toLowerCase();
@ -168,16 +185,18 @@ public class JeffChestSortOrganizer {
// 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) {
CategoryLinePair getCategoryLinePair(String typeName) {
typeName = typeName.toLowerCase();
for (JeffChestSortCategory cat : categories) {
if (cat.matches(typeName)) {
return cat.name;
short matchingLineNumber = cat.matches(typeName);
if (matchingLineNumber!=0) {
return new CategoryLinePair(cat.name,matchingLineNumber);
}
}
return "<none>";
return new CategoryLinePair((plugin.debug) ? "~category~" : emptyPlaceholderString,(short) 0);
}
// 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) {
char blocksFirst;
@ -193,24 +212,36 @@ public class JeffChestSortOrganizer {
String[] typeAndColor = getTypeAndColor(item.getType().name());
String typeName = typeAndColor[0];
String color = typeAndColor[1];
String category = getCategory(item.getType().name());
String category = getCategoryLinePair(item.getType().name()).getCategoryName();
String customName = (plugin.debug) ? "~customName~" : emptyPlaceholderString;
if(item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName()!=null) {
customName=item.getItemMeta().getDisplayName();
}
String lore =(plugin.debug)? "~lore~" : emptyPlaceholderString;
if(item.getItemMeta().hasLore() && item.getItemMeta().getLore() != null && item.getItemMeta().getLore().size()!=0) {
String[] loreArray=item.getItemMeta().getLore().toArray(new String[0]);
lore = String.join(",", loreArray);
}
String lineNumber = getCategoryLinePair(item.getType().name()).getFormattedPosition();
// The hashcode actually not needed anymore, but I kept it for debugging purposes
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(",", "|");
sortableString = sortableString.replaceAll("\\{itemsFirst\\}", String.valueOf(itemsFirst));
sortableString = sortableString.replaceAll("\\{blocksFirst\\}", String.valueOf(blocksFirst));
sortableString = sortableString.replaceAll("\\{name\\}", typeName);
sortableString = sortableString.replaceAll("\\{color\\}", color);
sortableString = sortableString.replaceAll("\\{category\\}", category);
sortableString = sortableString + "," + hashCode;
sortableString = sortableString.replaceAll("\\{line\\}", lineNumber);
sortableString = sortableString.replaceAll("\\{customName\\}", customName);
sortableString = sortableString.replaceAll("\\{lore\\}", lore);
return sortableString;
}
// Sort a complete inventory
void sortInventory(Inventory inv) {
sortInventory(inv,0,inv.getSize()-1);
@ -296,13 +327,5 @@ public class JeffChestSortOrganizer {
}
}
// 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) {
// I used to add some metadata here, but it has been removed since a long time
// as I said: feel free to remove this completely
return item.hashCode();
}
}

View File

@ -32,6 +32,7 @@ package de.jeffclan.JeffChestSort;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -59,7 +60,7 @@ public class JeffChestSortPlugin extends JavaPlugin {
JeffChestSortListener listener;
String sortingMethod;
ArrayList<String> disabledWorlds;
int currentConfigVersion = 9;
int currentConfigVersion = 10;
boolean usingMatchingConfig = true;
boolean debug = false;
boolean verbose = true;
@ -198,6 +199,8 @@ public class JeffChestSortPlugin extends JavaPlugin {
// the default values for unset options
createConfig();
debug = getConfig().getBoolean("debug");
// Save default sorting category files when enabled in the config (default=true)
saveDefaultCategories();
@ -261,12 +264,11 @@ public class JeffChestSortPlugin extends JavaPlugin {
}
registerMetrics();
}
private void registerMetrics() {
// Metrics will need json-simple with 1.14 API.
// Metrics will need json-simple with 1.14 API.
Metrics metrics = new Metrics(this);
metrics.addCustomChart(new Metrics.SimplePie("sorting_method", () -> sortingMethod));
metrics.addCustomChart(new Metrics.SimplePie("config_version",
@ -284,6 +286,8 @@ public class JeffChestSortPlugin extends JavaPlugin {
metrics.addCustomChart(
new Metrics.SimplePie("using_matching_config_version", () -> Boolean.toString(usingMatchingConfig)));
metrics.addCustomChart(new Metrics.SimplePie("sort_time", () -> getConfig().getString("sort-time")));
metrics.addCustomChart(new Metrics.SimplePie("auto_generate_category_files",
() -> Boolean.toString(getConfig().getBoolean("auto-generate-category-files"))));
}
// Saves default category files, when enabled in the config
@ -296,7 +300,39 @@ public class JeffChestSortPlugin extends JavaPlugin {
// Isn't there a smarter way to find all the 9** files in the .jar?
String[] defaultCategories = { "900-tools", "910-valuables", "920-combat", "930-brewing", "940-food",
"950-redstone", "960-wood", "970-stone", "980-plants", "981-corals" };
"950-redstone", "960-wood", "970-stone", "980-plants", "981-corals","_ReadMe - Category files" };
// Delete all files starting with 9..
for (File file : new File(getDataFolder().getAbsolutePath() + File.separator + "categories" + File.separator)
.listFiles(new FilenameFilter() {
public boolean accept(File directory, String fileName) {
if (!fileName.endsWith(".txt")) {
return false;
}
if (fileName.matches("(?i)9\\d\\d.*\\.txt$")) // Category between 900 and 999-... are default
// categories
{
return true;
}
return false;
}
})) {
boolean delete = true;
for (String name : defaultCategories) {
name=name+".txt";
if (name.equalsIgnoreCase(file.getName())) {
delete = false;
break;
}
}
if (delete) {
file.delete();
getLogger().warning("Deleting deprecated default category file " + file.getName());
}
}
for (String category : defaultCategories) {

View File

@ -0,0 +1,26 @@
package de.jeffclan.utils;
public class CategoryLinePair {
String categoryName;
String formattedPosition;
short position;
public CategoryLinePair(String categoryName,short position) {
this.categoryName=categoryName;
this.formattedPosition=Utils.shortToStringWithLeadingZeroes(position);
this.position=position;
}
public String getCategoryName() {
return categoryName;
}
public String getFormattedPosition() {
return formattedPosition;
}
public int getPosition() {
return position;
}
}

View File

@ -0,0 +1,27 @@
package de.jeffclan.utils;
public class TypeMatchPositionPair {
String typeMatch;
String formattedPosition;
public String getTypeMatch() {
return typeMatch;
}
public short getPosition() {
return position;
}
public String getFormattedPosition() {
return formattedPosition;
}
short position;
public TypeMatchPositionPair(String typeMatch,short position) {
this.typeMatch=typeMatch;
this.position=position;
this.formattedPosition=Utils.shortToStringWithLeadingZeroes(position);
}
}

View File

@ -28,4 +28,8 @@ public class Utils {
}
return buf;
}
public static String shortToStringWithLeadingZeroes(short number) {
return String.format("%05d", number);
}
}

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
*_pickaxe
*_shovel
*_hoe

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
diamond
emerald
diamond_ore

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
turtle_helmet
bow
arrow

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
ghast_tear
potion
glass_bottle

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
apple
baked_potato
beef

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
dispenser
note_block
sticky_piston

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
*_planks
*_sapling
*_log

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
stone
cobblestone
granite

View File

@ -1,3 +1,11 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
grass
fern
dead_bush

View File

@ -1 +1,9 @@
#
# ChestSort Default Category File
#
# If you want to change this file, rename it.
# Please do NOT use file prefixed between 900 and 999 for
# your custom files because ChestSort will overwrite them
#
*_coral*

View File

@ -0,0 +1,23 @@
#############
# ChestSort #
#############
You can define custom category files for ChestSort using simple .txt files.
If you have {category} in your sorting-method, it will get replaced with the category name.
Category names are determined by the file names. The name must start with a number ranging
from 000 to 899 and end with .txt
Default categories are prefixed with 900 to 999. Please do not edit the default categories.
You can instead copy or rename the default files and edit those instead.
WARNING: All files with names starting between 900 and 999 will be deleted on start.
If you put {keepCategoryOrder} behind {category} in the sorting-method, the items will be
ordered exactly as listed in the category files. Otherwise, they will be grouped by category
and then sorted according to the remaining variables in your sorting-method.
Category files can contain asterisks (*) as wildcard character at the beginning and/or end
of an expression, but not in the middle.
Category files can also contain comments using the hashtag (#) symbol

View File

@ -39,6 +39,8 @@ show-message-again-after-logout: true
# If you wish to edit those, you can disable the generation of these
# files, because otherwise all your changes in the pregenerated
# files will be overwritten on each server startup.
# However, a much smarter option is to copy the default files
# and rename them to from 900... to 800... and edit those instead.
auto-generate-category-files: true
# you can choose when ChestSort should sort chests.
@ -90,11 +92,14 @@ disabled-worlds:
# Only change this if you know what you are doing.
#
# Available variables:
# {category} order stuff by category as defined in plugins/ChestSort/categories/<category>.txt
# {itemsFirst} put items before blocks
# {blocksFirst} put blocks before items
# {name} returns the name (e.g. DIRT, GRASS_BLOCK, BIRCH_LOG, DIAMOND_SWORD, ...)
# {color} returns the color, e.g. light_blue for wool. Empty if block/item is not dyeable
# {category} order stuff by category as defined in plugins/ChestSort/categories/<category>.txt
# {keepCategoryOrder} orders stuff in the same category according to their line numbers in the category file
# {itemsFirst} put items before blocks
# {blocksFirst} put blocks before items
# {name} returns the name (e.g. DIRT, GRASS_BLOCK, BIRCH_LOG, DIAMOND_SWORD, ...)
# {color} returns the color, e.g. light_blue for wool. Empty if block/item is not dyeable
# {customName} returns the display name if set (e.g. with an anvil)
# {lore} returns the lore if set
#
# Warning: You must not use spaces and fields have to be separated by commas.
#
@ -111,6 +116,9 @@ disabled-worlds:
# sort by category, then put items before blocks and sort by name and color
# '{category},{itemsFirst},{name},{color}'
#
# sort by category, but keep exactly the same order as defined in each category file, then sort any undefined items by name and color
# '{category},{keepCategoryOrder},{name},{color}
#
sorting-method: '{category},{itemsFirst},{name},{color}'
#########################
@ -228,4 +236,4 @@ message-error-invalid-options: "&cError: Unknown option %s. Valid options are %s
#########################
# please do not change the following line manually!
config-version: 9
config-version: 10

View File

@ -1,6 +1,6 @@
main: de.jeffclan.JeffChestSort.JeffChestSortPlugin
name: ChestSort
version: 4.2
version: 4.3.1-dev
api-version: 1.13
description: Allows automatic chest sorting
author: mfnalex