Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.runelite.client.plugins.microbot.leaguestoolkit;

public enum AntiAfkMethod {
RANDOM_ARROW_KEY,
BACKSPACE,
CAMERA_ROTATION
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package net.runelite.client.plugins.microbot.leaguestoolkit;

import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigInformation;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.ConfigSection;
import net.runelite.client.config.Range;

@ConfigGroup("LeaguesToolkit")
@ConfigInformation("<h2>Leagues Toolkit</h2>" +
"<h3>Version: " + LeaguesToolkitPlugin.version + "</h3>" +
"<p>A grab-bag of Leagues-focused utilities. Start with <strong>Anti-AFK</strong> to keep long, " +
"auto-banking skilling sessions from getting logged out.</p>")
public interface LeaguesToolkitConfig extends Config {

@ConfigSection(
name = "Anti-AFK",
description = "Prevents the idle-timeout logout during long AFK sessions",
position = 0
)
String antiAfkSection = "antiAfkSection";

@ConfigItem(
keyName = "enableAntiAfk",
name = "Enable anti-AFK",
description = "Periodically triggers input to reset the idle timer so you never get logged out",
position = 0,
section = antiAfkSection
)
default boolean enableAntiAfk() {
return true;
}

@ConfigItem(
keyName = "antiAfkMethod",
name = "Input method",
description = "What kind of input to send. Random arrow keys look most natural.",
position = 1,
section = antiAfkSection
)
default AntiAfkMethod antiAfkMethod() {
return AntiAfkMethod.RANDOM_ARROW_KEY;
}

@Range(min = 50, max = 5000)
@ConfigItem(
keyName = "antiAfkBufferMin",
name = "Trigger buffer min (ticks)",
description = "Minimum ticks before the client's AFK threshold at which to fire input",
position = 2,
section = antiAfkSection
)
default int antiAfkBufferMin() {
return 500;
}

@Range(min = 50, max = 5000)
@ConfigItem(
keyName = "antiAfkBufferMax",
name = "Trigger buffer max (ticks)",
description = "Maximum ticks before the client's AFK threshold at which to fire input",
position = 3,
section = antiAfkSection
)
default int antiAfkBufferMax() {
return 1500;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.runelite.client.plugins.microbot.leaguestoolkit;

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.PluginDescriptor;
import net.runelite.client.plugins.microbot.PluginConstants;

import javax.inject.Inject;

@PluginDescriptor(
name = PluginConstants.DV + "Leagues Toolkit",
description = "Quality-of-life utilities for Leagues (anti-AFK, and more to come)",
tags = {"leagues", "microbot", "utility", "afk"},
version = LeaguesToolkitPlugin.version,
minClientVersion = "2.0.13",
enabledByDefault = PluginConstants.DEFAULT_ENABLED,
isExternal = PluginConstants.IS_EXTERNAL
)
@Slf4j
public class LeaguesToolkitPlugin extends Plugin {
public static final String version = "1.0.0";

@Inject
private LeaguesToolkitConfig config;

@Inject
private LeaguesToolkitScript leaguesToolkitScript;

@Provides
LeaguesToolkitConfig provideConfig(ConfigManager configManager) {
return configManager.getConfig(LeaguesToolkitConfig.class);
}

@Override
protected void startUp() {
leaguesToolkitScript.run(config);
}

@Override
protected void shutDown() {
leaguesToolkitScript.shutdown();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package net.runelite.client.plugins.microbot.leaguestoolkit;

import lombok.extern.slf4j.Slf4j;
import net.runelite.client.plugins.microbot.Microbot;
import net.runelite.client.plugins.microbot.Script;
import net.runelite.client.plugins.microbot.util.camera.Rs2Camera;
import net.runelite.client.plugins.microbot.util.keyboard.Rs2Keyboard;
import net.runelite.client.plugins.microbot.util.math.Rs2Random;
import net.runelite.client.plugins.microbot.util.player.Rs2Player;

import java.awt.event.KeyEvent;
import java.util.concurrent.TimeUnit;

@Slf4j
public class LeaguesToolkitScript extends Script {

private static final int[] ARROW_KEYS = {
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_UP, KeyEvent.VK_DOWN
};

public boolean run(LeaguesToolkitConfig config) {
mainScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> {
try {
if (!super.run()) return;
if (!Microbot.isLoggedIn()) return;

if (config.enableAntiAfk()) {
runAntiAfk(config);
}
} catch (Exception ex) {
log.error("LeaguesToolkitScript loop error", ex);
}
}, 0, 1000, TimeUnit.MILLISECONDS);
return true;
}

private void runAntiAfk(LeaguesToolkitConfig config) {
int minBuffer = Math.min(config.antiAfkBufferMin(), config.antiAfkBufferMax());
int maxBuffer = Math.max(config.antiAfkBufferMin(), config.antiAfkBufferMax());
long buffer = Rs2Random.between(minBuffer, maxBuffer);

if (!Rs2Player.checkIdleLogout(buffer)) return;

switch (config.antiAfkMethod()) {
case BACKSPACE:
Rs2Keyboard.keyPress(KeyEvent.VK_BACK_SPACE);
break;
case CAMERA_ROTATION:
Rs2Camera.setYaw(Rs2Random.between(0, 2047));
break;
case RANDOM_ARROW_KEY:
default:
Rs2Keyboard.keyPress(ARROW_KEYS[Rs2Random.between(0, ARROW_KEYS.length - 1)]);
break;
}
}

@Override
public void shutdown() {
super.shutdown();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Leagues Toolkit

Quality-of-life utilities for OSRS Leagues.

## Features

### Anti-AFK
Prevents the idle-timeout logout during long AFK skilling sessions (e.g. mining with the auto-bank relic where inventory never fills and no interaction happens between rock respawns). Periodically triggers a configurable input right before the client's AFK threshold so the session stays alive indefinitely.

Configurable:
- **Input method** — random arrow key (default, most natural), backspace, or camera yaw rotation
- **Trigger buffer min/max** — how many ticks before the idle-timeout to fire input (randomized between min and max)

## Roadmap

More Leagues-focused utilities planned. Open an issue or PR with ideas.
Loading