runelite-client: add !price command

This commit is contained in:
Adam
2017-07-16 13:49:17 -04:00
parent f8178aa2ee
commit 43f8c58d5a
10 changed files with 373 additions and 1 deletions

View File

@@ -35,6 +35,7 @@ import net.runelite.client.game.DeathChecker;
import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.overlay.OverlayRenderer;
import net.runelite.rs.api.MainBufferProvider;
import net.runelite.rs.api.MessageNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -190,4 +191,20 @@ public class Hooks
runelite.getEventBus().post(chatMessage);
}
public static void setMessage(Object object, int type, String name, String sender, String value)
{
MessageNode messageNode = (MessageNode) object;
// Hook is fired prior to actually setting these on the MessageNode, so send them
// in the event too.
SetMessage setMessage = new SetMessage();
setMessage.setMessageNode(new net.runelite.api.MessageNode(messageNode));
setMessage.setType(ChatMessageType.of(type));
setMessage.setName(name);
setMessage.setSender(sender);
setMessage.setValue(value);
runelite.getEventBus().post(setMessage);
}
}

View File

@@ -0,0 +1,68 @@
package net.runelite.client.events;
import net.runelite.api.ChatMessageType;
import net.runelite.api.MessageNode;
/**
* called when a message node's message is set
*
* @author Adam
*/
public class SetMessage
{
private MessageNode messageNode;
private ChatMessageType type;
private String name;
private String sender;
private String value;
public MessageNode getMessageNode()
{
return messageNode;
}
public void setMessageNode(MessageNode messageNode)
{
this.messageNode = messageNode;
}
public ChatMessageType getType()
{
return type;
}
public void setType(ChatMessageType type)
{
this.type = type;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getSender()
{
return sender;
}
public void setSender(String sender)
{
this.sender = sender;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
}

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.client.plugins;
import net.runelite.client.plugins.pricecommands.PriceCommands;
import net.runelite.client.task.ScheduledMethod;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Service;
@@ -102,6 +103,7 @@ public class PluginManager
plugins.add(new FishingPlugin());
plugins.add(new WoodcuttingPlugin());
plugins.add(new RememberUsername());
plugins.add(new PriceCommands());
if (RuneLite.getOptions().has("developer-mode"))
{

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2017. l2-
* 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.pricecommands;
import com.google.common.eventbus.Subscribe;
import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.MessageNode;
import net.runelite.client.game.ItemManager;
import net.runelite.client.RuneLite;
import net.runelite.client.events.SetMessage;
import net.runelite.client.plugins.Plugin;
import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.SearchResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PriceCommands extends Plugin
{
private static final Logger logger = LoggerFactory.getLogger(PriceCommands.class);
private final PriceCommandsConfig config = RuneLite.getRunelite().getConfigManager().getConfig(PriceCommandsConfig.class);
private final ItemManager itemManager = RuneLite.getRunelite().getItemManager();
private final ItemClient itemClient = new ItemClient();
private final RuneLite runelite = RuneLite.getRunelite();
private final Client client = RuneLite.getClient();
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
}
@Subscribe
public void onSetMessage(SetMessage setMessage)
{
if (client.getGameState() != GameState.LOGGED_IN || !config.enabled())
{
return;
}
switch (setMessage.getType())
{
case PUBLIC:
case CLANCHAT:
case PRIVATE_MESSAGE_RECEIVED:
break;
default:
return;
}
String message = setMessage.getValue();
if (message.toLowerCase().startsWith("!price") && message.length() > 7)
{
String search = message.substring(7);
logger.debug("Running lookup for {}", search);
ScheduledExecutorService executor = runelite.getExecutor();
executor.submit(() -> lookup(setMessage.getMessageNode(), search));
}
}
private void lookup(MessageNode messageNode, String search)
{
SearchResult result;
try
{
result = itemClient.search(search);
}
catch (IOException ex)
{
logger.warn("Unable to search for item {}", search, ex);
return;
}
if (result != null && result.getItems().size() == 1)
{
int itemId = result.getItems().get(0).getId();
ItemPrice itemPrice;
try
{
itemPrice = itemManager.getItemPrice(itemId);
}
catch (IOException ex)
{
logger.warn("Unable to fetch item price for {}", itemId, ex);
return;
}
int cost = itemPrice.getPrice();
String response = "Price of " + result.getItems().get(0).getName() + ": GE average " + String.format("%,d", cost);
logger.debug("Setting response {}", response);
// XXX hopefully messageNode hasn't been reused yet?
messageNode.setValue(response);
client.refreshChat();
}
}
}

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.pricecommands;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup(
keyName = "pricecommands",
name = "Chat commands",
description = "Configuration for chat commands"
)
public interface PriceCommandsConfig
{
@ConfigItem(
keyName = "enabled",
name = "Enable",
description = "Configures whether chat commands are enabled"
)
default boolean enabled()
{
return true;
}
}