open Lwt.Syntax open Shared let get_state_unsafe user_id = match User.get_state user_id with | Error _e -> assert false | Ok state -> state let handle_client request client = match Dream.session "user_id" request with | None -> Dream.log "User does not exists" |> Lwt.return | Some user_id -> (* send user island state for the first time *) let state = get_state_unsafe user_id in let* () = Dream.send ~text_or_binary:`Text client (Network.marshal (Network.Full_state state)) in let rec loop () = match%lwt Dream.receive client with | None -> (* TODO: backup everything to database *) Dream.close_websocket client | Some s -> let state = get_state_unsafe user_id in let (Network.Action_msg action : Network.client_message) = Network.unmarshal s in Dream.log "checking action %a" State.pp_action action; Dream.log "current state %a" State.pp state; let res = match State.check_action state action with | Error msg as e -> Dream.log "check_action error: %s" msg; e | Ok action' -> Dream.log "check_action ok: %a" State.pp_action' action'; let state = State.perform_action state action' in User.set_state user_id state; Ok action' in let* () = Dream.send client (Network.marshal (Network.Update_result res)) in loop () in loop ()