server.clj

Branches > main > 0b339d9 > files / src / net / bowmap / network / server.clj

(ns net.bowmap.network.server
  (:require
   [clojure.core.async :refer [>!! alt!! chan close! 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.packets.serverbound :refer [decode-packet!]]
   [net.bowmap.network.state :as state])
  (:import
   [java.net ServerSocket]))

(defonce server (atom nil))

; TODO handle errors and disconnect player
; Send player disconnected fact, and update the player list from that
(defn handle-client [client]
  (io-thread
    (let [serverbound-frames (chan 64)
          clientbound-packets (req! client ::client/clientbound-packets)]
      (io-thread
        (try
          (loop []
            (>!! serverbound-frames (connection/read-frame!! (::connection/connection client)))
            (recur))
          (finally
            (close! 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]
  (when-let [server @server]
    (ServerSocket/.close server))
  (let [server-socket (ServerSocket. port)]
    (reset! server server-socket)
    (loop []
      (let [socket (ServerSocket/.accept server-socket)
            client (client/client socket)]
        (handle-client client))
      (recur))))