diff --git a/Makefile b/Makefile index 3aedd83..b73faf0 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,12 @@ gen: protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:proto/ proto/roveapi/roveapi.proto test: - @echo Run unit and integration tests - docker-compose -f docker-compose-test.yml up --build --exit-code-from=rove-tests --abort-on-container-exit rove-tests - docker-compose -f docker-compose-test.yml down + @echo Unit tests + go test -v ./... + + @echo Integration tests + docker-compose up --build --exit-code-from=rove-tests --abort-on-container-exit rove-tests + docker-compose down go tool cover -html=/tmp/coverage-data/c.out -o /tmp/coverage.html @echo Done, coverage data can be found in /tmp/coverage.html diff --git a/README.md b/README.md index aad1a6f..2aff518 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ Rove ==== +![Tests](https://github.com/mdiluz/rove/workflows/Tests/badge.svg) ![Docker](https://github.com/mdiluz/rove/workflows/Docker/badge.svg) [![rove](https://snapcraft.io//rove/badge.svg)](https://snapcraft.io/rove) -![Rove](data/icon.svg) +![Rove](https://github.com/mdiluz/rove/blob/master/data/icon.svg) Rove is an asynchronous nomadic game about exploring as part of a loose community. -This repository contains the source code for the `rove-server` deployment and the `rove` command line client. See [mdiluz.github.io/rove](https://mdiluz.github.io/rove/) for game details, and [roveapi.proto](proto/roveapi/roveapi.proto) for the current server-client API. +This repository contains the source code for the `rove-server` deployment and the `rove` command line client. See [mdiluz.github.io/rove](https://mdiluz.github.io/rove/) for game details, and [roveapi.proto](https://github.com/mdiluz/rove/blob/master/proto/roveapi/roveapi.proto) for the current server-client API. diff --git a/pkg/accounts/accounts.go b/cmd/rove-server/internal/accounts.go similarity index 98% rename from pkg/accounts/accounts.go rename to cmd/rove-server/internal/accounts.go index eb8637d..9ae6db9 100644 --- a/pkg/accounts/accounts.go +++ b/cmd/rove-server/internal/accounts.go @@ -1,4 +1,4 @@ -package accounts +package internal // Accountant decribes something that stores accounts and account values type Accountant interface { diff --git a/pkg/accounts/accounts_test.go b/cmd/rove-server/internal/accounts_test.go similarity index 98% rename from pkg/accounts/accounts_test.go rename to cmd/rove-server/internal/accounts_test.go index bd2416f..9e7891f 100644 --- a/pkg/accounts/accounts_test.go +++ b/cmd/rove-server/internal/accounts_test.go @@ -1,4 +1,4 @@ -package accounts +package internal import ( "testing" diff --git a/cmd/rove-server/internal/routes.go b/cmd/rove-server/internal/routes.go index 69dd820..7174c31 100644 --- a/cmd/rove-server/internal/routes.go +++ b/cmd/rove-server/internal/routes.go @@ -34,7 +34,7 @@ func (s *Server) Register(ctx context.Context, req *roveapi.RegisterRequest) (*r return nil, fmt.Errorf("empty account name") } - if acc, err := s.world.Accountant.RegisterAccount(req.Name); err != nil { + if acc, err := s.accountant.RegisterAccount(req.Name); err != nil { return nil, err } else if _, err := s.SpawnRoverForAccount(req.Name); err != nil { @@ -57,13 +57,13 @@ func (s *Server) Register(ctx context.Context, req *roveapi.RegisterRequest) (*r func (s *Server) Status(ctx context.Context, req *roveapi.StatusRequest) (response *roveapi.StatusResponse, err error) { log.Printf("Handling status request: %s\n", req.Account.Name) - if valid, err := s.world.Accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { + if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { return nil, err } else if !valid { return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name) - } else if resp, err := s.world.Accountant.GetValue(req.Account.Name, "rover"); err != nil { + } else if resp, err := s.accountant.GetValue(req.Account.Name, "rover"); err != nil { return nil, err } else if rover, err := s.world.GetRover(resp); err != nil { @@ -85,29 +85,23 @@ func (s *Server) Status(ctx context.Context, req *roveapi.StatusRequest) (respon } response = &roveapi.StatusResponse{ - Readings: &roveapi.RoverReadings{ - Position: &roveapi.Vector{ - X: int32(rover.Pos.X), - Y: int32(rover.Pos.Y), - }, - Logs: logs, - Wind: s.world.Wind, - }, - Spec: &roveapi.RoverSpecifications{ - Name: rover.Name, - Range: int32(rover.Range), - Capacity: int32(rover.Capacity), - MaximumIntegrity: int32(rover.MaximumIntegrity), - MaximumCharge: int32(rover.MaximumCharge), - }, - Status: &roveapi.RoverStatus{ - Bearing: rover.Bearing, - Inventory: inv, - Integrity: int32(rover.Integrity), - Charge: int32(rover.Charge), - QueuedCommands: queued, - SailPosition: rover.SailPosition, + Name: rover.Name, + Position: &roveapi.Vector{ + X: int32(rover.Pos.X), + Y: int32(rover.Pos.Y), }, + Bearing: rover.Bearing, + Range: int32(rover.Range), + Inventory: inv, + Capacity: int32(rover.Capacity), + Integrity: int32(rover.Integrity), + MaximumIntegrity: int32(rover.MaximumIntegrity), + Charge: int32(rover.Charge), + MaximumCharge: int32(rover.MaximumCharge), + QueuedCommands: queued, + SailPosition: rover.SailPosition, + Logs: logs, + Wind: s.world.Wind, } } return response, nil @@ -117,7 +111,7 @@ func (s *Server) Status(ctx context.Context, req *roveapi.StatusRequest) (respon func (s *Server) Radar(ctx context.Context, req *roveapi.RadarRequest) (*roveapi.RadarResponse, error) { log.Printf("Handling radar request: %s\n", req.Account.Name) - if valid, err := s.world.Accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { + if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { return nil, err } else if !valid { @@ -126,7 +120,7 @@ func (s *Server) Radar(ctx context.Context, req *roveapi.RadarRequest) (*roveapi response := &roveapi.RadarResponse{} - resp, err := s.world.Accountant.GetValue(req.Account.Name, "rover") + resp, err := s.accountant.GetValue(req.Account.Name, "rover") if err != nil { return nil, err @@ -149,14 +143,14 @@ func (s *Server) Radar(ctx context.Context, req *roveapi.RadarRequest) (*roveapi func (s *Server) Command(ctx context.Context, req *roveapi.CommandRequest) (*roveapi.CommandResponse, error) { log.Printf("Handling command request: %s and %+v\n", req.Account.Name, req.Commands) - if valid, err := s.world.Accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { + if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { return nil, err } else if !valid { return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name) } - resp, err := s.world.Accountant.GetValue(req.Account.Name, "rover") + resp, err := s.accountant.GetValue(req.Account.Name, "rover") if err != nil { return nil, err } diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go index e2b7e16..786eb00 100644 --- a/cmd/rove-server/internal/server.go +++ b/cmd/rove-server/internal/server.go @@ -4,8 +4,6 @@ import ( "fmt" "log" "net" - "os" - "path" "sync" "github.com/mdiluz/rove/pkg/persistence" @@ -13,12 +11,8 @@ import ( "github.com/mdiluz/rove/proto/roveapi" "github.com/robfig/cron" "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/reflection" ) -var cert = os.Getenv("CERT_NAME") - const ( // PersistentData will allow the server to load and save it's state PersistentData = iota @@ -33,6 +27,9 @@ type Server struct { // Internal state world *rove.World + // Accountant + accountant Accountant + // gRPC server netListener net.Listener grpcServ *grpc.Server @@ -83,6 +80,7 @@ func NewServer(opts ...ServerOption) *Server { persistence: EphemeralData, schedule: cron.New(), world: rove.NewWorld(32), + accountant: NewSimpleAccountant(), } // Apply all options @@ -109,22 +107,8 @@ func (s *Server) Initialise(fillWorld bool) (err error) { if err != nil { log.Fatalf("failed to listen: %v", err) } - - // Load TLS - var opts []grpc.ServerOption - if len(os.Getenv("NO_TLS")) == 0 { - pem := path.Join("/etc/letsencrypt/live/", cert, "fullchain.pem") - key := path.Join("/etc/letsencrypt/live/", cert, "privkey.pem") - creds, err := credentials.NewServerTLSFromFile(pem, key) - if err != nil { - log.Fatalf("failed to setup TLS: %v", err) - } - opts = append(opts, grpc.Creds(creds)) - } - - s.grpcServ = grpc.NewServer(opts...) + s.grpcServ = grpc.NewServer() roveapi.RegisterRoveServer(s.grpcServ, s) - reflection.Register(s.grpcServ) return nil } @@ -204,7 +188,7 @@ func (s *Server) SaveWorld() error { if s.persistence == PersistentData { s.world.RLock() defer s.world.RUnlock() - if err := persistence.SaveAll("world", s.world); err != nil { + if err := persistence.SaveAll("world", s.world, "accounts", s.accountant); err != nil { return fmt.Errorf("failed to save out persistent data: %s", err) } } @@ -216,7 +200,7 @@ func (s *Server) LoadWorld() error { if s.persistence == PersistentData { s.world.Lock() defer s.world.Unlock() - if err := persistence.LoadAll("world", &s.world); err != nil { + if err := persistence.LoadAll("world", &s.world, "accounts", &s.accountant); err != nil { return err } } @@ -225,10 +209,22 @@ func (s *Server) LoadWorld() error { // SpawnRoverForAccount spawns the rover rover for an account func (s *Server) SpawnRoverForAccount(account string) (string, error) { - inst, err := s.world.SpawnRover(account) + inst, err := s.world.SpawnRover() if err != nil { return "", err } + err = s.accountant.AssignData(account, "rover", inst) + if err != nil { + log.Printf("Failed to assign rover to account, %s", err) + + // Try and clear up the rover + if err := s.world.DestroyRover(inst); err != nil { + log.Printf("Failed to destroy rover after failed rover assign: %s", err) + } + + return "", err + } + return inst, nil } diff --git a/cmd/rove-server/internal/server_test.go b/cmd/rove-server/internal/server_test.go index 40d4b80..36db679 100644 --- a/cmd/rove-server/internal/server_test.go +++ b/cmd/rove-server/internal/server_test.go @@ -1,7 +1,6 @@ package internal import ( - "os" "testing" ) @@ -31,7 +30,6 @@ func TestNewServer_OptionPersistentData(t *testing.T) { } func TestServer_Run(t *testing.T) { - os.Setenv("NO_TLS", "1") server := NewServer() if server == nil { t.Error("Failed to create server") @@ -47,7 +45,6 @@ func TestServer_Run(t *testing.T) { } func TestServer_RunPersistentData(t *testing.T) { - os.Setenv("NO_TLS", "1") server := NewServer(OptionPersistentData()) if server == nil { t.Error("Failed to create server") diff --git a/pkg/accounts/simpleAccountant.go b/cmd/rove-server/internal/simpleAccountant.go similarity index 99% rename from pkg/accounts/simpleAccountant.go rename to cmd/rove-server/internal/simpleAccountant.go index 9d6c43f..611ff59 100644 --- a/pkg/accounts/simpleAccountant.go +++ b/cmd/rove-server/internal/simpleAccountant.go @@ -1,4 +1,4 @@ -package accounts +package internal import ( "fmt" diff --git a/cmd/rove/internal/glyph.go b/cmd/rove/internal/glyph.go index 4a774e7..eac12c0 100644 --- a/cmd/rove/internal/glyph.go +++ b/cmd/rove/internal/glyph.go @@ -25,9 +25,6 @@ const ( // GlyphRoverDormant represents a dormant rover GlyphRoverDormant = Glyph('r') - // GlyphRoverParts represents spare rover parts - GlyphRoverParts = Glyph('*') - // GlyphRockSmall is a small stashable rock GlyphRockSmall = Glyph('o') @@ -61,8 +58,6 @@ func ObjectGlyph(o roveapi.Object) Glyph { return GlyphRoverDormant case roveapi.Object_RockLarge: return GlyphRockLarge - case roveapi.Object_RoverParts: - return GlyphRoverParts } log.Fatalf("Unknown object type: %c", o) diff --git a/cmd/rove/main.go b/cmd/rove/main.go index f1e993d..01e16ae 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -1,7 +1,6 @@ package main import ( - "crypto/tls" "encoding/json" "fmt" "io/ioutil" @@ -9,7 +8,6 @@ import ( "os" "path" "path/filepath" - "strconv" "time" "github.com/mdiluz/rove/cmd/rove/internal" @@ -17,7 +15,6 @@ import ( "github.com/mdiluz/rove/proto/roveapi" "golang.org/x/net/context" "google.golang.org/grpc" - "google.golang.org/grpc/credentials" ) var home = os.Getenv("HOME") @@ -25,30 +22,23 @@ var defaultDataPath = path.Join(home, ".local/share/") // Command usage func printUsage() { - fmt.Fprintln(os.Stderr, "Usage: rove ARG [OPT...]") - fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintln(os.Stderr, "Arguments:") - fmt.Fprintln(os.Stderr, "\tversion outputs version") - fmt.Fprintln(os.Stderr, "\thelp outputs this usage text") - fmt.Fprintln(os.Stderr, "\tconfig [HOST] outputs the local config, optionally sets host") - fmt.Fprintln(os.Stderr, "\tserver-status prints the server status") - fmt.Fprintln(os.Stderr, "\tregister NAME registers an account and spawns a rover") - fmt.Fprintln(os.Stderr, "\tradar prints radar data in ASCII form") - fmt.Fprintln(os.Stderr, "\tstatus gets rover status") - fmt.Fprintln(os.Stderr, "\tcommand CMD [VAL...] [REPEAT] sets the command queue, accepts multiple in sequence") - fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintln(os.Stderr, "Rover commands:") - fmt.Fprintln(os.Stderr, "\ttoggle toggles the current sail mode") - fmt.Fprintln(os.Stderr, "\tstash stores the object at the rover location in the inventory") - fmt.Fprintln(os.Stderr, "\trepair repairs the rover using inventory item") - fmt.Fprintln(os.Stderr, "\tbroadcast MSG broadcast a simple ASCII triplet to nearby rovers") - fmt.Fprintln(os.Stderr, "\tsalvage salvages a dormant rover for parts") - fmt.Fprintln(os.Stderr, "\ttransfer transfer's control into a dormant rover") - fmt.Fprintln(os.Stderr, "\tupgrade SPEC spends rover parts to upgrade one rover spec (capacity, range, integrity, charge") - fmt.Fprintln(os.Stderr, "\twait waits before performing the next command") - fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintln(os.Stderr, "Environment") - fmt.Fprintln(os.Stderr, "\tROVE_USER_DATA path to user data, defaults to "+defaultDataPath) + fmt.Fprintf(os.Stderr, "Usage: rove COMMAND [ARGS...]\n") + fmt.Fprintln(os.Stderr, "\nCommands") + fmt.Fprintln(os.Stderr, "\tserver-status prints the server status") + fmt.Fprintln(os.Stderr, "\tregister NAME registers an account and stores it (use with -name)") + fmt.Fprintln(os.Stderr, "\tcommand COMMAND [VAL...] issue commands to rover, accepts multiple, see below") + fmt.Fprintln(os.Stderr, "\tradar gathers radar data for the current rover") + fmt.Fprintln(os.Stderr, "\tstatus gets status info for current rover") + fmt.Fprintln(os.Stderr, "\tconfig [HOST] outputs the local config info, optionally sets host") + fmt.Fprintln(os.Stderr, "\thelp outputs this usage information") + fmt.Fprintln(os.Stderr, "\tversion outputs version info") + fmt.Fprintln(os.Stderr, "\nRover commands:") + fmt.Fprintln(os.Stderr, "\ttoggle toggles the sails, either catching the wind, or charging from the sun") + fmt.Fprintln(os.Stderr, "\tstash stores the object at the rover location in the inventory") + fmt.Fprintln(os.Stderr, "\trepair uses an inventory object to repair the rover") + fmt.Fprintln(os.Stderr, "\tbroadcast MSG broadcast a simple ASCII triplet to nearby rovers") + fmt.Fprintln(os.Stderr, "\nEnvironment") + fmt.Fprintln(os.Stderr, "\tROVE_USER_DATA path to user data, defaults to "+defaultDataPath) } const gRPCport = 9090 @@ -188,15 +178,8 @@ func InnerMain(command string, args ...string) error { return fmt.Errorf("no host set in %s, set one with '%s config {HOST}'", ConfigPath(), os.Args[0]) } - var opts []grpc.DialOption - if len(os.Getenv("NO_TLS")) == 0 { - opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) - } else { - opts = append(opts, grpc.WithInsecure()) - } - // Set up the server - clientConn, err := grpc.Dial(fmt.Sprintf("%s:%d", config.Host, gRPCport), opts...) + clientConn, err := grpc.Dial(fmt.Sprintf("%s:%d", config.Host, gRPCport), grpc.WithInsecure()) if err != nil { return err } @@ -248,8 +231,6 @@ func InnerMain(command string, args ...string) error { // Iterate through each command var commands []*roveapi.Command for i := 0; i < len(args); i++ { - - var cmd *roveapi.Command switch args[i] { case "turn": i++ @@ -260,10 +241,12 @@ func InnerMain(command string, args ...string) error { if b == roveapi.Bearing_BearingUnknown { return fmt.Errorf("turn command must be given a valid bearing %s", args[i]) } - cmd = &roveapi.Command{ - Command: roveapi.CommandType_turn, - Bearing: b, - } + commands = append(commands, + &roveapi.Command{ + Command: roveapi.CommandType_broadcast, + Broadcast: []byte(args[i]), + }, + ) case "broadcast": i++ if len(args) == i { @@ -271,51 +254,20 @@ func InnerMain(command string, args ...string) error { } else if len(args[i]) > 3 { return fmt.Errorf("broadcast command must be given ASCII triplet of 3 or less: %s", args[i]) } - cmd = &roveapi.Command{ - Command: roveapi.CommandType_broadcast, - Data: []byte(args[i]), - } - case "upgrade": - i++ - if len(args) == i { - return fmt.Errorf("upgrade command must be passed a spec to upgrade") - } - var u roveapi.RoverUpgrade - switch args[i] { - case "capacity": - u = roveapi.RoverUpgrade_Capacity - case "range": - u = roveapi.RoverUpgrade_Range - case "integrity": - u = roveapi.RoverUpgrade_MaximumIntegrity - case "charge": - u = roveapi.RoverUpgrade_MaximumCharge - default: - return fmt.Errorf("upgrade command must be passed a known upgrade spec") - } - cmd = &roveapi.Command{ - Command: roveapi.CommandType_upgrade, - Upgrade: u, - } + commands = append(commands, + &roveapi.Command{ + Command: roveapi.CommandType_broadcast, + Broadcast: []byte(args[i]), + }, + ) default: // By default just use the command literally - cmd = &roveapi.Command{ - Command: roveapi.CommandType(roveapi.CommandType_value[args[i]]), - } + commands = append(commands, + &roveapi.Command{ + Command: roveapi.CommandType(roveapi.CommandType_value[args[i]]), + }, + ) } - - // Try and convert the next command to a number - number := 0 - if len(args) > i+1 { - num, err := strconv.Atoi(args[i+1]) - if err == nil { - number = num - i++ - } - } - cmd.Repeat = int32(number) - - commands = append(commands, cmd) } _, err := client.Command(ctx, &roveapi.CommandRequest{ @@ -403,15 +355,6 @@ func InnerMain(command string, args ...string) error { func main() { // Bail without any args if len(os.Args) == 1 { - fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintln(os.Stderr, "m mm mmm m m mmm") - fmt.Fprintln(os.Stderr, "#\" \" #\" \"# \"m m\" #\" #") - fmt.Fprintln(os.Stderr, "# # # #m# #\"\"\"\"") - fmt.Fprintln(os.Stderr, "# \"#m#\" # \"#mm\"") - fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintln(os.Stderr, "Rove is an asychronous nomadic game about exploring a planet as part of a loose community.") - fmt.Fprintln(os.Stderr, "Visit https://mdiluz.github.io/rove/ for more information.") - fmt.Fprintf(os.Stderr, "\n") printUsage() os.Exit(1) } diff --git a/cmd/rove/main_test.go b/cmd/rove/main_test.go index 250988a..2eb564c 100644 --- a/cmd/rove/main_test.go +++ b/cmd/rove/main_test.go @@ -13,7 +13,6 @@ import ( ) func Test_InnerMain(t *testing.T) { - os.Setenv("NO_TLS", "1") // Use temporary local user data tmp, err := ioutil.TempDir(os.TempDir(), "rove-") @@ -54,14 +53,9 @@ func Test_InnerMain(t *testing.T) { assert.NoError(t, InnerMain("command", "toggle")) assert.NoError(t, InnerMain("command", "stash")) assert.NoError(t, InnerMain("command", "repair")) - assert.NoError(t, InnerMain("command", "upgrade", "capacity")) assert.NoError(t, InnerMain("command", "broadcast", "abc")) - assert.NoError(t, InnerMain("command", "wait", "10")) - assert.NoError(t, InnerMain("command", "wait", "1", "turn", "NW", "toggle", "broadcast", "zyx")) // Give it malformed commands assert.Error(t, InnerMain("command", "unknown")) assert.Error(t, InnerMain("command", "broadcast")) - assert.Error(t, InnerMain("command", "upgrade")) - assert.Error(t, InnerMain("command", "1")) } diff --git a/docker-compose-test.yml b/docker-compose-test.yml deleted file mode 100644 index aec8cee..0000000 --- a/docker-compose-test.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: '3' - -services: - rove-test-server: - build: - context: . - dockerfile: Dockerfile - image: rove:latest - ports: - - "9090:9090" - environment: - - PORT=9090 - - DATA_PATH=/tmp/ - - WORDS_FILE=data/words_alpha.txt - - TICK_RATE=10 - - NO_TLS=1 - command: [ "./rove-server"] - - rove-tests: - depends_on: [ rove-test-server ] - build: - context: . - dockerfile: Dockerfile - image: rove:latest - environment: - - ROVE_GRPC=rove-test-server - command: [ "./script/wait-for-it.sh", "rove-test-server:9090", "--", "go", "test", "-v", "./...", "--tags=integration", "-cover", "-coverprofile=/mnt/coverage-data/c.out", "-count", "1" ] - volumes: - - /tmp/coverage-data:/mnt/coverage-data:rw - - - diff --git a/docker-compose.yml b/docker-compose.yml index d5606f7..f1962a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,10 +16,21 @@ services: - DATA_PATH=/mnt/rove-server - WORDS_FILE=data/words_alpha.txt - TICK_RATE=3 - - CERT_NAME=${CERT_NAME} volumes: - persistent-data:/mnt/rove-server:rw - - /etc/letsencrypt/:/etc/letsencrypt/ command: [ "./rove-server"] + rove-tests: + depends_on: [ rove-server ] + build: + context: . + dockerfile: Dockerfile + image: rove:latest + environment: + - ROVE_GRPC=rove-server + command: [ "./script/wait-for-it.sh", "rove-server:9090", "--", "go", "test", "-v", "./...", "--tags=integration", "-cover", "-coverprofile=/mnt/coverage-data/c.out", "-count", "1" ] + volumes: + - /tmp/coverage-data:/mnt/coverage-data:rw + + diff --git a/pkg/rove/chunkAtlas.go b/pkg/rove/chunkAtlas.go index 1903c7b..88f1102 100644 --- a/pkg/rove/chunkAtlas.go +++ b/pkg/rove/chunkAtlas.go @@ -2,6 +2,7 @@ package rove import ( "log" + "math/rand" "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/proto/roveapi" @@ -110,6 +111,15 @@ func (a *chunkBasedAtlas) populate(chunk int) { } } + // Set up any objects + for i := 0; i < len(c.Tiles); i++ { + if rand.Intn(16) == 0 { + c.Objects[i] = Object{Type: roveapi.Object_RockLarge} + } else if rand.Intn(32) == 0 { + c.Objects[i] = Object{Type: roveapi.Object_RockSmall} + } + } + a.Chunks[chunk] = c } diff --git a/pkg/rove/command_test.go b/pkg/rove/command_test.go index bf1eed6..f55c6cb 100644 --- a/pkg/rove/command_test.go +++ b/pkg/rove/command_test.go @@ -1,26 +1,15 @@ package rove import ( - "encoding/json" "testing" - "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/proto/roveapi" "github.com/stretchr/testify/assert" ) -func TestCommand_Invalid(t *testing.T) { - w := NewWorld(8) - name, err := w.SpawnRover("") - assert.NoError(t, err) - - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_none}) - assert.Error(t, err) -} - func TestCommand_Toggle(t *testing.T) { w := NewWorld(8) - a, err := w.SpawnRover("") + a, err := w.SpawnRover() assert.NoError(t, err) r, err := w.GetRover(a) @@ -46,10 +35,10 @@ func TestCommand_Toggle(t *testing.T) { func TestCommand_Turn(t *testing.T) { w := NewWorld(8) - a, err := w.SpawnRover("") + a, err := w.SpawnRover() assert.NoError(t, err) - err = w.Enqueue(a, &roveapi.Command{Command: roveapi.CommandType_turn, Bearing: roveapi.Bearing_NorthWest}) + err = w.Enqueue(a, &roveapi.Command{Command: roveapi.CommandType_turn, Turn: roveapi.Bearing_NorthWest}) assert.NoError(t, err) w.Tick() @@ -59,247 +48,17 @@ func TestCommand_Turn(t *testing.T) { } func TestCommand_Stash(t *testing.T) { - w := NewWorld(8) - name, err := w.SpawnRover("") - assert.NoError(t, err) - - info, err := w.GetRover(name) - assert.NoError(t, err) - assert.Empty(t, info.Inventory) - - // Drop a pickup below us - w.Atlas.SetObject(info.Pos, Object{Type: roveapi.Object_RockSmall}) - - // Try and stash it - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_stash}) - assert.NoError(t, err) - w.Tick() - - // Check we now have it in the inventory - info, err = w.GetRover(name) - assert.NoError(t, err) - assert.Equal(t, 1, len(info.Inventory)) - assert.Equal(t, Object{Type: roveapi.Object_RockSmall}, info.Inventory[0]) - - // Check it's no longer on the atlas - _, obj := w.Atlas.QueryPosition(info.Pos) - assert.Equal(t, Object{Type: roveapi.Object_ObjectUnknown}, obj) + // TODO: Test the stash command } func TestCommand_Repair(t *testing.T) { - w := NewWorld(8) - name, err := w.SpawnRover("") - assert.NoError(t, err) - - info, err := w.GetRover(name) - assert.NoError(t, err) - assert.Equal(t, info.MaximumIntegrity, info.Integrity) - - // Put a blocking rock to the north - w.Atlas.SetObject(info.Pos.Added(maths.Vector{X: 0, Y: 1}), Object{Type: roveapi.Object_RockLarge}) - - // Try and move and make sure we're blocked - newpos, err := w.TryMoveRover(name, roveapi.Bearing_North) - assert.NoError(t, err) - assert.Equal(t, info.Pos, newpos) - - // Check we're damaged - info, err = w.GetRover(name) - assert.NoError(t, err) - assert.Equal(t, info.MaximumIntegrity-1, info.Integrity) - - // Stash a repair object - w.Atlas.SetObject(info.Pos, Object{Type: roveapi.Object_RoverParts}) - obj, err := w.RoverStash(name) - assert.NoError(t, err) - assert.Equal(t, roveapi.Object_RoverParts, obj) - - // Enqueue the repair and tick - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_repair}) - assert.NoError(t, err) - w.Tick() - - // Check we're repaired - info, err = w.GetRover(name) - assert.NoError(t, err) - assert.Equal(t, info.MaximumIntegrity, info.Integrity) - assert.Equal(t, 0, len(info.Inventory)) + // TODO: Test the repair command } func TestCommand_Broadcast(t *testing.T) { - w := NewWorld(8) - name, err := w.SpawnRover("") - assert.NoError(t, err) - - // Enqueue the broadcast and tick - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_broadcast, Data: []byte("ABC")}) - assert.NoError(t, err) - w.Tick() - - info, err := w.GetRover(name) - assert.NoError(t, err) - assert.Contains(t, info.Logs[len(info.Logs)-1].Text, "ABC") + // TODO: Test the stash command } -func TestCommand_Salvage(t *testing.T) { - w := NewWorld(8) - name, err := w.SpawnRover("") - assert.NoError(t, err) - - info, err := w.GetRover(name) - assert.NoError(t, err) - - w.Atlas.SetObject(info.Pos, Object{Type: roveapi.Object_RoverDormant}) - - // Enqueue the broadcast and tick - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_salvage}) - assert.NoError(t, err) - w.Tick() - - // Check we now have some rover parts - info, err = w.GetRover(name) - assert.NoError(t, err) - assert.NotEmpty(t, info.Inventory) - for _, i := range info.Inventory { - assert.Equal(t, roveapi.Object_RoverParts, i.Type) - } - - // Check the dormant rover is gone - _, obj := w.Atlas.QueryPosition(info.Pos) - assert.Equal(t, roveapi.Object_ObjectUnknown, obj.Type) -} - -func TestCommand_Transfer(t *testing.T) { - w := NewWorld(8) - acc, err := w.Accountant.RegisterAccount("tmp") - assert.NoError(t, err) - nameA, err := w.SpawnRover(acc.Name) - assert.NoError(t, err) - - infoA, err := w.GetRover(nameA) - assert.NoError(t, err) - - // Drop a dormant rover on the current position - infoB := DefaultRover() - infoB.Name = "abc" - infoB.Pos = infoA.Pos - data, err := json.Marshal(infoB) - assert.NoError(t, err) - w.Atlas.SetObject(infoA.Pos, Object{Type: roveapi.Object_RoverDormant, Data: data}) - - // Enqueue a transfer as well as a dud command - err = w.Enqueue(nameA, - &roveapi.Command{Command: roveapi.CommandType_transfer}, - &roveapi.Command{Command: roveapi.CommandType_broadcast, Data: []byte("xyz")}) - assert.NoError(t, err) - w.Tick() - - // Ensure both command queues are empty - assert.Empty(t, w.CommandQueue[nameA]) - assert.Empty(t, w.CommandQueue[infoB.Name]) - - // Verify the account now controls the new rover - accountRover, err := w.Accountant.GetValue(acc.Name, "rover") - assert.NoError(t, err) - assert.Equal(t, infoB.Name, accountRover) - - // Verify the position now has a dormant rover - _, obj := w.Atlas.QueryPosition(infoA.Pos) - assert.Equal(t, roveapi.Object_RoverDormant, obj.Type) - - // Verify the stored data matches - var stored Rover - err = json.Unmarshal(obj.Data, &stored) - assert.NoError(t, err) - assert.Equal(t, infoA.Name, stored.Name) - - // Verify the new rover data matches what we put in - infoB2, err := w.GetRover(infoB.Name) - assert.NoError(t, err) - assert.Equal(t, infoB.Name, infoB2.Name) - -} - -func TestCommand_Wait(t *testing.T) { - w := NewWorld(8) - a, err := w.SpawnRover("") - assert.NoError(t, err) - - r, err := w.GetRover(a) - assert.NoError(t, err) - assert.Equal(t, roveapi.SailPosition_SolarCharging, r.SailPosition) - - err = w.Enqueue(a, &roveapi.Command{Command: roveapi.CommandType_wait, Repeat: 4}, &roveapi.Command{Command: roveapi.CommandType_toggle}) - assert.NoError(t, err) - - // Tick 5 times during the wait (1 normal execute + 4) - for i := 0; i < 5; i++ { - w.Tick() - - r, err = w.GetRover(a) - assert.NoError(t, err) - assert.Equal(t, roveapi.SailPosition_SolarCharging, r.SailPosition) - } - - // One last tick to do the toggle - w.Tick() - - r, err = w.GetRover(a) - assert.NoError(t, err) - assert.Equal(t, roveapi.SailPosition_CatchingWind, r.SailPosition) -} - -func TestCommand_Upgrade(t *testing.T) { - w := NewWorld(8) - name, err := w.SpawnRover("") - assert.NoError(t, err) - rover, ok := w.Rovers[name] - assert.True(t, ok) - - // Try an invalid upgrade - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_upgrade}) - assert.Error(t, err) - - // Try a valid command but without the parts - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_upgrade, Upgrade: roveapi.RoverUpgrade_Capacity}) - assert.NoError(t, err) - - // Ensure nothing changed and we logged the attempt - pre := rover.Capacity - w.Tick() - assert.Equal(t, pre, rover.Capacity) - assert.Contains(t, rover.Logs[len(rover.Logs)-1].Text, "tried") - - // One non-part item - rover.Inventory = []Object{ - { - Type: roveapi.Object_RoverParts, - }, - { - Type: roveapi.Object_RoverParts, - }, - { - Type: roveapi.Object_RockSmall, - }, - { - Type: roveapi.Object_RoverParts, - }, - { - Type: roveapi.Object_RoverParts, - }, - { - Type: roveapi.Object_RoverParts, - }, - } - - // Try a valid command again - err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_upgrade, Upgrade: roveapi.RoverUpgrade_Capacity}) - assert.NoError(t, err) - - // Check that the capacity increases on the tick and all the parts are used - pre = rover.Capacity - w.Tick() - assert.Equal(t, pre+1, rover.Capacity) - assert.Equal(t, 1, len(rover.Inventory)) - assert.Equal(t, roveapi.Object_RockSmall, rover.Inventory[0].Type) +func TestCommand_Invalid(t *testing.T) { + // TODO: Test an invalid command } diff --git a/pkg/rove/objects.go b/pkg/rove/objects.go index df10453..f1ce227 100644 --- a/pkg/rove/objects.go +++ b/pkg/rove/objects.go @@ -17,6 +17,7 @@ type Object struct { func (o *Object) IsBlocking() bool { var blocking = [...]roveapi.Object{ roveapi.Object_RoverLive, + roveapi.Object_RoverDormant, roveapi.Object_RockLarge, } @@ -32,7 +33,6 @@ func (o *Object) IsBlocking() bool { func (o *Object) IsStashable() bool { var stashable = [...]roveapi.Object{ roveapi.Object_RockSmall, - roveapi.Object_RoverParts, } for _, t := range stashable { diff --git a/pkg/rove/rover.go b/pkg/rove/rover.go index bebde50..fb13ddc 100644 --- a/pkg/rove/rover.go +++ b/pkg/rove/rover.go @@ -13,10 +13,6 @@ import ( "github.com/mdiluz/rove/proto/roveapi" ) -const ( - maxLogEntries = 16 -) - // RoverLogEntry describes a single log entry for the rover type RoverLogEntry struct { // Time is the timestamp of the entry @@ -66,15 +62,12 @@ type Rover struct { // Logs Stores log of information Logs []RoverLogEntry - - // The account that owns this rover - Owner string } // DefaultRover returns a default rover object with default settings func DefaultRover() *Rover { return &Rover{ - Range: 10, + Range: 4, Integrity: 10, MaximumIntegrity: 10, Capacity: 10, @@ -96,11 +89,6 @@ func (r *Rover) AddLogEntryf(format string, args ...interface{}) { Text: text, }, ) - - // Limit the number of logs - if len(r.Logs) > maxLogEntries { - r.Logs = r.Logs[len(r.Logs)-maxLogEntries:] - } } var wordsFile = os.Getenv("WORDS_FILE") diff --git a/pkg/rove/world.go b/pkg/rove/world.go index d509d8d..591ba8e 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -1,23 +1,17 @@ package rove import ( - "encoding/json" "fmt" "log" "math/rand" "sync" - "github.com/mdiluz/rove/pkg/accounts" "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/proto/roveapi" ) const ( - // ticksPerNormalMove defines the number of ticks it should take for a "normal" speed move - ticksPerNormalMove = 4 - - // upgradeCost is the cost in rover parts needed to upgrade a rover specification - upgradeCost = 5 + TicksPerNormalMove = 4 ) // CommandStream is a list of commands to execute in order @@ -44,9 +38,6 @@ type World struct { // Commands is the set of currently executing command streams per rover CommandQueue map[string]CommandStream - // Accountant - Accountant accounts.Accountant - // Mutex to lock around all world operations worldMutex sync.RWMutex // Mutex to lock around command operations @@ -61,22 +52,17 @@ func NewWorld(chunkSize int) *World { Atlas: NewChunkAtlas(chunkSize), TicksPerDay: 24, CurrentTicks: 0, - Accountant: accounts.NewSimpleAccountant(), - Wind: roveapi.Bearing_North, } } -// SpawnRover adds an rover to the game (without lock) -func (w *World) SpawnRover(account string) (string, error) { +// SpawnRover adds an rover to the game +func (w *World) SpawnRover() (string, error) { w.worldMutex.Lock() defer w.worldMutex.Unlock() // Initialise the rover rover := DefaultRover() - // Assign the owner - rover.Owner = account - // Spawn in a random place near the origin rover.Pos = maths.Vector{ X: 10 - rand.Intn(20), @@ -101,13 +87,7 @@ func (w *World) SpawnRover(account string) (string, error) { // Append the rover to the list w.Rovers[rover.Name] = rover - var err error - // Only assign if we've been given an account - if len(account) > 0 { - err = w.Accountant.AssignData(account, "rover", rover.Name) - } - - return rover.Name, err + return rover.Name, nil } // GetRover gets a specific rover by name @@ -184,26 +164,12 @@ func (w *World) DestroyRover(rover string) error { w.worldMutex.Lock() defer w.worldMutex.Unlock() - r, ok := w.Rovers[rover] + _, ok := w.Rovers[rover] if !ok { return fmt.Errorf("no rover matching id") } - // Remove this rover from tracked rovers delete(w.Rovers, rover) - - r.Owner = "" - r.AddLogEntryf("rover destroyed") - - // Marshal the rover data - data, err := json.Marshal(r) - if err != nil { - return err - } - - // Place the dormant rover down - w.Atlas.SetObject(r.Pos, Object{Type: roveapi.Object_RoverDormant, Data: data}) - return nil } @@ -293,6 +259,9 @@ func (w *World) TryMoveRover(rover string, b roveapi.Bearing) (maths.Vector, err i.AddLogEntryf("tried to move %s to %+v", b.String(), newPos) i.Integrity = i.Integrity - 1 i.AddLogEntryf("had a collision, new integrity %d", i.Integrity) + // TODO: The rover needs to be left dormant with the player + //if i.Integrity == 0 { + //} } return i.Pos, nil @@ -310,13 +279,11 @@ func (w *World) RoverStash(rover string) (roveapi.Object, error) { // Can't pick up when full if len(r.Inventory) >= r.Capacity { - r.AddLogEntryf("tried to stash object but inventory was full") return roveapi.Object_ObjectUnknown, nil } // Ensure the rover has energy if r.Charge <= 0 { - r.AddLogEntryf("tried to stash object but had no charge") return roveapi.Object_ObjectUnknown, nil } r.Charge-- @@ -332,99 +299,6 @@ func (w *World) RoverStash(rover string) (roveapi.Object, error) { return obj.Type, nil } -// RoverSalvage will salvage a rover for parts -func (w *World) RoverSalvage(rover string) (roveapi.Object, error) { - w.worldMutex.Lock() - defer w.worldMutex.Unlock() - - r, ok := w.Rovers[rover] - if !ok { - return roveapi.Object_ObjectUnknown, fmt.Errorf("no rover matching id") - } - - // Can't pick up when full - if len(r.Inventory) >= r.Capacity { - r.AddLogEntryf("tried to salvage dormant rover but inventory was full") - return roveapi.Object_ObjectUnknown, nil - } - - // Ensure the rover has energy - if r.Charge <= 0 { - r.AddLogEntryf("tried to salvage dormant rover but had no charge") - return roveapi.Object_ObjectUnknown, nil - } - r.Charge-- - - _, obj := w.Atlas.QueryPosition(r.Pos) - if obj.Type != roveapi.Object_RoverDormant { - r.AddLogEntryf("tried to salvage dormant rover but found no rover to salvage") - return roveapi.Object_ObjectUnknown, nil - } - - r.AddLogEntryf("salvaged dormant rover") - for i := 0; i < 5; i++ { - if len(r.Inventory) == r.Capacity { - break - } - r.Inventory = append(r.Inventory, Object{Type: roveapi.Object_RoverParts}) - } - w.Atlas.SetObject(r.Pos, Object{Type: roveapi.Object_ObjectUnknown}) - return obj.Type, nil -} - -// RoverTransfer will transfer rover control to dormant rover -func (w *World) RoverTransfer(rover string) (string, error) { - w.worldMutex.Lock() - defer w.worldMutex.Unlock() - - oldRover, ok := w.Rovers[rover] - if !ok { - return "", fmt.Errorf("no rover matching id") - } - - _, obj := w.Atlas.QueryPosition(oldRover.Pos) - if obj.Type != roveapi.Object_RoverDormant { - oldRover.AddLogEntryf("tried to transfer to dormant rover but found no rover") - return "", nil - } - - // Unmarshal the dormant rover - var newRover Rover - err := json.Unmarshal(obj.Data, &newRover) - if err != nil { - return "", err - } - - // Add logs - oldRover.AddLogEntryf("transferring to dormant rover %s", newRover.Name) - newRover.AddLogEntryf("transferred from rover %s", oldRover.Name) - - // Transfer the ownership - err = w.Accountant.AssignData(oldRover.Owner, "rover", newRover.Name) - if err != nil { - return "", err - } - newRover.Owner = oldRover.Owner - oldRover.Owner = "" - - // Place the old rover in the world - oldRoverData, err := json.Marshal(oldRover) - if err != nil { - return "", err - } - w.Atlas.SetObject(oldRover.Pos, Object{Type: roveapi.Object_RoverDormant, Data: oldRoverData}) - - // Swap the rovers in the tracking - w.Rovers[newRover.Name] = &newRover - delete(w.Rovers, oldRover.Name) - - // Clear the command queues for both rovers - delete(w.CommandQueue, oldRover.Name) - delete(w.CommandQueue, newRover.Name) - - return newRover.Name, nil -} - // RoverToggle will toggle the sail position func (w *World) RoverToggle(rover string) (roveapi.SailPosition, error) { w.worldMutex.Lock() @@ -449,65 +323,6 @@ func (w *World) RoverToggle(rover string) (roveapi.SailPosition, error) { return r.SailPosition, nil } -// RoverUpgrade will try to upgrade the rover -func (w *World) RoverUpgrade(rover string, upgrade roveapi.RoverUpgrade) (int, error) { - w.worldMutex.Lock() - defer w.worldMutex.Unlock() - - r, ok := w.Rovers[rover] - if !ok { - return 0, fmt.Errorf("no rover matching id") - } - - cost := upgradeCost - num := 0 - for i := range r.Inventory { - if r.Inventory[i].Type == roveapi.Object_RoverParts { - num++ - } - } - - if num < cost { - r.AddLogEntryf("tried to upgrade but lacked rover parts") - return 0, nil - } - - // Apply the upgrade - var ret int - switch upgrade { - case roveapi.RoverUpgrade_Capacity: - r.Capacity++ - ret = r.Capacity - case roveapi.RoverUpgrade_Range: - r.Range++ - ret = r.Range - case roveapi.RoverUpgrade_MaximumCharge: - r.MaximumCharge++ - ret = r.MaximumCharge - case roveapi.RoverUpgrade_MaximumIntegrity: - r.MaximumIntegrity++ - ret = r.MaximumIntegrity - default: - return 0, fmt.Errorf("unknown upgrade: %s", upgrade) - } - - // Remove the cost in rover parts - var n []Object - for _, o := range r.Inventory { - if o.Type == roveapi.Object_RoverParts && cost > 0 { - cost-- - } else { - n = append(n, o) - } - } - // Assign back the inventory - r.Inventory = n - - r.AddLogEntryf("upgraded %s to %d", upgrade, ret) - - return ret, nil -} - // RoverTurn will turn the rover func (w *World) RoverTurn(rover string, bearing roveapi.Bearing) (roveapi.Bearing, error) { w.worldMutex.Lock() @@ -536,24 +351,11 @@ func (w *World) RoverRepair(rover string) (int, error) { return 0, fmt.Errorf("no rover matching id") } - // Can't repair past max - if r.Integrity >= r.MaximumIntegrity { - return r.Integrity, nil - } - - // Find rover parts in inventory - for i, o := range r.Inventory { - if o.Type == roveapi.Object_RoverParts { - - // Copy-erase from slice - r.Inventory[i] = r.Inventory[len(r.Inventory)-1] - r.Inventory = r.Inventory[:len(r.Inventory)-1] - - // Repair - r.Integrity = r.Integrity + 1 - r.AddLogEntryf("repaired self to %d", r.Integrity) - break - } + // Consume an inventory item to repair if possible + if len(r.Inventory) > 0 && r.Integrity < r.MaximumIntegrity { + r.Inventory = r.Inventory[:len(r.Inventory)-1] + r.Integrity = r.Integrity + 1 + r.AddLogEntryf("repaired self to %d", r.Integrity) } return r.Integrity, nil @@ -632,28 +434,21 @@ func (w *World) Enqueue(rover string, commands ...*roveapi.Command) error { for _, c := range commands { switch c.Command { case roveapi.CommandType_broadcast: - if len(c.GetData()) > 3 { - return fmt.Errorf("too many characters in message (limit 3): %d", len(c.GetData())) + if len(c.GetBroadcast()) > 3 { + return fmt.Errorf("too many characters in message (limit 3): %d", len(c.GetBroadcast())) } - for _, b := range c.GetData() { + for _, b := range c.GetBroadcast() { if b < 37 || b > 126 { return fmt.Errorf("invalid message character: %c", b) } } case roveapi.CommandType_turn: - if c.GetBearing() == roveapi.Bearing_BearingUnknown { + if c.GetTurn() == roveapi.Bearing_BearingUnknown { return fmt.Errorf("turn command given unknown bearing") } - case roveapi.CommandType_upgrade: - if c.GetUpgrade() == roveapi.RoverUpgrade_RoverUpgradeUnknown { - return fmt.Errorf("upgrade command given unknown upgrade") - } - case roveapi.CommandType_wait: case roveapi.CommandType_toggle: case roveapi.CommandType_stash: case roveapi.CommandType_repair: - case roveapi.CommandType_salvage: - case roveapi.CommandType_transfer: // Nothing to verify default: return fmt.Errorf("unknown command: %s", c.Command) @@ -679,24 +474,25 @@ func (w *World) Tick() { if len(cmds) != 0 { // Execute the command - if done, err := w.ExecuteCommand(cmds[0], rover); err != nil { + if err := w.ExecuteCommand(cmds[0], rover); err != nil { log.Println(err) // TODO: Report this error somehow - - } else if done { - // Extract the first command in the queue - // Only if the command queue still has entries (the command may have modified this queue) - if _, ok := w.CommandQueue[rover]; ok { - w.CommandQueue[rover] = cmds[1:] - } } + // Extract the first command in the queue + w.CommandQueue[rover] = cmds[1:] + } else { // Clean out the empty entry delete(w.CommandQueue, rover) } } + // Change the wind every day + if (w.CurrentTicks % w.TicksPerDay) == 0 { + w.Wind = roveapi.Bearing((rand.Int() % 8) + 1) // Random cardinal bearing + } + // Move all the rovers based on current wind and sails for n, r := range w.Rovers { // Skip if we're not catching the wind @@ -719,16 +515,16 @@ func (w *World) Tick() { switch diff { case 0: // Going with the wind, travel at base speed of once every 4 ticks - ticksToMove = ticksPerNormalMove + ticksToMove = TicksPerNormalMove case 1: // At a slight angle, we can go a little faster - ticksToMove = ticksPerNormalMove / 2 + ticksToMove = TicksPerNormalMove / 2 case 2: // Perpendicular to wind, max speed ticksToMove = 1 case 3: // Heading at 45 degrees into the wind, back to min speed - ticksToMove = ticksPerNormalMove + ticksToMove = TicksPerNormalMove case 4: // Heading durectly into the wind, no movement at all default: @@ -746,66 +542,48 @@ func (w *World) Tick() { // Reset the move ticks r.MoveTicks = 0 } - } - // Check all rover integrities - for _, r := range w.Rovers { - if r.Integrity <= 0 { - // The rover has died destroy it - err := w.DestroyRover(r.Name) - if err != nil { - log.Println(err) - // TODO: Report this error somehow - } - - // Spawn a new one for this account - _, err = w.SpawnRover(r.Owner) - if err != nil { - log.Println(err) - // TODO: Report this error somehow - } - } + log.Print(ticksToMove) } // Increment the current tick count w.CurrentTicks++ - - // Change the wind every day - if (w.CurrentTicks % w.TicksPerDay) == 0 { - w.Wind = roveapi.Bearing((rand.Int() % 8) + 1) // Random cardinal bearing - } } // ExecuteCommand will execute a single command -func (w *World) ExecuteCommand(c *roveapi.Command, rover string) (done bool, err error) { +func (w *World) ExecuteCommand(c *roveapi.Command, rover string) (err error) { log.Printf("Executing command: %+v for %s\n", c.Command, rover) switch c.Command { case roveapi.CommandType_toggle: - _, err = w.RoverToggle(rover) + if _, err := w.RoverToggle(rover); err != nil { + return err + } case roveapi.CommandType_stash: - _, err = w.RoverStash(rover) + if _, err := w.RoverStash(rover); err != nil { + return err + } + case roveapi.CommandType_repair: - _, err = w.RoverRepair(rover) + if _, err := w.RoverRepair(rover); err != nil { + return err + } + case roveapi.CommandType_broadcast: - err = w.RoverBroadcast(rover, c.GetData()) + if err := w.RoverBroadcast(rover, c.GetBroadcast()); err != nil { + return err + } + case roveapi.CommandType_turn: - _, err = w.RoverTurn(rover, c.GetBearing()) - case roveapi.CommandType_salvage: - _, err = w.RoverSalvage(rover) - case roveapi.CommandType_transfer: - _, err = w.RoverTransfer(rover) - case roveapi.CommandType_upgrade: - _, err = w.RoverUpgrade(rover, c.GetUpgrade()) - case roveapi.CommandType_wait: - // Nothing to do + if _, err := w.RoverTurn(rover, c.GetTurn()); err != nil { + return err + } + default: - return true, fmt.Errorf("unknown command: %s", c.Command) + return fmt.Errorf("unknown command: %s", c.Command) } - // Decrement the repeat number - c.Repeat-- - return c.Repeat < 0, err + return } // Daytime returns if it's currently daytime diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index f085d89..a3c2f47 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -18,9 +18,9 @@ func TestNewWorld(t *testing.T) { func TestWorld_CreateRover(t *testing.T) { world := NewWorld(8) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) - b, err := world.SpawnRover("") + b, err := world.SpawnRover() assert.NoError(t, err) // Basic duplicate check @@ -33,7 +33,7 @@ func TestWorld_CreateRover(t *testing.T) { func TestWorld_GetRover(t *testing.T) { world := NewWorld(4) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) rover, err := world.GetRover(a) @@ -44,9 +44,9 @@ func TestWorld_GetRover(t *testing.T) { func TestWorld_DestroyRover(t *testing.T) { world := NewWorld(1) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) - b, err := world.SpawnRover("") + b, err := world.SpawnRover() assert.NoError(t, err) err = world.DestroyRover(a) @@ -62,7 +62,7 @@ func TestWorld_DestroyRover(t *testing.T) { func TestWorld_GetSetMovePosition(t *testing.T) { world := NewWorld(4) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) pos := maths.Vector{ @@ -97,9 +97,9 @@ func TestWorld_GetSetMovePosition(t *testing.T) { func TestWorld_RadarFromRover(t *testing.T) { // Create world that should have visible walls on the radar world := NewWorld(2) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) - b, err := world.SpawnRover("") + b, err := world.SpawnRover() assert.NoError(t, err) // Warp the rovers into position @@ -109,16 +109,15 @@ func TestWorld_RadarFromRover(t *testing.T) { world.Atlas.SetObject(maths.Vector{X: 0, Y: 0}, Object{Type: roveapi.Object_ObjectUnknown}) assert.NoError(t, world.WarpRover(a, maths.Vector{X: 0, Y: 0}), "Failed to warp rover") - r, err := world.GetRover(a) - assert.NoError(t, err) - radar, objs, err := world.RadarFromRover(a) assert.NoError(t, err, "Failed to get radar from rover") - fullRange := r.Range + r.Range + 1 + fullRange := 4 + 4 + 1 assert.Equal(t, fullRange*fullRange, len(radar), "Radar returned wrong length") assert.Equal(t, fullRange*fullRange, len(objs), "Radar returned wrong length") - // TODO: Verify the other rover is on the radar + // Test the expected values + assert.Equal(t, roveapi.Object_RoverLive, objs[1+fullRange]) + assert.Equal(t, roveapi.Object_RoverLive, objs[4+4*fullRange]) // Check the radar results are stable radar1, objs1, err := world.RadarFromRover(a) @@ -129,11 +128,9 @@ func TestWorld_RadarFromRover(t *testing.T) { assert.Equal(t, objs1, objs2) } -func TestWorld_RoverDamage(t *testing.T) { +func TestWorld_RoverStash(t *testing.T) { world := NewWorld(2) - acc, err := world.Accountant.RegisterAccount("tmp") - assert.NoError(t, err) - a, err := world.SpawnRover(acc.Name) + a, err := world.SpawnRover() assert.NoError(t, err) pos := maths.Vector{ @@ -145,6 +142,78 @@ func TestWorld_RoverDamage(t *testing.T) { err = world.WarpRover(a, pos) assert.NoError(t, err, "Failed to set position for rover") + rover, err := world.GetRover(a) + assert.NoError(t, err, "Failed to get rover") + + for i := 0; i < rover.Capacity; i++ { + // Place an object + world.Atlas.SetObject(pos, Object{Type: roveapi.Object_RockSmall}) + + // Pick it up + o, err := world.RoverStash(a) + assert.NoError(t, err, "Failed to stash") + assert.Equal(t, roveapi.Object_RockSmall, o, "Failed to get correct object") + + // Check it's gone + _, obj := world.Atlas.QueryPosition(pos) + assert.Equal(t, roveapi.Object_ObjectUnknown, obj.Type, "Stash failed to remove object from atlas") + + // Check we have it + inv, err := world.RoverInventory(a) + assert.NoError(t, err, "Failed to get inventory") + assert.Equal(t, i+1, len(inv)) + assert.Equal(t, Object{Type: roveapi.Object_RockSmall}, inv[i]) + + // Check that this did reduce the charge + info, err := world.GetRover(a) + assert.NoError(t, err, "Failed to get rover") + assert.Equal(t, info.MaximumCharge-(i+1), info.Charge, "Rover lost charge for stash") + assert.Contains(t, info.Logs[len(info.Logs)-1].Text, "stashed", "Rover logs should contain the move") + } + + // Recharge the rover + for i := 0; i < rover.MaximumCharge; i++ { + _, err = world.RoverRecharge(a) + assert.NoError(t, err) + + } + + // Place an object + world.Atlas.SetObject(pos, Object{Type: roveapi.Object_RockSmall}) + + // Try to pick it up + o, err := world.RoverStash(a) + assert.NoError(t, err, "Failed to stash") + assert.Equal(t, roveapi.Object_ObjectUnknown, o, "Failed to get correct object") + + // Check it's still there + _, obj := world.Atlas.QueryPosition(pos) + assert.Equal(t, roveapi.Object_RockSmall, obj.Type, "Stash failed to remove object from atlas") + + // Check we don't have it + inv, err := world.RoverInventory(a) + assert.NoError(t, err, "Failed to get inventory") + assert.Equal(t, rover.Capacity, len(inv)) + + // Check that this didn't reduce the charge + info, err := world.GetRover(a) + assert.NoError(t, err, "Failed to get rover") + assert.Equal(t, info.MaximumCharge, info.Charge, "Rover lost charge for non-stash") +} + +func TestWorld_RoverDamage(t *testing.T) { + world := NewWorld(2) + a, err := world.SpawnRover() + assert.NoError(t, err) + + pos := maths.Vector{ + X: 0.0, + Y: 0.0, + } + + err = world.WarpRover(a, pos) + assert.NoError(t, err, "Failed to set position for rover") + info, err := world.GetRover(a) assert.NoError(t, err, "couldn't get rover info") @@ -158,29 +227,69 @@ func TestWorld_RoverDamage(t *testing.T) { assert.NoError(t, err, "couldn't get rover info") assert.Equal(t, info.Integrity-1, newinfo.Integrity, "rover should have lost integrity") assert.Contains(t, newinfo.Logs[len(newinfo.Logs)-1].Text, "collision", "Rover logs should contain the collision") +} - // Keep moving to damage the rover - for i := 0; i < info.Integrity-1; i++ { - vec, err := world.TryMoveRover(a, roveapi.Bearing_North) - assert.NoError(t, err, "Failed to move rover") - assert.Equal(t, pos, vec, "Rover managed to move into large rock") +func TestWorld_RoverRepair(t *testing.T) { + world := NewWorld(2) + a, err := world.SpawnRover() + assert.NoError(t, err) + + pos := maths.Vector{ + X: 0.0, + Y: 0.0, } - // Tick the world to check for rover deaths - world.Tick() + world.Atlas.SetObject(pos, Object{Type: roveapi.Object_ObjectUnknown}) - // Rover should have been destroyed now - _, err = world.GetRover(a) - assert.Error(t, err) + err = world.WarpRover(a, pos) + assert.NoError(t, err, "Failed to set position for rover") - _, obj := world.Atlas.QueryPosition(info.Pos) - assert.Equal(t, roveapi.Object_RoverDormant, obj.Type) + originalInfo, err := world.GetRover(a) + assert.NoError(t, err, "couldn't get rover info") + + // Pick up something to repair with + world.Atlas.SetObject(pos, Object{Type: roveapi.Object_RockSmall}) + o, err := world.RoverStash(a) + assert.NoError(t, err, "Failed to stash") + assert.Equal(t, roveapi.Object_RockSmall, o, "Failed to get correct object") + + world.Atlas.SetObject(maths.Vector{X: 0.0, Y: 1.0}, Object{Type: roveapi.Object_RockLarge}) + + // Try and bump into the rock + vec, err := world.TryMoveRover(a, roveapi.Bearing_North) + assert.NoError(t, err, "Failed to move rover") + assert.Equal(t, pos, vec, "Rover managed to move into large rock") + + newinfo, err := world.GetRover(a) + assert.NoError(t, err, "couldn't get rover info") + assert.Equal(t, originalInfo.Integrity-1, newinfo.Integrity, "rover should have lost integrity") + + err = world.ExecuteCommand(&roveapi.Command{Command: roveapi.CommandType_repair}, a) + assert.NoError(t, err, "Failed to repair rover") + + newinfo, err = world.GetRover(a) + assert.NoError(t, err, "couldn't get rover info") + assert.Equal(t, originalInfo.Integrity, newinfo.Integrity, "rover should have gained integrity") + assert.Contains(t, newinfo.Logs[len(newinfo.Logs)-1].Text, "repair", "Rover logs should contain the repair") + + // Check again that it can't repair past the max + world.Atlas.SetObject(pos, Object{Type: roveapi.Object_RockSmall}) + o, err = world.RoverStash(a) + assert.NoError(t, err, "Failed to stash") + assert.Equal(t, roveapi.Object_RockSmall, o, "Failed to get correct object") + + err = world.ExecuteCommand(&roveapi.Command{Command: roveapi.CommandType_repair}, a) + assert.NoError(t, err, "Failed to repair rover") + + newinfo, err = world.GetRover(a) + assert.NoError(t, err, "couldn't get rover info") + assert.Equal(t, originalInfo.Integrity, newinfo.Integrity, "rover should have kept the same integrity") } func TestWorld_Daytime(t *testing.T) { world := NewWorld(1) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) // Remove rover charge @@ -219,10 +328,10 @@ func TestWorld_Daytime(t *testing.T) { func TestWorld_Broadcast(t *testing.T) { world := NewWorld(8) - a, err := world.SpawnRover("") + a, err := world.SpawnRover() assert.NoError(t, err) - b, err := world.SpawnRover("") + b, err := world.SpawnRover() assert.NoError(t, err) // Warp rovers near to eachother @@ -285,7 +394,7 @@ func TestWorld_Sailing(t *testing.T) { world.Tick() // One initial tick to set the wind direction the first time world.Wind = roveapi.Bearing_North // Set the wind direction to north - name, err := world.SpawnRover("") + name, err := world.SpawnRover() assert.NoError(t, err) // Warp the rover to 0,0 after clearing it @@ -310,7 +419,7 @@ func TestWorld_Sailing(t *testing.T) { assert.Equal(t, maths.Vector{Y: 0}, info.Pos) // Loop a few more times - for i := 0; i < ticksPerNormalMove-2; i++ { + for i := 0; i < TicksPerNormalMove-2; i++ { world.Tick() info, err := world.GetRover(name) assert.NoError(t, err) @@ -332,7 +441,7 @@ func TestWorld_Sailing(t *testing.T) { assert.Equal(t, roveapi.Bearing_South, b) // Tick a bunch, we should never move - for i := 0; i < ticksPerNormalMove*2; i++ { + for i := 0; i < TicksPerNormalMove*2; i++ { world.Tick() info, err := world.GetRover(name) assert.NoError(t, err) diff --git a/pkg/rove/worldgen.go b/pkg/rove/worldgen.go index 6cb425f..e36b7b6 100644 --- a/pkg/rove/worldgen.go +++ b/pkg/rove/worldgen.go @@ -1,6 +1,9 @@ package rove import ( + "encoding/json" + "log" + "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/proto/roveapi" "github.com/ojrac/opensimplex-go" @@ -29,9 +32,8 @@ func NewNoiseWorldGen(seed int64) WorldGen { } const ( - terrainNoiseScale = 15 + terrainNoiseScale = 6 rockNoiseScale = 3 - partsNoiseScale = 2 ) // GetTile returns the chosen tile at a location @@ -49,22 +51,43 @@ func (g *NoiseWorldGen) GetTile(v maths.Vector) roveapi.Tile { // GetObject returns the chosen object at a location func (g *NoiseWorldGen) GetObject(v maths.Vector) (obj Object) { - r := g.noise.Eval2(float64(v.X)/rockNoiseScale, float64(v.Y)/rockNoiseScale) + o := g.noise.Eval2(float64(v.X)/rockNoiseScale, float64(v.Y)/rockNoiseScale) switch { - // Prioritise rocks - case r > 0.6: + case o > 0.6: obj.Type = roveapi.Object_RockLarge - case r > 0.5: + case o > 0.5: obj.Type = roveapi.Object_RockSmall + } - default: - // Otherwise, try some rover parts - p := g.noise.Eval2(float64(v.X)/partsNoiseScale, float64(v.Y)/partsNoiseScale) - switch { - case p > 0.7: - obj.Type = roveapi.Object_RoverParts + // Very rarely spawn a dormant rover + if obj.Type == roveapi.Object_ObjectUnknown { + // TODO: Make this better, ideally with noise + if v.X%25 == 0 && v.Y%25 == 0 && v.X != 0 && v.Y != 0 { + obj.Type = roveapi.Object_RoverDormant } } + // Post process any spawned objects + switch obj.Type { + case roveapi.Object_RoverDormant: + // Create the rover + r := DefaultRover() + + // Set the rover variables + r.Pos = v + + // For now, mark the log as corrupted + r.AddLogEntryf("log corrupted") + + // Marshal the rover data into the object data + b, err := json.Marshal(r) + if err != nil { + log.Fatalf("couldn't marshal rover, should never fail: %s", err) + } + + // Store the bytes + obj.Data = b + } + return obj } diff --git a/proto/roveapi/roveapi.pb.go b/proto/roveapi/roveapi.pb.go index 81a6cb5..4fbea99 100644 --- a/proto/roveapi/roveapi.pb.go +++ b/proto/roveapi/roveapi.pb.go @@ -39,51 +39,35 @@ type CommandType int32 const ( CommandType_none CommandType = 0 - // Waits before performing the next command - CommandType_wait CommandType = 1 // Toggles the sails, either catching the wind, or charging from the sun - CommandType_toggle CommandType = 2 - // Turns the rover in the specified bearing (requires bearing) - CommandType_turn CommandType = 3 + CommandType_toggle CommandType = 1 + // Turns the rover in the specified bearing, requires data + CommandType_turn CommandType = 2 // Stashes item at current location in rover inventory - CommandType_stash CommandType = 4 + CommandType_stash CommandType = 3 // Repairs the rover using an inventory object - CommandType_repair CommandType = 5 - // Broadcasts a message to nearby rovers (requires data) - CommandType_broadcast CommandType = 6 - // Salvages a neighboring dormant rover for parts - CommandType_salvage CommandType = 7 - // Transfers remote control into dormant rover - CommandType_transfer CommandType = 8 - // Upgrades a chosen rover specification using 5 rover parts - CommandType_upgrade CommandType = 9 + CommandType_repair CommandType = 4 + // Broadcasts a message to nearby rovers, requires data + CommandType_broadcast CommandType = 5 ) // Enum value maps for CommandType. var ( CommandType_name = map[int32]string{ 0: "none", - 1: "wait", - 2: "toggle", - 3: "turn", - 4: "stash", - 5: "repair", - 6: "broadcast", - 7: "salvage", - 8: "transfer", - 9: "upgrade", + 1: "toggle", + 2: "turn", + 3: "stash", + 4: "repair", + 5: "broadcast", } CommandType_value = map[string]int32{ "none": 0, - "wait": 1, - "toggle": 2, - "turn": 3, - "stash": 4, - "repair": 5, - "broadcast": 6, - "salvage": 7, - "transfer": 8, - "upgrade": 9, + "toggle": 1, + "turn": 2, + "stash": 3, + "repair": 4, + "broadcast": 5, } ) @@ -183,62 +167,6 @@ func (Bearing) EnumDescriptor() ([]byte, []int) { return file_roveapi_roveapi_proto_rawDescGZIP(), []int{1} } -// Describes the type of upgrade -type RoverUpgrade int32 - -const ( - RoverUpgrade_RoverUpgradeUnknown RoverUpgrade = 0 - RoverUpgrade_Range RoverUpgrade = 1 - RoverUpgrade_Capacity RoverUpgrade = 2 - RoverUpgrade_MaximumIntegrity RoverUpgrade = 3 - RoverUpgrade_MaximumCharge RoverUpgrade = 4 -) - -// Enum value maps for RoverUpgrade. -var ( - RoverUpgrade_name = map[int32]string{ - 0: "RoverUpgradeUnknown", - 1: "Range", - 2: "Capacity", - 3: "MaximumIntegrity", - 4: "MaximumCharge", - } - RoverUpgrade_value = map[string]int32{ - "RoverUpgradeUnknown": 0, - "Range": 1, - "Capacity": 2, - "MaximumIntegrity": 3, - "MaximumCharge": 4, - } -) - -func (x RoverUpgrade) Enum() *RoverUpgrade { - p := new(RoverUpgrade) - *p = x - return p -} - -func (x RoverUpgrade) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (RoverUpgrade) Descriptor() protoreflect.EnumDescriptor { - return file_roveapi_roveapi_proto_enumTypes[2].Descriptor() -} - -func (RoverUpgrade) Type() protoreflect.EnumType { - return &file_roveapi_roveapi_proto_enumTypes[2] -} - -func (x RoverUpgrade) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use RoverUpgrade.Descriptor instead. -func (RoverUpgrade) EnumDescriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{2} -} - // Types of objects type Object int32 @@ -253,9 +181,6 @@ const ( Object_RockSmall Object = 3 // RockLarge is a large blocking rock Object_RockLarge Object = 4 - // RoverParts is one unit of rover parts, used for repairing and fixing the - // rover - Object_RoverParts Object = 5 ) // Enum value maps for Object. @@ -266,7 +191,6 @@ var ( 2: "RoverDormant", 3: "RockSmall", 4: "RockLarge", - 5: "RoverParts", } Object_value = map[string]int32{ "ObjectUnknown": 0, @@ -274,7 +198,6 @@ var ( "RoverDormant": 2, "RockSmall": 3, "RockLarge": 4, - "RoverParts": 5, } ) @@ -289,11 +212,11 @@ func (x Object) String() string { } func (Object) Descriptor() protoreflect.EnumDescriptor { - return file_roveapi_roveapi_proto_enumTypes[3].Descriptor() + return file_roveapi_roveapi_proto_enumTypes[2].Descriptor() } func (Object) Type() protoreflect.EnumType { - return &file_roveapi_roveapi_proto_enumTypes[3] + return &file_roveapi_roveapi_proto_enumTypes[2] } func (x Object) Number() protoreflect.EnumNumber { @@ -302,7 +225,7 @@ func (x Object) Number() protoreflect.EnumNumber { // Deprecated: Use Object.Descriptor instead. func (Object) EnumDescriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{3} + return file_roveapi_roveapi_proto_rawDescGZIP(), []int{2} } type Tile int32 @@ -345,11 +268,11 @@ func (x Tile) String() string { } func (Tile) Descriptor() protoreflect.EnumDescriptor { - return file_roveapi_roveapi_proto_enumTypes[4].Descriptor() + return file_roveapi_roveapi_proto_enumTypes[3].Descriptor() } func (Tile) Type() protoreflect.EnumType { - return &file_roveapi_roveapi_proto_enumTypes[4] + return &file_roveapi_roveapi_proto_enumTypes[3] } func (x Tile) Number() protoreflect.EnumNumber { @@ -358,7 +281,7 @@ func (x Tile) Number() protoreflect.EnumNumber { // Deprecated: Use Tile.Descriptor instead. func (Tile) EnumDescriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{4} + return file_roveapi_roveapi_proto_rawDescGZIP(), []int{3} } // SailPosition represents the position of the sola sail @@ -397,11 +320,11 @@ func (x SailPosition) String() string { } func (SailPosition) Descriptor() protoreflect.EnumDescriptor { - return file_roveapi_roveapi_proto_enumTypes[5].Descriptor() + return file_roveapi_roveapi_proto_enumTypes[4].Descriptor() } func (SailPosition) Type() protoreflect.EnumType { - return &file_roveapi_roveapi_proto_enumTypes[5] + return &file_roveapi_roveapi_proto_enumTypes[4] } func (x SailPosition) Number() protoreflect.EnumNumber { @@ -410,7 +333,7 @@ func (x SailPosition) Number() protoreflect.EnumNumber { // Deprecated: Use SailPosition.Descriptor instead. func (SailPosition) EnumDescriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{5} + return file_roveapi_roveapi_proto_rawDescGZIP(), []int{4} } // ServerStatusRequest is an empty placeholder @@ -701,15 +624,11 @@ type Command struct { // The command type Command CommandType `protobuf:"varint,1,opt,name=command,proto3,enum=roveapi.CommandType" json:"command,omitempty"` - // The number of times to repeat the command after the first - Repeat int32 `protobuf:"varint,2,opt,name=repeat,proto3" json:"repeat,omitempty"` - // broadcast - a simple message, must be composed of up to 3 printable ASCII - // glyphs (32-126) - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - // move - the bearing for the rover to turn to - Bearing Bearing `protobuf:"varint,4,opt,name=bearing,proto3,enum=roveapi.Bearing" json:"bearing,omitempty"` - // upgrade - the upgrade to apply to the rover - Upgrade RoverUpgrade `protobuf:"varint,5,opt,name=upgrade,proto3,enum=roveapi.RoverUpgrade" json:"upgrade,omitempty"` + // A simple message, must be composed of printable ASCII glyphs (32-126) + // maximum of three characters + Broadcast []byte `protobuf:"bytes,2,opt,name=broadcast,proto3" json:"broadcast,omitempty"` + // The bearing for the rover to turn to + Turn Bearing `protobuf:"varint,3,opt,name=turn,proto3,enum=roveapi.Bearing" json:"turn,omitempty"` } func (x *Command) Reset() { @@ -751,34 +670,20 @@ func (x *Command) GetCommand() CommandType { return CommandType_none } -func (x *Command) GetRepeat() int32 { +func (x *Command) GetBroadcast() []byte { if x != nil { - return x.Repeat - } - return 0 -} - -func (x *Command) GetData() []byte { - if x != nil { - return x.Data + return x.Broadcast } return nil } -func (x *Command) GetBearing() Bearing { +func (x *Command) GetTurn() Bearing { if x != nil { - return x.Bearing + return x.Turn } return Bearing_BearingUnknown } -func (x *Command) GetUpgrade() RoverUpgrade { - if x != nil { - return x.Upgrade - } - return RoverUpgrade_RoverUpgradeUnknown -} - // CommandRequest describes a set of commands to be requested for the rover type CommandRequest struct { state protoimpl.MessageState @@ -1156,267 +1061,46 @@ func (x *Vector) GetY() int32 { return 0 } -type RoverSpecifications struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The name of the rover - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The range of this rover's radar and broadcasting - Range int32 `protobuf:"varint,2,opt,name=range,proto3" json:"range,omitempty"` - // The capacity of the inventory - Capacity int32 `protobuf:"varint,3,opt,name=capacity,proto3" json:"capacity,omitempty"` - // The maximum health of the rover - MaximumIntegrity int32 `protobuf:"varint,4,opt,name=maximumIntegrity,proto3" json:"maximumIntegrity,omitempty"` - // The max energy the rover can store - MaximumCharge int32 `protobuf:"varint,5,opt,name=maximumCharge,proto3" json:"maximumCharge,omitempty"` -} - -func (x *RoverSpecifications) Reset() { - *x = RoverSpecifications{} - if protoimpl.UnsafeEnabled { - mi := &file_roveapi_roveapi_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RoverSpecifications) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RoverSpecifications) ProtoMessage() {} - -func (x *RoverSpecifications) ProtoReflect() protoreflect.Message { - mi := &file_roveapi_roveapi_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RoverSpecifications.ProtoReflect.Descriptor instead. -func (*RoverSpecifications) Descriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{13} -} - -func (x *RoverSpecifications) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *RoverSpecifications) GetRange() int32 { - if x != nil { - return x.Range - } - return 0 -} - -func (x *RoverSpecifications) GetCapacity() int32 { - if x != nil { - return x.Capacity - } - return 0 -} - -func (x *RoverSpecifications) GetMaximumIntegrity() int32 { - if x != nil { - return x.MaximumIntegrity - } - return 0 -} - -func (x *RoverSpecifications) GetMaximumCharge() int32 { - if x != nil { - return x.MaximumCharge - } - return 0 -} - -type RoverStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The current direction of the rover - Bearing Bearing `protobuf:"varint,1,opt,name=bearing,proto3,enum=roveapi.Bearing" json:"bearing,omitempty"` - // The current position of the sails - SailPosition SailPosition `protobuf:"varint,2,opt,name=sailPosition,proto3,enum=roveapi.SailPosition" json:"sailPosition,omitempty"` - // The items in the rover inventory - Inventory []byte `protobuf:"bytes,3,opt,name=inventory,proto3" json:"inventory,omitempty"` - // The current health of the rover - Integrity int32 `protobuf:"varint,4,opt,name=integrity,proto3" json:"integrity,omitempty"` - // The energy stored in the rover - Charge int32 `protobuf:"varint,5,opt,name=charge,proto3" json:"charge,omitempty"` - // The set of currently queued commands - QueuedCommands []*Command `protobuf:"bytes,6,rep,name=queuedCommands,proto3" json:"queuedCommands,omitempty"` -} - -func (x *RoverStatus) Reset() { - *x = RoverStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_roveapi_roveapi_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RoverStatus) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RoverStatus) ProtoMessage() {} - -func (x *RoverStatus) ProtoReflect() protoreflect.Message { - mi := &file_roveapi_roveapi_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RoverStatus.ProtoReflect.Descriptor instead. -func (*RoverStatus) Descriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{14} -} - -func (x *RoverStatus) GetBearing() Bearing { - if x != nil { - return x.Bearing - } - return Bearing_BearingUnknown -} - -func (x *RoverStatus) GetSailPosition() SailPosition { - if x != nil { - return x.SailPosition - } - return SailPosition_UnknownSailPosition -} - -func (x *RoverStatus) GetInventory() []byte { - if x != nil { - return x.Inventory - } - return nil -} - -func (x *RoverStatus) GetIntegrity() int32 { - if x != nil { - return x.Integrity - } - return 0 -} - -func (x *RoverStatus) GetCharge() int32 { - if x != nil { - return x.Charge - } - return 0 -} - -func (x *RoverStatus) GetQueuedCommands() []*Command { - if x != nil { - return x.QueuedCommands - } - return nil -} - -type RoverReadings struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Position of the rover in world coordinates - Position *Vector `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` - // The current wind direction - Wind Bearing `protobuf:"varint,2,opt,name=wind,proto3,enum=roveapi.Bearing" json:"wind,omitempty"` - // The most recent logs - Logs []*Log `protobuf:"bytes,3,rep,name=logs,proto3" json:"logs,omitempty"` -} - -func (x *RoverReadings) Reset() { - *x = RoverReadings{} - if protoimpl.UnsafeEnabled { - mi := &file_roveapi_roveapi_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RoverReadings) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RoverReadings) ProtoMessage() {} - -func (x *RoverReadings) ProtoReflect() protoreflect.Message { - mi := &file_roveapi_roveapi_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RoverReadings.ProtoReflect.Descriptor instead. -func (*RoverReadings) Descriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{15} -} - -func (x *RoverReadings) GetPosition() *Vector { - if x != nil { - return x.Position - } - return nil -} - -func (x *RoverReadings) GetWind() Bearing { - if x != nil { - return x.Wind - } - return Bearing_BearingUnknown -} - -func (x *RoverReadings) GetLogs() []*Log { - if x != nil { - return x.Logs - } - return nil -} - // StatusResponse is the response given to a status request type StatusResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The static rover information - Spec *RoverSpecifications `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` - // Current rover status - Status *RoverStatus `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - // Current rover readings - Readings *RoverReadings `protobuf:"bytes,3,opt,name=readings,proto3" json:"readings,omitempty"` + // The name of the rover + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Position of the rover in world coordinates + Position *Vector `protobuf:"bytes,2,opt,name=position,proto3" json:"position,omitempty"` + // The current direction of the rover + Bearing Bearing `protobuf:"varint,3,opt,name=bearing,proto3,enum=roveapi.Bearing" json:"bearing,omitempty"` + // The range of this rover's radar and broadcasting + Range int32 `protobuf:"varint,4,opt,name=range,proto3" json:"range,omitempty"` + // The items in the rover inventory + Inventory []byte `protobuf:"bytes,5,opt,name=inventory,proto3" json:"inventory,omitempty"` + // The capacity of the inventory + Capacity int32 `protobuf:"varint,6,opt,name=capacity,proto3" json:"capacity,omitempty"` + // The current health of the rover + Integrity int32 `protobuf:"varint,7,opt,name=integrity,proto3" json:"integrity,omitempty"` + // The maximum health of the rover + MaximumIntegrity int32 `protobuf:"varint,8,opt,name=maximumIntegrity,proto3" json:"maximumIntegrity,omitempty"` + // The energy stored in the rover + Charge int32 `protobuf:"varint,9,opt,name=charge,proto3" json:"charge,omitempty"` + // The max energy the rover can store + MaximumCharge int32 `protobuf:"varint,10,opt,name=maximumCharge,proto3" json:"maximumCharge,omitempty"` + // The current position of the sails + SailPosition SailPosition `protobuf:"varint,11,opt,name=sailPosition,proto3,enum=roveapi.SailPosition" json:"sailPosition,omitempty"` + // The set of currently queued commands + QueuedCommands []*Command `protobuf:"bytes,12,rep,name=queuedCommands,proto3" json:"queuedCommands,omitempty"` + // The most recent logs + Logs []*Log `protobuf:"bytes,13,rep,name=logs,proto3" json:"logs,omitempty"` + // The current wind direction + Wind Bearing `protobuf:"varint,14,opt,name=wind,proto3,enum=roveapi.Bearing" json:"wind,omitempty"` } func (x *StatusResponse) Reset() { *x = StatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_roveapi_roveapi_proto_msgTypes[16] + mi := &file_roveapi_roveapi_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1429,7 +1113,7 @@ func (x *StatusResponse) String() string { func (*StatusResponse) ProtoMessage() {} func (x *StatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_roveapi_roveapi_proto_msgTypes[16] + mi := &file_roveapi_roveapi_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1442,30 +1126,107 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. func (*StatusResponse) Descriptor() ([]byte, []int) { - return file_roveapi_roveapi_proto_rawDescGZIP(), []int{16} + return file_roveapi_roveapi_proto_rawDescGZIP(), []int{13} } -func (x *StatusResponse) GetSpec() *RoverSpecifications { +func (x *StatusResponse) GetName() string { if x != nil { - return x.Spec + return x.Name + } + return "" +} + +func (x *StatusResponse) GetPosition() *Vector { + if x != nil { + return x.Position } return nil } -func (x *StatusResponse) GetStatus() *RoverStatus { +func (x *StatusResponse) GetBearing() Bearing { if x != nil { - return x.Status + return x.Bearing + } + return Bearing_BearingUnknown +} + +func (x *StatusResponse) GetRange() int32 { + if x != nil { + return x.Range + } + return 0 +} + +func (x *StatusResponse) GetInventory() []byte { + if x != nil { + return x.Inventory } return nil } -func (x *StatusResponse) GetReadings() *RoverReadings { +func (x *StatusResponse) GetCapacity() int32 { if x != nil { - return x.Readings + return x.Capacity + } + return 0 +} + +func (x *StatusResponse) GetIntegrity() int32 { + if x != nil { + return x.Integrity + } + return 0 +} + +func (x *StatusResponse) GetMaximumIntegrity() int32 { + if x != nil { + return x.MaximumIntegrity + } + return 0 +} + +func (x *StatusResponse) GetCharge() int32 { + if x != nil { + return x.Charge + } + return 0 +} + +func (x *StatusResponse) GetMaximumCharge() int32 { + if x != nil { + return x.MaximumCharge + } + return 0 +} + +func (x *StatusResponse) GetSailPosition() SailPosition { + if x != nil { + return x.SailPosition + } + return SailPosition_UnknownSailPosition +} + +func (x *StatusResponse) GetQueuedCommands() []*Command { + if x != nil { + return x.QueuedCommands } return nil } +func (x *StatusResponse) GetLogs() []*Log { + if x != nil { + return x.Logs + } + return nil +} + +func (x *StatusResponse) GetWind() Bearing { + if x != nil { + return x.Wind + } + return Bearing_BearingUnknown +} + var File_roveapi_roveapi_proto protoreflect.FileDescriptor var file_roveapi_roveapi_proto_rawDesc = []byte{ @@ -1492,157 +1253,129 @@ var file_roveapi_roveapi_proto_rawDesc = []byte{ 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc2, 0x01, 0x0a, 0x07, 0x43, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, - 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, - 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, - 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x70, - 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x22, 0x6a, - 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x08, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, - 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, - 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x75, 0x0a, 0x0d, 0x52, 0x61, 0x64, - 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, - 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, - 0x12, 0x23, 0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x69, 0x6c, 0x65, 0x52, 0x05, - 0x74, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, - 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, - 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, - 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x01, 0x79, 0x22, 0xad, 0x01, 0x0a, 0x13, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, - 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, - 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, - 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x24, 0x0a, 0x0d, - 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x22, 0x82, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, - 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x39, - 0x0a, 0x0c, 0x73, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, - 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x73, 0x61, 0x69, - 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x38, 0x0a, - 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x0d, 0x52, 0x6f, 0x76, 0x65, - 0x72, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x6f, - 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x04, 0x77, 0x69, 0x6e, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, - 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x04, 0x77, 0x69, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x04, - 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, - 0x65, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xa4, - 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, - 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x04, 0x73, - 0x70, 0x65, 0x63, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, - 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x72, 0x65, 0x61, - 0x64, 0x69, 0x6e, 0x67, 0x73, 0x2a, 0x85, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, - 0x08, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x6f, 0x67, - 0x67, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x10, 0x03, 0x12, - 0x09, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x73, 0x68, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x65, - 0x70, 0x61, 0x69, 0x72, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, - 0x61, 0x73, 0x74, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x73, 0x61, 0x6c, 0x76, 0x61, 0x67, 0x65, - 0x10, 0x07, 0x12, 0x0c, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x10, 0x08, - 0x12, 0x0b, 0x0a, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x10, 0x09, 0x2a, 0x83, 0x01, - 0x0a, 0x07, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x65, 0x61, - 0x72, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, - 0x05, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, - 0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x73, 0x74, 0x10, - 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x04, - 0x12, 0x09, 0x0a, 0x05, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x53, - 0x6f, 0x75, 0x74, 0x68, 0x57, 0x65, 0x73, 0x74, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x65, - 0x73, 0x74, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x57, 0x65, 0x73, - 0x74, 0x10, 0x08, 0x2a, 0x69, 0x0a, 0x0c, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x70, 0x67, 0x72, - 0x61, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x70, 0x67, 0x72, - 0x61, 0x64, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x70, 0x61, 0x63, - 0x69, 0x74, 0x79, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, - 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x4d, - 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x2a, 0x6a, - 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x52, - 0x6f, 0x76, 0x65, 0x72, 0x4c, 0x69, 0x76, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x6f, - 0x76, 0x65, 0x72, 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, - 0x52, 0x6f, 0x63, 0x6b, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x52, - 0x6f, 0x63, 0x6b, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x6f, - 0x76, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, 0x10, 0x05, 0x2a, 0x37, 0x0a, 0x04, 0x54, 0x69, - 0x6c, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x69, 0x6c, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x6f, 0x63, 0x6b, 0x10, 0x01, 0x12, 0x0a, 0x0a, - 0x06, 0x47, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x61, 0x6e, - 0x64, 0x10, 0x03, 0x2a, 0x4c, 0x0a, 0x0c, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x61, - 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, - 0x43, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x11, - 0x0a, 0x0d, 0x53, 0x6f, 0x6c, 0x61, 0x72, 0x43, 0x68, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x10, - 0x02, 0x32, 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x4d, 0x0a, 0x0c, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x72, 0x6f, 0x76, - 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, + 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x7d, 0x0a, 0x07, 0x43, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, + 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, 0x69, + 0x6e, 0x67, 0x52, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x6a, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, + 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, + 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x22, 0x75, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x74, 0x69, + 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, + 0x61, 0x70, 0x69, 0x2e, 0x54, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x12, + 0x29, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, + 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, + 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, + 0x0a, 0x01, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0x92, 0x04, 0x0a, + 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, + 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x09, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x61, + 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x24, + 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x72, 0x6f, 0x76, + 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0c, 0x73, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x38, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, + 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, + 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x6c, 0x6f, 0x67, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, + 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x04, 0x77, + 0x69, 0x6e, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, + 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x04, 0x77, 0x69, 0x6e, + 0x64, 0x2a, 0x53, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x10, 0x02, + 0x12, 0x09, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x73, 0x68, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x72, + 0x65, 0x70, 0x61, 0x69, 0x72, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, + 0x63, 0x61, 0x73, 0x74, 0x10, 0x05, 0x2a, 0x83, 0x01, 0x0a, 0x07, 0x42, 0x65, 0x61, 0x72, 0x69, + 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x02, + 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x73, 0x74, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x6f, + 0x75, 0x74, 0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x6f, 0x75, + 0x74, 0x68, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x57, 0x65, 0x73, + 0x74, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x65, 0x73, 0x74, 0x10, 0x07, 0x12, 0x0d, 0x0a, + 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x57, 0x65, 0x73, 0x74, 0x10, 0x08, 0x2a, 0x5a, 0x0a, 0x06, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x6f, 0x76, + 0x65, 0x72, 0x4c, 0x69, 0x76, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x6f, 0x76, 0x65, + 0x72, 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x6f, + 0x63, 0x6b, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x6f, 0x63, + 0x6b, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x2a, 0x37, 0x0a, 0x04, 0x54, 0x69, 0x6c, 0x65, + 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x69, 0x6c, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x6f, 0x63, 0x6b, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x47, + 0x72, 0x61, 0x76, 0x65, 0x6c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x61, 0x6e, 0x64, 0x10, + 0x03, 0x2a, 0x4c, 0x0a, 0x0c, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x69, 0x6c, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x61, + 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, + 0x53, 0x6f, 0x6c, 0x61, 0x72, 0x43, 0x68, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x32, + 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x4d, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, - 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x05, - 0x52, 0x61, 0x64, 0x61, 0x72, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, - 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, - 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6d, 0x64, 0x69, 0x6c, 0x75, 0x7a, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x05, 0x52, 0x61, + 0x64, 0x61, 0x72, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, + 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x6f, 0x76, + 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, + 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6d, 0x64, 0x69, 0x6c, 0x75, 0x7a, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1657,68 +1390,60 @@ func file_roveapi_roveapi_proto_rawDescGZIP() []byte { return file_roveapi_roveapi_proto_rawDescData } -var file_roveapi_roveapi_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_roveapi_roveapi_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_roveapi_roveapi_proto_enumTypes = make([]protoimpl.EnumInfo, 5) +var file_roveapi_roveapi_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_roveapi_roveapi_proto_goTypes = []interface{}{ (CommandType)(0), // 0: roveapi.CommandType (Bearing)(0), // 1: roveapi.Bearing - (RoverUpgrade)(0), // 2: roveapi.RoverUpgrade - (Object)(0), // 3: roveapi.Object - (Tile)(0), // 4: roveapi.Tile - (SailPosition)(0), // 5: roveapi.SailPosition - (*ServerStatusRequest)(nil), // 6: roveapi.ServerStatusRequest - (*ServerStatusResponse)(nil), // 7: roveapi.ServerStatusResponse - (*RegisterRequest)(nil), // 8: roveapi.RegisterRequest - (*Account)(nil), // 9: roveapi.Account - (*RegisterResponse)(nil), // 10: roveapi.RegisterResponse - (*Command)(nil), // 11: roveapi.Command - (*CommandRequest)(nil), // 12: roveapi.CommandRequest - (*CommandResponse)(nil), // 13: roveapi.CommandResponse - (*RadarRequest)(nil), // 14: roveapi.RadarRequest - (*RadarResponse)(nil), // 15: roveapi.RadarResponse - (*StatusRequest)(nil), // 16: roveapi.StatusRequest - (*Log)(nil), // 17: roveapi.Log - (*Vector)(nil), // 18: roveapi.Vector - (*RoverSpecifications)(nil), // 19: roveapi.RoverSpecifications - (*RoverStatus)(nil), // 20: roveapi.RoverStatus - (*RoverReadings)(nil), // 21: roveapi.RoverReadings - (*StatusResponse)(nil), // 22: roveapi.StatusResponse + (Object)(0), // 2: roveapi.Object + (Tile)(0), // 3: roveapi.Tile + (SailPosition)(0), // 4: roveapi.SailPosition + (*ServerStatusRequest)(nil), // 5: roveapi.ServerStatusRequest + (*ServerStatusResponse)(nil), // 6: roveapi.ServerStatusResponse + (*RegisterRequest)(nil), // 7: roveapi.RegisterRequest + (*Account)(nil), // 8: roveapi.Account + (*RegisterResponse)(nil), // 9: roveapi.RegisterResponse + (*Command)(nil), // 10: roveapi.Command + (*CommandRequest)(nil), // 11: roveapi.CommandRequest + (*CommandResponse)(nil), // 12: roveapi.CommandResponse + (*RadarRequest)(nil), // 13: roveapi.RadarRequest + (*RadarResponse)(nil), // 14: roveapi.RadarResponse + (*StatusRequest)(nil), // 15: roveapi.StatusRequest + (*Log)(nil), // 16: roveapi.Log + (*Vector)(nil), // 17: roveapi.Vector + (*StatusResponse)(nil), // 18: roveapi.StatusResponse } var file_roveapi_roveapi_proto_depIdxs = []int32{ - 9, // 0: roveapi.RegisterResponse.account:type_name -> roveapi.Account + 8, // 0: roveapi.RegisterResponse.account:type_name -> roveapi.Account 0, // 1: roveapi.Command.command:type_name -> roveapi.CommandType - 1, // 2: roveapi.Command.bearing:type_name -> roveapi.Bearing - 2, // 3: roveapi.Command.upgrade:type_name -> roveapi.RoverUpgrade - 9, // 4: roveapi.CommandRequest.account:type_name -> roveapi.Account - 11, // 5: roveapi.CommandRequest.commands:type_name -> roveapi.Command - 9, // 6: roveapi.RadarRequest.account:type_name -> roveapi.Account - 4, // 7: roveapi.RadarResponse.tiles:type_name -> roveapi.Tile - 3, // 8: roveapi.RadarResponse.objects:type_name -> roveapi.Object - 9, // 9: roveapi.StatusRequest.account:type_name -> roveapi.Account - 1, // 10: roveapi.RoverStatus.bearing:type_name -> roveapi.Bearing - 5, // 11: roveapi.RoverStatus.sailPosition:type_name -> roveapi.SailPosition - 11, // 12: roveapi.RoverStatus.queuedCommands:type_name -> roveapi.Command - 18, // 13: roveapi.RoverReadings.position:type_name -> roveapi.Vector - 1, // 14: roveapi.RoverReadings.wind:type_name -> roveapi.Bearing - 17, // 15: roveapi.RoverReadings.logs:type_name -> roveapi.Log - 19, // 16: roveapi.StatusResponse.spec:type_name -> roveapi.RoverSpecifications - 20, // 17: roveapi.StatusResponse.status:type_name -> roveapi.RoverStatus - 21, // 18: roveapi.StatusResponse.readings:type_name -> roveapi.RoverReadings - 6, // 19: roveapi.Rove.ServerStatus:input_type -> roveapi.ServerStatusRequest - 8, // 20: roveapi.Rove.Register:input_type -> roveapi.RegisterRequest - 12, // 21: roveapi.Rove.Command:input_type -> roveapi.CommandRequest - 14, // 22: roveapi.Rove.Radar:input_type -> roveapi.RadarRequest - 16, // 23: roveapi.Rove.Status:input_type -> roveapi.StatusRequest - 7, // 24: roveapi.Rove.ServerStatus:output_type -> roveapi.ServerStatusResponse - 10, // 25: roveapi.Rove.Register:output_type -> roveapi.RegisterResponse - 13, // 26: roveapi.Rove.Command:output_type -> roveapi.CommandResponse - 15, // 27: roveapi.Rove.Radar:output_type -> roveapi.RadarResponse - 22, // 28: roveapi.Rove.Status:output_type -> roveapi.StatusResponse - 24, // [24:29] is the sub-list for method output_type - 19, // [19:24] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 1, // 2: roveapi.Command.turn:type_name -> roveapi.Bearing + 8, // 3: roveapi.CommandRequest.account:type_name -> roveapi.Account + 10, // 4: roveapi.CommandRequest.commands:type_name -> roveapi.Command + 8, // 5: roveapi.RadarRequest.account:type_name -> roveapi.Account + 3, // 6: roveapi.RadarResponse.tiles:type_name -> roveapi.Tile + 2, // 7: roveapi.RadarResponse.objects:type_name -> roveapi.Object + 8, // 8: roveapi.StatusRequest.account:type_name -> roveapi.Account + 17, // 9: roveapi.StatusResponse.position:type_name -> roveapi.Vector + 1, // 10: roveapi.StatusResponse.bearing:type_name -> roveapi.Bearing + 4, // 11: roveapi.StatusResponse.sailPosition:type_name -> roveapi.SailPosition + 10, // 12: roveapi.StatusResponse.queuedCommands:type_name -> roveapi.Command + 16, // 13: roveapi.StatusResponse.logs:type_name -> roveapi.Log + 1, // 14: roveapi.StatusResponse.wind:type_name -> roveapi.Bearing + 5, // 15: roveapi.Rove.ServerStatus:input_type -> roveapi.ServerStatusRequest + 7, // 16: roveapi.Rove.Register:input_type -> roveapi.RegisterRequest + 11, // 17: roveapi.Rove.Command:input_type -> roveapi.CommandRequest + 13, // 18: roveapi.Rove.Radar:input_type -> roveapi.RadarRequest + 15, // 19: roveapi.Rove.Status:input_type -> roveapi.StatusRequest + 6, // 20: roveapi.Rove.ServerStatus:output_type -> roveapi.ServerStatusResponse + 9, // 21: roveapi.Rove.Register:output_type -> roveapi.RegisterResponse + 12, // 22: roveapi.Rove.Command:output_type -> roveapi.CommandResponse + 14, // 23: roveapi.Rove.Radar:output_type -> roveapi.RadarResponse + 18, // 24: roveapi.Rove.Status:output_type -> roveapi.StatusResponse + 20, // [20:25] is the sub-list for method output_type + 15, // [15:20] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_roveapi_roveapi_proto_init() } @@ -1884,42 +1609,6 @@ func file_roveapi_roveapi_proto_init() { } } file_roveapi_roveapi_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoverSpecifications); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_roveapi_roveapi_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoverStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_roveapi_roveapi_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoverReadings); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_roveapi_roveapi_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StatusResponse); i { case 0: return &v.state @@ -1937,8 +1626,8 @@ func file_roveapi_roveapi_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_roveapi_roveapi_proto_rawDesc, - NumEnums: 6, - NumMessages: 17, + NumEnums: 5, + NumMessages: 14, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/roveapi/roveapi.proto b/proto/roveapi/roveapi.proto index 72a1fc2..33bbc25 100644 --- a/proto/roveapi/roveapi.proto +++ b/proto/roveapi/roveapi.proto @@ -89,24 +89,16 @@ message RegisterResponse { // CommandType defines the type of a command to give to the rover enum CommandType { none = 0; - // Waits before performing the next command - wait = 1; // Toggles the sails, either catching the wind, or charging from the sun - toggle = 2; - // Turns the rover in the specified bearing (requires bearing) - turn = 3; + toggle = 1; + // Turns the rover in the specified bearing, requires data + turn = 2; // Stashes item at current location in rover inventory - stash = 4; + stash = 3; // Repairs the rover using an inventory object - repair = 5; - // Broadcasts a message to nearby rovers (requires data) - broadcast = 6; - // Salvages a neighboring dormant rover for parts - salvage = 7; - // Transfers remote control into dormant rover - transfer = 8; - // Upgrades a chosen rover specification using 5 rover parts - upgrade = 9; + repair = 4; + // Broadcasts a message to nearby rovers, requires data + broadcast = 5; } // Bearing represents a compass direction @@ -123,32 +115,17 @@ enum Bearing { NorthWest = 8; } -// Describes the type of upgrade -enum RoverUpgrade { - RoverUpgradeUnknown = 0; - Range = 1; - Capacity = 2; - MaximumIntegrity = 3; - MaximumCharge = 4; -} - // Command is a single command for a rover message Command { // The command type CommandType command = 1; - // The number of times to repeat the command after the first - int32 repeat = 2; + // A simple message, must be composed of printable ASCII glyphs (32-126) + // maximum of three characters + bytes broadcast = 2; - // broadcast - a simple message, must be composed of up to 3 printable ASCII - // glyphs (32-126) - bytes data = 3; - - // move - the bearing for the rover to turn to - Bearing bearing = 4; - - // upgrade - the upgrade to apply to the rover - RoverUpgrade upgrade = 5; + // The bearing for the rover to turn to + Bearing turn = 3; } // CommandRequest describes a set of commands to be requested for the rover @@ -183,10 +160,6 @@ enum Object { // RockLarge is a large blocking rock RockLarge = 4; - - // RoverParts is one unit of rover parts, used for repairing and fixing the - // rover - RoverParts = 5; } enum Tile { @@ -258,65 +231,47 @@ enum SailPosition { SolarCharging = 2; } -message RoverSpecifications { - +// StatusResponse is the response given to a status request +message StatusResponse { // The name of the rover string name = 1; - // The range of this rover's radar and broadcasting - int32 range = 2; - - // The capacity of the inventory - int32 capacity = 3; - - // The maximum health of the rover - int32 maximumIntegrity = 4; - - // The max energy the rover can store - int32 maximumCharge = 5; -} - -message RoverStatus { + // Position of the rover in world coordinates + Vector position = 2; // The current direction of the rover - Bearing bearing = 1; + Bearing bearing = 3; - // The current position of the sails - SailPosition sailPosition = 2; + // The range of this rover's radar and broadcasting + int32 range = 4; // The items in the rover inventory - bytes inventory = 3; + bytes inventory = 5; + + // The capacity of the inventory + int32 capacity = 6; // The current health of the rover - int32 integrity = 4; + int32 integrity = 7; + + // The maximum health of the rover + int32 maximumIntegrity = 8; // The energy stored in the rover - int32 charge = 5; + int32 charge = 9; + + // The max energy the rover can store + int32 maximumCharge = 10; + + // The current position of the sails + SailPosition sailPosition = 11; // The set of currently queued commands - repeated Command queuedCommands = 6; -} - -message RoverReadings { - // Position of the rover in world coordinates - Vector position = 1; - - // The current wind direction - Bearing wind = 2; + repeated Command queuedCommands = 12; // The most recent logs - repeated Log logs = 3; -} + repeated Log logs = 13; -// StatusResponse is the response given to a status request -message StatusResponse { - - // The static rover information - RoverSpecifications spec = 1; - - // Current rover status - RoverStatus status = 2; - - // Current rover readings - RoverReadings readings = 3; + // The current wind direction + Bearing wind = 14; } \ No newline at end of file