core.clj

Branches > client-handling-rewrite > e26c58d > files / src / net / bowmap / core.clj

(ns net.bowmap.core
  (:require
   [clojure.core.async :refer [>!! alt!! chan]]
   [net.bowmap.network.client :as c]
   [net.bowmap.network.message.client :as client]
   [net.bowmap.network.message.server :as server]
   [net.bowmap.network.state :as state]
   [net.bowmap.packet-handling :as handle]
   [net.bowmap.server :as server-process]))

;; TODO server should just provide messages in/out

(defn read-and-handle-packet
  "Reads/deserializes one packet into a message, and handles it.
   Because packet reading is dependent on the state of the client, and handling a packet can update the state of the client,
   Reading and handling must be synchronized!"
  [pk client]
  (when-some [msg (server/packet->message pk (::state/connection-state client))]
    (handle/handle-packet!! client msg)))


; TODO bad positional arguments, use a map?
; TODO only send in things to the server, the rest is stateful
(defn handle-packets-and-messages [client packets-in messages-out packets-out]
  (alt!!
    messages-out ([msg]
                  (when msg
                    ; Make one of these keepalive
                    ; How does keepalive begin though?
                    (assert (>!! packets-out (client/message->packet msg (::state/connection-state client))))
                    client))
    packets-in ([pk]
                (when pk
                  (read-and-handle-packet pk client)))))

; Do I need to close out?
; So clients should be managed by the server and they're not really data are they
(defn client-handler [packets-in packets-out]
  (let [messages-out (chan) ; Use like 1024 so it can block but only when bad things are happening bad things are afoot
        client-state {::state/connection-state ::state/handshaking
                      ; TODO this is used but get rid of it/make it generic and pass it around not a key of player
                      ::c/messages-out messages-out}]
    ; Client is not data
    (loop [client client-state]
      ; TODO this can just... stop the loop
      (when-some [client (handle-packets-and-messages client packets-in messages-out packets-out)]
        (recur client)))))

(defn start-server []
  (server-process/start-server! {:handler #'client-handler
                                 :logger-fn prn
                                 :port 25565}))

(defn -main [& _args]
  (start-server)
  (println "Server Started"))

(comment
  (def server (start-server))
  (.close server))