# HG changeset patch # User Steve Losh # Date 1312864131 14400 # Node ID a95ebcff284a89b41c678ec9556098b599422bfa # Parent 4d4fca0a37f937e24c6569125f356db15407ae1e The fuck? diff -r 4d4fca0a37f9 -r a95ebcff284a src/clojurecraft/chunks.clj --- 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 diff -r 4d4fca0a37f9 -r a95ebcff284a src/clojurecraft/core.clj --- 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) diff -r 4d4fca0a37f9 -r a95ebcff284a src/clojurecraft/in.clj --- 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])))))) diff -r 4d4fca0a37f9 -r a95ebcff284a src/clojurecraft/util.clj --- 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)) + +