logic.clj

Branches > facts > cc5984f > files / src / net / bowmap / server / logic.clj

(ns net.bowmap.server.logic
  (:require
   ; TODO I'd be skeptical of references to protocol stuff from within server...
   ; This is really only here so the response handler can know who to send the response to
   [net.bowmap.protocol.client :as client]
   [net.bowmap.server.entity :as entity]
   [net.bowmap.server.player :as player]
   [net.bowmap.server.server :as server]
   [net.bowmap.stormbow.fact :as fact]
   [net.bowmap.stormbow.response :as response]))

(defmulti handler
  (fn [fact]
    (::fact/id fact)))

(defmethod handler ::fact/server-list-requested [{:keys! [::client/client]}]
  [{::response/id ::response/send-server-list
    ::client/client client
    :server-list-response {:version {:name "26.2"
                                     :protocol 776}
                           :players {:online (count @server/players)
                                     :max server/max-player-count}
                           :description {:text "Bowmap!"}
                           :enforcesSecureChat false}}])

; Want this to be pure, which means you need a way to encode that state change as data?
(defmethod handler ::fact/player-joined [{::player/keys! [player]}]
  (let [{::entity/keys! [uuid]} player]
    (if (@server/players uuid)
      (throw (Exception. "Player tried to join with an existing UUID"))
      (commute server/players assoc uuid player))
    []))

(defmethod handler ::fact/player-left [{:keys! [::entity/uuid]}]
  (commute server/players dissoc uuid)
  [])

; Returns a seq of responses
; And document that this is not called synchronously (hence the transactions as well)
(defn handle-fact [fact]
  ; TODO I think this is fine because it has to be run within a transaction anyway?
  ; All though I suppose not all fact handling needs to be in a transaction some is trivial so idk.
  (dosync (handler fact)))