Merge pull request #236 from deathbeam/clan-ranks

Add clan ranks to clan chat
This commit is contained in:
Adam
2017-12-04 19:43:25 -05:00
committed by GitHub
25 changed files with 558 additions and 9 deletions

View 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();
}

View File

@@ -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;
}
}

View File

@@ -130,6 +130,8 @@ public interface Client
int getClanChatCount();
ClanMember[] getClanMembers();
HashTable getComponentTable();
boolean isPrayerActive(Prayer prayer);
@@ -153,4 +155,10 @@ public interface Client
IndexedSprite[] getMapScene();
SpritePixels[] getMapIcons();
IndexedSprite[] getModIcons();
void setModIcons(IndexedSprite[] modIcons);
IndexedSprite createIndexedSprite();
}

View File

@@ -28,15 +28,33 @@ public interface IndexedSprite
{
byte[] getPixels();
void setPixels(byte[] pixels);
int[] getPalette();
void setPalette(int[] palette);
int getOffsetX();
void setOffsetX(int offsetX);
int getOffsetY();
void setOffsetY(int offsetY);
int getWidth();
void setWidth(int width);
int getOriginalWidth();
void setOriginalWidth(int originalWidth);
int getHeight();
void setHeight(int height);
int getOriginalHeight();
void setOriginalHeight(int originalHeight);
}

View File

@@ -28,8 +28,14 @@ public interface MessageNode
{
ChatMessageType getType();
String getName();
void setName(String name);
String getSender();
void setSender(String sender);
String getValue();
void setValue(String value);

View File

@@ -157,6 +157,12 @@ public class Hooks
eventBus.post(varbitChanged);
break;
}
case "clanMembersChanged":
{
ClanMembersChanged clanMembersChanged = new ClanMembersChanged();
eventBus.post(clanMembersChanged);
break;
}
case "resizeChanged":
{
//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)
{
// Hook is fired prior to actually setting these on the MessageNode, so send them
// in the event too.
SetMessage setMessage = new SetMessage();
setMessage.setMessageNode(messageNode);
setMessage.setType(ChatMessageType.of(type));

View File

@@ -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
{
}

View File

@@ -45,9 +45,9 @@ import net.runelite.api.ItemComposition;
import net.runelite.api.MessageNode;
import net.runelite.api.Varbits;
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.ResizeableChanged;
import net.runelite.client.events.SetMessage;
import net.runelite.client.events.VarbitChanged;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.Plugin;

View File

@@ -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;
}
}

View File

@@ -24,13 +24,37 @@
*/
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.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.imageio.ImageIO;
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.GameState;
import net.runelite.api.IndexedSprite;
import net.runelite.api.widgets.Widget;
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.PluginDescriptor;
import net.runelite.client.task.Schedule;
@@ -38,12 +62,43 @@ import net.runelite.client.task.Schedule;
@PluginDescriptor(
name = "Clan chat plugin"
)
@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 final Map<String, ClanMemberRank> clanRanksCache = new HashMap<>();
private int modIconsLength;
@Inject
@Nullable
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(
period = 600,
unit = ChronoUnit.MILLIS
@@ -61,4 +116,168 @@ public class ClanChatPlugin extends Plugin
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', ' ');
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

View File

@@ -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());
}
}

View File

@@ -27,6 +27,7 @@ package net.runelite.mixins;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.GameState;
import net.runelite.api.IndexedSprite;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.NPC;
@@ -35,11 +36,12 @@ import net.runelite.api.Point;
import net.runelite.api.Prayer;
import net.runelite.api.Skill;
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.Mixin;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSIndexedSprite;
import net.runelite.rs.api.RSWidget;
@Mixin(RSClient.class)
@@ -314,4 +316,11 @@ public abstract class RSClientMixin implements RSClient
setMenuOptionCount(count);
}
@Inject
@Override
public void setModIcons(IndexedSprite[] modIcons)
{
setRSModIcons((RSIndexedSprite[]) modIcons);
}
}

View File

@@ -37,4 +37,6 @@ import java.lang.annotation.Target;
public @interface Hook
{
String value();
boolean end() default false;
}

View File

@@ -24,16 +24,17 @@
*/
package net.runelite.rs.api;
import net.runelite.api.ClanMember;
import net.runelite.mapping.Import;
public interface RSClanMember
public interface RSClanMember extends ClanMember
{
@Import("username")
String getUsernameName();
String getUsername();
@Import("world")
int getWorld();
@Import("rank")
byte getRank();
byte getRSRank();
}

View File

@@ -26,6 +26,7 @@ package net.runelite.rs.api;
import java.util.Map;
import net.runelite.api.Client;
import net.runelite.mapping.Construct;
import net.runelite.mapping.Import;
public interface RSClient extends RSGameEngine, Client
@@ -320,4 +321,15 @@ public interface RSClient extends RSGameEngine, Client
@Import("mapIcons")
@Override
RSSpritePixels[] getMapIcons();
@Import("modIcons")
@Override
RSIndexedSprite[] getModIcons();
@Import("modIcons")
void setRSModIcons(RSIndexedSprite[] modIcons);
@Construct
@Override
RSIndexedSprite createIndexedSprite();
}

View File

@@ -33,27 +33,63 @@ public interface RSIndexedSprite extends IndexedSprite
@Override
byte[] getPixels();
@Import("pixels")
@Override
void setPixels(byte[] pixels);
@Import("palette")
@Override
int[] getPalette();
@Import("palette")
@Override
void setPalette(int[] palette);
@Import("originalWidth")
@Override
int getOriginalWidth();
@Import("originalWidth")
@Override
void setOriginalWidth(int originalWidth);
@Import("originalHeight")
@Override
int getOriginalHeight();
@Import("originalHeight")
@Override
void setOriginalHeight(int originalHeight);
@Import("height")
@Override
int getHeight();
@Import("height")
@Override
void setHeight(int height);
@Import("offsetX")
@Override
int getOffsetX();
@Import("offsetX")
@Override
void setOffsetX(int offsetX);
@Import("offsetY")
@Override
int getOffsetY();
@Import("offsetY")
@Override
void setOffsetY(int offsetY);
@Import("width")
@Override
int getWidth();
@Import("width")
@Override
void setWidth(int width);
}

View File

@@ -32,10 +32,22 @@ public interface RSMessageNode extends MessageNode
@Import("type")
int getRSType();
@Import("name")
@Override
String getName();
@Import("name")
@Override
void setName(String name);
@Import("sender")
@Override
String getSender();
@Import("sender")
@Override
void setSender(String sender);
@Import("value")
@Override
String getValue();