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 bbfd3452cf..0b80bbc7e9 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 @@ -30,10 +30,6 @@ import com.google.common.cache.LoadingCache; import java.awt.Color; import java.awt.Dimension; 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.util.Arrays; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -152,8 +148,8 @@ public class ClanManager for (int i = 0; i < CLANCHAT_IMAGES.length; i++, curPosition++) { final int resource = CLANCHAT_IMAGES[i]; - clanChatImages[i] = rgbaToIndexedBufferedImage(clanChatImageFromSprite(spriteManager.getSprite(resource, 0))); - newModIcons[curPosition] = createIndexedSprite(client, clanChatImages[i]); + clanChatImages[i] = clanChatImageFromSprite(spriteManager.getSprite(resource, 0)); + newModIcons[curPosition] = ImageUtil.getImageIndexedSprite(clanChatImages[i], client); } client.setModIcons(newModIcons); @@ -166,54 +162,6 @@ public class ClanManager return cleaned.replace('\u00A0', ' '); } - private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) - { - 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 static BufferedImage clanChatImageFromSprite(final BufferedImage clanSprite) { final BufferedImage clanChatCanvas = ImageUtil.resizeCanvas(clanSprite, CLANCHAT_IMAGE_DIMENSION.width, CLANCHAT_IMAGE_DIMENSION.height); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java new file mode 100644 index 0000000000..5318d58ecb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2019, Lotto + * 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.plugins.emojis; + +import java.awt.image.BufferedImage; +import java.util.HashMap; +import java.util.Map; +import net.runelite.client.util.ImageUtil; + +public enum Emoji +{ + SLIGHT_SMILE(":)"), + JOY("=')"), + COWBOY("3:)"), + BLUSH("^_^"), + SMILE(":D"), + GRINNING("=D"), + WINK(";)"), + STUCK_OUT_TONGUE_CLOSED_EYES("X-P"), + STUCK_OUT_TONGUE(":P"), + YUM("=P~"), + HUGGING(":D"), // >:D< + TRIUMPH(":"), // :> + THINKING(":-?"), + CONFUSED(":/"), + NEUTRAL_FACE("=|"), + EXPRESSIONLESS(":|"), + UNAMUSED(":-|"), + SLIGHT_FROWN(":("), + FROWNING2("=("), + CRY(":'("), + SOB(":_("), + FLUSHED(":$"), + ZIPPER_MOUTH(":-#"), + PERSEVERE("_"), // >_< + SUNGLASSES("8-)"), + INNOCENT("O:)"), + SMILING_IMP(":)"), // >:) + RAGE(":("), // >:( + HUSHED(":-O"), + OPEN_MOUTH(":O"), + SCREAM(":-@"), + SEE_NO_EVIL("X_X"), + DANCER("\\:D/"), + OK_HAND("(Ok)"), + THUMBSUP("(Y)"), + THUMBSDOWN("(N)"), + HEARTS("3"), // <3 + BROKEN_HEART("/3"), // "), // <>< + CAT(":3"), + DOG("=3"), + CRAB("V(;,;)V"), + FORK_AND_KNIFE("--E"), + COOKING("--(o)"), + PARTY_POPPER("@@@"); + + private static final Map emojiMap = new HashMap<>(); + + private final String trigger; + + static + { + final Emoji[] emojis = values(); + + for (final Emoji emoji : emojis) + { + emojiMap.put(emoji.trigger, emoji); + } + } + + Emoji(String trigger) + { + this.trigger = trigger; + } + + public static Emoji getEmoji(String trigger) + { + return emojiMap.get(trigger); + } + + public BufferedImage loadImage() + { + return ImageUtil.getResourceStreamFromClass(getClass(), this.name().toLowerCase() + ".png"); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java new file mode 100644 index 0000000000..a04bb443db --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2019, Lotto + * 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.plugins.emojis; + +import java.awt.image.BufferedImage; +import java.util.Arrays; +import javax.inject.Inject; +import joptsimple.internal.Strings; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.IndexedSprite; +import net.runelite.api.MessageNode; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameStateChanged; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.util.ImageUtil; + +@PluginDescriptor( + name = "Emojis", + description = "Replaces common emoticons such as :) with their corresponding emoji in the chat", + enabledByDefault = false, + type = PluginType.UTILITY +) +@Slf4j +public class EmojiPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ChatMessageManager chatMessageManager; + + private int modIconsStart = -1; + + @Override + protected void startUp() + { + } + + @Override + protected void shutDown() + { + } + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) + { + if (gameStateChanged.getGameState() == GameState.LOGGED_IN + && modIconsStart == -1) + { + loadEmojiIcons(); + } + } + + private void loadEmojiIcons() + { + final Emoji[] emojis = Emoji.values(); + + final IndexedSprite[] modIcons = client.getModIcons(); + final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + emojis.length); + modIconsStart = modIcons.length; + + for (int i = 0; i < emojis.length; i++) + { + final Emoji emoji = emojis[i]; + + try + { + final BufferedImage image = emoji.loadImage(); + final IndexedSprite sprite = ImageUtil.getImageIndexedSprite(image, client); + newModIcons[modIconsStart + i] = sprite; + } + catch (Exception ex) + { + log.warn("Failed to load the sprite for emoji " + emoji, ex); + } + } + + client.setModIcons(newModIcons); + } + + @Subscribe + public void onChatMessage(ChatMessage chatMessage) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + switch (chatMessage.getType()) + { + case PUBLICCHAT: + case MODCHAT: + case FRIENDSCHAT: + case PRIVATECHAT: + case PRIVATECHATOUT: + break; + default: + return; + } + + final String message = chatMessage.getMessage(); + final String[] messageWords = message.split(" "); + + boolean editedMessage = false; + for (int i = 0; i < messageWords.length; i++) + { + final Emoji emoji = Emoji.getEmoji(messageWords[i]); + + if (emoji == null) + { + continue; + } + + final int emojiId = modIconsStart + emoji.ordinal(); + + messageWords[i] = ""; + editedMessage = true; + } + + // If we haven't edited the message any, don't update it. + if (!editedMessage) + { + return; + } + + final String newMessage = Strings.join(messageWords, " "); + + final MessageNode messageNode = chatMessage.getMessageNode(); + messageNode.setRuneLiteFormatMessage(newMessage); + chatMessageManager.update(messageNode); + client.refreshChat(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 16a6b1c78a..d7f579b722 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -24,6 +24,7 @@ */ package net.runelite.client.util; +import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; @@ -34,12 +35,15 @@ import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.RescaleOp; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javax.imageio.ImageIO; import javax.swing.GrayFilter; import java.util.function.Predicate; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.IndexedSprite; import net.runelite.api.SpritePixels; /** @@ -448,4 +452,74 @@ public class ImageUtil return client.createSpritePixels(pixels, image.getWidth(), image.getHeight()); } + + /** + * Converts an image into an {@code IndexedSprite} instance. + * + * The passed in image can only have at max 255 different colors. + * + * @param image The image to be converted + * @param client Current client instance + * @return The image as an {@code IndexedSprite} + */ + public static IndexedSprite getImageIndexedSprite(BufferedImage image, Client client) + { + final byte[] pixels = new byte[image.getWidth() * image.getHeight()]; + final List palette = new ArrayList<>(); + /* + When drawing the indexed sprite, palette idx 0 is seen as fully transparent, + so pad the palette out so that our colors start at idx 1. + */ + palette.add(0); + + final int[] sourcePixels = image.getRGB(0, 0, + image.getWidth(), image.getHeight(), + null, 0, image.getWidth()); + + /* + Build a color palette and assign the pixels to positions in the palette. + */ + for (int j = 0; j < sourcePixels.length; j++) + { + final int argb = sourcePixels[j]; + final int a = (argb >> 24) & 0xFF; + final int rgb = argb & 0xFF_FF_FF; + + // Default to not drawing the pixel. + int paletteIdx = 0; + + // If the pixel is fully opaque, draw it. + if (a == 0xFF) + { + paletteIdx = palette.indexOf(rgb); + + if (paletteIdx == -1) + { + paletteIdx = palette.size(); + palette.add(rgb); + } + } + + pixels[j] = (byte) paletteIdx; + } + + if (palette.size() > 256) + { + throw new RuntimeException("Passed in image had " + (palette.size() - 1) + + " different colors, exceeding the max of 255."); + } + + final IndexedSprite sprite = client.createIndexedSprite(); + + sprite.setPixels(pixels); + sprite.setPalette(Ints.toArray(palette)); + sprite.setWidth(image.getWidth()); + sprite.setHeight(image.getHeight()); + sprite.setOriginalWidth(image.getWidth()); + sprite.setOriginalHeight(image.getHeight()); + sprite.setOffsetX(0); + sprite.setOffsetY(0); + + return sprite; + } } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE new file mode 100644 index 0000000000..9e2a9503a0 --- /dev/null +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE @@ -0,0 +1 @@ +The images in this folder are derivatives of "twemoji" (https://github.com/twitter/twemoji) by "Twitter, Inc", used under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). The derivatives are licensed under the same license. \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/blush.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/blush.png new file mode 100644 index 0000000000..7024942ef0 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/blush.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/broken_heart.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/broken_heart.png new file mode 100644 index 0000000000..f990ce74b2 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/broken_heart.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cat.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cat.png new file mode 100644 index 0000000000..59cdc638de Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cat.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/confused.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/confused.png new file mode 100644 index 0000000000..0d3275a236 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/confused.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cooking.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cooking.png new file mode 100644 index 0000000000..7c853a76db Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cooking.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cowboy.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cowboy.png new file mode 100644 index 0000000000..9c255c613b Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cowboy.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/crab.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/crab.png new file mode 100644 index 0000000000..dceb67eb18 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/crab.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cry.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cry.png new file mode 100644 index 0000000000..dda95de8f9 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cry.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dancer.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dancer.png new file mode 100644 index 0000000000..4a307a4d4d Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dancer.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dog.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dog.png new file mode 100644 index 0000000000..abdb0ecf48 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dog.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/expressionless.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/expressionless.png new file mode 100644 index 0000000000..4d6904de06 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/expressionless.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fish.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fish.png new file mode 100644 index 0000000000..3239750a0d Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fish.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/flushed.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/flushed.png new file mode 100644 index 0000000000..2ca84e2af0 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/flushed.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fork_and_knife.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fork_and_knife.png new file mode 100644 index 0000000000..6f9d56d4f4 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fork_and_knife.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/frowning2.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/frowning2.png new file mode 100644 index 0000000000..bbc46462e1 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/frowning2.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/grinning.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/grinning.png new file mode 100644 index 0000000000..b5ed41cd83 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/grinning.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hearts.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hearts.png new file mode 100644 index 0000000000..4639733791 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hearts.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hugging.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hugging.png new file mode 100644 index 0000000000..146af72906 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hugging.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hushed.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hushed.png new file mode 100644 index 0000000000..d966a3ccbd Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hushed.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/innocent.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/innocent.png new file mode 100644 index 0000000000..01ee7c2f75 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/innocent.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/joy.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/joy.png new file mode 100644 index 0000000000..6bc95ee669 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/joy.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/kissing.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/kissing.png new file mode 100644 index 0000000000..5dc6f2ee44 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/kissing.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/neutral_face.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/neutral_face.png new file mode 100644 index 0000000000..c1f8599802 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/neutral_face.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/ok_hand.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/ok_hand.png new file mode 100644 index 0000000000..677a3f045f Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/ok_hand.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/open_mouth.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/open_mouth.png new file mode 100644 index 0000000000..dc9163b0bb Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/open_mouth.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/party_popper.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/party_popper.png new file mode 100644 index 0000000000..319e3b884b Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/party_popper.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/persevere.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/persevere.png new file mode 100644 index 0000000000..743a6d40c6 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/persevere.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rage.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rage.png new file mode 100644 index 0000000000..67af8f8a85 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rage.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/scream.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/scream.png new file mode 100644 index 0000000000..9ee5a20df4 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/scream.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/see_no_evil.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/see_no_evil.png new file mode 100644 index 0000000000..8c24967ce8 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/see_no_evil.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_frown.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_frown.png new file mode 100644 index 0000000000..4ca50c44d5 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_frown.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_smile.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_smile.png new file mode 100644 index 0000000000..7fe967d033 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_smile.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smile.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smile.png new file mode 100644 index 0000000000..547d0c1af6 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smile.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smiling_imp.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smiling_imp.png new file mode 100644 index 0000000000..988f863b67 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smiling_imp.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sob.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sob.png new file mode 100644 index 0000000000..7b7b607702 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sob.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue.png new file mode 100644 index 0000000000..3e650a63e6 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue_closed_eyes.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue_closed_eyes.png new file mode 100644 index 0000000000..a92049bb60 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue_closed_eyes.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sunglasses.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sunglasses.png new file mode 100644 index 0000000000..27df566883 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sunglasses.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thinking.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thinking.png new file mode 100644 index 0000000000..6be3b18d7f Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thinking.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsdown.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsdown.png new file mode 100644 index 0000000000..674b5dd659 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsdown.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsup.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsup.png new file mode 100644 index 0000000000..e52f8364ff Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsup.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/triumph.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/triumph.png new file mode 100644 index 0000000000..ee5c6b7ced Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/triumph.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/unamused.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/unamused.png new file mode 100644 index 0000000000..342dd80e79 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/unamused.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/wink.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/wink.png new file mode 100644 index 0000000000..def8b2775a Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/wink.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/yum.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/yum.png new file mode 100644 index 0000000000..29d1bf7761 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/yum.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zipper_mouth.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zipper_mouth.png new file mode 100644 index 0000000000..37e137c0c9 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zipper_mouth.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zzz.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zzz.png new file mode 100644 index 0000000000..02fc33fe71 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zzz.png differ