aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2022-02-27 11:53:57 -0500
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2022-02-27 11:53:57 -0500
commitb09f774d422263ce15b97d6d0804beddf856176d (patch)
treee542258481d7496b15679f3c329ef9e087c7d8fc /src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
parent22cb02adbeb24b7ec98f843bcaba99cebe3e4f03 (diff)
downloadnotenoughupdates-b09f774d422263ce15b97d6d0804beddf856176d.tar.gz
notenoughupdates-b09f774d422263ce15b97d6d0804beddf856176d.tar.bz2
notenoughupdates-b09f774d422263ce15b97d6d0804beddf856176d.zip
feat: improve formating :)
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java2913
1 files changed, 1499 insertions, 1414 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 3aaad72c..df31834f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -38,115 +38,132 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class NEUManager {
- private final NotEnoughUpdates neu;
- public final Gson gson;
- public final APIManager auctionManager;
-
- private final TreeMap<String, JsonObject> itemMap = new TreeMap<>();
-
- private final TreeMap<String, HashMap<String, List<Integer>>> titleWordMap = new TreeMap<>();
- private final TreeMap<String, HashMap<String, List<Integer>>> loreWordMap = new TreeMap<>();
-
- public final KeyBinding keybindGive = new KeyBinding("Add item to inventory (Creative-only)", Keyboard.KEY_L, "NotEnoughUpdates");
- public final KeyBinding keybindFavourite = new KeyBinding("Set item as favourite", Keyboard.KEY_F, "NotEnoughUpdates");
- public final KeyBinding keybindViewUsages = new KeyBinding("Show usages for item", Keyboard.KEY_U, "NotEnoughUpdates");
- public final KeyBinding keybindViewRecipe = new KeyBinding("Show recipe for item", Keyboard.KEY_R, "NotEnoughUpdates");
- public final KeyBinding keybindToggleDisplay = new KeyBinding("Toggle NEU overlay", 0, "NotEnoughUpdates");
- public final KeyBinding keybindClosePanes = new KeyBinding("Close NEU panes", 0, "NotEnoughUpdates");
- public final KeyBinding keybindItemSelect = new KeyBinding("Select Item", -98 /*middle*/, "NotEnoughUpdates");
- public final KeyBinding[] keybinds = new KeyBinding[]{keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe,
- keybindToggleDisplay, keybindClosePanes, keybindItemSelect};
-
- public String viewItemAttemptID = null;
- public long viewItemAttemptTime = 0;
-
- private String currentProfile = "";
- private final String currentProfileBackup = "";
- public final HypixelApi hypixelApi = new HypixelApi();
-
- private final Map<String, ItemStack> itemstackCache = new HashMap<>();
-
- private final ExecutorService repoLoaderES = Executors.newSingleThreadExecutor();
-
- private static String GIT_COMMITS_URL;
-
- // TODO: private final Map<String, NeuItem>
-
- private final Set<NeuRecipe> recipes = new HashSet<>();
- private final HashMap<String, Set<NeuRecipe>> recipesMap = new HashMap<>();
- private final HashMap<String, Set<NeuRecipe>> usagesMap = new HashMap<>();
-
- public String latestRepoCommit = null;
-
- public File configLocation;
- public File repoLocation;
- public File configFile;
- public HotmInformation hotm;
-
- public KatSitterOverlay katSitterOverlay;
-
- public CraftingOverlay craftingOverlay;
-
- public NEUManager(NotEnoughUpdates neu, File configLocation) {
- this.neu = neu;
- this.configLocation = configLocation;
- this.auctionManager = new APIManager(this);
- this.hotm = new HotmInformation(neu);
- this.craftingOverlay = new CraftingOverlay(this);
- this.katSitterOverlay = new KatSitterOverlay();
-
- GIT_COMMITS_URL = neu.config.hidden.repoCommitsURL;
-
- gson = new GsonBuilder().setPrettyPrinting().create();
-
- this.repoLocation = new File(configLocation, "repo");
- repoLocation.mkdir();
- }
-
- public void setCurrentProfile(String currentProfile) {
- SBInfo.getInstance().currentProfile = currentProfile;
- }
-
- public String getCurrentProfile() {
- return SBInfo.getInstance().currentProfile;
- }
-
- public <T> T getJsonFromFile(File file, Class<T> clazz) {
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
- T obj = gson.fromJson(reader, clazz);
- return obj;
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
- * Parses a file in to a JsonObject.
- */
- public JsonObject getJsonFromFile(File file) {
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
- JsonObject json = gson.fromJson(reader, JsonObject.class);
- return json;
- } catch (Exception e) {
- return null;
- }
- }
-
- public void resetRepo() {
- try {
- Utils.recursiveDelete(new File(configLocation, "repo"));
- } catch (Exception ignored) {
- }
- try {
- new File(configLocation, "currentCommit.json").delete();
- } catch (Exception ignored) {}
- }
-
- /**
- * Called when the game is first loaded. Compares the local repository to the github repository and handles the
- * downloading of new/updated files. This then calls the "loadItem" method for every item in the local repository.
- */
- public void loadItemInformation() {
+ private final NotEnoughUpdates neu;
+ public final Gson gson;
+ public final APIManager auctionManager;
+
+ private final TreeMap<String, JsonObject> itemMap = new TreeMap<>();
+
+ private final TreeMap<String, HashMap<String, List<Integer>>> titleWordMap = new TreeMap<>();
+ private final TreeMap<String, HashMap<String, List<Integer>>> loreWordMap = new TreeMap<>();
+
+ public final KeyBinding keybindGive =
+ new KeyBinding("Add item to inventory (Creative-only)", Keyboard.KEY_L, "NotEnoughUpdates");
+ public final KeyBinding keybindFavourite =
+ new KeyBinding("Set item as favourite", Keyboard.KEY_F, "NotEnoughUpdates");
+ public final KeyBinding keybindViewUsages =
+ new KeyBinding("Show usages for item", Keyboard.KEY_U, "NotEnoughUpdates");
+ public final KeyBinding keybindViewRecipe =
+ new KeyBinding("Show recipe for item", Keyboard.KEY_R, "NotEnoughUpdates");
+ public final KeyBinding keybindToggleDisplay = new KeyBinding("Toggle NEU overlay", 0, "NotEnoughUpdates");
+ public final KeyBinding keybindClosePanes = new KeyBinding("Close NEU panes", 0, "NotEnoughUpdates");
+ public final KeyBinding keybindItemSelect = new KeyBinding("Select Item", -98 /*middle*/, "NotEnoughUpdates");
+ public final KeyBinding[] keybinds = new KeyBinding[]{
+ keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe,
+ keybindToggleDisplay, keybindClosePanes, keybindItemSelect
+ };
+
+ public String viewItemAttemptID = null;
+ public long viewItemAttemptTime = 0;
+
+ private final String currentProfile = "";
+ private final String currentProfileBackup = "";
+ public final HypixelApi hypixelApi = new HypixelApi();
+
+ private final Map<String, ItemStack> itemstackCache = new HashMap<>();
+
+ private final ExecutorService repoLoaderES = Executors.newSingleThreadExecutor();
+
+ private static String GIT_COMMITS_URL;
+
+ // TODO: private final Map<String, NeuItem>
+
+ private final Set<NeuRecipe> recipes = new HashSet<>();
+ private final HashMap<String, Set<NeuRecipe>> recipesMap = new HashMap<>();
+ private final HashMap<String, Set<NeuRecipe>> usagesMap = new HashMap<>();
+
+ public String latestRepoCommit = null;
+
+ public File configLocation;
+ public File repoLocation;
+ public File configFile;
+ public HotmInformation hotm;
+
+ public KatSitterOverlay katSitterOverlay;
+
+ public CraftingOverlay craftingOverlay;
+
+ public NEUManager(NotEnoughUpdates neu, File configLocation) {
+ this.neu = neu;
+ this.configLocation = configLocation;
+ this.auctionManager = new APIManager(this);
+ this.hotm = new HotmInformation(neu);
+ this.craftingOverlay = new CraftingOverlay(this);
+ this.katSitterOverlay = new KatSitterOverlay();
+
+ GIT_COMMITS_URL = neu.config.hidden.repoCommitsURL;
+
+ gson = new GsonBuilder().setPrettyPrinting().create();
+
+ this.repoLocation = new File(configLocation, "repo");
+ repoLocation.mkdir();
+ }
+
+ public void setCurrentProfile(String currentProfile) {
+ SBInfo.getInstance().currentProfile = currentProfile;
+ }
+
+ public String getCurrentProfile() {
+ return SBInfo.getInstance().currentProfile;
+ }
+
+ public <T> T getJsonFromFile(File file, Class<T> clazz) {
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(file),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ T obj = gson.fromJson(reader, clazz);
+ return obj;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Parses a file in to a JsonObject.
+ */
+ public JsonObject getJsonFromFile(File file) {
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(file),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ JsonObject json = gson.fromJson(reader, JsonObject.class);
+ return json;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void resetRepo() {
+ try {
+ Utils.recursiveDelete(new File(configLocation, "repo"));
+ } catch (Exception ignored) {
+ }
+ try {
+ new File(configLocation, "currentCommit.json").delete();
+ } catch (Exception ignored) {
+ }
+ }
+
+ /**
+ * Called when the game is first loaded. Compares the local repository to the github repository and handles the
+ * downloading of new/updated files. This then calls the "loadItem" method for every item in the local repository.
+ */
+ public void loadItemInformation() {
/*File repoFile = new File(configLocation, "repo2");
repoFile.mkdirs();
@@ -178,1309 +195,1377 @@ public class NEUManager {
}*/
- repoLoaderES.submit(() -> {
- JDialog dialog = null;
- try {
- if (NotEnoughUpdates.INSTANCE.config.hidden.autoupdate) {
- JOptionPane pane = new JOptionPane("Getting items to download from remote repository.");
- dialog = pane.createDialog("NotEnoughUpdates Remote Sync");
- dialog.setModal(false);
- if (NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true);
-
- if (Display.isActive()) dialog.toFront();
-
- JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json"));
-
- latestRepoCommit = null;
- try (Reader inReader = new InputStreamReader(new URL(GIT_COMMITS_URL).openStream())) {
- JsonObject commits = gson.fromJson(inReader, JsonObject.class);
- latestRepoCommit = commits.get("sha").getAsString();
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (latestRepoCommit == null || latestRepoCommit.isEmpty()) return;
-
- if (new File(configLocation, "repo").exists() && new File(configLocation, "repo/items").exists()) {
- if (currentCommitJSON != null && currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) {
- dialog.setVisible(false);
- return;
- }
- }
-
- if (Display.isActive()) dialog.toFront();
-
- Utils.recursiveDelete(repoLocation);
- repoLocation.mkdirs();
-
- String dlUrl = neu.config.hidden.repoURL;
-
- pane.setMessage("Downloading NEU Master Archive. (DL# >20)");
- dialog.pack();
- if (NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true);
- if (Display.isActive()) dialog.toFront();
-
- File itemsZip = new File(repoLocation, "neu-items-master.zip");
- try {
- itemsZip.createNewFile();
- } catch (IOException e) {
- return;
- }
-
- URL url = new URL(dlUrl);
- URLConnection urlConnection = url.openConnection();
- urlConnection.setConnectTimeout(15000);
- urlConnection.setReadTimeout(30000);
-
- try (InputStream is = urlConnection.getInputStream()) {
- FileUtils.copyInputStreamToFile(is, itemsZip);
- } catch (IOException e) {
- dialog.dispose();
- e.printStackTrace();
- System.err.println("Failed to download NEU Repo! Please report this issue to the mod creator");
- return;
- }
- /*try (BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream());
- FileOutputStream fileOutputStream = new FileOutputStream(itemsZip)) {
- byte dataBuffer[] = new byte[1024];
- int bytesRead;
- while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) {
- fileOutputStream.write(dataBuffer, 0, bytesRead);
- }
- } catch (IOException e) {
- dialog.dispose();
- return;
- }*/
-
- pane.setMessage("Unzipping NEU Master Archive.");
- dialog.pack();
- //dialog.setVisible(true);
- if (Display.isActive()) dialog.toFront();
-
- unzipIgnoreFirstFolder(itemsZip.getAbsolutePath(), repoLocation.getAbsolutePath());
-
- if (currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) {
- JsonObject newCurrentCommitJSON = new JsonObject();
- newCurrentCommitJSON.addProperty("sha", latestRepoCommit);
- try {
- writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json"));
- } catch (IOException ignored) {}
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (dialog != null) dialog.dispose();
- }
-
- File items = new File(repoLocation, "items");
- if (items.exists()) {
- File[] itemFiles = new File(repoLocation, "items").listFiles();
- if (itemFiles != null) {
- ProgressManager.ProgressBar bar = ProgressManager.push("Loading recipes", itemFiles.length);
- for (File f : itemFiles) {
- String internalname = f.getName().substring(0, f.getName().length() - 5);
- bar.step(internalname);
- synchronized (itemMap) {
- if (!itemMap.containsKey(internalname)) {
- loadItem(internalname);
- }
- }
- }
- ProgressManager.pop(bar);
- }
- }
-
- try {
- Constants.reload();
- } catch (Exception e) {
- e.printStackTrace();
- }
- });
-
- File items = new File(repoLocation, "items");
- if (items.exists()) {
- File[] itemFiles = new File(repoLocation, "items").listFiles();
- if (itemFiles != null) {
- ProgressManager.ProgressBar bar = ProgressManager.push("Loading items", itemFiles.length);
- for (File f : itemFiles) {
- String internalname = f.getName().substring(0, f.getName().length() - 5);
- bar.step(internalname);
- synchronized (itemMap) {
- if (!itemMap.containsKey(internalname)) {
- loadItem(internalname);
- }
- }
- }
- ProgressManager.pop(bar);
- }
- }
-
- try {
- Constants.reload();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Loads the item in to the itemMap and also stores various words associated with this item in to titleWordMap and
- * loreWordMap. These maps are used in the searching algorithm.
- */
- public void loadItem(String internalName) {
- itemstackCache.remove(internalName);
- try {
- JsonObject json = getJsonFromFile(new File(new File(repoLocation, "items"), internalName + ".json"));
- if (json == null) {
- return;
- }
-
- if (json.get("itemid") == null) return;
-
- String itemid = json.get("itemid").getAsString();
- Item mcitem = Item.getByNameOrId(itemid);
- if (mcitem != null) {
- itemid = mcitem.getRegistryName();
- }
- json.addProperty("itemid", itemid);
-
- itemMap.put(internalName, json);
-
- if (json.has("recipe")) {
- JsonObject recipe = json.getAsJsonObject("recipe");
- NeuRecipe neuRecipe = NeuRecipe.parseRecipe(this, recipe, json);
- if (neuRecipe != null)
- registerNeuRecipe(neuRecipe);
- }
- if (json.has("recipes")) {
- for (JsonElement element : json.getAsJsonArray("recipes")) {
- JsonObject recipe = element.getAsJsonObject();
- NeuRecipe neuRecipe = NeuRecipe.parseRecipe(this, recipe, json);
- if (neuRecipe != null)
- registerNeuRecipe(neuRecipe);
- }
- }
-
- if (json.has("displayname")) {
- synchronized (titleWordMap) {
- int wordIndex = 0;
- for (String str : json.get("displayname").getAsString().split(" ")) {
- str = clean(str);
- if (!titleWordMap.containsKey(str)) {
- titleWordMap.put(str, new HashMap<>());
- }
- if (!titleWordMap.get(str).containsKey(internalName)) {
- titleWordMap.get(str).put(internalName, new ArrayList<>());
- }
- titleWordMap.get(str).get(internalName).add(wordIndex);
- wordIndex++;
- }
- }
- }
-
- if (json.has("lore")) {
- synchronized (loreWordMap) {
- int wordIndex = 0;
- for (JsonElement element : json.get("lore").getAsJsonArray()) {
- for (String str : element.getAsString().split(" ")) {
- str = clean(str);
- if (!loreWordMap.containsKey(str)) {
- loreWordMap.put(str, new HashMap<>());
- }
- if (!loreWordMap.get(str).containsKey(internalName)) {
- loreWordMap.get(str).put(internalName, new ArrayList<>());
- }
- loreWordMap.get(str).get(internalName).add(wordIndex);
- wordIndex++;
- }
- }
- }
- }
- } catch (Exception e) {
- synchronized (loreWordMap) {
- System.out.println("loreWordMap is : " + loreWordMap);
- }
- synchronized (titleWordMap) {
- System.out.println("titleWordMap is : " + titleWordMap);
- }
- System.out.println("internalName is : " + internalName);
- e.printStackTrace();
- }
- }
-
- public void registerNeuRecipe(NeuRecipe recipe) {
- recipes.add(recipe);
- for (Ingredient output : recipe.getOutputs()) {
- recipesMap.computeIfAbsent(output.getInternalItemId(), ignored -> new HashSet<>()).add(recipe);
- }
- for (Ingredient input : recipe.getIngredients()) {
- usagesMap.computeIfAbsent(input.getInternalItemId(), ignored -> new HashSet<>()).add(recipe);
- }
- }
-
- public Set<NeuRecipe> getRecipesFor(String internalName) {
- return recipesMap.getOrDefault(internalName, Collections.emptySet());
- }
-
- public List<NeuRecipe> getAvailableRecipesFor(String internalname) {
- return getRecipesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList());
- }
-
- public Set<NeuRecipe> getUsagesFor(String internalName) {
- return usagesMap.getOrDefault(internalName, Collections.emptySet());
- }
-
- public List<NeuRecipe> getAvailableUsagesFor(String internalname) {
- return getUsagesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList());
- }
-
- /**
- * Searches a string for a query. This method is used to mimic the behaviour of the more complex map-based search
- * function. This method is used for the chest-item-search feature.
- */
- public boolean searchString(String toSearch, String query) {
- int lastMatch = -1;
-
- toSearch = clean(toSearch).toLowerCase();
- query = clean(query).toLowerCase();
- String[] splitToSeach = toSearch.split(" ");
- out:
- for (String s : query.split(" ")) {
- for (int i = 0; i < splitToSeach.length; i++) {
- if (!(lastMatch == -1 || lastMatch == i - 1)) continue;
- if (splitToSeach[i].startsWith(s)) {
- lastMatch = i;
- continue out;
- }
- }
- return false;
- }
-
- return true;
- }
-
- /**
- * Checks whether an itemstack matches a certain query, following the same rules implemented by the more complex
- * map-based search function.
- */
- public boolean doesStackMatchSearch(ItemStack stack, String query) {
- if (query.startsWith("title:")) {
- query = query.substring(6);
- return searchString(stack.getDisplayName(), query);
- } else if (query.startsWith("desc:")) {
- query = query.substring(5);
- String lore = "";
- NBTTagCompound tag = stack.getTagCompound();
- if (tag != null) {
- NBTTagCompound display = tag.getCompoundTag("display");
- if (display.hasKey("Lore", 9)) {
- NBTTagList list = display.getTagList("Lore", 8);
- for (int i = 0; i < list.tagCount(); i++) {
- lore += list.getStringTagAt(i) + " ";
- }
- }
- }
- return searchString(lore, query);
- } else if (query.startsWith("id:")) {
- query = query.substring(3);
- String internalName = getInternalNameForItem(stack);
- return query.equalsIgnoreCase(internalName);
- } else {
- boolean result = false;
- if (!query.trim().contains(" ")) {
- StringBuilder sb = new StringBuilder();
- for (char c : query.toCharArray()) {
- sb.append(c).append(" ");
- }
- result = result || searchString(stack.getDisplayName(), sb.toString());
- }
- result = result || searchString(stack.getDisplayName(), query);
-
- String lore = "";
- NBTTagCompound tag = stack.getTagCompound();
- if (tag != null) {
- NBTTagCompound display = tag.getCompoundTag("display");
- if (display.hasKey("Lore", 9)) {
- NBTTagList list = display.getTagList("Lore", 8);
- for (int i = 0; i < list.tagCount(); i++) {
- lore += list.getStringTagAt(i) + " ";
- }
- }
- }
-
- result = result || searchString(lore, query);
-
- return result;
- }
- }
-
- /**
- * Calls search for each query, separated by | eg. search(A|B) = search(A) + search(B)
- */
- public Set<String> search(String query, boolean multi) {
- if (multi) {
- Set<String> result = new HashSet<>();
-
- StringBuilder query2 = new StringBuilder();
- char lastOp = '|';
- for (char c : query.toCharArray()) {
- if (c == '|' || c == '&') {
- if (lastOp == '|') {
- result.addAll(search(query2.toString()));
- } else if (lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- query2 = new StringBuilder();
- lastOp = c;
- } else {
- query2.append(c);
- }
- }
- if (lastOp == '|') {
- result.addAll(search(query2.toString()));
- } else if (lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- return result;
- } else {
- return search(query);
- }
- }
-
- /*public TreeMap<ItemStack> searchForStacks(String query, Set<ItemStack> stacks, boolean multi) {
- if(multi) {
- Set<String> result = new HashSet<>();
-
- StringBuilder query2 = new StringBuilder();
- char lastOp = '|';
- for(char c : query.toCharArray()) {
- if(c == '|' || c == '&') {
- if(lastOp == '|') {
- result.addAll(doesStackMatchSearch(stack, query2.toString()));
- } else if(lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- query2 = new StringBuilder();
- lastOp = c;
- } else {
- query2.append(c);
- }
- }
- if(lastOp == '|') {
- result.addAll(search(query2.toString()));
- } else if(lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- return result;
- } else {
- return search(query);
- }
- }*/
-
- /**
- * Returns the name of items which match a certain search query.
- */
- public Set<String> search(String query) {
- query = query.trim();
- boolean negate = query.startsWith("!");
- if (negate) query = query.substring(1);
-
- LinkedHashSet<String> results = new LinkedHashSet<>();
- if (query.startsWith("title:")) {
- query = query.substring(6);
- results.addAll(new TreeSet<>(search(query, titleWordMap)));
- } else if (query.startsWith("desc:")) {
- query = query.substring(5);
- results.addAll(new TreeSet<>(search(query, loreWordMap)));
- } else if (query.startsWith("id:")) {
- query = query.substring(3);
- results.addAll(new TreeSet<>(subMapWithKeysThatAreSuffixes(query.toUpperCase(), itemMap).keySet()));
- } else {
- if (!query.trim().contains(" ")) {
- StringBuilder sb = new StringBuilder();
- for (char c : query.toCharArray()) {
- sb.append(c).append(" ");
- }
- results.addAll(new TreeSet<>(search(sb.toString(), titleWordMap)));
- }
- results.addAll(new TreeSet<>(search(query, titleWordMap)));
- results.addAll(new TreeSet<>(search(query, loreWordMap)));
- }
- if (!negate) {
- return results;
- } else {
- Set<String> negatedResults = new HashSet<>();
- for (String internalname : itemMap.keySet()) {
- negatedResults.add(internalname);
- }
- negatedResults.removeAll(results);
- return negatedResults;
- }
- }
-
- /**
- * Splits a search query into an array of strings delimited by a space character. Then, matches the query to the
- * start of words in the various maps (title & lore). The small query does not need to match the whole entry of the
- * map, only the beginning. eg. "ench" and "encha" will both match "enchanted". All sub queries must follow a word
- * matching the previous sub query. eg. "ench po" will match "enchanted pork" but will not match "pork enchanted".
- */
- public Set<String> search(String query, TreeMap<String, HashMap<String, List<Integer>>> wordMap) {
- HashMap<String, List<Integer>> matches = null;
-
- query = clean(query).toLowerCase();
- for (String queryWord : query.split(" ")) {
- HashMap<String, List<Integer>> matchesToKeep = new HashMap<>();
- for (HashMap<String, List<Integer>> wordMatches : subMapWithKeysThatAreSuffixes(queryWord, wordMap).values()) {
- if (!(wordMatches != null && !wordMatches.isEmpty())) continue;
- if (matches == null) {
- //Copy all wordMatches to titleMatches
- for (String internalname : wordMatches.keySet()) {
- if (!matchesToKeep.containsKey(internalname)) {
- matchesToKeep.put(internalname, new ArrayList<>());
- }
- matchesToKeep.get(internalname).addAll(wordMatches.get(internalname));
- }
- } else {
- for (String internalname : matches.keySet()) {
- if (!wordMatches.containsKey(internalname)) continue;
- for (Integer newIndex : wordMatches.get(internalname)) {
- if (!matches.get(internalname).contains(newIndex - 1)) continue;
- if (!matchesToKeep.containsKey(internalname)) {
- matchesToKeep.put(internalname, new ArrayList<>());
- }
- matchesToKeep.get(internalname).add(newIndex);
- }
- }
- }
- }
- if (matchesToKeep.isEmpty()) return new HashSet<>();
- matches = matchesToKeep;
- }
-
- return matches.keySet();
- }
-
- /**
- * From https://stackoverflow.com/questions/10711494/get-values-in-treemap-whose-string-keys-start-with-a-pattern
- */
- public <T> Map<String, T> subMapWithKeysThatAreSuffixes(String prefix, NavigableMap<String, T> map) {
- if ("".equals(prefix)) return map;
- String lastKey = createLexicographicallyNextStringOfTheSameLength(prefix);
- return map.subMap(prefix, true, lastKey, false);
- }
-
- public String createLexicographicallyNextStringOfTheSameLength(String input) {
- final int lastCharPosition = input.length() - 1;
- String inputWithoutLastChar = input.substring(0, lastCharPosition);
- char lastChar = input.charAt(lastCharPosition);
- char incrementedLastChar = (char) (lastChar + 1);
- return inputWithoutLastChar + incrementedLastChar;
- }
-
- public JsonObject getJsonFromItemBytes(String item_bytes) {
- try {
- NBTTagCompound tag = CompressedStreamTools.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(item_bytes)));
- //System.out.println(tag.toString());
- return getJsonFromNBT(tag);
- } catch (IOException e) {
- return null;
- }
- }
-
- public String getUUIDFromNBT(NBTTagCompound tag) {
- String uuid = null;
- if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- if (ea.hasKey("uuid", 8)) {
- uuid = ea.getString("uuid");
- }
- }
- return uuid;
- }
-
- public String getInternalnameFromNBT(NBTTagCompound tag) {
- String internalname = null;
- if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- if (ea.hasKey("id", 8)) {
- internalname = ea.getString("id").replaceAll(":", "-");
- } else {
- return null;
- }
-
- if ("PET".equals(internalname)) {
- String petInfo = ea.getString("petInfo");
- if (petInfo.length() > 0) {
- JsonObject petInfoObject = gson.fromJson(petInfo, JsonObject.class);
- internalname = petInfoObject.get("type").getAsString();
- String tier = petInfoObject.get("tier").getAsString();
- switch (tier) {
- case "COMMON":
- internalname += ";0";
- break;
- case "UNCOMMON":
- internalname += ";1";
- break;
- case "RARE":
- internalname += ";2";
- break;
- case "EPIC":
- internalname += ";3";
- break;
- case "LEGENDARY":
- internalname += ";4";
- break;
- case "MYTHIC":
- internalname += ";5";
- break;
- }
- }
- }
- if ("ENCHANTED_BOOK".equals(internalname) && ea.hasKey("enchantments", 10)) {
- NBTTagCompound enchants = ea.getCompoundTag("enchantments");
-
- for (String enchname : enchants.getKeySet()) {
- internalname = enchname.toUpperCase() + ";" + enchants.getInteger(enchname);
- break;
- }
- }
- if ("RUNE".equals(internalname) && ea.hasKey("runes", 10)) {
- NBTTagCompound rune = ea.getCompoundTag("runes");
-
- for (String runename : rune.getKeySet()) {
- internalname = runename.toUpperCase() + "_RUNE" + ";" + rune.getInteger(runename);
- break;
- }
- }
- if ("PARTY_HAT_CRAB".equals(internalname) && (ea.getString("party_hat_color") != null)) {
- String crabhat = ea.getString("party_hat_color");
- internalname = "PARTY_HAT_CRAB" + "_" + crabhat.toUpperCase();
- }
- }
-
- return internalname;
- }
-
- public String[] getLoreFromNBT(NBTTagCompound tag) {
- String[] lore = new String[0];
- NBTTagCompound display = tag.getCompoundTag("display");
-
- if (display.hasKey("Lore", 9)) {
- NBTTagList list = display.getTagList("Lore", 8);
- lore = new String[list.tagCount()];
- for (int k = 0; k < list.tagCount(); k++) {
- lore[k] = list.getStringTagAt(k);
- }
- }
- return lore;
- }
-
- public JsonObject getJsonFromNBT(NBTTagCompound tag) {
- return getJsonFromNBTEntry(tag.getTagList("i", 10).getCompoundTagAt(0));
- }
-
- public JsonObject getJsonFromNBTEntry(NBTTagCompound tag) {
- if (tag.getKeySet().size() == 0) return null;
-
- int id = tag.getShort("id");
- int damage = tag.getShort("Damage");
- int count = tag.getShort("Count");
- tag = tag.getCompoundTag("tag");
-
- if (id == 141) id = 391; //for some reason hypixel thinks carrots have id 141
-
- String internalname = getInternalnameFromNBT(tag);
- if (internalname == null) return null;
-
- NBTTagCompound display = tag.getCompoundTag("display");
- String[] lore = getLoreFromNBT(tag);
-
- Item itemMc = Item.getItemById(id);
- String itemid = "null";
- if (itemMc != null) {
- itemid = itemMc.getRegistryName();
- }
- String displayname = display.getString("Name");
- String[] info = new String[0];
- String clickcommand = "";