From 5054caffa1454ddb1e59bb19be01b57cb28b5cf4 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Tue, 10 Apr 2018 20:27:03 -0600 Subject: [PATCH 1/5] Initialize ItemManager to a complete state This reverts e3637fbb27868c42b9acb7c9f2a8f4308179e143 , changing it so RuneLite gets it's ItemManager late, as opposed to the ItemManager being constructed in a invalid state. --- .../src/main/java/net/runelite/client/RuneLite.java | 8 ++++++-- .../main/java/net/runelite/client/game/ItemManager.java | 9 ++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 73be75e72f..cfcc2876fb 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -31,6 +31,7 @@ import com.google.common.eventbus.EventBus; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; +import com.google.inject.Provider; import java.applet.Applet; import java.io.File; import java.util.Optional; @@ -104,7 +105,7 @@ public class RuneLite private TitleToolbar titleToolbar; @Inject - private ItemManager itemManager; + private Provider itemManager; @Inject private ClanManager clanManager; @@ -169,8 +170,11 @@ public class RuneLite eventBus.register(chatMessageManager); eventBus.register(commandManager); eventBus.register(pluginManager); - eventBus.register(itemManager); eventBus.register(clanManager); + if (client != null) + { + eventBus.register(itemManager.get()); + } // Load user configuration configManager.load(); diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index 03ab868452..a29513e45b 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -38,7 +38,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.inject.Inject; -import javax.inject.Provider; import javax.inject.Singleton; import lombok.Value; import lombok.extern.slf4j.Slf4j; @@ -74,7 +73,7 @@ public class ItemManager */ static final ItemPrice NONE = new ItemPrice(); - private final Provider client; + private final Client client; private final ScheduledExecutorService scheduledExecutorService; private final ItemClient itemClient = new ItemClient(); @@ -84,7 +83,7 @@ public class ItemManager private final LoadingCache itemCompositions; @Inject - public ItemManager(Provider client, ScheduledExecutorService executor) + public ItemManager(Client client, ScheduledExecutorService executor) { this.client = client; this.scheduledExecutorService = executor; @@ -126,7 +125,7 @@ public class ItemManager @Override public ItemComposition load(Integer key) throws Exception { - return client.get().getItemDefinition(key); + return client.getItemDefinition(key); } }); } @@ -274,7 +273,7 @@ public class ItemManager */ private BufferedImage loadImage(int itemId, int quantity, boolean stackable) { - SpritePixels sprite = client.get().createItemSprite(itemId, quantity, 1, SpritePixels.DEFAULT_SHADOW_COLOR, + SpritePixels sprite = client.createItemSprite(itemId, quantity, 1, SpritePixels.DEFAULT_SHADOW_COLOR, stackable ? 1 : 0, false, CLIENT_DEFAULT_ZOOM); return sprite.toBufferedImage(); } From d680c91c194ab4c39c573f419a36d0869d9c5796 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 11 Apr 2018 03:19:36 -0600 Subject: [PATCH 2/5] Allow ClientThread to re-run invokeLater-ed methods --- .../client/callback/ClientThread.java | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java index 08ae4011b5..f17c8d774c 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java @@ -27,6 +27,7 @@ package net.runelite.client.callback; import com.google.inject.Inject; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.BooleanSupplier; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; @@ -35,16 +36,32 @@ import net.runelite.api.Client; @Slf4j public class ClientThread { - private ConcurrentLinkedQueue invokes = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue invokes = new ConcurrentLinkedQueue<>(); @Inject private Client client; public void invokeLater(Runnable r) { - if (client.isClientThread()) + invokeLater(() -> { r.run(); + return true; + }); + } + + /** + * Will run r on the game thread, at a unspecified point in the future. + * If r returns false, r will be ran again, at a later point + */ + public void invokeLater(BooleanSupplier r) + { + if (client.isClientThread()) + { + if (r.getAsBoolean()) + { + invokes.add(r); + } return; } invokes.add(r); @@ -53,14 +70,14 @@ public class ClientThread void invoke() { assert client.isClientThread(); - Iterator ir = invokes.iterator(); + Iterator ir = invokes.iterator(); for (; ir.hasNext(); ) { - Runnable r = ir.next(); - ir.remove(); + BooleanSupplier r = ir.next(); + boolean remove = true; try { - r.run(); + remove = r.getAsBoolean(); } catch (ThreadDeath d) { @@ -70,6 +87,10 @@ public class ClientThread { log.warn("Exception in invokeLater", e); } + if (remove) + { + ir.remove(); + } } } } From b3fa9a5e497a88c0f8addc5c727fb7e81f3d797b Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 11 Apr 2018 03:39:28 -0600 Subject: [PATCH 3/5] Allow ItemManager to be ran off the client thread This allows the ItemManager to return a blank BufferedImage if it's not called on the client thread. This also makes it not render the image until the cache has been downloaded --- .../java/net/runelite/api/SpritePixels.java | 7 ++ .../client/game/AsyncBufferedImage.java | 84 +++++++++++++++++++ .../net/runelite/client/game/ItemManager.java | 50 ++++++++--- .../runelite/mixins/RSSpritePixelsMixin.java | 19 ++++- 4 files changed, 146 insertions(+), 14 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/game/AsyncBufferedImage.java diff --git a/runelite-api/src/main/java/net/runelite/api/SpritePixels.java b/runelite-api/src/main/java/net/runelite/api/SpritePixels.java index 49fd5fc973..732ab1ffa0 100644 --- a/runelite-api/src/main/java/net/runelite/api/SpritePixels.java +++ b/runelite-api/src/main/java/net/runelite/api/SpritePixels.java @@ -44,4 +44,11 @@ public interface SpritePixels * @return */ BufferedImage toBufferedImage(); + + + /** + * Writes the contents of the SpritePixels to the BufferedImage. + * Width and Height must match + */ + void toBufferedImage(BufferedImage img); } diff --git a/runelite-client/src/main/java/net/runelite/client/game/AsyncBufferedImage.java b/runelite-client/src/main/java/net/runelite/client/game/AsyncBufferedImage.java new file mode 100644 index 0000000000..0290c7856a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/AsyncBufferedImage.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.game; + +import java.awt.image.BufferedImage; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; + +public class AsyncBufferedImage extends BufferedImage +{ + private final List listeners = new CopyOnWriteArrayList<>(); + public AsyncBufferedImage(int width, int height, int imageType) + { + super(width, height, imageType); + } + + /** + * Call when the buffer has been changed + */ + public void changed() + { + for (Runnable r : listeners) + { + r.run(); + } + } + + /** + * Register a function to be ran when the buffer has changed + */ + public void onChanged(Runnable r) + { + listeners.add(r); + } + + /** + * Calls setIcon on c, ensuring it is repainted when this changes + */ + public void addTo(JButton c) + { + c.setIcon(makeIcon(c)); + } + + /** + * Calls setIcon on c, ensuring it is repainted when this changes + */ + public void addTo(JLabel c) + { + c.setIcon(makeIcon(c)); + } + + private ImageIcon makeIcon(JComponent c) + { + listeners.add(c::repaint); + return new ImageIcon(this); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index a29513e45b..950b0a4081 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -47,6 +47,7 @@ import net.runelite.api.GameState; import net.runelite.api.ItemComposition; import net.runelite.api.SpritePixels; import net.runelite.api.events.GameStateChanged; +import net.runelite.client.callback.ClientThread; import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.SearchResult; @@ -75,18 +76,20 @@ public class ItemManager private final Client client; private final ScheduledExecutorService scheduledExecutorService; + private final ClientThread clientThread; private final ItemClient itemClient = new ItemClient(); private final LoadingCache itemSearches; private final LoadingCache itemPriceCache; - private final LoadingCache itemImages; + private final LoadingCache itemImages; private final LoadingCache itemCompositions; @Inject - public ItemManager(Client client, ScheduledExecutorService executor) + public ItemManager(Client client, ScheduledExecutorService executor, ClientThread clientThread) { this.client = client; this.scheduledExecutorService = executor; + this.clientThread = clientThread; itemPriceCache = CacheBuilder.newBuilder() .maximumSize(1024L) @@ -108,10 +111,10 @@ public class ItemManager itemImages = CacheBuilder.newBuilder() .maximumSize(128L) .expireAfterAccess(1, TimeUnit.HOURS) - .build(new CacheLoader() + .build(new CacheLoader() { @Override - public BufferedImage load(ImageKey key) throws Exception + public AsyncBufferedImage load(ImageKey key) throws Exception { return loadImage(key.itemId, key.itemQuantity, key.stackable); } @@ -271,32 +274,55 @@ public class ItemManager * @param itemId * @return */ - private BufferedImage loadImage(int itemId, int quantity, boolean stackable) + private AsyncBufferedImage loadImage(int itemId, int quantity, boolean stackable) { - SpritePixels sprite = client.createItemSprite(itemId, quantity, 1, SpritePixels.DEFAULT_SHADOW_COLOR, - stackable ? 1 : 0, false, CLIENT_DEFAULT_ZOOM); - return sprite.toBufferedImage(); + AsyncBufferedImage img = new AsyncBufferedImage(36, 32, BufferedImage.TYPE_INT_ARGB); + clientThread.invokeLater(() -> + { + if (client.getGameState().ordinal() < GameState.LOGIN_SCREEN.ordinal()) + { + return false; + } + SpritePixels sprite = client.createItemSprite(itemId, quantity, 1, SpritePixels.DEFAULT_SHADOW_COLOR, + stackable ? 1 : 0, false, CLIENT_DEFAULT_ZOOM); + if (sprite == null) + { + return false; + } + sprite.toBufferedImage(img); + img.changed(); + return true; + }); + return img; } /** - * Get item sprite image + * Get item sprite image as BufferedImage. + *

+ * This method may return immediately with a blank image if not called on the game thread. + * The image will be filled in later. If this is used for a UI label/button, it should be added + * using AsyncBufferedImage::addTo to ensure it is painted properly * * @param itemId * @return */ - public BufferedImage getImage(int itemId) + public AsyncBufferedImage getImage(int itemId) { return getImage(itemId, 1, false); } /** - * Get item sprite image as BufferedImage + * Get item sprite image as BufferedImage. + *

+ * This method may return immediately with a blank image if not called on the game thread. + * The image will be filled in later. If this is used for a UI label/button, it should be added + * using AsyncBufferedImage::addTo to ensure it is painted properly * * @param itemId * @param quantity * @return */ - public BufferedImage getImage(int itemId, int quantity, boolean stackable) + public AsyncBufferedImage getImage(int itemId, int quantity, boolean stackable) { try { diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSSpritePixelsMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSSpritePixelsMixin.java index eeca0febcb..7511df70d7 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSSpritePixelsMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSSpritePixelsMixin.java @@ -35,12 +35,28 @@ public abstract class RSSpritePixelsMixin implements RSSpritePixels @Inject @Override public BufferedImage toBufferedImage() + { + BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); + + toBufferedImage(img); + + return img; + } + + @Inject + @Override + public void toBufferedImage(BufferedImage img) { int width = getWidth(); int height = getHeight(); + + if (img.getWidth() != width || img.getHeight() != height) + { + throw new IllegalArgumentException("Image bounds do not match SpritePixels"); + } + int[] pixels = getPixels(); int[] transPixels = new int[pixels.length]; - BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < pixels.length; i++) { @@ -51,6 +67,5 @@ public abstract class RSSpritePixelsMixin implements RSSpritePixels } img.setRGB(0, 0, width, height, transPixels, 0, width); - return img; } } From 30413c0257e8ba5baa26c6690da57c52393cc428 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 11 Apr 2018 03:42:11 -0600 Subject: [PATCH 4/5] Use ItemManager in KourendLibraryPlugin --- .../client/plugins/kourendlibrary/Book.java | 26 ++++++------------ .../plugins/kourendlibrary/BookPanel.java | 4 +-- .../kourendlibrary/KourendLibraryPlugin.java | 6 ++++ .../plugins/kourendlibrary/items/13514.png | Bin 679 -> 0 bytes .../plugins/kourendlibrary/items/13515.png | Bin 658 -> 0 bytes .../plugins/kourendlibrary/items/13516.png | Bin 661 -> 0 bytes .../plugins/kourendlibrary/items/13517.png | Bin 676 -> 0 bytes .../plugins/kourendlibrary/items/13518.png | Bin 635 -> 0 bytes .../plugins/kourendlibrary/items/13519.png | Bin 655 -> 0 bytes .../plugins/kourendlibrary/items/13520.png | Bin 621 -> 0 bytes .../plugins/kourendlibrary/items/13521.png | Bin 607 -> 0 bytes .../plugins/kourendlibrary/items/13522.png | Bin 602 -> 0 bytes .../plugins/kourendlibrary/items/13523.png | Bin 631 -> 0 bytes .../plugins/kourendlibrary/items/13524.png | Bin 783 -> 0 bytes .../plugins/kourendlibrary/items/13525.png | Bin 811 -> 0 bytes .../plugins/kourendlibrary/items/13526.png | Bin 872 -> 0 bytes .../plugins/kourendlibrary/items/13527.png | Bin 854 -> 0 bytes .../plugins/kourendlibrary/items/13528.png | Bin 868 -> 0 bytes .../plugins/kourendlibrary/items/13529.png | Bin 802 -> 0 bytes .../plugins/kourendlibrary/items/13530.png | Bin 686 -> 0 bytes .../plugins/kourendlibrary/items/13531.png | Bin 749 -> 0 bytes .../plugins/kourendlibrary/items/13532.png | Bin 735 -> 0 bytes .../plugins/kourendlibrary/items/13533.png | Bin 854 -> 0 bytes .../plugins/kourendlibrary/items/13534.png | Bin 1134 -> 0 bytes .../plugins/kourendlibrary/items/13535.png | Bin 816 -> 0 bytes .../plugins/kourendlibrary/items/13536.png | Bin 1203 -> 0 bytes .../plugins/kourendlibrary/items/13537.png | Bin 1171 -> 0 bytes .../plugins/kourendlibrary/items/19637.png | Bin 947 -> 0 bytes .../plugins/kourendlibrary/items/21756.png | Bin 738 -> 0 bytes 29 files changed, 16 insertions(+), 20 deletions(-) delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13514.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13515.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13516.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13517.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13518.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13519.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13520.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13521.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13522.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13523.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13524.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13525.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13526.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13527.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13528.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13529.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13530.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13531.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13532.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13533.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13534.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13535.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13536.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13537.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/19637.png delete mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/21756.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java index 8f88d433c1..759272950b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java @@ -24,14 +24,13 @@ */ package net.runelite.client.plugins.kourendlibrary; -import java.awt.image.BufferedImage; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import javax.imageio.ImageIO; import lombok.Getter; import net.runelite.api.ItemID; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ItemManager; public enum Book { @@ -77,7 +76,7 @@ public enum Book return Collections.unmodifiableMap(byId); } - private static final Map buildByName() + private static Map buildByName() { HashMap byName = new HashMap<>(); for (Book b : Book.values()) @@ -110,7 +109,7 @@ public enum Book private final String shortName; @Getter - private final BufferedImage icon; + private AsyncBufferedImage icon; @Getter private final boolean isDarkManuscript; @@ -121,7 +120,6 @@ public enum Book this.isDarkManuscript = false; this.shortName = shortName; this.name = name; - this.icon = getImage(Integer.toString(id)); } Book(int id) @@ -130,21 +128,13 @@ public enum Book this.isDarkManuscript = true; this.name = "Dark Manuscript"; this.shortName = "Dark Manuscript"; - this.icon = getImage(Integer.toString(id)); } - private static BufferedImage getImage(String name) + static void fillImages(ItemManager itemManager) { - try + for (Book b : values()) { - synchronized (ImageIO.class) - { - return ImageIO.read(Book.class.getResourceAsStream("items/" + name + ".png")); - } - } - catch (IOException | IllegalArgumentException e) - { - throw new RuntimeException("Cannot load book " + name, e); + b.icon = itemManager.getImage(b.item); } } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java index a5d1c0db53..b819731a03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java @@ -26,7 +26,6 @@ package net.runelite.client.plugins.kourendlibrary; import java.awt.Color; import javax.swing.GroupLayout; -import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import net.runelite.client.ui.FontManager; @@ -40,7 +39,8 @@ class BookPanel extends JPanel GroupLayout layout = new GroupLayout(this); this.setLayout(layout); - JLabel image = new JLabel(new ImageIcon(b.getIcon())); + JLabel image = new JLabel(); + b.getIcon().addTo(image); JLabel name = new JLabel(b.getShortName()); location.setFont(FontManager.getRunescapeSmallFont()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java index 5096e2cd22..7395add2f8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java @@ -42,6 +42,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.NavigationButton; @@ -68,6 +69,9 @@ public class KourendLibraryPlugin extends Plugin @Inject private KourendLibraryOverlay overlay; + @Inject + private ItemManager itemManager; + private KourendLibraryPanel panel; private NavigationButton navButton; @@ -77,6 +81,8 @@ public class KourendLibraryPlugin extends Plugin @Override protected void startUp() throws Exception { + Book.fillImages(itemManager); + panel = injector.getInstance(KourendLibraryPanel.class); panel.init(); diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13514.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13514.png deleted file mode 100644 index fd432311a54eeab7c20ec2756fb09f13cdfccb80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 679 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10A}YWq#1%+0FfcY2$JG_a z*5pT5TzrWKn8n>r>`sfBPKyHR*@>}9#4?EvI56+Agu$$stmpUD;5I{ z683a)46!)9c2Z*aAp;)Q>1vYMD;F%<>i7Tudz1CD?%Td7zZY&VFLyRt_VT5oRNc?{ z2j(eU{JF(N)K8Pe&ble$(VR()bAlg>ks$fOY`8?4mUHhXv5w0#aAG%ALUvWe{rAtv#eY#$O zLvDYhYQRdP`( zkYX@0FtpG$Fw!+N4>2^gGBCC>G}kpSw=ytz;_7e!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10!aKkx#1%+0Ffg{2Ck1+X zHWtT~XGhc(#x|EG7#kaxW`?y_C3n`O_BCYG~bp9zYIfzMESykY)m6R)$wo zA2$FQ>?NMQuI!JP1jSfIs;qlFfkK>R1&--JS`&;5&C6tf2Jw2jIEGl9K0E1PRf_^o zi#SJT$HBGhKK;wT#rZ|4?EAI%uVwa}nXlMcY4dO4oR^bd)^a?#C*sC8LA>ztSs%3> z#c?0@GU+*m&AQTUc<=O6-teSgZ-q$X4)2!Bmy{<7txU;Iu5gwXn!Ks>r^_)0f#!y# z0W+Nq9x-(YsxAw1(%5A)-IQO@=?FuTPSlkB+j6BFZgOiLW7zP1L-D!msZ9(YypC^F zZtVDTBW>PO8~+~_OoulK_BUoY9F_6VP-yEgl@8F}%y_Fqy5J212Sawqv}kd$fR)TE z1(RLYTCnP@eed#9jIr`h*0!Vjg`Sm`GkCC1ioIy!Vsci_!FYM5#U4J3?~nKGydC$m zJNws@zf1QqE}qV}H~7MfeZUY>Epd$~Nl7e8wMs5Z1yT$~28I^821dGu<{^frRtCma qhUU5k=2ivPsvQH#I0ef#1Bv;GI+ZBxvX!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10!al$!#1%+0Ffdl-MwVuV z6{H5|B?lI#hX#6jPH4)i$&W72j_7O1s4I+ZuS)KzOEWe$ZY+*#E=}mHNo^}n0_was z>B?J>0VP3x!3+-1Zlr-YN#5=*3>~bp9zYIfzMESykY)j5CWhkPX;DB1dx@v7EBhlR zK`~a5D(fCkkh-!0$8;dA4aBMp6TD_f0}Yb#ba4!^IK6h#-Lk_9Jk1+#DoA+zsQh0( z*XQPmgoMF5oGq!O&$hjfPl+ZBsDeH<``>s#F z50`DzB0Fy`SkdV2F4*2)?(kMOn=#$>O5$EFt}jjA-QJcRmA(7F&wasWaNXObd4_P> zlnjPvaSs0sD_CdozhcjOAfkMsZk_@tz)D;rN>UO_QmvAUQh^kMk%6Iwu7Q!Rp?Qd* usg;4Tm7%$=fw`4|!4p@9TPPZG^HVa@DsgL=D)9pprwpF1elF{r5}E)-ZswE# diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13517.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13517.png deleted file mode 100644 index 79ea1d2ba648f01f0f683b937392838599b02645..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 676 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10A~wJ$#1%+0FfcY2$JG_a zmS%>PXGc`!M%LsdRC=-lqS38$2re!jhWsMRi5f@Y;0Vd9-0v5?(c3H z9ps!D=a&-Y)mENVkQ&@xmE2jA+EbU-*N_1;H%?W3HpuvrAirP+hi5m^K%69RcNc~Z zR#^`qhcn;Jtr#Q-#B2=iI)~l@8SEvVzOL+#m;}XGMXIcOJVENp3LMjcv?>s*Gt4NP z{Sv5$*VDx@#NzbcNjHm{4R~B9w&;e(I`6X3`}zO=o2i~gH(KnT@i7~}D44)<_`?f< zx8Ye48OzPuRvhYlnyIYVn`qL#N{L}!e4I5?lz^TA`@MViFE%KeNFCzydHCa|_9WpK z4B|45{qf&BvKSt$dOv^Kf;TKI7Bl@EA5~r$ z>uHACJ>T@?*S&5k`uIaFF<|Y9C`SoneeHnV%Yqe7A6n!0YLeSTn}7@ly%SLz8C02P zyqI=4>YyA$-S24&*>_C)|NC?K=@V|h7W`p+ohsm`Z+LMoD3nTEBT7;dOH!?pi&B9U zgOP!ug|2~-uAzB|p{bRDv6Z2@u7SCgfx#13hg&Eba`RI%(<*Umm@4rD6p0L;u6{1- HoD!Mjx diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13518.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13518.png deleted file mode 100644 index e955d7ae82e803ada23ef360ee862c7247e7e88b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 635 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10!Y{xl#1%+0Ffg{2C$(24 zch;o#)TK2R$JOLVmuE*5r-v4#23O@q))mG!mnM{Eh8Y_hx0IJRloV$tCX{AnO>S!o z^z`g&$e7TSHMu1lXpr23r@KMsl?3?(GdMiEkp|)cE&v(qC7!;n?2niP#aKnEtb05`>dFcn(}A=O5Nk3h{(8P1$oTB(;uvCa`s}6C zVTTQPST6j~6!+$1k^1ppKUL)NHLsvBof)D2&)n*kT>c{ec!GL=bxp_0|3bULsQsl>Ly~sa1SY-r_x9whVt*dT|j&++1&l6_754_yUcbP0l+XkKvn$!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10A~wJ$#1%+0Ffi5?##ZG< zmS;xO`t6l8o!kY6x^!?PP8F~%fscNc~Z zR#^`qhcn;Jtr$py{K&!}e>Y$akilN!>Fdh=h)Gb4Riw(g#}lNktiUlHNSgq$Izzx8 zuj@d@4^J1z5R21$CtZv>tiaFu;q&uCEfpT>N{h#_QTIb|BuJ=wX@7vwwpE2 zcvbR(3QpsL93CaJoSg*SnvOEB=`vO5wt8_;+rej|KxjjM`g#UKRwJY2s;as|t`j|l z=U>kbb}(ywcWvvXKkphR>4*Ao&9S>9$rbTGuyI4sk3X+O1G+m*8kstudD+i38HN=t9=1BQWWiEBhjN@7W>RdP`(kYX@0FtpG$Fw!+N4>2^gGBCC>G}kpS lw=ytz;_7e!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10!YRNf#1%+0Fff*9N0erU z)#OJv7RR+$CHFOCw3R0{mnKx@Mh1F%8XFsT)};2-rPUS2PHxH0PE07x%4#SnZYeJZ zYW^W-(FHQ2B*-tA!Qt7BG!Q4r+uensgH_f8$l=U)b1MeY>_E)Quq&d-7{n>@^mS!_ z#3U%jDpFX@Bn?Xz98OVblJzX3_EKZ-D6gaKffWuXowIw5E)y@A= z>`DIqs(K5)f4^&|rLt6BiNB@BD2;uBn3&@p$(<4V>Y6KW?_<>ncV&FIYjfz6x7QX3 zNVy%`_v)Yud=-K*q3hcL_T4?ib= zZ<^Bi@h-!rKX0cl3i$a{=J?AkVeAi2o!{JWYuPu2Cwt>6Hw$*1*kaG=p3N|C_1fQ# z8%{2WTaYChxF9_H?4&q`ZSNF9;@8bR$hy_=P;)|ut?>Eo*e8J>!Y{O*OmjI{xcGVS z#q`FAU%qc+6Yo4Z@OOr0F7wOsAMEEm1%wx<7^VU}uUg_7QIe8al4_M)lnSI6j0_Ad zbPbGj4b4LgO|1-!tqjd|4a}_!44$|;+(OZio1c=IR*74~REZy;h+^<`^>bP0l+XkK D((>3W diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13521.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13521.png deleted file mode 100644 index f21f84d0d33c055cabad0042a5ed8076e3810142..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 607 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10!Y05c#1%+0FfdMN%Ia&# z=&4I9P7f{33^O)1F3*k#^z`hkNv+C_Y_CeL$&YR>O{go3Z7hy!D^JQ!3;=2qF*^>j zfUzXVFPOpM*^M+1C&}C0g`tC0)&t1l%y)Au2GKyw&af$^@F0j$;_2(k{)kCXj8&w{ zy2leFUsm9l4x~+hSexOGC+lq>zzdfjBIMP@k_cr`z@D8i} zzZQQG{=)0}miNBK*?JbBr&UW_BT7;dOH!?pi&B9UgOP!ug|2~-uAzB|p{bRDv6Z2@ nu7SCgfx#13hg&Eba`RI%(<*Umm@4rD6hRE0u6{1-oD!M!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10A|${k#1%+0Ffaysde#-j zR^>*PXGavLhZdv;*W^bx7RNQ0CKM&Obe06xW_snvIcG%J85e!&b5&u)Ok7?Zr+T^Kr8Wj%l#&U`nw zVj#^1Vl&*`_-+=E!CvC&>&pI!Nl=Vcq{_O-6C_tw;Fu1ijeyvYVV13oERb==)5S5w z;`H5#C&dma@VH7(O6Uj{b^Z9?{>lMMK8MovqcIb-yW($zzsye8_o5IRn-tcSPij0k%TRwD&|1r1~d(MB}vpfISADmm) zX6>+)Yx(N5yHkMvQY~?fC`m~yNwrEYN(E93Mh1o!x&}tNhUOuLrd9^VRv@mqm4Sf} huYoa&hTQy=%(P0}8j=G#`hgl4JYD@<);T3K0RVda#SQ=f diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13523.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13523.png deleted file mode 100644 index 8afc530245ebe8d80f5569ab264c8b6799f1b4f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10!Xv;Z#1%+0FfjJirL|Wj zch;mD8ymNkCzWSMROLq2%|88VodoyCwVs$fS}WzhDN3XE)M7oFs2|7lsa2Sq~tGGvCdv7)Ub#F$Y7u_1v>S z278I8uPgf_CP6V)kt*vRPmsE@0>^Y9tpUWk4ENX*_5vASJzX3_EKXmYbh_-Y0*?!` zQiJNl>6iZfUtZ?Ycb>Csa;Y`9*u2v(8uPdRU%^njMOozD?I|%2|5X>Am}ynmSFrv{ zr>pUmsM*Im46be}X$TelXVow0DB;2Ga`f*{CyPUMT-)Dr?h)f$b;y9xp!~nkL~Eto z+uKT0&rW&t&x_@hLrCC>Ha?DtvT_RUlY!f82#vN1R*iMO>9O&kK-|R4)3qdYWXi%n5;o z|E3u-{@`nWx4f0PbLQXQ3olP@T#&c_f2{qD3#MQDU$7rM%&VDi@b)J#08~p{BT7;d zOH!?pi&B9UgOP!ug|2~-uAzB|p{bRDu@#7GZe?H~#A{%Tq9HdwB{QuOw}#|^j((s9 N22WQ%mvv4FO#mvw+fo1k diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13524.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13524.png deleted file mode 100644 index a0c2a1085ad34ff4bbdaed820e7e3e2e648b87d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 783 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10Vsd~_h%1n0U|@7Gle09C za<-JWHIa6+QS`J^3UE>Naa5L-8&Lq$Qc)?6YZxR zl%lV$BpjY)C@I3FuP(;V$F8j^!o|s&8*7vvVUQB4pBSt+V^?@ql%cAe;FPVQ1@Wd` zEBsp)c-PK!pRgf#@}`iU)d5X&z53P#mQ8f2p5_L0je9^+706K~L4Lsu4$p3+fjCLt z?k)@+tg;?J4rjibTQQJk17a424EYJyfeiK%PhVH|M@)iZtRhv`J)R(SWd)AuKw2M& z)fp_`?&t>^RP|gGy!JwbyUT=B#t%Lx z_f;uObr#zf@I!gRCbr8)EDWsHFN41C+_=J#pS)E`FDnz+m8BdVDaN$Ri&HX&A54I z+GXv9ch3DjbpP&pv)OMCKc24rbJ43X(bFq#-@W|KvQu5b>W_Tv*-bsuQ-1H7)1>j5 zJ4ODC*!_Fzx;#7wPOn+<@b@1FnaMvT-*8@%xiL9M?2E2@{Yw6AM}#fY13CPF!Kzx~ z8c~vxSdwa$T$Bo=7>o=IEp!cxbPdfz3{9;JjIBUib1MS_AzlMx6b-rgDVb@NxHTjP SbO7Uvfx*+&&t;ucLK6TkhY>me diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13525.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13525.png deleted file mode 100644 index 583c4d120082e30b4d28c7f376abf1dd8461de6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 811 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10Vo`ukh%1n0U|_VcvoNtV zv39UFvoW)EwzYS&H#9eN^>KCfau$~qclUR9@Nj5b>|<>cc_Z>sMX>gO5gDIz8! zC@dHl6%-H=5R{^?tgalMWvFMQr>(E8siVoq&!?uP#>K-G91|R$86TYz9i9+AV^?@& zQly-c+?1`M3E7FEaiLu+{96`y*UogGupxNzrjVZ10Zntg`ql-OO?0WA<_2`!uX^pd zAUBo-`2{mLJiCzw;v{*yyD)UH%6b4focV5U#Xy=3h*=miK8C{J0a+Sqj=R?sOM=E2yY*9KRqs ztCeZW1K5 zhKQ(>f<;Wb)i`ud<$O?@FTL=jxr6xARI}Ip1v~dQ)NpzgM23F;C;G3tobffw($rA# z!#3t&JK9T|rj<_6k6pLq9qYRF>)3;t#JLr#9oL5)zH>f;tGwHKiKt2RU6x?Bm7$yO z<;-?{XYE)h`z-IQ;l-@V-S^&X3)3tM@7eCMBjnhVZ*}|YGWh!auU2@Q<(K_FCZ)`G z{P|;Vp?-&wU-o6(*&_A6eEF*lJA&dLd|zr(`Cnq|1!IQCYUecm%$eV@rRhIkl+zKB z3{NZ0n$s8KUkU%W7E5fgiSY)8v1*BHL`h0wNvc(HQ7VvPFfuT-&^0j9H8c+~G_^7? pwgPd@tqcr=cnyqEH00)|WTsW(){q>~0gOBb22WQ%mvv4FO#put4Rini diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13526.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13526.png deleted file mode 100644 index 98389e896484a410322da4782925eeca61aa87f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 872 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;&6aZh%1n0U|@_jw~a8d zOtN;!uyYADGS78zPqlGQu&|3Vvo3Y@$#?e5vUk%Im#XpzSiHz5*wD<_*tp(1I6&W| z#Xqdv-A_qGOioa^J2<*6AfnbQC?#3H$tToKRWmEourn~yOWVLl&q!5F++9oGMN>zL zU$Dr<%TY~BoQF@Ci)UV3`t+#e$>H&RAu+plgwKshn;Ma5DzCJ4OX#wsoQ3h3E0*~$ znD0Gvy8DK8!J9UQtX>%~cdpmEHGvZ+xJ;Yk26X+|%3C0>GnNGT1v5B2yO9RsBze2L zFm$lWdH^|``EG8-K$;DRSr{_pCtL?I*h@TpUD+Qo35v0b^4jdV4^mfF;Fu1i^?_KO z!Sd~nexO0wo-U3d7N^%<$_#Ec5MWC%<5hV$L0Q$7iEHcBEbXYRSF8U0uTNcYO~~z~ z#pAl#`JQIG4SW9UG$>oXD&;=l&N4$HGM0%Wwaj@-G}G~~SsV4s7IA-&HRoWm-Xi%m z#$D89BHNDlETxJ$LXRqIJH7}f={3~~PHttEWjL}gTj}DYH=Lh8qhFTE&cE0!-5lfgG(8Y&QJ_tv_7f+ygl4OZ22puVtoNGwVw+n z_J`_SIqb7bSmWe!XWi#PJKjxSacjmoJ*i+Oz1oK&_n8*o{Iki@HDKlBm4>2Ob*uPA z&aK~~+3bBJW8)sZ%@KE>7;0ZH{>rc8<5IJEN9?*9#TR!M>{Wdw+VuI#{`!dNPoI6v zymW6;kNfIUO-p^V+t1&6Cv0ul_*;IpPtn7@Y_qplN=pQWE_kL{+jQSPN>@gr!6(%* z_lM>EiB4~ylm`fF?Q-y4k^?$`5zD~f>FVdQ&MBb@ E08`s8Bme*a diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13527.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13527.png deleted file mode 100644 index cf652a98b504bae9ec995b9926c9df2210d261be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 854 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;#h!Bh%1n0U|?)%wyh|) zXl_nuY=~=YurW3^Zf{F&Yfb9x2<+@kZEFjtuk)Tc-My*NXWA6Ei4$BVPYRznA*`jv zfAVD4zFz0}V&={*o;jmn@}%s( z-i(^+=qZzP>*`{sPs^V$A*-q~vZLLhr#r2*#Js#bqOH{)=mB4+%PJs$lmz(&GdMiE zkp|)G1mNK=omsE{-79QN4sUW0Xq$OtNAf1FkPh*n-4n_krf>cAfB&k; z4Z=BH%b&mgZD4JjK4D2cV}a`aOj9X^?fH(GCLwRT7G%36OD~u`E$eV9d&%D9$XBuA zejPiVzr?j`*Is}9`#XPs6Jw*ZkFe;GZMpZqw@ynGXgOD4p(B%R@~SaNIKifK-m=Y% zip6)|L@s_VZZX+^`TG3A7Xoo^It`U4f9v##H%~Y)zvk!RELn@sRgFshUTU-7^4%BU zaygw5wBcsLycKV^s4@KSGj`h+x#-mI`{F;m7>ngZQ#ut-PmRfYuNaqDp>cABV)j%% zM`z`;*I&P3F*Q+MX~NKBc>ePx6P_}eDifh7SwXv~wYP&jWxZY+E}Xf6iH}R}^hHGz zYYyvaA}j|=10SAKva6mE^KzHo>A;-@J6BZ1POp9Th}(4O`%UYYT@JsnBW8ib$#*9I ztu3}(((!Qm$J@I{Z{dE!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;(UNlh%1n0U|?)%wyh|) z=urW3^?&}Td?h3A|jGQq!*JAce z^U0H4`+A+byBz1t@?5;gXZ6Z}O&dcN%(q;&)MoJ_>$%3H`lrt z?NMQuI!JP1jSfI zd2ROG2dOJ7a7+i%nn0|?FzN96>p=C(Oq_V|Z znuHGCef9tU^0e0CDZU@S)I8q9zuEY(632h02R?NdGff@dd~?V$O?le0Kr1R+dcimL zO?=B`1KQgRC+NEe9Dcsc^o_KS7?zKf3sUmI{xu-@TWhU5>kIKosN`QFR}i!O6BYsVt-DC zua0CreSbEq!EuvS9GB1h`tgM8LG{H=YG+Lf=bE$JIGT7=?edh;jrNUeMU;HZO_we! zxz4_`!~dk&oh7EKfx8|#wl7!^_+(%FHG#+@>-Xg|Xe{k}EYkWsl}AZi%2GyfpVi#B zr6OvIF4sIxu5D;+axN~>30iiikCl^gLvF~7&2#1V&hU}EX?8ZyvamR?(9P`cxu3#P zr*15>&kc`vdR)?Y*JIbkfA1e$2->Ys@Kc|?ME_V>>S7CEc&nDUMwFx^mZVxG7o`Fz z1|tJQ3ta;vT|@H_LsKgQV=EBX+{(Z}h}XavMMG|WN@iLmZVkx+9sNKJ44$rjF6*2U FngH0MQ`-Ol diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13529.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13529.png deleted file mode 100644 index 738b4c3a3dd7cc05e80673b8267c6aa9290baddf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 802 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10Vsd~_h%1n0U||v}aR}klvEKutpdfhir0l-ljN+ou_O|4z%E;#C1fXk{{`hnT2*<)fq+}2Q$vG_KySd-EeqDJz4q&0{`Ir0kCqx;p84#3 z`LmkYzD*C}`5AnkD|RlESRm4AQQ6{f%A~>N+io_-G||Xu=ift8X0S> zAm}mE;JComnvEY=G*)t^$^4Q?;yW$4Vycdhrw7NgFvio24a=^z=zT0cH{XqM%{AY* zUKtskHQOrt?($qvx*)+?&ZV--_tPVh3)|cl-kIYTxG!z$Y{p%3ji-g27NyKqb>8>- z*S~d3?o4{f_o3}bD5qW2Ke=A-hHbZh3hnO6kWYUs&myUx?qDE$z~GTsd{mgp1)- zQ`rv+?RVR~YU!ip!kjO^=dKe>3AwCLWH&#OXZz0u4_AfF*;L(lo#FATKszJhovF({ z@1HMk`a=F!ZZOL$U`VT$xJHzuB$lLFB^RXvDF!10LknF4BV9xD5JOWd17j-?*WAj$ iK#14C7)3*FeoAIqC2kGL0UiB74Gf;HelF{r5}E+rnG(VP diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13530.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13530.png deleted file mode 100644 index 058ccef5e1da8eff496b7e0258a5958cb71e0576..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 686 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10A}zot#1%+0Ffi&Uv8&6m z8mO|HYO)LSF~QYLH3jc`2{mL zJiCzw;v{*yyD)UH%6b4focV5U#Xy=3h*=mi%(GT>o*pysQido-|Z_F>EK|LdP#3Tq8h z+rIlLbH#VNB@-81sTVuo)+c3lppD^{fI~}_;;V@bmfJ2AXy2L2#1nkkBfo6&vGT4D(vfQ@=mrFawt_;)y`YCd0oS)`^P07aUB2r zO$UWZPXn;tro@;Fm!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10qA|cH#1%+0Fff+JndgQZ zbr(2xC-zPb_iiD{@W=)Sq1Dn&__==dIJ0ZQqh7kM{TB8eYST~u1`z8e|3^&R;Xd5yH-VlMQO5Yew=erf=h0ULq>#MQiydz zphbDAduo_XR+K%^Zf&V|IUpyL1o;IsI6S+N2I3@nySp%Su*!M>Ih^@!ZpA>F2_(VL z_frk%F9!A!PhVH|M@)iZtfIU&d+vkOl@&Oq18GelR$`cRc>Q&tdLvI4#}JFtQzt(x zYck+*X~tujy=?q@_Oe@UKFxIE_O_Xu z-dClqUcm71@07d`$1i_(YOuBo?wDT}zhJ79@y5?P7r)n^F8TbXRF87e=?BM87hY53 z3|eU-yX?#3!Y`ZI4oEKEI<08)%k`4(_s_etWariet9-tvEY~C&5OBe5Ve;>V++}k_ zBp8+kD5{s%%c*JJSRJ^+W@k*umXN5GA6i?Rj;AFpk6-X{&wF} zVCX65{%iiBb--X$Epd$~Nl7e8wMs5Z1yT$~28I^821dGu<{^frRtCmaAg;NUfq@XO gfia4P-29Zxv`X9>k^?&Wff^V*UHx3vIVCg!0AX?mL;wH) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13532.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13532.png deleted file mode 100644 index 516b12fb2a6f0c319d41a7e395f56da78cb9174e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 735 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10qAtKE#1%+0FfghrDk{mz zsVghXOH0d2NolF6Ns5b$iHIy%Fj-hoP)AdfpO24+i%VZy+t}FHNKen--`&(eKRDPs zFwoQ7&@eRAFDf$7(!?Y#F4V@%EFmF0B_%pDBR)SrW!}7rrKMT3W_C}V+CF)5TUBLV zUtdE*Lvee1HPGUNvpK$j>@NxO3ubV5b|VeMN%D4gVd!9$^#F1>^WEHvfix2kvoRdp zvB4S0U@!6Xb!C6VBq+uz%4@UdK1f|zfnz$5)&ycLhA1gjpdh2Vr;B5V#p$(|UI#TB z2(TuYU1xO)c3E7JnZ0)E_j)ID-$Q%PSR~gK?X%o0Jt_5n6+?n``kZ`8fu2ImtF}ys znDwtz@xIWQ;&f&@+ZMGzkyf5XI?LI5Ive`fRaV_qIB-iLLZNm23auOZjJ^+x;~guR z0vS*d3UlOo98zx zV9kU1GVS{vqRqZsop;_zSV?ipl*LT{L!!flf9{HzapBmBe8ZEQbNu}e2ligQuATlS zeO|Rwo14O=QrXD{=YxBf37SM}N@O`?RO`P#>n3-m?BDm#+(!e%9=+0S2c{ba)e_f; zl9a@fRIB8oR3OD*WMF8aYha{nXdYr{YGq(-1>%}p85juh8W^K!$jwj5OsmALAvvI< QAE<%B)78&qol`;+0Hk2?c>n+a diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13533.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13533.png deleted file mode 100644 index cf652a98b504bae9ec995b9926c9df2210d261be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 854 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;#h!Bh%1n0U|?)%wyh|) zXl_nuY=~=YurW3^Zf{F&Yfb9x2<+@kZEFjtuk)Tc-My*NXWA6Ei4$BVPYRznA*`jv zfAVD4zFz0}V&={*o;jmn@}%s( z-i(^+=qZzP>*`{sPs^V$A*-q~vZLLhr#r2*#Js#bqOH{)=mB4+%PJs$lmz(&GdMiE zkp|)G1mNK=omsE{-79QN4sUW0Xq$OtNAf1FkPh*n-4n_krf>cAfB&k; z4Z=BH%b&mgZD4JjK4D2cV}a`aOj9X^?fH(GCLwRT7G%36OD~u`E$eV9d&%D9$XBuA zejPiVzr?j`*Is}9`#XPs6Jw*ZkFe;GZMpZqw@ynGXgOD4p(B%R@~SaNIKifK-m=Y% zip6)|L@s_VZZX+^`TG3A7Xoo^It`U4f9v##H%~Y)zvk!RELn@sRgFshUTU-7^4%BU zaygw5wBcsLycKV^s4@KSGj`h+x#-mI`{F;m7>ngZQ#ut-PmRfYuNaqDp>cABV)j%% zM`z`;*I&P3F*Q+MX~NKBc>ePx6P_}eDifh7SwXv~wYP&jWxZY+E}Xf6iH}R}^hHGz zYYyvaA}j|=10SAKva6mE^KzHo>A;-@J6BZ1POp9Th}(4O`%UYYT@JsnBW8ib$#*9I ztu3}(((!Qm$J@I{Z{dE!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+0817l2pPlzi}0g!2=r>CQ- zX=Bj zXJKJ!V&YYs<588hYrDR@w6w9Yv5lFTe@n4XQ=xZ#o>8b5Cp&v!XL&$dsY!&7VX%jo zh)76ZO>lRmtdVxa)TZ#s4Pg`O^aEU3xi}rHt)pkPMNMyUFV83~k#n}SjbGRkH?J#Z zZb#CxiHS@4-R$jCS4~M?F0+%#3pDHYt*YL;qHOolh=2ekIXQV#{XM%4wr$nlvPo~_I=%M88=4QUZ9K51 za`&>jqQc^gjI`L;n2=z9clZ5!4G$eKoN{tU|M9K8M>n^WmzU?{eKor)9>+r$k2sgEfWua5X4&OM?7@862M7NCR<_ zyxm>3vuavq28SEvVzOL+#m;}XGMR{%Z+y|*ED{xE)(!f|{ zP+>4VzY7?(j5j=8978NlPrdXud{%+TfkOQUUWO{JCpu>(c^|zX!?To ze@c1C)e-0tc zi$r%deb3z*_r7GC?c)iX1nvf26RB~G4t-y`ds%wGGA+Y9wb%H+RK5LoVABS}s984B zH{O12E4y!gdzYHwQiTRC=kg7PUvF{kUA*QI!!O<=&F%ee)y}uee77sw-m5)i$NTSD zS&n_J!8{+n{&~H9?cYv*zAT>Js?ZRpD7EXN$NTyFZR)@Ndi3G!?U&Y5>)x|FeR%lz z-T@Qe*vZG)J8G?F&O7Gqc;M%)ho6sLEWE$TD*EcD>FXyOS{ZRHIGJ+5`P%^#Dbtmb znlYReY>OwRp18Sr<^lN^x4+BVSI*eXf8opZI}QyGp6$KO`S)7vA`9yMd9d zTH+c}l9E`GYL#4+3Zxi}3=A!F4UBXR%|i@LtqhE!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10Vq<_$h%1n0U|{UbG^|U| zSx{{`x6-05-N4w`cv-#8;#%vhDEpO7HW?9iNg>v$VKy^L%<59DtCK8emzhs3GM!vt zvZlp$OP9l*2`-K4HZ7U9xiJn2ffh|gJ}o8wZRG)-m4V&W!QBOp`Ekxg2`;hz<`YX? z`ih)8ave&OT`LkSYV*9xGu=z$%!^{os~bp9zYIfzMESykY)l&F!cRY z1BL?wdx@v7EBhlRK`~ZQUYkAlLF&p19MgfcCJ-wzOgg;&I#9i|C;DLr9ZXoR>(~(FrU5|35yf&{F+|i2wWR&lA(i&MnCN&vk&eZaKeH!VKjN zY`nL3D(*P<_kqNNKJ{&k*JTT0&(FT0)@-IV|JS=4%Bl|%AK2K~X|kQUV4*!PeOBAU z70S*nZZgL=ovE>7TdjT|X{OEkYn#uOIiE}U$0YtE>+3G>@4t05vlyQk?Jk`aWd7sy zWU~{0o%b_*REa#Lv*}KKbvTzwi?~sw;;F~({tkMXu8MVk-a2Tvrk-A04j$FwFNAZkx05rHTFWb*}enm1!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+0817l}^Plzi}0g&nK9qj7r z6A%#L=^5zk>}6}~Y++%StrnM|8k4FV85|tr=NIbk?(g8>QKFSrsF{+do|vQ*7Oxai zp`9767#Jb%=V{LDYQpSb$ZVs>93Gw!7!=j0S6HW$H*-dTsx*VKv2k>CN@!?Yn?YHN zeo3gDw~-n%9~VQ9QB9{|Wst0gln6t7d}d^1(qxmy2_|($f;uzI+NPSe_)EL;FmvfE zGbbhG#>S@2wdkI0-jS5(VXnoTmR6XMn7!C~!UD_QYVDjgw$oSIOj%|#IV-C)B_)5I z-K>m^;%$x#w>Zq(Xg^1vUo$VSDkrCWkIS;1&WrO4Y7V-t+V8TWvop25E%~I!#^dhm zkGQQ(^AuvbL01LNTK_x~)Qs3-~Y3ubV5b|VeMN%D4gVd!9$ z^#F1>^WEHvfix2sFTGOg4rH*Gc>21sKVlLTV-@AK*>fMHuB^Z@9Y_O{0D}sH>G@s2 zbinw*)5S5w;`G!@zvC|jNU(j74eD+@CefoI%aV62%pze@ualber5OfILAx6&RCU+B zse5n#e$K}3ABwA=U;qBQ@?7<{=EVPk4F8P2$5>2n*!Z!td-{R-y_|b2-Z3v0{NV2w z%O~LIazbE35t~oT;f@Nyg-YRz!q@L)@;P6z>_vo3s)Gi{y5<&J|8sqn64QFE4>}iL zlwPT5aPlM1;Y-bx0_w`<`Hd~C4psN;l~aslOmupE4tNJec5NzeNHCi&?3$vG_%cG_ zMf8cu+t(@|cr^EC=E{HuHvu1~_U4dp?`*T#17f_?y;URK*sd1X?CsHiGFR52&@eVk zq%=X`VMNoZNs-lYn(K5zS3ljfNU51a+?lnqy7|;!(Y0ZhbCta<=Pd|x_H*1DXxOtX zO|oK&&anrg&*n6-e|1}Z*KF2_7gj1l{w`s2c?~XP%q;9t;t@Sy-D6*~W!pZ+*32xS z&p%EEf13GwruIKS^L;mO-@13xH79@n|33<%CwKo}IWI(X>xH*6`z&fIOa8q2I(zc= z_cib5GV#>>xRLcLG}1zVUzKT-~E5ef=jYGL zy}AEcT7OT0;K6{<0$?IgEpd$~Nl7e8wMs5Z1yT$~28I^821dGu<{^frRtCmaAg;NU kfq@XOfia4P-29Zxv`X9>k^?&Wff^V*UHx3vIVCg!0P0G~V*mgE diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13537.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13537.png deleted file mode 100644 index b0a0f6d8905f4f9c63ab8b3465b7f2043f2ef9a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1171 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+0817l%;Plzi}0g!2=r>CQ- zX=ZVPR=vQXY|A8kV_hyMCCxpS-lRv9Ym@nOR+IVNG;?pp7RdJ9~3NX=7Y*Rb;Ne zrMsAjNM~wIdvaA>xv4CGcwX*V`D;s{oUR7?=?Jh!0^zr?FScc-9LZR-nkoF%FD}h za&nWC62imn^(+ECJ$+nVC$+X5S-x}iO6_%PbdIguePH31-80s8)z((!1^057 z7|1X;GIlo_^fEk`;7y6?Vl0m6oa(e}W>{Fs{`h~t&)wjyKJn@I?Rnon*PO5ZCe#01 zi1Ej9nZx=j4hcKHbN#u?u(6?9ytYp0nKFj}x3`F>35P6`_H%|d{no>$%{pC@c^Y>z zT@aV^SLvP6;`%^q$s5ad2dl}RR*K5nJoDxs<4{fReXTOLQ0vSw3Co zZk^-!h$FymmhPrCdzp{SaL9~3p`1MF$S0+pifwzY2?ji~a9cHnCwWqZg@oq418Za* z^p5Yy+Nu`GHu0+O|F#!z5*l_bGSO-F&~x7Cx+~-S?4q4_vbN_2YjU>k_`ht2+AV35 z)SqF?7jKJNw$k&pjTVO`>)pJ~*RPu#H_38pnxlK;RoPd^^M-GC9SOdeyPU!F#pN4r zYo7~0$t^sp=TLs&-JQFV?_M<@yi&5{%iguWzc7C{H)pOs`S)VQpAQc%eh844v9+r! znpDbtK`_QSGh|Zra)1B%w)WK@KV5yY)n|Vpm(7Q7ck|+NSC)E8yjA}8FQZ7NXBX?S z>~{Wi_I6v}>~Qba{`tq0OT4!;s7^JScmKJ5e0x=Vs8(g&<>_-ZH}v$DnYen)pQHVQ zx%T(J$Lh?*&-7;fnHBv&X-9?K+mCzH@1NSI)|ds8zo@>NS*BT7;dOH!?pi&B9U zgOP!ug|2~-uAzB|p{bRDu@#7GZe?H~#A{%Tq9HdwB{QuOw}#|^j((s922WQ%mvv4F FO#o@;%Rm4C diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/19637.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/19637.png deleted file mode 100644 index d60bcbdcabf41ec51d54be3ec5303dc9c29ead72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 947 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081EXw!Plzi}0g&nA>gwU> z;B0GaXJMhQt*@i0G8?Y-}W}s4XR{DK2HCXQ-v7Wh$?vFD+-PZ>p}WZfpx_8#5a_RZTk!I|pkAM>Q>HTW1$d9XESd4+jr-EqyO%FE4EaA6FlL zcmF`oKqWaPA3dXB@8E>+@K8U$P`}XfoSgjBl$7Y`0DY5)fba>;O>LExH3j*_85zNb zW>JBWOQuho-P=34t*xuJwyCT%CO9T8G%g`LAt^E`B|2sO(k0V7J421k8ybpRTFSdR zYbQ)-nmoB}*39m?bNd%9nzDS^>?KR4Em$yl`t;78?z#vQ%c)b_SIwKZXzG+%-Q7`U z)@iY63nou)C@GFLw@t9H1BMIdJ||vK@RS7k1v5B2yO9RsBze2LFm$lWdVmz3IIs~9WS{BXg@CyyS? zbD3Dd8<=Vzk>kk4b^i5)Wn7sByh$39Qk-_F8EI%}Olp0hB;4d)(b_x1$UAr9Q&ZW+ z0WLZ-@7`mKwrC4<(kU&^muFe`c#7ceptZ6M3*K4rE~&hcC4X?iyIseP=lX5G{d(?~ z*~{Nbah$vJx%*&&$vhwZ_3P9h&%XGfj3HipXR+JkJ6Go4&EAzaYg%fS5jXSUO>dJn zhGqCBR^uMF(Z6|%S z8Yk_s1O~WjiEBhjN@7W>RdP`(kYX@0FtpG$Fw!+N4>2^gGBCCRam}p^41{gTe~DWM4f^ixKm diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/21756.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/21756.png deleted file mode 100644 index 5021db2a7df60215c3996dbc3750da28ac12735f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 738 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10qA|cH#1%+0FfiI!Gn<<; zJJ>TD88PeYF}u1jYiTm5Dl^QU-77E8;OW6ECB+~j!r77%jwojVWGGRhf zd3jDxcU@gwVOv`z(C*X6>XblEC<*clW^j0RBMrn!@^*J&=wOxg0CG6<-Q0?SG!qcB zF&x~n!5PS4FY)wsWq-sZD8?$vYqRG*NL^WhV>*!51Y#|QC@EE-Afvjci(`nz>9v<` z`W-e9V7<_Dz4P%kUPkALQ(+oE|I4Su+`cKz$!Y&gF7~X2URS*>!-l!W=eF~39NRJF zl@z0(gFx0^wh|#P#cAHmQIidhozPg7m3812%L^8Vr0w!77UHbkM_Rh>^6_~)1h?3P z1k7W+^3~&sX5KHRj8}0_LO1T&8=T4Z!Pj`@jx|wtAKQgC%*gI|*OmwQECPm| zYKdz^NlIc#s#S7PDv)9@GBC8zH89dOG!HQ}wK6ca0&&f)3=D*L4UADVFVdQ&MBb@0ID(fZU6uP From 8cd5675d36539ba7231acfd6c30b70b610ad4613 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Wed, 11 Apr 2018 03:46:18 -0600 Subject: [PATCH 5/5] Use ItemManager in GrandExchangePlugin --- .../grandexchange/GrandExchangeItemPanel.java | 7 +++---- .../grandexchange/GrandExchangeItems.java | 6 +++--- .../GrandExchangeSearchPanel.java | 21 ++----------------- .../GrandExchangeOfferSlotTest.java | 4 ++-- 4 files changed, 10 insertions(+), 28 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItemPanel.java index 72febcf417..24905da2c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItemPanel.java @@ -30,14 +30,13 @@ import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; -import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import lombok.extern.slf4j.Slf4j; +import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.StackFormatter; @@ -46,7 +45,7 @@ class GrandExchangeItemPanel extends JPanel { private static final Dimension ICON_SIZE = new Dimension(32, 32); - GrandExchangeItemPanel(BufferedImage icon, String name, int itemID, int gePrice, Double + GrandExchangeItemPanel(AsyncBufferedImage icon, String name, int itemID, int gePrice, Double haPrice) { BorderLayout layout = new BorderLayout(); @@ -88,7 +87,7 @@ class GrandExchangeItemPanel extends JPanel itemIcon.setPreferredSize(ICON_SIZE); if (icon != null) { - itemIcon.setIcon(new ImageIcon(icon)); + icon.addTo(itemIcon); } add(itemIcon, BorderLayout.LINE_START); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItems.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItems.java index 28300b295a..ef8cb0fcb0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItems.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeItems.java @@ -24,19 +24,19 @@ */ package net.runelite.client.plugins.grandexchange; -import java.awt.image.BufferedImage; import lombok.Data; +import net.runelite.client.game.AsyncBufferedImage; @Data public class GrandExchangeItems { - private final BufferedImage icon; + private final AsyncBufferedImage icon; private final String name; private final int itemId; private final int gePrice; private final double haPrice; - GrandExchangeItems(BufferedImage icon, String name, int itemId, int gePrice, double haPrice) + GrandExchangeItems(AsyncBufferedImage icon, String name, int itemId, int gePrice, double haPrice) { this.icon = icon; this.name = name; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java index f500e032e1..d3eb52044d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java @@ -44,10 +44,10 @@ import javax.swing.border.EmptyBorder; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.ItemComposition; +import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.hiscore.IconTextField; import net.runelite.http.api.item.Item; -import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.SearchResult; @@ -60,8 +60,6 @@ class GrandExchangeSearchPanel extends JPanel private final ItemManager itemManager; private final ScheduledExecutorService executor; - private ItemClient itemClient; - private Icon search; private IconTextField searchBox = new IconTextField(); @@ -150,8 +148,6 @@ class GrandExchangeSearchPanel extends JPanel if (result != null && !result.getItems().isEmpty()) { - itemClient = new ItemClient(); - for (Item item : result.getItems()) { int itemId = item.getId(); @@ -172,20 +168,7 @@ class GrandExchangeSearchPanel extends JPanel log.warn("Unable to fetch item price for {}", itemId, ex); } - BufferedImage itemImage = null; - try - { - itemImage = itemClient.getIcon(itemId); - } - catch (IOException ex) - { - log.warn("Unable to fetch item icon for {}", itemId, ex); - } - - if (itemImage == null) - { - log.warn("Unable to fetch item icon for {}", itemId); - } + AsyncBufferedImage itemImage = itemManager.getImage(itemId); ITEMS_LIST.add(new GrandExchangeItems(itemImage, item.getName(), itemId, itemPrice != null ? itemPrice.getPrice() : 0, itemComp.getPrice() * 0.6)); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlotTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlotTest.java index 2ed3b1175a..313278a734 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlotTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlotTest.java @@ -25,10 +25,10 @@ package net.runelite.client.plugins.grandexchange; -import java.awt.image.BufferedImage; import net.runelite.api.GrandExchangeOffer; import net.runelite.api.GrandExchangeOfferState; import net.runelite.api.ItemComposition; +import net.runelite.client.game.AsyncBufferedImage; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -48,7 +48,7 @@ public class GrandExchangeOfferSlotTest when(offer.getState()).thenReturn(GrandExchangeOfferState.CANCELLED_BUY); GrandExchangeOfferSlot offerSlot = new GrandExchangeOfferSlot(); - offerSlot.updateOffer(mock(ItemComposition.class), mock(BufferedImage.class), offer); + offerSlot.updateOffer(mock(ItemComposition.class), mock(AsyncBufferedImage.class), offer); } }