07359c8

Bowmap · bowmap.git · Tickets

Branches > main > 07359c8 > files

Handle client packets

Grahp, 2026-09-08

Commit: 07359c8b196676595877bb4a2e8094343785f201
Parent: 58deb69

3 changed files:

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

@@ -1,10 +1,8 @@ (ns net.bowmap.core   (:require    [net.bowmap.network.server :as server]-   [nrepl.server :as nrepl])-  (:import-   [java.net ServerSocket]))+   [nrepl.server :as nrepl]))  (defn -main [& _args]   (spit ".nrepl-port" (req! (nrepl/start-server) :port))-  @(server/run-server! (ServerSocket. 25565)))+  @(server/run-server! :port 25565))

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

@@ -0,0 +1,33 @@+(ns net.bowmap.network.client+  (:require+   [medley.core :refer [assoc-some]]+   [net.bowmap.network.packet :as packet]+   [net.bowmap.network.packets :as packets]+   [net.bowmap.network.phase :as phase]+   [net.bowmap.network.serverbound-packets :as serverbound]))++(defn phase-transition+  "Returns the phase a client should take on after parsing 'packet', or nil."+  [packet]+  (case (req! packet ::packet/id)+    ::serverbound/handshaking (req! packet ::phase/phase)+    ::serverbound/login-acknowledged ::phase/config+    ::serverbound/finish-config ::phase/play+    nil))++(defn with-state-transition+  "Updates the client with any state transitions caused by 'packet'.+   Serverbound packets may:+    1. Update the connection phase+    2. Update encryption state+    3. Update compression state"+  [client packet]+  (assoc-some client ::phase/phase (phase-transition packet)))++(defn apply-serverbound-frame+  "Decodes 'frame' using the given client state, and returns [client' packet].+   Decoding a frame can update a client's connection phase, encryption state,+   and compression state"+  [client frame]+  (let [packet (packets/decode-frame client frame)]+    [(with-state-transition client packet) packet]))

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

@@ -1,13 +1,33 @@ (ns net.bowmap.network.server-  (:import-   [java.net ServerSocket]))+  (:require+   [clojure.core.async :refer [<!! chan io-thread put!]]+   [net.bowmap.network.client :refer [apply-serverbound-frame]]+   [net.bowmap.network.connection :as connection]+   [net.bowmap.network.phase :as phase]+   [net.bowmap.network.socket :as socket]))++(defn client-step+  ([_] {::phase/phase ::phase/handshaking})+  ([client in frame]+   (case in+     ::connection/serverbound-frames (apply-serverbound-frame client frame))))++(defn handle-connection! [{::connection/keys! [serverbound-frames]}]+  (let [serverbound-packets (chan 1024)]+    (io-thread+      (loop [client-state (client-step nil)]+        (when-some [frame (<!! serverbound-frames)]+          (let [[client' packet] (client-step client-state ::connection/serverbound-frames frame)]+            (put! serverbound-packets packet)+            (recur client')))))))  (defn run-server!-  "Starts running the Minecraft server with the supplied server socket.-   Returns a future that will deliver with an exception when the server closes."-  [server-socket]-  (future-    (loop []-      (let [socket (ServerSocket/.accept server-socket)]-        (println "Client connected:" socket)-        (recur)))))+  "Starts running the Minecraft server.+   Returns a future that delivers when the server closes."+  [& {:keys [& :port :bind-addr] :as args}]+  (let [server (socket/server-socket args)]+    (future+      (loop []+        (when-some [connection (<!! server)]+          (handle-connection! connection)+          (recur))))))