bdc7514

Branches > main > bdc7514 > files

the great packet purge...

Grahp, 2026-07-10

Commit: bdc751415d3b16e80e7d6a97ca57cfee015e61c9
Parent: a8bd38f

10 changed files:

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

@@ -73,23 +73,23 @@          {::msg/id ::clientbound/finish-config})})  (defn- build-chunk-messages []-  (let [pk {::msg/id ::clientbound/chunk-data-and-update-light-            :chunk-data-            (let [stone {:block-count (* 16 16 16)-                         :block-states {:bpe 0-                                        :palatte 1}-                         :biomes {:bpe 0-                                  :palatte 0}}-                  air {:block-count 0-                       :block-states {:bpe 0-                                      :palatte 0}-                       :biomes {:bpe 0-                                :palatte 0}}]-              {:data (cons stone (repeat (- chunk/world-height-chunk-sections 1) air))})-            :light-data {}}]+  (let [msg {::msg/id ::clientbound/chunk-data-and-update-light+             :chunk-data+             (let [stone {:block-count (* 16 16 16)+                          :block-states {:bpe 0+                                         :palatte 1}+                          :biomes {:bpe 0+                                   :palatte 0}}+                   air {:block-count 0+                        :block-states {:bpe 0+                                       :palatte 0}+                        :biomes {:bpe 0+                                 :palatte 0}}]+               {:data (cons stone (repeat (- chunk/world-height-chunk-sections 1) air))})+             :light-data {}}]     (for [x (range -16 17)           z (range -16 17)]-      (assoc pk+      (assoc msg              :chunk-x x              :chunk-z z)))) 

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

@@ -9,10 +9,11 @@    [net.bowmap.network.protocol.message.clientbound :as clientbound]    [net.bowmap.network.protocol.message.serverbound :as serverbound]    [net.bowmap.network.protocol.state :as state]-   [net.bowmap.network.server :as server]))+   [net.bowmap.network.server :as server]+   [net.bowmap.server.step :as step])) -(defn handle-incoming-packet [client packet outgoing-messages]-  (let [message (serverbound/packet->message packet (::state/connection-state client))+(defn handle-incoming-frame [client frame outgoing-messages]+  (let [message (serverbound/frame->message frame (::state/connection-state client))         {::client/keys! [client] ::a/keys [messages keep-alive?]} (a/handle-message message client)]     (doseq [message messages]       (put! outgoing-messages message))@@ -25,18 +26,18 @@             (recur)))))     client)) -(defn handle-packets!! [client outgoing-messages]+(defn handle-client!! [client outgoing-messages]   (let [{::server/keys! [incoming-frames outgoing-frames]} client]     (alt!!       incoming-frames       ([frame]        (if (some? frame)-         (handle-incoming-packet client frame outgoing-messages)+         (handle-incoming-frame client frame outgoing-messages)          (raise "client incoming frame channel closed!")))       outgoing-messages       ([message]        (if (some? message)-         (do (>!! outgoing-frames (clientbound/message->packet message (::state/connection-state client)))+         (do (>!! outgoing-frames (clientbound/message->frame message (::state/connection-state client)))              client)          (raise "client outgoing message channel closed!")))))) @@ -44,7 +45,7 @@   (let [outgoing-messages (chan 1024)]     (io-thread       (loop [client client]-        (recur (handle-packets!! client outgoing-messages))))+        (recur (handle-client!! client outgoing-messages))))     nil))  (defn closing-promise@@ -69,4 +70,8 @@           (do (connect! client)               (recur))           (deliver shutdown :shutdown))))+    (io-thread+      (loop [model model]+        (let [[model' effects] (step/step model fact)])+        (recur)))     shutdown))

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

@@ -0,0 +1,10 @@+(ns net.bowmap.network.protocol.frame+  (:require+   [clojure.spec.alpha :as s])+  (:import+   [io.netty.buffer ByteBuf]))++; The serialized byte form of a message+; See https://minecraft.wiki/w/Java_Edition_protocol/Packets++(s/def ::frame #(instance? ByteBuf %))

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

@@ -4,15 +4,14 @@    [dev.grahp.spec :as S]))  (S/def ::id-  "The id of a message. See the serverbound and clientbound packet definitions for the names."+  "The id of a message. See the serverbound and clientbound message definitions for the names."   qualified-keyword?)  (S/def ::numeric-id-  "Protocol id of a packet, i.e. 0x00, 0x80, etc.+  "Protocol id of a message, i.e. 0x00, 0x80, etc.    Numeric ids are NOT unique across connection states! See the wiki"   pos-int?)  (S/def ::message-  "Represents a logical message map (object) from client to/from server.-   'Packet' is used to refer to a serialized message"+  "Represents a logical message map (object) from client to/from server."   (s/keys :opt [::id]))

src/net/bowmap/network/protocol/message/clientbound.clj modified (view file)

@@ -4,7 +4,7 @@    [clojure.spec.alpha :as s]    [dev.grahp.build :refer [build]]    [net.bowmap.network.protocol.message :as msg]-   [net.bowmap.network.protocol.packet :as pk]+   [net.bowmap.network.protocol.frame :as frame]    [net.bowmap.network.protocol.types :as t]    [net.bowmap.network.protocol.writers :as write     :refer [bit-mask-> boolean-> byte-> chunk-data-> coerce context-optional->@@ -17,34 +17,34 @@   (:import    [io.netty.buffer Unpooled])) -(defn build-packet-ids-  "Builds a map of connection states and message ids to packet ids.+(defn build-numeric-ids+  "Builds a map of connection states and message ids to numeric ids.    Message ids may be duplicated across connection states."   [registry]-  (build [[state packet-ids] registry-          [i id] (map-indexed vector packet-ids)]+  (build [[state numeric-ids] registry+          [i id] (map-indexed vector numeric-ids)]     [{::state/connection-state state       ::msg/id id}      i])) -(s/fdef build-packet-ids+(s/fdef build-numeric-ids         :args (s/cat :registry (s/map-of ::state/connection-state (s/coll-of ::msg/id :type vector?)))         :ret (s/map-of (s/keys :opt [::state/connection-state ::msg/id]) ::msg/numeric-id)) -(defn build-packets+(defn build-messages   "Builds a map of message ids to message writers."   [registry]-  (reduce (fn [acc [packet-id table]]-            (assoc acc packet-id (coerce table)))+  (reduce (fn [acc [numeric-id table]]+            (assoc acc numeric-id (coerce table)))           {} registry)) -(s/fdef build-packets+(s/fdef build-messages         :args (s/cat :registry (s/map-of ::msg/id ::t/table))         :ret (s/map-of ::msg/id ::write/writer))  ; TODO terrible name?-(def message->packet-ids-  (build-packet-ids+(def numeric-id+  (build-numeric-ids     {::state/status      [::status-response       ::pong-response]@@ -219,8 +219,8 @@       ::clear-dialog       ::show-dialog-play]})) -(def packets-  (build-packets+(def messages+  (build-messages     {::status-response [:response "Response to serverbound ::status-request" json->]      ::pong-response [:timestamp "The same timestamp as serverbound ::ping-request" long->]      ::login-success [:uuid uuid->@@ -283,17 +283,17 @@                                                         :relative-velocity-x :relative-velocity-y :relative-velocity-z                                                         :rotate-velocity])]})) -(defn message->packet-  "Encodes a message into a packet.-   Like decoding, encoding a packet requires the connection state, as packet-   ids are not unique across connection states. Several packets are logically+(defn message->frame+  "Encodes a message into a frame.+   Like decoding, encoding a message requires the connection state, as message+   ids are not unique across connection states. Several messages are logically    the same across states, and can be sent without needing to switch on state."   [msg state]-  (let [payload-writer (req! packets (::msg/id msg))]+  (let [payload-writer (req! messages (::msg/id msg))]     (length-prefixed (-> (Unpooled/buffer)-                         (varint-> (req! message->packet-ids {::msg/id (::msg/id msg) ::state/connection-state state}))+                         (varint-> (req! numeric-id {::msg/id (::msg/id msg) ::state/connection-state state}))                          (payload-writer msg))))) -(s/fdef message->packet+(s/fdef message->frame         :args (s/cat :msg ::msg/message :state ::state/connection-state)-        :ret ::pk/packet)+        :ret ::frame/frame)

src/net/bowmap/network/protocol/message/serverbound.clj modified (view file)

@@ -5,7 +5,7 @@    [dev.grahp.build :refer [build]]    [dev.grahp.error :refer [adorn raise]]    [net.bowmap.network.protocol.message :as msg]-   [net.bowmap.network.protocol.packet :as pk]+   [net.bowmap.network.protocol.frame :as frame]    [net.bowmap.network.protocol.readers     :refer [->bit-mask ->byte ->double ->enum ->float ->identifier ->int             ->list ->long ->optional ->position ->short ->string ->ubyte@@ -16,19 +16,19 @@  ; TODO docstring, rename? (defn build-message-readers [registry]-  (reduce (fn [acc [packet-id table]]-            (assoc acc packet-id+  (reduce (fn [acc [numeric-id table]]+            (assoc acc numeric-id                    (let [reader (coerce table)]                      (fn [buf]                        (assoc (reader buf)-                              ::msg/id packet-id)))))+                              ::msg/id numeric-id)))))           {} registry))  ; TODO docstring, rename? ; TODO spec for sure (defn build-message-id-map [registry]-  (build [[state packet-ids] registry-          [i id] (map-indexed vector packet-ids)]+  (build [[state numeric-ids] registry+          [i id] (map-indexed vector numeric-ids)]     [{::state/connection-state state       ::msg/numeric-id i}      id]))@@ -132,7 +132,7 @@  (def ^{:spec (s/map-of ::msg/id (s/fspec :args (s/cat :buf #(instance? ByteBuf %))                                          :ret ::msg/message))}-  packets+  messages   (build-message-readers     ; Handshaking     {::handshaking [:protocol ->varint@@ -174,8 +174,8 @@      ::custom-click-action TODO      ::accept-code-of-conduct TODO -     ;; This packet has more fields I just don't care about them :p-     ;; This packet also has a bunch of fields that I probably do care about!+     ;; This message has more fields I just don't care about them :p+     ;; This message also has a bunch of fields that I probably do care about!       ; Play @@ -263,28 +263,28 @@      ::use-item TODO}))  (assert (= (set (vals numeric-ids))-           (set (keys packets))))+           (set (keys messages))))  (comment   (require '[clojure.set :as set])   (let [all-ids (set (vals numeric-ids))-        present-ids (set (keys packets))]+        present-ids (set (keys messages))]     (set/difference all-ids present-ids))) -(defn packet->message-  "Deserializes one (framed, serialized) packet into a message.-   The initial length field of the packet should be stripped from the buffer.+(defn frame->message+  "Deserializes one frame into a message.+   The initial length field of the frame should be stripped from the buffer!    Can throw if:-    1. No such packet with the given numeric id and state exists-    2. No schema exists for that packet id+    1. No such frame with the given numeric id and state exists+    2. No schema exists for that message id     3. 'buf' is not properly framed-    4. The contents of 'buf' are not a valid packet"-  [packet state]-  (let [numeric-id (->varint packet)+    4. The contents of 'buf' are not a valid message"+  [frame state]+  (let [numeric-id (->varint frame)         message-id (req! numeric-ids {::state/connection-state state ::msg/numeric-id numeric-id})-        reader (req! packets message-id)]-    (adorn (reader packet) "Error while calling packet reader" {:numeric-id numeric-id :packet-id message-id :reader reader})))+        reader (req! messages message-id)]+    (adorn (reader frame) "Error while calling message reader" {:numeric-id numeric-id :message-id message-id :reader reader}))) -(s/fdef packet->message-        :args (s/cat :packet ::pk/packet :state ::state/connection-state)+(s/fdef frame->message+        :args (s/cat :frame ::frame/frame :state ::state/connection-state)         :ret ::msg/message)

src/net/bowmap/network/protocol/packet.clj deleted (view file)

@@ -1,11 +0,0 @@-(ns net.bowmap.network.protocol.packet-  (:require-   [dev.grahp.spec :as S])-  (:import-   [io.netty.buffer ByteBuf]))--; The serialized byte form of a message-; See https://minecraft.wiki/w/Java_Edition_protocol/Packets--; TODO rename to a frame, packet is still an overloaded term-(S/def ::packet #(instance? ByteBuf %))

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

@@ -1,5 +1,5 @@ (ns net.bowmap.network.protocol.readers-  "Functions for reading data from serialized packet ByteBufs.+  "Functions for reading data from frames.    When given bad data, read functions will throw.    See https://minecraft.wiki/w/Java_Edition_protocol/Packets#Data_types"   (:require

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

@@ -7,24 +7,24 @@    [java.net ServerSocket Socket]))  (defn new-client [socket]-  (let [packets-in (chan)-        packets-out (chan)]+  (let [incoming-frames (chan)+        outgoing-frames (chan)]     (io-thread       (loop []         (try (let [frame (stream/read-frame!! (Socket/.getInputStream socket))]-               (>!! packets-in frame))+               (>!! incoming-frames frame))              (catch Exception _-               ; Disconnect packet?+               ; Disconnect?                (Socket/.close socket)))         (recur)))      (io-thread       (loop []-        (let [frame (<!! packets-out)]+        (let [frame (<!! outgoing-frames)]           (stream/write-frame!! frame (Socket/.getOutputStream socket)))         (recur)))-    {::incoming-frames packets-in-     ::outgoing-frames packets-out}))+    {::incoming-frames incoming-frames+     ::outgoing-frames outgoing-frames}))  (defn start-tcp-server!   "Starts a TCP server at the given port. Returns a channel of clients as they connect.

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

@@ -3,7 +3,7 @@ ; Where is this called, who's controlling this loop? (defn step [model fact] ; -> [model [effects]]   (case (:id model)-    :status-requested ; Effect status response which eventually sends out packets to the client+    :status-requested ; Effect status response which eventually sends out messages to the client     (let [{:keys! [client]} fact]       [model        [{:effect/id :send-status-response