133 lines
3.3 KiB
Fennel
133 lines
3.3 KiB
Fennel
(local socket (require "socket"))
|
|
|
|
;; Guide: https://www.love2d.org/wiki/Tutorial:Networking_with_UDP
|
|
|
|
;; Configuration
|
|
(local config {
|
|
:host "localhost"
|
|
:port 9999
|
|
})
|
|
|
|
;; Network state
|
|
(local state {
|
|
:socket nil
|
|
:connected false
|
|
; :player-id nil
|
|
; :last-error nil
|
|
})
|
|
|
|
;; Callback functions for network events
|
|
; (local callbacks {
|
|
; :on-ready (fn [])
|
|
; :on-wait (fn [])
|
|
; :on-opponent-update (fn [data])
|
|
; :on-error (fn [error])
|
|
; })
|
|
|
|
(fn init []
|
|
"Initialize UDP connection to server
|
|
Returns true on success, false on error"
|
|
(let [udp (socket.udp)]
|
|
(udp:setpeername config.host config.port)
|
|
(udp:settimeout 0) ; non-blocking
|
|
|
|
(set state.socket udp)
|
|
(set state.connected true)))
|
|
|
|
(fn send-msg [dg]
|
|
(state.socket:send dg))
|
|
|
|
(fn update [dt]
|
|
(let [(data msg) (state.socket:receive)]
|
|
(when data
|
|
(print (fennel.view {: data : msg})))))
|
|
|
|
; (fn register []
|
|
; "Send REGISTER message to server"
|
|
; (when state.socket
|
|
; (try
|
|
; (state.socket:send "REGISTER")
|
|
; (catch err
|
|
; (set state.last-error err)
|
|
; (when callbacks.on-error (callbacks.on-error err))))))
|
|
|
|
; (fn split-string [str delimiter]
|
|
; "Split string by delimiter into table"
|
|
; (local result [])
|
|
; (local current "")
|
|
; (each [i 1 (length str) 1]
|
|
; (let [char (string.sub str i i)]
|
|
; (if (= char delimiter)
|
|
; (do
|
|
; (table.insert result current)
|
|
; (set current ""))
|
|
; (set current (.. current char)))))
|
|
; (table.insert result current)
|
|
; result)
|
|
|
|
; (fn parse-message [msg]
|
|
; "Parse message in format: COMMAND#arg1#arg2#..."
|
|
; (split-string msg "#"))
|
|
|
|
; (fn send-update [x y rotation battery]
|
|
; "Send player state to server in format: UPDATE#x#y#rotation#battery"
|
|
; (when state.socket
|
|
; (try
|
|
; (let [msg (.. "UPDATE#" x "#" y "#" rotation "#" battery)]
|
|
; (state.socket:send msg))
|
|
; (catch err
|
|
; (set state.last-error err)))))
|
|
|
|
; (fn update [dt]
|
|
; "Call from love.update to process incoming messages"
|
|
; (when state.socket
|
|
; (let [(msg _src-ip _src-port) (state.socket:receivefrom)]
|
|
; (when msg
|
|
; (let [parts (parse-message msg)
|
|
; command (. parts 1)]
|
|
; (match command
|
|
; "READY_TO_PLAY" (callbacks.on-ready)
|
|
; "WAIT" (callbacks.on-wait)
|
|
; "UPDATE" (callbacks.on-opponent-update {
|
|
; :x (tonumber (. parts 2))
|
|
; :y (tonumber (. parts 3))
|
|
; :rotation (tonumber (. parts 4))
|
|
; :battery (tonumber (. parts 5))
|
|
; })
|
|
; _ (print (.. "← Message: " msg))))))))
|
|
|
|
; (fn set-callback [event cb]
|
|
; "Register callback for network events
|
|
; Available events: :on-ready :on-wait :on-opponent-update :on-error"
|
|
; (tset callbacks event cb))
|
|
|
|
(fn close []
|
|
"Close network connection"
|
|
(when state.socket
|
|
(state.socket:close)
|
|
(set state.socket nil)
|
|
(set state.connected false)))
|
|
|
|
; (fn is-connected []
|
|
; "Check if currently connected to server"
|
|
; state.connected)
|
|
|
|
; (fn get-last-error []
|
|
; "Get the last error that occurred"
|
|
; state.last-error)
|
|
|
|
;; Export public API
|
|
{
|
|
: init
|
|
: update
|
|
: state
|
|
: send-msg
|
|
: close
|
|
; :register register
|
|
; :send-update send-update
|
|
; :update update
|
|
; :set-callback set-callback
|
|
; :close close
|
|
; :is-connected is-connected
|
|
; :get-last-error get-last-error
|
|
}
|