readers.clj
Branches > main > 4f918a3 > files / src / net / bowmap / network / frame / readers.clj
(ns net.bowmap.network.frame.readers
"Functions for reading values from frames.
Functions look like ->type, where 'type' is a Minecraft protocol type.
See https://minecraft.wiki/w/Java_Edition_protocol/Packets#Data_types"
(:require
[net.bowmap.network.frame.types :refer [max-varint-size]])
(:import
[io.netty.buffer ByteBuf]
[java.nio.charset Charset]))
(def ->byte ByteBuf/.readByte)
(def ->ubyte (comp unchecked-byte ByteBuf/.readByte))
(def ->short ByteBuf/.readShort)
(def ->ushort (comp unchecked-short ByteBuf/.readShort))
(def ->int ByteBuf/.readInt)
(def ->long ByteBuf/.readLong)
(def ->float ByteBuf/.readFloat)
(def ->double ByteBuf/.readDouble)
(defn ->varint [buf]
(loop [num-read 0
result 0]
(if (>= num-read max-varint-size)
(throw (Exception. "VarInt too long"))
(let [b (ByteBuf/.readByte buf)
result' (bit-or result (bit-shift-left (bit-and b 0x7F) (* 7 num-read)))]
(if (zero? (bit-and b 0x80))
result'
(recur (inc num-read) result'))))))
(defn ->string [buf]
(let [len (->varint buf)]
(if (neg? len)
(throw (Exception. "String length cannot be negative"))
(ByteBuf/.readCharSequence buf len (Charset/forName "UTF-8")))))
(defn ->enum [reader m]
(fn [buf]
(m (reader buf))))