2ba13a7

Branches > main > 2ba13a7 > files / src / net / bowmap / server / core.clj

Add login and play packets to new client handling

Grahp, 2026-08-20

Commit: 2ba13a700f8a6862b24b82e15ab891abf71c0534
Parent: 083e2e7

1 changed file:

src/net/bowmap/network/handle.clj modified (view file)

@@ -1,10 +1,15 @@ (ns net.bowmap.network.handle   (:require+   [net.bowmap.network.chunk :as chunk]    [net.bowmap.network.client :refer [send-packet!]]    [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]+   [net.bowmap.network.registry :as reg]    [net.bowmap.network.state :as state]+   [net.bowmap.server.entity :as entity]+   [net.bowmap.server.gamemode :as gamemode]    [net.bowmap.server.server :as server]))  (defmulti handle-packet@@ -12,13 +17,15 @@     (::pk/id packet)))  (defmethod handle-packet :default [client _]-  {:client client})+  {:client client+   :packets []})  (defmethod handle-packet ::serverbound/handshaking [client pk]   (let [{:keys! [intent protocol]} pk]     {:client (assoc client                     ::state/connection-state intent-                    :protocol-id protocol)}))+                    :protocol-id protocol)+     :packets []}))  ; TODO move to a fact and the game logic handler :) (defmethod handle-packet ::serverbound/status-request [client _]@@ -33,8 +40,143 @@                          :description {:text "Bowmap!"}                          :enforcesSecureChat false}}]}) +(defmethod handle-packet ::serverbound/ping-request [client pk]+  {:client client+   :packets [{::pk/id ::clientbound/pong-response+              :timestamp (:timestamp pk)}]})++(defmethod handle-packet ::serverbound/login-start [client pk]+  (let [{:keys! [uuid username]} pk]+    {:client (assoc client ::entity/uuid uuid)+     :packets [{::pk/id ::clientbound/login-success+                :profile {:uuid uuid+                          :username username+                          :properties []}+                :session-id (random-uuid)}]}))++(defmethod handle-packet ::serverbound/login-acknowledged [client _]+  {:client (assoc client ::state/connection-state ::state/config)+   :packets [{::pk/id ::clientbound/known-packs+              ;; TODO also probably good to unbundle this+              :known-packs [{:namespace "minecraft"+                             :id "core"+                             :version "26.2"}]}]})++; TODO how to update state here?+; Yield facts from this as well and send 'em in!+; Or well, this can be retried so just use the dosync+(defmethod handle-packet ::serverbound/known-packs [client _]+  {:client client+   :packets (conj (vec (registry/registry-packets))+                  {::pk/id ::clientbound/update-tags+                   :tagged-registries [{:registry "minecraft:block"+                                        :tags [{:tag-name "bowmap:infiniburn"+                                                :entries []}]}]}++                  {::pk/id ::clientbound/update-tags+                   :tagged-registries [{:registry "minecraft:damage_type"+                                        :tags [{:tag-name "minecraft:is_fire"+                                                :entries []}+                                               {:tag-name "minecraft:is_explosion"+                                                :entries []}+                                               {:tag-name "minecraft:bypasses_shield"+                                                :entries []}]}]}++                  {::pk/id ::clientbound/update-tags+                   :tagged-registries [{:registry "minecraft:banner_pattern"+                                        :tags [{:tag-name "minecraft:pattern_item/bordure_indented" :entries []}+                                               {:tag-name "minecraft:pattern_item/creeper" :entries []}+                                               {:tag-name "minecraft:pattern_item/field_masoned" :entries []}+                                               {:tag-name "minecraft:pattern_item/flow" :entries []}+                                               {:tag-name "minecraft:pattern_item/flower" :entries []}+                                               {:tag-name "minecraft:pattern_item/globe" :entries []}+                                               {:tag-name "minecraft:pattern_item/guster" :entries []}+                                               {:tag-name "minecraft:pattern_item/mojang" :entries []}+                                               {:tag-name "minecraft:pattern_item/piglin" :entries []}+                                               {:tag-name "minecraft:pattern_item/skull" :entries []}]}]}++                  {::pk/id ::clientbound/finish-config})})+++(defn- build-chunk-packets []+  (let [pk {::pk/id ::clientbound/chunk-data-and-update-light+            :chunk-data+            (let [stone {:block-count (* 16 16 16)+                         :fluid-count 0+                         :block-states {:bpe 0+                                        :palatte 1}+                         :biomes {:bpe 0+                                  :palatte 0}}+                  air {:block-count 0+                       :fluid-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 handle-packet ::serverbound/finish-config [client _]+  (let [entity-id (entity/next-entity-id!)+        uuid (req! client ::entity/uuid)+        client (assoc client+                      ::state/connection-state ::state/play+                      ::entity/id entity-id)+        player {::entity/id entity-id+                ::entity/uuid uuid}]+    ; Bad state here, yield a fact instead, but that's later ofc+    (dosync+      (if (@server/players uuid)+        (throw (Exception. "Player tried to join with an existing UUID"))+        (commute server/players assoc uuid player)))+    {:client client+     :packets (-> [{::pk/id ::clientbound/login+                    :entity-id entity-id+                    :hardcore? false+                    ; TODO use the registry id, show that connection somehow because this is a reference to that id+                    :dimension-names [reg/world-dimension]+                    :max-players server/max-player-count+                    :view-distance 32+                    :simulation-distance 32+                    :reduced-debug-info? false+                    :enable-respawn-screen? false+                    :do-limited-crafting? false+                    :dimension-type-id reg/world-dimension-id+                    :dimension-name reg/world-dimension+                    :hashed-seed 203894+                    :gamemode ::gamemode/adventure+                    :debug-world? false+                    :superflat-world? true+                    :has-death-location? false+                    :portal-cooldown 10+                    :sea-level 60+                    :online-mode? false+                    :enforce-secure-chat? true}+                   {::pk/id ::clientbound/game-event+                    :event :wait-for-chunks}]+                  (into (build-chunk-packets))+                  (conj {::pk/id ::clientbound/synchronize-player-position+                         :teleport-id (rand-int Integer/MAX_VALUE)+                         :x 0+                         :y 16+                         :z 0+                         :velocity-x 0+                         :velocity-y 0+                         :velocity-z 0+                         :yaw 0+                         :pitch 0+                         :flags #{}}))}))+++; TODO keepalive+ (defn handle!! [client-ref packet]-  (let [{:keys [client packets]} (handle-packet @client-ref packet)]+  (let [{:keys! [client packets]} (handle-packet @client-ref packet)]     (dosync       (ref-set client-ref client))     (doseq [pk packets]