e126c09
Branches > main > e126c09 > files
Pre-client/connection changes
Commit: e126c095526e9c605d93d9e5bd6935e244beb0ce
Parent: 77e8015
5 changed files:
src/net/bowmap/core.clj view file
@@ -1,10 +1,11 @@ (ns net.bowmap.core (:require [net.bowmap.server :as server]+ [net.bowmap.transport.server :as mc] [nrepl.server :as nrepl])) (defn start-server! []- (Thread/.start (Thread. #(server/start-server! 25565)))+ (Thread/.start (Thread. #(mc/start-server! 25565 #'server/connection-handler))) (println "Server started!")) (defn -main [& _args]src/net/bowmap/server.clj view file
@@ -1,28 +1,22 @@ (ns net.bowmap.server (:require [net.bowmap.protocol.handle :as handle]- [net.bowmap.server.logic :as logic] [net.bowmap.server.player :as player]- [net.bowmap.stormbow.effect-execution :refer [execute-effects!]]+ [net.bowmap.stormbow.effect-execution :refer [perform!]] [net.bowmap.stormbow.event :as event]- [net.bowmap.transport.connection :as connection]- [net.bowmap.transport.server :as mc]))+ [net.bowmap.transport.connection :as connection])) -(defn handle-response [send-packet {:keys [packets events]}]- (doseq [packet packets]- (send-packet packet))- (doseq [event events]- (execute-effects! (logic/handle-events event))))--(defn handle-connection [connection]+; Will be the client handler+(defn connection-handler [connection] (let [{::connection/keys! [close-fn send-packet receive-packet]} connection] (try (loop []- (handle-response send-packet (handle/interpret-packet (assoc (receive-packet) ::connection/connection connection)))- (recur))+ (when-some [packet (receive-packet)]+ (let [{:keys [packets events]} (handle/interpret-packet (assoc packet ::connection/connection connection))]+ (run! send-packet packets)+ (run! perform! events))+ (recur))) (finally (when-let [uuid (close-fn)]- (execute-effects! (logic/handle-events {::event/id ::event/player-left ::player/uuid uuid})))))))--(defn start-server! [port]- (mc/start-server! port #'handle-connection))+ (perform! {::event/id ::event/player-left+ ::player/uuid uuid}))))))src/net/bowmap/server/server.clj view file
@@ -1,5 +1,7 @@ (ns net.bowmap.server.server) +; TODO this isn't a good name+ ; Map of player uuids to their values (defonce players (ref {})) (def max-player-count 1000)src/net/bowmap/stormbow/effect_execution.clj view file
@@ -1,7 +1,9 @@+; TODO this isn't really a stormbow thing it's a server logic thing, so it should probably go there (ns net.bowmap.stormbow.effect-execution (:require [net.bowmap.protocol.packet :as pk] [net.bowmap.protocol.packet.clientbound :as clientbound]+ [net.bowmap.server.logic :as logic] [net.bowmap.server.player :as player] [net.bowmap.server.server :as server] [net.bowmap.server.text :as text]@@ -24,3 +26,6 @@ (defn execute-effects! [effects] (run! execute-effect! effects))++(defn perform! [event]+ (execute-effects! (logic/handle-events event)))src/net/bowmap/transport/connection.clj view file
@@ -13,6 +13,7 @@ [java.io EOFException] [java.net Socket SocketException])) +; TODO This seems to couple the I/O, the protocol, and the client (defn connection "Creates a connection object from a java.net.Socket Connections have a channel of serverbound packets, and a channel of clientbound packets.@@ -23,6 +24,10 @@ state (atom {::phase/phase ::phase/handshaking}) close (fn [] (Socket/.close socket)+ ; When client and connection are split, maybe this can be a thing?+ ;(when-some [uuid (@state ::player/uuid)]+ ; (perform! {::event/id ::event/player-left+ ; ::player/uuid uuid})) (@state ::player/uuid)) conn {::close-fn close ::send-packet (fn [packet]@@ -35,26 +40,26 @@ (when-not (instance? SocketException t) (throw t))))) ::receive-packet (fn []- (when (Socket/.isClosed socket)- (throw (Exception. "Tried to read packet from a disconnected client")))- (try- (let [frame (streams/read-frame!! input-stream)- {::phase/keys! [phase]} @state- packet (decode-packet! frame phase)]- (when-let [{::pk/keys! [id]} packet]- (case id- ::serverbound/handshaking (swap! state assoc ::phase/phase (req! packet ::phase/phase))- ::serverbound/login-acknowledged (swap! state assoc ::phase/phase ::phase/config)- ::serverbound/finish-config (swap! state assoc ::phase/phase ::phase/play)- ::serverbound/login-start- (let [{:keys! [username uuid]} packet]- (swap! state assoc ::player/uuid uuid))- nil)- (merge packet (select-keys @state [::player/uuid]))))- (catch Throwable t- (close)- (when-not (or (instance? SocketException t) (instance? EOFException t))- (throw t)))))}]+ (when-not (Socket/.isClosed socket)+ (try+ ; TODO just have read-frame return nil and call (close) in a finally+ (let [frame (streams/read-frame!! input-stream)+ {::phase/keys! [phase]} @state+ packet (decode-packet! frame phase)]+ (when-let [{::pk/keys! [id]} packet]+ (case id+ ::serverbound/handshaking (swap! state assoc ::phase/phase (req! packet ::phase/phase))+ ::serverbound/login-acknowledged (swap! state assoc ::phase/phase ::phase/config)+ ::serverbound/finish-config (swap! state assoc ::phase/phase ::phase/play)+ ::serverbound/login-start+ (let [{:keys! [username uuid]} packet]+ (swap! state assoc ::player/uuid uuid))+ nil)+ (merge packet (select-keys @state [::player/uuid]))))+ (catch Throwable t+ (close)+ (when-not (or (instance? SocketException t) (instance? EOFException t))+ (throw t))))))}] (io-thread (loop [] (Thread/sleep 15000)