packet_handling.clj
Branches > main > 2817adb > files / src / net / bowmap / packet_handling.clj
(ns net.bowmap.packet-handling
(:require
[net.bowmap.network.state :as state]
[net.bowmap.network.message :as msg]
[net.bowmap.network.message.client :as client]
[net.bowmap.network.registry :as registry]
[net.bowmap.network.message.server :as server]))
; "packet handling" is inherently about the low-level protocol level, so either handle stuff at a low level or turn
; packets into high level game events to be sent somewhere else
(defmulti handle-packet
(fn [msg client]
(::msg/id msg)))
; Should return just a client...
; Should be a much better interface as well
; Basically sending a packet into the server?
(defn response
"Returns a map of a client, and any other keys a packet handler may use.
Client may be unchanged, or adorned with any information, such as a new state."
[client msg]
(let [response (handle-packet msg client)]
(if (:client response)
response
(assoc response :client client))))
(defmethod handle-packet :default [msg client]
(prn "Unhandled message:" msg))
(defmethod handle-packet ::server/handshaking [msg client]
{:client (assoc client ::state/state (:intent msg))})
(defmethod handle-packet ::server/status-request [msg client]
{:response [{::msg/id ::client/status-response
;; Should be un-bundled yeah.
:response {:version {:name "1.21.11"
:protocol 774}
:players {:online 0
:max 1000}
; Is this a text component? Could make that interface
:description {:text "Bowmap!"}
:enforcesSecureChat false}}]})
(defmethod handle-packet ::server/ping-request [msg client]
{:response [{::msg/id ::client/pong-response
:timestamp (:timestamp msg)}]})
(defmethod handle-packet ::server/login-start [msg client]
{:response [{::msg/id ::client/login-success
:uuid (:uuid msg)
:username (:username msg)
:properties []}]})
(defmethod handle-packet ::server/login-acknowledged [msg client]
{:client (assoc client ::state/state ::state/config)
:response [{::msg/id ::client/known-packs
;; TODO also probably good to unbundle this
:known-packs [{:namespace "minecraft" :id "core" :version "1.12.11"}]}]})
(defmethod handle-packet ::server/known-packs [msg client]
{:response (conj (vec registry/registry-packets)
{::msg/id ::client/finish-config})})
(defmethod handle-packet ::server/finish-config [msg client]
{:client (assoc client ::state/state ::state/play)
:keepalive true
:response [{::msg/id ::client/login
:entity-id 0 ;; TODO magic zero :p
:hardcore? false
:dimension-names ["world"]
:max-players 1000
:view-distance 32
:simulation-distance 32
:reduced-debug-info? false
:enable-respawn-screen? false
:do-limited-crafting? false
:dimension-type-id 0
:dimension-name "world"
:hashed-seed 203894
:gamemode :creative
:previous-gamemode :unknown
:debug-world? false
:superflat-world? true
:has-death-location? false
:portal-cooldown 10
:sea-level 60
:enforce-secure-chat? true}
{::msg/id ::client/game-event
:event :wait-for-chunks}]})