42f9fba
Branches > main > 42f9fba > files
Update client message writing
Commit: 42f9fba9fbd23946cb6b20d501472c2ebda79df2
Parent: 15f3896
3 changed files:
src/dev/grahp/error.clj view file
@@ -71,3 +71,9 @@ (str/trim-newline (s/explain-str ~spec x#))) (assoc ~m '~x x#)) x#))))++(defmacro get!+ "Same as '(get k m)', but throws an error when the key is not present"+ ([m k] (get! ~m ~k "Failed get!, no such key in map!"))+ ([m k msg]+ `(get ~m ~k (raise ~msg {:map ~m :key ~k}))))src/net/bowmap/network/message/client.clj view file
@@ -4,19 +4,19 @@ (:require [clojure.alpha.spec :as s] [dev.grahp.build :refer [build]]- [dev.grahp.error :refer [adorn assert!]]+ [dev.grahp.error :refer [adorn get!]] [net.bowmap.network.message :as msg] [net.bowmap.network.packet :as pk]- [net.bowmap.network.packet.types :as t] [net.bowmap.network.packet.write :refer [boolean-> byte-> context-optional-> enum-> float->- identifier-> int-> json-> list->- long-> nbt-> optional-> or->- position-> string-> table->- ubyte-> uuid-> varint->]]+ identifier-> int-> json->+ length-prefixed list-> long->+ nbt-> optional-> or-> position->+ string-> table-> ubyte-> uuid->+ varint->]] [net.bowmap.network.state :as state]) (:import- [io.netty.buffer ByteBuf CompositeByteBuf Unpooled]))+ [io.netty.buffer ByteBuf Unpooled])) ; TODO docstrings! (defn build-packet-ids [registry]@@ -32,14 +32,12 @@ (assoc acc packet-id (table-> table))) {} registry)) +; TODO docstring? (def ^{:spec (s/map-of (s/schema [::state/connection-state ::msg/id]) ::pk/id)} packet-ids- ; TODO docstrings shouldn't contain these yeag...- ; Update- "Map of [::state/state ::pk/id] to numeric-id.- Packet ids (::pk/id) could map directly to numeric-ids and be stateless,- but some packets have duplicates across connection states that you'd want to handle in the same way.- If it turns out that I don't end up handling packets in this way, then packet ids could map directly to numeric ids."+ ; Packet ids could map directly to numeric-ids and be stateless,+ ; but some packets have duplicates across connection states that you'd want to handle in the same way.+ ; If it turns out that I don't end up handling packets in this way, then packet ids could map directly to numeric ids." (build-packet-ids {::state/status [::status-response@@ -218,8 +216,8 @@ :ret #(instance? ByteBuf %)))} packets (build-packets- {::status-response [:response "Response to ::sp/status-request" json->]- ::pong-response [:timestamp "The same timestamp as ::sp/ping-request" long->]+ {::status-response [:response "Response to serverbound ::status-request" json->]+ ::pong-response [:timestamp "The same timestamp as serverbound ::ping-request" long->] ::login-success [:uuid uuid-> :username string-> :properties (list-> (table-> [:name string->@@ -261,32 +259,6 @@ ::game-event [:event (enum-> byte-> {3 :set-gamemode 13 :wait-for-chunks}) :value (or-> float-> 0)]})) -(defn- numeric-id [pk state]- (assert! (packet-ids {::state/connection-state state ::msg/id (::msg/id pk)})- {:pk pk :state state}- "No such packet with that id."))--(defn- packet-encoder [pk]- (assert! (packets (::msg/id pk))- {:pk pk}- "No such encoder for that packet."))--(defn- length-prefixed- "Returns a composite bytebuf prefixed by the varint length of 'buf'."- [buf]- (-> (Unpooled/compositeBuffer 2)- ; TODO document, 5 is the max lenght a varint could be, same with the other magic number 5- (CompositeByteBuf/.addComponent true (varint-> (Unpooled/buffer t/max-varint-size) (ByteBuf/.writerIndex buf)))- (CompositeByteBuf/.addComponent true buf)))--(defn- encoded-packet- "Returns an encoded packet."- [pk state]- (let [encode-body (packet-encoder pk)]- (length-prefixed (-> (Unpooled/buffer)- (varint-> (numeric-id pk state))- (encode-body pk)))))- (defn message->packet "Encodes packet 'pk' into a ByteBuf of the packet bytes. Like decoding, encoding a packet also requires the connection state, as@@ -295,6 +267,9 @@ There are several packets (disconnect, keep alive) that are logically the same across connection states, and so can be sent without needing to switch on the connection state."- [pk state]- (adorn (encoded-packet pk state)- "Error while encoding message into packet" {:pk pk :state state}))+ [msg state]+ (-> (let [encode-body (get! packets msg)]+ (length-prefixed (-> (Unpooled/buffer)+ (varint-> (get! packet-ids msg state))+ (encode-body msg))))+ (adorn "Error while encoding message into packet" {:pk msg :state state})))src/net/bowmap/network/packet/write.clj view file
@@ -9,7 +9,7 @@ [dev.grahp.spec :as S] [net.bowmap.network.packet.types :as t]) (:import- [io.netty.buffer ByteBuf]+ [io.netty.buffer ByteBuf CompositeByteBuf Unpooled] [java.nio.charset Charset] [java.util UUID])) @@ -23,6 +23,14 @@ (recur (ByteBuf/.writeByte buf (bit-or b 0x80)) nxt))))) +(defn length-prefixed+ "Returns a new ByteBuf prefixed by an encoded varint of the length of 'buf'."+ [buf]+ (-> (Unpooled/compositeBuffer 2)+ (CompositeByteBuf/.addComponent true (varint-> (Unpooled/buffer t/max-varint-size) (ByteBuf/.writerIndex buf)))+ (CompositeByteBuf/.addComponent true buf)))++ (defn string-> [buf s] (doto buf (varint-> (count s))