Echo_
2012-07-14 17:02:45
I was bored, so I decided to write an RS client loader in Clojure :)
web.clj
gui.clj
main.clj
Obviously not the safest way to load the client, but that can be fixed. I also attached the Clojure source code and compiled classes, because it's fun to see how Clojure compiles to Java bytecode :p
web.clj
(ns loader.web
(:import (java.io BufferedReader InputStreamReader)
(java.net URL)))
(def session-pattern #"src=\"(.*)\" f")
(def archive-pattern #"archive=(.*)\s+code=(.*)\.class m")
(def param-pattern #"<param name=\"([^\s]+)\"\s+value=\"([^>]*)\">")
(defn- read-page [address]
(with-open [reader (BufferedReader. (InputStreamReader. (.openStream (URL. address))))]
(let [lines (line-seq reader)]
(reduce #(str %1 "\n" %2) lines))))
(defn- read-session [html]
(.trim (second (re-find session-pattern html))))
(defn- read-archive [html]
(let [archive (re-find archive-pattern html)]
{:jar (second archive) :code (last archive)}))
(defn- read-params [html]
(loop [matches (re-seq param-pattern html)
result {}]
(if (empty? matches)
result
(recur (rest matches) (assoc result (-> matches first second) (-> matches first last))))))
(defn read-info []
(let [page (read-page "http://www.runescape.com/game.ws?j=0")
session (read-session page)
frame (read-page session)
url (.substring session 0 (.indexOf session "/,"))
archive (read-archive frame)
parameters (read-params frame)]
(println " - Loaded" url)
(println " - SecretKeySpec =" (parameters "0"))
(println " - IvParameterSpec =" (parameters "-1"))
{:session url :archive archive :parameters parameters}))gui.clj
(ns loader.gui
(:require [loader.web :as web])
(:import (java.applet Applet AppletStub)
(java.awt BorderLayout Dimension)
(java.net MalformedURLException URL URLClassLoader)
(javax.swing JFrame JPanel)))
(defn- create-loader [session parameters]
(proxy [JFrame AppletStub] []
(appletResize [width height])
(getAppletContext [] nil)
(getCodeBase [] (URL. session))
(getDocumentBase [] (.getCodeBase this))
(getParameter [name] (parameters name))
(isActive [] false)))
(defn init-loader []
(let [info (web/read-info)
loader (create-loader (info :session) (info :parameters))
class-loader (URLClassLoader. (into-array [(URL. (str (info :session) "/" (-> info :archive :jar)))]))
applet-class (.loadClass class-loader (-> info :archive :code))
#^Applet applet-loader (.newInstance applet-class)
game (JPanel. (BorderLayout.))]
(.setStub applet-loader loader)
(.setTitle loader "RuneScape")
(.setPreferredSize game (Dimension. 768 560))
(.setDefaultCloseOperation loader JFrame/EXIT_ON_CLOSE)
(.setSize loader 768 560)
(.init applet-loader)
(.start applet-loader)
(.add game applet-loader)
(.. loader getContentPane (add game BorderLayout/CENTER))
(.setVisible loader true)))main.clj
(ns loader.main
(:require [loader.gui :as gui])
(:gen-class))
(defn -main [& args]
(gui/init-loader))Obviously not the safest way to load the client, but that can be fixed. I also attached the Clojure source code and compiled classes, because it's fun to see how Clojure compiles to Java bytecode :p