diff --git a/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java b/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java index ceb49644c4..55062db92e 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java @@ -28,9 +28,16 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.eventbus.Subscribe; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBufferByte; +import java.awt.image.IndexColorModel; +import java.awt.image.WritableRaster; +import java.io.IOException; import java.util.Arrays; import java.util.Objects; import java.util.concurrent.TimeUnit; +import javax.imageio.ImageIO; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; @@ -38,13 +45,26 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.ClanMember; import net.runelite.api.ClanMemberRank; import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.IndexedSprite; import net.runelite.api.events.ClanChanged; +import net.runelite.api.events.GameStateChanged; import net.runelite.client.util.Text; @Singleton @Slf4j public class ClanManager { + private static final String[] CLANCHAT_IMAGES = + { + "Friend_clan_rank.png", "Recruit_clan_rank.png", + "Corporal_clan_rank.png", "Sergeant_clan_rank.png", + "Lieutenant_clan_rank.png", "Captain_clan_rank.png", + "General_clan_rank.png", "Owner_clan_rank.png" + }; + + private int modIconsLength; + @Inject private Provider clientProvider; @@ -78,15 +98,107 @@ public class ClanManager return clanRanksCache.getUnchecked(playerName); } + public int getIconNumber(final ClanMemberRank clanMemberRank) + { + return modIconsLength - CLANCHAT_IMAGES.length + clanMemberRank.getValue(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) + { + if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN + && modIconsLength == 0) + { + // this is after "Loading sprites" so we can modify modicons now + loadClanChatIcons(); + } + } + @Subscribe public void onClanChange(ClanChanged clanChanged) { clanRanksCache.invalidateAll(); } + private void loadClanChatIcons() + { + try + { + final Client client = clientProvider.get(); + final IndexedSprite[] modIcons = client.getModIcons(); + final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + CLANCHAT_IMAGES.length); + int curPosition = newModIcons.length - CLANCHAT_IMAGES.length; + + for (String resource : CLANCHAT_IMAGES) + { + IndexedSprite sprite = createIndexedSprite(client, resource); + newModIcons[curPosition++] = sprite; + } + + client.setModIcons(newModIcons); + modIconsLength = newModIcons.length; + } + catch (IOException e) + { + log.warn("Failed loading of clan chat icons", e); + } + } + private static String sanitize(String lookup) { final String cleaned = Text.removeTags(lookup); return cleaned.replace('\u00A0', ' '); } + + + private static IndexedSprite createIndexedSprite(final Client client, final String imagePath) throws IOException + { + final BufferedImage bufferedImage = rgbaToIndexedBufferedImage(ImageIO + .read(ClanManager.class.getResource(imagePath))); + + final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); + + final int width = bufferedImage.getWidth(); + final int height = bufferedImage.getHeight(); + final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); + final int[] palette = new int[indexedCM.getMapSize()]; + indexedCM.getRGBs(palette); + + final IndexedSprite newIndexedSprite = client.createIndexedSprite(); + newIndexedSprite.setPixels(pixels); + newIndexedSprite.setPalette(palette); + newIndexedSprite.setWidth(width); + newIndexedSprite.setHeight(height); + newIndexedSprite.setOriginalWidth(width); + newIndexedSprite.setOriginalHeight(height); + newIndexedSprite.setOffsetX(0); + newIndexedSprite.setOffsetY(0); + return newIndexedSprite; + } + + private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) + { + final BufferedImage indexedImage = new BufferedImage( + sourceBufferedImage.getWidth(), + sourceBufferedImage.getHeight(), + BufferedImage.TYPE_BYTE_INDEXED); + + final ColorModel cm = indexedImage.getColorModel(); + final IndexColorModel icm = (IndexColorModel) cm; + + final int size = icm.getMapSize(); + final byte[] reds = new byte[size]; + final byte[] greens = new byte[size]; + final byte[] blues = new byte[size]; + icm.getReds(reds); + icm.getGreens(greens); + icm.getBlues(blues); + + final WritableRaster raster = indexedImage.getRaster(); + final int pixel = raster.getSample(0, 0, 0); + final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); + final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); + resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); + return resultIndexedImage; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java index 804bf98dc1..b7031212fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java @@ -25,23 +25,13 @@ package net.runelite.client.plugins.clanchat; import com.google.common.eventbus.Subscribe; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.DataBufferByte; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; -import java.io.IOException; import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import javax.imageio.ImageIO; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ClanMemberRank; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.api.IndexedSprite; -import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.SetMessage; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; @@ -56,42 +46,12 @@ import net.runelite.client.task.Schedule; @Slf4j public class ClanChatPlugin extends Plugin { - private static final String[] CLANCHAT_IMAGES = - { - "Friend_clan_rank.png", "Recruit_clan_rank.png", - "Corporal_clan_rank.png", "Sergeant_clan_rank.png", - "Lieutenant_clan_rank.png", "Captain_clan_rank.png", - "General_clan_rank.png", "Owner_clan_rank.png" - }; - - private int modIconsLength; - @Inject private Client client; @Inject private ClanManager clanManager; - @Override - protected void startUp() throws Exception - { - if (modIconsLength == 0 && client.getGameState().compareTo(GameState.LOGIN_SCREEN) >= 0) - { - loadClanChatIcons(); - } - } - - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) - { - if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN - && modIconsLength == 0) - { - // this is after "Loading sprites" so we can modify modicons now - loadClanChatIcons(); - } - } - @Schedule( period = 600, unit = ChronoUnit.MILLIS @@ -124,79 +84,6 @@ public class ClanChatPlugin extends Plugin } } - private void loadClanChatIcons() - { - try - { - final IndexedSprite[] modIcons = client.getModIcons(); - final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + CLANCHAT_IMAGES.length); - int curPosition = newModIcons.length - CLANCHAT_IMAGES.length; - - for (String resource : CLANCHAT_IMAGES) - { - IndexedSprite sprite = createIndexedSprite(resource); - newModIcons[curPosition++] = sprite; - } - - client.setModIcons(newModIcons); - modIconsLength = newModIcons.length; - } - catch (IOException e) - { - log.warn("Failed loading of clan chat icons", e); - } - } - - private IndexedSprite createIndexedSprite(final String imagePath) throws IOException - { - final BufferedImage bufferedImage = rgbaToIndexedBufferedImage(ImageIO - .read(this.getClass().getResource(imagePath))); - - final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel(); - - final int width = bufferedImage.getWidth(); - final int height = bufferedImage.getHeight(); - final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); - final int[] palette = new int[indexedCM.getMapSize()]; - indexedCM.getRGBs(palette); - - final IndexedSprite newIndexedSprite = client.createIndexedSprite(); - newIndexedSprite.setPixels(pixels); - newIndexedSprite.setPalette(palette); - newIndexedSprite.setWidth(width); - newIndexedSprite.setHeight(height); - newIndexedSprite.setOriginalWidth(width); - newIndexedSprite.setOriginalHeight(height); - newIndexedSprite.setOffsetX(0); - newIndexedSprite.setOffsetY(0); - return newIndexedSprite; - } - - private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) - { - final BufferedImage indexedImage = new BufferedImage( - sourceBufferedImage.getWidth(), - sourceBufferedImage.getHeight(), - BufferedImage.TYPE_BYTE_INDEXED); - - final ColorModel cm = indexedImage.getColorModel(); - final IndexColorModel icm = (IndexColorModel) cm; - - final int size = icm.getMapSize(); - final byte[] reds = new byte[size]; - final byte[] greens = new byte[size]; - final byte[] blues = new byte[size]; - icm.getReds(reds); - icm.getGreens(greens); - icm.getBlues(blues); - - final WritableRaster raster = indexedImage.getRaster(); - final int pixel = raster.getSample(0, 0, 0); - final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel); - final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null); - resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null); - return resultIndexedImage; - } private void insertClanRankIcon(final SetMessage message) { @@ -204,15 +91,12 @@ public class ClanChatPlugin extends Plugin if (rank != null && rank != ClanMemberRank.UNRANKED) { - int iconNumber = getIconNumber(rank); + int iconNumber = clanManager.getIconNumber(rank); message.getMessageNode() .setSender(message.getMessageNode().getSender() + " "); client.refreshChat(); } } - private int getIconNumber(final ClanMemberRank clanMemberRank) - { - return modIconsLength - CLANCHAT_IMAGES.length + clanMemberRank.getValue(); - } + } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Captain_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Captain_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Captain_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Captain_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Corporal_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Corporal_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Corporal_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Corporal_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Friend_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Friend_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Friend_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Friend_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/General_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/General_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/General_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/General_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Lieutenant_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Lieutenant_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Lieutenant_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Lieutenant_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Owner_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Owner_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Owner_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Owner_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Recruit_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Recruit_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Recruit_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Recruit_clan_rank.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Sergeant_clan_rank.png b/runelite-client/src/main/resources/net/runelite/client/game/Sergeant_clan_rank.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/clanchat/Sergeant_clan_rank.png rename to runelite-client/src/main/resources/net/runelite/client/game/Sergeant_clan_rank.png