0dda787

Branches > main > 0dda787 > files

Remove player from player list after they have disconnected

Grahp, 2026-08-23

Commit: 0dda78737152f57bd21746677ff51dd14999d036
Parent: bade11c

1 changed file:

src/net/bowmap/protocol/server.clj modified (view file)

@@ -8,41 +8,63 @@    [net.bowmap.protocol.packet.serverbound :refer [decode-packet!]]    [net.bowmap.protocol.state :as state]    [net.bowmap.server.logic :as logic]+   [net.bowmap.server.player :as player]    [net.bowmap.stormbow.effect-execution :refer [execute-effects!]]+   [net.bowmap.stormbow.event :as event]    [net.bowmap.transport.connection :as connection]    [net.bowmap.transport.server :as mc]))  (defn adorn-effects-with-client [client events]   (mapv #(assoc % ::client/client client) events)) +(defn handle-serverbound-frame [client frame]+  (let [{:keys! [::state/connection-state ::client/clientbound-packets]} client+        packet (decode-packet! frame connection-state)+        {:keys [client packets events keep-alive?] :or {:client client}} (handle/interpret-packet client packet)]+    ; TODO probably want to clean up this side effecting stuff+    (doseq [pk packets]+      (put! clientbound-packets pk))+    (doseq [event events]+      (execute-effects! (adorn-effects-with-client client (logic/handle-events event))))+    (when keep-alive?+      (keepalive/keep-alive! client))+    client))++(defn client-lifecycle+  "Loops forever, handling server and client-bound packets.+   Returns the final client value at the end of the client's lifecycle."+  [client]+  (let [{:keys! [::client/clientbound-packets ::connection/connection]} client+        {::connection/keys! [serverbound-frames clientbound-frames]} connection]+    (loop [client client]+      (let [res (try+                  (alt!!+                    serverbound-frames ([frame]+                                        (if (some? frame)+                                          (handle-serverbound-frame client frame)+                                          ::disconnect))+                    clientbound-packets ([packet]+                                         (if (some? packet)+                                           (do (>!! clientbound-frames (encode-packet! packet (::state/connection-state client)))+                                               client)+                                           (throw (Exception. "Clientbound packets was closed idk why")))))+                  (catch Throwable t+                    (Throwable/.printStackTrace t)+                    ::disconnect))]+        (if (= ::disconnect res)+          client+          (recur res))))))+ (defn handle-connection [connection]   (io-thread     (let [client (client/client connection)-          clientbound-packets (req! client ::client/clientbound-packets)-          {::connection/keys! [serverbound-frames clientbound-frames close-fn]} connection]-      (try-        (loop [client client]-          (alt!!-            serverbound-frames ([frame]-                                (when (some? frame)-                                  (let [packet (decode-packet! frame (::state/connection-state client))-                                        {:keys [client packets events keep-alive?] :or {:client client}} (handle/interpret-packet client packet)]-                                    ; TODO probably want to clean up this side effecting stuff-                                    (doseq [pk packets]-                                      (put! clientbound-packets pk))-                                    (doseq [event events]-                                      (execute-effects! (adorn-effects-with-client client (logic/handle-events event))))-                                    (when keep-alive?-                                      (keepalive/keep-alive! client))-                                    (recur client))))-            clientbound-packets ([packet]-                                 (if (some? packet)-                                   (do (>!! clientbound-frames (encode-packet! packet (::state/connection-state client)))-                                       (recur client))-                                   (throw (Exception. "Clientbound packets was closed idk why"))))))-        (finally-          ; TODO Send player disconnected event, and update the player list from that-          (close-fn))))))+          {::connection/keys! [close-fn]} connection+          client (client-lifecycle client)]+      (when-let [uuid (::player/uuid client)]+        (execute-effects! (adorn-effects-with-client client+                                                     (logic/handle-events {::event/id ::event/player-left+                                                                           ::player/uuid uuid}))))+      (close-fn))))  (defn start-server! [port]   (let [connections (mc/start-server! port)]