181d0a2
Branches > main > 181d0a2 > files / src / net / bowmap / server
The new age
Commit: 181d0a2ed1a718637ac19ecfbe18a0c9aac0f298
Parent: 616efd3
4 changed files:
src/net/bowmap/network/client.clj 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 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 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 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))))