src/clojurecraft/core.clj @ 505c3366e2b3
Oh my god.
author |
Steve Losh <steve@stevelosh.com> |
date |
Tue, 21 Jun 2011 20:17:50 -0400 |
parents |
(none) |
children |
b659dc7894e4 |
(ns clojurecraft.core
(:import (java.net Socket)
(java.io DataOutputStream DataInputStream)))
(def minecraft-local {:name "localhost" :port 25565})
; Packet Type Maps -----------------------------------------------------------------
(def packet-ids {
:login 0x01
:handshake 0x02
})
(def packet-types {
0x01 :login
0x02 :handshake
})
(declare conn-handler)
; Connection Wrappers --------------------------------------------------------------
(defn connect [server]
(let [socket (Socket. (:name server) (:port server))
in (DataInputStream. (.getInputStream socket))
out (DataOutputStream. (.getOutputStream socket))
conn (ref {:in in :out out})]
(doto (Thread. #(conn-handler conn)) (.start))
conn))
(defn disconnect [conn]
(dosync (alter conn merge {:exit true})))
; Writing Data ---------------------------------------------------------------------
(defn writ-byte [conn i]
(println (str "-> PACKET ID: " (Integer/toHexString i)))
(doto (:out @conn)
(.writeByte (int i))))
(defn writ-short [conn i]
(println (str "-> SHORT: " i))
(doto (:out @conn)
(.writeShort (int i))))
(defn writ-int [conn i]
(println (str "-> INT: " i))
(doto (:out @conn)
(.writeInt (int i))))
(defn writ-long [conn i]
(println (str "-> LONG: " i))
(doto (:out @conn)
(.writeLong (int i))))
(defn writ-string16 [conn s]
(writ-short conn (count s))
(println (str "-> STRING: " s))
(doto (:out @conn)
(.writeChars s)))
(defn writ-chars [conn s]
(println (str "-> CHARS: " s))
(doto (:out @conn)
(.writeChars s)))
; Writing Packets ------------------------------------------------------------------
(defn write-packet-handshake [conn {username :username}]
(writ-byte conn (:handshake packet-ids))
(writ-string16 conn username))
(defn write-packet-login [conn {version :version username :username}]
(writ-byte conn (:login packet-ids))
(writ-int conn version)
(writ-string16 conn username)
(writ-long conn 0)
(writ-byte conn 0))
; Writing Wrappers -----------------------------------------------------------------
(defn flushc [conn]
(doto (:out @conn) (.flush)))
(defn write-packet [conn packet-type payload]
(cond
(= packet-type :handshake) (write-packet-handshake conn payload)
(= packet-type :login) (write-packet-login conn payload)
)
(flushc conn))
; Reading Data ---------------------------------------------------------------------
(defn red-byte [conn]
(let [b (.readByte (:in @conn))]
b))
(defn red-int [conn]
(let [i (.readInt (:in @conn))]
i))
(defn red-long [conn]
(let [i (.readLong (:in @conn))]
i))
(defn red-string16 [conn]
(let [str-len (.readShort (:in @conn))
s (apply str (repeatedly str-len #(.readChar (:in @conn))))]
s))
; Handling Packets -----------------------------------------------------------------
(defn handle-packet-handshake [conn]
(println "OMG got a handshake")
(-> {}
(assoc :hash (red-string16 conn))))
(defn handle-packet-login [conn]
(println "OMG got a login")
(-> {}
(assoc :eid (red-int conn))
(assoc :unknown (red-string16 conn))
(assoc :seed (red-long conn))
(assoc :dimension (red-byte conn))))
(defn handle-packet [conn packet-id]
(let [packet-id (int packet-id)]
(println "\n----->")
(println
(cond
(= (packet-types packet-id) :handshake) (handle-packet-handshake conn)
(= (packet-types packet-id) :login) (handle-packet-login conn)
:else (str "UNKNOWN PACKET TYPE: " packet-id)
))
(println "\n\n\n")))
; Handling Wrappers ----------------------------------------------------------------
(defn login [conn]
; Send handshake
(write-packet conn :handshake {:username "timmy"})
; Get handshake
(let [packet-id (red-byte conn)]
(handle-packet conn packet-id))
; Send login
(write-packet conn :login {:version 13 :username "timmy"})
; Get login
(let [packet-id (red-byte conn)]
(handle-packet conn packet-id))
)
(defn conn-handler [conn]
(println "connecting")
(login conn)
(while (nil? (:exit @conn))
(let [packet-id (.readByte (:in @conn))]
(handle-packet conn packet-id)
))
(println "done"))
; REPL -----------------------------------------------------------------------------
(def server (connect minecraft-local))
(disconnect server)