server.clj

Branches > main > 21b5507 > files / src / net / bowmap / network / server.clj

(ns net.bowmap.network.server
  (:require
   [clojure.core.async :refer [<!! alt!! io-thread]]
   [net.bowmap.network.client :as client :refer [send-packet!!]]
   [net.bowmap.network.connection :as connection]
   [net.bowmap.network.handle :as handle]
   [net.bowmap.network.minecraft-server :as mc]
   [net.bowmap.network.packets.serverbound :refer [decode-packet!]]
   [net.bowmap.network.state :as state]))

; TODO handle errors and disconnect player
; Send player disconnected fact, and update the player list from that
(defn handle-connection [connection]
  (io-thread
    (let [client (client/client connection)
          clientbound-packets (req! client ::client/clientbound-packets)
          serverbound-frames (req! connection ::connection/serverbound-frames)]
      (loop [client client]
        (recur
          (alt!!
            serverbound-frames ([frame]
                                (if (some? frame)
                                  (handle/handle!! client (decode-packet! frame (::state/connection-state client)))
                                  ; TODO should you disconnect the client when this happens?
                                  (throw (Exception. "AAAAH"))))
            clientbound-packets ([pk]
                                 (if (some? pk)
                                   ; TODO Can't sending packets change the client state?
                                   (do (send-packet!! client pk)
                                       client)
                                   (throw (Exception. "Disconnect, eventually"))))))))))

(defn start-server! [port]
  (let [connections (mc/start-server! port)]
    (loop []
      (when-let [connection (<!! connections)]
        (handle-connection connection))
      (recur))))