07359c8
Branches > main > 07359c8 > files
Handle client packets
Commit: 07359c8b196676595877bb4a2e8094343785f201
Parent: 58deb69
3 changed files:
src/net/bowmap/core.clj 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 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 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))))))