mirror of
https://github.com/bdnugget/IdleRSC.git
synced 2026-11-07 07:57:27 +00:00
* Adds patcher and core openrsc client the IdleRSC project * app = idlersc app files * client = openrsc client * patcher = idlersc patcher "* Fix CLI due to input causing the program to crash on startup. * Fix transitive dependency spitting out an error on [startup](https://www.slf4j.org/codes.html#StaticLoggerBinder). * Fix `.editorconfig` causing IDE formatting to clash with spotless' preferred formatting. * Fix typo in debugger button. (This isn't 100% fixed, I'll investigate later.) * Fix infinite looping bug when the cache creation window is exited. * Add more documentation. * Add `patcher` and `client` subprojects. * Add `run` task to gradle for development/debugging purposes. This can be invoked via IDE or command line using the gradle wrapper. Bonus - args can be passed via the gradle --args option. For example, `./gradlew run --args='--auto-login --username username --password password --init-cache coleslaw'` * Move main project to `app` subproject due to shared dependencies. * ~~Bump JDK required to 11.~~ Keeping minimum required JDK at 8. * Add convenience scripts to update code shared from `core` repository. * Played musical chairs with level 3 chickens. Spoiler: I lost, every time."
1209 lines
39 KiB
Java
1209 lines
39 KiB
Java
package bot;
|
|
|
|
import static org.reflections.scanners.Scanners.Resources;
|
|
import static org.reflections.scanners.Scanners.SubTypes;
|
|
import static org.reflections.util.ClasspathHelper.forJavaClassPath;
|
|
|
|
import bot.cli.CLIParser;
|
|
import bot.cli.ParseResult;
|
|
import bot.debugger.Debugger;
|
|
import callbacks.DrawCallback;
|
|
import compatibility.apos.Script;
|
|
import controller.Controller;
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.net.MalformedURLException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.util.*;
|
|
import java.util.AbstractMap.SimpleEntry;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Stream;
|
|
import javax.swing.*;
|
|
import javax.swing.event.DocumentEvent;
|
|
import javax.swing.event.DocumentListener;
|
|
import javax.swing.table.DefaultTableModel;
|
|
import javax.swing.table.TableRowSorter;
|
|
import listeners.LoginListener;
|
|
import listeners.WindowListener;
|
|
import org.apache.commons.cli.ParseException;
|
|
import org.reflections.Reflections;
|
|
import org.reflections.util.ConfigurationBuilder;
|
|
import org.reflections.util.FilterBuilder;
|
|
import orsc.OpenRSC;
|
|
import orsc.mudclient;
|
|
import reflector.Reflector;
|
|
import scripting.idlescript.IdleScript;
|
|
import utils.Version;
|
|
|
|
/**
|
|
* This is the starting class of the entire IdleRSC project.
|
|
*
|
|
* @author Dvorak
|
|
*/
|
|
public class Main {
|
|
public static Config config = new Config();
|
|
private static final Reflections reflections =
|
|
new Reflections(
|
|
new ConfigurationBuilder()
|
|
.setScanners(SubTypes, Resources)
|
|
.addUrls(forJavaClassPath())
|
|
.filterInputsBy(new FilterBuilder()));
|
|
private static final Map<String, List<Class<?>>> scripts =
|
|
Stream.of(
|
|
new SimpleEntry<>("Native", reflections.getSubTypesOf(IdleScript.class)),
|
|
new SimpleEntry<>("APOS", reflections.getSubTypesOf(compatibility.apos.Script.class)),
|
|
new SimpleEntry<>("SBot", reflections.getSubTypesOf(compatibility.sbot.Script.class)))
|
|
.collect(Collectors.toMap(SimpleEntry::getKey, e -> new ArrayList<>(e.getValue())));
|
|
// this is tied to the start/stop button on the side panel.
|
|
private static Color themeTextColor = new java.awt.Color(219, 219, 219, 255);
|
|
private static Color themeBackColor = new java.awt.Color(40, 40, 40, 255);
|
|
private static boolean isRunning = false;
|
|
private static String username = "";
|
|
private static String themeName = "RuneDark Theme";
|
|
private static JMenuBar menuBar;
|
|
private static JMenu themeMenu, settingsMenu;
|
|
private static JFrame scriptFrame; // all the windows.
|
|
private static JButton startStopButton, buttonClear;
|
|
private static JCheckBox autoLoginCheckbox,
|
|
logWindowCheckbox,
|
|
debugCheckbox,
|
|
graphicsCheckbox,
|
|
botPaintCheckbox,
|
|
interlaceCheckbox,
|
|
autoscrollLogsCheckbox,
|
|
sidebarCheckbox,
|
|
gfxCheckbox; // all the checkboxes on the sidepanel.
|
|
private static JButton loadScriptButton,
|
|
pathwalkerButton,
|
|
takeScreenshotButton,
|
|
showIdButton,
|
|
openDebuggerButton,
|
|
resetXpButton;
|
|
private static JTextArea logArea; // self explanatory
|
|
private static JScrollPane scroller; // this is the main window for the log.
|
|
private static Debugger debugger = null;
|
|
private static Thread loginListener = null; // see LoginListener.java
|
|
private static final Thread positionListener = null; // see PositionListener.java
|
|
private static Thread windowListener = null; // see WindowListener.java
|
|
private static final Thread messageListener = null; // see MessageListener.java
|
|
private static Thread debuggerThread = null;
|
|
private static Controller controller =
|
|
null; // this is the queen bee that controls the actual bot and is the native scripting
|
|
// language.
|
|
private static Object currentRunningScript =
|
|
null; // the object instance of the current running script.
|
|
|
|
private static boolean shouldFilter = true;
|
|
private static boolean aposInitCalled = false;
|
|
|
|
// themeNames and colorCodes MUST have the same index values
|
|
// todo hash map
|
|
private static final String[] themeNames = {
|
|
"RuneDark Theme",
|
|
"2007scape Theme",
|
|
"Classic Theme",
|
|
"Purple Theme",
|
|
"Magenta Theme",
|
|
"Red Theme",
|
|
"Aquamarine Theme",
|
|
"Blue Theme",
|
|
"Green Theme",
|
|
"Brown Theme",
|
|
"Orange Theme",
|
|
"Gold Theme"
|
|
};
|
|
private static final Color[][] colorCodes = { // {background, text color, log color}
|
|
{
|
|
new java.awt.Color(40, 40, 40, 255), // Runelite Dark Mode
|
|
new java.awt.Color(219, 219, 219, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(194, 177, 144, 255), // 2007scape Theme
|
|
new java.awt.Color(10, 10, 8, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(91, 100, 128, 255), // Classic Theme
|
|
new java.awt.Color(0, 0, 0, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(41, 21, 72, 255), // Purple Theme
|
|
new java.awt.Color(209, 186, 255, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(141, 22, 129, 255), // Magenta Theme
|
|
new java.awt.Color(255, 217, 255, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(110, 0, 16, 255), // Red Theme
|
|
new java.awt.Color(255, 183, 195, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(11, 143, 137, 255), // Aquamarine Theme
|
|
new java.awt.Color(210, 255, 255, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(22, 65, 182, 255), // Blue Theme
|
|
new java.awt.Color(191, 208, 255, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(9, 94, 0, 255), // Green Theme
|
|
new java.awt.Color(195, 255, 187, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(73, 48, 48, 255), // Brown Theme
|
|
new java.awt.Color(234, 202, 202, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(159, 58, 0, 255), // Orange Theme
|
|
new java.awt.Color(255, 202, 188, 255)
|
|
},
|
|
{
|
|
new java.awt.Color(141, 113, 22, 255), // Gold Theme
|
|
new java.awt.Color(255, 254, 200, 255)
|
|
}
|
|
};
|
|
|
|
public static Color getThemeTextColor() {
|
|
return themeTextColor;
|
|
}
|
|
|
|
public static void setThemeTextColor(Color textColor) {
|
|
themeTextColor = textColor;
|
|
}
|
|
|
|
public static Color getThemeBackColor() {
|
|
return themeBackColor;
|
|
}
|
|
|
|
public static void setThemeBackColor(Color backColor) {
|
|
themeBackColor = backColor;
|
|
}
|
|
|
|
public static Color getColorCode(int x, int y) {
|
|
return colorCodes[x][y];
|
|
}
|
|
/**
|
|
* Set the Color elements for the Theme name entered Changes themeColorBack and themeTextColor
|
|
*
|
|
* @param theme String -- name of the "Theme"
|
|
*/
|
|
public static void setThemeElements(String theme) {
|
|
for (int i = 0; i < themeNames.length; i++) {
|
|
if (themeNames[i].equals(theme)) {
|
|
themeBackColor = colorCodes[i][0];
|
|
themeTextColor = colorCodes[i][1];
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the Color[] for the Theme name entered
|
|
*
|
|
* @param theme String -- name of the "Theme"
|
|
* @return Color[] -- with values [back, front]
|
|
*/
|
|
public static Color[] getThemeElements(String theme) {
|
|
for (int i = 0; i < themeNames.length; i++) {
|
|
if (themeNames[i].equals(theme)) {
|
|
return colorCodes[i];
|
|
}
|
|
}
|
|
return new Color[] {Color.BLACK, Color.WHITE};
|
|
}
|
|
|
|
public static Object getCurrentRunningScript() {
|
|
return currentRunningScript;
|
|
}
|
|
|
|
/** The initial program entrypoint for IdleRSC. */
|
|
public static void main(String[] args)
|
|
throws MalformedURLException, ClassNotFoundException, NoSuchMethodException,
|
|
SecurityException, InstantiationException, IllegalAccessException,
|
|
IllegalArgumentException, InvocationTargetException, InterruptedException {
|
|
CLIParser parser = new CLIParser();
|
|
Version version = new Version();
|
|
ParseResult parseResult = new ParseResult();
|
|
new EntryFrame();
|
|
setThemeElements(themeName);
|
|
try {
|
|
parseResult = parser.parse(args);
|
|
} catch (ParseException e) {
|
|
System.err.println(e.getMessage() + "\n");
|
|
parser.printHelp();
|
|
System.out.println("Waiting for 5 minute...");
|
|
Thread.sleep(340000);
|
|
System.out.println("Closing Bot in 1 minute...");
|
|
Thread.sleep(60000);
|
|
System.exit(1);
|
|
}
|
|
|
|
if (parseResult.isHelp()) {
|
|
parser.printHelp();
|
|
System.out.println("Waiting for 1 minute...");
|
|
Thread.sleep(60000);
|
|
System.out.println("Launching Bot...");
|
|
}
|
|
|
|
if (parseResult.isVersion()) {
|
|
System.out.println(
|
|
"IdleRSC version "
|
|
+ version.getCommitDate()
|
|
+ "-"
|
|
+ version.getCommitCount()
|
|
+ "-"
|
|
+ version.getCommitHash());
|
|
System.out.println("Built with JDK " + version.getBuildJDK());
|
|
System.exit(0);
|
|
}
|
|
|
|
config.absorb(parseResult);
|
|
// handleCache(config);
|
|
|
|
Reflector reflector = new Reflector(); // start up our reflector helper
|
|
OpenRSC client = reflector.createClient(); // start up our client jar
|
|
mudclient mud = reflector.getMud(client); // grab the mud from the client
|
|
|
|
controller = new Controller(reflector, client, mud); // start up our controller
|
|
debugger = new Debugger(reflector, client, mud, controller);
|
|
debuggerThread = new Thread(debugger);
|
|
debuggerThread.start();
|
|
|
|
// just building out the windows
|
|
JComponent botFrame = new JPanel();
|
|
themeMenu = new JMenu();
|
|
JPanel consoleFrame = new JPanel(); // log window
|
|
JFrame rscFrame = (JFrame) reflector.getClassMember("orsc.OpenRSC", "jframe");
|
|
if (config.getUsername() != null) {
|
|
scriptFrame = new JFrame(config.getUsername() + "'s Script Selector");
|
|
} else if (controller.getPlayerName() != null) {
|
|
scriptFrame = new JFrame(controller.getPlayerName() + "'s Script Selector");
|
|
} else {
|
|
scriptFrame = new JFrame("Script Selector");
|
|
}
|
|
|
|
initializeBotFrame(botFrame);
|
|
initializeConsoleFrame(consoleFrame);
|
|
initializeScriptFrame(scriptFrame);
|
|
initializeMenuBar();
|
|
|
|
JButton[] buttonArray = {
|
|
startStopButton,
|
|
loadScriptButton,
|
|
pathwalkerButton,
|
|
takeScreenshotButton,
|
|
showIdButton,
|
|
openDebuggerButton,
|
|
resetXpButton
|
|
};
|
|
JCheckBox[] checkBoxArray = {
|
|
autoLoginCheckbox,
|
|
logWindowCheckbox,
|
|
debugCheckbox,
|
|
graphicsCheckbox,
|
|
botPaintCheckbox,
|
|
interlaceCheckbox,
|
|
sidebarCheckbox,
|
|
gfxCheckbox
|
|
};
|
|
Dimension buttonSize = new Dimension(125, 25);
|
|
// todo swap side bar by swapping container contents
|
|
for (JCheckBox jCheckbox : checkBoxArray) {
|
|
jCheckbox.setBackground(themeBackColor);
|
|
jCheckbox.setForeground(themeTextColor);
|
|
jCheckbox.setFocusable(false);
|
|
}
|
|
for (JButton jButton : buttonArray) {
|
|
jButton.setBackground(themeBackColor.darker());
|
|
jButton.setForeground(themeTextColor);
|
|
jButton.setFocusable(false);
|
|
jButton.setMaximumSize(buttonSize);
|
|
jButton.setPreferredSize(buttonSize);
|
|
}
|
|
|
|
botFrame.setBackground(themeBackColor);
|
|
rscFrame.getContentPane().setBackground(themeBackColor);
|
|
botFrame.setBorder(BorderFactory.createLineBorder(themeBackColor));
|
|
|
|
// combine everything into our client
|
|
rscFrame.add(botFrame, BorderLayout.EAST);
|
|
rscFrame.add(menuBar, BorderLayout.NORTH);
|
|
rscFrame.add(consoleFrame, BorderLayout.SOUTH);
|
|
consoleFrame.setVisible(config.isLogWindowVisible());
|
|
botFrame.setVisible(config.isSidebarVisible());
|
|
|
|
if (config.getUsername() != null) {
|
|
log("Starting client for " + config.getUsername());
|
|
}
|
|
log("IdleRSC initialized.");
|
|
|
|
// don't do anything until RSC is loaded.
|
|
while (!controller.isLoaded()) controller.sleep(1);
|
|
|
|
// Set Sizes After initilizing for correct sizing
|
|
rscFrame.setMinimumSize(new Dimension(533, 405)); // this doesn't seem to be doing anything
|
|
rscFrame.setSize(new Dimension(533, 405));
|
|
if (config.isLogWindowVisible())
|
|
rscFrame.setSize(new Dimension(rscFrame.getWidth(), rscFrame.getHeight() + 188));
|
|
if (config.isSidebarVisible())
|
|
rscFrame.setSize(new Dimension(rscFrame.getWidth() + 122, rscFrame.getHeight()));
|
|
|
|
// Set checkboxes on side panel using "get" methods
|
|
logWindowCheckbox.setSelected(config.isLogWindowVisible());
|
|
sidebarCheckbox.setSelected(config.isSidebarVisible());
|
|
debugCheckbox.setSelected(config.isDebug());
|
|
botPaintCheckbox.setSelected(config.isBotPaintVisible());
|
|
interlaceCheckbox.setSelected(config.isGraphicsInterlacingEnabled());
|
|
|
|
if (config.isGraphicsInterlacingEnabled()) {
|
|
controller.setInterlacer(config.isGraphicsInterlacingEnabled());
|
|
}
|
|
if (config.isScriptSelectorOpen()) {
|
|
showLoadScript();
|
|
}
|
|
|
|
if (config.isDebug()) debugger.open();
|
|
|
|
if (config.getScriptName() != null && !config.getScriptName().isEmpty()) {
|
|
if (!loadAndRunScript(config.getScriptName())) {
|
|
System.out.println("Could not find script: " + config.getScriptName());
|
|
} else {
|
|
isRunning = true;
|
|
startStopButton.setText("Stop");
|
|
}
|
|
}
|
|
|
|
autoLoginCheckbox.setSelected(config.isAutoLogin());
|
|
graphicsCheckbox.setSelected(config.isGraphicsEnabled());
|
|
gfxCheckbox.setSelected(config.isGraphicsEnabled());
|
|
// start up our listener threads
|
|
log("Initializing LoginListener...");
|
|
loginListener = new Thread(new LoginListener(controller));
|
|
loginListener.start();
|
|
log("LoginListener initialized.");
|
|
|
|
log("Initializing WindowListener...");
|
|
windowListener =
|
|
new Thread(
|
|
new WindowListener(
|
|
botFrame,
|
|
consoleFrame,
|
|
rscFrame,
|
|
settingsMenu,
|
|
themeMenu,
|
|
menuBar,
|
|
scroller,
|
|
logArea,
|
|
controller,
|
|
buttonClear,
|
|
autoscrollLogsCheckbox,
|
|
buttonArray,
|
|
checkBoxArray));
|
|
windowListener.start();
|
|
log("WindowListener started.");
|
|
|
|
// give everything a nice synchronization break juuuuuuuuuuuuuust in case...
|
|
Thread.sleep(3000);
|
|
|
|
if (!config.isGraphicsEnabled()) {
|
|
if (controller != null) {
|
|
controller.setDrawing(config.isGraphicsEnabled());
|
|
if (config.isGraphicsEnabled()) DrawCallback.setNextRefresh(-1);
|
|
else DrawCallback.setNextRefresh(System.currentTimeMillis() + 30000L);
|
|
}
|
|
}
|
|
while (true) {
|
|
if (isRunning()) {
|
|
if (currentRunningScript != null) {
|
|
|
|
// handle native scripts
|
|
if (currentRunningScript instanceof IdleScript) {
|
|
((IdleScript) currentRunningScript).setController(controller);
|
|
int sleepAmount =
|
|
((IdleScript) currentRunningScript).start(config.getScriptArguments()) + 1;
|
|
Thread.sleep(sleepAmount);
|
|
} else if (currentRunningScript instanceof compatibility.sbot.Script) {
|
|
controller.displayMessage(
|
|
"@red@IdleRSC: Note that SBot scripts are mostly, but not fully compatible.", 3);
|
|
controller.displayMessage(
|
|
"@red@IdleRSC: If you still experience problems after modifying script please report.",
|
|
3);
|
|
((compatibility.sbot.Script) currentRunningScript).setController(controller);
|
|
|
|
String sbotScriptName = config.getScriptName();
|
|
((compatibility.sbot.Script) currentRunningScript)
|
|
.start(sbotScriptName, config.getScriptArguments());
|
|
|
|
Thread.sleep(618); // wait 1 tick before performing next action
|
|
} else if (currentRunningScript instanceof compatibility.apos.Script) {
|
|
if (!controller.isSleeping()) {
|
|
StringBuilder params = new StringBuilder();
|
|
|
|
if (config.getScriptArguments() != null) {
|
|
for (int i = 0; i < config.getScriptArguments().length; i++) {
|
|
String arg = config.getScriptArguments()[i];
|
|
if (i == 0) params = new StringBuilder(arg);
|
|
else params.append(" ").append(arg);
|
|
}
|
|
}
|
|
|
|
if (!aposInitCalled) {
|
|
Script.setController(controller);
|
|
((compatibility.apos.Script) currentRunningScript).init(params.toString());
|
|
aposInitCalled = true;
|
|
}
|
|
|
|
int sleepAmount = ((compatibility.apos.Script) currentRunningScript).main() + 1;
|
|
Thread.sleep(sleepAmount);
|
|
} else {
|
|
Thread.sleep(10);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
aposInitCalled = false;
|
|
Thread.sleep(100);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Clears the log window. */
|
|
public static void clearLog() {
|
|
logArea.setText("");
|
|
}
|
|
|
|
/**
|
|
* Add a line to the log window.
|
|
*
|
|
* @param text
|
|
*/
|
|
public static void log(String text) {
|
|
System.out.println(text);
|
|
if (logArea == null) {
|
|
return; // messages will still add text if element isVisible is false.
|
|
}
|
|
|
|
logArea.append(text + "\n");
|
|
|
|
if (autoscrollLogsCheckbox.isSelected()) {
|
|
logArea.setCaretPosition(logArea.getDocument().getLength());
|
|
}
|
|
}
|
|
/**
|
|
* For logging function calls in an easy manner.
|
|
*
|
|
* @param method -- the method called.
|
|
* @param params -- the object(s) which were sent to the function. You may put in any object.
|
|
*/
|
|
public static void logMethod(String method, Object... params) {
|
|
if (isDebug()) {
|
|
StringBuilder current = new StringBuilder(method + "(");
|
|
|
|
if (params != null && params.length > 0) {
|
|
for (Object o : params) {
|
|
current.append(o.toString()).append(", ");
|
|
}
|
|
|
|
current = new StringBuilder(current.substring(0, current.length() - 2));
|
|
}
|
|
|
|
current.append(")");
|
|
|
|
log(current.toString());
|
|
}
|
|
}
|
|
|
|
private static void initializeMenuBar() {
|
|
int[] keyEvents = {
|
|
KeyEvent.VK_1,
|
|
KeyEvent.VK_2,
|
|
KeyEvent.VK_3,
|
|
KeyEvent.VK_4,
|
|
KeyEvent.VK_5,
|
|
KeyEvent.VK_6,
|
|
KeyEvent.VK_7,
|
|
KeyEvent.VK_8,
|
|
KeyEvent.VK_9,
|
|
KeyEvent.VK_0,
|
|
KeyEvent.VK_F1,
|
|
KeyEvent.VK_F2,
|
|
KeyEvent.VK_F3,
|
|
KeyEvent.VK_F5,
|
|
};
|
|
// Make the menu bar
|
|
menuBar = new JMenuBar();
|
|
settingsMenu = new JMenu("Settings");
|
|
themeMenu = new JMenu("Theme Menu");
|
|
gfxCheckbox = new JCheckBox("GFX");
|
|
logWindowCheckbox = new JCheckBox("Console");
|
|
sidebarCheckbox = new JCheckBox("Sidebar");
|
|
|
|
menuBar.add(settingsMenu);
|
|
menuBar.add(themeMenu);
|
|
menuBar.add(Box.createHorizontalGlue());
|
|
menuBar.add(gfxCheckbox);
|
|
menuBar.add(logWindowCheckbox);
|
|
menuBar.add(sidebarCheckbox);
|
|
menuBar.setFocusable(false);
|
|
gfxCheckbox.setFocusable(false);
|
|
logWindowCheckbox.setFocusable(false);
|
|
sidebarCheckbox.setFocusable(false);
|
|
|
|
// style our elements
|
|
settingsMenu.setBackground(themeBackColor);
|
|
settingsMenu.setBorder(BorderFactory.createLineBorder(themeBackColor));
|
|
settingsMenu.setForeground(themeTextColor);
|
|
themeMenu.setForeground(themeTextColor);
|
|
menuBar.setBackground(themeBackColor);
|
|
menuBar.setBorder(BorderFactory.createLineBorder(themeBackColor));
|
|
|
|
gfxCheckbox.addActionListener(
|
|
e -> {
|
|
if (controller != null) {
|
|
graphicsCheckbox.setSelected(gfxCheckbox.isSelected());
|
|
controller.setDrawing(gfxCheckbox.isSelected());
|
|
if (gfxCheckbox.isSelected()) DrawCallback.setNextRefresh(-1);
|
|
else DrawCallback.setNextRefresh(System.currentTimeMillis() + 30000L);
|
|
}
|
|
});
|
|
|
|
// Build Theme Menu
|
|
JMenuItem menuItem;
|
|
for (int i = 0; i < themeNames.length; i++) {
|
|
menuItem = new JMenuItem(themeNames[i], keyEvents[i]);
|
|
menuItem.setAccelerator(KeyStroke.getKeyStroke((char) keyEvents[i]));
|
|
int finalI = i;
|
|
menuItem.addActionListener(
|
|
e -> {
|
|
themeName = themeNames[finalI];
|
|
});
|
|
themeMenu.add(menuItem);
|
|
}
|
|
|
|
menuItem = new JMenuItem("Account Startup Settings", KeyEvent.VK_F4); // s
|
|
menuItem.setAccelerator(KeyStroke.getKeyStroke((char) KeyEvent.VK_F4));
|
|
menuItem.addActionListener(
|
|
e -> {
|
|
AuthFrame authFrame =
|
|
new AuthFrame("Editing the account - " + config.getUsername(), null, null);
|
|
authFrame.setLoadSettings(true);
|
|
authFrame.addActionListener(
|
|
e1 -> { // ALWAYS make properties lowercase
|
|
username = authFrame.getUsername();
|
|
System.out.println("username " + username);
|
|
authFrame.storeAuthData(authFrame);
|
|
authFrame.setVisible(false);
|
|
});
|
|
authFrame.setVisible(true);
|
|
});
|
|
settingsMenu.add(menuItem);
|
|
}
|
|
/**
|
|
* Sets up the sidepanel
|
|
*
|
|
* @param botFrame -- the sidepanel frame
|
|
*/
|
|
private static void initializeBotFrame(JComponent botFrame) {
|
|
botFrame.setLayout(new BoxLayout(botFrame, BoxLayout.Y_AXIS));
|
|
|
|
startStopButton = new JButton(isRunning ? "Stop" : "Start");
|
|
|
|
autoLoginCheckbox = new JCheckBox("Auto-Login");
|
|
debugCheckbox = new JCheckBox("Debug Messages");
|
|
graphicsCheckbox = new JCheckBox("Show Graphics");
|
|
botPaintCheckbox = new JCheckBox("Show Bot Paint");
|
|
interlaceCheckbox = new JCheckBox("Interlace");
|
|
loadScriptButton = new JButton("Load Script");
|
|
pathwalkerButton = new JButton("PathWalker");
|
|
// all the buttons on the sidepanel.
|
|
takeScreenshotButton = new JButton("Screenshot");
|
|
showIdButton = new JButton("Show ID's");
|
|
openDebuggerButton = new JButton("Debugger");
|
|
resetXpButton = new JButton("Reset XP");
|
|
|
|
startStopButton.addActionListener(
|
|
e -> {
|
|
isRunning = !isRunning;
|
|
if (isRunning) {
|
|
startStopButton.setText("Stop");
|
|
} else {
|
|
startStopButton.setText("Start");
|
|
}
|
|
});
|
|
|
|
loadScriptButton.addActionListener(e -> showLoadScript());
|
|
|
|
pathwalkerButton.addActionListener(
|
|
e -> {
|
|
if (!isRunning) {
|
|
loadAndRunScript("PathWalker");
|
|
config.setScriptArguments(new String[] {""});
|
|
isRunning = true;
|
|
startStopButton.setText("Stop");
|
|
} else {
|
|
JOptionPane.showMessageDialog(null, "Stop the current script first.");
|
|
}
|
|
});
|
|
|
|
openDebuggerButton.addActionListener(
|
|
e -> {
|
|
controller.log("opening debug window");
|
|
debugger.open();
|
|
});
|
|
resetXpButton.addActionListener(e -> DrawCallback.resetXpCounter());
|
|
showIdButton.addActionListener(e -> controller.toggleViewId());
|
|
takeScreenshotButton.addActionListener(e -> controller.takeScreenshot(""));
|
|
graphicsCheckbox.addActionListener(
|
|
e -> {
|
|
if (controller != null) {
|
|
gfxCheckbox.setSelected(graphicsCheckbox.isSelected());
|
|
controller.setDrawing(graphicsCheckbox.isSelected());
|
|
if (graphicsCheckbox.isSelected()) DrawCallback.setNextRefresh(-1);
|
|
else DrawCallback.setNextRefresh(System.currentTimeMillis() + 30000L);
|
|
}
|
|
});
|
|
botPaintCheckbox.addActionListener(
|
|
e -> {
|
|
if (controller != null) {
|
|
controller.setBotPaint(botPaintCheckbox.isSelected());
|
|
}
|
|
});
|
|
interlaceCheckbox.addActionListener(
|
|
e -> {
|
|
if (controller != null) {
|
|
controller.setInterlacer(interlaceCheckbox.isSelected());
|
|
}
|
|
});
|
|
|
|
Dimension buttonSize = new Dimension(125, 25);
|
|
|
|
botFrame.add(startStopButton);
|
|
botFrame.add(loadScriptButton);
|
|
botFrame.add(pathwalkerButton);
|
|
botFrame.add(autoLoginCheckbox);
|
|
botFrame.add(debugCheckbox);
|
|
botFrame.add(interlaceCheckbox);
|
|
botFrame.add(botPaintCheckbox);
|
|
botFrame.add(graphicsCheckbox);
|
|
botFrame.add(takeScreenshotButton);
|
|
botFrame.add(showIdButton);
|
|
botFrame.add(openDebuggerButton);
|
|
botFrame.add(resetXpButton);
|
|
|
|
botFrame.setSize(buttonSize.width, botFrame.getHeight());
|
|
}
|
|
|
|
/**
|
|
* Sets up the log window
|
|
*
|
|
* @param consoleFrame -- the log window frame
|
|
*/
|
|
private static void initializeConsoleFrame(JPanel consoleFrame) {
|
|
buttonClear = new JButton("Clear");
|
|
autoscrollLogsCheckbox = new JCheckBox("Lock scroll to bottom", true);
|
|
|
|
logArea = new JTextArea(9, 44);
|
|
logArea.setEditable(false);
|
|
scroller = new JScrollPane(logArea);
|
|
|
|
buttonClear.setBackground(themeBackColor.darker());
|
|
buttonClear.setForeground(themeTextColor);
|
|
autoscrollLogsCheckbox.setBackground(themeBackColor);
|
|
autoscrollLogsCheckbox.setForeground(themeTextColor);
|
|
logArea.setBackground(themeBackColor.brighter());
|
|
logArea.setForeground(themeTextColor);
|
|
scroller.setBackground(themeBackColor);
|
|
scroller.setForeground(themeTextColor);
|
|
|
|
consoleFrame.setBackground(themeBackColor);
|
|
consoleFrame.setForeground(themeTextColor);
|
|
|
|
consoleFrame.setLayout(new GridBagLayout());
|
|
|
|
GridBagConstraints constraints = new GridBagConstraints();
|
|
|
|
constraints.gridy = 1;
|
|
constraints.insets = new Insets(5, 5, 5, 5);
|
|
constraints.anchor = GridBagConstraints.SOUTHEAST;
|
|
constraints.gridx = 2;
|
|
constraints.weightx = 0.5;
|
|
consoleFrame.add(autoscrollLogsCheckbox, constraints);
|
|
|
|
constraints.gridy = 1;
|
|
constraints.insets = new Insets(0, 5, 5, 5);
|
|
constraints.anchor = GridBagConstraints.SOUTHWEST;
|
|
constraints.gridx = 1;
|
|
constraints.weightx = 0.5;
|
|
consoleFrame.add(buttonClear, constraints);
|
|
|
|
constraints.gridx = 0;
|
|
constraints.gridy = 0;
|
|
constraints.gridwidth = 4;
|
|
constraints.fill = GridBagConstraints.BOTH;
|
|
constraints.anchor = GridBagConstraints.NORTH;
|
|
constraints.weightx = 1.0;
|
|
constraints.weighty = 1.0;
|
|
consoleFrame.add(new JScrollPane(logArea), constraints);
|
|
|
|
buttonClear.addActionListener(evt -> clearLog());
|
|
|
|
// consoleFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
consoleFrame.setSize(480, 320);
|
|
}
|
|
|
|
/**
|
|
* This function will go ahead and find the location of the `scriptName` and try to load the class
|
|
* file.
|
|
*
|
|
* @param scriptName -- the name of the script (without .class at the end.)
|
|
* @return boolean -- whether or not the script was successfully loaded.
|
|
*/
|
|
private static boolean loadAndRunScript(String scriptName) {
|
|
try {
|
|
currentRunningScript =
|
|
scripts.values().stream()
|
|
.flatMap(List::stream)
|
|
.filter(c -> c.getSimpleName().equalsIgnoreCase(scriptName))
|
|
.findFirst()
|
|
.map(
|
|
clazz -> {
|
|
try {
|
|
return clazz.getSuperclass().equals(compatibility.apos.Script.class)
|
|
? clazz.getDeclaredConstructor(String.class).newInstance("")
|
|
: clazz.getDeclaredConstructor().newInstance();
|
|
} catch (InstantiationException
|
|
| IllegalAccessException
|
|
| NoSuchMethodException
|
|
| InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
return null;
|
|
}
|
|
})
|
|
.orElse(null);
|
|
|
|
if (currentRunningScript == null) {
|
|
return false;
|
|
}
|
|
|
|
Main.config.setScriptName(scriptName);
|
|
return true;
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initializes the script menu selector.
|
|
*
|
|
* @param scriptFrame -- the script menu selector frame.
|
|
*/
|
|
private static void initializeScriptFrame(JFrame scriptFrame) {
|
|
String[] columnNames = {"Name", "Type"};
|
|
DefaultTableModel tableModel = new DefaultTableModel(columnNames, 0);
|
|
|
|
scripts.forEach(
|
|
(type, classes) ->
|
|
classes.stream()
|
|
.sorted(Comparator.comparing(Class::getSimpleName))
|
|
.forEach(clazz -> tableModel.addRow(new String[] {clazz.getSimpleName(), type})));
|
|
|
|
// Setup table
|
|
final JTable scriptTable =
|
|
new JTable(tableModel) {
|
|
@Override
|
|
public boolean isCellEditable(int row, int column) {
|
|
return false;
|
|
}
|
|
};
|
|
scriptTable.setSelectionMode(
|
|
ListSelectionModel.SINGLE_SELECTION); // Only allow single row selected at a time
|
|
scriptTable.setAutoCreateRowSorter(true); // Automatically create a table row sorter
|
|
scriptTable.getTableHeader().setReorderingAllowed(false); // Disable reordering columns
|
|
scriptTable.getTableHeader().setResizingAllowed(false); // Disable resizing columns
|
|
scriptTable
|
|
.getTableHeader()
|
|
.setFont(scriptTable.getTableHeader().getFont().deriveFont(Font.BOLD, 15f));
|
|
scriptTable.setBorder(BorderFactory.createEmptyBorder());
|
|
|
|
final JScrollPane scriptScroller = new JScrollPane(scriptTable);
|
|
|
|
// Setup script args field
|
|
final String scriptArgsPlaceholder = "Script args (ex: arg1 arg2 arg3 ...)";
|
|
final JTextField scriptArgs = new JTextField(scriptArgsPlaceholder);
|
|
scriptArgs.setForeground(Color.GRAY);
|
|
scriptArgs.addFocusListener(
|
|
getPlaceholderFocusListener(scriptArgs, scriptArgsPlaceholder, false));
|
|
|
|
// Setup filter field
|
|
final String scriptFilterPlaceholder = "Filter";
|
|
final JTextField scriptFilter = new JTextField(scriptFilterPlaceholder);
|
|
scriptFilter.setForeground(Color.GRAY);
|
|
scriptFilter.addFocusListener(
|
|
getPlaceholderFocusListener(scriptFilter, scriptFilterPlaceholder, true));
|
|
scriptFilter
|
|
.getDocument()
|
|
.addDocumentListener(
|
|
new DocumentListener() {
|
|
@Override
|
|
public void insertUpdate(DocumentEvent e) {
|
|
filter();
|
|
}
|
|
|
|
@Override
|
|
public void removeUpdate(DocumentEvent e) {
|
|
filter();
|
|
}
|
|
|
|
@Override
|
|
public void changedUpdate(DocumentEvent e) {
|
|
filter();
|
|
}
|
|
|
|
public void filter() {
|
|
if (!shouldFilter) {
|
|
return;
|
|
}
|
|
String filterValue = scriptFilter.getText().toLowerCase().trim();
|
|
TableRowSorter sorter = ((TableRowSorter) scriptTable.getRowSorter());
|
|
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + filterValue, 0));
|
|
|
|
scriptTable.setRowSorter(sorter);
|
|
}
|
|
});
|
|
|
|
// Setup script button
|
|
final JButton scriptButton = new JButton("Run");
|
|
scriptButton.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
scriptButton.addActionListener(
|
|
e -> {
|
|
int selectedRowIndex = scriptTable.getSelectedRow();
|
|
if (selectedRowIndex > -1) {
|
|
String scriptName =
|
|
(String)
|
|
scriptTable
|
|
.getModel()
|
|
.getValueAt(scriptTable.convertRowIndexToModel(selectedRowIndex), 0);
|
|
|
|
if (loadAndRunScript(scriptName)) {
|
|
if (scriptArgs.getText().equals(scriptArgsPlaceholder)) {
|
|
scriptArgs.setText("");
|
|
}
|
|
|
|
config.setScriptArguments(scriptArgs.getText().split(" "));
|
|
isRunning = true;
|
|
startStopButton.setText("Stop");
|
|
scriptFrame.setVisible(false);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Setup layout
|
|
scriptFrame.setLayout(new BoxLayout(scriptFrame.getContentPane(), BoxLayout.Y_AXIS));
|
|
scriptFrame.add(scriptFilter);
|
|
scriptFrame.add(scriptScroller);
|
|
scriptFrame.add(scriptArgs);
|
|
scriptFrame.add(scriptButton);
|
|
scriptFrame.setSize(300, 300);
|
|
|
|
scriptFrame.setLocationRelativeTo(null);
|
|
}
|
|
|
|
private static FocusListener getPlaceholderFocusListener(
|
|
JTextField textField, String placeholderText, boolean disableFilter) {
|
|
return new FocusListener() {
|
|
@Override
|
|
public void focusGained(FocusEvent e) {
|
|
if (textField.getText().equals(placeholderText)) {
|
|
if (disableFilter) {
|
|
shouldFilter = false;
|
|
}
|
|
|
|
textField.setText("");
|
|
textField.setForeground(Color.BLACK);
|
|
shouldFilter = true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void focusLost(FocusEvent e) {
|
|
if (textField.getText().isEmpty()) {
|
|
if (disableFilter) {
|
|
shouldFilter = false;
|
|
}
|
|
|
|
textField.setText(placeholderText);
|
|
textField.setForeground(Color.GRAY);
|
|
shouldFilter = true;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
// /** Checks if the user has made a Cache/ folder. If not, spawns a wizard to create the folder.
|
|
// */
|
|
// private static void handleCache(Config config) {
|
|
// final int COLESLAW_PORT = 43599;
|
|
// final int URANIUM_PORT = 43601;
|
|
// // Does the directory exist?
|
|
// File cacheDirectory = new File("Cache/");
|
|
//
|
|
// if (cacheDirectory.exists()) return;
|
|
//
|
|
// // If --init-cache argument is used, bypass the GUI
|
|
// if (!config.getInitCache().isEmpty()) {
|
|
// if (config.getInitCache().equals("uranium")) {
|
|
// // Create Uranium cache
|
|
// createCache(URANIUM_PORT);
|
|
// return;
|
|
// } else if (config.getInitCache().equals("coleslaw")) {
|
|
// // Create Coleslaw cache
|
|
// createCache(COLESLAW_PORT);
|
|
// return;
|
|
// } else {
|
|
// System.out.println("Server (" + config.getInitCache() + ") is not known.");
|
|
// }
|
|
// }
|
|
//
|
|
// JFrame cacheFrame = new JFrame("Cache Setup");
|
|
// JLabel cacheLabel = new JLabel("First setup: you must select either Uranium or Coleslaw.");
|
|
// JButton uraniumButton = new JButton("Uranium (2018 RSC)");
|
|
// JButton coleslawButton = new JButton("Coleslaw (modified RSC, new content)");
|
|
//
|
|
// uraniumButton.addActionListener(
|
|
// e -> {
|
|
// // Create Uranium cache
|
|
// createCache(URANIUM_PORT);
|
|
// });
|
|
//
|
|
// coleslawButton.addActionListener(
|
|
// e -> {
|
|
// // Create Coleslaw cache
|
|
// createCache(COLESLAW_PORT);
|
|
// });
|
|
//
|
|
// cacheFrame.setLayout(new GridLayout(0, 1));
|
|
// cacheFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
// cacheFrame.add(cacheLabel);
|
|
// cacheFrame.add(uraniumButton);
|
|
// cacheFrame.add(coleslawButton);
|
|
//
|
|
// cacheFrame.pack();
|
|
// cacheFrame.setLocationRelativeTo(null);
|
|
// cacheFrame.setVisible(true);
|
|
// cacheFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
//
|
|
// while (!cacheDirectory.exists()) {
|
|
// try {
|
|
// Thread.sleep(100);
|
|
// } catch (InterruptedException e) {
|
|
// e.printStackTrace();
|
|
// }
|
|
// cacheDirectory = new File("Cache/");
|
|
// }
|
|
// cacheFrame.setVisible(false);
|
|
// cacheFrame.dispose();
|
|
// }
|
|
|
|
// private static void createCache(int ServerPort) {
|
|
// // Create Cache directory
|
|
// File dir = new File("." + File.separator + "Cache");
|
|
// dir.mkdirs();
|
|
//
|
|
// // Copy embedded cache to cache directory
|
|
// try {
|
|
// Extractor.extractZipResource("/cache/ZipCache.zip", dir.toPath());
|
|
// } catch (IOException ignored) {
|
|
// System.out.print(ignored);
|
|
// }
|
|
//
|
|
// // Add port to client cache
|
|
// try {
|
|
// FileWriter portFile = new FileWriter("Cache/port.txt");
|
|
// portFile.write(Integer.toString(43599));
|
|
// portFile.close();
|
|
// } catch (IOException ignored) {
|
|
// System.out.print(ignored);
|
|
// }
|
|
// }
|
|
|
|
private static void copyDirectory(
|
|
String sourceDirectoryLocation, String destinationDirectoryLocation) {
|
|
try {
|
|
Files.walk(Paths.get(sourceDirectoryLocation))
|
|
.forEach(
|
|
source -> {
|
|
Path destination =
|
|
Paths.get(
|
|
destinationDirectoryLocation,
|
|
source.toString().substring(sourceDirectoryLocation.length()));
|
|
try {
|
|
Files.copy(source, destination);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
System.exit(1);
|
|
}
|
|
}
|
|
|
|
public static boolean isDrawEnabled() {
|
|
if (controller != null) {
|
|
return controller.isDrawEnabled();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static void showLoadScript() {
|
|
if (!isRunning) {
|
|
scriptFrame.setVisible(true);
|
|
scriptFrame.toFront();
|
|
scriptFrame.requestFocusInWindow();
|
|
} else {
|
|
// JOptionPane.showMessageDialog(null, "Stop the current script first.");
|
|
|
|
JLabel stopLabel = new JLabel("A Script is already running for this account!");
|
|
JLabel stopLabel2 = new JLabel("You must stop the script before loading a new one");
|
|
JButton cancelButton = new JButton("Force cancel script");
|
|
JButton closeWindow = new JButton("Close this warning");
|
|
|
|
cancelButton.addActionListener(
|
|
e -> {
|
|
setRunning(false);
|
|
|
|
scriptFrame.setVisible(false);
|
|
scriptFrame.dispose();
|
|
});
|
|
|
|
closeWindow.addActionListener(
|
|
e -> {
|
|
scriptFrame.setVisible(false);
|
|
scriptFrame.dispose();
|
|
});
|
|
|
|
if (config.getUsername() != null) {
|
|
scriptFrame = new JFrame(config.getUsername() + "'s Script already running");
|
|
} else if (controller.getPlayerName() != null) {
|
|
scriptFrame = new JFrame(controller.getPlayerName() + "'s Script already running");
|
|
} else {
|
|
scriptFrame = new JFrame("Script already running");
|
|
}
|
|
|
|
scriptFrame.setLayout(new GridLayout(0, 1));
|
|
scriptFrame.add(stopLabel);
|
|
scriptFrame.add(stopLabel2);
|
|
scriptFrame.add(cancelButton);
|
|
scriptFrame.add(closeWindow);
|
|
}
|
|
}
|
|
/**
|
|
* Returns the global Controller instance.
|
|
*
|
|
* @return Controller
|
|
*/
|
|
public static Controller getController() {
|
|
return controller;
|
|
}
|
|
|
|
public static String[] getThemeNames() {
|
|
return themeNames;
|
|
}
|
|
|
|
public static void setUsername(String name) {
|
|
username = name;
|
|
}
|
|
|
|
public static String getUsername() {
|
|
return username;
|
|
}
|
|
|
|
public static void setThemeName(String name) {
|
|
themeName = name;
|
|
}
|
|
|
|
public static String getThemeName() {
|
|
return themeName;
|
|
}
|
|
/**
|
|
* Used by the WindowListener for tracking the log window.
|
|
*
|
|
* @return whether or not the log window is open.
|
|
*/
|
|
public static boolean isLogWindowOpen() {
|
|
return logWindowCheckbox.isSelected();
|
|
}
|
|
/**
|
|
* Used by the WindowListener for tracking the side window.
|
|
*
|
|
* @return whether or not the side window is open.
|
|
*/
|
|
public static boolean isSideWindowOpen() {
|
|
return sidebarCheckbox.isSelected();
|
|
}
|
|
/**
|
|
* Returns whether or not a script is running.
|
|
*
|
|
* @return boolean with whether or not a script is running.
|
|
*/
|
|
public static boolean isRunning() {
|
|
return isRunning;
|
|
}
|
|
|
|
/**
|
|
* Returns whether or not auto-login is enabled.
|
|
*
|
|
* @return boolean with whether or not autologin is enabled.
|
|
*/
|
|
public static boolean isAutoLogin() {
|
|
return autoLoginCheckbox.isSelected();
|
|
}
|
|
|
|
/**
|
|
* Returns whether or not debug is enabled.
|
|
*
|
|
* @return boolean with whether or not debug is enabled.
|
|
*/
|
|
public static boolean isDebug() {
|
|
return debugCheckbox.isSelected();
|
|
}
|
|
|
|
/**
|
|
* A function for controlling whether or not scripts are running.
|
|
*
|
|
* @param b
|
|
*/
|
|
public static void setRunning(boolean b) {
|
|
isRunning = b;
|
|
|
|
if (isRunning) {
|
|
startStopButton.setText("Stop");
|
|
} else {
|
|
startStopButton.setText("Start");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A function for controlling the autologin functionality.
|
|
*
|
|
* @param b
|
|
*/
|
|
public static void setAutoLogin(boolean b) {
|
|
autoLoginCheckbox.setSelected(b);
|
|
}
|
|
|
|
/**
|
|
* A function which returns the current running IdleScript/Script instance.
|
|
*
|
|
* @return Object (which is an instanceof IdleScript or Script)
|
|
*/
|
|
}
|