handle.clj
Branches > main > 4e07f38 > files / src / net / bowmap / server / game / handle.clj
(ns net.bowmap.server.game.handle
(:require
[com.wotbrew.relic :as rel]
[net.bowmap.server.game.player :as player]
[net.bowmap.server.game.server :as server]
[net.bowmap.server.network.connection :as connection]
[net.bowmap.server.protocol.clientbound-packets :as clientbound]
[net.bowmap.server.protocol.component :as component]
[net.bowmap.server.protocol.packet :as packet]
[net.bowmap.server.protocol.registry :as registry]
[net.bowmap.server.protocol.schema :as p]
[net.bowmap.server.protocol.serverbound-packets :as serverbound]))
(defmulti handle-packet
"Handles a packet from a player given their connection uuid. Takes the game
state, and returns a vector of nil or a state value, followed by 0 or more
response packets."
(fn [state connection-uuid packet]
(::packet/id packet)))
(defmethod handle-packet :default [_ _ _])
(defmethod handle-packet ::serverbound/status-request [state _ _]
[nil
{::packet/id ::clientbound/status-response
::p/version-name "26.3"
::p/protocol 777
::p/motd {::component/text "Bowmap!"
::component/color "#9f9f9f"}
::p/online-player-count (count (state ::server/players))
::p/max-player-count 1000}])
(defmethod handle-packet ::serverbound/ping-request [_ _ {::p/keys! [timestamp]}]
[nil
{::packet/id ::clientbound/pong-response
::p/timestamp timestamp}])
(defmethod handle-packet ::serverbound/login-start [state connection-uuid {::p/keys! [uuid username]}]
[(rel/transact state
[:insert ::server/players
{::player/uuid uuid
::player/username username
::connection/connection-uuid connection-uuid}])
{::packet/id ::clientbound/login-success
::p/game-profile {::p/uuid uuid
::p/username username
::p/game-profile-properties []}
::p/session-uuid connection-uuid}])
(defmethod handle-packet ::serverbound/login-acknowledged [_ _ _]
[nil
{::packet/id ::clientbound/known-packs
::p/known-packs [registry/core-data-pack]}])
(defmethod handle-packet ::serverbound/known-packs [state _ {::p/keys! [known-packs]}]
(if (= [registry/core-data-pack] known-packs)
(cons state
(conj registry/registry-packets
{::packet/id ::clientbound/finish-config}))
(throw (ex-info "Client does not support the core datapack"
{:known-packs known-packs}))))