f9703b2
Branches > main > f9703b2 > files / src / net / bowmap
Implement everything in the protocol up to registry data (oh boy)
Commit: f9703b2dec6755752de923e7f29537fa12bd8a7f
Parent: 6cc1acd
6 changed files:
src/net/bowmap/network/client.clj view file
@@ -54,6 +54,7 @@ (OutputStream/.flush output-stream))) (defn send-clientbound-packet [client packet]+ (println "sending packet out: " packet) (write-frame!! (encode-packet! packet (req! client ::state/connection-state)) (Socket/.getOutputStream (req! client ::socket))) client)src/net/bowmap/network/handle.clj view file
@@ -1,40 +1,150 @@ (ns net.bowmap.network.handle (:require+ [net.bowmap.network.chunk :as chunk] [net.bowmap.network.client :as client] [net.bowmap.network.packet :as pk] [net.bowmap.network.packets.clientbound :as clientbound]+ [net.bowmap.network.packets.registry :as registry] [net.bowmap.network.packets.serverbound :as serverbound :refer [decode-packet!]]- [net.bowmap.network.state :as state]))+ [net.bowmap.network.state :as state]+ [net.bowmap.server.gamemode :as gamemode])) ; Handles incoming packets from clients +(defmulti handler+ (fn [client client-agent packet]+ (::pk/id packet)))++(defmethod handler :default [client a pk]+ (prn "Unhandled packet:" pk)+ client)++(defmethod handler ::serverbound/handshaking [client _ pk]+ (assoc client+ ::state/connection-state (req! pk :intent)+ :protocol-id (req! pk :protocol)))++(defmethod handler ::serverbound/status-request [client a _]+ (send a client/send-clientbound-packet+ {::pk/id ::clientbound/status-response+ ;; Should be un-bundled yeah.+ :response {:version {:name "26.2"+ :protocol 776}+ :players {:online 0+ :max 1000}+ ; Is this a text component? Could make that interface+ :description {:text "Bowmap!"}+ :enforcesSecureChat false}})+ client)++(defmethod handler ::serverbound/ping-request [client a pk]+ (send a client/send-clientbound-packet+ {::pk/id ::clientbound/pong-response+ :timestamp (:timestamp pk)})+ client)++(defmethod handler ::serverbound/login-start [client a pk]+ (let [{:keys! [uuid username]} pk]+ (send a client/send-clientbound-packet+ {::pk/id ::clientbound/login-success+ :profile {:uuid uuid+ :username username+ :properties []}+ :uuid uuid}))+ client)++(defmethod handler ::serverbound/login-acknowledged [client a pk]+ (send a client/send-clientbound-packet+ {::pk/id ::clientbound/known-packs+ ;; TODO also probably good to unbundle this+ :known-packs [{:namespace "minecraft"+ :id "core"+ :version "1.12.11"}]})+ (assoc client ::state/connection-state ::state/config))++(defmethod handler ::serverbound/known-packs [client a pk]+ (doseq [pk (registry/registry-packets)]+ (send a client/send-clientbound-packet pk))+ (send a client/send-clientbound-packet {::pk/id ::clientbound/finish-config})+ client)++(defn- build-chunk-messages []+ (let [pk {::pk/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+ :chunk-x x+ :chunk-z z))))++(defmethod handler ::serverbound/finish-config [client a pk]+ (send a client/send-clientbound-packet+ {::pk/id ::clientbound/login+ ;; TODO magic zero :p+ ;; I think you can keep a registry of entity ids and stick this on the client+ :entity-id 0+ :hardcore? falsesrc/net/bowmap/network/packets/clientbound.clj view file
@@ -3,9 +3,9 @@ [net.bowmap.network.packet :as pk] [net.bowmap.network.packets.writers :as write :refer [bit-mask-> boolean-> byte-> chunk-data-> coerce context-optional->- double-> enum-> float-> identifier-> int-> json-> length-prefixed- light-data-> list-> long-> nbt-> optional-> or-> position->- string-> ubyte-> uuid-> varint->]]+ double-> enum-> float-> game-profile-> identifier-> int-> json->+ length-prefixed light-data-> list-> long-> nbt-> optional-> or->+ position-> string-> ubyte-> uuid-> varint->]] [net.bowmap.network.registry :as reg] [net.bowmap.network.state :as state] [net.bowmap.server.gamemode :as gamemode])@@ -189,11 +189,8 @@ (def packets {::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-> [:name string->- :value string->- :signature (optional-> string->)])]+ ::login-success [:profile game-profile->+ :uuid uuid->] ::known-packs [:known-packs (list-> [:namespace string-> :id string-> :version string->])]src/net/bowmap/network/packets/registry.clj view file
@@ -0,0 +1,14 @@+(ns net.bowmap.network.packets.registry+ (:require+ [net.bowmap.network.packet :as pk]+ [net.bowmap.network.packets.clientbound :as clientbound]+ [net.bowmap.network.registry :as reg]))++; Not in love with this...+(defn registry-packets []+ (for [[id m] (partition 2 reg/registries)]+ {::pk/id ::clientbound/registry-data+ ::reg/id id+ ::reg/entries (for [[entry-id data] m]+ {::reg/entry-id entry-id+ ::reg/entry-data data})}))src/net/bowmap/network/packets/writers.clj view file
@@ -30,6 +30,7 @@ (CompositeByteBuf/.addComponent true buf))) (defn string-> [buf s]+ {:pre [(string? s)]} (doto buf (varint-> (count s)) (ByteBuf/.writeCharSequence s (Charset/forName "UTF-8"))))@@ -67,6 +68,7 @@ (fn [buf m] (write-table! buf table m)))) + (defn coerce "If writer is an actual writer, returns it. If writer is a vector, turnes it into a table writer." [writer]@@ -236,6 +238,12 @@ (boolean-> buf x) (writer buf x)))) +(def game-profile-> (table-> [:uuid uuid->+ :username string->+ :properties (list-> [:name string->+ :value string->+ :signature (optional-> string->)])]))+ ; Chunks ; TODO eventually encode pallates and the different valuessrc/net/bowmap/network/registry.clj view file
@@ -1,6 +1,7 @@ (ns net.bowmap.network.registry (:require- [net.bowmap.network.chunk :as chunk]))+ [net.bowmap.network.chunk :as chunk]+ [net.bowmap.network.packet :as pk])) ;; Some way to keep track of order of these things and make that clear... ;; Probably a map of id -> order?@@ -81,6 +82,7 @@ :whine_sound "minecraft:entity.wolf.ambient"}}])) ;; Make a map of ids -> order+; This probably has to be per-client since different clients could have different registries #_(defn registry-id "Function to get the ordered numerical id from a given registry id" [id])