diff options
Diffstat (limited to 'src/main/java')
7 files changed, 152 insertions, 32 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index a001850e..5eab77f9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -102,7 +102,7 @@ public class NEUManager { private final TreeMap<String, JsonObject> itemMap = new TreeMap<>(); private boolean hasBeenLoadedBefore = false; - private final TreeMap<String, HashMap<String, List<Integer>>> titleWordMap = new TreeMap<>(); + public 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 = @@ -320,7 +320,7 @@ public class NEUManager { synchronized (titleWordMap) { int wordIndex = 0; for (String str : json.get("displayname").getAsString().split(" ")) { - str = clean(str); + str = cleanForTitleMapSearch(str); if (!titleWordMap.containsKey(str)) { titleWordMap.put(str, new HashMap<>()); } @@ -338,7 +338,7 @@ public class NEUManager { int wordIndex = 0; for (JsonElement element : json.get("lore").getAsJsonArray()) { for (String str : element.getAsString().split(" ")) { - str = clean(str); + str = cleanForTitleMapSearch(str); if (!loreWordMap.containsKey(str)) { loreWordMap.put(str, new HashMap<>()); } @@ -466,8 +466,8 @@ public class NEUManager { int lastStringMatch = -1; ArrayList<DebugMatch> debugMatches = new ArrayList<>(); - toSearch = clean(toSearch).toLowerCase(); - query = clean(query).toLowerCase(); + toSearch = cleanForTitleMapSearch(toSearch).toLowerCase(); + query = cleanForTitleMapSearch(query).toLowerCase(); String[] splitToSearch = toSearch.split(" "); String[] queryArray = query.split(" "); @@ -684,7 +684,7 @@ public class NEUManager { public Set<String> search(String query, TreeMap<String, HashMap<String, List<Integer>>> wordMap) { HashMap<String, List<Integer>> matches = null; - query = clean(query).toLowerCase(); + query = cleanForTitleMapSearch(query).toLowerCase(); for (String queryWord : query.split(" ")) { HashMap<String, List<Integer>> matchesToKeep = new HashMap<>(); for (HashMap<String, List<Integer>> wordMatches : subMapWithKeysThatAreSuffixes(queryWord, wordMap).values()) { @@ -859,7 +859,7 @@ public class NEUManager { return item; } - private String clean(String str) { + public static String cleanForTitleMapSearch(String str) { return str.replaceAll("(\u00a7.)|[^0-9a-zA-Z ]", "").toLowerCase().trim(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/GuiContainerBackgroundDrawnEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/GuiContainerBackgroundDrawnEvent.java new file mode 100644 index 00000000..bdb6d1a1 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/events/GuiContainerBackgroundDrawnEvent.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.events; + +import lombok.Value; +import net.minecraft.client.gui.inventory.GuiContainer; + +@Value +public class GuiContainerBackgroundDrawnEvent extends NEUEvent { + public GuiContainer container; + public float partialTicks; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java index a5bb99b8..8aca73d1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java @@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.GuiContainerBackgroundDrawnEvent; import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneFavourites; @@ -330,6 +331,6 @@ public abstract class MixinGuiContainer extends GuiScreen { @Inject(method = "drawScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;color(FFFF)V", ordinal = 1)) private void drawBackground(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { - AbiphoneFavourites.getInstance().onDrawBackground(this); + new GuiContainerBackgroundDrawnEvent(((GuiContainer) (Object) this), partialTicks).post(); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 552cb5b1..e9c34e03 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -56,6 +56,7 @@ import io.github.moulberry.notenoughupdates.options.seperateSections.Mining; import io.github.moulberry.notenoughupdates.options.seperateSections.MinionHelper; import io.github.moulberry.notenoughupdates.options.seperateSections.Misc; import io.github.moulberry.notenoughupdates.options.seperateSections.MiscOverlays; +import io.github.moulberry.notenoughupdates.options.seperateSections.Museum; import io.github.moulberry.notenoughupdates.options.seperateSections.NeuAuctionHouse; import io.github.moulberry.notenoughupdates.options.seperateSections.Notifications; import io.github.moulberry.notenoughupdates.options.seperateSections.PetOverlay; @@ -387,6 +388,13 @@ public class NEUConfig extends Config { @Expose @Category( + name = "Museum", + desc = "Museum overlays" + ) + public Museum museum = new Museum(); + + @Expose + @Category( name = "Profile Viewer", desc = "Profile Viewer" ) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java new file mode 100644 index 00000000..c476fc3b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Museum.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.options.seperateSections; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorColour; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; + +public class Museum { + + @Expose + @ConfigOption( + name = "Show Museum Items", + desc = "Show real items instead of green dye in the museum" + ) + @ConfigEditorBoolean + public boolean museumItemShow = false; + + @Expose + @ConfigOption( + name = "Highlight virtual museum items", + desc = "Highlight virtual museum items with a background color" + ) + @ConfigEditorColour + public String museumItemColor = "0:255:0:255:0"; + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java index ea5e13ab..280a0d3d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java @@ -24,6 +24,7 @@ import com.google.gson.JsonParseException; import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import lombok.var; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.inventory.GuiChest; @@ -36,9 +37,10 @@ import net.minecraft.nbt.NBTTagCompound; import javax.annotation.Nullable; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -188,31 +190,63 @@ public class ItemResolutionQuery { return null; } + /** + * Search for an item by the display name + * + * @param displayName The display name of the item we are searching + * @param mayBeMangled Whether the item name may be mangled (for example: reforges, stars) + * @return the internal neu item id of that item, or null + */ + public static String findInternalNameByDisplayName(String displayName, boolean mayBeMangled) { + var cleanDisplayName = StringUtils.cleanColour(displayName); + var manager = NotEnoughUpdates.INSTANCE.manager; + String bestMatch = null; + int bestMatchLength = -1; + for (String internalName : findInternalNameCandidatesForDisplayName(cleanDisplayName)) { + var item = manager.createItem(internalName); + if (item.getDisplayName() == null) continue; + var cleanItemDisplayName = StringUtils.cleanColour(item.getDisplayName()); + if (cleanItemDisplayName.length() == 0) continue; + if (mayBeMangled + ? !cleanDisplayName.contains(cleanItemDisplayName) + : !cleanItemDisplayName.equals(cleanDisplayName)) { + continue; + } + if (cleanItemDisplayName.length() > bestMatchLength) { + bestMatchLength = cleanItemDisplayName.length(); + bestMatch = internalName; + } + } + return bestMatch; + } + + /** + * Find potential item ids for a given display name. This function is over eager to give results, + * and may give invalid results, but if there is a matching item in the repository it will return <em>at least</em> + * that item. This should be used as a first filtering pass. Use {@link #findInternalNameByDisplayName} for a more + * user-friendly API. + * + * @param displayName The display name of the item we are searching + * @return a list of internal neu item ids some of which may have a matching display name + */ + public static Set<String> findInternalNameCandidatesForDisplayName(String displayName) { + var cleanDisplayName = NEUManager.cleanForTitleMapSearch(displayName); + var titleWordMap = NotEnoughUpdates.INSTANCE.manager.titleWordMap; + var candidates = new HashSet<String>(); + for (var partialDisplayName : cleanDisplayName.split(" ")) { + if (!titleWordMap.containsKey(partialDisplayName)) continue; + candidates.addAll(titleWordMap.get(partialDisplayName).keySet()); + } + return candidates; + } + private String resolveItemInCatacombsRngMeter() { List<String> lore = ItemUtils.getLore(compound); if (lore.size() > 16) { String s = lore.get(15); if (s.equals("ยง7Selected Drop")) { String displayName = lore.get(16); - return getInternalNameByDisplayName(displayName); - } - } - - return null; - } - - private String getInternalNameByDisplayName(String displayName) { - String cleanDisplayName = StringUtils.cleanColour(displayName); - for (Map.Entry<String, JsonObject> entry : NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .entrySet()) { - - JsonObject object = entry.getValue(); - if (object.has("displayname")) { - String name = object.get("displayname").getAsString(); - if (StringUtils.cleanColour(name).equals(cleanDisplayName)) { - return entry.getKey(); - } + return findInternalNameByDisplayName(displayName, false); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/LRUCache.java b/src/main/java/io/github/moulberry/notenoughupdates/util/LRUCache.java index f107d522..6adbc30d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/LRUCache.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/LRUCache.java @@ -32,13 +32,15 @@ public interface LRUCache<K, V> extends Function<K, V> { } static <K, V> LRUCache<K, V> memoize(Function<K, V> mapper, IntSupplier maxCacheSize) { - Map<K, V> cache = new LinkedHashMap<K, V>(10, 0.75F, true) { + Map<K, Object> cache = new LinkedHashMap<K, Object>(10, 0.75F, true) { @Override - protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { + protected boolean removeEldestEntry(Map.Entry<K, Object> eldest) { return this.size() > maxCacheSize.getAsInt(); } }; - Map<K, V> synchronizedCache = Collections.synchronizedMap(cache); + Object SENTINEL_CACHE_RESULT_NULL = new Object(); + Function<K, Object> sentinelAwareMapper = mapper.andThen(it -> it == null ? SENTINEL_CACHE_RESULT_NULL : it); + Map<K, Object> synchronizedCache = Collections.synchronizedMap(cache); return new LRUCache<K, V>() { @Override public void clearCache() { @@ -52,7 +54,8 @@ public interface LRUCache<K, V> extends Function<K, V> { @Override public V apply(K k) { - return synchronizedCache.computeIfAbsent(k, mapper); + Object value = synchronizedCache.computeIfAbsent(k, sentinelAwareMapper); + return value == SENTINEL_CACHE_RESULT_NULL ? null : (V) value; } }; } |