--- a/src/clojurecraft/chunks.clj Mon Aug 08 21:01:07 2011 -0400
+++ b/src/clojurecraft/chunks.clj Tue Aug 09 00:28:51 2011 -0400
@@ -18,12 +18,12 @@
(defn block-from-chunk [x y z chunk]
(let [i (block-index-in-chunk x y z)
- block-type (get (:types @chunk) i)
- block-meta (get (:metadata @chunk) i)
- block-light (get (:light @chunk) i)
- block-sky-light (get (:sky-light @chunk) i)]
+ block-type (aget (:types @chunk) i)
+ block-meta (aget (:metadata @chunk) i)
+ block-light (aget (:light @chunk) i)
+ block-sky-light (aget (:sky-light @chunk) i)]
(Block. [x y z]
- (block-types block-type)
+ (block-types (int block-type))
block-meta
block-light
block-sky-light)))
@@ -43,11 +43,11 @@
(+ 1 (int (+ (:y (:loc @(:player bot))) y)))
(int (+ (:z (:loc @(:player bot))) z))))
-(defn block-standing-in [bot]
+(defn block-beneath [bot]
(block bot
- (int (:x (:loc @(:player bot))))
- (int (:y (:loc @(:player bot))))
- (int (:z (:loc @(:player bot))))))
+ (int (Math/floor (:x (:loc @(:player bot)))))
+ (int (Math/floor (:y (:loc @(:player bot)))))
+ (int (Math/floor (:z (:loc @(:player bot)))))))
(defn current [bot]
(chunk-containing
--- a/src/clojurecraft/core.clj Mon Aug 08 21:01:07 2011 -0400
+++ b/src/clojurecraft/core.clj Tue Aug 09 00:28:51 2011 -0400
@@ -37,19 +37,21 @@
(write-packet bot :handshake {:username username})
; Get handshake
- (read-packet bot)
+ (read-packet bot nil)
; Send login
(write-packet bot :login {:version 14 :username username})
; Get login
- (read-packet bot))
+ (get (read-packet bot nil) 1))
(defn input-handler [bot]
(let [conn (:connection bot)]
- (while (nil? (:exit @conn))
- (read-packet bot)))
+ (loop [prev nil]
+ (if (nil? (:exit @conn))
+ (recur (read-packet bot prev))
+ prev)))
(println "done - input handler"))
@@ -69,7 +71,9 @@
new-velocity]))
(defn should-apply-gravity? [bot]
- (non-solid-blocks (:type (chunks/block-standing-in bot))))
+ (let [y (:y (:loc @(:player bot)))]
+ (or (> (- y (Math/floor y)) 0.2)
+ (non-solid-blocks (:type (chunks/block-beneath bot))))))
(defn update-location [bot]
(when (chunks/current bot)
--- a/src/clojurecraft/in.clj Mon Aug 08 21:01:07 2011 -0400
+++ b/src/clojurecraft/in.clj Tue Aug 09 00:28:51 2011 -0400
@@ -6,28 +6,14 @@
(:import [clojurecraft.data Location Entity Chunk])
(:import (java.util.zip Inflater)))
-; Bytes ----------------------------------------------------------------------------
-(defn byte-seq [b]
- (loop [n 0 b b s []]
- (if (< n 8)
- (recur (inc n) (bit-shift-right b 1) (conj s (bit-and b 1)))
- (reverse s))))
-
-(defn top [b]
- (Integer. (bit-shift-right (bit-and b 0xf0) 4)))
-
-(defn bottom [b]
- (Integer. (bit-and b 0x0f)))
-
-(defn to-unsigned [b]
- (bit-and b 0xff))
-
-
; Reading Data ---------------------------------------------------------------------
-(defn- -read-byte [conn]
+(defn- -read-byte-bare [conn]
(io!
(let [b (.readByte (:in @conn))]
- (Integer. (int b)))))
+ b)))
+
+(defn- -read-byte [conn]
+ (int (-read-byte-bare conn)))
(defn- -read-bytearray-bare [conn size]
(io!
@@ -100,8 +86,8 @@
:damage (-read-short conn))))
6 (recur (conj data (assoc {}
:i (-read-int conn)
- :j (-read-int conn)
- :k (-read-int conn))))))))))
+ :y (-read-int conn)
+ :z (-read-int conn))))))))))
; Reading Packets ------------------------------------------------------------------
@@ -364,7 +350,7 @@
nibbles []
data data]
(if (= i len)
- [nibbles data]
+ [(byte-array nibbles) data]
(let [next-byte (get data 0)
top-byte (top next-byte)
bottom-byte (bottom next-byte)]
@@ -374,8 +360,8 @@
(defn- -read-packet-mapchunk-decode [predata data-ba]
(let [len (* (:sizex predata) (:sizey predata) (:sizez predata))
- data (into [] data-ba)
- block-types (vec (map int (subvec data 0 len)))
+ data (into (vector-of :byte) data-ba) ; Make the data a vector for easier parsing.
+ block-types (byte-array (subvec data 0 len))
data (subvec data len)]
(let [[block-metadata data] (-parse-nibbles len data)
[block-light data] (-parse-nibbles len data)
@@ -395,8 +381,8 @@
buffer))
-(def FULL-CHUNK (* 16 16 28))
-(def BLANK-CHUNK-ARRAY (vec (repeatedly FULL-CHUNK #(identity nil))))
+(def FULL-CHUNK (* 16 16 128))
+(def BLANK-CHUNK-ARRAY (byte-array FULL-CHUNK))
(defn- -get-or-make-chunk [chunks coords]
(or (@chunks coords)
(let [chunk (ref (Chunk. BLANK-CHUNK-ARRAY
@@ -410,24 +396,20 @@
(dosync (let [chunk-coords (coords-of-chunk-containing x z)
chunk (-get-or-make-chunk chunks chunk-coords)
start-index (block-index-in-chunk x y z)]
- (println "Updating chunk data array with new data of size"
- (count types)
- "beginning at"
- start-index)
- (if (= (count types) FULL-CHUNK)
- (alter chunk assoc
+ (if (= (alength types) FULL-CHUNK)
+ (alter chunk assoc ; Short-circuit for speed if we have a full chunk.
:types types
:metadata meta
:light light
:skylight sky)
- (alter chunk assoc
- :types (replace-slice (:types @chunk) start-index types)
- :metadata (replace-slice (:metadata @chunk) start-index meta)
- :light (replace-slice (:light @chunk) start-index light)
- :skylight (replace-slice (:sky-light @chunk) start-index sky))))))
+ (alter chunk assoc ; Otherwise: sadness.
+ :types (replace-array-slice (:types @chunk) start-index types)
+ :metadata (replace-array-slice (:metadata @chunk) start-index meta)
+ :light (replace-array-slice (:light @chunk) start-index light)
+ :skylight (replace-array-slice (:sky-light @chunk) start-index sky))))))
(defn- read-packet-mapchunk [bot conn]
- (let [predata (assoc {}
+ (time (let [predata (assoc {}
:x (-read-int conn)
:y (-read-short conn)
:z (-read-int conn)
@@ -437,20 +419,20 @@
:compressedsize (-read-int conn))]
(let [decompressed-data (-read-packet-mapchunk-chunkdata conn predata)
decoded-data (-read-packet-mapchunk-decode predata decompressed-data)
- [types meta light sky] decoded-data]
- (time (-update-world-with-data bot
+ [types meta light sky] decoded-data] ; Note: These are all byte-array's!
+ (-update-world-with-data bot
(:x predata) (:y predata) (:z predata)
- types meta light sky))
- (assoc predata :data decompressed-data))))
+ types meta light sky)
+ (assoc predata :data decompressed-data)))))
(defn -update-single-block [bot x y z type meta]
- (println "Altering block " x y z " to be " (block-types type))
(dosync (let [chunk (chunk-containing x z (:chunks (:world bot)))
- idx (block-index-in-chunk x y z)]
+ i (block-index-in-chunk x y z)]
(when chunk
- (alter chunk assoc-in [:types idx] type)
- (alter chunk assoc-in [:metadata idx] meta)))))
+ (alter chunk assoc
+ :types (replace-array-index (:types @chunk) i type)
+ :metadata (replace-array-index (:metadata @chunk) i meta))))))
(defn- read-packet-multiblockchange [bot conn]
(let [prearrays (assoc {}
@@ -575,6 +557,7 @@
:text4 (-read-string-ucs2 conn)))
(defn- read-packet-mapdata [bot conn]
+ ; TODO: Fix this
(let [pretext (assoc {}
:unknown1 (-read-int conn)
:unknown2 (-read-short conn)
@@ -646,7 +629,7 @@
:disconnectkick read-packet-disconnectkick})
; Reading Wrappers -----------------------------------------------------------------
-(defn read-packet [bot]
+(defn read-packet [bot prev]
(let [conn (:connection bot)
packet-id-byte (-read-byte conn)]
(let [packet-id (when (not (nil? packet-id-byte))
@@ -665,11 +648,12 @@
; Handle packet
(if (nil? packet-type)
(do
- (println (str "UNKNOWN PACKET TYPE: " (Integer/toHexString packet-id)))
+ (println (str "UNKNOWN PACKET TYPE: " (Integer/toHexString packet-id) packet-id
+ " ---------- PREVIOUS: " prev))
(/ 1 0))
(let [payload (do ((packet-type packet-readers) bot conn))]
(do
(when (#{} packet-type)
(println (str "--PACKET--> " packet-type)))
- payload))))))
+ [packet-type payload]))))))
--- a/src/clojurecraft/util.clj Mon Aug 08 21:01:07 2011 -0400
+++ b/src/clojurecraft/util.clj Tue Aug 09 00:28:51 2011 -0400
@@ -14,9 +14,37 @@
(defn invert [m]
(apply assoc {} (mapcat reverse m)))
-(defn replace-slice [v start items]
- (if (empty? items)
- v
- (recur (assoc v start (first items))
- (+ 1 start)
- (rest items))))
+(defn replace-array-slice
+ "Return a new byte-array with the given elements replaced."
+ [old-arr start new-data]
+ (let [len (alength new-data)
+ new-arr (byte-array old-arr)]
+ (dorun (map #(aset-byte new-arr (+ start %) (aget new-data %))
+ (range len)))
+ new-arr))
+
+(defn replace-array-index
+ "Return a new byte-array with the given byte replaced."
+ [old-arr i b]
+ (let [new-arr (byte-array old-arr)]
+ (aset-byte new-arr i b)
+ new-arr))
+
+
+; Bytes ----------------------------------------------------------------------------
+(defn byte-seq [b]
+ (loop [n 0 b b s []]
+ (if (< n 8)
+ (recur (inc n) (bit-shift-right b 1) (conj s (bit-and b 1)))
+ (reverse s))))
+
+(defn top [b]
+ (byte (bit-shift-right (bit-and b 0xf0) 4)))
+
+(defn bottom [b]
+ (byte (bit-and b 0x0f)))
+
+(defn to-unsigned [b]
+ (bit-and b 0xff))
+
+