181d0a2

Branches > facts > 181d0a2 > files / .gitignore

The new age

Grahp, 2026-08-21

Commit: 181d0a2ed1a718637ac19ecfbe18a0c9aac0f298
Parent: 616efd3

4 changed files:

src/net/bowmap/network/client.clj modified (view file)

@@ -2,23 +2,10 @@   (:require    [clojure.spec.alpha :as s]    [net.bowmap.network.connection :as connection]-   [net.bowmap.network.state :as state]-   [net.bowmap.server.entity :as entity]-   [net.bowmap.server.server :as server]))+   [net.bowmap.network.state :as state]))  (s/def ::client (s/keys :opt [::state/connection-state ::connection/connection]))  (defn client [socket]   (ref {::state/connection-state ::state/handshaking         ::connection/connection (connection/connection socket)}))--(defn leave! [client-ref]-  (dosync-    (let [{:keys! [::connection/connection] :keys [::playing? ::entity/uuid]} @client-ref]-      (try-        (when playing?-          ; What should really happen if this fails?-          ; Probably should come up with a better solution-          (commute server/players dissoc uuid))-        (finally-          (send connection connection/close!))))))

src/net/bowmap/network/connection.clj modified (view file)

@@ -15,17 +15,10 @@           ::input-stream (Socket/.getInputStream socket)           ::output-stream (Socket/.getOutputStream socket)})) -(defn read-frame! [input-stream]-  (let [{:keys! [::input-stream]} connection]-    (streams/read-frame!! input-stream))-  connection)- (defn send-frame-action! [connection frame]   (let [{:keys! [::output-stream]} connection]     (streams/write-frame!! frame output-stream)     connection)) -(defn keep-alive-action! [connection])- (defn close! [connection]   (Socket/.close (req! connection ::socket)))

src/net/bowmap/network/handle.clj modified (view file)

@@ -34,7 +34,7 @@   {:facts [{::fact/id ::fact/server-list-requested             ::client/client client}]}) -(defmethod handle-packet ::serverbound/ping-request [client pk]+(defmethod handle-packet ::serverbound/ping-request [_ pk]   {:packets [{::pk/id ::clientbound/pong-response               :timestamp (:timestamp pk)}]}) @@ -116,6 +116,8 @@              :chunk-z z))))  (defmethod handle-packet ::serverbound/finish-config [client _]+  ; TODO shit, this is not a pure function!+  ; I'm just going to pretend like this is a pure function for now.   (let [entity-id (entity/next-entity-id!)         uuid (req! client ::entity/uuid)         client (assoc client@@ -164,6 +166,7 @@                          :flags #{}}))      :keepalive? true})) +; TODO just make this a pure function and put the handling logic elsewhere to make the separation clearer (defn handle!! [client-ref packet]   (dosync     ; May want sync-facts vs. async-facts?

src/net/bowmap/network/server.clj modified (view file)

@@ -1,7 +1,8 @@ (ns net.bowmap.network.server   (:require    [clojure.core.async :refer [io-thread]]-   [net.bowmap.network.client :as client :refer [leave!]]+   [net.bowmap.network.client :as client]+   [net.bowmap.network.connection :as connection]    [net.bowmap.network.handle :as handle]    [net.bowmap.network.packets.serverbound :refer [decode-packet!]]    [net.bowmap.network.state :as state]@@ -20,17 +21,31 @@     (loop []       (let [socket (ServerSocket/.accept server-socket)             input-stream (Socket/.getInputStream socket)+            ; HERE IS THE NEW AGE!+            ; A client is a piece of data, it has state info+            ; Get this ref out of here, we don't like it.+            ; Connections do I/O, and they need no state.+            ; They're just for frames+            ; They also don't need synchronized+            ; There does need to be one point in the program where serverbound packets are handled 1 at a time+            ; And a new client state will be returned from that handling, as well as other things to happen             client-ref (client/client socket)]         (io-thread           (try+            ; TODO also read packets from the clientbound channel!             (loop []               (let [frame (streams/read-frame!! input-stream)]                 (dosync                   (->> (decode-packet! frame (::state/connection-state @client-ref))+                       ; So I want sending a clientbound packet to be kind of a private detail+                       ; But it could happen asynchronously at any time...+                       ; So the client may need to keep its connection object, which I don't love.+                       ; Perhaps a map of player uuids to connections/to a queue you could send packets out onto would be best?                        (handle/handle!! client-ref))))               (recur))             (catch EOFException _)             (catch SocketException _)             (finally-              (leave! client-ref)))))+              ; TODO Send player disconnected packet+              (send (@client-ref ::connection/connection) connection/close!)))))       (recur))))