0dda787
Branches > main > 0dda787 > files
Remove player from player list after they have disconnected
Commit: 0dda78737152f57bd21746677ff51dd14999d036
Parent: bade11c
1 changed file:
src/net/bowmap/protocol/server.clj 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)]