@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.http.api.kc;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class KillCountClient
|
||||||
|
{
|
||||||
|
public boolean submit(String username, String boss, int kc) throws IOException
|
||||||
|
{
|
||||||
|
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||||
|
.addPathSegment("kc")
|
||||||
|
.addQueryParameter("name", username)
|
||||||
|
.addQueryParameter("boss", boss)
|
||||||
|
.addQueryParameter("kc", Integer.toString(kc))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.post(RequestBody.create(null, new byte[0]))
|
||||||
|
.url(url)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||||
|
{
|
||||||
|
return response.isSuccessful();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(String username, String boss) throws IOException
|
||||||
|
{
|
||||||
|
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||||
|
.addPathSegment("kc")
|
||||||
|
.addQueryParameter("name", username)
|
||||||
|
.addQueryParameter("boss", boss)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||||
|
{
|
||||||
|
if (!response.isSuccessful())
|
||||||
|
{
|
||||||
|
throw new IOException("Unable to look up killcount!");
|
||||||
|
}
|
||||||
|
return Integer.parseInt(response.body().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.http.service.kc;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import net.runelite.http.service.util.exception.NotFoundException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/kc")
|
||||||
|
public class KillCountController
|
||||||
|
{
|
||||||
|
private final Cache<KillCountKey, Integer> cache = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterWrite(2, TimeUnit.MINUTES)
|
||||||
|
.maximumSize(128L)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KillCountService killCountService;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public void submit(@RequestParam String name, @RequestParam String boss, @RequestParam int kc)
|
||||||
|
{
|
||||||
|
if (kc <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
killCountService.setKc(name, boss, kc);
|
||||||
|
cache.put(new KillCountKey(name, boss), kc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public int get(@RequestParam String name, @RequestParam String boss)
|
||||||
|
{
|
||||||
|
Integer kc = cache.getIfPresent(new KillCountKey(name, boss));
|
||||||
|
if (kc == null)
|
||||||
|
{
|
||||||
|
kc = killCountService.getKc(name, boss);
|
||||||
|
if (kc != null)
|
||||||
|
{
|
||||||
|
cache.put(new KillCountKey(name, boss), kc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kc == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
return kc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.http.service.kc;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
class KillCountKey
|
||||||
|
{
|
||||||
|
private String username;
|
||||||
|
private String boss;
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.http.service.kc;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.sql2o.Connection;
|
||||||
|
import org.sql2o.Sql2o;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class KillCountService
|
||||||
|
{
|
||||||
|
private static final String CREATE = "CREATE TABLE IF NOT EXISTS `kc` (\n" +
|
||||||
|
" `name` varchar(32) NOT NULL,\n" +
|
||||||
|
" `boss` varchar(32) NOT NULL,\n" +
|
||||||
|
" `kc` int(11) NOT NULL,\n" +
|
||||||
|
" `time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),\n" +
|
||||||
|
" UNIQUE KEY `name` (`name`, `boss`),\n" +
|
||||||
|
" KEY `time` (`time`)\n" +
|
||||||
|
") ENGINE=InnoDB;";
|
||||||
|
|
||||||
|
private final Sql2o sql2o;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public KillCountService(@Qualifier("Runelite SQL2O") Sql2o sql2o)
|
||||||
|
{
|
||||||
|
this.sql2o = sql2o;
|
||||||
|
|
||||||
|
try (Connection con = sql2o.open())
|
||||||
|
{
|
||||||
|
con.createQuery(CREATE)
|
||||||
|
.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getKc(String name, String boss)
|
||||||
|
{
|
||||||
|
try (Connection con = sql2o.open())
|
||||||
|
{
|
||||||
|
return con.createQuery("select kc from kc where name = :name and boss = :boss")
|
||||||
|
.addParameter("name", name)
|
||||||
|
.addParameter("boss", boss)
|
||||||
|
.executeScalar(Integer.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKc(String name, String boss, int kc)
|
||||||
|
{
|
||||||
|
try (Connection con = sql2o.open())
|
||||||
|
{
|
||||||
|
con.createQuery("insert into kc (name, boss, kc) values (:name, :boss, :kc) on duplicate key update kc = VALUES(kc)")
|
||||||
|
.addParameter("name", name)
|
||||||
|
.addParameter("boss", boss)
|
||||||
|
.addParameter("kc", kc)
|
||||||
|
.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void purge()
|
||||||
|
{
|
||||||
|
try (Connection con = sql2o.open())
|
||||||
|
{
|
||||||
|
con.createQuery("delete from kc where time < (now() - interval 2 minute);")
|
||||||
|
.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedDelay = 60_000)
|
||||||
|
public void schedPurge()
|
||||||
|
{
|
||||||
|
purge();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,5 +26,6 @@ package net.runelite.api;
|
|||||||
|
|
||||||
public final class ScriptID
|
public final class ScriptID
|
||||||
{
|
{
|
||||||
|
public static final int CHATBOX_INPUT = 96;
|
||||||
public static final int RUNELITE_CHATBOX_INPUT_INIT = 10001;
|
public static final int RUNELITE_CHATBOX_INPUT_INIT = 10001;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,33 +33,54 @@ import javax.inject.Provider;
|
|||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.ScriptID;
|
||||||
import net.runelite.api.VarClientStr;
|
import net.runelite.api.VarClientStr;
|
||||||
import net.runelite.api.events.CommandExecuted;
|
import net.runelite.api.events.CommandExecuted;
|
||||||
import net.runelite.api.events.ScriptCallbackEvent;
|
import net.runelite.api.events.ScriptCallbackEvent;
|
||||||
|
import net.runelite.client.callback.ClientThread;
|
||||||
|
import net.runelite.client.events.ChatboxInput;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CommandManager
|
public class CommandManager
|
||||||
{
|
{
|
||||||
private static final String CALLBACK_NAME = "runeliteCommand";
|
private static final String RUNELITE_COMMAND = "runeliteCommand";
|
||||||
|
private static final String CHATBOX_INPUT = "chatboxInput";
|
||||||
|
|
||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
private final Provider<ClientThread> clientThreadProvider;
|
||||||
|
private boolean sending;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CommandManager(Provider<Client> clientProvider, EventBus eventBus)
|
public CommandManager(Provider<Client> clientProvider, EventBus eventBus, Provider<ClientThread> clientThreadProvider)
|
||||||
{
|
{
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
|
this.clientThreadProvider = clientThreadProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void scriptEvent(ScriptCallbackEvent event)
|
private void scriptEvent(ScriptCallbackEvent event)
|
||||||
{
|
{
|
||||||
if (!CALLBACK_NAME.equals(event.getEventName()))
|
if (sending)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (event.getEventName())
|
||||||
|
{
|
||||||
|
case RUNELITE_COMMAND:
|
||||||
|
runCommand();
|
||||||
|
break;
|
||||||
|
case CHATBOX_INPUT:
|
||||||
|
handleInput(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCommand()
|
||||||
|
{
|
||||||
Client client = clientProvider.get();
|
Client client = clientProvider.get();
|
||||||
String typedText = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT).substring(2); // strip ::
|
String typedText = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT).substring(2); // strip ::
|
||||||
|
|
||||||
@@ -79,4 +100,55 @@ public class CommandManager
|
|||||||
CommandExecuted commandExecuted = new CommandExecuted(command, args);
|
CommandExecuted commandExecuted = new CommandExecuted(command, args);
|
||||||
eventBus.post(commandExecuted);
|
eventBus.post(commandExecuted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleInput(ScriptCallbackEvent event)
|
||||||
|
{
|
||||||
|
Client client = clientProvider.get();
|
||||||
|
final String[] stringStack = client.getStringStack();
|
||||||
|
final int[] intStack = client.getIntStack();
|
||||||
|
int stringStackCount = client.getStringStackSize();
|
||||||
|
int intStackCount = client.getIntStackSize();
|
||||||
|
|
||||||
|
final String typedText = stringStack[stringStackCount - 1];
|
||||||
|
final int chatType = intStack[intStackCount - 1];
|
||||||
|
|
||||||
|
ChatboxInput chatboxInput = new ChatboxInput(typedText, chatType)
|
||||||
|
{
|
||||||
|
private boolean resumed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resume()
|
||||||
|
{
|
||||||
|
if (resumed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resumed = true;
|
||||||
|
|
||||||
|
ClientThread clientThread = clientThreadProvider.get();
|
||||||
|
clientThread.invokeLater(() -> sendChatboxInput(chatType, typedText));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
eventBus.post(chatboxInput);
|
||||||
|
|
||||||
|
if (chatboxInput.isStop())
|
||||||
|
{
|
||||||
|
// input was blocked.
|
||||||
|
stringStack[stringStackCount - 1] = ""; // prevent script from sending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendChatboxInput(int chatType, String input)
|
||||||
|
{
|
||||||
|
Client client = clientProvider.get();
|
||||||
|
sending = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.runScript(ScriptID.CHATBOX_INPUT, chatType, input);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 abstract class ChatboxInput
|
||||||
|
{
|
||||||
|
private final String value;
|
||||||
|
private final int chatType;
|
||||||
|
private boolean stop;
|
||||||
|
|
||||||
|
public abstract void resume();
|
||||||
|
}
|
||||||
@@ -47,7 +47,9 @@ import net.runelite.api.vars.AccountType;
|
|||||||
import net.runelite.client.chat.ChatColorType;
|
import net.runelite.client.chat.ChatColorType;
|
||||||
import net.runelite.client.chat.ChatMessageBuilder;
|
import net.runelite.client.chat.ChatMessageBuilder;
|
||||||
import net.runelite.client.chat.ChatMessageManager;
|
import net.runelite.client.chat.ChatMessageManager;
|
||||||
|
import net.runelite.client.chat.CommandManager;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.events.ChatboxInput;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.input.KeyManager;
|
import net.runelite.client.input.KeyManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
@@ -62,6 +64,7 @@ import net.runelite.http.api.hiscore.Skill;
|
|||||||
import net.runelite.http.api.item.Item;
|
import net.runelite.http.api.item.Item;
|
||||||
import net.runelite.http.api.item.ItemPrice;
|
import net.runelite.http.api.item.ItemPrice;
|
||||||
import net.runelite.http.api.item.SearchResult;
|
import net.runelite.http.api.item.SearchResult;
|
||||||
|
import net.runelite.http.api.kc.KillCountClient;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Chat Commands",
|
name = "Chat Commands",
|
||||||
@@ -76,6 +79,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
private static final Pattern WINTERTODT_PATERN = Pattern.compile("Your subdued Wintertodt count is: <col=ff0000>(\\d+)</col>.");
|
private static final Pattern WINTERTODT_PATERN = Pattern.compile("Your subdued Wintertodt count is: <col=ff0000>(\\d+)</col>.");
|
||||||
|
|
||||||
private final HiscoreClient hiscoreClient = new HiscoreClient();
|
private final HiscoreClient hiscoreClient = new HiscoreClient();
|
||||||
|
private final KillCountClient killCountClient = new KillCountClient();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
@@ -101,6 +105,9 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ChatKeyboardListener chatKeyboardListener;
|
private ChatKeyboardListener chatKeyboardListener;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CommandManager commandManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startUp()
|
public void startUp()
|
||||||
{
|
{
|
||||||
@@ -194,6 +201,13 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
log.debug("Running clue lookup for {}", search);
|
log.debug("Running clue lookup for {}", search);
|
||||||
executor.submit(() -> playerClueLookup(setMessage, search));
|
executor.submit(() -> playerClueLookup(setMessage, search));
|
||||||
}
|
}
|
||||||
|
else if (message.toLowerCase().startsWith("!kc "))
|
||||||
|
{
|
||||||
|
String search = message.substring(4);
|
||||||
|
|
||||||
|
log.debug("Running killcount lookup for {}", search);
|
||||||
|
executor.submit(() -> killCountLookup(setMessage.getType(), setMessage, search));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -223,12 +237,90 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onChatboxInput(ChatboxInput chatboxInput)
|
||||||
|
{
|
||||||
|
final String value = chatboxInput.getValue();
|
||||||
|
if (!value.startsWith("!kc "))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String boss = longBossName(value.substring(4));
|
||||||
|
|
||||||
|
final int kc = getKc(boss);
|
||||||
|
if (kc <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chatboxInput.setStop(true);
|
||||||
|
final String playerName = client.getLocalPlayer().getName();
|
||||||
|
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
killCountClient.submit(playerName, boss, kc);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.warn("unable to submit killcount", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
chatboxInput.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void killCountLookup(ChatMessageType type, SetMessage setMessage, String search)
|
||||||
|
{
|
||||||
|
final String player;
|
||||||
|
if (type.equals(ChatMessageType.PRIVATE_MESSAGE_SENT))
|
||||||
|
{
|
||||||
|
player = client.getLocalPlayer().getName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player = sanitize(setMessage.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
search = longBossName(search);
|
||||||
|
|
||||||
|
final int kc;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
kc = killCountClient.get(player, search);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
log.debug("unable to lookup killcount", ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String response = new ChatMessageBuilder()
|
||||||
|
.append(ChatColorType.HIGHLIGHT)
|
||||||
|
.append(search)
|
||||||
|
.append(ChatColorType.NORMAL)
|
||||||
|
.append(" kill count: ")
|
||||||
|
.append(ChatColorType.HIGHLIGHT)
|
||||||
|
.append(Integer.toString(kc))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
log.debug("Setting response {}", response);
|
||||||
|
final MessageNode messageNode = setMessage.getMessageNode();
|
||||||
|
messageNode.setRuneLiteFormatMessage(response);
|
||||||
|
chatMessageManager.update(messageNode);
|
||||||
|
client.refreshChat();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up the item price and changes the original message to the
|
* Looks up the item price and changes the original message to the
|
||||||
* response.
|
* response.
|
||||||
*
|
*
|
||||||
* @param messageNode The chat message containing the command.
|
* @param messageNode The chat message containing the command.
|
||||||
* @param search The item given with the command.
|
* @param search The item given with the command.
|
||||||
*/
|
*/
|
||||||
private void itemPriceLookup(MessageNode messageNode, String search)
|
private void itemPriceLookup(MessageNode messageNode, String search)
|
||||||
{
|
{
|
||||||
@@ -291,7 +383,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
* response.
|
* response.
|
||||||
*
|
*
|
||||||
* @param setMessage The chat message containing the command.
|
* @param setMessage The chat message containing the command.
|
||||||
* @param search The item given with the command.
|
* @param search The item given with the command.
|
||||||
*/
|
*/
|
||||||
private void playerSkillLookup(SetMessage setMessage, String search)
|
private void playerSkillLookup(SetMessage setMessage, String search)
|
||||||
{
|
{
|
||||||
@@ -415,6 +507,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets correct lookup data for message
|
* Gets correct lookup data for message
|
||||||
|
*
|
||||||
* @param setMessage chat message
|
* @param setMessage chat message
|
||||||
* @return hiscore lookup data
|
* @return hiscore lookup data
|
||||||
*/
|
*/
|
||||||
@@ -452,7 +545,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
* Returns the item if its name is equal to the original input or null
|
* Returns the item if its name is equal to the original input or null
|
||||||
* if it can't find the item.
|
* if it can't find the item.
|
||||||
*
|
*
|
||||||
* @param items List of items.
|
* @param items List of items.
|
||||||
* @param originalInput String with the original input.
|
* @param originalInput String with the original input.
|
||||||
* @return Item which has a name equal to the original input.
|
* @return Item which has a name equal to the original input.
|
||||||
*/
|
*/
|
||||||
@@ -483,6 +576,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up the ironman status of the local player. Does NOT work on other players.
|
* Looks up the ironman status of the local player. Does NOT work on other players.
|
||||||
|
*
|
||||||
* @return hiscore endpoint
|
* @return hiscore endpoint
|
||||||
*/
|
*/
|
||||||
private HiscoreEndpoint getHiscoreEndpointType()
|
private HiscoreEndpoint getHiscoreEndpointType()
|
||||||
@@ -492,6 +586,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ironman status based on the symbol in the name of the player.
|
* Returns the ironman status based on the symbol in the name of the player.
|
||||||
|
*
|
||||||
* @param name player name
|
* @param name player name
|
||||||
* @return hiscore endpoint
|
* @return hiscore endpoint
|
||||||
*/
|
*/
|
||||||
@@ -517,6 +612,7 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts account type to hiscore endpoint
|
* Converts account type to hiscore endpoint
|
||||||
|
*
|
||||||
* @param accountType account type
|
* @param accountType account type
|
||||||
* @return hiscore endpoint
|
* @return hiscore endpoint
|
||||||
*/
|
*/
|
||||||
@@ -541,4 +637,95 @@ public class ChatCommandsPlugin extends Plugin
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final HiscoreEndpoint endpoint;
|
private final HiscoreEndpoint endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String longBossName(String boss)
|
||||||
|
{
|
||||||
|
switch (boss.toLowerCase())
|
||||||
|
{
|
||||||
|
case "corp":
|
||||||
|
return "Corporeal Beast";
|
||||||
|
|
||||||
|
case "jad":
|
||||||
|
return "TzTok-Jad";
|
||||||
|
|
||||||
|
case "kq":
|
||||||
|
return "Kalphite Queen";
|
||||||
|
|
||||||
|
case "chaos ele":
|
||||||
|
return "Chaos Elemental";
|
||||||
|
|
||||||
|
case "dusk":
|
||||||
|
case "dawn":
|
||||||
|
case "gargs":
|
||||||
|
return "Grotesque Guardians";
|
||||||
|
|
||||||
|
case "archaeologist":
|
||||||
|
return "Crazy Archaeologist";
|
||||||
|
|
||||||
|
case "mole":
|
||||||
|
return "Giant Mole";
|
||||||
|
|
||||||
|
case "vetion":
|
||||||
|
return "Vet'ion";
|
||||||
|
|
||||||
|
case "kbd":
|
||||||
|
return "King Black Dragon";
|
||||||
|
|
||||||
|
case "sire":
|
||||||
|
return "Abyssal Sire";
|
||||||
|
|
||||||
|
case "smoke devil":
|
||||||
|
case "thermy":
|
||||||
|
return "Thermonuclear Smoke Devil";
|
||||||
|
|
||||||
|
case "zuk":
|
||||||
|
case "inferno":
|
||||||
|
return "TzKal-Zuk";
|
||||||
|
|
||||||
|
// gwd
|
||||||
|
case "sara":
|
||||||
|
case "saradomin":
|
||||||
|
case "zilyana":
|
||||||
|
return "Commander Zilyana";
|
||||||
|
case "zammy":
|
||||||
|
case "zamorak":
|
||||||
|
case "kril":
|
||||||
|
case "kril trutsaroth":
|
||||||
|
return "K'ril Tsutsaroth";
|
||||||
|
case "arma":
|
||||||
|
case "kree":
|
||||||
|
case "kreearra":
|
||||||
|
case "armadyl":
|
||||||
|
return "Kree'arra";
|
||||||
|
case "bando":
|
||||||
|
case "bandos":
|
||||||
|
case "graardor":
|
||||||
|
return "General Graardor";
|
||||||
|
|
||||||
|
// dks
|
||||||
|
case "supreme":
|
||||||
|
return "Dagannoth Supreme";
|
||||||
|
case "rex":
|
||||||
|
return "Dagannoth Rex";
|
||||||
|
case "prime":
|
||||||
|
return "Dagannoth Prime";
|
||||||
|
|
||||||
|
case "wt":
|
||||||
|
return "Wintertodt";
|
||||||
|
case "barrows":
|
||||||
|
return "Barrows Chests";
|
||||||
|
|
||||||
|
case "xeric":
|
||||||
|
case "olm":
|
||||||
|
case "raids":
|
||||||
|
return "Chambers of Xeric";
|
||||||
|
|
||||||
|
case "verxik":
|
||||||
|
case "raids 2":
|
||||||
|
return "Theatre of Blood";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return boss;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
runelite-scripts/scripts/ChatboxInput.hash
Normal file
1
runelite-scripts/scripts/ChatboxInput.hash
Normal file
@@ -0,0 +1 @@
|
|||||||
|
7D172258726F2B866D2EFFB0F2E401D0551A377DCA7F72CCD8839AC88B3EA6A2
|
||||||
51
runelite-scripts/scripts/ChatboxInput.rs2asm
Normal file
51
runelite-scripts/scripts/ChatboxInput.rs2asm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
.id 96
|
||||||
|
.int_stack_count 1
|
||||||
|
.string_stack_count 1
|
||||||
|
.int_var_count 1
|
||||||
|
.string_var_count 1
|
||||||
|
sload 0 ; load input
|
||||||
|
iload 0 ; load chat type
|
||||||
|
load_string "chatboxInput" ; event name
|
||||||
|
runelite_callback ; invoke callback
|
||||||
|
pop_int ; pop chat type
|
||||||
|
string_length ; get string length of chat message
|
||||||
|
iload 0 ; load 0
|
||||||
|
if_icmpne LABEL100 ; if length is not 0, continue
|
||||||
|
return
|
||||||
|
LABEL100:
|
||||||
|
get_varbit 4394
|
||||||
|
load_int 1
|
||||||
|
if_icmpeq LABEL4
|
||||||
|
jump LABEL24
|
||||||
|
LABEL4:
|
||||||
|
iload 0
|
||||||
|
load_int 1
|
||||||
|
if_icmpeq LABEL8
|
||||||
|
jump LABEL16
|
||||||
|
LABEL8:
|
||||||
|
get_localplayer_name
|
||||||
|
load_string ": "
|
||||||
|
load_string "<col=2020ef>"
|
||||||
|
sload 0
|
||||||
|
load_string "</col>"
|
||||||
|
string_append 5
|
||||||
|
send_game_message
|
||||||
|
jump LABEL23
|
||||||
|
LABEL16:
|
||||||
|
get_localplayer_name
|
||||||
|
load_string ": "
|
||||||
|
load_string "<col=0000ff>"
|
||||||
|
sload 0
|
||||||
|
load_string "</col>"
|
||||||
|
string_append 5
|
||||||
|
send_game_message
|
||||||
|
LABEL23:
|
||||||
|
jump LABEL27
|
||||||
|
LABEL24:
|
||||||
|
sload 0
|
||||||
|
iload 0
|
||||||
|
chatbox_input
|
||||||
|
LABEL27:
|
||||||
|
get_gamecycle
|
||||||
|
put_varc 61
|
||||||
|
return
|
||||||
Reference in New Issue
Block a user