From 6ef69cec02cb2e503faa14d8deeb640221bf09dc Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 5 Jun 2020 16:49:24 +0100 Subject: [PATCH] Even more cleanup and refactor to simplify handlers --- pkg/server/routes.go | 93 ++++++++------------------------------------ pkg/server/server.go | 28 ++++++++++--- 2 files changed, 39 insertions(+), 82 deletions(-) diff --git a/pkg/server/routes.go b/pkg/server/routes.go index cd157c8..6bcb672 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -7,12 +7,11 @@ import ( "net/http" "github.com/google/uuid" - "github.com/mdiluz/rove/pkg/game" "github.com/mdiluz/rove/pkg/version" ) // Handler describes a function that handles any incoming request and can respond -type Handler func(*Server, io.ReadCloser, io.Writer) error +type Handler func(*Server, io.ReadCloser, io.Writer) (interface{}, error) // Route defines the information for a single path->function route type Route struct { @@ -51,29 +50,22 @@ var Routes = []Route{ } // HandleStatus handles the /status request -func HandleStatus(s *Server, b io.ReadCloser, w io.Writer) error { +func HandleStatus(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { - // Simply encode the current status - var response = StatusResponse{ + // Simply return the current server status + return StatusResponse{ Ready: true, Version: version.Version, - } - - // Reply with the current status - json.NewEncoder(w).Encode(response) - - return nil + }, nil } // HandleRegister handles /register endpoint -func HandleRegister(s *Server, b io.ReadCloser, w io.Writer) error { - - // Set up the response +func HandleRegister(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { var response = RegisterResponse{ Success: false, } - // Pull out the registration info + // Decode the registration info, verify it and register the account var data RegisterData err := json.NewDecoder(b).Decode(&data) if err != nil { @@ -87,31 +79,20 @@ func HandleRegister(s *Server, b io.ReadCloser, w io.Writer) error { response.Error = err.Error() } else { - // log the data sent - fmt.Printf("\tdata: %+v\n", data) - - // If we didn't fail, respond with the account ID string response.Id = acc.Id.String() response.Success = true } - // Log the response - fmt.Printf("\tresponse: %+v\n", response) - - // Reply with the current status - json.NewEncoder(w).Encode(response) - - return nil + return response, nil } // HandleSpawn will spawn the player entity for the associated account -func HandleSpawn(s *Server, b io.ReadCloser, w io.Writer) error { - // Set up the response +func HandleSpawn(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { var response = SpawnResponse{ Success: false, } - // Pull out the incoming info + // Decode the spawn info, verify it and spawn the rover for this account var data SpawnData if err := json.NewDecoder(b).Decode(&data); err != nil { fmt.Printf("Failed to decode json: %s\n", err) @@ -127,46 +108,20 @@ func HandleSpawn(s *Server, b io.ReadCloser, w io.Writer) error { response.Error = err.Error() } else { - - // Create a new rover response.Success = true response.Position = pos - } - // Log the response - fmt.Printf("\tresponse: %+v\n", response) - - // Reply with the current status - json.NewEncoder(w).Encode(response) - - return nil -} - -// ConvertCommands converts server commands to game commands -func (s *Server) ConvertCommands(commands []Command, inst uuid.UUID) ([]game.Command, error) { - var cmds []game.Command - for _, c := range commands { - switch c.Command { - case CommandMove: - if bearing, err := game.DirectionFromString(c.Bearing); err != nil { - return nil, err - } else { - cmds = append(cmds, s.world.CommandMove(inst, bearing, c.Duration)) - } - } - } - return cmds, nil + return response, nil } // HandleSpawn will spawn the player entity for the associated account -func HandleCommands(s *Server, b io.ReadCloser, w io.Writer) error { - // Set up the response +func HandleCommands(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { var response = CommandsResponse{ Success: false, } - // Go through each possible validation step for the data + // Decode the commands, verify them and the account, and execute the commands var data CommandsData if err := json.NewDecoder(b).Decode(&data); err != nil { fmt.Printf("Failed to decode json: %s\n", err) @@ -191,23 +146,16 @@ func HandleCommands(s *Server, b io.ReadCloser, w io.Writer) error { response.Success = true } - // Log the response - fmt.Printf("\tresponse: %+v\n", response) - - // Reply with the current status - json.NewEncoder(w).Encode(response) - - return nil + return response, nil } // HandleRadar handles the radar request -func HandleRadar(s *Server, b io.ReadCloser, w io.Writer) error { - // Set up the response +func HandleRadar(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { var response = RadarResponse{ Success: false, } - // Pull out the incoming info + // Decode the radar message, verify it, and respond with the radar info var data CommandsData if err := json.NewDecoder(b).Decode(&data); err != nil { fmt.Printf("Failed to decode json: %s\n", err) @@ -226,16 +174,9 @@ func HandleRadar(s *Server, b io.ReadCloser, w io.Writer) error { response.Error = fmt.Sprintf("Error getting radar from rover: %s", err) } else { - // Fill in the response response.Rovers = radar.Rovers response.Success = true } - // Log the response - fmt.Printf("\tresponse: %+v\n", response) - - // Reply with the current status - json.NewEncoder(w).Encode(response) - - return nil + return response, nil } diff --git a/pkg/server/server.go b/pkg/server/server.go index 490f720..c4c9005 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -2,6 +2,7 @@ package server import ( "context" + "encoding/json" "fmt" "log" "net/http" @@ -141,22 +142,21 @@ func (s *Server) wrapHandler(method string, handler Handler) func(w http.Respons // Log the request fmt.Printf("%s\t%s\n", r.Method, r.RequestURI) - // Verify we're hit with the right method + // Verify the method, call the handler, and encode the return if r.Method != method { w.WriteHeader(http.StatusMethodNotAllowed) - } else if err := handler(s, r.Body, w); err != nil { - // Log the error + } else if val, err := handler(s, r.Body, w); err != nil { fmt.Printf("Failed to handle http request: %s", err) + w.WriteHeader(http.StatusInternalServerError) - // Respond that we've had an error + } else if err := json.NewEncoder(w).Encode(val); err != nil { + fmt.Printf("Failed to encode return to json: %s", err) w.WriteHeader(http.StatusInternalServerError) } else { - // Be a good citizen and set the header for the return w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) - } } } @@ -180,3 +180,19 @@ func (s *Server) SpawnRoverForAccount(accountid uuid.UUID) (game.Vector, uuid.UU } } } + +// ConvertCommands converts server commands to game commands +func (s *Server) ConvertCommands(commands []Command, inst uuid.UUID) ([]game.Command, error) { + var cmds []game.Command + for _, c := range commands { + switch c.Command { + case CommandMove: + if bearing, err := game.DirectionFromString(c.Bearing); err != nil { + return nil, err + } else { + cmds = append(cmds, s.world.CommandMove(inst, bearing, c.Duration)) + } + } + } + return cmds, nil +}