Skip to content
Merged
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@ build/
.gradle/
OsrsBot.jar
.idea/

target/*
.clj-kondo/*
.lsp/*

output/*
31 changes: 31 additions & 0 deletions partial-patch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
target_file="~/Code/OsrsBot/src/main/java/net/runelite/rsb/wrappers/client_wrapper/RSClient.java"
lein run 2>&1 | while read -r line; do
if echo "$line" | grep -q "return type void is not compatible with"; then
type=$(echo "$line" | awk '{print $9}')
fi
if echo "$line" | grep -q "RSClient is not abstract and does not override abstract method"; then
method=$(echo "$line" | awk '{print $13}')
echo "public void $method { $method; }"
sed -i '$ d' "$target_file"
echo "public void $method { $method; }" >> "$target_file"
echo "}" >> "$target_file"
fi
done

lein run 2>&1 | while read -r line; do
if echo "$line" | grep -q "return type void is not compatible with"; then
type=$(echo "$line" | awk '{print $8}')
echo "public $type $method { $method; }"
sed -i '$ d' "$target_file"
sed -i '$ d' "$target_file"
echo "public $type $method { return $method; }" >> "$target_file"
echo "}" >> "$target_file"
fi
if echo "$line" | grep -q "RSClient is not abstract and does not override abstract method"; then
method=$(echo "$line" | awk '{print $13}')

fi
done



24 changes: 24 additions & 0 deletions project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(defn get-runelite-version []
())

(defproject OSRSB "0.0.1"
:description "A revised bot client on RuneLite (for now)"
:dependencies [[org.clojure/clojure "1.10.3"]
[clj-http "3.12.3"]
[org.clojure/core.async "1.7.701"]
[com.cemerick/pomegranate "1.1.0"]
[net.runelite/client "1.10.49"]
[net.runelite/cache "1.10.49"]
#_[org.projectlombok/lombok "1.18.32"]
#_[javassist/javassist "3.12.1.GA"]
#_[net.sf.jopt-simple/jopt-simple "5.0.4"]
#_[com.github.joonasvali.naturalmouse/naturalmouse "2.0.3"]
#_[com.github.OSRSB/OSRSBPlugin "main-SNAPSHOT"]]
:repositories {"runelite" "https://repo.runelite.net"
"jitpack" "https://jitpack.io"
"central" "https://repo1.maven.org/maven2/"}
:jvm-opts ["--add-opens=java.base/java.lang=ALL-UNNAMED"]
:source-paths ["src/main/clojure"]
#_:java-source-paths #_["src/main/java"]
:javac-options ["-processor" "lombok.launch.AnnotationProcessorHider$AnnotationProcessor"]
:main net.runelite.rsb.launcher.core)
59 changes: 59 additions & 0 deletions src/main/clojure/net/runelite/rsb/launcher/application.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
(ns net.runelite.rsb.launcher.application
(:require [clojure.core.async :as async :refer [chan go <! <!! >!! close!]]
[clojure.string :as str]
[net.runelite.rsb.launcher.botlite :as botlite])
(:import #_[net.runelite.rsb.botLauncher BotLite]))

(def bots [])

(defn get-classloader
"Gets the classloader of an object."
[obj]
((.getClassLoader (.getClass obj))))

(defn get-bot
"Retrieves the Bot for any object loaded in its client."
[obj]
(doseq [bot bots]
(when (== (get-classloader obj) (get-classloader bot))
bot)))

(defn add-bot
""
[show-ui]
(let [bot (botlite/create-botlite-instance show-ui)]
(println bot)
(println "Test")
#_(.launch bot (into-array String ["--bot-runelite" "--developer-mode"]))
#_(conj bots bot)))

(defn command-line-listener
"Handles command-line interfacing with the client.
The REPL is likely to be more immediately useful in most cases."
[]
(go (loop [command (str/trim (read-line))]
(case (first (str/split (str/lower-case command) #" "))
"runscript" (println "runscript")
"stopscript" (println "stopscript")
"addbot" (do
(println "Adding bot")
(add-bot true))
"checkstate" (println "checkstate")
(println "Invalid command"))
(recur (str/trim (read-line))))))

(defn start
"Parses command-line arguments passed to the program and then passes the remaining
to the command-line-listener method to continue handling the next inputs if applicable."
[args]
(println args)
(cond
(contains? args "--bot-runelite")
(do
(add-bot true)
(command-line-listener))
(contains? args "--salsa-bowl")
(println "Random Behavior")
#_(println "S")
#_(.main Runelite (into-array String args))))

102 changes: 102 additions & 0 deletions src/main/clojure/net/runelite/rsb/launcher/botlite.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
(ns net.runelite.rsb.launcher.botlite
(:require [clojure.core.async :as async :refer [chan go >! <! >!! close!]]
[clj-http.client :as client]
[clojure.java.shell :refer [sh]]
[clojure.string :as str]
[clojure.java.io :as io]
[cemerick.pomegranate :as pomegranate]
[cemerick.pomegranate.aether :as aether])
(:import
[clojure.lang DynamicClassLoader]
[java.io File]))

(defn classloader-classpath [classloader]
(->> (seq (.getURLs classloader))
(map #(.getPath %))
(clojure.string/join ":")))

(defn get-runelite-version []
(let [url "http://repo.runelite.net/net/runelite/client/maven-metadata.xml"
response (client/get url {:as :stream})]
(with-open [reader (io/reader (:body response))]
(some #(when (str/includes? % "<release>")
(str/trim (str/replace % #"</?release>" "")))
(line-seq reader)))))

(defn add-dependency [classloader group-id artifact-id version]
(pomegranate/add-dependencies
:classloader classloader
:coordinates [[(symbol (str group-id "/" artifact-id)) version]]
:repositories (merge aether/maven-central
{"clojars" "https://repo.clojars.org/"
"jitpack" "https://jitpack.io"
"central" "https://repo1.maven.org/maven2/"
"runelite" "https://repo.runelite.net"})))


(defn find-lombok-jar [classloader]
(->> (seq (.getURLs classloader))
(map #(.getPath %))
(filter #(re-matches #".*lombok-.*\.jar$" %))
first))


(defn compile-java-files [classloader]
(spit "java-files.txt"
(str/join "\n"
(map #(.getPath %)
(filter #(str/ends-with? (.getName %) ".java")
(file-seq (io/file "src/main/java"))))))
(let [lombok-jar (find-lombok-jar classloader)
processorpath (if lombok-jar
lombok-jar
(throw (Exception. "Lombok JAR not found on classpath")))]
(sh "javac" "-d" "output" "-cp" (classloader-classpath classloader) "-processorpath" processorpath "@java-files.txt")))

(defn handle-deps [classloader]
(add-dependency classloader "net.runelite" "client" (get-runelite-version))
(add-dependency classloader "net.runelite" "cache" (get-runelite-version))
(add-dependency classloader "org.clojure" "clojure" "1.10.3")
(add-dependency classloader "org.slf4j" "slf4j-simple" "1.7.36")
(add-dependency classloader "org.projectlombok" "lombok" "1.18.32")
(add-dependency classloader "com.github.joonasvali.naturalmouse" "naturalmouse" "2.0.3")
(add-dependency classloader "com.github.OSRSB" "OSRSBPlugin" "main-SNAPSHOT")
(add-dependency classloader "javassist" "javassist" "3.12.1.GA")
(add-dependency classloader "net.sf.jopt-simple" "jopt-simple" "5.0.4"))

(defn instantiate-class [lc]
(.newInstance lc))

(defn get-injector [lc]
(let [injector (.getDeclaredField lc "injector")]
(.setAccessible injector true)
(.get injector nil)))

(def output-dir (File. "output"))

(defn list-all-dirs [dir]
(let [dirs (file-seq dir)]
(filter #(.isDirectory %) dirs)))

(defn add-dirs-to-classloader [classloader dirs]
(doseq [dir dirs]
(let [url (.toURL (.toURI dir))]
(.addURL classloader url))))

(defn create-botlite-instance [show-ui]
(let [class-name "net.runelite.rsb.botLauncher.BotLite"
class-loader (DynamicClassLoader. (ClassLoader/getSystemClassLoader))
deps (handle-deps class-loader)
outputDeps (add-dirs-to-classloader class-loader (list-all-dirs output-dir))
javaDeps (compile-java-files class-loader)
loaded-class (.loadClass class-loader class-name)
emptylite (instantiate-class loaded-class)
test (.launch emptylite (into-array String ["--bot-runelite" "--developer-mode"]))
botlite (.getInjectorInstance emptylite)]
#_(.launch botlite (into-array String ["--bot-runelite" "--developer-mode"]))
(.init botlite true)
{:class-loader class-loader
:loaded-class loaded-class
:class-name class-name
:empty-class emptylite
:botlite botlite}))
42 changes: 42 additions & 0 deletions src/main/clojure/net/runelite/rsb/launcher/core.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
(ns net.runelite.rsb.launcher.core
(:require [clj-http.client :as client]
[clojure.java.io :as io] [clojure.string :as str]
[cemerick.pomegranate :as pomegranate]
[cemerick.pomegranate.aether :as aether]
[net.runelite.rsb.launcher.application :as app]
)
(:import [net.runelite.rsb.botLauncher Application])
(:gen-class))

(defn get-runelite-version []
(let [url "http://repo.runelite.net/net/runelite/client/maven-metadata.xml"
response (client/get url {:as :stream})]
(with-open [reader (io/reader (:body response))]
(some #(when (str/includes? % "<release>")
(str/trim (str/replace % #"</?release>" "")))
(line-seq reader)))))

(defn add-dependency [group-id artifact-id version]
(let [current-thread (Thread/currentThread)
context-loader (.getContextClassLoader current-thread)]
(try
(.setContextClassLoader current-thread (clojure.lang.DynamicClassLoader. context-loader))
(pomegranate/add-dependencies
:coordinates [[(symbol (str group-id "/" artifact-id)) version]]
:repositories (merge aether/maven-central
{"clojars" "https://repo.clojars.org/"
"runelite" "https://repo.runelite.net"}))
(finally
(.setContextClassLoader current-thread context-loader)))))

(defn handle-deps []
(add-dependency "net.runelite" "client" (get-runelite-version))
(add-dependency "net.runelite" "cache" (get-runelite-version))
(add-dependency "org.projectlombok" "lombok" "1.18.24")
(add-dependency "javassist" "javassist" "3.12.1.GA")
(add-dependency "net.sf.jopt-simple" "jopt-simple" "5.0.4"))

(defn -main [& args]
(handle-deps) ;; This will be used when we convert ALL code from Java and can do runtime compilation only
(app/start (set args))
#_(Application/main (into-array String args)))
3 changes: 1 addition & 2 deletions src/main/java/net/runelite/rsb/botLauncher/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ public class Application {
* @throws Throwable Any error that might be thrown
*/
public static void main(final String[] args) throws Throwable {
JnREPL.startRepl();
preParser = new ArgumentPreParser(args);
if (preParser.contains("--bot-runelite")) {
addBot(preParser.contains("--headless"));
checkForCacheAndLoad();
// checkForCacheAndLoad();
CLIHandler.handleCLI();
} else {
net.runelite.client.RuneLite.main(args);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package net.runelite.rsb.wrappers.client_wrapper;

import net.runelite.api.*;
import net.runelite.api.Menu;
import net.runelite.api.Point;
import net.runelite.api.annotations.Varp;
import net.runelite.api.clan.ClanChannel;
import net.runelite.api.clan.ClanSettings;
Expand All @@ -17,21 +15,31 @@
import net.runelite.api.widgets.WidgetModalMode;
import net.runelite.api.worldmap.MapElementConfig;
import net.runelite.api.worldmap.WorldMap;
import net.runelite.api.RuneLiteObjectController;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.applet.Applet;
import java.awt.*;
import java.lang.reflect.Method;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.function.IntPredicate;
import com.jagex.oldscape.pub.OAuthApi;
import com.jagex.oldscape.pub.OtlTokenRequester;
import com.jagex.oldscape.pub.OtlTokenResponse;





/*
Base class for wrapping runelite Client, along with some weird Applet shenanigans.
*/
@SuppressWarnings("removal")
public abstract class BaseClientWrapper extends Applet implements Client {
public abstract class BaseClientWrapper extends Applet implements Client, OAuthApi
{
public final Client wrappedClient;

public BaseClientWrapper(Client client) {
Expand Down Expand Up @@ -263,7 +271,7 @@ public int getScale() {
}

@Override
public Point getMouseCanvasPosition() {
public net.runelite.api.Point getMouseCanvasPosition() {
return wrappedClient.getMouseCanvasPosition();
}

Expand Down Expand Up @@ -1587,7 +1595,7 @@ public void setFreeCameraSpeed(int i) {
}

@Override
public Menu getMenu() {
public net.runelite.api.Menu getMenu() {
return wrappedClient.getMenu();
}

Expand Down Expand Up @@ -1620,4 +1628,34 @@ public WorldView getWorldView(int i) {
public WorldView getTopLevelWorldView() {
return wrappedClient.getTopLevelWorldView();
}

@Override
public Model applyTransformations(Model m, Animation animA, int frameA, Animation animB, int frameB) {
return wrappedClient.applyTransformations(m, animA, frameA, animB, frameB);
}

@Override
public void setDraw2DMask(int mask) {
wrappedClient.setDraw2DMask(mask);
}

@Override
public int getDraw2DMask() {
return wrappedClient.getDraw2DMask();
}

@Override
public List<MidiRequest> getActiveMidiRequests() {
return wrappedClient.getActiveMidiRequests();
}

@Override
public boolean isRuneLiteObjectRegistered(RuneLiteObjectController controller) {return wrappedClient.isRuneLiteObjectRegistered(controller);}

@Override
public void removeRuneLiteObject(RuneLiteObjectController controller) {wrappedClient.removeRuneLiteObject(controller);}

@Override
public void registerRuneLiteObject(RuneLiteObjectController controller) {wrappedClient.registerRuneLiteObject(controller);}

}
Original file line number Diff line number Diff line change
Expand Up @@ -779,4 +779,8 @@ public void setOnScrollWheelListener(Object... objects) {
@Override
public void clearActions() { wrappedWidget.clearActions(); }


@Override
public int[] getVarTransmitTrigger() { return wrappedWidget.getVarTransmitTrigger(); }

}
Loading
Loading