0b64212
Branches > main > 0b64212 > files / src / net / bowmap
Add functions to encode and decode packets
Commit: 0b6421211abed4d29c1b1794151452f083f1938a
Parent: 6cf19ed
3 changed files:
src/net/bowmap/network/frame/types.clj view file
@@ -1,3 +1,8 @@-(ns net.bowmap.network.frame.types)+(ns net.bowmap.network.frame.types+ (:import+ [io.netty.buffer Unpooled])) (def max-varint-size 5)++(defn frame []+ (Unpooled/buffer))src/net/bowmap/network/packet.clj view file
@@ -0,0 +1,9 @@+(ns net.bowmap.network.packet+ "A Minecraft protocol packet sent either to the server (serverbound),+ or to the client (clientbound).+ See https://minecraft.wiki/w/Java_Edition_protocol/Packets"+ (:require+ [clojure.spec.alpha :as s]))++(s/def ::id qualified-keyword?)+(s/def ::packet (s/keys :opt [::id]))src/net/bowmap/network/packets.clj view file
@@ -0,0 +1,42 @@+(ns net.bowmap.network.packets+ (:require+ [net.bowmap.network.clientbound-packets :refer [clientbound-packets]]+ [net.bowmap.network.frame.readers :as readers]+ [net.bowmap.network.frame.types :refer [frame]]+ [net.bowmap.network.frame.writers :as writers]+ [net.bowmap.network.packet :as packet]+ [net.bowmap.network.phase :as phase]+ [net.bowmap.network.serverbound-packets :refer [serverbound-packets]]))++(defn- find-indexed+ "Takes a seq of pairs and returns both the index of the first pair+ 'keyed' by the given id and its 'value' in linear time.+ E.g. (find-indexed [:a [] :b {} :c #{}] :b) -> [1 {}]"+ [id pairs]+ (some (fn [[i [k v]]]+ (when (= id k)+ [i v]))+ (map-indexed vector (partition 2 pairs))))++(defn encode-packet+ "Encodes a packet into a frame.+ Throws when the packet cannot be encoded."+ [{::phase/keys! [phase]} {::packet/keys! [id] :as packet}]+ (let [schemas (clientbound-packets phase)+ [numeric-id schema] (find-indexed id schemas)+ payload-writer (writers/to-writer schema)]+ (writers/length-prefixed+ (-> (frame)+ (writers/varint-> numeric-id)+ (payload-writer packet)))))++(defn decode-frame+ "Decodes a packet from a frame.+ Can throw if the frame does not contain a valid packet."+ [{:keys! [::phase/phase]} frame]+ (let [numeric-id (readers/->varint frame)+ schemas (serverbound-packets phase)+ [id schema] (nth (partition 2 schemas) numeric-id)+ payload-reader (readers/to-reader schema)]+ (assoc (payload-reader frame)+ ::packet/id id)))