Initial commit

This commit is contained in:
2022-01-08 19:46:18 +01:00
commit 57ba5a5858
207 changed files with 12402 additions and 0 deletions

View File

@ -0,0 +1,146 @@
package io.reisub.openosrs.util;
import io.reisub.openosrs.util.enums.Activity;
import io.reisub.openosrs.util.tasks.KittenTask;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.GameState;
import net.runelite.api.Skill;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigButtonClicked;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.StatChanged;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.iutils.scripts.iScript;
import javax.inject.Inject;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import static net.runelite.api.AnimationID.IDLE;
@Slf4j
public abstract class CScript extends iScript {
@Inject
protected Calculations calc;
protected final List<Task> tasks = new ArrayList<>();
protected KittenTask kittenTask;
@Getter
protected Activity currentActivity = Activity.IDLE;
protected Instant lastLogin = Instant.EPOCH;
protected Instant lastActionTime = Instant.EPOCH;
protected Instant lastExperience = Instant.EPOCH;
protected final Map<Skill, Activity> idleCheckSkills = new HashMap<>();
@Override
protected void loop() {
for (Task t : tasks) {
if (t.validate()) {
log.info(t.getStatus());
t.execute();
break;
}
}
checkActionTimeout();
game.sleepDelay();
}
@Override
protected void onStart() {
log.info("Starting " + this.getName());
kittenTask = KittenTask.getInstance(injector);
}
@Override
protected void onStop() {
log.info("Stopping " + this.getName());
tasks.clear();
KittenTask.handleKitten = false;
}
protected final <T extends Task> void addTask(Class<T> type) {
tasks.add(injector.getInstance(type));
}
@SuppressWarnings("unused")
@Subscribe
private void onConfigButtonPressed(ConfigButtonClicked event) {
String name = this.getName().replaceAll(" ", "").toLowerCase(Locale.ROOT);
if (event.getGroup().equals(name) && event.getKey().equals("startButton")) {
execute();
}
}
@SuppressWarnings("unused")
@Subscribe
private void onChatMessage(ChatMessage event) {
if (kittenTask != null) {
kittenTask.onChatMessage(event);
}
if (event.getType() == ChatMessageType.GAMEMESSAGE) {
if (event.getMessage().startsWith("Congratulations, you've just advanced your")) {
setActivity(Activity.IDLE);
}
}
}
@SuppressWarnings("unused")
@Subscribe
private void onStatChanged(StatChanged event) {
for (Skill skill : idleCheckSkills.keySet()) {
if (event.getSkill() == skill) {
setActivity(idleCheckSkills.get(skill));
lastExperience = Instant.now();
}
}
}
@Subscribe
@SuppressWarnings("unused")
private void onGameStateChanged(GameStateChanged event) {
if (event.getGameState() == GameState.LOGGED_IN) {
lastLogin = Instant.now();
}
}
protected void setActivity(Activity action) {
currentActivity = action;
if (action != Activity.IDLE) {
lastActionTime = Instant.now();
}
}
protected void checkActionTimeout() {
if (currentActivity == Activity.IDLE) return;
if (Duration.between(lastExperience, Instant.now()).getSeconds() < 5) return;
int animId = game.localPlayer().animation();
if (animId != IDLE || lastActionTime == null) return;
Duration timeout = Duration.ofSeconds(5);
Duration sinceAction = Duration.between(lastActionTime, Instant.now());
if (sinceAction.compareTo(timeout) >= 0) {
setActivity(Activity.IDLE);
}
}
public final boolean isLoggedIn() {
return game.client() != null && game.client().getGameState() == GameState.LOGGED_IN;
}
public final boolean isLoggedInForLongerThan(int seconds) {
return Duration.between(lastLogin, Instant.now()).getSeconds() >= seconds;
}
}

View File

@ -0,0 +1,95 @@
package io.reisub.openosrs.util;
import javax.inject.Singleton;
import java.util.Random;
@Singleton
public class Calculations {
private final Random random = new Random();
/**
* Get a random number in the interval [min, max[.
*
* @param min inclusive minimum value
* @param max exclusive maximum value
* @return random number min <= n < max
*/
public int random(int min, int max) {
if (max <= min) return min;
return random.nextInt(max - min) + min;
}
/**
* Get a random number in the interval [min, max[.
*
* @param min inclusive minimum value
* @param max exclusive maximum value
* @return random number min <= n < max
*/
public double random(double min, double max) {
if (max <= min) return min;
return min + random.nextDouble() * (max - min);
}
/**
* Get a random Gaussian distributed number around a mean using deviation.
*
* @param mean mean value
* @param deviation deviation from the mean
* @param weighted if true the distribution will be weighted to the mean and right side (curve shifted to the right)
* @return random number min <= n <= max according to normal distribution
*/
public int randomGauss(int mean, int deviation, boolean weighted) {
double v;
if (weighted) {
v = -Math.log(Math.abs(random.nextGaussian())) * deviation + mean;
} else {
v = random.nextGaussian() * deviation + mean;
}
return (int) v;
}
/**
* Get a random Gaussian distributed number around a mean using deviation.
*
* @param mean mean value
* @param deviation deviation from the mean
* @return random number min <= n <= max according to normal distribution
*/
public int randomGauss(int mean, int deviation) {
return randomGauss(mean, deviation, false);
}
/**
* Get a random Gaussian distributed number within an interval [min, max] around a mean using deviation.
*
* @param min inclusive minimum value
* @param max inclusive maximum value
* @param mean mean value
* @param deviation deviation from the mean
* @param weighted if true the distribution will be weighted to the mean and right side (curve shifted to the right)
* @return random number min <= n <= max according to normal distribution
*/
public int randomGauss(int min, int max, int mean, int deviation, boolean weighted) {
return clamp(randomGauss(mean, deviation, weighted), min, max);
}
/**
* Get a random Gaussian distributed number within an interval [min, max] around a mean using deviation.
*
* @param min inclusive minimum value
* @param max inclusive maximum value
* @param mean mean value
* @param deviation deviation from the mean
* @return random number min <= n <= max according to normal distribution
*/
public int randomGauss(int min, int max, int mean, int deviation) {
return randomGauss(min, max, deviation, mean, false);
}
private int clamp(int v, int min, int max) {
return Math.max(min, Math.min(max, v));
}
}

View File

@ -0,0 +1,8 @@
package io.reisub.openosrs.util;
import net.runelite.client.config.*;
@ConfigGroup("ChaosUtilConfig")
public interface Config extends net.runelite.client.config.Config {
}

View File

@ -0,0 +1,67 @@
package io.reisub.openosrs.util;
import net.runelite.api.GameState;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.game.WorldService;
import net.runelite.client.plugins.iutils.game.Game;
import net.runelite.client.util.WorldUtil;
import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldResult;
import javax.inject.Inject;
import java.time.Duration;
import java.time.Instant;
public class HopHelper {
@Inject
private Game game;
@Inject
private WorldService worldService;
private Instant lastAttempt;
private net.runelite.api.World quickHopTargetWorld;
private int displaySwitcherAttempts = 0;
public void prepare(int worldId) {
if (Duration.between(lastAttempt, Instant.now()).getSeconds() < 5) return;
WorldResult worldResult = worldService.getWorlds();
if (worldResult == null) return;
World world = worldResult.findWorld(worldId);
if (world == null) return;
final net.runelite.api.World rsWorld = game.client().createWorld();
rsWorld.setActivity(world.getActivity());
rsWorld.setAddress(world.getAddress());
rsWorld.setId(world.getId());
rsWorld.setPlayerCount(world.getPlayers());
rsWorld.setLocation(world.getLocation());
rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
if (game.client().getGameState() == GameState.LOGIN_SCREEN) {
game.client().changeWorld(rsWorld);
return;
}
quickHopTargetWorld = rsWorld;
displaySwitcherAttempts = 0;
lastAttempt = Instant.now();
}
public void onGameTick() {
if (quickHopTargetWorld == null) return;
if (game.client().getWidget(WidgetInfo.WORLD_SWITCHER_LIST) == null) {
game.client().openWorldHopper();
if (++displaySwitcherAttempts >= 5) {
displaySwitcherAttempts = 0;
quickHopTargetWorld = null;
}
} else {
game.client().hopToWorld(quickHopTargetWorld);
quickHopTargetWorld = null;
}
}
}

View File

@ -0,0 +1,40 @@
package io.reisub.openosrs.util;
import java.util.ArrayList;
import java.util.List;
public abstract class ParentTask extends Task {
protected final List<Task> children = new ArrayList<>();
protected Task current;
@Override
public String getStatus() {
if (current != null) return current.getStatus();
return "";
}
public void addChildren(Task... children) {
this.children.addAll(List.of(children));
}
@Override
public boolean validate() {
for (Task t : children) {
if (t.validate()) {
current = t;
return true;
}
}
return false;
}
@Override
public void execute() {
if (current != null) {
current.execute();
current = null;
}
}
}

View File

@ -0,0 +1,70 @@
package io.reisub.openosrs.util;
import com.google.inject.Injector;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.plugins.iutils.api.Combat;
import net.runelite.client.plugins.iutils.api.Prayers;
import net.runelite.client.plugins.iutils.game.Game;
import net.runelite.client.plugins.iutils.ui.Bank;
import net.runelite.client.plugins.iutils.ui.Chatbox;
import net.runelite.client.plugins.iutils.ui.Equipment;
import net.runelite.client.plugins.iutils.walking.Walking;
import javax.inject.Inject;
import java.util.List;
@Slf4j
public abstract class Task {
@Inject
protected Game game;
@Inject
protected Injector injector;
@Inject
protected Calculations calc;
@Inject
protected Walking walking;
@Inject
protected Equipment equipment;
@Inject
protected Combat combat;
@Inject
protected Prayers prayers;
@Inject
protected Bank bank;
@Inject
protected Chatbox chatbox;
protected void log(String msg) {
log.info(msg);
}
protected void logTrace(String msg) {
log.trace(msg);
}
protected void logDebug(String msg) {
log.debug(msg);
}
protected void logWarn(String msg) {
log.warn(msg);
}
protected void logError(String msg) {
log.error(msg);
}
public abstract String getStatus();
public abstract boolean validate();
public abstract void execute();
}

View File

@ -0,0 +1,38 @@
package io.reisub.openosrs.util;
import com.google.inject.Provides;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.iutils.iUtils;
import org.pf4j.Extension;
import javax.inject.Singleton;
@Extension
@PluginDependency(iUtils.class)
@PluginDescriptor(
name = "Chaos Util",
description = "Utilities for Chaos scripts"
)
@Slf4j
@Singleton
public class Util extends Plugin {
@Provides
Config provideConfig(ConfigManager configManager)
{
return configManager.getConfig(Config.class);
}
@Override
protected void startUp() {
log.info(this.getName() + " started");
}
@Override
protected void shutDown() {
log.info(this.getName() + " stopped");
}
}

View File

@ -0,0 +1,6 @@
package io.reisub.openosrs.util.enums;
public enum Activity {
IDLE,
GLASSBLOWING;
}

View File

@ -0,0 +1,21 @@
package io.reisub.openosrs.util.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.ItemID;
@AllArgsConstructor
@Getter
public enum Log {
NORMAL(ItemID.LOGS),
OAK(ItemID.OAK_LOGS),
WILLOW(ItemID.WILLOW_LOGS),
TEAK(ItemID.TEAK_LOGS),
MAPLE(ItemID.MAPLE_LOGS),
MAHOGANY(ItemID.MAHOGANY_LOGS),
YEW(ItemID.YEW_LOGS),
MAGIC(ItemID.MAGIC_LOGS),
REDWOOD(ItemID.REDWOOD_LOGS);
private final int id;
}

View File

@ -0,0 +1,33 @@
package io.reisub.openosrs.util.tasks;
import io.reisub.openosrs.util.Task;
public class CutFoodForKitten extends Task {
@Override
public String getStatus() {
return "Cutting food for kitten";
}
@Override
public boolean validate() {
return KittenTask.handleKitten
&& !game.inventory().withName("Roe", "Raw karambwanji").exists()
&& game.inventory().withNamePart("Leaping").exists()
&& game.inventory().withName("Knife").exists();
}
@Override
public void execute() {
if (game.inventory().full()) {
game.inventory().withNamePart("Leaping").first().interact("Drop");
game.tick();
}
long count = game.inventory().withNamePart("Leaping").count();
game.inventory().withName("Knife").first().useOn(game.inventory().withNamePart("Leaping").first());
game.tick();
game.waitUntil(() -> game.inventory().withNamePart("Leaping").count() < count, 5);
}
}

View File

@ -0,0 +1,64 @@
package io.reisub.openosrs.util.tasks;
import io.reisub.openosrs.util.Task;
import net.runelite.api.Skill;
public class Eat extends Task {
private long last = 0;
private boolean wait = true;
private int threshold = 5;
private int mean = 5;
private int sigma = 1;
public void setInterval(int min, int max) {
mean = (min + max) / 2;
sigma = mean - min;
if (sigma <= 0) threshold = min;
threshold = getNewThreshold();
}
public void setWait(boolean wait) {
this.wait = wait;
}
@Override
public boolean validate() {
return game.modifiedLevel(Skill.HITPOINTS) <= threshold
&& game.inventory().withAction("Eat", "Drink").findAny().isPresent()
&& System.currentTimeMillis() > last + 1800;
}
@Override
public void execute() {
int hp = game.modifiedLevel(Skill.HITPOINTS);
game.inventory().withAction("Eat", "Drink").findFirst().ifPresent(inventoryItem -> {
if (inventoryItem.actions().contains("Eat")) {
inventoryItem.interact("Eat");
} else {
inventoryItem.interact("Drink");
}
last = System.currentTimeMillis();
});
if (wait) game.tick();
threshold = getNewThreshold();
if (wait) game.waitUntil(() -> hp < game.modifiedLevel(Skill.HITPOINTS), 10);
}
private int getNewThreshold() {
if (sigma <= 0) {
return threshold;
}
return calc.randomGauss(1, 99, sigma, mean, false);
}
@Override
public String getStatus() {
return "Eating";
}
}

View File

@ -0,0 +1,92 @@
package io.reisub.openosrs.util.tasks;
import io.reisub.openosrs.util.Task;
import net.runelite.client.plugins.iutils.game.InventoryItem;
import net.runelite.client.plugins.iutils.game.iNPC;
import net.runelite.client.plugins.iutils.ui.Chatbox;
import java.time.Duration;
import java.time.Instant;
public class HandleKitten extends Task {
private iNPC kitten;
private Instant lastAte;
private Instant lastStroke;
private int strokesDone;
@Override
public String getStatus() {
return "Feeding kitten";
}
@Override
public boolean validate() {
kitten = game.npcs().filter((npc) -> npc != null
&& npc.name() != null && npc.name().equals("Kitten")
&& npc.target() != null && npc.target().name() != null && npc.target().name().equals(game.localPlayer().name())
&& npc.actions() != null && npc.actions().contains("Pick-up")).nearest();
return KittenTask.handleKitten
&& kitten != null
&& game.inventory().withName("Roe", "Raw karambwanji").exists()
&& kitten.position().reachable(game.localPlayer().position());
}
@Override
public void execute() {
int count = getCount();
if (lastAte == null || Duration.between(lastAte, Instant.now()).getSeconds() > 60) {
game.inventory().withName("Roe", "Raw karambwanji").first().useOn(kitten);
game.tick();
if (!game.waitUntil(() -> getCount() < count && game.localPlayer().isIdle(), 10)) {
logWarn("Timed out trying to feed our kitten");
return;
}
lastAte = Instant.now();
}
if (lastStroke == null || Duration.between(lastStroke, Instant.now()).getSeconds() > 60) {
int strokesToDo = strokesDone == 0 ? 2 : 1;
for (int i = 0; i < strokesToDo; i++) {
kitten.interact("Interact");
game.tick();
if (!game.waitUntil(() -> chatbox.chatState().equals(Chatbox.ChatState.OPTIONS_CHAT), 10)) {
logWarn("Timed out trying to stroke our kitten");
return;
}
chatbox.chooseOption("Stroke");
game.tick();
if (!game.waitUntil(() -> chatbox.chatState().equals(Chatbox.ChatState.PLAYER_CHAT), 10)) {
logWarn("Timed out trying to stroke our kitten");
return;
}
strokesDone++;
}
if (strokesDone == 2) {
strokesDone = 0;
lastStroke = Instant.now();
}
}
KittenTask.handleKitten = false;
log("Finished taking care of our kitten");
}
private int getCount() {
long count = game.inventory().withName("Roe").count();
InventoryItem karambwanji = game.inventory().withName("Raw karambwanji").first();
if (karambwanji != null) {
count =+karambwanji.quantity();
}
return (int) count;
}
}

View File

@ -0,0 +1,28 @@
package io.reisub.openosrs.util.tasks;
import com.google.inject.Injector;
import io.reisub.openosrs.util.ParentTask;
import net.runelite.api.events.ChatMessage;
public class KittenTask extends ParentTask {
public static boolean handleKitten;
public static KittenTask getInstance(Injector injector) {
KittenTask instance = injector.getInstance(KittenTask.class);
instance.addChildren(
injector.getInstance(CutFoodForKitten.class),
injector.getInstance(HandleKitten.class),
injector.getInstance(PickupCat.class)
);
return instance;
}
public void onChatMessage(ChatMessage chatMessage) {
if (chatMessage.getMessage().contains("Your kitten wants attention.")
|| chatMessage.getMessage().contains("Your kitten is hungry.")) {
handleKitten = true;
}
}
}

View File

@ -0,0 +1,31 @@
package io.reisub.openosrs.util.tasks;
import io.reisub.openosrs.util.Task;
import net.runelite.client.plugins.iutils.game.iNPC;
public class PickupCat extends Task {
private iNPC cat;
@Override
public String getStatus() {
return "Picking up cat";
}
@Override
public boolean validate() {
cat = game.npcs().filter((npc) -> npc != null
&& npc.name() != null && npc.name().equals("Cat")
&& npc.target() != null && npc.target().name().equals(game.localPlayer().name())
&& npc.actions() != null && npc.actions().contains("Pick-up")).nearest();
return cat != null && !game.inventory().full();
}
@Override
public void execute() {
cat.interact("Pick-up");
game.tick();
game.waitUntil(() -> game.inventory().withName("Cat").exists(), 10);
}
}

View File

@ -0,0 +1,50 @@
package io.reisub.openosrs.util.tasks;
import io.reisub.openosrs.util.Task;
import net.runelite.client.plugins.iutils.walking.Walking;
import javax.inject.Inject;
public class Run extends Task {
@Inject
private Walking walking;
private int threshold = 90;
private int mean = 85;
private int sigma = 5;
public void setInterval(int min, int max) {
mean = (min + max) / 2;
sigma = mean - min;
if (sigma <= 0) threshold = min;
threshold = getNewThreshold();
}
@Override
public String getStatus() {
return "Enabling run";
}
@Override
public boolean validate() {
return !walking.isRunning() && game.energy() > threshold;
}
@Override
public void execute() {
walking.setRun(true);
game.tick();
threshold = getNewThreshold();
}
private int getNewThreshold() {
if (sigma <= 0) {
return threshold;
}
return calc.randomGauss(1, 99, sigma, mean, false);
}
}

47
util/util.gradle.kts Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
* 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.
*/
version = "1.0.0"
project.extra["PluginName"] = "Chaos Util"
project.extra["PluginDescription"] = "Utilities for Chaos scripts"
tasks {
jar {
manifest {
attributes(mapOf(
"Plugin-Version" to project.version,
"Plugin-Id" to nameToId(project.extra["PluginName"] as String),
"Plugin-Provider" to project.extra["PluginProvider"],
"Plugin-Description" to project.extra["PluginDescription"],
"Plugin-Dependencies" to
arrayOf(
nameToId("iUtils")
).joinToString(),
"Plugin-License" to project.extra["PluginLicense"]
))
}
}
}