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/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/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(); + } } } } 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 03ab868452..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 @@ -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; @@ -48,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; @@ -74,20 +74,22 @@ public class ItemManager */ static final ItemPrice NONE = new ItemPrice(); - private final Provider client; + 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(Provider 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) @@ -109,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); } @@ -126,7 +128,7 @@ public class ItemManager @Override public ItemComposition load(Integer key) throws Exception { - return client.get().getItemDefinition(key); + return client.getItemDefinition(key); } }); } @@ -272,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.get().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-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/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 fd432311a5..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13514.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13515.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13515.png deleted file mode 100644 index 65279b24b8..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13515.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13516.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13516.png deleted file mode 100644 index 272c806e73..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13516.png and /dev/null differ 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 79ea1d2ba6..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13517.png and /dev/null differ 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 e955d7ae82..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13518.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13519.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13519.png deleted file mode 100644 index e2afb3a60e..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13519.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13520.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13520.png deleted file mode 100644 index 5f60351a10..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13520.png and /dev/null differ 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 f21f84d0d3..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13521.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13522.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13522.png deleted file mode 100644 index aecc61a062..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13522.png and /dev/null differ 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 8afc530245..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13523.png and /dev/null differ 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 a0c2a1085a..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13524.png and /dev/null differ 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 583c4d1200..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13525.png and /dev/null differ 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 98389e8964..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13526.png and /dev/null differ 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 cf652a98b5..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13527.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13528.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13528.png deleted file mode 100644 index f5625c5ea8..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13528.png and /dev/null differ 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 738b4c3a3d..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13529.png and /dev/null differ 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 058ccef5e1..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13530.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13531.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13531.png deleted file mode 100644 index 9d61342efa..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13531.png and /dev/null differ 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 516b12fb2a..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13532.png and /dev/null differ 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 cf652a98b5..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13533.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13534.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13534.png deleted file mode 100644 index 40479929f3..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13534.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13535.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13535.png deleted file mode 100644 index e646c21655..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13535.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13536.png b/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13536.png deleted file mode 100644 index a72d1236f1..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13536.png and /dev/null differ 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 b0a0f6d890..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/13537.png and /dev/null differ 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 d60bcbdcab..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/19637.png and /dev/null differ 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 5021db2a7d..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/kourendlibrary/items/21756.png and /dev/null differ 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); } } 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; } }