0b64212

Bowmap · bowmap.git · Tickets

Branches > main > 0b64212 > files / src / net / bowmap

Add functions to encode and decode packets

Grahp, 2026-09-06

Commit: 0b6421211abed4d29c1b1794151452f083f1938a
Parent: 6cf19ed

3 changed files:

src/net/bowmap/network/frame/types.clj modified (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 added (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 added (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)))