runelite-client: add !price command
This commit is contained in:
@@ -72,4 +72,37 @@ public class ItemClient
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public SearchResult search(String itemName) throws IOException
|
||||
{
|
||||
HttpUrl url = RuneliteAPI.getApiBase().newBuilder()
|
||||
.addPathSegment("item")
|
||||
.addPathSegment("search")
|
||||
.addQueryParameter("query", itemName)
|
||||
.build();
|
||||
|
||||
logger.debug("Built URI: {}", url);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
Response response = RuneliteAPI.CLIENT.newCall(request).execute();
|
||||
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
logger.debug("Error looking up item {}: {}", itemName, response.message());
|
||||
return null;
|
||||
}
|
||||
|
||||
try (ResponseBody body = response.body())
|
||||
{
|
||||
InputStream in = body.byteStream();
|
||||
return RuneliteAPI.GSON.fromJson(new InputStreamReader(in), SearchResult.class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,4 +410,9 @@ public class Client
|
||||
{
|
||||
client.setGameDrawingMode(gameDrawingMode);
|
||||
}
|
||||
|
||||
public void refreshChat()
|
||||
{
|
||||
client.setChatCycle(client.getCycleCntr());
|
||||
}
|
||||
}
|
||||
|
||||
55
runelite-api/src/main/java/net/runelite/api/MessageNode.java
Normal file
55
runelite-api/src/main/java/net/runelite/api/MessageNode.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 class MessageNode
|
||||
{
|
||||
private final net.runelite.rs.api.MessageNode messageNode;
|
||||
|
||||
public MessageNode(net.runelite.rs.api.MessageNode messageNode)
|
||||
{
|
||||
this.messageNode = messageNode;
|
||||
}
|
||||
|
||||
public ChatMessageType getType()
|
||||
{
|
||||
return ChatMessageType.of(messageNode.getType());
|
||||
}
|
||||
|
||||
public String getSender()
|
||||
{
|
||||
return messageNode.getSender();
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return messageNode.getValue();
|
||||
}
|
||||
|
||||
public void setValue(String value)
|
||||
{
|
||||
messageNode.setValue(value);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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"))
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -234,4 +234,10 @@ public interface Client extends GameEngine
|
||||
setter = true
|
||||
)
|
||||
void setGameDrawingMode(int gameDrawingMode);
|
||||
|
||||
@Import("cycleCntr")
|
||||
int getCycleCntr();
|
||||
|
||||
@Import(value = "chatCycle", setter = true)
|
||||
void setChatCycle(int value);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* (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.rs.api;
|
||||
|
||||
import net.runelite.mapping.Import;
|
||||
@@ -37,4 +36,10 @@ public interface MessageNode
|
||||
|
||||
@Import("value")
|
||||
String getValue();
|
||||
|
||||
@Import(
|
||||
value = "value",
|
||||
setter = true
|
||||
)
|
||||
void setValue(String value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user