Add /rover command to get rover info

This commit is contained in:
Marc Di Luzio 2020-06-05 22:23:01 +01:00
parent e2e0256d44
commit 9d57f48f98
6 changed files with 145 additions and 9 deletions

View file

@ -22,6 +22,7 @@ func Usage() {
fmt.Println("\tspawn \tspawns a rover for the current account") fmt.Println("\tspawn \tspawns a rover for the current account")
fmt.Println("\tcommands\tissues commands to the rover") fmt.Println("\tcommands\tissues commands to the rover")
fmt.Println("\tradar \tgathers radar data for the current rover") fmt.Println("\tradar \tgathers radar data for the current rover")
fmt.Println("\trover \tgets data for current rover")
fmt.Println("\nOptions:") fmt.Println("\nOptions:")
flag.PrintDefaults() flag.PrintDefaults()
} }
@ -29,7 +30,7 @@ func Usage() {
var home = os.Getenv("HOME") var home = os.Getenv("HOME")
var filepath = path.Join(home, ".local/share/rove.json") 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") var data = flag.String("data", filepath, "data file for storage")
// Config is used to store internal data // Config is used to store internal data
@ -58,13 +59,8 @@ func main() {
os.Exit(1) os.Exit(1)
} }
// Set up the config
var config = Config{
Host: *host,
}
var server = rove.Server(*host)
// Load in the persistent file // Load in the persistent file
var config = Config{}
_, err := os.Stat(*data) _, err := os.Stat(*data)
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
if b, err := ioutil.ReadFile(*data); err != nil { 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 // Print the config info
fmt.Printf("host: %s\taccount: %s\n", config.Host, config.Account) fmt.Printf("host: %s\taccount: %s\n", config.Host, config.Account)
@ -161,6 +171,21 @@ func main() {
fmt.Printf("%+v\n", response) 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: default:
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command) fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
os.Exit(1) os.Exit(1)

View file

@ -107,7 +107,6 @@ type Command struct {
// API: /radar POST // API: /radar POST
// Radar queries the current radar for the user // 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) { func (s Server) Radar(d RadarData) (r RadarResponse, err error) {
err = s.POST("radar", d, &r) err = s.POST("radar", d, &r)
return return
@ -126,3 +125,26 @@ type RadarResponse struct {
// The set of positions for nearby rovers // The set of positions for nearby rovers
Rovers []game.Vector `json:"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"`
}

View file

@ -109,3 +109,27 @@ func TestServer_Radar(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, r3.Success) 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)
}

View file

@ -48,6 +48,11 @@ var Routes = []Route{
method: http.MethodPost, method: http.MethodPost,
handler: HandleRadar, handler: HandleRadar,
}, },
{
path: "/rover",
method: http.MethodPost,
handler: HandleRover,
},
} }
// HandleStatus handles the /status request // HandleStatus handles the /status request
@ -181,3 +186,34 @@ func HandleRadar(s *Server, b io.ReadCloser, w io.Writer) (interface{}, error) {
return response, nil 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
}

View file

@ -149,3 +149,33 @@ func TestHandleRadar(t *testing.T) {
// TODO: Verify the radar information // 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
}

View file

@ -157,7 +157,6 @@ func (s *Server) wrapHandler(method string, handler Handler) func(w http.Respons
} else { } else {
w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
} }
} }
} }