b6f2926
Branches > main > b6f2926 > files
Rename connection state to phase and move to transport layer
Commit: b6f2926e34f07e7601a965a1f3d3ab360bc3b6f3
Parent: 8adfb52
6 changed files:
src/net/bowmap/protocol/packet/clientbound.clj view file
@@ -6,7 +6,7 @@ light-data-> list-> long-> nbt-> optional-> or-> position-> string-> ubyte-> uuid-> varint->]] [net.bowmap.protocol.registry :as reg]- [net.bowmap.protocol.state :as state]+ [net.bowmap.transport.phase :as phase] [net.bowmap.server.gamemode :as gamemode])) (def packets@@ -85,10 +85,10 @@ :entries (list-> varint->)])])]}) (def packet-order- {::state/status+ {::phase/status [::status-response ::pong-response]- ::state/login+ ::phase/login ; TODO do the message ids actually have to be different just because a different encoded format is used for the same logic message? [::login-disconnect ; Uses JSON instead of a text component :p ::encryption-request@@ -96,7 +96,7 @@ ::set-compression ::login-plugin-request ::cookie-request]- ::state/config+ ::phase/config [::cookie-request ::plugin-message ::disconnect@@ -117,7 +117,7 @@ ::clear-dialog ::show-dialog ::code-of-conduct]- ::state/play+ ::phase/play [::bundle-delimiter ::spawn-entity ::entity-animationsrc/net/bowmap/protocol/packet/serverbound.clj view file
@@ -4,7 +4,7 @@ :refer [->bit-mask ->boolean ->byte ->double ->enum ->float ->identifier ->int ->list ->location ->long ->optional ->short ->string ->ubyte ->uuid ->varint]]- [net.bowmap.protocol.state :as state]+ [net.bowmap.transport.phase :as phase] [net.bowmap.server.position :as position])) (def unused-fields [])@@ -16,7 +16,7 @@ :address ->string :port ->short ; TODO move to protocol state when that ns is sorted- :intent (->enum ->varint {1 ::state/status 2 ::state/login 3 ::state/transfer})]+ :intent (->enum ->varint {1 ::phase/status 2 ::phase/login 3 ::phase/transfer})] ; Status ::status-request []@@ -92,19 +92,19 @@ ::swing-arm [:hand (->enum ->varint [:main-hand :off-hand])]}) (def packet-order- "Map of connection states to vectors of serverbound packet ids in the order the appear in the protocol."- {::state/handshaking+ "Map of connection phases to vectors of serverbound packet ids in the order the appear in the protocol."+ {::phase/handshaking [::handshaking]- ::state/status+ ::phase/status [::status-request ::ping-request]- ::state/login+ ::phase/login [::login-start ::encryption-response ::login-plugin-response ::login-acknowledged ::cookie-response]- ::state/config+ ::phase/config [::client-information ::cookie-response ::plugin-message@@ -115,7 +115,7 @@ ::known-packs ::custom-click-action ::accept-code-of-conduct]- ::state/play+ ::phase/play [::confirm-teleportation ::attack ::query-block-entity-tagsrc/net/bowmap/protocol/state.clj view file
@@ -1,4 +0,0 @@-(ns net.bowmap.protocol.state- (:require [clojure.spec.alpha :as s]))--(s/def ::connection-state #{::handshaking ::status ::login ::config ::play})src/net/bowmap/transport/connection.clj view file
@@ -5,7 +5,7 @@ [net.bowmap.protocol.packet :as pk] [net.bowmap.protocol.packet.clientbound :as clientbound] [net.bowmap.protocol.packet.serverbound :as serverbound]- [net.bowmap.protocol.state :as state]+ [net.bowmap.transport.phase :as phase] [net.bowmap.server.player :as player] [net.bowmap.transport.packets :refer [decode-packet! encode-packet!]] [net.bowmap.transport.streams :as streams])@@ -13,22 +13,14 @@ [java.io EOFException] [java.net Socket SocketException])) -; TODO should all this decoding of packets be here instead?-; Connection state definitely should, so maybe packet stuff should as well-; But packets are protocol level stuff, so idk.-; The packets themselves are protocol-level, their parsing is network/transport level-; Or whatever I want to call this package.-; I think the barrier should be bytebuf readers and writers should be here, and the packets can use those functions-; Since they don't just describe serialization, but also schema and structure (defn handle-serverbound-frame! [state frame]- ; TODO rename to protocol state, connection state is a misleading name- (let [{::state/keys! [connection-state]} @state- {::pk/keys! [id] :as packet} (decode-packet! frame connection-state)]+ (let [{::phase/keys! [phase]} @state+ {::pk/keys! [id] :as packet} (decode-packet! frame phase)] (case id- ::serverbound/handshaking (swap! state assoc ::state/connection-state (req! packet :intent))- ::serverbound/login-acknowledged (swap! state assoc ::state/connection-state ::state/config)- ::serverbound/finish-config (swap! state assoc ::state/connection-state ::state/play)+ ::serverbound/handshaking (swap! state assoc ::phase/phase (req! packet :intent))+ ::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/username username ::player/uuid uuid))@@ -46,7 +38,7 @@ clientbound-packets (chan 64) input-stream (Socket/.getInputStream socket) output-stream (Socket/.getOutputStream socket)- state (atom {::state/connection-state ::state/handshaking})+ state (atom {::phase/phase ::phase/handshaking}) closed-promise (promise) conn {::close-fn (fn [] (Socket/.close socket)@@ -60,7 +52,7 @@ (loop [] (when (= ::not-closed (deref (promise) 0 ::not-closed)) (<!! (timeout 15000))- (when (#{::state/config ::state/play} (::state/connection-state @state))+ (when (#{::phase/config ::phase/play} (::phase/phase @state)) (put! clientbound-packets {::pk/id ::clientbound/keep-alive :id (rand-int Integer/MAX_VALUE)}))@@ -77,11 +69,12 @@ (close! serverbound-packets) (deliver closed-promise (@state ::player/uuid)) (Socket/.close socket))))+ (io-thread (try (loop [] (when-some [packet (<!! clientbound-packets)]- (streams/write-frame!! (encode-packet! packet (req! @state ::state/connection-state)) output-stream)+ (streams/write-frame!! (encode-packet! packet (req! @state ::phase/phase)) output-stream) (recur))) (finally (close! clientbound-packets))))src/net/bowmap/transport/packets.clj view file
@@ -5,7 +5,7 @@ [net.bowmap.transport.readers :as readers] [net.bowmap.protocol.packet.serverbound :as serverbound] [net.bowmap.transport.writers :as writers]- [net.bowmap.protocol.state :as state])+ [net.bowmap.transport.phase :as phase]) (:import [io.netty.buffer Unpooled])) @@ -13,9 +13,9 @@ (defn build-clientbound-packet-id-index [registry] (into {}- (for [[state packet-ids] registry+ (for [[phase packet-ids] registry [i id] (map-indexed vector packet-ids)]- [{::state/connection-state state+ [{::phase/phase phase ::pk/id id} i]))) @@ -30,25 +30,23 @@ (defn encode-packet! "Encodes a packet into a frame.- Requires the connection state, as packet ids are not unique across connection states.- Several packets are logically the same across states."- [packet state]+ Requires the connection phase, as packet ids are not unique across phases.+ Several packets are logically the same across phases."+ [packet phase] (let [payload-writer (req! packet-encoders (::pk/id packet))] (writers/length-prefixed (-> (Unpooled/buffer)- (writers/varint-> (req! clientbound-packet-ids {::pk/id (::pk/id packet) ::state/connection-state state}))+ (writers/varint-> (req! clientbound-packet-ids {::pk/id (::pk/id packet) ::phase/phase phase})) (payload-writer packet))))) ; Serverbound -(defn build-serverbound-packet-id-index- "Takes a map of connection states to vectors of packet ids and returns a map of [connection-state numeric-id] to packet ids"- [registry]+(defn build-serverbound-packet-id-index [registry] (into {}- (for [[state packet-ids] registry- [i id] (map-indexed vector packet-ids)]- [{::state/connection-state state- ::pk/numeric-id i}- id])))+ (for [[phase packet-ids] registry+ [i id] (map-indexed vector packet-ids)]+ [{::phase/phase phase+ ::pk/numeric-id i}+ id]))) (defn build-packet-readers [registry]@@ -63,13 +61,10 @@ (def serverbound-packet-ids (build-serverbound-packet-id-index serverbound/packet-order)) (def packet-decoders (build-packet-readers serverbound/packets)) -; So _this_ belongs in transport-; As do the above maps and functions-; But the schema is fine here :) (defn decode-packet! "Decodes a packet from a frame."- [frame connection-state]+ [frame phase] (let [numeric-id (readers/->varint frame)- packet-id (req! serverbound-packet-ids {::state/connection-state connection-state ::pk/numeric-id numeric-id})+ packet-id (req! serverbound-packet-ids {::phase/phase phase ::pk/numeric-id numeric-id}) decode-fn (req! packet-decoders packet-id)] (decode-fn frame)))src/net/bowmap/transport/phase.clj view file
@@ -0,0 +1,5 @@+(ns net.bowmap.transport.phase+ "The phase of connection, also known as a connection state or protocol state in Minecraft."+ (:require [clojure.spec.alpha :as s]))++(s/def ::phase #{::handshaking ::status ::login ::config ::play})