e126c09

Branches > main > e126c09 > files

Pre-client/connection changes

Grahp, 2026-08-31

Commit: e126c095526e9c605d93d9e5bd6935e244beb0ce
Parent: 77e8015

5 changed files:

src/net/bowmap/core.clj modified (view file)

@@ -1,10 +1,11 @@ (ns net.bowmap.core   (:require    [net.bowmap.server :as server]+   [net.bowmap.transport.server :as mc]    [nrepl.server :as nrepl]))  (defn start-server! []-  (Thread/.start (Thread. #(server/start-server! 25565)))+  (Thread/.start (Thread. #(mc/start-server! 25565 #'server/connection-handler)))   (println "Server started!"))  (defn -main [& _args]

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

@@ -1,28 +1,22 @@ (ns net.bowmap.server   (:require    [net.bowmap.protocol.handle :as handle]-   [net.bowmap.server.logic :as logic]    [net.bowmap.server.player :as player]-   [net.bowmap.stormbow.effect-execution :refer [execute-effects!]]+   [net.bowmap.stormbow.effect-execution :refer [perform!]]    [net.bowmap.stormbow.event :as event]-   [net.bowmap.transport.connection :as connection]-   [net.bowmap.transport.server :as mc]))+   [net.bowmap.transport.connection :as connection])) -(defn handle-response [send-packet {:keys [packets events]}]-  (doseq [packet packets]-    (send-packet packet))-  (doseq [event events]-    (execute-effects! (logic/handle-events event))))--(defn handle-connection [connection]+; Will be the client handler+(defn connection-handler [connection]   (let [{::connection/keys! [close-fn send-packet receive-packet]} connection]     (try       (loop []-        (handle-response send-packet (handle/interpret-packet (assoc (receive-packet) ::connection/connection connection)))-        (recur))+        (when-some [packet (receive-packet)]+          (let [{:keys [packets events]} (handle/interpret-packet (assoc packet ::connection/connection connection))]+            (run! send-packet packets)+            (run! perform! events))+          (recur)))       (finally         (when-let [uuid (close-fn)]-          (execute-effects! (logic/handle-events {::event/id ::event/player-left ::player/uuid uuid})))))))--(defn start-server! [port]-  (mc/start-server! port #'handle-connection))+          (perform! {::event/id ::event/player-left+                     ::player/uuid uuid}))))))

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

@@ -1,5 +1,7 @@ (ns net.bowmap.server.server) +; TODO this isn't a good name+ ; Map of player uuids to their values (defonce players (ref {})) (def max-player-count 1000)

src/net/bowmap/stormbow/effect_execution.clj modified (view file)

@@ -1,7 +1,9 @@+; TODO this isn't really a stormbow thing it's a server logic thing, so it should probably go there (ns net.bowmap.stormbow.effect-execution   (:require    [net.bowmap.protocol.packet :as pk]    [net.bowmap.protocol.packet.clientbound :as clientbound]+   [net.bowmap.server.logic :as logic]    [net.bowmap.server.player :as player]    [net.bowmap.server.server :as server]    [net.bowmap.server.text :as text]@@ -24,3 +26,6 @@  (defn execute-effects! [effects]   (run! execute-effect! effects))++(defn perform! [event]+  (execute-effects! (logic/handle-events event)))

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

@@ -13,6 +13,7 @@    [java.io EOFException]    [java.net Socket SocketException])) +; TODO This seems to couple the I/O, the protocol, and the client (defn connection   "Creates a connection object from a java.net.Socket    Connections have a channel of serverbound packets, and a channel of clientbound packets.@@ -23,6 +24,10 @@         state (atom {::phase/phase ::phase/handshaking})         close (fn []                 (Socket/.close socket)+                ; When client and connection are split, maybe this can be a thing?+                ;(when-some [uuid (@state ::player/uuid)]+                ;    (perform! {::event/id ::event/player-left+                ;               ::player/uuid uuid}))                 (@state ::player/uuid))         conn {::close-fn close               ::send-packet (fn [packet]@@ -35,26 +40,26 @@                                   (when-not (instance? SocketException t)                                     (throw t)))))               ::receive-packet (fn []-                                 (when (Socket/.isClosed socket)-                                   (throw (Exception. "Tried to read packet from a disconnected client")))-                                 (try-                                   (let [frame (streams/read-frame!! input-stream)-                                         {::phase/keys! [phase]} @state-                                         packet (decode-packet! frame phase)]-                                     (when-let [{::pk/keys! [id]} packet]-                                       (case id-                                         ::serverbound/handshaking        (swap! state assoc ::phase/phase (req! packet ::phase/phase))-                                         ::serverbound/login-acknowledged (swap! state assoc ::phase/phase ::phase/config)-                                         ::serverbound/finish-config      (swap! state assoc ::phase/phase ::phase/play)-                                         ::serverbound/login-start-                                         (let [{:keys! [username uuid]} packet]-                                           (swap! state assoc ::player/uuid uuid))-                                         nil)-                                       (merge packet (select-keys @state [::player/uuid]))))-                                   (catch Throwable t-                                     (close)-                                     (when-not (or (instance? SocketException t) (instance? EOFException t))-                                       (throw t)))))}]+                                 (when-not (Socket/.isClosed socket)+                                   (try+                                     ; TODO just have read-frame return nil and call (close) in a finally+                                     (let [frame (streams/read-frame!! input-stream)+                                           {::phase/keys! [phase]} @state+                                           packet (decode-packet! frame phase)]+                                       (when-let [{::pk/keys! [id]} packet]+                                         (case id+                                           ::serverbound/handshaking        (swap! state assoc ::phase/phase (req! packet ::phase/phase))+                                           ::serverbound/login-acknowledged (swap! state assoc ::phase/phase ::phase/config)+                                           ::serverbound/finish-config      (swap! state assoc ::phase/phase ::phase/play)+                                           ::serverbound/login-start+                                           (let [{:keys! [username uuid]} packet]+                                             (swap! state assoc ::player/uuid uuid))+                                           nil)+                                         (merge packet (select-keys @state [::player/uuid]))))+                                     (catch Throwable t+                                       (close)+                                       (when-not (or (instance? SocketException t) (instance? EOFException t))+                                         (throw t))))))}]     (io-thread       (loop []         (Thread/sleep 15000)