Merge pull request #236 from deathbeam/clan-ranks
Add clan ranks to clan chat
34
runelite-api/src/main/java/net/runelite/api/ClanMember.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* 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.api;
|
||||||
|
|
||||||
|
public interface ClanMember
|
||||||
|
{
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
int getWorld();
|
||||||
|
|
||||||
|
ClanMemberRank getRank();
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* 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.api;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum ClanMemberRank
|
||||||
|
{
|
||||||
|
UNRANKED((byte) -1),
|
||||||
|
FRIEND((byte) 0),
|
||||||
|
RECRUIT((byte) 1),
|
||||||
|
CORPORAL((byte) 2),
|
||||||
|
SERGEANT((byte) 3),
|
||||||
|
LIEUTENANT((byte) 4),
|
||||||
|
CAPTAIN((byte) 5),
|
||||||
|
GENERAL((byte) 6),
|
||||||
|
OWNER((byte) 7);
|
||||||
|
|
||||||
|
private static final Map<Byte, ClanMemberRank> BYTE_TO_RANK = new HashMap<>();
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for (final ClanMemberRank clanMemberRank : ClanMemberRank.values())
|
||||||
|
{
|
||||||
|
BYTE_TO_RANK.put(clanMemberRank.value, clanMemberRank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClanMemberRank valueOf(byte rank)
|
||||||
|
{
|
||||||
|
return BYTE_TO_RANK.get(rank);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final byte value;
|
||||||
|
|
||||||
|
ClanMemberRank(final byte value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getValue()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -130,6 +130,8 @@ public interface Client
|
|||||||
|
|
||||||
int getClanChatCount();
|
int getClanChatCount();
|
||||||
|
|
||||||
|
ClanMember[] getClanMembers();
|
||||||
|
|
||||||
HashTable getComponentTable();
|
HashTable getComponentTable();
|
||||||
|
|
||||||
boolean isPrayerActive(Prayer prayer);
|
boolean isPrayerActive(Prayer prayer);
|
||||||
@@ -153,4 +155,10 @@ public interface Client
|
|||||||
IndexedSprite[] getMapScene();
|
IndexedSprite[] getMapScene();
|
||||||
|
|
||||||
SpritePixels[] getMapIcons();
|
SpritePixels[] getMapIcons();
|
||||||
|
|
||||||
|
IndexedSprite[] getModIcons();
|
||||||
|
|
||||||
|
void setModIcons(IndexedSprite[] modIcons);
|
||||||
|
|
||||||
|
IndexedSprite createIndexedSprite();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,33 @@ public interface IndexedSprite
|
|||||||
{
|
{
|
||||||
byte[] getPixels();
|
byte[] getPixels();
|
||||||
|
|
||||||
|
void setPixels(byte[] pixels);
|
||||||
|
|
||||||
int[] getPalette();
|
int[] getPalette();
|
||||||
|
|
||||||
|
void setPalette(int[] palette);
|
||||||
|
|
||||||
int getOffsetX();
|
int getOffsetX();
|
||||||
|
|
||||||
|
void setOffsetX(int offsetX);
|
||||||
|
|
||||||
int getOffsetY();
|
int getOffsetY();
|
||||||
|
|
||||||
|
void setOffsetY(int offsetY);
|
||||||
|
|
||||||
int getWidth();
|
int getWidth();
|
||||||
|
|
||||||
|
void setWidth(int width);
|
||||||
|
|
||||||
int getOriginalWidth();
|
int getOriginalWidth();
|
||||||
|
|
||||||
|
void setOriginalWidth(int originalWidth);
|
||||||
|
|
||||||
int getHeight();
|
int getHeight();
|
||||||
|
|
||||||
|
void setHeight(int height);
|
||||||
|
|
||||||
|
int getOriginalHeight();
|
||||||
|
|
||||||
|
void setOriginalHeight(int originalHeight);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,14 @@ public interface MessageNode
|
|||||||
{
|
{
|
||||||
ChatMessageType getType();
|
ChatMessageType getType();
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
void setName(String name);
|
||||||
|
|
||||||
String getSender();
|
String getSender();
|
||||||
|
|
||||||
|
void setSender(String sender);
|
||||||
|
|
||||||
String getValue();
|
String getValue();
|
||||||
|
|
||||||
void setValue(String value);
|
void setValue(String value);
|
||||||
|
|||||||
@@ -157,6 +157,12 @@ public class Hooks
|
|||||||
eventBus.post(varbitChanged);
|
eventBus.post(varbitChanged);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "clanMembersChanged":
|
||||||
|
{
|
||||||
|
ClanMembersChanged clanMembersChanged = new ClanMembersChanged();
|
||||||
|
eventBus.post(clanMembersChanged);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "resizeChanged":
|
case "resizeChanged":
|
||||||
{
|
{
|
||||||
//maybe couple with varbitChanged. resizeable may not be a varbit but it would fit with the other client settings.
|
//maybe couple with varbitChanged. resizeable may not be a varbit but it would fit with the other client settings.
|
||||||
@@ -256,8 +262,6 @@ public class Hooks
|
|||||||
|
|
||||||
public static void setMessage(MessageNode messageNode, int type, String name, String sender, String value)
|
public static void setMessage(MessageNode messageNode, int type, String name, String sender, String value)
|
||||||
{
|
{
|
||||||
// Hook is fired prior to actually setting these on the MessageNode, so send them
|
|
||||||
// in the event too.
|
|
||||||
SetMessage setMessage = new SetMessage();
|
SetMessage setMessage = new SetMessage();
|
||||||
setMessage.setMessageNode(messageNode);
|
setMessage.setMessageNode(messageNode);
|
||||||
setMessage.setType(ChatMessageType.of(type));
|
setMessage.setType(ChatMessageType.of(type));
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* 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.events;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ClanMembersChanged
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -45,9 +45,9 @@ import net.runelite.api.ItemComposition;
|
|||||||
import net.runelite.api.MessageNode;
|
import net.runelite.api.MessageNode;
|
||||||
import net.runelite.api.Varbits;
|
import net.runelite.api.Varbits;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.events.SetMessage;
|
|
||||||
import net.runelite.client.events.ResizeableChanged;
|
|
||||||
import net.runelite.client.events.ConfigChanged;
|
import net.runelite.client.events.ConfigChanged;
|
||||||
|
import net.runelite.client.events.ResizeableChanged;
|
||||||
|
import net.runelite.client.events.SetMessage;
|
||||||
import net.runelite.client.events.VarbitChanged;
|
import net.runelite.client.events.VarbitChanged;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* 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.clanchat;
|
||||||
|
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
|
||||||
|
@ConfigGroup(
|
||||||
|
keyName = "clanchat",
|
||||||
|
name = "Clan Chat",
|
||||||
|
description = "Configuration for clan chat"
|
||||||
|
)
|
||||||
|
public interface ClanChatConfig extends Config
|
||||||
|
{
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "clanRank",
|
||||||
|
name = "Show Clan Ranks Icon",
|
||||||
|
description = "Configures whether the clan ranks icons are shown next to name in chat"
|
||||||
|
)
|
||||||
|
default boolean clanRank()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,13 +24,37 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.clanchat;
|
package net.runelite.client.plugins.clanchat;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
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.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.ChatMessageType;
|
||||||
|
import net.runelite.api.ClanMember;
|
||||||
|
import net.runelite.api.ClanMemberRank;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.IndexedSprite;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.events.ClanMembersChanged;
|
||||||
|
import net.runelite.client.events.GameStateChanged;
|
||||||
|
import net.runelite.client.events.SetMessage;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.task.Schedule;
|
import net.runelite.client.task.Schedule;
|
||||||
@@ -38,12 +62,43 @@ import net.runelite.client.task.Schedule;
|
|||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Clan chat plugin"
|
name = "Clan chat plugin"
|
||||||
)
|
)
|
||||||
|
@Slf4j
|
||||||
public class ClanChatPlugin extends Plugin
|
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 final Map<String, ClanMemberRank> clanRanksCache = new HashMap<>();
|
||||||
|
private int modIconsLength;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Nullable
|
@Nullable
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ClanChatConfig config;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
ClanChatConfig provideConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(ClanChatConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||||
|
{
|
||||||
|
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN)
|
||||||
|
{
|
||||||
|
// this is after "Loading sprites" so we can modify modicons now
|
||||||
|
loadClanChatIcons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Schedule(
|
@Schedule(
|
||||||
period = 600,
|
period = 600,
|
||||||
unit = ChronoUnit.MILLIS
|
unit = ChronoUnit.MILLIS
|
||||||
@@ -61,4 +116,168 @@ public class ClanChatPlugin extends Plugin
|
|||||||
clanChatTitleWidget.setText("Clan Chat (" + client.getClanChatCount() + "/100)");
|
clanChatTitleWidget.setText("Clan Chat (" + client.getClanChatCount() + "/100)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schedule(
|
||||||
|
period = 2,
|
||||||
|
unit = ChronoUnit.MINUTES
|
||||||
|
)
|
||||||
|
public void cacheClanMemberRanks()
|
||||||
|
{
|
||||||
|
if (client.getGameState() != GameState.LOGGED_IN || !config.clanRank())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clanRanksCache.clear();
|
||||||
|
|
||||||
|
final ClanMember[] clanMembersArr = client.getClanMembers();
|
||||||
|
|
||||||
|
if (clanMembersArr == null || clanMembersArr.length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Set<ClanMember> clanMembers = Arrays.stream(clanMembersArr)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
final int clanMembersSize = clanMembers.size();
|
||||||
|
|
||||||
|
if (clanMembersSize == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Caching clan members...");
|
||||||
|
|
||||||
|
for (ClanMember clanMember : clanMembers)
|
||||||
|
{
|
||||||
|
final String name = sanitize(clanMember.getUsername());
|
||||||
|
final ClanMemberRank rank = clanMember.getRank();
|
||||||
|
|
||||||
|
if (rank != null)
|
||||||
|
{
|
||||||
|
clanRanksCache.put(name, rank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onClanMembersChanged(ClanMembersChanged event)
|
||||||
|
{
|
||||||
|
cacheClanMemberRanks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onSetMessage(SetMessage setMessage)
|
||||||
|
{
|
||||||
|
if (client.getGameState() != GameState.LOGGED_IN)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.clanRank() && setMessage.getType() == ChatMessageType.CLANCHAT)
|
||||||
|
{
|
||||||
|
insertClanRankIcon(setMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
modIconsLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
final String playerName = sanitize(message.getName());
|
||||||
|
final ClanMemberRank rank = clanRanksCache.get(playerName);
|
||||||
|
|
||||||
|
if (rank != null && rank != ClanMemberRank.UNRANKED)
|
||||||
|
{
|
||||||
|
int iconNumber = getIconNumber(rank);
|
||||||
|
message.getMessageNode()
|
||||||
|
.setSender(message.getMessageNode().getSender() + " <img=" + iconNumber + ">");
|
||||||
|
client.refreshChat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getIconNumber(final ClanMemberRank clanMemberRank)
|
||||||
|
{
|
||||||
|
return modIconsLength - CLANCHAT_IMAGES.length + clanMemberRank.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sanitize(String lookup)
|
||||||
|
{
|
||||||
|
final String cleaned = lookup.contains("<img") ? lookup.substring(lookup.lastIndexOf('>') + 1) : lookup;
|
||||||
|
return cleaned.replace('\u00A0', ' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 186 B |
|
After Width: | Height: | Size: 100 B |
|
After Width: | Height: | Size: 186 B |
|
After Width: | Height: | Size: 191 B |
|
After Width: | Height: | Size: 176 B |
|
After Width: | Height: | Size: 124 B |
|
After Width: | Height: | Size: 90 B |
|
After Width: | Height: | Size: 115 B |
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* 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.mixins;
|
||||||
|
|
||||||
|
import net.runelite.api.ClanMemberRank;
|
||||||
|
import net.runelite.api.mixins.Inject;
|
||||||
|
import net.runelite.api.mixins.Mixin;
|
||||||
|
import net.runelite.rs.api.RSClanMember;
|
||||||
|
|
||||||
|
@Mixin(RSClanMember.class)
|
||||||
|
public abstract class RSClanMemberMixin implements RSClanMember
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
@Inject
|
||||||
|
public ClanMemberRank getRank()
|
||||||
|
{
|
||||||
|
return ClanMemberRank.valueOf(getRSRank());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ package net.runelite.mixins;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.IndexedSprite;
|
||||||
import net.runelite.api.MenuAction;
|
import net.runelite.api.MenuAction;
|
||||||
import net.runelite.api.MenuEntry;
|
import net.runelite.api.MenuEntry;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
@@ -35,11 +36,12 @@ import net.runelite.api.Point;
|
|||||||
import net.runelite.api.Prayer;
|
import net.runelite.api.Prayer;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
import net.runelite.api.Varbits;
|
import net.runelite.api.Varbits;
|
||||||
import net.runelite.api.widgets.Widget;
|
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
|
||||||
import net.runelite.api.mixins.Inject;
|
import net.runelite.api.mixins.Inject;
|
||||||
import net.runelite.api.mixins.Mixin;
|
import net.runelite.api.mixins.Mixin;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import net.runelite.rs.api.RSClient;
|
import net.runelite.rs.api.RSClient;
|
||||||
|
import net.runelite.rs.api.RSIndexedSprite;
|
||||||
import net.runelite.rs.api.RSWidget;
|
import net.runelite.rs.api.RSWidget;
|
||||||
|
|
||||||
@Mixin(RSClient.class)
|
@Mixin(RSClient.class)
|
||||||
@@ -314,4 +316,11 @@ public abstract class RSClientMixin implements RSClient
|
|||||||
|
|
||||||
setMenuOptionCount(count);
|
setMenuOptionCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setModIcons(IndexedSprite[] modIcons)
|
||||||
|
{
|
||||||
|
setRSModIcons((RSIndexedSprite[]) modIcons);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,6 @@ import java.lang.annotation.Target;
|
|||||||
public @interface Hook
|
public @interface Hook
|
||||||
{
|
{
|
||||||
String value();
|
String value();
|
||||||
|
|
||||||
|
boolean end() default false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,16 +24,17 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.rs.api;
|
package net.runelite.rs.api;
|
||||||
|
|
||||||
|
import net.runelite.api.ClanMember;
|
||||||
import net.runelite.mapping.Import;
|
import net.runelite.mapping.Import;
|
||||||
|
|
||||||
public interface RSClanMember
|
public interface RSClanMember extends ClanMember
|
||||||
{
|
{
|
||||||
@Import("username")
|
@Import("username")
|
||||||
String getUsernameName();
|
String getUsername();
|
||||||
|
|
||||||
@Import("world")
|
@Import("world")
|
||||||
int getWorld();
|
int getWorld();
|
||||||
|
|
||||||
@Import("rank")
|
@Import("rank")
|
||||||
byte getRank();
|
byte getRSRank();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ package net.runelite.rs.api;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.mapping.Construct;
|
||||||
import net.runelite.mapping.Import;
|
import net.runelite.mapping.Import;
|
||||||
|
|
||||||
public interface RSClient extends RSGameEngine, Client
|
public interface RSClient extends RSGameEngine, Client
|
||||||
@@ -320,4 +321,15 @@ public interface RSClient extends RSGameEngine, Client
|
|||||||
@Import("mapIcons")
|
@Import("mapIcons")
|
||||||
@Override
|
@Override
|
||||||
RSSpritePixels[] getMapIcons();
|
RSSpritePixels[] getMapIcons();
|
||||||
|
|
||||||
|
@Import("modIcons")
|
||||||
|
@Override
|
||||||
|
RSIndexedSprite[] getModIcons();
|
||||||
|
|
||||||
|
@Import("modIcons")
|
||||||
|
void setRSModIcons(RSIndexedSprite[] modIcons);
|
||||||
|
|
||||||
|
@Construct
|
||||||
|
@Override
|
||||||
|
RSIndexedSprite createIndexedSprite();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,27 +33,63 @@ public interface RSIndexedSprite extends IndexedSprite
|
|||||||
@Override
|
@Override
|
||||||
byte[] getPixels();
|
byte[] getPixels();
|
||||||
|
|
||||||
|
@Import("pixels")
|
||||||
|
@Override
|
||||||
|
void setPixels(byte[] pixels);
|
||||||
|
|
||||||
@Import("palette")
|
@Import("palette")
|
||||||
@Override
|
@Override
|
||||||
int[] getPalette();
|
int[] getPalette();
|
||||||
|
|
||||||
|
@Import("palette")
|
||||||
|
@Override
|
||||||
|
void setPalette(int[] palette);
|
||||||
|
|
||||||
@Import("originalWidth")
|
@Import("originalWidth")
|
||||||
@Override
|
@Override
|
||||||
int getOriginalWidth();
|
int getOriginalWidth();
|
||||||
|
|
||||||
|
@Import("originalWidth")
|
||||||
|
@Override
|
||||||
|
void setOriginalWidth(int originalWidth);
|
||||||
|
|
||||||
|
@Import("originalHeight")
|
||||||
|
@Override
|
||||||
|
int getOriginalHeight();
|
||||||
|
|
||||||
|
@Import("originalHeight")
|
||||||
|
@Override
|
||||||
|
void setOriginalHeight(int originalHeight);
|
||||||
|
|
||||||
@Import("height")
|
@Import("height")
|
||||||
@Override
|
@Override
|
||||||
int getHeight();
|
int getHeight();
|
||||||
|
|
||||||
|
@Import("height")
|
||||||
|
@Override
|
||||||
|
void setHeight(int height);
|
||||||
|
|
||||||
@Import("offsetX")
|
@Import("offsetX")
|
||||||
@Override
|
@Override
|
||||||
int getOffsetX();
|
int getOffsetX();
|
||||||
|
|
||||||
|
@Import("offsetX")
|
||||||
|
@Override
|
||||||
|
void setOffsetX(int offsetX);
|
||||||
|
|
||||||
@Import("offsetY")
|
@Import("offsetY")
|
||||||
@Override
|
@Override
|
||||||
int getOffsetY();
|
int getOffsetY();
|
||||||
|
|
||||||
|
@Import("offsetY")
|
||||||
|
@Override
|
||||||
|
void setOffsetY(int offsetY);
|
||||||
|
|
||||||
@Import("width")
|
@Import("width")
|
||||||
@Override
|
@Override
|
||||||
int getWidth();
|
int getWidth();
|
||||||
|
|
||||||
|
@Import("width")
|
||||||
|
@Override
|
||||||
|
void setWidth(int width);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,10 +32,22 @@ public interface RSMessageNode extends MessageNode
|
|||||||
@Import("type")
|
@Import("type")
|
||||||
int getRSType();
|
int getRSType();
|
||||||
|
|
||||||
|
@Import("name")
|
||||||
|
@Override
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
@Import("name")
|
||||||
|
@Override
|
||||||
|
void setName(String name);
|
||||||
|
|
||||||
@Import("sender")
|
@Import("sender")
|
||||||
@Override
|
@Override
|
||||||
String getSender();
|
String getSender();
|
||||||
|
|
||||||
|
@Import("sender")
|
||||||
|
@Override
|
||||||
|
void setSender(String sender);
|
||||||
|
|
||||||
@Import("value")
|
@Import("value")
|
||||||
@Override
|
@Override
|
||||||
String getValue();
|
String getValue();
|
||||||
|
|||||||