a95ebcff284a

The fuck?
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Tue, 09 Aug 2011 00:28:51 -0400
parents 4d4fca0a37f9
children 325222ba620b
branches/tags (none)
files src/clojurecraft/chunks.clj src/clojurecraft/core.clj src/clojurecraft/in.clj src/clojurecraft/util.clj

Changes

--- 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))
+
+