handle.clj

Bowmap · bowmap.git · Tickets

Branches > main > 0d6765e > files / src / net / bowmap / server / game / handle.clj

(ns net.bowmap.server.game.handle
  (:require
   [datascript.core :as d]
   [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.
   Returning a sequence of response packets."
  (fn [connection-uuid packet]
    (::packet/id packet)))

(defmethod handle-packet :default [_ _])

(defmethod handle-packet ::serverbound/status-request [_ _]
  [{::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 0
    ::p/max-player-count 1000}])

(defmethod handle-packet ::serverbound/ping-request [_ {::p/keys! [timestamp]}]
  [{::packet/id ::clientbound/pong-response
    ::p/timestamp timestamp}])

(defmethod handle-packet ::serverbound/login-start [connection-uuid {::p/keys! [uuid username]}]
  (d/transact! server/conn
               [{::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 [_ _]
  [{::packet/id ::clientbound/known-packs
    ::p/known-packs [registry/core-data-pack]}])

(defmethod handle-packet ::serverbound/known-packs [_ {::p/keys! [known-packs]}]
  (if (= [registry/core-data-pack] known-packs)
    (conj registry/registry-packets
          {::packet/id ::clientbound/finish-config})
    (throw (ex-info "Client does not support the core datapack"
                    {:known-packs known-packs}))))