diff --git a/cmd/rove/main.go b/cmd/rove/main.go index 7efdcd1..eae9302 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -22,6 +22,7 @@ func Usage() { fmt.Println("\tspawn \tspawns a rover for the current account") fmt.Println("\tcommands\tissues commands to the rover") fmt.Println("\tradar \tgathers radar data for the current rover") + fmt.Println("\trover \tgets data for current rover") fmt.Println("\nOptions:") flag.PrintDefaults() } @@ -29,7 +30,7 @@ func Usage() { var home = os.Getenv("HOME") var filepath = path.Join(home, ".local/share/rove.json") -var host = flag.String("host", "api.rove-game.com", "path to game host server") +var host = flag.String("host", "", "path to game host server") var data = flag.String("data", filepath, "data file for storage") // Config is used to store internal data @@ -58,13 +59,8 @@ func main() { os.Exit(1) } - // Set up the config - var config = Config{ - Host: *host, - } - var server = rove.Server(*host) - // Load in the persistent file + var config = Config{} _, err := os.Stat(*data) if !os.IsNotExist(err) { if b, err := ioutil.ReadFile(*data); err != nil { @@ -79,6 +75,20 @@ func main() { } } + // If there's a host set on the command line, override the one in the config + if len(*host) != 0 { + config.Host = *host + } + + // If there's still no host, bail + if len(config.Host) == 0 { + fmt.Fprintln(os.Stderr, "no host set, please set one with -host") + os.Exit(1) + } + + // Set up the server + var server = rove.Server(config.Host) + // Print the config info fmt.Printf("host: %s\taccount: %s\n", config.Host, config.Account) @@ -161,6 +171,21 @@ func main() { fmt.Printf("%+v\n", response) } + case "rover": + verifyId(config) + d := rove.RoverData{Id: config.Account} + if response, err := server.Rover(d); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + + } else if !response.Success { + fmt.Fprintf(os.Stderr, "Server returned failure: %s\n", response.Error) + os.Exit(1) + + } else { + fmt.Printf("position: %v\n", response.Position) + } + default: fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command) os.Exit(1) diff --git a/pkg/rove/api.go b/pkg/rove/api.go index 189f297..8a75766 100644 --- a/pkg/rove/api.go +++ b/pkg/rove/api.go @@ -107,7 +107,6 @@ type Command struct { // API: /radar POST // Radar queries the current radar for the user -// Commands issues a set of commands from the user func (s Server) Radar(d RadarData) (r RadarResponse, err error) { err = s.POST("radar", d, &r) return @@ -126,3 +125,26 @@ type RadarResponse struct { // The set of positions for nearby rovers Rovers []game.Vector `json:"rovers"` } + +// ================ +// API: /rover POST + +// Rover queries the current state of the rover +func (s Server) Rover(d RoverData) (r RoverResponse, err error) { + err = s.POST("rover", d, &r) + return +} + +// RoverData describes the input data to request rover status +type RoverData struct { + Id string `json:"id"` +} + +// RoverResponse includes information about the rover in question +type RoverResponse struct { + Success bool `json:"success"` + Error string `json:"error,omitempty"` + + // The set of positions for nearby rovers + Position game.Vector `json:"position"` +} diff --git a/pkg/rove/integration_test.go b/pkg/rove/integration_test.go index c2577f5..06ed9ab 100644 --- a/pkg/rove/integration_test.go +++ b/pkg/rove/integration_test.go @@ -109,3 +109,27 @@ func TestServer_Radar(t *testing.T) { assert.NoError(t, err) assert.True(t, r3.Success) } + +func TestServer_Rover(t *testing.T) { + d1 := RegisterData{ + Name: uuid.New().String(), + } + r1, err := server.Register(d1) + assert.NoError(t, err) + assert.True(t, r1.Success) + assert.NotZero(t, len(r1.Id)) + + s := SpawnData{ + Id: r1.Id, + } + r2, err := server.Spawn(s) + assert.NoError(t, err) + assert.True(t, r2.Success) + + r := RoverData{ + Id: r1.Id, + } + r3, err := server.Rover(r) + assert.NoError(t, err) + assert.True(t, r3.Success) +} diff --git a/pkg/server/routes.go b/pkg/server/routes.go index 3b15492..8462857 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -48,6 +48,11 @@ var Routes = []Route{ method: http.MethodPost, handler: HandleRadar, }, + { + path: "/rover", + method: http.MethodPost, + handler: HandleRover, + }, } // HandleStatus handles the /status request @@ -181,3 +186,34 @@ func HandleRadar(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { return response, nil } + +// HandleRover handles the rover request +func HandleRover(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) { + var response = rove.RoverResponse{ + Success: false, + } + + var data rove.RoverData + if err := json.NewDecoder(b).Decode(&data); err != nil { + fmt.Printf("Failed to decode json: %s\n", err) + response.Error = err.Error() + + } else if len(data.Id) == 0 { + response.Error = "No account ID provided" + + } else if id, err := uuid.Parse(data.Id); err != nil { + response.Error = fmt.Sprintf("Provided account ID was invalid: %s", err) + + } else if inst, err := s.accountant.GetRover(id); err != nil { + response.Error = fmt.Sprintf("Provided account has no rover: %s", err) + + } else if pos, err := s.world.RoverPosition(inst); err != nil { + response.Error = fmt.Sprintf("Error getting radar from rover: %s", err) + + } else { + response.Position = pos + response.Success = true + } + + return response, nil +} diff --git a/pkg/server/routes_test.go b/pkg/server/routes_test.go index deffd21..828df1f 100644 --- a/pkg/server/routes_test.go +++ b/pkg/server/routes_test.go @@ -149,3 +149,33 @@ func TestHandleRadar(t *testing.T) { // TODO: Verify the radar information } + +func TestHandleRover(t *testing.T) { + s := NewServer() + a, err := s.accountant.RegisterAccount("test") + assert.NoError(t, err, "Error registering account") + + // Spawn the rover rover for the account + _, _, err = s.SpawnRoverForAccount(a.Id) + + data := rove.RoverData{ + Id: a.Id.String(), + } + + b, err := json.Marshal(data) + assert.NoError(t, err, "Error marshalling data") + + request, _ := http.NewRequest(http.MethodPost, "/rover", bytes.NewReader(b)) + response := httptest.NewRecorder() + + s.wrapHandler(http.MethodPost, HandleRover)(response, request) + + var status rove.RoverResponse + json.NewDecoder(response.Body).Decode(&status) + + if status.Success != true { + t.Errorf("got false for /rover") + } + + // TODO: Verify the radar information +} diff --git a/pkg/server/server.go b/pkg/server/server.go index beed460..00ec75a 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -157,7 +157,6 @@ func (s *Server) wrapHandler(method string, handler Handler) func(w http.Respons } else { w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) } } }