friendicons: add note icon in friends/ignore list

Co-authored-by: Adam <Adam@sigterm.info>
This commit is contained in:
ThatGamerBlue
2020-03-13 17:50:54 +00:00
committed by Adam
parent 51f562b547
commit 7b4e8c2848
8 changed files with 304 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020, ThatGamerBlue <https://github.com/ThatGamerBlue>
* 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 HOLDER 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.friendnotes;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup(FriendNotesPlugin.CONFIG_GROUP)
public interface FriendNotesConfig extends Config
{
@ConfigItem(
keyName = "showIcons",
name = "Show Icons",
description = "Show icons on friend or ignore list",
position = 1
)
default boolean showIcons()
{
return true;
}
}

View File

@@ -29,29 +29,40 @@ package net.runelite.client.plugins.friendnotes;
import com.google.common.base.Strings;
import com.google.common.collect.ObjectArrays;
import com.google.inject.Provides;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.annotation.Nullable;
import javax.inject.Inject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Friend;
import net.runelite.api.GameState;
import net.runelite.api.Ignore;
import net.runelite.api.IndexedSprite;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.Nameable;
import net.runelite.api.ScriptID;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.NameableNameChanged;
import net.runelite.api.events.RemovedFriend;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text;
@Slf4j
@@ -61,13 +72,15 @@ import net.runelite.client.util.Text;
)
public class FriendNotesPlugin extends Plugin
{
private static final String CONFIG_GROUP = "friendNotes";
static final String CONFIG_GROUP = "friendNotes";
private static final int CHARACTER_LIMIT = 128;
private static final String KEY_PREFIX = "note_";
private static final String ADD_NOTE = "Add Note";
private static final String EDIT_NOTE = "Edit Note";
private static final String NOTE_PROMPT_FORMAT = "%s's Notes<br>" +
ColorUtil.prependColorTag("(Limit %s Characters)", new Color(0, 0, 170));
private static final int ICON_WIDTH = 14;
private static final int ICON_HEIGHT = 12;
@Inject
private Client client;
@@ -84,19 +97,74 @@ public class FriendNotesPlugin extends Plugin
@Inject
private ChatboxPanelManager chatboxPanelManager;
@Inject
private ClientThread clientThread;
@Inject
private FriendNotesConfig config;
@Getter
private HoveredFriend hoveredFriend = null;
private int iconIdx = -1;
private String currentlyLayouting;
@Provides
private FriendNotesConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(FriendNotesConfig.class);
}
@Override
protected void startUp() throws Exception
{
overlayManager.add(overlay);
clientThread.invoke(this::loadIcon);
if (client.getGameState() == GameState.LOGGED_IN)
{
rebuildFriendsList();
rebuildIgnoreList();
}
}
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(overlay);
if (client.getGameState() == GameState.LOGGED_IN)
{
rebuildFriendsList();
rebuildIgnoreList();
}
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
if (event.getGameState() == GameState.LOGGED_IN)
{
loadIcon();
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals(CONFIG_GROUP))
{
return;
}
switch (event.getKey())
{
case "showIcons":
if (client.getGameState() == GameState.LOGGED_IN)
{
rebuildFriendsList();
rebuildIgnoreList();
}
break;
}
}
/**
@@ -112,6 +180,11 @@ public class FriendNotesPlugin extends Plugin
{
configManager.setConfiguration(CONFIG_GROUP, KEY_PREFIX + displayName, note);
}
if (client.getGameState() == GameState.LOGGED_IN)
{
rebuildFriendsList();
rebuildIgnoreList();
}
}
/**
@@ -258,4 +331,104 @@ public class FriendNotesPlugin extends Plugin
log.debug("Remove friend: '{}'", displayName);
setFriendNote(displayName, null);
}
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent event)
{
if (!config.showIcons() || iconIdx == -1)
{
return;
}
switch (event.getEventName())
{
case "friend_cc_settext":
case "ignore_cc_settext":
String[] stringStack = client.getStringStack();
int stringStackSize = client.getStringStackSize();
final String rsn = stringStack[stringStackSize - 1];
final String sanitized = Text.toJagexName(Text.removeTags(rsn));
currentlyLayouting = sanitized;
if (getFriendNote(sanitized) != null)
{
stringStack[stringStackSize - 1] = rsn + " <img=" + iconIdx + ">";
}
break;
case "friend_cc_setposition":
case "ignore_cc_setposition":
if (currentlyLayouting == null || getFriendNote(currentlyLayouting) == null)
{
return;
}
int[] intStack = client.getIntStack();
int intStackSize = client.getIntStackSize();
int xpos = intStack[intStackSize - 4];
xpos += ICON_WIDTH + 1;
intStack[intStackSize - 4] = xpos;
break;
}
}
private void rebuildFriendsList()
{
clientThread.invokeLater(() ->
{
log.debug("Rebuilding friends list");
client.runScript(
ScriptID.FRIENDS_UPDATE,
WidgetInfo.FRIEND_LIST_FULL_CONTAINER.getPackedId(),
WidgetInfo.FRIEND_LIST_SORT_BY_NAME_BUTTON.getPackedId(),
WidgetInfo.FRIEND_LIST_SORT_BY_LAST_WORLD_CHANGE_BUTTON.getPackedId(),
WidgetInfo.FRIEND_LIST_SORT_BY_WORLD_BUTTON.getPackedId(),
WidgetInfo.FRIEND_LIST_LEGACY_SORT_BUTTON.getPackedId(),
WidgetInfo.FRIEND_LIST_NAMES_CONTAINER.getPackedId(),
WidgetInfo.FRIEND_LIST_SCROLL_BAR.getPackedId(),
WidgetInfo.FRIEND_LIST_LOADING_TEXT.getPackedId(),
WidgetInfo.FRIEND_LIST_PREVIOUS_NAME_HOLDER.getPackedId()
);
});
}
private void rebuildIgnoreList()
{
clientThread.invokeLater(() ->
{
log.debug("Rebuilding ignore list");
client.runScript(
ScriptID.IGNORE_UPDATE,
WidgetInfo.IGNORE_FULL_CONTAINER.getPackedId(),
WidgetInfo.IGNORE_SORT_BY_NAME_BUTTON.getPackedId(),
WidgetInfo.IGNORE_LEGACY_SORT_BUTTON.getPackedId(),
WidgetInfo.IGNORE_NAMES_CONTAINER.getPackedId(),
WidgetInfo.IGNORE_SCROLL_BAR.getPackedId(),
WidgetInfo.IGNORE_LOADING_TEXT.getPackedId(),
WidgetInfo.IGNORE_PREVIOUS_NAME_HOLDER.getPackedId()
);
});
}
private void loadIcon()
{
final IndexedSprite[] modIcons = client.getModIcons();
if (iconIdx != -1 || modIcons == null)
{
return;
}
final BufferedImage iconImg = ImageUtil.getResourceStreamFromClass(getClass(), "note_icon.png");
if (iconImg == null)
{
return;
}
final BufferedImage resized = ImageUtil.resizeImage(iconImg, ICON_WIDTH, ICON_HEIGHT);
final IndexedSprite[] newIcons = Arrays.copyOf(modIcons, modIcons.length + 1);
newIcons[newIcons.length - 1] = ImageUtil.getImageIndexedSprite(resized, client);
iconIdx = newIcons.length - 1;
client.setModIcons(newIcons);
}
}