0431d566789d

Update everything to use the new data structures.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 21 Jul 2011 21:23:41 -0400
parents 86070faebacf
children 0551a05c0e1e
branches/tags (none)
files src/clojurecraft/actions.clj src/clojurecraft/core.clj src/clojurecraft/data.clj src/clojurecraft/in.clj

Changes

--- a/src/clojurecraft/actions.clj	Thu Jul 21 20:27:23 2011 -0400
+++ b/src/clojurecraft/actions.clj	Thu Jul 21 21:23:41 2011 -0400
@@ -5,12 +5,13 @@
 (defn move [bot x-change y-change z-change]
   (let [player (:player bot)]
     (dosync
-      (let [location (:location @player)
+      (let [location (:loc @player)
             new-location (merge location
                                 {:x (+ x-change (:x location))
                                  :y (+ y-change (:y location))
                                  :z (+ z-change (:z location))
                                  :stance (+ y-change (:stance location))})]
-        (alter player merge {:location new-location}))))
+        (println (str "Moving from " location " to " new-location))
+        (alter player merge {:loc new-location}))))
   bot)
 
--- a/src/clojurecraft/core.clj	Thu Jul 21 20:27:23 2011 -0400
+++ b/src/clojurecraft/core.clj	Thu Jul 21 21:23:41 2011 -0400
@@ -3,16 +3,17 @@
   (:use [clojurecraft.in])
   (:use [clojurecraft.out])
   (:use [clojurecraft.util])
-  (:use [clojurecraft.data])
   (:use [clojure.contrib.pprint :only (pprint)])
   (:require [clojurecraft.actions :as act])
+  (:require (clojurecraft.data))
+  (:import [clojurecraft.data Location Entity Block Chunk World Bot])
   (:import (java.net Socket)
            (java.io DataOutputStream DataInputStream)
            (java.util.concurrent LinkedBlockingQueue)))
 
-(def minecraft-local {:name "localhost" :port 25565})
+(def STARTING-LOC (Location. 0 0 0 0 0 0 false))
 
-; Connections ----------------------------------------------------------------------
+; Worlds ---------------------------------------------------------------------------
 (def *worlds* (ref {}))
 (defn get-world [server]
   (dosync
@@ -25,6 +26,7 @@
           (@*worlds* server))))))
 
 
+; Connections ----------------------------------------------------------------------
 (defn login [bot username]
   ; Send handshake
   (write-packet bot :handshake {:username username})
@@ -40,8 +42,7 @@
 
 
 (defn input-handler [bot]
-  (let [conn (:connection bot)
-        test 1]
+  (let [conn (:connection bot)]
     (while (nil? (:exit @conn))
       (read-packet bot)))
   (println "done"))
@@ -50,7 +51,7 @@
   (let [conn (:connection bot)
         outqueue (:outqueue bot)]
     (while (nil? (:exit @conn))
-      (let [location (:location @(:player bot))]
+      (let [location (:loc @(:player bot))]
         (.put outqueue [:playerpositionlook location])
         (Thread/sleep 50)))))
 
@@ -68,44 +69,57 @@
         out (DataOutputStream. (.getOutputStream socket))
         conn (ref {:in in :out out})
         outqueue (LinkedBlockingQueue.)
-
         world (get-world server)
-        player (ref {:location {:onground false, :pitch 0.0, :yaw 0.0, :z 240.0,
-                                :y 85.0, :stance 60.0, :x -120.0}})
-        bot {:connection conn, :outqueue outqueue, :player player, :world world,
-             :packet-counts-in (atom {}), :packet-counts-out (atom {})}]
+        bot (Bot. conn outqueue nil world
+                  (atom {}) (atom {}))]
 
     (println "connecting")
-    (login bot username)
-    (println "connected and logged in")
+
+    ; We need to log in to find out our bot's entity ID, so we delay creation of the
+    ; player until then.
+    (let [player-id (:eid (login bot username))
+          player (ref (Entity. player-id STARTING-LOC false))
+          bot (assoc bot :player player)]
 
-    (println "starting read handler")
-    (doto (Thread. #(input-handler bot)) (.start))
-
-    (println "starting write handler")
-    (doto (Thread. #(output-handler bot)) (.start))
+      ; Theoretically another connected bot could fill in the player's entity entry
+      ; in the world before we get here, but in practice it probably doesn't matter
+      ; because we're going to fill it in anyway.
+      ;
+      ; The fact that there could be a ref thrown away is troubling.
+      ;
+      ; TODO: Think more about this.
+      (dosync (alter (:entities world) assoc player-id player))
 
-    (println "starting location updating handler")
-    (doto (Thread. #(location-handler bot)) (.start))
+      (println "connected and logged in")
+
+      (println "queueing initial keepalive packet")
+      (.put outqueue [:keepalive {}])
+
+      (println "starting read handler")
+      (.start (Thread. #(input-handler bot)))
 
-    (println "writing initial keepalive packet")
-    (.put outqueue [:keepalive {}])
+      (println "starting write handler")
+      (.start (Thread. #(output-handler bot)))
 
-    (println "all systems go, returning bot")
-    bot))
+      (println "starting location updating handler")
+      (.start (Thread. #(location-handler bot)))
+
+      (println "all systems go!")
+
+      bot)))
 
 (defn disconnect [bot]
   (dosync (alter (:connection bot) merge {:exit true})))
 
 
-; Utility functions ----------------------------------------------------------------
+; Scratch --------------------------------------------------------------------------
+(def minecraft-local {:name "localhost" :port 25565})
 
-; Scratch --------------------------------------------------------------------------
 ;(def bot (connect minecraft-local "Honeydew"))
-;(act/move bot 0 -1 0)
+;(act/move bot -2 0 0)
 ;(pprint @(:packet-counts-in bot))
 ;(pprint @(:packet-counts-out bot))
 ;(pprint (:player bot))
-;(println (:location @(:player bot)))
+;(println (:loc @(:player bot)))
 ;(disconnect bot)
 
--- a/src/clojurecraft/data.clj	Thu Jul 21 20:27:23 2011 -0400
+++ b/src/clojurecraft/data.clj	Thu Jul 21 21:23:41 2011 -0400
@@ -77,7 +77,7 @@
 ;   A queue of packets to write, so we can coordinate the writes
 ;   to avoid mixing packets together.
 ;
-;   Don't ever touch this.  Use out/-write-packet-* instead.
+;   Don't ever touch this.  Use out/write-packet instead.
 ;
 ; player -> (ref Entity)
 ;   A ref to the Entity representing the bot's player in the world.
--- a/src/clojurecraft/in.clj	Thu Jul 21 20:27:23 2011 -0400
+++ b/src/clojurecraft/in.clj	Thu Jul 21 21:23:41 2011 -0400
@@ -1,6 +1,8 @@
 (ns clojurecraft.in
   (:use [clojurecraft.util])
   (:use [clojurecraft.mappings])
+  (:require (clojurecraft.data))
+  (:import [clojurecraft.data Location])
   (:import (java.util.zip Inflater)))
 
 ; Bytes ----------------------------------------------------------------------------
@@ -117,7 +119,7 @@
 (defn- read-packet-timeupdate [bot conn]
   (let [payload (assoc {}
                        :time (-read-long conn))]
-    (dosync (alter (:world bot) assoc :time (:time payload)))
+    (dosync (ref-set (:time (:world bot)) (:time payload)))
     payload))
 
 (defn- read-packet-equipment [bot conn]
@@ -156,7 +158,10 @@
                        :yaw (-read-float conn)
                        :pitch (-read-float conn)
                        :onground (-read-bool conn))]
-    (dosync (alter (:player bot) merge {:location payload}))
+    (dosync
+      (alter (:player bot)
+             assoc :loc (merge (Location. nil nil nil nil nil nil nil)
+                               payload)))
     payload))
 
 (defn- read-packet-playerdigging [bot conn]