Merge pull request #241 from deathbeam/examine-item-price

Show item price when examining item
This commit is contained in:
Adam
2017-12-07 21:30:22 -05:00
committed by GitHub
18 changed files with 642 additions and 285 deletions

View File

@@ -42,6 +42,7 @@ public enum ChatMessageType
FRIENDS_LIST_ADD(30),
IGNORE_LIST_ADD(31),
AUTOCHAT(90),
GAME(99),
TRADE(101),
DUEL(103),
FILTERED(105),
@@ -66,4 +67,9 @@ public enum ChatMessageType
}
return UNKNOWN;
}
public int getType()
{
return type;
}
}

View File

@@ -40,7 +40,7 @@ public interface Client
int getRealSkillLevel(Skill skill);
void sendGameMessage(String message);
void sendGameMessage(ChatMessageType type, String message);
GameState getGameState();

View File

@@ -58,6 +58,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Query;
import net.runelite.client.account.AccountSession;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.SessionClose;
import net.runelite.client.events.SessionOpen;
@@ -101,6 +102,9 @@ public class RuneLite
@Inject
private ConfigManager configManager;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private ScheduledExecutorService executor;
@@ -166,6 +170,7 @@ public class RuneLite
configManager.load();
eventBus.register(menuManager);
eventBus.register(chatMessageManager);
// Setup the notifier
notifier = new Notifier(trayIcon);

View File

@@ -33,6 +33,7 @@ import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneliteConfig;
import net.runelite.client.game.ItemManager;
@@ -50,6 +51,7 @@ public class RuneliteModule extends AbstractModule
{
bind(ScheduledExecutorService.class).toInstance(Executors.newSingleThreadScheduledExecutor());
bind(MenuManager.class);
bind(ChatMessageManager.class);
bind(ItemManager.class);
bind(InfoBoxManager.class);
bind(Scheduler.class);

View File

@@ -1,6 +1,5 @@
/*
* Copyright (c) 2017. l2-
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* Copyright (c) 2017, Tomas Slusny <slusnucky@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,23 +22,19 @@
* (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.chatcommands;
package net.runelite.client.chat;
import java.awt.Color;
import net.runelite.api.ChatMessageType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
class ChatColor
@Data
@AllArgsConstructor
@EqualsAndHashCode(exclude = "color")
public class ChatColor
{
Color color;
ChatMessageType type;
boolean transparent;
boolean highlight;
ChatColor(Color color, ChatMessageType type, boolean transparent, boolean highlight)
{
this.color = color;
this.type = type;
this.transparent = transparent;
this.highlight = highlight;
}
private ChatColorType type;
private Color color;
private boolean transparent;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2017, Tomas Slusny <slusnucky@gmail.com>
* 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.chat;
public enum ChatColorType
{
NORMAL,
HIGHLIGHT
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, Tomas Slusny <slusnucky@gmail.com>
* 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.chat;
public class ChatMessageBuilder
{
private final StringBuilder builder = new StringBuilder();
public ChatMessageBuilder append(final ChatColorType type)
{
builder.append("<col").append(type.name()).append(">");
return this;
}
public ChatMessageBuilder append(final String message)
{
builder.append(message);
return this;
}
public String build()
{
return builder.toString();
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (c) 2017, Tomas Slusny <slusnucky@gmail.com>
* 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.chat;
import com.google.common.eventbus.Subscribe;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatLineBuffer;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.Varbits;
import net.runelite.client.config.RuneliteConfig;
import net.runelite.client.events.ResizeableChanged;
import net.runelite.client.events.VarbitChanged;
@Slf4j
@Singleton
public class ChatMessageManager
{
private final Map<ChatMessageType, Set<ChatColor>> colorCache = new HashMap<>();
private final Provider<Client> clientProvider;
private final ScheduledExecutorService executor;
private final RuneliteConfig config;
private int transparancyVarbit = -1;
@Inject
public ChatMessageManager(Provider<Client> clientProvider, ScheduledExecutorService executor, RuneliteConfig config)
{
this.clientProvider = clientProvider;
this.executor = executor;
this.config = config;
}
@Subscribe
public void onVarbitChanged(VarbitChanged event)
{
int setting = clientProvider.get().getSetting(Varbits.TRANSPARANT_CHATBOX);
if (transparancyVarbit != setting)
{
transparancyVarbit = setting;
refreshAll();
}
}
@Subscribe
public void onResizableChanged(ResizeableChanged event)
{
refreshAll();
}
public ChatMessageManager cacheColor(final ChatColor chatColor, final ChatMessageType... types)
{
for (ChatMessageType chatMessageType : types)
{
colorCache.putIfAbsent(chatMessageType, new HashSet<>());
final Set<ChatColor> chatColors = colorCache.get(chatMessageType);
chatColors.remove(chatColor);
chatColors.add(chatColor);
}
return this;
}
public void add(final ChatMessageType type, final String mesage)
{
final Client client = clientProvider.get();
client.sendGameMessage(type, mesage);
final ChatLineBuffer chatLineBuffer = client.getChatLineMap().get(type.getType());
final MessageNode[] lines = chatLineBuffer.getLines();
final MessageNode line = lines[0];
update(line.getType(), mesage, line);
}
public void update(final ChatMessageType type, final String message, final MessageNode target)
{
final Client client = clientProvider.get();
final Set<ChatColor> chatColors = colorCache.get(type);
// If we do not have any colors cached or recoloring is disabled, simply set message
if (!config.chatCommandsRecolorEnabled() || chatColors == null || chatColors.isEmpty())
{
target.setRuneLiteFormatMessage(message);
target.setValue(message);
return;
}
final AtomicReference<String> resultMessage = new AtomicReference<>(message);
// Replace custom formatting with actual colors
chatColors.stream()
.filter(chatColor -> chatColor.isTransparent() ==
(client.isResized() && client.getSetting(Varbits.TRANSPARANT_CHATBOX) != 0))
.forEach(chatColor ->
resultMessage.getAndUpdate(oldMessage -> oldMessage.replaceAll(
"<col" + chatColor.getType().name() + ">",
"<col=" + Integer.toHexString(chatColor.getColor().getRGB() & 0xFFFFFF) + ">")));
target.setRuneLiteFormatMessage(message);
target.setValue(resultMessage.get());
}
public void refreshAll()
{
if (!config.chatCommandsRecolorEnabled())
{
return;
}
final Client client = clientProvider.get();
executor.submit(() ->
{
final Set<MessageNode> chatLines = client.getChatLineMap().values().stream()
.filter(Objects::nonNull)
.flatMap(clb -> Arrays.stream(clb.getLines()))
.filter(Objects::nonNull)
.filter(mn -> mn.getRuneLiteFormatMessage() != null)
.collect(Collectors.toSet());
chatLines.forEach(chatLine -> update(chatLine.getType(), chatLine.getRuneLiteFormatMessage(), chatLine));
if (!chatLines.isEmpty())
{
client.refreshChat();
}
});
}
}

View File

@@ -41,6 +41,16 @@ public interface RuneliteConfig extends Config
return false;
}
@ConfigItem(
keyName = "chatCommandsRecolorEnabled",
name = "Enable chat commands recolor",
description = "Determines if recoloring of custom RuneLite chat commands is enabled"
)
default boolean chatCommandsRecolorEnabled()
{
return true;
}
@ConfigItem(
keyName = "enablePlugins",
name = "Enable loading of external plugins",

View File

@@ -36,9 +36,11 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.api.ItemComposition;
import net.runelite.api.SpritePixels;
import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.SearchResult;
@Singleton
public class ItemManager
@@ -55,8 +57,10 @@ public class ItemManager
private final Client client;
private final ItemClient itemClient = new ItemClient();
private final LoadingCache<String, SearchResult> itemSearches;
private final LoadingCache<Integer, ItemPrice> itemPrices;
private final LoadingCache<Integer, BufferedImage> itemImages;
private final LoadingCache<Integer, ItemComposition> itemCompositions;
@Inject
public ItemManager(@Nullable Client client, ScheduledExecutorService executor)
@@ -67,6 +71,18 @@ public class ItemManager
.expireAfterAccess(1, TimeUnit.HOURS)
.build(new ItemPriceLoader(executor, itemClient));
itemSearches = CacheBuilder.newBuilder()
.maximumSize(512L)
.expireAfterAccess(1, TimeUnit.HOURS)
.build(new CacheLoader<String, SearchResult>()
{
@Override
public SearchResult load(String key) throws Exception
{
return itemClient.search(key);
}
});
itemImages = CacheBuilder.newBuilder()
.maximumSize(200)
.expireAfterAccess(1, TimeUnit.HOURS)
@@ -78,15 +94,27 @@ public class ItemManager
return loadImage(itemId);
}
});
itemCompositions = CacheBuilder.newBuilder()
.maximumSize(1024L)
.expireAfterAccess(1, TimeUnit.HOURS)
.build(new CacheLoader<Integer, ItemComposition>()
{
@Override
public ItemComposition load(Integer key) throws Exception
{
return client.getItemDefinition(key);
}
});
}
/**
* Look up an item's price asynchronously.
*
* @param itemId
* @param itemId item id
* @return the price, or null if the price is not yet loaded
*/
public ItemPrice get(int itemId)
public ItemPrice getItemPriceAsync(int itemId)
{
ItemPrice itemPrice = itemPrices.getIfPresent(itemId);
if (itemPrice != null && itemPrice != EMPTY)
@@ -101,8 +129,8 @@ public class ItemManager
/**
* Look up an item's price synchronously
*
* @param itemId
* @return
* @param itemId item id
* @return item price
* @throws IOException
*/
public ItemPrice getItemPrice(int itemId) throws IOException
@@ -118,6 +146,30 @@ public class ItemManager
return itemPrice;
}
/**
* Look up an item's composition
*
* @param itemName item name
* @return item search result
* @throws java.util.concurrent.ExecutionException exception when item
* is not found
*/
public SearchResult searchForItem(String itemName) throws ExecutionException
{
return itemSearches.get(itemName);
}
/**
* Look up an item's composition
*
* @param itemId item id
* @return item composition
*/
public ItemComposition getItemComposition(int itemId)
{
return itemCompositions.getUnchecked(itemId);
}
/**
* Convert a quantity to stack size
*

View File

@@ -60,28 +60,6 @@ public interface ChatCommandsConfig extends Config
@ConfigItem(
position = 2,
keyName = "enableRecolor",
name = "Enable command recolor",
description = "Configures whether chat commands are recolored"
)
default boolean recolorEnabled()
{
return true;
}
@ConfigItem(
position = 3,
keyName = "enablePrivateRecolor",
name = "enable private recolor",
description = "enable private recolor"
)
default boolean isPrivateRecolor()
{
return false;
}
@ConfigItem(
position = 4,
keyName = "hexColorPublic",
name = "Public chat",
description = "Color of Public chat"
@@ -92,7 +70,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 5,
position = 3,
keyName = "hexColorPublicH",
name = "Public chat highlight",
description = "Color of Public chat highlight"
@@ -103,7 +81,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 6,
position = 4,
keyName = "hexColorPrivate",
name = "Private chat",
description = "Color of Private chat"
@@ -114,7 +92,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 7,
position = 5,
keyName = "hexColorPrivateH",
name = "Private chat highlight",
description = "Color of Private chat highlight"
@@ -125,7 +103,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 8,
position = 6,
keyName = "hexColorCc",
name = "Clan chat",
description = "Color of Clan chat"
@@ -136,7 +114,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 9,
position = 7,
keyName = "hexColorCcH",
name = "Clan chat Highlight",
description = "Color of Clan chat highlight"
@@ -147,18 +125,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 10,
keyName = "transparancyRecolor",
name = "Different colors for transparent chatbox",
description = "Configures whether colors are different for transparent chatbox"
)
default boolean transparancyRecolor()
{
return true;
}
@ConfigItem(
position = 11,
position = 8,
keyName = "transparentHexColorPublic",
name = "Transparent public chat",
description = "Color of Public chat"
@@ -169,7 +136,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 12,
position = 9,
keyName = "transparentHexColorPublicH",
name = "Transparent public chat highlight",
description = "Color of Public chat highlight"
@@ -180,7 +147,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 13,
position = 10,
keyName = "transparentHexColorPrivate",
name = "Transparent private chat",
description = "Color of Private chat"
@@ -191,7 +158,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 14,
position = 11,
keyName = "transparentHexColorPrivateH",
name = "Transparent private chat highlight",
description = "Color of Private chat highlight"
@@ -202,7 +169,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 15,
position = 12,
keyName = "transparentHexColorCc",
name = "Transparent clan chat",
description = "Color of Clan chat"
@@ -213,7 +180,7 @@ public interface ChatCommandsConfig extends Config
}
@ConfigItem(
position = 16,
position = 13,
keyName = "transparentHexColorCcH",
name = "Transparent clan chat Highlight",
description = "Color of Clan chat highlight"

View File

@@ -27,14 +27,10 @@ package net.runelite.client.plugins.chatcommands;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides;
import java.awt.Color;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
@@ -43,12 +39,14 @@ import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.ItemComposition;
import net.runelite.api.MessageNode;
import net.runelite.api.Varbits;
import net.runelite.client.chat.ChatColor;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.ResizeableChanged;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.events.SetMessage;
import net.runelite.client.events.VarbitChanged;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@@ -57,7 +55,6 @@ import net.runelite.http.api.hiscore.HiscoreSkill;
import net.runelite.http.api.hiscore.SingleHiscoreSkillResult;
import net.runelite.http.api.hiscore.Skill;
import net.runelite.http.api.item.Item;
import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.SearchResult;
@@ -69,11 +66,7 @@ public class ChatCommandsPlugin extends Plugin
{
private static final float HIGH_ALCHEMY_CONSTANT = 0.6f;
private final String colKeyword = "<colRegular>";
private final String colKeywordHighLight = "<colHighlight>";
private final ItemClient itemClient = new ItemClient();
private final HiscoreClient hiscoreClient = new HiscoreClient();
private int transparancyVarbit = -1;
@Inject
@Nullable
@@ -85,6 +78,9 @@ public class ChatCommandsPlugin extends Plugin
@Inject
ItemManager itemManager;
@Inject
ChatMessageManager chatMessageManager;
@Inject
ScheduledExecutorService executor;
@@ -94,58 +90,52 @@ public class ChatCommandsPlugin extends Plugin
return configManager.getConfig(ChatCommandsConfig.class);
}
/**
* Checks if the chatbox is no longer transparent and if messages need
* to be recolored
*
* @param event the event object
*/
@Subscribe
public void onVarbitChange(VarbitChanged event)
public void onGameStateChange(GameStateChanged event)
{
if (transparancyVarbit == -1)
if (event.getGameState().equals(GameState.LOGIN_SCREEN))
{
transparancyVarbit = client.getSetting(Varbits.TRANSPARANT_CHATBOX);
}
else if (transparancyVarbit != client.getSetting(Varbits.TRANSPARANT_CHATBOX))
{
transparancyVarbit = client.getSetting(Varbits.TRANSPARANT_CHATBOX);
executor.submit(() -> recolorChat());
cacheConfiguredColors();
}
}
@Subscribe
public void onResizableChanged(ResizeableChanged event)
{
executor.submit(() -> recolorChat());
}
/**
* get the MessageNodes that have a runeltie message
*
* @return
*/
private Collection<MessageNode> getRuneliteMessages()
{
return client.getChatLineMap().values().stream()
.filter(Objects::nonNull)
.flatMap(clb -> Arrays.stream(clb.getLines()))
.filter(Objects::nonNull)
.filter(mn -> mn.getRuneLiteFormatMessage() != null)
.collect(Collectors.toList());
}
/**
* Updates the ingame recolored messages to the new config recolorChat
* cannot color messages without color tags because it won't know what
* to replace.
*
* @param event the event object
*/
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
executor.submit(() -> recolorChat());
if (event.getGroup().equals("chatcommands"))
{
cacheConfiguredColors();
chatMessageManager.refreshAll();
}
}
private void cacheConfiguredColors()
{
chatMessageManager
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getPublicRecolor(), false),
ChatMessageType.PUBLIC)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getPublicHRecolor(), false),
ChatMessageType.PUBLIC)
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getPrivateRecolor(), false),
ChatMessageType.PRIVATE_MESSAGE_SENT, ChatMessageType.PRIVATE_MESSAGE_RECEIVED)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getPrivateHRecolor(), false),
ChatMessageType.PRIVATE_MESSAGE_SENT, ChatMessageType.PRIVATE_MESSAGE_RECEIVED)
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getCcRecolor(), false),
ChatMessageType.CLANCHAT)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getCcHRecolor(), false),
ChatMessageType.CLANCHAT)
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getTransparentPublicRecolor(), true),
ChatMessageType.PUBLIC)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getTransparentPublicHRecolor(), true),
ChatMessageType.PUBLIC)
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getTransparentPrivateRecolor(), true),
ChatMessageType.PRIVATE_MESSAGE_SENT, ChatMessageType.PRIVATE_MESSAGE_RECEIVED)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getTransparentPrivateHRecolor(), true),
ChatMessageType.PRIVATE_MESSAGE_SENT, ChatMessageType.PRIVATE_MESSAGE_RECEIVED)
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getTransparentCcRecolor(), true),
ChatMessageType.CLANCHAT)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getTransparentCcHRecolor(), true),
ChatMessageType.CLANCHAT);
}
/**
@@ -190,7 +180,7 @@ public class ChatCommandsPlugin extends Plugin
log.debug("Running price lookup for {}", search);
executor.submit(() -> lookup(setMessage.getType(), setMessage.getMessageNode(), search));
executor.submit(() -> itemPriceLookup(setMessage.getType(), setMessage.getMessageNode(), search));
}
else if (config.lvl() && message.toLowerCase().startsWith("!lvl") && message.length() > 5)
{
@@ -208,15 +198,15 @@ public class ChatCommandsPlugin extends Plugin
* @param messageNode The chat message containing the command.
* @param search The item given with the command.
*/
private void lookup(ChatMessageType type, MessageNode messageNode, String search)
private void itemPriceLookup(ChatMessageType type, MessageNode messageNode, String search)
{
SearchResult result;
try
{
result = itemClient.search(search);
result = itemManager.searchForItem(search);
}
catch (IOException ex)
catch (ExecutionException ex)
{
log.warn("Unable to search for item {}", search, ex);
return;
@@ -244,27 +234,31 @@ public class ChatCommandsPlugin extends Plugin
return;
}
StringBuilder builder = new StringBuilder();
builder.append(colKeyword).append("Price of ")
.append(colKeywordHighLight).append(item.getName())
.append(colKeyword).append(": GE average ")
.append(colKeywordHighLight).append(String.format("%,d", itemPrice.getPrice()));
final ChatMessageBuilder builder = new ChatMessageBuilder()
.append(ChatColorType.NORMAL)
.append("Price of ")
.append(ChatColorType.HIGHLIGHT)
.append(item.getName())
.append(ChatColorType.NORMAL)
.append(": GE average ")
.append(ChatColorType.HIGHLIGHT)
.append(String.format("%,d", itemPrice.getPrice()));
ItemComposition itemComposition = client.getItemDefinition(itemId);
ItemComposition itemComposition = itemManager.getItemComposition(itemId);
if (itemComposition != null)
{
int alchPrice = Math.round(itemComposition.getPrice() * HIGH_ALCHEMY_CONSTANT);
builder.append(colKeyword).append(" HA value ")
.append(colKeywordHighLight).append(String.format("%,d", alchPrice));
builder
.append(ChatColorType.NORMAL)
.append(" HA value ")
.append(ChatColorType.HIGHLIGHT)
.append(String.format("%,d", alchPrice));
}
String response = builder.toString();
String response = builder.build();
log.debug("Setting response {}", response);
// XXX hopefully messageNode hasn't been reused yet?
messageNode.setRuneLiteFormatMessage(response);
messageNode.setValue(recolorMessage(messageNode.getType(), response));
chatMessageManager.update(type, response, messageNode);
client.refreshChat();
}
}
@@ -310,20 +304,23 @@ public class ChatCommandsPlugin extends Plugin
SingleHiscoreSkillResult result = hiscoreClient.lookup(player, skill);
Skill hiscoreSkill = result.getSkill();
String response = new StringBuilder()
.append(colKeyword).append("Level ")
.append(colKeywordHighLight).append(skill.getName()).append(": ").append(hiscoreSkill.getLevel())
.append(colKeyword).append(" Experience: ")
.append(colKeywordHighLight).append(String.format("%,d", hiscoreSkill.getExperience()))
.append(colKeyword).append(" Rank: ")
.append(colKeywordHighLight).append(String.format("%,d", hiscoreSkill.getRank()))
.toString();
String response = new ChatMessageBuilder()
.append(ChatColorType.NORMAL)
.append("Level ")
.append(ChatColorType.HIGHLIGHT)
.append(skill.getName()).append(": ").append(String.valueOf(hiscoreSkill.getLevel()))
.append(ChatColorType.NORMAL)
.append(" Experience: ")
.append(ChatColorType.HIGHLIGHT)
.append(String.format("%,d", hiscoreSkill.getExperience()))
.append(ChatColorType.NORMAL)
.append(" Rank: ")
.append(ChatColorType.HIGHLIGHT)
.append(String.format("%,d", hiscoreSkill.getRank()))
.build();
log.debug("Setting response {}", response);
// XXX hopefully messageNode hasn't been reused yet?
setMessage.getMessageNode().setRuneLiteFormatMessage(response);
setMessage.getMessageNode().setValue(recolorMessage(setMessage.getType(), response));
chatMessageManager.update(type, response, setMessage.getMessageNode());
client.refreshChat();
}
catch (IOException ex)
@@ -353,108 +350,6 @@ public class ChatCommandsPlugin extends Plugin
return null;
}
private ChatColor getChatColor(ChatMessageType type)
{
if ((type == ChatMessageType.PRIVATE_MESSAGE_SENT || type == ChatMessageType.PRIVATE_MESSAGE_RECEIVED) && !config.isPrivateRecolor())
{
return null;
}
if (client.getSetting(Varbits.TRANSPARANT_CHATBOX) == 0 || !client.isResized() || !config.transparancyRecolor())
{
switch (type)
{
case PUBLIC:
return new ChatColor(config.getPublicRecolor(), type, false, false);
case PRIVATE_MESSAGE_RECEIVED:
case PRIVATE_MESSAGE_SENT:
return new ChatColor(config.getPrivateRecolor(), type, false, false);
case CLANCHAT:
return new ChatColor(config.getCcRecolor(), type, false, false);
}
}
else
{
switch (type)
{
case PUBLIC:
return new ChatColor(config.getTransparentPublicRecolor(), type, true, false);
case PRIVATE_MESSAGE_RECEIVED:
case PRIVATE_MESSAGE_SENT:
return new ChatColor(config.getTransparentPrivateRecolor(), type, true, false);
case CLANCHAT:
return new ChatColor(config.getTransparentCcRecolor(), type, true, false);
}
}
return null;
}
private ChatColor getChatColorH(ChatMessageType type)
{
if ((type == ChatMessageType.PRIVATE_MESSAGE_SENT || type == ChatMessageType.PRIVATE_MESSAGE_RECEIVED) && !config.isPrivateRecolor())
{
return null;
}
if (client.getSetting(Varbits.TRANSPARANT_CHATBOX) == 0 || !client.isResized() || !config.transparancyRecolor())
{
switch (type)
{
case PUBLIC:
return new ChatColor(config.getPublicHRecolor(), type, false, true);
case PRIVATE_MESSAGE_RECEIVED:
case PRIVATE_MESSAGE_SENT:
return new ChatColor(config.getPrivateHRecolor(), type, false, true);
case CLANCHAT:
return new ChatColor(config.getCcHRecolor(), type, false, true);
}
}
else
{
switch (type)
{
case PUBLIC:
return new ChatColor(config.getTransparentPublicHRecolor(), type, true, true);
case PRIVATE_MESSAGE_RECEIVED:
case PRIVATE_MESSAGE_SENT:
return new ChatColor(config.getTransparentPrivateHRecolor(), type, true, true);
case CLANCHAT:
return new ChatColor(config.getTransparentCcHRecolor(), type, true, true);
}
}
return null;
}
private String recolorMessage(ChatMessageType type, String value)
{
ChatColor chatcolor = getChatColor(type);
ChatColor chatColorH = getChatColorH(type);
if (config.recolorEnabled() && chatcolor != null && chatColorH != null)
{
value = value.replace(colKeyword, getColTag(chatcolor.color))
.replace(colKeywordHighLight, getColTag(chatColorH.color));
}
else
{
value = value.replace(colKeyword, "")
.replace(colKeywordHighLight, "");
}
return value;
}
private void recolorChat()
{
Collection<MessageNode> nodes = getRuneliteMessages();
for (MessageNode message : nodes)
{
message.setValue(recolorMessage(message.getType(), message.getRuneLiteFormatMessage()));
}
client.refreshChat();
}
public static String getColTag(Color color)
{
return color == null ? "" : "<col=" + Integer.toHexString(color.getRGB() & 0xFFFFFF) + ">";
}
/**
* Cleans the playername string from ironman status icon if present and
* corrects spaces

View File

@@ -0,0 +1,93 @@
/*
* 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.examine;
import java.awt.Color;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup(
keyName = "examine",
name = "Examine",
description = "Configuration for examine plugin"
)
public interface ExamineConfig extends Config
{
@ConfigItem(
position = 1,
keyName = "itemPrice",
name = "Show item price on examine",
description = "Configures whether the item price is shown when examining item"
)
default boolean itemPrice()
{
return true;
}
@ConfigItem(
position = 2,
keyName = "hexColorExamine",
name = "Examine messages",
description = "Color of examine messages"
)
default Color getExamineRecolor()
{
return Color.decode("#000000");
}
@ConfigItem(
position = 3,
keyName = "hexColorExamineH",
name = "Examine messages highlight",
description = "Color of examine messages highlight"
)
default Color getExamineHRecolor()
{
return Color.decode("#0000FF");
}
@ConfigItem(
position = 4,
keyName = "transparentHexColorExamine",
name = "Transparent examine messages",
description = "Color of examine messages"
)
default Color getTransparentExamineRecolor()
{
return Color.decode("#FFFFFF");
}
@ConfigItem(
position = 5,
keyName = "transparentHexColorExamineH",
name = "Transparent examine messages highlight",
description = "Color of examine messages highlight"
)
default Color getTransparentExamineHRecolor()
{
return Color.decode("#9090FF");
}
}

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.examine;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayDeque;
@@ -34,12 +35,24 @@ import java.util.Deque;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.ItemComposition;
import net.runelite.client.chat.ChatColor;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.ChatMessage;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.events.MenuOptionClicked;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.http.api.examine.ExamineClient;
import net.runelite.http.api.item.ItemPrice;
/**
* Submits exammine info to the api
@@ -52,19 +65,67 @@ import net.runelite.http.api.examine.ExamineClient;
@Slf4j
public class ExaminePlugin extends Plugin
{
private final ExamineClient client = new ExamineClient();
private static final float HIGH_ALCHEMY_CONSTANT = 0.6f;
private final ExamineClient examineClient = new ExamineClient();
private final Deque<PendingExamine> pending = new ArrayDeque<>();
private final Cache<CacheKey, Boolean> cache = CacheBuilder.newBuilder()
.maximumSize(128L)
.build();
@Inject
Client client;
@Inject
ExamineConfig config;
@Inject
ItemManager itemManager;
@Inject
ChatMessageManager chatMessageManager;
@Inject
ScheduledExecutorService executor;
@Provides
ExamineConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(ExamineConfig.class);
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("examine"))
{
cacheConfiguredColors();
chatMessageManager.refreshAll();
}
}
private void cacheConfiguredColors()
{
chatMessageManager
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getExamineRecolor(), false),
ChatMessageType.EXAMINE_ITEM, ChatMessageType.EXAMINE_NPC, ChatMessageType.EXAMINE_OBJECT)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getExamineHRecolor(), false),
ChatMessageType.EXAMINE_ITEM, ChatMessageType.EXAMINE_NPC, ChatMessageType.EXAMINE_OBJECT)
.cacheColor(new ChatColor(ChatColorType.NORMAL, config.getTransparentExamineRecolor(), true),
ChatMessageType.EXAMINE_ITEM, ChatMessageType.EXAMINE_NPC, ChatMessageType.EXAMINE_OBJECT)
.cacheColor(new ChatColor(ChatColorType.HIGHLIGHT, config.getTransparentExamineHRecolor(), true),
ChatMessageType.EXAMINE_ITEM, ChatMessageType.EXAMINE_NPC, ChatMessageType.EXAMINE_OBJECT);
}
@Subscribe
public void onGameStateChange(GameStateChanged event)
{
pending.clear();
if (event.getGameState().equals(GameState.LOGIN_SCREEN))
{
cacheConfiguredColors();
}
}
@Subscribe
@@ -130,6 +191,11 @@ public class ExaminePlugin extends Plugin
log.debug("Got examine for {} {}: {}", pendingExamine.getType(), pendingExamine.getId(), event.getMessage());
if (config.itemPrice() && pendingExamine.getType() == ExamineType.ITEM)
{
executor.submit(() -> getItemPrice(pendingExamine));
}
CacheKey key = new CacheKey(type, pendingExamine.getId());
Boolean cached = cache.getIfPresent(key);
if (cached != null)
@@ -138,11 +204,48 @@ public class ExaminePlugin extends Plugin
}
cache.put(key, Boolean.TRUE);
executor.submit(() -> submit(pendingExamine, event.getMessage()));
executor.submit(() -> submitExamine(pendingExamine, event.getMessage()));
}
private void submit(PendingExamine examine, String text)
private void getItemPrice(PendingExamine examine)
{
try
{
final ItemComposition itemComposition = itemManager.getItemComposition(examine.getId());
if (itemComposition != null)
{
final int id = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemComposition.getId();
final ItemPrice itemPrice = itemManager.getItemPrice(id);
final int gePrice = itemPrice == null ? 0 : itemPrice.getPrice();
final int alchPrice = Math.round(itemComposition.getPrice() * HIGH_ALCHEMY_CONSTANT);
final String message = new ChatMessageBuilder()
.append(ChatColorType.NORMAL)
.append("Price of ")
.append(ChatColorType.HIGHLIGHT)
.append(itemComposition.getName())
.append(ChatColorType.NORMAL)
.append(": GE average ")
.append(ChatColorType.HIGHLIGHT)
.append(String.valueOf(gePrice))
.append(ChatColorType.NORMAL)
.append(" HA value ")
.append(ChatColorType.HIGHLIGHT)
.append(String.valueOf(alchPrice))
.build();
chatMessageManager.add(ChatMessageType.EXAMINE_ITEM, message);
client.refreshChat();
}
}
catch (IOException e)
{
log.warn("Error looking up item price", e);
}
}
private void submitExamine(PendingExamine examine, String text)
{
int id = examine.getId();
@@ -151,13 +254,13 @@ public class ExaminePlugin extends Plugin
switch (examine.getType())
{
case ITEM:
client.submitItem(id, text);
examineClient.submitItem(id, text);
break;
case OBJECT:
client.submitObject(id, text);
examineClient.submitObject(id, text);
break;
case NPC:
client.submitNpc(id, text);
examineClient.submitNpc(id, text);
break;
}
}

View File

@@ -24,21 +24,17 @@
*/
package net.runelite.client.plugins.grounditems;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.runelite.api.Client;
@@ -88,17 +84,6 @@ public class GroundItemsOverlay extends Overlay
private final Client client;
private final GroundItemsConfig config;
private final StringBuilder itemStringBuilder = new StringBuilder();
private final LoadingCache<Integer, ItemComposition> itemCache = CacheBuilder.newBuilder()
.maximumSize(1024L)
.expireAfterAccess(1, TimeUnit.MINUTES)
.build(new CacheLoader<Integer, ItemComposition>()
{
@Override
public ItemComposition load(Integer key) throws Exception
{
return client.getItemDefinition(key);
}
});
@Inject
ItemManager itemManager;
@@ -186,7 +171,7 @@ public class GroundItemsOverlay extends Overlay
Item item = (Item) current;
int itemId = item.getId();
int itemQuantity = item.getQuantity();
ItemComposition itemDefinition = itemCache.getUnchecked(itemId);
ItemComposition itemDefinition = itemManager.getItemComposition(itemId);
Integer currentQuantity = items.get(itemId);
if (!hiddenItems.contains(itemDefinition.getName().toLowerCase()))
@@ -200,7 +185,7 @@ public class GroundItemsOverlay extends Overlay
? itemQuantity
: currentQuantity + itemQuantity;
ItemPrice itemPrice = itemManager.get(itemId);
ItemPrice itemPrice = itemManager.getItemPriceAsync(itemId);
int gePrice = itemPrice == null ? 0 : itemPrice.getPrice() * quantity;
int alchPrice = Math.round(itemDefinition.getPrice() * HIGH_ALCHEMY_CONSTANT);
@@ -230,7 +215,7 @@ public class GroundItemsOverlay extends Overlay
int itemId = itemIds.get(i);
int quantity = items.get(itemId);
ItemComposition item = itemCache.getUnchecked(itemId);
ItemComposition item = itemManager.getItemComposition(itemId);
if (item == null)
{
@@ -257,7 +242,7 @@ public class GroundItemsOverlay extends Overlay
}
Color textColor = Color.WHITE; // Color to use when drawing the ground item
ItemPrice itemPrice = itemManager.get(itemId);
ItemPrice itemPrice = itemManager.getItemPriceAsync(itemId);
if (itemPrice != null && config.showGEPrice())
{
int cost = itemPrice.getPrice() * quantity;

View File

@@ -30,6 +30,7 @@ import com.google.inject.Binder;
import com.google.inject.Provides;
import java.awt.Color;
import static java.lang.Math.abs;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.GameState;
@@ -281,7 +282,7 @@ public class VolcanicMinePlugin extends Plugin
{
if (warningMode == WarningMode.INGAME || warningMode == WarningMode.INGAME_AND_NOTIFICATION)
{
client.sendGameMessage(getColTag(config.platformColorHigh()) + "Volcanic Mine helper: " + warning);
client.sendGameMessage(ChatMessageType.GAME, getColTag(config.platformColorHigh()) + "Volcanic Mine helper: " + warning);
}
if (warningMode == WarningMode.NOTIFICATION || warningMode == WarningMode.INGAME_AND_NOTIFICATION)
{

View File

@@ -26,6 +26,7 @@ package net.runelite.mixins;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.ChatMessageType;
import net.runelite.api.GameState;
import net.runelite.api.IndexedSprite;
import net.runelite.api.MenuAction;
@@ -99,9 +100,9 @@ public abstract class RSClientMixin implements RSClient
@Inject
@Override
public void sendGameMessage(String message)
public void sendGameMessage(ChatMessageType type, String message)
{
sendGameMessage(99, "", message);
sendGameMessage(type.getType(), "", message);
}
@Inject

View File

@@ -10,6 +10,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.ChatMessageType;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.plugins.Plugin;
@@ -49,7 +50,7 @@ public class ExamplePlugin extends Plugin
{
if (gameStateChanged.getGameState() == GameState.LOGGED_IN)
{
client.sendGameMessage("Example plugin is running!");
client.sendGameMessage(ChatMessageType.GAME, "Example plugin is running!");
}
}
@@ -71,4 +72,4 @@ public class ExamplePlugin extends Plugin
return configManager.getConfig(ExamplePluginConfiguration.class);
}
}
}